aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cpu/samsung/exynos5420/clk.h9
-rw-r--r--src/cpu/samsung/exynos5420/clock.c59
-rw-r--r--src/cpu/samsung/exynos5420/pinmux.c2
-rw-r--r--src/mainboard/google/pit/romstage.c9
4 files changed, 64 insertions, 15 deletions
diff --git a/src/cpu/samsung/exynos5420/clk.h b/src/cpu/samsung/exynos5420/clk.h
index 8e2f9edb01..a4e538d370 100644
--- a/src/cpu/samsung/exynos5420/clk.h
+++ b/src/cpu/samsung/exynos5420/clk.h
@@ -86,6 +86,15 @@ unsigned long clock_get_periph_rate(enum periph_id peripheral);
int clock_set_mshci(enum periph_id peripheral);
/*
+ * Set dwmci controller instances clock drivder
+ *
+ * @param enum periph_id instance of the dwmci controller
+ *
+ * Return 0 if ok else -1
+ */
+int clock_set_dwmci(enum periph_id peripheral);
+
+/*
* Sets the epll clockrate
*
* @param rate Required clock rate to the presacaler in Hz
diff --git a/src/cpu/samsung/exynos5420/clock.c b/src/cpu/samsung/exynos5420/clock.c
index 8c4baf8cc7..694f024ca8 100644
--- a/src/cpu/samsung/exynos5420/clock.c
+++ b/src/cpu/samsung/exynos5420/clock.c
@@ -66,6 +66,11 @@ static struct st_epll_con_val epll_div[] = {
{ 180633600, 0, 45, 3, 1, 10381 }
};
+static inline unsigned long div_round_up(unsigned int n, unsigned int d)
+{
+ return (n + d - 1) / d;
+}
+
/* exynos5: return pll clock frequency */
unsigned long get_pll_clk(int pllreg)
{
@@ -177,13 +182,6 @@ unsigned long clock_get_periph_rate(enum periph_id peripheral)
src = readl(&clk->clk_src_isp);
div = readl(&clk->clk_div_isp1);
break;
- case PERIPH_ID_SDMMC0:
- case PERIPH_ID_SDMMC1:
- case PERIPH_ID_SDMMC2:
- case PERIPH_ID_SDMMC3:
- src = readl(&clk->clk_src_fsys);
- div = readl(&clk->clk_div_fsys1);
- break;
case PERIPH_ID_I2C0:
case PERIPH_ID_I2C1:
case PERIPH_ID_I2C2:
@@ -250,6 +248,35 @@ unsigned long get_arm_clk(void)
return armclk;
}
+/* exynos5: get the mmc clock */
+static unsigned long get_mmc_clk(int dev_index)
+{
+ struct exynos5420_clock *clk = samsung_get_base_clock();
+ unsigned long uclk, sclk;
+ unsigned int sel, ratio;
+ int shift = 0;
+
+ sel = readl(&clk->clk_src_fsys);
+ sel = (sel >> ((dev_index * 4) + 8)) & 0x7;
+
+ if (sel == 0x3)
+ sclk = get_pll_clk(MPLL);
+ else if (sel == 0x6)
+ sclk = get_pll_clk(EPLL);
+ else
+ return 0;
+
+ ratio = readl(&clk->clk_div_fsys1);
+
+ shift = dev_index * 10;
+
+ ratio = (ratio >> shift) & 0x3ff;
+ uclk = (sclk / (ratio + 1));
+ printk(BIOS_DEBUG, "%s(%d): %lu\n", __func__, dev_index, uclk);
+
+ return uclk;
+}
+
/* exynos5: set the mmc clock */
void set_mmc_clk(int dev_index, unsigned int div)
{
@@ -266,6 +293,24 @@ void set_mmc_clk(int dev_index, unsigned int div)
writel(val, addr);
}
+/* Set DW MMC Controller clock */
+int clock_set_dwmci(enum periph_id peripheral)
+{
+ /* Request MMC clock value to 52MHz. */
+ const unsigned long freq = 52000000;
+ unsigned long sclk, div;
+ int device_index = (int)peripheral - (int)PERIPH_ID_SDMMC0;
+
+ ASSERT(device_index >= 0 && device_index < 4);
+ sclk = get_mmc_clk(device_index);
+ if (!sclk) {
+ return -1;
+ }
+ div = div_round_up(sclk, freq);
+ set_mmc_clk(device_index, div);
+ return 0;
+}
+
void clock_ll_set_pre_ratio(enum periph_id periph_id, unsigned divisor)
{
struct exynos5420_clock *clk = samsung_get_base_clock();
diff --git a/src/cpu/samsung/exynos5420/pinmux.c b/src/cpu/samsung/exynos5420/pinmux.c
index 566ba606a3..843a6db723 100644
--- a/src/cpu/samsung/exynos5420/pinmux.c
+++ b/src/cpu/samsung/exynos5420/pinmux.c
@@ -80,8 +80,8 @@ static void exynos_pinmux_sdmmc(int start, int start_ext)
void exynos_pinmux_sdmmc0(void)
{
- gpio_set_pull(GPIO_C02, GPIO_PULL_UP);
exynos_pinmux_sdmmc(GPIO_C00, GPIO_C30);
+ gpio_set_pull(GPIO_C02, GPIO_PULL_UP);
}
void exynos_pinmux_sdmmc1(void)
diff --git a/src/mainboard/google/pit/romstage.c b/src/mainboard/google/pit/romstage.c
index 765ff82fa4..7ead3c9353 100644
--- a/src/mainboard/google/pit/romstage.c
+++ b/src/mainboard/google/pit/romstage.c
@@ -113,17 +113,12 @@ static void setup_power(int is_resume)
static void setup_storage(void)
{
/* MMC0: Fixed, 8 bit mode, connected with GPIO. */
- if (clock_set_mshci(PERIPH_ID_SDMMC0))
+ if (clock_set_dwmci(PERIPH_ID_SDMMC0))
printk(BIOS_CRIT, "%s: Failed to set MMC0 clock.\n", __func__);
- if (gpio_direction_output(MMC0_GPIO_PIN, 1)) {
- printk(BIOS_CRIT, "%s: Unable to power on MMC0.\n", __func__);
- }
- gpio_set_pull(MMC0_GPIO_PIN, GPIO_PULL_NONE);
- gpio_set_drv(MMC0_GPIO_PIN, GPIO_DRV_4X);
exynos_pinmux_sdmmc0();
/* MMC2: Removable, 4 bit mode, no GPIO. */
- clock_set_mshci(PERIPH_ID_SDMMC2);
+ clock_set_dwmci(PERIPH_ID_SDMMC2);
exynos_pinmux_sdmmc2();
}