summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv7
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/armv7')
-rw-r--r--arch/arm/cpu/armv7/mx6/Kconfig5
-rw-r--r--arch/arm/cpu/armv7/mx6/clock.c151
-rw-r--r--arch/arm/cpu/armv7/omap-common/clocks-common.c41
-rw-r--r--arch/arm/cpu/armv7/omap5/hw_data.c10
-rw-r--r--arch/arm/cpu/armv7/omap5/prcm-regs.c16
5 files changed, 217 insertions, 6 deletions
diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig
index 1bcd399093..663f970c4c 100644
--- a/arch/arm/cpu/armv7/mx6/Kconfig
+++ b/arch/arm/cpu/armv7/mx6/Kconfig
@@ -136,6 +136,10 @@ config TARGET_OT1200
bool "Bachmann OT1200"
select SUPPORT_SPL
+config TARGET_PICO_IMX6UL
+ bool "PICO-IMX6UL-EMMC"
+ select MX6UL
+
config TARGET_PLATINUM_PICON
bool "platinum-picon"
select SUPPORT_SPL
@@ -200,6 +204,7 @@ source "board/gateworks/gw_ventana/Kconfig"
source "board/kosagi/novena/Kconfig"
source "board/seco/Kconfig"
source "board/solidrun/mx6cuboxi/Kconfig"
+source "board/technexion/pico-imx6ul/Kconfig"
source "board/tbs/tbs2910/Kconfig"
source "board/tqc/tqma6/Kconfig"
source "board/udoo/Kconfig"
diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
index 3b53842e40..e6f227548a 100644
--- a/arch/arm/cpu/armv7/mx6/clock.c
+++ b/arch/arm/cpu/armv7/mx6/clock.c
@@ -1217,6 +1217,157 @@ void enable_ipu_clock(void)
}
}
#endif
+
+#if defined(CONFIG_MX6Q) || defined(CONFIG_MX6D) || defined(CONFIG_MX6DL) || \
+ defined(CONFIG_MX6S)
+static void disable_ldb_di_clock_sources(void)
+{
+ struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+ int reg;
+
+ /* Make sure PFDs are disabled at boot. */
+ reg = readl(&mxc_ccm->analog_pfd_528);
+ /* Cannot disable pll2_pfd2_396M, as it is the MMDC clock in iMX6DL */
+ if (is_cpu_type(MXC_CPU_MX6DL))
+ reg |= 0x80008080;
+ else
+ reg |= 0x80808080;
+ writel(reg, &mxc_ccm->analog_pfd_528);
+
+ /* Disable PLL3 PFDs */
+ reg = readl(&mxc_ccm->analog_pfd_480);
+ reg |= 0x80808080;
+ writel(reg, &mxc_ccm->analog_pfd_480);
+
+ /* Disable PLL5 */
+ reg = readl(&mxc_ccm->analog_pll_video);
+ reg &= ~(1 << 13);
+ writel(reg, &mxc_ccm->analog_pll_video);
+}
+
+static void enable_ldb_di_clock_sources(void)
+{
+ struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+ int reg;
+
+ reg = readl(&mxc_ccm->analog_pfd_528);
+ if (is_cpu_type(MXC_CPU_MX6DL))
+ reg &= ~(0x80008080);
+ else
+ reg &= ~(0x80808080);
+ writel(reg, &mxc_ccm->analog_pfd_528);
+
+ reg = readl(&mxc_ccm->analog_pfd_480);
+ reg &= ~(0x80808080);
+ writel(reg, &mxc_ccm->analog_pfd_480);
+}
+
+/*
+ * Try call this function as early in the boot process as possible since the
+ * function temporarily disables PLL2 PFD's, PLL3 PFD's and PLL5.
+ */
+void select_ldb_di_clock_source(enum ldb_di_clock clk)
+{
+ struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+ int reg;
+
+ /*
+ * Need to follow a strict procedure when changing the LDB
+ * clock, else we can introduce a glitch. Things to keep in
+ * mind:
+ * 1. The current and new parent clocks must be disabled.
+ * 2. The default clock for ldb_dio_clk is mmdc_ch1 which has
+ * no CG bit.
+ * 3. In the RTL implementation of the LDB_DI_CLK_SEL mux
+ * the top four options are in one mux and the PLL3 option along
+ * with another option is in the second mux. There is third mux
+ * used to decide between the first and second mux.
+ * The code below switches the parent to the bottom mux first
+ * and then manipulates the top mux. This ensures that no glitch
+ * will enter the divider.
+ *
+ * Need to disable MMDC_CH1 clock manually as there is no CG bit
+ * for this clock. The only way to disable this clock is to move
+ * it to pll3_sw_clk and then to disable pll3_sw_clk
+ * Make sure periph2_clk2_sel is set to pll3_sw_clk
+ */
+
+ /* Disable all ldb_di clock parents */
+ disable_ldb_di_clock_sources();
+
+ /* Set MMDC_CH1 mask bit */
+ reg = readl(&mxc_ccm->ccdr);
+ reg |= MXC_CCM_CCDR_MMDC_CH1_HS_MASK;
+ writel(reg, &mxc_ccm->ccdr);
+
+ /* Set periph2_clk2_sel to be sourced from PLL3_sw_clk */
+ reg = readl(&mxc_ccm->cbcmr);
+ reg &= ~MXC_CCM_CBCMR_PERIPH2_CLK2_SEL;
+ writel(reg, &mxc_ccm->cbcmr);
+
+ /*
+ * Set the periph2_clk_sel to the top mux so that
+ * mmdc_ch1 is from pll3_sw_clk.
+ */
+ reg = readl(&mxc_ccm->cbcdr);
+ reg |= MXC_CCM_CBCDR_PERIPH2_CLK_SEL;
+ writel(reg, &mxc_ccm->cbcdr);
+
+ /* Wait for the clock switch */
+ while (readl(&mxc_ccm->cdhipr))
+ ;
+ /* Disable pll3_sw_clk by selecting bypass clock source */
+ reg = readl(&mxc_ccm->ccsr);
+ reg |= MXC_CCM_CCSR_PLL3_SW_CLK_SEL;
+ writel(reg, &mxc_ccm->ccsr);
+
+ /* Set the ldb_di0_clk and ldb_di1_clk to 111b */
+ reg = readl(&mxc_ccm->cs2cdr);
+ reg |= ((7 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET)
+ | (7 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET));
+ writel(reg, &mxc_ccm->cs2cdr);
+
+ /* Set the ldb_di0_clk and ldb_di1_clk to 100b */
+ reg = readl(&mxc_ccm->cs2cdr);
+ reg &= ~(MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK
+ | MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK);
+ reg |= ((4 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET)
+ | (4 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET));
+ writel(reg, &mxc_ccm->cs2cdr);
+
+ /* Set the ldb_di0_clk and ldb_di1_clk to desired source */
+ reg = readl(&mxc_ccm->cs2cdr);
+ reg &= ~(MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK
+ | MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK);
+ reg |= ((clk << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET)
+ | (clk << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET));
+ writel(reg, &mxc_ccm->cs2cdr);
+
+ /* Unbypass pll3_sw_clk */
+ reg = readl(&mxc_ccm->ccsr);
+ reg &= ~MXC_CCM_CCSR_PLL3_SW_CLK_SEL;
+ writel(reg, &mxc_ccm->ccsr);
+
+ /*
+ * Set the periph2_clk_sel back to the bottom mux so that
+ * mmdc_ch1 is from its original parent.
+ */
+ reg = readl(&mxc_ccm->cbcdr);
+ reg &= ~MXC_CCM_CBCDR_PERIPH2_CLK_SEL;
+ writel(reg, &mxc_ccm->cbcdr);
+
+ /* Wait for the clock switch */
+ while (readl(&mxc_ccm->cdhipr))
+ ;
+ /* Clear MMDC_CH1 mask bit */
+ reg = readl(&mxc_ccm->ccdr);
+ reg &= ~MXC_CCM_CCDR_MMDC_CH1_HS_MASK;
+ writel(reg, &mxc_ccm->ccdr);
+
+ enable_ldb_di_clock_sources();
+}
+#endif
+
/***************************************************/
U_BOOT_CMD(
diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c b/arch/arm/cpu/armv7/omap-common/clocks-common.c
index cb41055b91..ef2ac98217 100644
--- a/arch/arm/cpu/armv7/omap-common/clocks-common.c
+++ b/arch/arm/cpu/armv7/omap-common/clocks-common.c
@@ -584,22 +584,46 @@ void scale_vcores(struct vcores_data const *vcores)
debug("mpu: %d\n", vcores->mpu.value);
do_scale_vcore(vcores->mpu.addr, vcores->mpu.value, vcores->mpu.pmic);
/* Configure MPU ABB LDO after scale */
- abb_setup((*ctrl)->control_std_fuse_opp_vdd_mpu_2,
+ abb_setup(vcores->mpu.efuse.reg,
(*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,
+ vcores->mpu.abb_tx_done_mask,
OMAP_ABB_FAST_OPP);
/* The .mm member is not used for the DRA7xx */
debug("gpu: %d\n", vcores->gpu.value);
do_scale_vcore(vcores->gpu.addr, vcores->gpu.value, vcores->gpu.pmic);
+ /* Configure GPU ABB LDO after scale */
+ abb_setup(vcores->gpu.efuse.reg,
+ (*ctrl)->control_wkup_ldovbb_gpu_voltage_ctrl,
+ (*prcm)->prm_abbldo_gpu_setup,
+ (*prcm)->prm_abbldo_gpu_ctrl,
+ (*prcm)->prm_irqstatus_mpu,
+ vcores->gpu.abb_tx_done_mask,
+ OMAP_ABB_FAST_OPP);
debug("eve: %d\n", vcores->eve.value);
do_scale_vcore(vcores->eve.addr, vcores->eve.value, vcores->eve.pmic);
+ /* Configure EVE ABB LDO after scale */
+ abb_setup(vcores->eve.efuse.reg,
+ (*ctrl)->control_wkup_ldovbb_eve_voltage_ctrl,
+ (*prcm)->prm_abbldo_eve_setup,
+ (*prcm)->prm_abbldo_eve_ctrl,
+ (*prcm)->prm_irqstatus_mpu,
+ vcores->eve.abb_tx_done_mask,
+ OMAP_ABB_FAST_OPP);
debug("iva: %d\n", vcores->iva.value);
do_scale_vcore(vcores->iva.addr, vcores->iva.value, vcores->iva.pmic);
+ /* Configure IVA ABB LDO after scale */
+ abb_setup(vcores->iva.efuse.reg,
+ (*ctrl)->control_wkup_ldovbb_iva_voltage_ctrl,
+ (*prcm)->prm_abbldo_iva_setup,
+ (*prcm)->prm_abbldo_iva_ctrl,
+ (*prcm)->prm_irqstatus_mpu,
+ vcores->iva.abb_tx_done_mask,
+ OMAP_ABB_FAST_OPP);
/* Might need udelay(1000) here if debug is enabled to see all prints */
#else
u32 val;
@@ -621,17 +645,26 @@ void scale_vcores(struct vcores_data const *vcores)
do_scale_vcore(vcores->mpu.addr, val, vcores->mpu.pmic);
/* Configure MPU ABB LDO after scale */
- abb_setup((*ctrl)->control_std_fuse_opp_vdd_mpu_2,
+ abb_setup(vcores->mpu.efuse.reg,
(*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,
+ vcores->mpu.abb_tx_done_mask,
OMAP_ABB_FAST_OPP);
val = optimize_vcore_voltage(&vcores->mm);
do_scale_vcore(vcores->mm.addr, val, vcores->mm.pmic);
+ /* Configure MM ABB LDO after scale */
+ abb_setup(vcores->mm.efuse.reg,
+ (*ctrl)->control_wkup_ldovbb_mm_voltage_ctrl,
+ (*prcm)->prm_abbldo_mm_setup,
+ (*prcm)->prm_abbldo_mm_ctrl,
+ (*prcm)->prm_irqstatus_mpu,
+ vcores->mm.abb_tx_done_mask,
+ OMAP_ABB_FAST_OPP);
+
val = optimize_vcore_voltage(&vcores->gpu);
do_scale_vcore(vcores->gpu.addr, val, vcores->gpu.pmic);
diff --git a/arch/arm/cpu/armv7/omap5/hw_data.c b/arch/arm/cpu/armv7/omap5/hw_data.c
index b69c0d1371..88e8920bad 100644
--- a/arch/arm/cpu/armv7/omap5/hw_data.c
+++ b/arch/arm/cpu/armv7/omap5/hw_data.c
@@ -352,6 +352,7 @@ struct vcores_data omap5430_volts_es2 = {
.mpu.value = VDD_MPU_ES2,
.mpu.addr = SMPS_REG_ADDR_12_MPU,
.mpu.pmic = &palmas,
+ .mpu.abb_tx_done_mask = OMAP_ABB_MPU_TXDONE_MASK,
.core.value = VDD_CORE_ES2,
.core.addr = SMPS_REG_ADDR_8_CORE,
@@ -360,6 +361,7 @@ struct vcores_data omap5430_volts_es2 = {
.mm.value = VDD_MM_ES2,
.mm.addr = SMPS_REG_ADDR_45_IVA,
.mm.pmic = &palmas,
+ .mm.abb_tx_done_mask = OMAP_ABB_MM_TXDONE_MASK,
};
struct vcores_data dra752_volts = {
@@ -368,18 +370,21 @@ struct vcores_data dra752_volts = {
.mpu.efuse.reg_bits = DRA752_EFUSE_REGBITS,
.mpu.addr = TPS659038_REG_ADDR_SMPS12,
.mpu.pmic = &tps659038,
+ .mpu.abb_tx_done_mask = OMAP_ABB_MPU_TXDONE_MASK,
.eve.value = VDD_EVE_DRA752,
.eve.efuse.reg = STD_FUSE_OPP_VMIN_DSPEVE_NOM,
.eve.efuse.reg_bits = DRA752_EFUSE_REGBITS,
.eve.addr = TPS659038_REG_ADDR_SMPS45,
.eve.pmic = &tps659038,
+ .eve.abb_tx_done_mask = OMAP_ABB_EVE_TXDONE_MASK,
.gpu.value = VDD_GPU_DRA752,
.gpu.efuse.reg = STD_FUSE_OPP_VMIN_GPU_NOM,
.gpu.efuse.reg_bits = DRA752_EFUSE_REGBITS,
.gpu.addr = TPS659038_REG_ADDR_SMPS6,
.gpu.pmic = &tps659038,
+ .gpu.abb_tx_done_mask = OMAP_ABB_GPU_TXDONE_MASK,
.core.value = VDD_CORE_DRA752,
.core.efuse.reg = STD_FUSE_OPP_VMIN_CORE_NOM,
@@ -392,6 +397,7 @@ struct vcores_data dra752_volts = {
.iva.efuse.reg_bits = DRA752_EFUSE_REGBITS,
.iva.addr = TPS659038_REG_ADDR_SMPS8,
.iva.pmic = &tps659038,
+ .iva.abb_tx_done_mask = OMAP_ABB_IVA_TXDONE_MASK,
};
struct vcores_data dra722_volts = {
@@ -400,6 +406,7 @@ struct vcores_data dra722_volts = {
.mpu.efuse.reg_bits = DRA752_EFUSE_REGBITS,
.mpu.addr = TPS65917_REG_ADDR_SMPS1,
.mpu.pmic = &tps659038,
+ .mpu.abb_tx_done_mask = OMAP_ABB_MPU_TXDONE_MASK,
.core.value = VDD_CORE_DRA72x,
.core.efuse.reg = STD_FUSE_OPP_VMIN_CORE_NOM,
@@ -416,18 +423,21 @@ struct vcores_data dra722_volts = {
.gpu.efuse.reg_bits = DRA752_EFUSE_REGBITS,
.gpu.addr = TPS65917_REG_ADDR_SMPS3,
.gpu.pmic = &tps659038,
+ .gpu.abb_tx_done_mask = OMAP_ABB_GPU_TXDONE_MASK,
.eve.value = VDD_EVE_DRA72x,
.eve.efuse.reg = STD_FUSE_OPP_VMIN_DSPEVE_NOM,
.eve.efuse.reg_bits = DRA752_EFUSE_REGBITS,
.eve.addr = TPS65917_REG_ADDR_SMPS3,
.eve.pmic = &tps659038,
+ .eve.abb_tx_done_mask = OMAP_ABB_EVE_TXDONE_MASK,
.iva.value = VDD_IVA_DRA72x,
.iva.efuse.reg = STD_FUSE_OPP_VMIN_IVA_NOM,
.iva.efuse.reg_bits = DRA752_EFUSE_REGBITS,
.iva.addr = TPS65917_REG_ADDR_SMPS3,
.iva.pmic = &tps659038,
+ .iva.abb_tx_done_mask = OMAP_ABB_IVA_TXDONE_MASK,
};
/*
diff --git a/arch/arm/cpu/armv7/omap5/prcm-regs.c b/arch/arm/cpu/armv7/omap5/prcm-regs.c
index cd289ddd2b..655e92ba27 100644
--- a/arch/arm/cpu/armv7/omap5/prcm-regs.c
+++ b/arch/arm/cpu/armv7/omap5/prcm-regs.c
@@ -297,7 +297,6 @@ struct prcm_regs const omap5_es1_prcm = {
struct omap_sys_ctrl_regs const omap5_ctrl = {
.control_status = 0x4A002134,
- .control_std_fuse_opp_vdd_mpu_2 = 0x4A0021B4,
.control_std_fuse_die_id_0 = 0x4A002200,
.control_std_fuse_die_id_1 = 0x4A002208,
.control_std_fuse_die_id_2 = 0x4A00220C,
@@ -353,6 +352,7 @@ struct omap_sys_ctrl_regs const omap5_ctrl = {
.control_emif1_sdram_config_ext = 0x4AE0C144,
.control_emif2_sdram_config_ext = 0x4AE0C148,
.control_wkup_ldovbb_mpu_voltage_ctrl = 0x4AE0C318,
+ .control_wkup_ldovbb_mm_voltage_ctrl = 0x4AE0C314,
.control_padconf_wkup_base = 0x4AE0C800,
.control_smart1nopmio_padconf_0 = 0x4AE0CDA0,
.control_smart1nopmio_padconf_1 = 0x4AE0CDA4,
@@ -440,13 +440,15 @@ struct omap_sys_ctrl_regs const dra7xx_ctrl = {
.control_srcomp_code_latch = 0x4A002E84,
.control_ddr_control_ext_0 = 0x4A002E88,
.control_padconf_core_base = 0x4A003400,
- .control_std_fuse_opp_vdd_mpu_2 = 0x4A003B20,
.control_port_emif1_sdram_config = 0x4AE0C110,
.control_port_emif1_lpddr2_nvm_config = 0x4AE0C114,
.control_port_emif2_sdram_config = 0x4AE0C118,
.control_emif1_sdram_config_ext = 0x4AE0C144,
.control_emif2_sdram_config_ext = 0x4AE0C148,
.control_wkup_ldovbb_mpu_voltage_ctrl = 0x4AE0C158,
+ .control_wkup_ldovbb_iva_voltage_ctrl = 0x4A002470,
+ .control_wkup_ldovbb_eve_voltage_ctrl = 0x4A00246C,
+ .control_wkup_ldovbb_gpu_voltage_ctrl = 0x4AE0C154,
.control_std_fuse_die_id_0 = 0x4AE0C200,
.control_std_fuse_die_id_1 = 0x4AE0C208,
.control_std_fuse_die_id_2 = 0x4AE0C20C,
@@ -724,6 +726,7 @@ struct prcm_regs const omap5_es2_prcm = {
.cm_l3init_usb_otg_ss1_clkctrl = 0x4a0096f0,
/* prm irqstatus regs */
+ .prm_irqstatus_mpu = 0x4ae06010,
.prm_irqstatus_mpu_2 = 0x4ae06014,
/* l4 wkup regs */
@@ -753,6 +756,8 @@ struct prcm_regs const omap5_es2_prcm = {
.prm_abbldo_mpu_setup = 0x4ae07cdc,
.prm_abbldo_mpu_ctrl = 0x4ae07ce0,
+ .prm_abbldo_mm_setup = 0x4ae07ce4,
+ .prm_abbldo_mm_ctrl = 0x4ae07ce8,
/* SCRM stuff, used by some boards */
.scrm_auxclk0 = 0x4ae0a310,
@@ -829,6 +834,7 @@ struct prcm_regs const dra7xx_prcm = {
.cm_ipu_i2c5_clkctrl = 0x4a005578,
/* prm irqstatus regs */
+ .prm_irqstatus_mpu = 0x4ae06010,
.prm_irqstatus_mpu_2 = 0x4ae06014,
/* cm2.ckgen */
@@ -997,6 +1003,12 @@ struct prcm_regs const dra7xx_prcm = {
.prm_abbldo_mpu_setup = 0x4AE07DDC,
.prm_abbldo_mpu_ctrl = 0x4AE07DE0,
+ .prm_abbldo_iva_setup = 0x4AE07E34,
+ .prm_abbldo_iva_ctrl = 0x4AE07E24,
+ .prm_abbldo_eve_setup = 0x4AE07E30,
+ .prm_abbldo_eve_ctrl = 0x4AE07E20,
+ .prm_abbldo_gpu_setup = 0x4AE07DE4,
+ .prm_abbldo_gpu_ctrl = 0x4AE07DE8,
/*l3main1 edma*/
.cm_l3main1_tptc1_clkctrl = 0x4a008778,