X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fclk%2Fclk-hsdk-cgu.c;h=6eaafdeaf996fc082eac086b69967950fdf48e7d;hb=ecb3a0a154fa43e636012be691521910928d67bd;hp=64bb1db821a13f28fb1aab859d31ce73c29c99d1;hpb=f6d7812d8d9ca2b0b04d2825b820160e8bdd79c8;p=oweals%2Fu-boot.git diff --git a/drivers/clk/clk-hsdk-cgu.c b/drivers/clk/clk-hsdk-cgu.c index 64bb1db821..6eaafdeaf9 100644 --- a/drivers/clk/clk-hsdk-cgu.c +++ b/drivers/clk/clk-hsdk-cgu.c @@ -46,21 +46,23 @@ * | |-->|CGU_TUN_IDIV_ROM|-----------> * | |-->|CGU_TUN_IDIV_PWM|-----------> * | - * | ------------ - * |-->| HDMI PLL | - * | ------------ - * | | - * | |-->|CGU_HDMI_IDIV_APB|------> - * | * | ----------- * |-->| DDR PLL | * ----------- * | * |----------------------------> + * + * ------------------ + * | 27.00 MHz xtal | + * ------------------ + * | + * | ------------ + * |-->| HDMI PLL | + * ------------ + * | + * |-->|CGU_HDMI_IDIV_APB|------> */ -DECLARE_GLOBAL_DATA_PTR; - #define CGU_ARC_IDIV 0x080 #define CGU_TUN_IDIV_TUN 0x380 #define CGU_TUN_IDIV_ROM 0x390 @@ -119,7 +121,8 @@ DECLARE_GLOBAL_DATA_PTR; #define CREG_CORE_IF_CLK_DIV_2 0x1 #define MIN_PLL_RATE 100000000 /* 100 MHz */ -#define PARENT_RATE 33333333 /* fixed clock - xtal */ +#define PARENT_RATE_33 33333333 /* fixed clock - xtal */ +#define PARENT_RATE_27 27000000 /* fixed clock - xtal */ #define CGU_MAX_CLOCKS 26 #define CGU_SYS_CLOCKS 16 @@ -141,7 +144,7 @@ struct hsdk_tun_clk_cfg { static const struct hsdk_tun_clk_cfg tun_clk_cfg = { { 25000000, 50000000, 75000000, 100000000, 125000000, 150000000 }, - { 600000000, 600000000, 600000000, 600000000, 700000000, 600000000 }, { + { 600000000, 600000000, 600000000, 600000000, 750000000, 600000000 }, { { CGU_TUN_IDIV_TUN, { 24, 12, 8, 6, 6, 4 } }, { CGU_TUN_IDIV_ROM, { 4, 4, 4, 4, 5, 4 } }, { CGU_TUN_IDIV_PWM, { 8, 8, 8, 8, 10, 8 } } @@ -202,6 +205,7 @@ static const struct hsdk_pll_cfg asdt_pll_cfg[] = { { 500000000, 0, 14, 1, 0 }, { 600000000, 0, 17, 1, 0 }, { 700000000, 0, 20, 1, 0 }, + { 750000000, 1, 44, 1, 0 }, { 800000000, 0, 23, 1, 0 }, { 900000000, 1, 26, 0, 0 }, { 1000000000, 1, 29, 0, 0 }, @@ -239,6 +243,7 @@ struct hsdk_cgu_clk { }; struct hsdk_pll_devdata { + const u32 parent_rate; const struct hsdk_pll_cfg *pll_cfg; int (*update_rate)(struct hsdk_cgu_clk *clk, unsigned long rate, const struct hsdk_pll_cfg *cfg); @@ -250,16 +255,19 @@ static int hsdk_pll_comm_update_rate(struct hsdk_cgu_clk *, unsigned long, const struct hsdk_pll_cfg *); static const struct hsdk_pll_devdata core_pll_dat = { + .parent_rate = PARENT_RATE_33, .pll_cfg = asdt_pll_cfg, .update_rate = hsdk_pll_core_update_rate, }; static const struct hsdk_pll_devdata sdt_pll_dat = { + .parent_rate = PARENT_RATE_33, .pll_cfg = asdt_pll_cfg, .update_rate = hsdk_pll_comm_update_rate, }; static const struct hsdk_pll_devdata hdmi_pll_dat = { + .parent_rate = PARENT_RATE_27, .pll_cfg = hdmi_pll_cfg, .update_rate = hsdk_pll_comm_update_rate, }; @@ -374,19 +382,20 @@ static ulong pll_get(struct clk *sclk) u64 rate; u32 idiv, fbdiv, odiv; struct hsdk_cgu_clk *clk = dev_get_priv(sclk->dev); + u32 parent_rate = clk->pll_devdata->parent_rate; val = hsdk_pll_read(clk, CGU_PLL_CTRL); pr_debug("current configurarion: %#x\n", val); + /* Check if PLL is bypassed */ + if (val & CGU_PLL_CTRL_BYPASS) + return parent_rate; + /* Check if PLL is disabled */ if (val & CGU_PLL_CTRL_PD) return 0; - /* Check if PLL is bypassed */ - if (val & CGU_PLL_CTRL_BYPASS) - return PARENT_RATE; - /* input divider = reg.idiv + 1 */ idiv = 1 + ((val & CGU_PLL_CTRL_IDIV_MASK) >> CGU_PLL_CTRL_IDIV_SHIFT); /* fb divider = 2*(reg.fbdiv + 1) */ @@ -394,7 +403,7 @@ static ulong pll_get(struct clk *sclk) /* output divider = 2^(reg.odiv) */ odiv = 1 << ((val & CGU_PLL_CTRL_ODIV_MASK) >> CGU_PLL_CTRL_ODIV_SHIFT); - rate = (u64)PARENT_RATE * fbdiv; + rate = (u64)parent_rate * fbdiv; do_div(rate, idiv * odiv); return rate; @@ -492,7 +501,8 @@ static ulong pll_set(struct clk *sclk, ulong rate) } } - pr_err("invalid rate=%ld, parent_rate=%d\n", best_rate, PARENT_RATE); + pr_err("invalid rate=%ld Hz, parent_rate=%d Hz\n", best_rate, + clk->pll_devdata->parent_rate); return -EINVAL; } @@ -623,14 +633,14 @@ static ulong idiv_set(struct clk *sclk, ulong rate) } if (div_factor & ~CGU_IDIV_MASK) { - pr_err("invalid rate=%ld, parent_rate=%ld, div=%d: max divider valie is%d\n", + pr_err("invalid rate=%ld Hz, parent_rate=%ld Hz, div=%d: max divider valie is%d\n", rate, parent_rate, div_factor, CGU_IDIV_MASK); div_factor = CGU_IDIV_MASK; } if (div_factor == 0) { - pr_err("invalid rate=%ld, parent_rate=%ld, div=%d: min divider valie is 1\n", + pr_err("invalid rate=%ld Hz, parent_rate=%ld Hz, div=%d: min divider valie is 1\n", rate, parent_rate, div_factor); div_factor = 1;