summaryrefslogtreecommitdiffstats
path: root/arch/arm/cpu/armv7/omap-common
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/armv7/omap-common')
-rw-r--r--arch/arm/cpu/armv7/omap-common/Makefile1
-rw-r--r--arch/arm/cpu/armv7/omap-common/clocks-common.c99
-rw-r--r--arch/arm/cpu/armv7/omap-common/emif-common.c41
-rw-r--r--arch/arm/cpu/armv7/omap-common/hwinit-common.c16
-rw-r--r--arch/arm/cpu/armv7/omap-common/lowlevel_init.S14
-rw-r--r--arch/arm/cpu/armv7/omap-common/reset.c (renamed from arch/arm/cpu/armv7/omap-common/reset.S)30
-rw-r--r--arch/arm/cpu/armv7/omap-common/spl.c1
-rw-r--r--arch/arm/cpu/armv7/omap-common/spl_mmc.c5
-rw-r--r--arch/arm/cpu/armv7/omap-common/vc.c138
9 files changed, 250 insertions, 95 deletions
diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile
index 447fcd5eff..2a6625f1c4 100644
--- a/arch/arm/cpu/armv7/omap-common/Makefile
+++ b/arch/arm/cpu/armv7/omap-common/Makefile
@@ -37,6 +37,7 @@ ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
COBJS += hwinit-common.o
COBJS += clocks-common.o
COBJS += emif-common.o
+COBJS += vc.o
endif
ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c b/arch/arm/cpu/armv7/omap-common/clocks-common.c
index 4e7456992f..10d286a6d4 100644
--- a/arch/arm/cpu/armv7/omap-common/clocks-common.c
+++ b/arch/arm/cpu/armv7/omap-common/clocks-common.c
@@ -245,6 +245,11 @@ 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();
do_setup_dpll(&prcm->cm_clkmode_dpll_mpu, params, DPLL_LOCK, "mpu");
@@ -360,56 +365,51 @@ static void setup_non_essential_dplls(void)
}
#endif
-void do_scale_tps62361(u32 reg, u32 volt_mv)
+void do_scale_tps62361(int gpio, u32 reg, u32 volt_mv)
{
- u32 temp, step;
+ u32 step;
+ int ret = 0;
+
+ /* See if we can first get the GPIO if needed */
+ if (gpio >= 0)
+ ret = gpio_request(gpio, "TPS62361_VSEL0_GPIO");
+ if (ret < 0) {
+ printf("%s: gpio %d request failed %d\n", __func__, gpio, ret);
+ gpio = -1;
+ }
+
+ /* Pull the GPIO low to select SET0 register, while we program SET1 */
+ if (gpio >= 0)
+ gpio_direction_output(gpio, 0);
step = volt_mv - TPS62361_BASE_VOLT_MV;
step /= 10;
- temp = TPS62361_I2C_SLAVE_ADDR |
- (reg << PRM_VC_VAL_BYPASS_REGADDR_SHIFT) |
- (step << PRM_VC_VAL_BYPASS_DATA_SHIFT) |
- PRM_VC_VAL_BYPASS_VALID_BIT;
debug("do_scale_tps62361: volt - %d step - 0x%x\n", volt_mv, step);
-
- writel(temp, &prcm->prm_vc_val_bypass);
- if (!wait_on_value(PRM_VC_VAL_BYPASS_VALID_BIT, 0,
- &prcm->prm_vc_val_bypass, LDELAY)) {
+ if (omap_vc_bypass_send_value(TPS62361_I2C_SLAVE_ADDR, reg, step))
puts("Scaling voltage failed for vdd_mpu from TPS\n");
- }
+
+ /* Pull the GPIO high to select SET1 register */
+ if (gpio >= 0)
+ gpio_direction_output(gpio, 1);
}
void do_scale_vcore(u32 vcore_reg, u32 volt_mv)
{
- u32 temp, offset_code;
- u32 step = 12660; /* 12.66 mV represented in uV */
+ u32 offset_code;
u32 offset = volt_mv;
/* convert to uV for better accuracy in the calculations */
offset *= 1000;
- if (omap_revision() == OMAP4430_ES1_0)
- offset -= PHOENIX_SMPS_BASE_VOLT_STD_MODE_UV;
- else
- offset -= PHOENIX_SMPS_BASE_VOLT_STD_MODE_WITH_OFFSET_UV;
-
- offset_code = (offset + step - 1) / step;
- /* The code starts at 1 not 0 */
- offset_code++;
+ offset_code = get_offset_code(offset);
debug("do_scale_vcore: volt - %d offset_code - 0x%x\n", volt_mv,
offset_code);
- temp = SMPS_I2C_SLAVE_ADDR |
- (vcore_reg << PRM_VC_VAL_BYPASS_REGADDR_SHIFT) |
- (offset_code << PRM_VC_VAL_BYPASS_DATA_SHIFT) |
- PRM_VC_VAL_BYPASS_VALID_BIT;
- writel(temp, &prcm->prm_vc_val_bypass);
- if (!wait_on_value(PRM_VC_VAL_BYPASS_VALID_BIT, 0,
- &prcm->prm_vc_val_bypass, LDELAY)) {
+ if (omap_vc_bypass_send_value(SMPS_I2C_SLAVE_ADDR,
+ vcore_reg, offset_code))
printf("Scaling voltage failed for 0x%x\n", vcore_reg);
- }
}
static inline void enable_clock_domain(u32 *const clkctrl_reg, u32 enable_mode)
@@ -452,6 +452,7 @@ void freq_update_core(void)
{
u32 freq_config1 = 0;
const struct dpll_params *core_dpll_params;
+ u32 omap_rev = omap_revision();
core_dpll_params = get_core_dpll_params();
/* Put EMIF clock domain in sw wakeup mode */
@@ -477,11 +478,18 @@ void freq_update_core(void)
hang();
}
- /* Put EMIF clock domain back in hw auto mode */
- enable_clock_domain(&prcm->cm_memif_clkstctrl,
- CD_CLKCTRL_CLKTRCTRL_HW_AUTO);
- wait_for_clk_enable(&prcm->cm_memif_emif_1_clkctrl);
- wait_for_clk_enable(&prcm->cm_memif_emif_2_clkctrl);
+ /*
+ * Putting EMIF in HW_AUTO is seen to be causing issues with
+ * EMIF clocks and the master DLL. Put EMIF in SW_WKUP
+ * in OMAP5430 ES1.0 silicon
+ */
+ if (omap_rev != OMAP5430_ES1_0) {
+ /* Put EMIF clock domain back in hw auto mode */
+ enable_clock_domain(&prcm->cm_memif_clkstctrl,
+ CD_CLKCTRL_CLKTRCTRL_HW_AUTO);
+ wait_for_clk_enable(&prcm->cm_memif_emif_1_clkctrl);
+ wait_for_clk_enable(&prcm->cm_memif_emif_2_clkctrl);
+ }
}
void bypass_dpll(u32 *const base)
@@ -529,29 +537,6 @@ void setup_clocks_for_console(void)
CD_CLKCTRL_CLKTRCTRL_SHIFT);
}
-void setup_sri2c(void)
-{
- u32 sys_clk_khz, cycles_hi, cycles_low, temp;
-
- sys_clk_khz = get_sys_clk_freq() / 1000;
-
- /*
- * Setup the dedicated I2C controller for Voltage Control
- * I2C clk - high period 40% low period 60%
- */
- cycles_hi = sys_clk_khz * 4 / PRM_VC_I2C_CHANNEL_FREQ_KHZ / 10;
- cycles_low = sys_clk_khz * 6 / PRM_VC_I2C_CHANNEL_FREQ_KHZ / 10;
- /* values to be set in register - less by 5 & 7 respectively */
- cycles_hi -= 5;
- cycles_low -= 7;
- temp = (cycles_hi << PRM_VC_CFG_I2C_CLK_SCLH_SHIFT) |
- (cycles_low << PRM_VC_CFG_I2C_CLK_SCLL_SHIFT);
- writel(temp, &prcm->prm_vc_cfg_i2c_clk);
-
- /* Disable high speed mode and all advanced features */
- writel(0x0, &prcm->prm_vc_cfg_i2c_mode);
-}
-
void do_enable_clocks(u32 *const *clk_domains,
u32 *const *clk_modules_hw_auto,
u32 *const *clk_modules_explicit_en,
diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c
index 62678ff5d3..db509c9295 100644
--- a/arch/arm/cpu/armv7/omap-common/emif-common.c
+++ b/arch/arm/cpu/armv7/omap-common/emif-common.c
@@ -90,20 +90,33 @@ static void do_lpddr2_init(u32 base, u32 cs)
* tZQINIT = 1 us
* Enough loops assuming a maximum of 2GHz
*/
+
sdelay(2000);
- set_mr(base, cs, LPDDR2_MR1, MR1_BL_8_BT_SEQ_WRAP_EN_NWR_3);
+
+ if (omap_revision() >= OMAP5430_ES1_0)
+ set_mr(base, cs, LPDDR2_MR1, MR1_BL_8_BT_SEQ_WRAP_EN_NWR_8);
+ else
+ set_mr(base, cs, LPDDR2_MR1, MR1_BL_8_BT_SEQ_WRAP_EN_NWR_3);
+
set_mr(base, cs, LPDDR2_MR16, MR16_REF_FULL_ARRAY);
+
/*
* Enable refresh along with writing MR2
* Encoding of RL in MR2 is (RL - 2)
*/
mr_addr = LPDDR2_MR2 | EMIF_REG_REFRESH_EN_MASK;
set_mr(base, cs, mr_addr, RL_FINAL - 2);
+
+ if (omap_revision() >= OMAP5430_ES1_0)
+ set_mr(base, cs, LPDDR2_MR3, 0x1);
}
static void lpddr2_init(u32 base, const struct emif_regs *regs)
{
struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+ u32 *ext_phy_ctrl_base = 0;
+ u32 *emif_ext_phy_ctrl_base = 0;
+ u32 i = 0;
/* Not NVM */
clrbits_le32(&emif->emif_lpddr2_nvm_config, EMIF_REG_CS1NVMEN_MASK);
@@ -119,7 +132,31 @@ static void lpddr2_init(u32 base, const struct emif_regs *regs)
* un-locked frequency & default RL
*/
writel(regs->sdram_config_init, &emif->emif_sdram_config);
- writel(regs->emif_ddr_phy_ctlr_1_init, &emif->emif_ddr_phy_ctrl_1);
+ writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1);
+
+ ext_phy_ctrl_base = (u32 *) &(regs->emif_ddr_ext_phy_ctrl_1);
+ emif_ext_phy_ctrl_base = (u32 *) &(emif->emif_ddr_ext_phy_ctrl_1);
+
+ if (omap_revision() >= OMAP5430_ES1_0) {
+ /* Configure external phy control timing registers */
+ for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) {
+ writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++);
+ /* Update shadow registers */
+ writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++);
+ }
+
+ /*
+ * external phy 6-24 registers do not change with
+ * ddr frequency
+ */
+ for (i = 0; i < EMIF_EXT_PHY_CTRL_CONST_REG; i++) {
+ writel(ext_phy_ctrl_const_base[i],
+ emif_ext_phy_ctrl_base++);
+ /* Update shadow registers */
+ writel(ext_phy_ctrl_const_base[i],
+ emif_ext_phy_ctrl_base++);
+ }
+ }
do_lpddr2_init(base, CS0);
if (regs->sdram_config & EMIF_REG_EBANK_MASK)
diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
index ab46bff5af..cf71ab4443 100644
--- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c
+++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
@@ -203,21 +203,15 @@ int checkboard(void)
}
/*
-* This function is called by start_armboot. You can reliably use static
-* data. Any boot-time function that require static data should be
-* called from here
-*/
-int arch_cpu_init(void)
-{
- return 0;
-}
-
-/*
* get_device_type(): tell if GP/HS/EMU/TST
*/
u32 get_device_type(void)
{
- return 0;
+ struct omap_sys_ctrl_regs *ctrl =
+ (struct omap_sys_ctrl_regs *) SYSCTRL_GENERAL_CORE_BASE;
+
+ return (readl(&ctrl->control_status) &
+ (DEVICE_TYPE_MASK)) >> DEVICE_TYPE_SHIFT;
}
/*
diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
index 35f38acf5d..ccc6bb6b85 100644
--- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
+++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
@@ -27,9 +27,9 @@
*/
#include <asm/arch/omap.h>
+#include <linux/linkage.h>
-.global save_boot_params
-save_boot_params:
+ENTRY(save_boot_params)
/*
* See if the rom code passed pointer is valid:
* It is not valid if it is not in non-secure SRAM
@@ -76,10 +76,9 @@ save_boot_params:
strb r2, [r3, #CH_FLAGS_OFFSET]
1:
bx lr
+ENDPROC(save_boot_params)
-
-.globl lowlevel_init
-lowlevel_init:
+ENTRY(lowlevel_init)
/*
* Setup a temporary stack
*/
@@ -95,12 +94,13 @@ lowlevel_init:
*/
bl s_init
pop {ip, pc}
+ENDPROC(lowlevel_init)
-.globl set_pl310_ctrl_reg
-set_pl310_ctrl_reg:
+ENTRY(set_pl310_ctrl_reg)
PUSH {r4-r11, lr} @ save registers - ROM code may pollute
@ our registers
LDR r12, =0x102 @ Set PL310 control register - value in R0
.word 0xe1600070 @ SMC #0 - hand assembled because -march=armv5
@ call ROM Code API to set control register
POP {r4-r11, pc}
+ENDPROC(set_pl310_ctrl_reg)
diff --git a/arch/arm/cpu/armv7/omap-common/reset.S b/arch/arm/cpu/armv7/omap-common/reset.c
index 838b1221ee..234e90a868 100644
--- a/arch/arm/cpu/armv7/omap-common/reset.S
+++ b/arch/arm/cpu/armv7/omap-common/reset.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 2009 Samsung Electronics.
- * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * Common layer for reset related functionality of OMAP based socs.
+ *
+ * (C) Copyright 2012
+ * Texas Instruments, <www.ti.com>
+ *
+ * Sricharan R <r.sricharan@ti.com>
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -20,19 +25,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
-
#include <config.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <linux/compiler.h>
-.global reset_cpu
-reset_cpu:
- ldr r1, rstctl @ get addr for global reset
- @ reg
- ldr r3, rstbit @ sw reset bit
- str r3, [r1] @ force reset
- mov r0, r0
-_loop_forever:
- b _loop_forever
-rstctl:
- .word PRM_RSTCTRL
-rstbit:
- .word PRM_RSTCTRL_RESET
+void __weak reset_cpu(unsigned long ignored)
+{
+ writel(PRM_RSTCTRL_RESET, PRM_RSTCTRL);
+}
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c
index 0f2e0a2d27..4d1ac85d00 100644
--- a/arch/arm/cpu/armv7/omap-common/spl.c
+++ b/arch/arm/cpu/armv7/omap-common/spl.c
@@ -162,6 +162,7 @@ void board_init_r(gd_t *id, ulong dummy)
#ifdef CONFIG_SPL_MMC_SUPPORT
case BOOT_DEVICE_MMC1:
case BOOT_DEVICE_MMC2:
+ case BOOT_DEVICE_MMC2_2:
spl_mmc_load_image();
break;
#endif
diff --git a/arch/arm/cpu/armv7/omap-common/spl_mmc.c b/arch/arm/cpu/armv7/omap-common/spl_mmc.c
index 6f5b43e559..2f921bb07d 100644
--- a/arch/arm/cpu/armv7/omap-common/spl_mmc.c
+++ b/arch/arm/cpu/armv7/omap-common/spl_mmc.c
@@ -39,10 +39,11 @@ int board_mmc_init(bd_t *bis)
{
switch (omap_boot_device()) {
case BOOT_DEVICE_MMC1:
- omap_mmc_init(0);
+ omap_mmc_init(0, 0, 0);
break;
case BOOT_DEVICE_MMC2:
- omap_mmc_init(1);
+ case BOOT_DEVICE_MMC2_2:
+ omap_mmc_init(1, 0, 0);
break;
}
return 0;
diff --git a/arch/arm/cpu/armv7/omap-common/vc.c b/arch/arm/cpu/armv7/omap-common/vc.c
new file mode 100644
index 0000000000..a045b77180
--- /dev/null
+++ b/arch/arm/cpu/armv7/omap-common/vc.c
@@ -0,0 +1,138 @@
+/*
+ * Voltage Controller implementation for OMAP
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <asm/omap_common.h>
+#include <asm/arch/sys_proto.h>
+
+/*
+ * Define Master code if there are multiple masters on the I2C_SR bus.
+ * Normally not required
+ */
+#ifndef CONFIG_OMAP_VC_I2C_HS_MCODE
+#define CONFIG_OMAP_VC_I2C_HS_MCODE 0x0
+#endif
+
+/* Register defines and masks for VC IP Block */
+/* PRM_VC_CFG_I2C_MODE */
+#define PRM_VC_CFG_I2C_MODE_DFILTEREN_BIT (0x1 << 6)
+#define PRM_VC_CFG_I2C_MODE_SRMODEEN_BIT (0x1 << 4)
+#define PRM_VC_CFG_I2C_MODE_HSMODEEN_BIT (0x1 << 3)
+#define PRM_VC_CFG_I2C_MODE_HSMCODE_SHIFT 0x0
+#define PRM_VC_CFG_I2C_MODE_HSMCODE_MASK 0x3
+
+/* PRM_VC_CFG_I2C_CLK */
+#define PRM_VC_CFG_I2C_CLK_HSCLL_SHIFT 24
+#define PRM_VC_CFG_I2C_CLK_HSCLL_MASK 0xFF
+#define PRM_VC_CFG_I2C_CLK_HSCLH_SHIFT 16
+#define PRM_VC_CFG_I2C_CLK_HSCLH_MASK 0xFF
+#define PRM_VC_CFG_I2C_CLK_SCLH_SHIFT 0
+#define PRM_VC_CFG_I2C_CLK_SCLH_MASK 0xFF
+#define PRM_VC_CFG_I2C_CLK_SCLL_SHIFT 8
+#define PRM_VC_CFG_I2C_CLK_SCLL_MASK (0xFF << 8)
+
+/* PRM_VC_VAL_BYPASS */
+#define PRM_VC_VAL_BYPASS_VALID_BIT (0x1 << 24)
+#define PRM_VC_VAL_BYPASS_SLAVEADDR_SHIFT 0
+#define PRM_VC_VAL_BYPASS_SLAVEADDR_MASK 0x7F
+#define PRM_VC_VAL_BYPASS_REGADDR_SHIFT 8
+#define PRM_VC_VAL_BYPASS_REGADDR_MASK 0xFF
+#define PRM_VC_VAL_BYPASS_DATA_SHIFT 16
+#define PRM_VC_VAL_BYPASS_DATA_MASK 0xFF
+
+/**
+ * omap_vc_init() - Initialization for Voltage controller
+ * @speed_khz: I2C buspeed in KHz
+ */
+void omap_vc_init(u16 speed_khz)
+{
+ u32 val;
+ u32 sys_clk_khz, cycles_hi, cycles_low;
+
+ sys_clk_khz = get_sys_clk_freq() / 1000;
+
+ if (speed_khz > 400) {
+ puts("higher speed requested - throttle to 400Khz\n");
+ speed_khz = 400;
+ }
+
+ /*
+ * Setup the dedicated I2C controller for Voltage Control
+ * I2C clk - high period 40% low period 60%
+ */
+ speed_khz /= 10;
+ cycles_hi = sys_clk_khz * 4 / speed_khz;
+ cycles_low = sys_clk_khz * 6 / speed_khz;
+ /* values to be set in register - less by 5 & 7 respectively */
+ cycles_hi -= 5;
+ cycles_low -= 7;
+ val = (cycles_hi << PRM_VC_CFG_I2C_CLK_SCLH_SHIFT) |
+ (cycles_low << PRM_VC_CFG_I2C_CLK_SCLL_SHIFT);
+ writel(val, &prcm->prm_vc_cfg_i2c_clk);
+
+ val = CONFIG_OMAP_VC_I2C_HS_MCODE <<
+ PRM_VC_CFG_I2C_MODE_HSMCODE_SHIFT;
+ /* No HS mode for now */
+ val &= ~PRM_VC_CFG_I2C_MODE_HSMODEEN_BIT;
+ writel(val, &prcm->prm_vc_cfg_i2c_mode);
+}
+
+/**
+ * omap_vc_bypass_send_value() - Send a data using VC Bypass command
+ * @sa: 7 bit I2C slave address of the PMIC
+ * @reg_addr: I2C register address(8 bit) address in PMIC
+ * @reg_data: what 8 bit data to write
+ */
+int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data)
+{
+ /*
+ * Unfortunately we need to loop here instead of a defined time
+ * use arbitary large value
+ */
+ u32 timeout = 0xFFFF;
+ u32 reg_val;
+
+ sa &= PRM_VC_VAL_BYPASS_SLAVEADDR_MASK;
+ reg_addr &= PRM_VC_VAL_BYPASS_REGADDR_MASK;
+ reg_data &= PRM_VC_VAL_BYPASS_DATA_MASK;
+
+ /* program VC to send data */
+ reg_val = sa << PRM_VC_VAL_BYPASS_SLAVEADDR_SHIFT |
+ reg_addr << PRM_VC_VAL_BYPASS_REGADDR_SHIFT |
+ reg_data << PRM_VC_VAL_BYPASS_DATA_SHIFT;
+ writel(reg_val, &prcm->prm_vc_val_bypass);
+
+ /* Signal VC to send data */
+ writel(reg_val | PRM_VC_VAL_BYPASS_VALID_BIT, &prcm->prm_vc_val_bypass);
+
+ /* Wait on VC to complete transmission */
+ do {
+ reg_val = readl(&prcm->prm_vc_val_bypass) &
+ PRM_VC_VAL_BYPASS_VALID_BIT;
+ if (!reg_val)
+ break;
+
+ sdelay(100);
+ } while (--timeout);
+
+ /* Optional: cleanup PRM_IRQSTATUS_Ax */
+ /* In case we can do something about it in future.. */
+ if (!timeout)
+ return -1;
+
+ /* All good.. */
+ return 0;
+}
OpenPOWER on IntegriCloud