X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;f=arch%2Farm%2Fcpu%2Farmv7%2Fomap-common%2Fclocks-common.c;h=ab0c5680f546ba3c068a56e21ecd2754df007e21;hb=5a9120439416a9101dec7c7dc65bb75a5ff09c4e;hp=88e5336850cfbab0698ad65a90fbf86b357d8121;hpb=3fcdd4a5f8ba0e0fac4b2afdb5e90efac9f7f301;p=karo-tx-uboot.git diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c b/arch/arm/cpu/armv7/omap-common/clocks-common.c index 88e5336850..ab0c5680f5 100644 --- a/arch/arm/cpu/armv7/omap-common/clocks-common.c +++ b/arch/arm/cpu/armv7/omap-common/clocks-common.c @@ -11,28 +11,13 @@ * Santosh Shilimkar * Rajendra Nayak * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ */ #include +#include #include #include -#include +#include #include #include #include @@ -49,7 +34,7 @@ const u32 sys_clk_array[8] = { 12000000, /* 12 MHz */ - 13000000, /* 13 MHz */ + 20000000, /* 20 MHz */ 16800000, /* 16.8 MHz */ 19200000, /* 19.2 MHz */ 26000000, /* 26 MHz */ @@ -59,7 +44,7 @@ const u32 sys_clk_array[8] = { static inline u32 __get_sys_clk_index(void) { - u32 ind; + s8 ind; /* * For ES1 the ROM code calibration of sys clock is not reliable * due to hw issue. So, use hard-coded value. If this value is not @@ -103,10 +88,14 @@ void setup_post_dividers(u32 const base, const struct dpll_params *params) writel(params->m6_h13, &dpll_regs->cm_div_m6_h13_dpll); if (params->m7_h14 >= 0) writel(params->m7_h14, &dpll_regs->cm_div_m7_h14_dpll); + if (params->h21 >= 0) + writel(params->h21, &dpll_regs->cm_div_h21_dpll); if (params->h22 >= 0) writel(params->h22, &dpll_regs->cm_div_h22_dpll); if (params->h23 >= 0) writel(params->h23, &dpll_regs->cm_div_h23_dpll); + if (params->h24 >= 0) + writel(params->h24, &dpll_regs->cm_div_h24_dpll); } static inline void do_bypass_dpll(u32 const base) @@ -197,12 +186,37 @@ const struct dpll_params *get_abe_dpll_params(struct dplls const *dpll_data) #endif } +static const struct dpll_params *get_ddr_dpll_params + (struct dplls const *dpll_data) +{ + u32 sysclk_ind = get_sys_clk_index(); + + if (!dpll_data->ddr) + return NULL; + return &dpll_data->ddr[sysclk_ind]; +} + +#ifdef CONFIG_DRIVER_TI_CPSW +static const struct dpll_params *get_gmac_dpll_params + (struct dplls const *dpll_data) +{ + u32 sysclk_ind = get_sys_clk_index(); + + if (!dpll_data->gmac) + return NULL; + return &dpll_data->gmac[sysclk_ind]; +} +#endif + static void do_setup_dpll(u32 const base, const struct dpll_params *params, u8 lock, char *dpll) { u32 temp, M, N; struct dpll_regs *const dpll_regs = (struct dpll_regs *)base; + if (!params) + return; + temp = readl(&dpll_regs->cm_clksel_dpll); if (check_for_lock(base)) { @@ -319,11 +333,6 @@ void configure_mpu_dpll(void) CM_CLKSEL_DCC_EN_MASK); } - setbits_le32((*prcm)->cm_mpu_mpu_clkctrl, - MPU_CLKCTRL_CLKSEL_EMIF_DIV_MODE_MASK); - setbits_le32((*prcm)->cm_mpu_mpu_clkctrl, - MPU_CLKCTRL_CLKSEL_ABE_DIV_MODE_MASK); - params = get_mpu_dpll_params(*dplls_data); do_setup_dpll((*prcm)->cm_clkmode_dpll_mpu, params, DPLL_LOCK, "mpu"); @@ -397,6 +406,15 @@ static void setup_dplls(void) #ifdef CONFIG_USB_EHCI_OMAP setup_usb_dpll(); +#endif + params = get_ddr_dpll_params(*dplls_data); + do_setup_dpll((*prcm)->cm_clkmode_dpll_ddrphy, + params, DPLL_LOCK, "ddr"); + +#ifdef CONFIG_DRIVER_TI_CPSW + params = get_gmac_dpll_params(*dplls_data); + do_setup_dpll((*prcm)->cm_clkmode_dpll_gmac, params, + DPLL_LOCK, "gmac"); #endif } @@ -417,6 +435,12 @@ static void setup_non_essential_dplls(void) params = get_abe_dpll_params(*dplls_data); #ifdef CONFIG_SYS_OMAP_ABE_SYSCK abe_ref_clk = CM_ABE_PLL_REF_CLKSEL_CLKSEL_SYSCLK; + + if (omap_revision() == DRA752_ES1_0) + /* Select the sys clk for dpll_abe */ + clrsetbits_le32((*prcm)->cm_abe_pll_sys_clksel, + CM_CLKSEL_ABE_PLL_SYS_CLKSEL_MASK, + CM_ABE_PLL_SYS_CLKSEL_SYSCLK2); #else abe_ref_clk = CM_ABE_PLL_REF_CLKSEL_CLKSEL_32KCLK; /* @@ -464,6 +488,10 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic) u32 offset = volt_mv; int ret = 0; + if (!volt_mv) + return; + + pmic->pmic_bus_init(); /* See if we can first get the GPIO if needed */ if (pmic->gpio_en) ret = gpio_request(pmic->gpio, "PMIC_GPIO"); @@ -486,14 +514,45 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic) debug("do_scale_vcore: volt - %d offset_code - 0x%x\n", volt_mv, offset_code); - if (omap_vc_bypass_send_value(SMPS_I2C_SLAVE_ADDR, - vcore_reg, offset_code)) + if (pmic->pmic_write(pmic->i2c_slave_addr, vcore_reg, offset_code)) printf("Scaling voltage failed for 0x%x\n", vcore_reg); if (pmic->gpio_en) gpio_direction_output(pmic->gpio, 1); } +static u32 optimize_vcore_voltage(struct volts const *v) +{ + u32 val; + if (!v->value) + return 0; + if (!v->efuse.reg) + return v->value; + + switch (v->efuse.reg_bits) { + case 16: + val = readw(v->efuse.reg); + break; + case 32: + val = readl(v->efuse.reg); + break; + default: + printf("Error: efuse 0x%08x bits=%d unknown\n", + v->efuse.reg, v->efuse.reg_bits); + return v->value; + } + + if (!val) { + printf("Error: efuse 0x%08x bits=%d val=0, using %d\n", + v->efuse.reg, v->efuse.reg_bits, v->value); + return v->value; + } + + debug("%s:efuse 0x%08x bits=%d Vnom=%d, using efuse value %d\n", + __func__, v->efuse.reg, v->efuse.reg_bits, v->value, val); + return val; +} + /* * Setup the voltages for vdd_mpu, vdd_core, and vdd_iva * We set the maximum voltages allowed here because Smart-Reflex is not @@ -502,23 +561,34 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic) */ void scale_vcores(struct vcores_data const *vcores) { - omap_vc_init(PRM_VC_I2C_CHANNEL_FREQ_KHZ); + u32 val; - do_scale_vcore(vcores->core.addr, vcores->core.value, - vcores->core.pmic); + val = optimize_vcore_voltage(&vcores->core); + do_scale_vcore(vcores->core.addr, val, vcores->core.pmic); - do_scale_vcore(vcores->mpu.addr, vcores->mpu.value, - vcores->mpu.pmic); + val = optimize_vcore_voltage(&vcores->mpu); + do_scale_vcore(vcores->mpu.addr, val, vcores->mpu.pmic); - do_scale_vcore(vcores->mm.addr, vcores->mm.value, - vcores->mm.pmic); + /* Configure MPU ABB LDO after scale */ + abb_setup((*ctrl)->control_std_fuse_opp_vdd_mpu_2, + (*ctrl)->control_wkup_ldovbb_mpu_voltage_ctrl, + (*prcm)->prm_abbldo_mpu_setup, + (*prcm)->prm_abbldo_mpu_ctrl, + (*prcm)->prm_irqstatus_mpu_2, + OMAP_ABB_MPU_TXDONE_MASK, + OMAP_ABB_FAST_OPP); - if (emif_sdram_type() == EMIF_SDRAM_TYPE_DDR3) { - /* Configure LDO SRAM "magic" bits */ - writel(2, (*prcm)->prm_sldo_core_setup); - writel(2, (*prcm)->prm_sldo_mpu_setup); - writel(2, (*prcm)->prm_sldo_mm_setup); - } + val = optimize_vcore_voltage(&vcores->mm); + do_scale_vcore(vcores->mm.addr, val, vcores->mm.pmic); + + val = optimize_vcore_voltage(&vcores->gpu); + do_scale_vcore(vcores->gpu.addr, val, vcores->gpu.pmic); + + val = optimize_vcore_voltage(&vcores->eve); + do_scale_vcore(vcores->eve.addr, val, vcores->eve.pmic); + + val = optimize_vcore_voltage(&vcores->iva); + do_scale_vcore(vcores->iva.addr, val, vcores->iva.pmic); } static inline void enable_clock_domain(u32 const clkctrl_reg, u32 enable_mode) @@ -589,7 +659,7 @@ void freq_update_core(void) /* * Putting EMIF in HW_AUTO is seen to be causing issues with - * EMIF clocks and the master DLL. Put EMIF in SW_WKUP + * EMIF clocks and the master DLL. Keep EMIF in SW_WKUP * in OMAP5430 ES1.0 silicon */ if (omap_rev != OMAP5430_ES1_0) { @@ -636,7 +706,7 @@ void setup_clocks_for_console(void) MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << MODULE_CLKCTRL_MODULEMODE_SHIFT); - clrsetbits_le32((*prcm)->cm_l4per_uart3_clkctrl, + clrsetbits_le32((*prcm)->cm_l4per_uart4_clkctrl, MODULE_CLKCTRL_MODULEMODE_MASK, MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << MODULE_CLKCTRL_MODULEMODE_SHIFT); @@ -687,12 +757,14 @@ void prcm_init(void) case OMAP_INIT_CONTEXT_UBOOT_FROM_NOR: case OMAP_INIT_CONTEXT_UBOOT_AFTER_CH: enable_basic_clocks(); + timer_init(); scale_vcores(*omap_vcores); setup_dplls(); #ifdef CONFIG_SYS_CLOCKS_ENABLE_ALL setup_non_essential_dplls(); enable_non_essential_clocks(); #endif + setup_warmreset_time(); break; default: break; @@ -701,3 +773,13 @@ void prcm_init(void) if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context()) enable_basic_uboot_clocks(); } + +void gpi2c_init(void) +{ + static int gpi2c = 1; + + if (gpi2c) { + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + gpi2c = 0; + } +}