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 f7829b2cc..4f3b451be 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 d28f05557..7776add9d 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 4116781a3..d4bce6d4d 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 dcfcec22d..ab65b8d3a 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 4426611d1..8424c57e9 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();  } |