summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv7/exynos
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/armv7/exynos')
-rw-r--r--arch/arm/cpu/armv7/exynos/clock.c45
-rw-r--r--arch/arm/cpu/armv7/exynos/lowlevel_init.c8
-rw-r--r--arch/arm/cpu/armv7/exynos/pinmux.c35
-rw-r--r--arch/arm/cpu/armv7/exynos/power.c6
4 files changed, 54 insertions, 40 deletions
diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c
index 1fea4d6..400d134 100644
--- a/arch/arm/cpu/armv7/exynos/clock.c
+++ b/arch/arm/cpu/armv7/exynos/clock.c
@@ -869,7 +869,7 @@ static void exynos4_set_mmc_clk(int dev_index, unsigned int div)
{
struct exynos4_clock *clk =
(struct exynos4_clock *)samsung_get_base_clock();
- unsigned int addr;
+ unsigned int addr, clear_bit, set_bit;
/*
* CLK_DIV_FSYS1
@@ -877,44 +877,26 @@ static void exynos4_set_mmc_clk(int dev_index, unsigned int div)
* CLK_DIV_FSYS2
* MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
* CLK_DIV_FSYS3
- * MMC4_PRE_RATIO [15:8]
+ * MMC4_RATIO [3:0]
*/
if (dev_index < 2) {
addr = (unsigned int)&clk->div_fsys1;
- } else if (dev_index == 4) {
+ clear_bit = MASK_PRE_RATIO(dev_index);
+ set_bit = SET_PRE_RATIO(dev_index, div);
+ } else if (dev_index == 4) {
addr = (unsigned int)&clk->div_fsys3;
dev_index -= 4;
+ /* MMC4 is controlled with the MMC4_RATIO value */
+ clear_bit = MASK_RATIO(dev_index);
+ set_bit = SET_RATIO(dev_index, div);
} else {
addr = (unsigned int)&clk->div_fsys2;
dev_index -= 2;
+ clear_bit = MASK_PRE_RATIO(dev_index);
+ set_bit = SET_PRE_RATIO(dev_index, div);
}
- clrsetbits_le32(addr, 0xff << ((dev_index << 4) + 8),
- (div & 0xff) << ((dev_index << 4) + 8));
-}
-
-/* exynos4x12: set the mmc clock */
-static void exynos4x12_set_mmc_clk(int dev_index, unsigned int div)
-{
- struct exynos4x12_clock *clk =
- (struct exynos4x12_clock *)samsung_get_base_clock();
- unsigned int addr;
-
- /*
- * CLK_DIV_FSYS1
- * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
- * CLK_DIV_FSYS2
- * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
- */
- if (dev_index < 2) {
- addr = (unsigned int)&clk->div_fsys1;
- } else {
- addr = (unsigned int)&clk->div_fsys2;
- dev_index -= 2;
- }
-
- clrsetbits_le32(addr, 0xff << ((dev_index << 4) + 8),
- (div & 0xff) << ((dev_index << 4) + 8));
+ clrsetbits_le32(addr, clear_bit, set_bit);
}
/* exynos5: set the mmc clock */
@@ -1612,10 +1594,7 @@ void set_mmc_clk(int dev_index, unsigned int div)
else
exynos5_set_mmc_clk(dev_index, div);
} else {
- if (proid_is_exynos4412())
- exynos4x12_set_mmc_clk(dev_index, div);
- else
- exynos4_set_mmc_clk(dev_index, div);
+ exynos4_set_mmc_clk(dev_index, div);
}
}
diff --git a/arch/arm/cpu/armv7/exynos/lowlevel_init.c b/arch/arm/cpu/armv7/exynos/lowlevel_init.c
index 11fe5b8..dcc270f 100644
--- a/arch/arm/cpu/armv7/exynos/lowlevel_init.c
+++ b/arch/arm/cpu/armv7/exynos/lowlevel_init.c
@@ -39,6 +39,7 @@ enum {
DO_CLOCKS = 1 << 1,
DO_MEM_RESET = 1 << 2,
DO_UART = 1 << 3,
+ DO_POWER = 1 << 4,
};
int do_lowlevel_init(void)
@@ -48,6 +49,8 @@ int do_lowlevel_init(void)
arch_cpu_init();
+ set_ps_hold_ctrl();
+
reset_status = get_reset_status();
switch (reset_status) {
@@ -60,9 +63,12 @@ int do_lowlevel_init(void)
break;
default:
/* This is a normal boot (not a wake from sleep) */
- actions = DO_CLOCKS | DO_MEM_RESET;
+ actions = DO_CLOCKS | DO_MEM_RESET | DO_POWER;
}
+ if (actions & DO_POWER)
+ set_ps_hold_ctrl();
+
if (actions & DO_CLOCKS) {
system_clock_init();
mem_ctrl_init(actions & DO_MEM_RESET);
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c
index ee7c2e5..86a0c75 100644
--- a/arch/arm/cpu/armv7/exynos/pinmux.c
+++ b/arch/arm/cpu/armv7/exynos/pinmux.c
@@ -573,15 +573,26 @@ static void exynos4_i2c_config(int peripheral, int flags)
static int exynos4_mmc_config(int peripheral, int flags)
{
int i, start = 0, start_ext = 0;
+ unsigned int func, ext_func;
switch (peripheral) {
case PERIPH_ID_SDMMC0:
start = EXYNOS4_GPIO_K00;
start_ext = EXYNOS4_GPIO_K13;
+ func = S5P_GPIO_FUNC(0x2);
+ ext_func = S5P_GPIO_FUNC(0x3);
break;
case PERIPH_ID_SDMMC2:
start = EXYNOS4_GPIO_K20;
start_ext = EXYNOS4_GPIO_K33;
+ func = S5P_GPIO_FUNC(0x2);
+ ext_func = S5P_GPIO_FUNC(0x3);
+ break;
+ case PERIPH_ID_SDMMC4:
+ start = EXYNOS4_GPIO_K00;
+ start_ext = EXYNOS4_GPIO_K13;
+ func = S5P_GPIO_FUNC(0x3);
+ ext_func = S5P_GPIO_FUNC(0x4);
break;
default:
return -1;
@@ -589,13 +600,14 @@ static int exynos4_mmc_config(int peripheral, int flags)
for (i = start; i < (start + 7); i++) {
if (i == (start + 2))
continue;
- gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2));
+ gpio_cfg_pin(i, func);
gpio_set_pull(i, S5P_GPIO_PULL_NONE);
gpio_set_drv(i, S5P_GPIO_DRV_4X);
}
+ /* SDMMC2 do not use 8bit mode at exynos4 */
if (flags & PINMUX_FLAG_8BIT_MODE) {
for (i = start_ext; i < (start_ext + 4); i++) {
- gpio_cfg_pin(i, S5P_GPIO_FUNC(0x3));
+ gpio_cfg_pin(i, ext_func);
gpio_set_pull(i, S5P_GPIO_PULL_NONE);
gpio_set_drv(i, S5P_GPIO_DRV_4X);
}
@@ -676,15 +688,26 @@ static void exynos4x12_i2c_config(int peripheral, int flags)
static int exynos4x12_mmc_config(int peripheral, int flags)
{
int i, start = 0, start_ext = 0;
+ unsigned int func, ext_func;
switch (peripheral) {
case PERIPH_ID_SDMMC0:
start = EXYNOS4X12_GPIO_K00;
start_ext = EXYNOS4X12_GPIO_K13;
+ func = S5P_GPIO_FUNC(0x2);
+ ext_func = S5P_GPIO_FUNC(0x3);
break;
case PERIPH_ID_SDMMC2:
start = EXYNOS4X12_GPIO_K20;
start_ext = EXYNOS4X12_GPIO_K33;
+ func = S5P_GPIO_FUNC(0x2);
+ ext_func = S5P_GPIO_FUNC(0x3);
+ break;
+ case PERIPH_ID_SDMMC4:
+ start = EXYNOS4_GPIO_K00;
+ start_ext = EXYNOS4_GPIO_K13;
+ func = S5P_GPIO_FUNC(0x3);
+ ext_func = S5P_GPIO_FUNC(0x4);
break;
default:
return -1;
@@ -692,13 +715,13 @@ static int exynos4x12_mmc_config(int peripheral, int flags)
for (i = start; i < (start + 7); i++) {
if (i == (start + 2))
continue;
- gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2));
+ gpio_cfg_pin(i, func);
gpio_set_pull(i, S5P_GPIO_PULL_NONE);
gpio_set_drv(i, S5P_GPIO_DRV_4X);
}
if (flags & PINMUX_FLAG_8BIT_MODE) {
for (i = start_ext; i < (start_ext + 4); i++) {
- gpio_cfg_pin(i, S5P_GPIO_FUNC(0x3));
+ gpio_cfg_pin(i, ext_func);
gpio_set_pull(i, S5P_GPIO_PULL_NONE);
gpio_set_drv(i, S5P_GPIO_DRV_4X);
}
@@ -759,10 +782,10 @@ static int exynos4_pinmux_config(int peripheral, int flags)
break;
case PERIPH_ID_SDMMC0:
case PERIPH_ID_SDMMC2:
+ case PERIPH_ID_SDMMC4:
return exynos4_mmc_config(peripheral, flags);
case PERIPH_ID_SDMMC1:
case PERIPH_ID_SDMMC3:
- case PERIPH_ID_SDMMC4:
debug("SDMMC device %d not implemented\n", peripheral);
return -1;
default:
@@ -794,10 +817,10 @@ static int exynos4x12_pinmux_config(int peripheral, int flags)
break;
case PERIPH_ID_SDMMC0:
case PERIPH_ID_SDMMC2:
+ case PERIPH_ID_SDMMC4:
return exynos4x12_mmc_config(peripheral, flags);
case PERIPH_ID_SDMMC1:
case PERIPH_ID_SDMMC3:
- case PERIPH_ID_SDMMC4:
debug("SDMMC device %d not implemented\n", peripheral);
return -1;
default:
diff --git a/arch/arm/cpu/armv7/exynos/power.c b/arch/arm/cpu/armv7/exynos/power.c
index 563abd7..638ee0b 100644
--- a/arch/arm/cpu/armv7/exynos/power.c
+++ b/arch/arm/cpu/armv7/exynos/power.c
@@ -112,6 +112,12 @@ static void exynos5_set_ps_hold_ctrl(void)
EXYNOS_PS_HOLD_CONTROL_DATA_HIGH);
}
+/*
+ * Set ps_hold data driving value high
+ * This enables the machine to stay powered on
+ * after the initial power-on condition goes away
+ * (e.g. power button).
+ */
void set_ps_hold_ctrl(void)
{
if (cpu_is_exynos5())