aboutsummaryrefslogtreecommitdiff
path: root/src/cpu/samsung/exynos5420/clock.c
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2013-06-18 06:08:42 -0700
committerStefan Reinauer <stefan.reinauer@coreboot.org>2013-07-10 22:32:00 +0200
commitc883fdc964207d3871e8609c67988c07d448a87d (patch)
treed9fb63c0cb91bc94b12ccce291d70f30ce46b97c /src/cpu/samsung/exynos5420/clock.c
parente6af9296619a8bc1abe0c19268c9d961bf73843f (diff)
exynox5420: Remove the 5250 clock registers and fix the SPI frequency.
The 5420 clock code still had a data structure in it for the 5250 clock registers which was used by some of the clock functions. That caused some clocks to be configured incorrectly, specifically the i2c clock which was running at about 80KHz instead of about 600KHz as configured by U-Boot. Also, the registers and bit positions used to set up the SPI bus were not consistent with U-Boot, and if the bus clock rate were set to 50MHz, a rate which has historically worked on snow, loading would fail. With these fixes the clock rate can be set to 50MHz and the device boots as much as is expected. I haven't yet measured the actual frequency of the bus to verify that it's now being calculated correctly. Change-Id: Id53448fcb6d186bddb3f889c84ba267135dfbc00 Signed-off-by: Gabe Black <gabeblack@chromium.org> Reviewed-on: http://review.coreboot.org/3678 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/cpu/samsung/exynos5420/clock.c')
-rw-r--r--src/cpu/samsung/exynos5420/clock.c104
1 files changed, 48 insertions, 56 deletions
diff --git a/src/cpu/samsung/exynos5420/clock.c b/src/cpu/samsung/exynos5420/clock.c
index 8799149627..e5ab001374 100644
--- a/src/cpu/samsung/exynos5420/clock.c
+++ b/src/cpu/samsung/exynos5420/clock.c
@@ -69,8 +69,7 @@ static struct st_epll_con_val epll_div[] = {
/* exynos5: return pll clock frequency */
unsigned long get_pll_clk(int pllreg)
{
- struct exynos5420_clock *clk =
- (struct exynos5420_clock *)samsung_get_base_clock();
+ struct exynos5420_clock *clk = samsung_get_base_clock();
unsigned long r, m, p, s, k = 0, mask, fout;
unsigned int freq;
@@ -146,44 +145,44 @@ unsigned long clock_get_periph_rate(enum periph_id peripheral)
struct clk_bit_info *bit_info = &clk_bit_info[peripheral];
unsigned long sclk, sub_clk;
unsigned int src, div, sub_div;
- struct exynos5_clock *clk = samsung_get_base_clock();
+ struct exynos5420_clock *clk = samsung_get_base_clock();
switch (peripheral) {
case PERIPH_ID_UART0:
case PERIPH_ID_UART1:
case PERIPH_ID_UART2:
case PERIPH_ID_UART3:
- src = readl(&clk->src_peric0);
- div = readl(&clk->div_peric0);
+ src = readl(&clk->clk_src_peric0);
+ div = readl(&clk->clk_div_peric0);
break;
case PERIPH_ID_PWM0:
case PERIPH_ID_PWM1:
case PERIPH_ID_PWM2:
case PERIPH_ID_PWM3:
case PERIPH_ID_PWM4:
- src = readl(&clk->src_peric0);
- div = readl(&clk->div_peric3);
+ src = readl(&clk->clk_src_peric0);
+ div = readl(&clk->clk_div_peric3);
break;
case PERIPH_ID_SPI0:
case PERIPH_ID_SPI1:
- src = readl(&clk->src_peric1);
- div = readl(&clk->div_peric1);
+ src = readl(&clk->clk_src_peric1);
+ div = readl(&clk->clk_div_peric1);
break;
case PERIPH_ID_SPI2:
- src = readl(&clk->src_peric1);
- div = readl(&clk->div_peric2);
+ src = readl(&clk->clk_src_peric1);
+ div = readl(&clk->clk_div_peric2);
break;
case PERIPH_ID_SPI3:
case PERIPH_ID_SPI4:
- src = readl(&clk->sclk_src_isp);
- div = readl(&clk->sclk_div_isp);
+ 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->src_fsys);
- div = readl(&clk->div_fsys1);
+ src = readl(&clk->clk_src_fsys);
+ div = readl(&clk->clk_div_fsys1);
break;
case PERIPH_ID_I2C0:
case PERIPH_ID_I2C1:
@@ -197,8 +196,8 @@ unsigned long clock_get_periph_rate(enum periph_id peripheral)
case PERIPH_ID_I2C9:
case PERIPH_ID_I2C10:
sclk = get_pll_clk(MPLL);
- sub_div = ((readl(&clk->div_top1) >> 24) & 0x7) + 1;
- div = (readl(&clk->div_top0) & 0x7) + 1;
+ sub_div = ((readl(&clk->clk_div_top1) >> 24) & 0x7) + 1;
+ div = (readl(&clk->clk_div_top0) & 0x7) + 1;
return (sclk / sub_div) / div;
default:
printk(BIOS_DEBUG, "%s: invalid peripheral %d", __func__, peripheral);
@@ -234,13 +233,13 @@ unsigned long clock_get_periph_rate(enum periph_id peripheral)
/* exynos5: return ARM clock frequency */
unsigned long get_arm_clk(void)
{
- struct exynos5_clock *clk = samsung_get_base_clock();
+ struct exynos5420_clock *clk = samsung_get_base_clock();
unsigned long div;
unsigned long armclk;
unsigned int arm_ratio;
unsigned int arm2_ratio;
- div = readl(&clk->div_cpu0);
+ div = readl(&clk->clk_div_cpu0);
/* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */
arm_ratio = (div >> 0) & 0x7;
@@ -255,8 +254,7 @@ unsigned long get_arm_clk(void)
/* exynos5: set the mmc clock */
void set_mmc_clk(int dev_index, unsigned int div)
{
- struct exynos5420_clock *clk =
- (struct exynos5420_clock *)samsung_get_base_clock();
+ struct exynos5420_clock *clk = samsung_get_base_clock();
void *addr;
unsigned int val, shift;
@@ -271,8 +269,7 @@ void set_mmc_clk(int dev_index, unsigned int div)
void clock_ll_set_pre_ratio(enum periph_id periph_id, unsigned divisor)
{
- struct exynos5_clock *clk =
- samsung_get_base_clock();
+ struct exynos5420_clock *clk = samsung_get_base_clock();
unsigned shift;
unsigned mask = 0xff;
u32 *reg;
@@ -287,24 +284,24 @@ void clock_ll_set_pre_ratio(enum periph_id periph_id, unsigned divisor)
*/
switch (periph_id) {
case PERIPH_ID_SPI0:
- reg = &clk->div_peric1;
+ reg = &clk->clk_div_peric4;
shift = 8;
break;
case PERIPH_ID_SPI1:
- reg = &clk->div_peric1;
- shift = 24;
+ reg = &clk->clk_div_peric4;
+ shift = 16;
break;
case PERIPH_ID_SPI2:
- reg = &clk->div_peric2;
- shift = 8;
+ reg = &clk->clk_div_peric4;
+ shift = 24;
break;
case PERIPH_ID_SPI3:
- reg = &clk->sclk_div_isp;
- shift = 4;
+ reg = &clk->clk_div_isp1;
+ shift = 0;
break;
case PERIPH_ID_SPI4:
- reg = &clk->sclk_div_isp;
- shift = 16;
+ reg = &clk->clk_div_isp1;
+ shift = 8;
break;
default:
printk(BIOS_DEBUG, "%s: Unsupported peripheral ID %d\n", __func__,
@@ -316,32 +313,31 @@ void clock_ll_set_pre_ratio(enum periph_id periph_id, unsigned divisor)
void clock_ll_set_ratio(enum periph_id periph_id, unsigned divisor)
{
- struct exynos5_clock *clk =
- samsung_get_base_clock();
+ struct exynos5420_clock *clk = samsung_get_base_clock();
unsigned shift;
unsigned mask = 0xff;
u32 *reg;
switch (periph_id) {
case PERIPH_ID_SPI0:
- reg = &clk->div_peric1;
- shift = 0;
+ reg = &clk->clk_div_peric1;
+ shift = 20;
break;
case PERIPH_ID_SPI1:
- reg = &clk->div_peric1;
- shift = 16;
+ reg = &clk->clk_div_peric1;
+ shift = 24;
break;
case PERIPH_ID_SPI2:
- reg = &clk->div_peric2;
- shift = 0;
+ reg = &clk->clk_div_peric1;
+ shift = 28;
break;
case PERIPH_ID_SPI3:
- reg = &clk->sclk_div_isp;
- shift = 0;
+ reg = &clk->clk_div_isp1;
+ shift = 16;
break;
case PERIPH_ID_SPI4:
- reg = &clk->sclk_div_isp;
- shift = 12;
+ reg = &clk->clk_div_isp1;
+ shift = 20;
break;
default:
printk(BIOS_DEBUG, "%s: Unsupported peripheral ID %d\n", __func__,
@@ -441,8 +437,7 @@ int clock_set_rate(enum periph_id periph_id, unsigned int rate)
int clock_set_mshci(enum periph_id peripheral)
{
- struct exynos5_clock *clk =
- samsung_get_base_clock();
+ struct exynos5420_clock *clk = samsung_get_base_clock();
u32 *addr;
unsigned int clock;
unsigned int tmp;
@@ -459,10 +454,10 @@ int clock_set_mshci(enum periph_id peripheral)
*/
switch (peripheral) {
case PERIPH_ID_SDMMC0:
- addr = &clk->div_fsys1;
+ addr = &clk->clk_div_fsys1;
break;
case PERIPH_ID_SDMMC2:
- addr = &clk->div_fsys2;
+ addr = &clk->clk_div_fsys2;
break;
default:
printk(BIOS_DEBUG, "invalid peripheral\n");
@@ -484,8 +479,7 @@ int clock_epll_set_rate(unsigned long rate)
unsigned int i;
unsigned int lockcnt;
unsigned int start;
- struct exynos5_clock *clk =
- samsung_get_base_clock();
+ struct exynos5420_clock *clk = samsung_get_base_clock();
epll_con = readl(&clk->epll_con0);
epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK <<
@@ -534,17 +528,15 @@ int clock_epll_set_rate(unsigned long rate)
void clock_select_i2s_clk_source(void)
{
- struct exynos5_clock *clk =
- samsung_get_base_clock();
+ struct exynos5420_clock *clk = samsung_get_base_clock();
- clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
+ clrsetbits_le32(&clk->clk_src_peric1, AUDIO1_SEL_MASK,
(CLK_SRC_SCLK_EPLL));
}
int clock_set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq)
{
- struct exynos5_clock *clk =
- samsung_get_base_clock();
+ struct exynos5420_clock *clk = samsung_get_base_clock();
unsigned int div ;
if ((dst_frq == 0) || (src_frq == 0)) {
@@ -559,7 +551,7 @@ int clock_set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq)
printk(BIOS_DEBUG, "src frq = %d des frq = %d ", src_frq, dst_frq);
return -1;
}
- clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
+ clrsetbits_le32(&clk->clk_div_peric4, AUDIO_1_RATIO_MASK,
(div & AUDIO_1_RATIO_MASK));
return 0;
}