diff options
author | Lokesh Vutla <lokeshvutla@ti.com> | 2013-12-10 15:02:20 +0530 |
---|---|---|
committer | Tom Rini <trini@ti.com> | 2013-12-18 21:14:01 -0500 |
commit | cf04d0326bd1e24909cfe644c0c8676440a915b1 (patch) | |
tree | b0363c4e98bc6eb2bfe4c5bf5c6ef76f40ccaf36 /board/ti | |
parent | 4892495e368da9462cd5c1c0d6498fe95b45192e (diff) | |
download | u-boot-imx-cf04d0326bd1e24909cfe644c0c8676440a915b1.zip u-boot-imx-cf04d0326bd1e24909cfe644c0c8676440a915b1.tar.gz u-boot-imx-cf04d0326bd1e24909cfe644c0c8676440a915b1.tar.bz2 |
ARM: AM43xx: clocks: Update DPLL details
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>
Diffstat (limited to 'board/ti')
-rw-r--r-- | board/ti/am43xx/board.c | 138 | ||||
-rw-r--r-- | board/ti/am43xx/board.h | 4 | ||||
-rw-r--r-- | board/ti/am43xx/mux.c | 5 |
3 files changed, 144 insertions, 3 deletions
diff --git a/board/ti/am43xx/board.c b/board/ti/am43xx/board.c index 723d0ca..5c92ac7 100644 --- a/board/ti/am43xx/board.c +++ b/board/ti/am43xx/board.c @@ -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) diff --git a/board/ti/am43xx/board.h b/board/ti/am43xx/board.h index 9268895..091162e 100644 --- a/board/ti/am43xx/board.h +++ b/board/ti/am43xx/board.h @@ -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 diff --git a/board/ti/am43xx/mux.c b/board/ti/am43xx/mux.c index 46bad01..a2d72dd 100644 --- a/board/ti/am43xx/mux.c +++ b/board/ti/am43xx/mux.c @@ -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); +} |