aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaehoon Chung <jh80.chung@samsung.com>2011-05-17 21:19:17 +0000
committerMinkyu Kang <mk7.kang@samsung.com>2011-05-26 19:33:09 +0900
commit68a8cbfad93241387ee1385b9d19e3e2b7919c4e (patch)
tree0d7664d1ddf1e819f58d593815db7a61f0e2f25d
parent5d845f2758d86f9287e2ac3d48fdcbe80ad1d21b (diff)
S5P: add set_mmc_clk for external clock control
This patch added set_mmc_clk for external clock control. c210 didn't support host clock control. So We need external_clock_control function for c210. Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Minkyu Kang <mk7.kang@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
-rw-r--r--arch/arm/cpu/armv7/s5pc1xx/clock.c5
-rw-r--r--arch/arm/cpu/armv7/s5pc2xx/clock.c32
-rw-r--r--arch/arm/include/asm/arch-s5pc1xx/clk.h1
-rw-r--r--arch/arm/include/asm/arch-s5pc1xx/mmc.h1
-rw-r--r--arch/arm/include/asm/arch-s5pc2xx/clk.h1
-rw-r--r--arch/arm/include/asm/arch-s5pc2xx/mmc.h1
-rw-r--r--drivers/mmc/s5p_mmc.c4
7 files changed, 45 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/s5pc1xx/clock.c b/arch/arm/cpu/armv7/s5pc1xx/clock.c
index e92647cdf..1c87e8f8c 100644
--- a/arch/arm/cpu/armv7/s5pc1xx/clock.c
+++ b/arch/arm/cpu/armv7/s5pc1xx/clock.c
@@ -336,3 +336,8 @@ unsigned long get_uart_clk(int dev_index)
{
return s5pc1xx_get_uart_clk(dev_index);
}
+
+void set_mmc_clk(int dev_index, unsigned int div)
+{
+ /* Do NOTHING */
+}
diff --git a/arch/arm/cpu/armv7/s5pc2xx/clock.c b/arch/arm/cpu/armv7/s5pc2xx/clock.c
index 450a63048..624de6257 100644
--- a/arch/arm/cpu/armv7/s5pc2xx/clock.c
+++ b/arch/arm/cpu/armv7/s5pc2xx/clock.c
@@ -199,6 +199,33 @@ static unsigned long s5pc210_get_uart_clk(int dev_index)
return uclk;
}
+/* s5pc210: set the mmc clock */
+static void s5pc210_set_mmc_clk(int dev_index, unsigned int div)
+{
+ struct s5pc210_clock *clk =
+ (struct s5pc210_clock *)samsung_get_base_clock();
+ unsigned int addr;
+ unsigned int val;
+
+ /*
+ * 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;
+ }
+
+ val = readl(addr);
+ val &= ~(0xff << ((dev_index << 4) + 8));
+ val |= (div & 0xff) << ((dev_index << 4) + 8);
+ writel(val, addr);
+}
+
unsigned long get_pll_clk(int pllreg)
{
return s5pc210_get_pll_clk(pllreg);
@@ -218,3 +245,8 @@ unsigned long get_uart_clk(int dev_index)
{
return s5pc210_get_uart_clk(dev_index);
}
+
+void set_mmc_clk(int dev_index, unsigned int div)
+{
+ s5pc210_set_mmc_clk(dev_index, div);
+}
diff --git a/arch/arm/include/asm/arch-s5pc1xx/clk.h b/arch/arm/include/asm/arch-s5pc1xx/clk.h
index 4c389c1fc..692dfe063 100644
--- a/arch/arm/include/asm/arch-s5pc1xx/clk.h
+++ b/arch/arm/include/asm/arch-s5pc1xx/clk.h
@@ -33,5 +33,6 @@ unsigned long get_pll_clk(int pllreg);
unsigned long get_arm_clk(void);
unsigned long get_pwm_clk(void);
unsigned long get_uart_clk(int dev_index);
+void set_mmc_clk(int dev_index, unsigned int div);
#endif
diff --git a/arch/arm/include/asm/arch-s5pc1xx/mmc.h b/arch/arm/include/asm/arch-s5pc1xx/mmc.h
index d458d3bb8..adef4ee21 100644
--- a/arch/arm/include/asm/arch-s5pc1xx/mmc.h
+++ b/arch/arm/include/asm/arch-s5pc1xx/mmc.h
@@ -64,6 +64,7 @@ struct mmc_host {
struct s5p_mmc *reg;
unsigned int version; /* SDHCI spec. version */
unsigned int clock; /* Current clock (MHz) */
+ int dev_index;
};
int s5p_mmc_init(int dev_index, int bus_width);
diff --git a/arch/arm/include/asm/arch-s5pc2xx/clk.h b/arch/arm/include/asm/arch-s5pc2xx/clk.h
index 5a1cdf151..ff0f6415d 100644
--- a/arch/arm/include/asm/arch-s5pc2xx/clk.h
+++ b/arch/arm/include/asm/arch-s5pc2xx/clk.h
@@ -32,5 +32,6 @@ unsigned long get_pll_clk(int pllreg);
unsigned long get_arm_clk(void);
unsigned long get_pwm_clk(void);
unsigned long get_uart_clk(int dev_index);
+void set_mmc_clk(int dev_index, unsigned int div);
#endif
diff --git a/arch/arm/include/asm/arch-s5pc2xx/mmc.h b/arch/arm/include/asm/arch-s5pc2xx/mmc.h
index 04827cad7..30f82b8aa 100644
--- a/arch/arm/include/asm/arch-s5pc2xx/mmc.h
+++ b/arch/arm/include/asm/arch-s5pc2xx/mmc.h
@@ -64,6 +64,7 @@ struct mmc_host {
struct s5p_mmc *reg;
unsigned int version; /* SDHCI spec. version */
unsigned int clock; /* Current clock (MHz) */
+ int dev_index;
};
int s5p_mmc_init(int dev_index, int bus_width);
diff --git a/drivers/mmc/s5p_mmc.c b/drivers/mmc/s5p_mmc.c
index 86447e05b..280738fbf 100644
--- a/drivers/mmc/s5p_mmc.c
+++ b/drivers/mmc/s5p_mmc.c
@@ -22,6 +22,7 @@
#include <mmc.h>
#include <asm/io.h>
#include <asm/arch/mmc.h>
+#include <asm/arch/clk.h>
/* support 4 mmc hosts */
struct mmc mmc_dev[4];
@@ -291,6 +292,8 @@ static void mmc_change_clock(struct mmc_host *host, uint clock)
clk = (div << 8) | (1 << 0);
writew(clk, &host->reg->clkcon);
+ set_mmc_clk(host->dev_index, div);
+
/* Wait max 10 ms */
timeout = 10;
while (!(readw(&host->reg->clkcon) & (1 << 1))) {
@@ -464,6 +467,7 @@ static int s5p_mmc_initialize(int dev_index, int bus_width)
mmc->f_min = 400000;
mmc->f_max = 52000000;
+ mmc_host[dev_index].dev_index = dev_index;
mmc_host[dev_index].clock = 0;
mmc_host[dev_index].reg = s5p_get_base_mmc(dev_index);
mmc->b_max = 0;