]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
ARM: AM43xx: clocks: Update DPLL details
authorLokesh Vutla <lokeshvutla@ti.com>
Tue, 10 Dec 2013 09:32:20 +0000 (15:02 +0530)
committerTom Rini <trini@ti.com>
Thu, 19 Dec 2013 02:14:01 +0000 (21:14 -0500)
Updating the Multiplier and Dividers value for all DPLLs.
Safest OPP is read from DEV ATTRIBUTE register. Accoring to the value
returned the MPU DPLL is locked.
At different OPPs follwoing are the MPU locked frequencies.
OPP50 300MHz
OPP100 600MHz
OPP120 720MHz
OPPTB 800MHz
OPPNT 1000MHz
According to the latest DM following is the OPP table dependencies:
VDD_CORE  VDD_MPU
OPP50 OPP50
OPP50  OPP100
OPP100 OPP50
OPP100 OPP100
OPP100 OPP120
So at different OPPs of MPU it is safest to lock CORE at OPP_NOM.
Following are the DPLL locking frequencies at OPP NOM:
Core locks at 1000MHz
Per locks at 960MHz
LPDDR2 locks at 266MHz
DDR3 locks at 400MHz

Touching AM33xx files also to get DPLL values specific to board but no
functionality difference.
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
arch/arm/cpu/armv7/am33xx/clock.c
arch/arm/cpu/armv7/am33xx/clock_am33xx.c
arch/arm/cpu/armv7/am33xx/clock_am43xx.c
arch/arm/include/asm/arch-am33xx/clock.h
arch/arm/include/asm/arch-am33xx/cpu.h
arch/arm/include/asm/arch-am33xx/hardware_am43xx.h
board/ti/am43xx/board.c
board/ti/am43xx/board.h
board/ti/am43xx/mux.c

index 8e5f3c671503be332e2870694fa640ff82b9e70c..0672798fe0415afbcd66286dde5031f255a30eda 100644 (file)
@@ -101,9 +101,15 @@ void do_setup_dpll(const struct dpll_regs *dpll_regs,
 static void setup_dplls(void)
 {
        const struct dpll_params *params;
-       do_setup_dpll(&dpll_core_regs, &dpll_core);
-       do_setup_dpll(&dpll_mpu_regs, &dpll_mpu);
-       do_setup_dpll(&dpll_per_regs, &dpll_per);
+
+       params = get_dpll_core_params();
+       do_setup_dpll(&dpll_core_regs, params);
+
+       params = get_dpll_mpu_params();
+       do_setup_dpll(&dpll_mpu_regs, params);
+
+       params = get_dpll_per_params();
+       do_setup_dpll(&dpll_per_regs, params);
        writel(0x300, &cmwkup->clkdcoldodpllper);
 
        params = get_dpll_ddr_params();
index fabe2595a33e97f220133c634bf93b945c7fe602..92142c893444bc63ad7e1b811172c5996d6005a0 100644 (file)
@@ -62,6 +62,21 @@ const struct dpll_params dpll_core = {
 const struct dpll_params dpll_per = {
                960, OSC-1, 5, -1, -1, -1, -1};
 
+const struct dpll_params *get_dpll_mpu_params(void)
+{
+       return &dpll_mpu;
+}
+
+const struct dpll_params *get_dpll_core_params(void)
+{
+       return &dpll_core;
+}
+
+const struct dpll_params *get_dpll_per_params(void)
+{
+       return &dpll_per;
+}
+
 void setup_clocks_for_console(void)
 {
        clrsetbits_le32(&cmwkup->wkclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK,
index 22963b7f8530a7bc3a7b4c10b714b8b6cae61ae2..97c00b4925ff332129a6649a1ca3c83eb37d24c9 100644 (file)
@@ -48,15 +48,9 @@ const struct dpll_regs dpll_ddr_regs = {
        .cm_idlest_dpll         = CM_WKUP + 0x5A4,
        .cm_clksel_dpll         = CM_WKUP + 0x5AC,
        .cm_div_m2_dpll         = CM_WKUP + 0x5B0,
+       .cm_div_m4_dpll         = CM_WKUP + 0x5B8,
 };
 
-const struct dpll_params dpll_mpu = {
-               -1, -1, -1, -1, -1, -1, -1};
-const struct dpll_params dpll_core = {
-               -1, -1, -1, -1, -1, -1, -1};
-const struct dpll_params dpll_per = {
-               -1, -1, -1, -1, -1, -1, -1};
-
 void setup_clocks_for_console(void)
 {
        /* Do not add any spl_debug prints in this function */
index 519249e4af4058fbdd30db3ceaa8984e39fd1998..76374575496d598d6466750883f68693c19f2a4e 100644 (file)
@@ -98,13 +98,12 @@ extern const struct dpll_regs dpll_mpu_regs;
 extern const struct dpll_regs dpll_core_regs;
 extern const struct dpll_regs dpll_per_regs;
 extern const struct dpll_regs dpll_ddr_regs;
-extern const struct dpll_params dpll_mpu;
-extern const struct dpll_params dpll_core;
-extern const struct dpll_params dpll_per;
-extern const struct dpll_params dpll_ddr;
 
 extern struct cm_wkuppll *const cmwkup;
 
+const struct dpll_params *get_dpll_mpu_params(void);
+const struct dpll_params *get_dpll_core_params(void);
+const struct dpll_params *get_dpll_per_params(void);
 const struct dpll_params *get_dpll_ddr_params(void);
 void do_setup_dpll(const struct dpll_regs *, const struct dpll_params *);
 void prcm_init(void);
index 19b84690a199ae7a9ee4db4feb488b0892e715ab..3ee37dc4e7960a61836ce9bae98523064b2a7bf9 100644 (file)
@@ -480,6 +480,8 @@ struct ctrl_stat {
        unsigned int statusreg;         /* ofset 0x40 */
        unsigned int resv2[51];
        unsigned int secure_emif_sdram_config;  /* offset 0x0110 */
+       unsigned int resv3[319];
+       unsigned int dev_attr;
 };
 
 /* AM33XX GPIO registers */
index 0a3f8ee32a8f117b6be28f0456dabcd7393e2206..468521bf34b026bad8529fadfe86b09a74bbbc5d 100644 (file)
 #define PRM_PER_USBPHYOCP2SCP1_CLKCTRL (CM_PER + 0x5c0)
 #define USBPHYOCPSCP_MODULE_EN (1 << 1)
 
+/* Control status register */
+#define CTRL_CRYSTAL_FREQ_SRC_MASK             (1 << 31)
+#define CTRL_CRYSTAL_FREQ_SRC_SHIFT            31
+#define CTRL_CRYSTAL_FREQ_SELECTION_MASK       (0x3 << 29)
+#define CTRL_CRYSTAL_FREQ_SELECTION_SHIFT      29
+#define CTRL_SYSBOOT_15_14_MASK                        (0x3 << 22)
+#define CTRL_SYSBOOT_15_14_SHIFT               22
+
+#define CTRL_CRYSTAL_FREQ_SRC_SYSBOOT          0x0
+#define CTRL_CRYSTAL_FREQ_SRC_EFUSE            0x1
+
+#define NUM_CRYSTAL_FREQ                       0x4
+
 #endif /* __AM43XX_HARDWARE_AM43XX_H */
index 723d0ca3274c03a16eed86b71a17a3a94eeb1024..5c92ac7f30da9d2c3a6822df65a4333b1da27588 100644 (file)
@@ -65,12 +65,144 @@ static int read_eeprom(struct am43xx_board_id *header)
 
 #ifdef CONFIG_SPL_BUILD
 
-const struct dpll_params dpll_ddr = {
-               -1, -1, -1, -1, -1, -1, -1};
+#define NUM_OPPS       6
+
+const struct dpll_params dpll_mpu[NUM_CRYSTAL_FREQ][NUM_OPPS] = {
+       {       /* 19.2 MHz */
+               {-1, -1, -1, -1, -1, -1, -1},   /* OPP 50 */
+               {-1, -1, -1, -1, -1, -1, -1},   /* OPP RESERVED */
+               {-1, -1, -1, -1, -1, -1, -1},   /* OPP 100 */
+               {-1, -1, -1, -1, -1, -1, -1},   /* OPP 120 */
+               {-1, -1, -1, -1, -1, -1, -1},   /* OPP TB */
+               {-1, -1, -1, -1, -1, -1, -1}    /* OPP NT */
+       },
+       {       /* 24 MHz */
+               {300, 23, 1, -1, -1, -1, -1},   /* OPP 50 */
+               {-1, -1, -1, -1, -1, -1, -1},   /* OPP RESERVED */
+               {600, 23, 1, -1, -1, -1, -1},   /* OPP 100 */
+               {720, 23, 1, -1, -1, -1, -1},   /* OPP 120 */
+               {800, 23, 1, -1, -1, -1, -1},   /* OPP TB */
+               {1000, 23, 1, -1, -1, -1, -1}   /* OPP NT */
+       },
+       {       /* 25 MHz */
+               {300, 24, 1, -1, -1, -1, -1},   /* OPP 50 */
+               {-1, -1, -1, -1, -1, -1, -1},   /* OPP RESERVED */
+               {600, 24, 1, -1, -1, -1, -1},   /* OPP 100 */
+               {720, 24, 1, -1, -1, -1, -1},   /* OPP 120 */
+               {800, 24, 1, -1, -1, -1, -1},   /* OPP TB */
+               {1000, 24, 1, -1, -1, -1, -1}   /* OPP NT */
+       },
+       {       /* 26 MHz */
+               {300, 25, 1, -1, -1, -1, -1},   /* OPP 50 */
+               {-1, -1, -1, -1, -1, -1, -1},   /* OPP RESERVED */
+               {600, 25, 1, -1, -1, -1, -1},   /* OPP 100 */
+               {720, 25, 1, -1, -1, -1, -1},   /* OPP 120 */
+               {800, 25, 1, -1, -1, -1, -1},   /* OPP TB */
+               {1000, 25, 1, -1, -1, -1, -1}   /* OPP NT */
+       },
+};
+
+const struct dpll_params dpll_core[NUM_CRYSTAL_FREQ] = {
+               {-1, -1, -1, -1, -1, -1, -1},   /* 19.2 MHz */
+               {1000, 23, -1, -1, 10, 8, 4},   /* 24 MHz */
+               {1000, 24, -1, -1, 10, 8, 4},   /* 25 MHz */
+               {1000, 25, -1, -1, 10, 8, 4}    /* 26 MHz */
+};
+
+const struct dpll_params dpll_per[NUM_CRYSTAL_FREQ] = {
+               {-1, -1, -1, -1, -1, -1, -1},   /* 19.2 MHz */
+               {960, 23, 5, -1, -1, -1, -1},   /* 24 MHz */
+               {960, 24, 5, -1, -1, -1, -1},   /* 25 MHz */
+               {960, 25, 5, -1, -1, -1, -1}    /* 26 MHz */
+};
+
+const struct dpll_params epos_evm_dpll_ddr = {
+               266, 24, 1, -1, 1, -1, -1};
+
+const struct dpll_params gp_evm_dpll_ddr = {
+               400, 23, 1, -1, 1, -1, -1};
 
 const struct dpll_params *get_dpll_ddr_params(void)
 {
-       return &dpll_ddr;
+       struct am43xx_board_id header;
+
+       enable_i2c0_pin_mux();
+       i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
+       if (read_eeprom(&header) < 0)
+               puts("Could not get board ID.\n");
+
+       if (board_is_eposevm())
+               return &epos_evm_dpll_ddr;
+       else if (board_is_gpevm())
+               return &gp_evm_dpll_ddr;
+
+       puts(" Board not supported\n");
+       return NULL;
+}
+
+/*
+ * get_sys_clk_index : returns the index of the sys_clk read from
+ *                     ctrl status register. This value is either
+ *                     read from efuse or sysboot pins.
+ */
+static u32 get_sys_clk_index(void)
+{
+       struct ctrl_stat *ctrl = (struct ctrl_stat *)CTRL_BASE;
+       u32 ind = readl(&ctrl->statusreg), src;
+
+       src = (ind & CTRL_CRYSTAL_FREQ_SRC_MASK) >> CTRL_CRYSTAL_FREQ_SRC_SHIFT;
+       if (src == CTRL_CRYSTAL_FREQ_SRC_EFUSE) /* Value read from EFUSE */
+               return ((ind & CTRL_CRYSTAL_FREQ_SELECTION_MASK) >>
+                       CTRL_CRYSTAL_FREQ_SELECTION_SHIFT);
+       else /* Value read from SYS BOOT pins */
+               return ((ind & CTRL_SYSBOOT_15_14_MASK) >>
+                       CTRL_SYSBOOT_15_14_SHIFT);
+}
+
+/*
+ * get_opp_offset:
+ * Returns the index for safest OPP of the device to boot.
+ * max_off:    Index of the MAX OPP in DEV ATTRIBUTE register.
+ * min_off:    Index of the MIN OPP in DEV ATTRIBUTE register.
+ * This data is read from dev_attribute register which is e-fused.
+ * A'1' in bit indicates OPP disabled and not available, a '0' indicates
+ * OPP available. Lowest OPP starts with min_off. So returning the
+ * bit with rightmost '0'.
+ */
+static int get_opp_offset(int max_off, int min_off)
+{
+       struct ctrl_stat *ctrl = (struct ctrl_stat *)CTRL_BASE;
+       int opp = readl(&ctrl->dev_attr), offset, i;
+
+       for (i = max_off; i >= min_off; i--) {
+               offset = opp & (1 << i);
+               if (!offset)
+                       return i;
+       }
+
+       return min_off;
+}
+
+const struct dpll_params *get_dpll_mpu_params(void)
+{
+       int opp = get_opp_offset(DEV_ATTR_MAX_OFFSET, DEV_ATTR_MIN_OFFSET);
+       u32 ind = get_sys_clk_index();
+
+       return &dpll_mpu[ind][opp];
+}
+
+const struct dpll_params *get_dpll_core_params(void)
+{
+       int ind = get_sys_clk_index();
+
+       return &dpll_core[ind];
+}
+
+const struct dpll_params *get_dpll_per_params(void)
+{
+       int ind = get_sys_clk_index();
+
+       return &dpll_per[ind];
 }
 
 void set_uart_mux_conf(void)
index 9268895659376517623eb9c9397bb61fc2d10570..091162ee20ff8ff9b49f571e483d43775e300f2a 100644 (file)
@@ -25,6 +25,9 @@ static char *const am43xx_board_name = (char *)AM4372_BOARD_NAME_START;
 #define HDR_ETH_ALEN           6
 #define HDR_NAME_LEN           8
 
+#define DEV_ATTR_MAX_OFFSET    5
+#define DEV_ATTR_MIN_OFFSET    0
+
 struct am43xx_board_id {
        unsigned int  magic;
        char name[HDR_NAME_LEN];
@@ -46,4 +49,5 @@ static inline int board_is_gpevm(void)
 
 void enable_uart0_pin_mux(void);
 void enable_board_pin_mux(void);
+void enable_i2c0_pin_mux(void);
 #endif
index 46bad0199d896a10e5918bf27dd5a5c31fd407ed..a2d72dde5f56246f028a9dcb77e822207a5f7b36 100644 (file)
@@ -43,3 +43,8 @@ void enable_board_pin_mux(void)
        configure_module_pin_mux(mmc0_pin_mux);
        configure_module_pin_mux(i2c0_pin_mux);
 }
+
+void enable_i2c0_pin_mux(void)
+{
+       configure_module_pin_mux(i2c0_pin_mux);
+}