diff options
Diffstat (limited to 'arch/arm/cpu/armv7/exynos')
-rw-r--r-- | arch/arm/cpu/armv7/exynos/clock.c | 139 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/exynos/pinmux.c | 22 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/exynos/power.c | 21 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/exynos/soc.c | 8 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/exynos/system.c | 18 |
5 files changed, 196 insertions, 12 deletions
diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index f7829b2cc7..4f3b451be9 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -98,7 +98,7 @@ static unsigned long exynos5_get_pll_clk(int pllreg) struct exynos5_clock *clk = (struct exynos5_clock *)samsung_get_base_clock(); unsigned long r, m, p, s, k = 0, mask, fout; - unsigned int freq; + unsigned int freq, pll_div2_sel, fout_sel; switch (pllreg) { case APLL: @@ -115,6 +115,9 @@ static unsigned long exynos5_get_pll_clk(int pllreg) r = readl(&clk->vpll_con0); k = readl(&clk->vpll_con1); break; + case BPLL: + r = readl(&clk->bpll_con0); + break; default: printf("Unsupported PLL (%d)\n", pllreg); return 0; @@ -125,8 +128,9 @@ static unsigned long exynos5_get_pll_clk(int pllreg) * MPLL_CON: MIDV [25:16] * EPLL_CON: MIDV [24:16] * VPLL_CON: MIDV [24:16] + * BPLL_CON: MIDV [25:16] */ - if (pllreg == APLL || pllreg == MPLL) + if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL) mask = 0x3ff; else mask = 0x1ff; @@ -155,6 +159,29 @@ static unsigned long exynos5_get_pll_clk(int pllreg) fout = m * (freq / (p * (1 << (s - 1)))); } + /* According to the user manual, in EVT1 MPLL and BPLL always gives + * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/ + if (pllreg == MPLL || pllreg == BPLL) { + pll_div2_sel = readl(&clk->pll_div2_sel); + + switch (pllreg) { + case MPLL: + fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT) + & MPLL_FOUT_SEL_MASK; + break; + case BPLL: + fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT) + & BPLL_FOUT_SEL_MASK; + break; + default: + fout_sel = -1; + break; + } + + if (fout_sel == 0) + fout /= 2; + } + return fout; } @@ -456,6 +483,48 @@ static unsigned long exynos4_get_lcd_clk(void) return pclk; } +/* get_lcd_clk: return lcd clock frequency */ +static unsigned long exynos5_get_lcd_clk(void) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + unsigned long pclk, sclk; + unsigned int sel; + unsigned int ratio; + + /* + * CLK_SRC_LCD0 + * FIMD0_SEL [3:0] + */ + sel = readl(&clk->src_disp1_0); + sel = sel & 0xf; + + /* + * 0x6: SCLK_MPLL + * 0x7: SCLK_EPLL + * 0x8: SCLK_VPLL + */ + if (sel == 0x6) + sclk = get_pll_clk(MPLL); + else if (sel == 0x7) + sclk = get_pll_clk(EPLL); + else if (sel == 0x8) + sclk = get_pll_clk(VPLL); + else + return 0; + + /* + * CLK_DIV_LCD0 + * FIMD0_RATIO [3:0] + */ + ratio = readl(&clk->div_disp1_0); + ratio = ratio & 0xf; + + pclk = sclk / (ratio + 1); + + return pclk; +} + void exynos4_set_lcd_clk(void) { struct exynos4_clock *clk = @@ -518,6 +587,68 @@ void exynos4_set_lcd_clk(void) writel(cfg, &clk->div_lcd0); } +void exynos5_set_lcd_clk(void) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + unsigned int cfg = 0; + + /* + * CLK_GATE_BLOCK + * CLK_CAM [0] + * CLK_TV [1] + * CLK_MFC [2] + * CLK_G3D [3] + * CLK_LCD0 [4] + * CLK_LCD1 [5] + * CLK_GPS [7] + */ + cfg = readl(&clk->gate_block); + cfg |= 1 << 4; + writel(cfg, &clk->gate_block); + + /* + * CLK_SRC_LCD0 + * FIMD0_SEL [3:0] + * MDNIE0_SEL [7:4] + * MDNIE_PWM0_SEL [8:11] + * MIPI0_SEL [12:15] + * set lcd0 src clock 0x6: SCLK_MPLL + */ + cfg = readl(&clk->src_disp1_0); + cfg &= ~(0xf); + cfg |= 0x8; + writel(cfg, &clk->src_disp1_0); + + /* + * CLK_GATE_IP_LCD0 + * CLK_FIMD0 [0] + * CLK_MIE0 [1] + * CLK_MDNIE0 [2] + * CLK_DSIM0 [3] + * CLK_SMMUFIMD0 [4] + * CLK_PPMULCD0 [5] + * Gating all clocks for FIMD0 + */ + cfg = readl(&clk->gate_ip_disp1); + cfg |= 1 << 0; + writel(cfg, &clk->gate_ip_disp1); + + /* + * CLK_DIV_LCD0 + * FIMD0_RATIO [3:0] + * MDNIE0_RATIO [7:4] + * MDNIE_PWM0_RATIO [11:8] + * MDNIE_PWM_PRE_RATIO [15:12] + * MIPI0_RATIO [19:16] + * MIPI0_PRE_RATIO [23:20] + * set fimd ratio + */ + cfg &= ~(0xf); + cfg |= 0x0; + writel(cfg, &clk->div_disp1_0); +} + void exynos4_set_mipi_clk(void) { struct exynos4_clock *clk = @@ -656,13 +787,15 @@ unsigned long get_lcd_clk(void) if (cpu_is_exynos4()) return exynos4_get_lcd_clk(); else - return 0; + return exynos5_get_lcd_clk(); } void set_lcd_clk(void) { if (cpu_is_exynos4()) exynos4_set_lcd_clk(); + else + exynos5_set_lcd_clk(); } void set_mipi_clk(void) diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index d28f05557f..7776add9db 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -40,8 +40,8 @@ static void exynos5_uart_config(int peripheral) count = 4; break; case PERIPH_ID_UART1: - bank = &gpio1->a0; - start = 4; + bank = &gpio1->d0; + start = 0; count = 4; break; case PERIPH_ID_UART2: @@ -66,23 +66,27 @@ static int exynos5_mmc_config(int peripheral, int flags) struct exynos5_gpio_part1 *gpio1 = (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); struct s5p_gpio_bank *bank, *bank_ext; - int i; + int i, start = 0, gpio_func = 0; switch (peripheral) { case PERIPH_ID_SDMMC0: bank = &gpio1->c0; bank_ext = &gpio1->c1; + start = 0; + gpio_func = GPIO_FUNC(0x2); break; case PERIPH_ID_SDMMC1: - bank = &gpio1->c1; + bank = &gpio1->c2; bank_ext = NULL; break; case PERIPH_ID_SDMMC2: - bank = &gpio1->c2; - bank_ext = &gpio1->c3; + bank = &gpio1->c3; + bank_ext = &gpio1->c4; + start = 3; + gpio_func = GPIO_FUNC(0x3); break; case PERIPH_ID_SDMMC3: - bank = &gpio1->c3; + bank = &gpio1->c4; bank_ext = NULL; break; } @@ -92,8 +96,8 @@ static int exynos5_mmc_config(int peripheral, int flags) return -1; } if (flags & PINMUX_FLAG_8BIT_MODE) { - for (i = 3; i <= 6; i++) { - s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x3)); + for (i = start; i <= (start + 3); i++) { + s5p_gpio_cfg_pin(bank_ext, i, gpio_func); s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP); s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X); } diff --git a/arch/arm/cpu/armv7/exynos/power.c b/arch/arm/cpu/armv7/exynos/power.c index 4116781a36..d4bce6d4dd 100644 --- a/arch/arm/cpu/armv7/exynos/power.c +++ b/arch/arm/cpu/armv7/exynos/power.c @@ -74,3 +74,24 @@ void set_usbhost_phy_ctrl(unsigned int enable) if (cpu_is_exynos5()) exynos5_set_usbhost_phy_ctrl(enable); } + +static void exynos5_dp_phy_control(unsigned int enable) +{ + unsigned int cfg; + struct exynos5_power *power = + (struct exynos5_power *)samsung_get_base_power(); + + cfg = readl(&power->dptx_phy_control); + if (enable) + cfg |= EXYNOS_DP_PHY_ENABLE; + else + cfg &= ~EXYNOS_DP_PHY_ENABLE; + + writel(cfg, &power->dptx_phy_control); +} + +void set_dp_phy_ctrl(unsigned int enable) +{ + if (cpu_is_exynos5()) + exynos5_dp_phy_control(enable); +} diff --git a/arch/arm/cpu/armv7/exynos/soc.c b/arch/arm/cpu/armv7/exynos/soc.c index dcfcec22dc..ab65b8d3a8 100644 --- a/arch/arm/cpu/armv7/exynos/soc.c +++ b/arch/arm/cpu/armv7/exynos/soc.c @@ -28,3 +28,11 @@ void reset_cpu(ulong addr) { writel(0x1, samsung_get_base_swreset()); } + +#ifndef CONFIG_SYS_DCACHE_OFF +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} +#endif diff --git a/arch/arm/cpu/armv7/exynos/system.c b/arch/arm/cpu/armv7/exynos/system.c index 4426611d1b..8424c57e95 100644 --- a/arch/arm/cpu/armv7/exynos/system.c +++ b/arch/arm/cpu/armv7/exynos/system.c @@ -62,8 +62,26 @@ static void exynos4_set_system_display(void) writel(cfg, &sysreg->display_ctrl); } +static void exynos5_set_system_display(void) +{ + struct exynos5_sysreg *sysreg = + (struct exynos5_sysreg *)samsung_get_base_sysreg(); + unsigned int cfg = 0; + + /* + * system register path set + * 0: MIE/MDNIE + * 1: FIMD Bypass + */ + cfg = readl(&sysreg->disp1blk_cfg); + cfg |= (1 << 15); + writel(cfg, &sysreg->disp1blk_cfg); +} + void set_system_display_ctrl(void) { if (cpu_is_exynos4()) exynos4_set_system_display(); + else + exynos5_set_system_display(); } |