123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- /*
- * Copyright (C) 2009 Samsung Electronics
- * Minkyu Kang <mk7.kang@samsung.com>
- * Heungjun Kim <riverful.kim@samsung.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
- #include <common.h>
- #include <asm/io.h>
- #include <asm/arch/clock.h>
- #include <asm/arch/clk.h>
- #define CLK_M 0
- #define CLK_D 1
- #define CLK_P 2
- #ifndef CONFIG_SYS_CLK_FREQ_C100
- #define CONFIG_SYS_CLK_FREQ_C100 12000000
- #endif
- #ifndef CONFIG_SYS_CLK_FREQ_C110
- #define CONFIG_SYS_CLK_FREQ_C110 24000000
- #endif
- /* s5pc110: return pll clock frequency */
- static unsigned long s5pc100_get_pll_clk(int pllreg)
- {
- struct s5pc100_clock *clk =
- (struct s5pc100_clock *)samsung_get_base_clock();
- unsigned long r, m, p, s, mask, fout;
- unsigned int freq;
- switch (pllreg) {
- case APLL:
- r = readl(&clk->apll_con);
- break;
- case MPLL:
- r = readl(&clk->mpll_con);
- break;
- case EPLL:
- r = readl(&clk->epll_con);
- break;
- case HPLL:
- r = readl(&clk->hpll_con);
- break;
- default:
- printf("Unsupported PLL (%d)\n", pllreg);
- return 0;
- }
- /*
- * APLL_CON: MIDV [25:16]
- * MPLL_CON: MIDV [23:16]
- * EPLL_CON: MIDV [23:16]
- * HPLL_CON: MIDV [23:16]
- */
- if (pllreg == APLL)
- mask = 0x3ff;
- else
- mask = 0x0ff;
- m = (r >> 16) & mask;
- /* PDIV [13:8] */
- p = (r >> 8) & 0x3f;
- /* SDIV [2:0] */
- s = r & 0x7;
- /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
- freq = CONFIG_SYS_CLK_FREQ_C100;
- fout = m * (freq / (p * (1 << s)));
- return fout;
- }
- /* s5pc100: return pll clock frequency */
- static unsigned long s5pc110_get_pll_clk(int pllreg)
- {
- struct s5pc110_clock *clk =
- (struct s5pc110_clock *)samsung_get_base_clock();
- unsigned long r, m, p, s, mask, fout;
- unsigned int freq;
- switch (pllreg) {
- case APLL:
- r = readl(&clk->apll_con);
- break;
- case MPLL:
- r = readl(&clk->mpll_con);
- break;
- case EPLL:
- r = readl(&clk->epll_con);
- break;
- case VPLL:
- r = readl(&clk->vpll_con);
- break;
- default:
- printf("Unsupported PLL (%d)\n", pllreg);
- return 0;
- }
- /*
- * APLL_CON: MIDV [25:16]
- * MPLL_CON: MIDV [25:16]
- * EPLL_CON: MIDV [24:16]
- * VPLL_CON: MIDV [24:16]
- */
- if (pllreg == APLL || pllreg == MPLL)
- mask = 0x3ff;
- else
- mask = 0x1ff;
- m = (r >> 16) & mask;
- /* PDIV [13:8] */
- p = (r >> 8) & 0x3f;
- /* SDIV [2:0] */
- s = r & 0x7;
- freq = CONFIG_SYS_CLK_FREQ_C110;
- if (pllreg == APLL) {
- if (s < 1)
- s = 1;
- /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */
- fout = m * (freq / (p * (1 << (s - 1))));
- } else
- /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
- fout = m * (freq / (p * (1 << s)));
- return fout;
- }
- /* s5pc110: return ARM clock frequency */
- static unsigned long s5pc110_get_arm_clk(void)
- {
- struct s5pc110_clock *clk =
- (struct s5pc110_clock *)samsung_get_base_clock();
- unsigned long div;
- unsigned long dout_apll, armclk;
- unsigned int apll_ratio;
- div = readl(&clk->div0);
- /* APLL_RATIO: [2:0] */
- apll_ratio = div & 0x7;
- dout_apll = get_pll_clk(APLL) / (apll_ratio + 1);
- armclk = dout_apll;
- return armclk;
- }
- /* s5pc100: return ARM clock frequency */
- static unsigned long s5pc100_get_arm_clk(void)
- {
- struct s5pc100_clock *clk =
- (struct s5pc100_clock *)samsung_get_base_clock();
- unsigned long div;
- unsigned long dout_apll, armclk;
- unsigned int apll_ratio, arm_ratio;
- div = readl(&clk->div0);
- /* ARM_RATIO: [6:4] */
- arm_ratio = (div >> 4) & 0x7;
- /* APLL_RATIO: [0] */
- apll_ratio = div & 0x1;
- dout_apll = get_pll_clk(APLL) / (apll_ratio + 1);
- armclk = dout_apll / (arm_ratio + 1);
- return armclk;
- }
- /* s5pc100: return HCLKD0 frequency */
- static unsigned long get_hclk(void)
- {
- struct s5pc100_clock *clk =
- (struct s5pc100_clock *)samsung_get_base_clock();
- unsigned long hclkd0;
- uint div, d0_bus_ratio;
- div = readl(&clk->div0);
- /* D0_BUS_RATIO: [10:8] */
- d0_bus_ratio = (div >> 8) & 0x7;
- hclkd0 = get_arm_clk() / (d0_bus_ratio + 1);
- return hclkd0;
- }
- /* s5pc100: return PCLKD1 frequency */
- static unsigned long get_pclkd1(void)
- {
- struct s5pc100_clock *clk =
- (struct s5pc100_clock *)samsung_get_base_clock();
- unsigned long d1_bus, pclkd1;
- uint div, d1_bus_ratio, pclkd1_ratio;
- div = readl(&clk->div0);
- /* D1_BUS_RATIO: [14:12] */
- d1_bus_ratio = (div >> 12) & 0x7;
- /* PCLKD1_RATIO: [18:16] */
- pclkd1_ratio = (div >> 16) & 0x7;
- /* ASYNC Mode */
- d1_bus = get_pll_clk(MPLL) / (d1_bus_ratio + 1);
- pclkd1 = d1_bus / (pclkd1_ratio + 1);
- return pclkd1;
- }
- /* s5pc110: return HCLKs frequency */
- static unsigned long get_hclk_sys(int dom)
- {
- struct s5pc110_clock *clk =
- (struct s5pc110_clock *)samsung_get_base_clock();
- unsigned long hclk;
- unsigned int div;
- unsigned int offset;
- unsigned int hclk_sys_ratio;
- if (dom == CLK_M)
- return get_hclk();
- div = readl(&clk->div0);
- /*
- * HCLK_MSYS_RATIO: [10:8]
- * HCLK_DSYS_RATIO: [19:16]
- * HCLK_PSYS_RATIO: [27:24]
- */
- offset = 8 + (dom << 0x3);
- hclk_sys_ratio = (div >> offset) & 0xf;
- hclk = get_pll_clk(MPLL) / (hclk_sys_ratio + 1);
- return hclk;
- }
- /* s5pc110: return PCLKs frequency */
- static unsigned long get_pclk_sys(int dom)
- {
- struct s5pc110_clock *clk =
- (struct s5pc110_clock *)samsung_get_base_clock();
- unsigned long pclk;
- unsigned int div;
- unsigned int offset;
- unsigned int pclk_sys_ratio;
- div = readl(&clk->div0);
- /*
- * PCLK_MSYS_RATIO: [14:12]
- * PCLK_DSYS_RATIO: [22:20]
- * PCLK_PSYS_RATIO: [30:28]
- */
- offset = 12 + (dom << 0x3);
- pclk_sys_ratio = (div >> offset) & 0x7;
- pclk = get_hclk_sys(dom) / (pclk_sys_ratio + 1);
- return pclk;
- }
- /* s5pc110: return peripheral clock frequency */
- static unsigned long s5pc110_get_pclk(void)
- {
- return get_pclk_sys(CLK_P);
- }
- /* s5pc100: return peripheral clock frequency */
- static unsigned long s5pc100_get_pclk(void)
- {
- return get_pclkd1();
- }
- /* s5pc1xx: return uart clock frequency */
- static unsigned long s5pc1xx_get_uart_clk(int dev_index)
- {
- if (cpu_is_s5pc110())
- return s5pc110_get_pclk();
- else
- return s5pc100_get_pclk();
- }
- /* s5pc1xx: return pwm clock frequency */
- static unsigned long s5pc1xx_get_pwm_clk(void)
- {
- if (cpu_is_s5pc110())
- return s5pc110_get_pclk();
- else
- return s5pc100_get_pclk();
- }
- unsigned long get_pll_clk(int pllreg)
- {
- if (cpu_is_s5pc110())
- return s5pc110_get_pll_clk(pllreg);
- else
- return s5pc100_get_pll_clk(pllreg);
- }
- unsigned long get_arm_clk(void)
- {
- if (cpu_is_s5pc110())
- return s5pc110_get_arm_clk();
- else
- return s5pc100_get_arm_clk();
- }
- unsigned long get_pwm_clk(void)
- {
- return s5pc1xx_get_pwm_clk();
- }
- 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 */
- }
|