From: "Rajendra Nayak" <rnayak@ti.com>
To: linux-omap@vger.kernel.org
Subject: [PATCH 06/09] virtual clock nodes for VDD1 and VDD2
Date: Tue, 8 Jul 2008 17:09:30 +0530 [thread overview]
Message-ID: <030d01c8e0ef$48b116f0$68bf18ac@ent.ti.com> (raw)
The patch defines virtual nodes for VDD1 and VDD2
Also adds VDD1/VDD2 specific rate/OPP tables in the board file
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
arch/arm/mach-omap2/board-3430sdp.c | 38 +++++
arch/arm/mach-omap2/clock34xx.c | 206 +++++++++++++++++++++++++-----
arch/arm/mach-omap2/clock34xx.h | 28 ++++
include/asm-arm/arch-omap/board-3430sdp.h | 35 +++++
include/asm-arm/arch-omap/clock.h | 8 +
5 files changed, 286 insertions(+), 29 deletions(-)
Index: linux-omap-2.6/arch/arm/mach-omap2/clock34xx.h
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/clock34xx.h 2008-07-08 15:21:45.039649888 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/clock34xx.h 2008-07-08 15:21:57.861233153 +0530
@@ -35,6 +35,13 @@ static u32 omap3_dpll_autoidle_read(stru
static int omap3_noncore_dpll_enable(struct clk *clk);
static void omap3_noncore_dpll_disable(struct clk *clk);
static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate);
+static void omap3_table_recalc(struct clk *clk);
+static long omap3_round_to_table_rate(struct clk *clk, unsigned long rate);
+static int omap3_select_table_rate(struct clk *clk, unsigned long rate);
+
+extern struct vdd_prcm_config vdd1_rate_table[];
+extern struct vdd_prcm_config vdd2_rate_table[];
+extern struct vdd_prcm_config iva2_rate_table[];
/* Maximum DPLL multiplier, divider values for OMAP3 */
#define OMAP3_MAX_DPLL_MULT 2048
@@ -3046,6 +3053,24 @@ static struct clk wdt1_fck = {
.recalc = &followparent_recalc,
};
+static struct clk virt_vdd1_prcm_set = {
+ .name = "virt_vdd1_prcm_set",
+ .flags = CLOCK_IN_OMAP343X | VIRTUAL_CLOCK | ALWAYS_ENABLED,
+ .parent = &mpu_ck, /* Indexed by mpu speed, no parent */
+ .recalc = &omap3_table_recalc, /*sets are keyed on mpu rate */
+ .set_rate = &omap3_select_table_rate,
+ .round_rate = &omap3_round_to_table_rate,
+};
+
+static struct clk virt_vdd2_prcm_set = {
+ .name = "virt_vdd2_prcm_set",
+ .flags = CLOCK_IN_OMAP343X | VIRTUAL_CLOCK | ALWAYS_ENABLED,
+ .parent = &core_ck,
+ .recalc = &omap3_table_recalc,
+ .set_rate = &omap3_select_table_rate,
+ .round_rate = &omap3_round_to_table_rate,
+};
+
static struct clk *onchip_34xx_clks[] __initdata = {
&omap_32k_fck,
&virt_12m_ck,
@@ -3258,6 +3283,9 @@ static struct clk *onchip_34xx_clks[] __
&secure_32k_fck,
&gpt12_fck,
&wdt1_fck,
+ /* virtual group clock */
+ &virt_vdd1_prcm_set,
+ &virt_vdd2_prcm_set,
};
#endif
Index: linux-omap-2.6/arch/arm/mach-omap2/clock34xx.c
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/clock34xx.c 2008-07-08 15:21:45.039649888 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/clock34xx.c 2008-07-08 15:22:27.625265807 +0530
@@ -25,6 +25,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/limits.h>
+#include <linux/err.h>
#include <asm/arch/clock.h>
#include <asm/arch/sram.h>
@@ -45,6 +46,32 @@
#define MAX_DPLL_WAIT_TRIES 1000000
+struct vdd_prcm_config *curr_vdd1_prcm_set;
+struct vdd_prcm_config *curr_vdd2_prcm_set;
+static struct clk *dpll1_clk, *dpll2_clk, *dpll3_clk;
+
+#ifndef CONFIG_CPU_FREQ
+static unsigned long compute_lpj(unsigned long ref, u_int div, u_int mult)
+{
+ unsigned long new_jiffy_l, new_jiffy_h;
+
+ /*
+ * Recalculate loops_per_jiffy. We do it this way to
+ * avoid math overflow on 32-bit machines. Maybe we
+ * should make this architecture dependent? If you have
+ * a better way of doing this, please replace!
+ *
+ * new = old * mult / div
+ */
+ new_jiffy_h = ref / div;
+ new_jiffy_l = (ref % div) / 100;
+ new_jiffy_h *= mult;
+ new_jiffy_l = new_jiffy_l * mult / div;
+
+ return new_jiffy_h + new_jiffy_l * 100;
+}
+#endif
+
/**
* omap3_dpll_recalc - recalculate DPLL rate
* @clk: DPLL struct clk
@@ -569,15 +596,6 @@ void omap2_clk_prepare_for_reboot(void)
*/
static int __init omap2_clk_arch_init(void)
{
- if (!mpurate)
- return -EINVAL;
-
- /* REVISIT: not yet ready for 343x */
-#if 0
- if (omap2_select_table_rate(&virt_prcm_set, mpurate))
- printk(KERN_ERR "Could not find matching MPU rate\n");
-#endif
-
recalculate_root_clocks();
printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL3/MPU): "
@@ -595,6 +613,9 @@ int __init omap2_clk_init(void)
struct clk **clkp;
/* u32 clkrate; */
u32 cpu_clkflg;
+ unsigned long mpu_speed, core_speed;
+ struct vdd_prcm_config *prcm_vdd;
+
/* REVISIT: Ultimately this will be used for multiboot */
#if 0
@@ -637,22 +658,31 @@ int __init omap2_clk_init(void)
}
}
- /* REVISIT: Not yet ready for OMAP3 */
-#if 0
- /* Check the MPU rate set by bootloader */
- clkrate = omap2_get_dpll_rate_24xx(&dpll_ck);
- for (prcm = rate_table; prcm->mpu_speed; prcm++) {
- if (!(prcm->flags & cpu_mask))
- continue;
- if (prcm->xtal_speed != sys_ck.rate)
- continue;
- if (prcm->dpll_speed <= clkrate)
- break;
+ recalculate_root_clocks();
+
+ dpll1_clk = clk_get(NULL, "dpll1_ck");
+ dpll2_clk = clk_get(NULL, "dpll2_ck");
+ dpll3_clk = clk_get(NULL, "dpll3_ck");
+
+#ifdef CONFIG_MACH_OMAP_3430SDP
+ mpu_speed = dpll1_clk->rate;
+ prcm_vdd = vdd1_rate_table + MAX_VDD1_OPP;
+ for (; prcm_vdd->speed; prcm_vdd--) {
+ if (prcm_vdd->speed <= mpu_speed) {
+ curr_vdd1_prcm_set = prcm_vdd;
+ break;
+ }
}
- curr_prcm_set = prcm;
-#endif
- recalculate_root_clocks();
+ core_speed = dpll3_clk->rate;
+ prcm_vdd = vdd2_rate_table + MAX_VDD2_OPP;
+ for (; prcm_vdd->speed; prcm_vdd--) {
+ if (prcm_vdd->speed <= core_speed) {
+ curr_vdd2_prcm_set = prcm_vdd;
+ break;
+ }
+ }
+#endif
printk(KERN_INFO "Clocking rate (Crystal/DPLL/ARM core): "
"%ld.%01ld/%ld/%ld MHz\n",
@@ -665,13 +695,131 @@ int __init omap2_clk_init(void)
*/
clk_enable_init_clocks();
- /* Avoid sleeping during omap2_clk_prepare_for_reboot() */
- /* REVISIT: not yet ready for 343x */
-#if 0
- vclk = clk_get(NULL, "virt_prcm_set");
- sclk = clk_get(NULL, "sys_ck");
-#endif
return 0;
}
+inline unsigned int get_freq(struct vdd_prcm_config *opp_freq_table,
+ unsigned long opp)
+{
+ struct vdd_prcm_config *prcm_config;
+ prcm_config = opp_freq_table;
+
+ for (; prcm_config->opp; prcm_config--)
+ if (prcm_config->opp == opp)
+ return prcm_config->speed;
+ return 0;
+}
+
+inline unsigned int get_opp(struct vdd_prcm_config *opp_freq_table,
+ unsigned long freq)
+{
+ struct vdd_prcm_config *prcm_config;
+ prcm_config = opp_freq_table;
+
+ if (prcm_config->speed <= freq)
+ return prcm_config->opp; /* Return the Highest OPP */
+ for (; prcm_config->speed; prcm_config--) {
+ if (prcm_config->speed < freq)
+ return (prcm_config+1)->opp;
+ else if (prcm_config->speed == freq)
+ return prcm_config->opp;
+ }
+ /* Return the least OPP */
+ return (prcm_config+1)->opp;
+}
+
+#ifdef CONFIG_MACH_OMAP_3430SDP
+static void omap3_table_recalc(struct clk *clk)
+{
+ if ((clk != &virt_vdd1_prcm_set) && (clk != &virt_vdd2_prcm_set))
+ return;
+
+ if ((curr_vdd1_prcm_set) && (clk == &virt_vdd1_prcm_set))
+ clk->rate = curr_vdd1_prcm_set->speed;
+ else if ((curr_vdd2_prcm_set) && (clk == &virt_vdd2_prcm_set))
+ clk->rate = curr_vdd2_prcm_set->speed;
+ pr_debug("CLK RATE:%lu\n", clk->rate);
+}
+
+static long omap3_round_to_table_rate(struct clk *clk, unsigned long rate)
+{
+ struct vdd_prcm_config *ptr;
+ long highest_rate;
+
+ if ((clk != &virt_vdd1_prcm_set) && (clk != &virt_vdd2_prcm_set))
+ return -EINVAL;
+
+ highest_rate = -EINVAL;
+
+ if (clk == &virt_vdd1_prcm_set)
+ ptr = vdd1_rate_table + MAX_VDD1_OPP;
+ else
+ ptr = vdd2_rate_table + MAX_VDD2_OPP;
+
+ for (; ptr->speed; ptr--) {
+ highest_rate = ptr->speed;
+ pr_debug("Highest speed : %lu, rate: %lu\n", highest_rate,
+ rate);
+ if (ptr->speed <= rate)
+ break;
+ }
+ return highest_rate;
+}
+
+static int omap3_select_table_rate(struct clk *clk, unsigned long rate)
+{
+ struct vdd_prcm_config *prcm_vdd;
+ unsigned long found_speed = 0, curr_mpu_speed;
+ int index;
+
+ if ((clk != &virt_vdd1_prcm_set) && (clk != &virt_vdd2_prcm_set))
+ return -EINVAL;
+
+ if (clk == &virt_vdd1_prcm_set) {
+ prcm_vdd = vdd1_rate_table + MAX_VDD1_OPP;
+ index = MAX_VDD1_OPP;
+ } else if (clk == &virt_vdd2_prcm_set) {
+ prcm_vdd = vdd2_rate_table + MAX_VDD2_OPP;
+ index = MAX_VDD2_OPP;
+ }
+
+ for (; prcm_vdd->speed; prcm_vdd--, index--) {
+ if (prcm_vdd->speed <= rate) {
+ found_speed = prcm_vdd->speed;
+ pr_debug("Found speed = %lu\n", found_speed);
+ break;
+ }
+ }
+
+ if (!found_speed) {
+ printk(KERN_INFO "Could not set table rate to %luMHz\n",
+ rate / 1000000);
+ return -EINVAL;
+ }
+
+
+ if (clk == &virt_vdd1_prcm_set) {
+ curr_mpu_speed = curr_vdd1_prcm_set->speed;
+ clk_set_rate(dpll1_clk, prcm_vdd->speed);
+ clk_set_rate(dpll2_clk, iva2_rate_table[index].speed);
+ curr_vdd1_prcm_set = prcm_vdd;
+#ifndef CONFIG_CPU_FREQ
+ /*Update loops_per_jiffy if processor speed is being changed*/
+ loops_per_jiffy = compute_lpj(loops_per_jiffy,
+ curr_mpu_speed/1000, found_speed/1000);
#endif
+ } else {
+ clk_set_rate(dpll3_clk, prcm_vdd->speed);
+ curr_vdd2_prcm_set = prcm_vdd;
+ }
+ return 0;
+}
+#else /* CONFIG_MACH_OMAP_3430SDP */
+static void omap3_table_recalc(struct clk *clk) {}
+static long omap3_round_to_table_rate(struct clk *clk, unsigned long rate)
+{ return 0; }
+static int omap3_select_table_rate(struct clk *clk, unsigned long rate)
+{ return 0; }
+#endif /* CONFIG_MACH_OMAP_3430SDP */
+
+#endif /* CONFIG_ARCH_OMAP3 */
Index: linux-omap-2.6/include/asm-arm/arch-omap/clock.h
===================================================================
--- linux-omap-2.6.orig/include/asm-arm/arch-omap/clock.h 2008-07-08 15:21:45.038649920 +0530
+++ linux-omap-2.6/include/asm-arm/arch-omap/clock.h 2008-07-08 15:21:57.862233120 +0530
@@ -109,6 +109,14 @@ struct clk_functions {
#endif
};
+#ifdef CONFIG_ARCH_OMAP3
+struct vdd_prcm_config {
+ unsigned long speed;
+ unsigned long opp;
+ unsigned long flags;
+};
+#endif
+
extern unsigned int mpurate;
extern int clk_init(struct clk_functions *custom_clocks);
Index: linux-omap-2.6/arch/arm/mach-omap2/board-3430sdp.c
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/board-3430sdp.c 2008-07-08 15:21:45.039649888 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/board-3430sdp.c 2008-07-08 15:21:57.863233088 +0530
@@ -40,6 +40,7 @@
#include <asm/arch/keypad.h>
#include <asm/arch/dma.h>
#include <asm/arch/gpmc.h>
+#include <asm/arch/clock.h>
#include <asm/io.h>
#include <asm/delay.h>
@@ -49,6 +50,43 @@
#define ENABLE_VAUX3_DEDICATED 0x03
#define ENABLE_VAUX3_DEV_GRP 0x20
+struct vdd_prcm_config vdd1_rate_table[] = {
+ {0, 0, 0},
+ /*OPP1*/
+ {S125M, VDD1_OPP1, 0},
+ /*OPP2*/
+ {S250M, VDD1_OPP2, 0},
+ /*OPP3*/
+ {S500M, VDD1_OPP3, 0},
+ /*OPP4*/
+ {S550M, VDD1_OPP4, 0},
+ /*OPP5*/
+ {S600M, VDD1_OPP5, 0},
+};
+
+struct vdd_prcm_config vdd2_rate_table[] = {
+ {0, 0, 0},
+ /*OPP1*/
+ {0, VDD2_OPP1, 0},
+ /*OPP2*/
+ {S83M, VDD2_OPP2, 0},
+ /*OPP3*/
+ {S166M, VDD2_OPP3, 0},
+};
+
+struct vdd_prcm_config iva2_rate_table[] = {
+ {0, 0, 0},
+ /*OPP1*/
+ {S90M, VDD1_OPP1, 0},
+ /*OPP2*/
+ {S180M, VDD1_OPP2, 0},
+ /*OPP3*/
+ {S360M, VDD1_OPP3, 0},
+ /*OPP4*/
+ {S400M, VDD1_OPP4, 0},
+ /*OPP5*/
+ {S430M, VDD1_OPP5, 0},
+};
static struct resource sdp3430_smc91x_resources[] = {
[0] = {
Index: linux-omap-2.6/include/asm-arm/arch-omap/board-3430sdp.h
===================================================================
--- linux-omap-2.6.orig/include/asm-arm/arch-omap/board-3430sdp.h 2008-07-08 15:21:45.038649920 +0530
+++ linux-omap-2.6/include/asm-arm/arch-omap/board-3430sdp.h 2008-07-08 15:21:57.863233088 +0530
@@ -67,5 +67,40 @@ extern void sdp3430_flash_init(void);
#define FLASH_SIZE_SDPV1 SZ_64M
#define FLASH_SIZE_SDPV2 SZ_128M
+/* MPU speeds */
+#define S600M 600000000
+#define S550M 550000000
+#define S500M 500000000
+#define S250M 250000000
+#define S125M 125000000
+
+/* IVA speeds */
+#define S430M 430000000
+#define S400M 400000000
+#define S360M 360000000
+#define S180M 180000000
+#define S90M 90000000
+
+/* L3 speeds */
+#define S83M 83000000
+#define S166M 166000000
+
+/* VDD1 OPPS */
+#define VDD1_OPP1 0x1
+#define VDD1_OPP2 0x2
+#define VDD1_OPP3 0x3
+#define VDD1_OPP4 0x4
+#define VDD1_OPP5 0x5
+
+/* VDD2 OPPS */
+#define VDD2_OPP1 0x1
+#define VDD2_OPP2 0x2
+#define VDD2_OPP3 0x3
+
+#define MIN_VDD1_OPP VDD1_OPP1
+#define MAX_VDD1_OPP VDD1_OPP5
+#define MIN_VDD2_OPP VDD2_OPP1
+#define MAX_VDD2_OPP VDD2_OPP3
+
#endif /* __ASM_ARCH_OMAP_3430SDP_H */
reply other threads:[~2008-07-08 11:39 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='030d01c8e0ef$48b116f0$68bf18ac@ent.ti.com' \
--to=rnayak@ti.com \
--cc=linux-omap@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.