aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter De Schrijver <pdeschrijver@nvidia.com>2013-09-06 07:37:37 -0400
committerPeter De Schrijver <pdeschrijver@nvidia.com>2013-11-26 11:46:21 -0500
commit04edb099a4a7e774a98b241dc016957922cbfb44 (patch)
tree02b71767543bb4051a202222055be01556346e0d
parent5bb9d26700c3db54d5a4346c3b6621b8889f3813 (diff)
clk: tegra: move some PLLC and PLLXC init to clk-pll.c
VCO min clipping, dynamic ramp setup and IDDQ init can be done in the respective PLL clk_register functions if the parent is already registered. This is done for other some PLLs already. Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
-rw-r--r--drivers/clk/tegra/clk-pll.c95
-rw-r--r--drivers/clk/tegra/clk-tegra114.c109
2 files changed, 111 insertions, 93 deletions
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 25734348242f..8f51147185db 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -773,6 +773,48 @@ static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params,
773 return 1; 773 return 1;
774} 774}
775 775
776static unsigned long _clip_vco_min(unsigned long vco_min,
777 unsigned long parent_rate)
778{
779 return DIV_ROUND_UP(vco_min, parent_rate) * parent_rate;
780}
781
782static int _setup_dynamic_ramp(struct tegra_clk_pll_params *pll_params,
783 void __iomem *clk_base,
784 unsigned long parent_rate)
785{
786 u32 val;
787 u32 step_a, step_b;
788
789 switch (parent_rate) {
790 case 12000000:
791 case 13000000:
792 case 26000000:
793 step_a = 0x2B;
794 step_b = 0x0B;
795 break;
796 case 16800000:
797 step_a = 0x1A;
798 step_b = 0x09;
799 break;
800 case 19200000:
801 step_a = 0x12;
802 step_b = 0x08;
803 break;
804 default:
805 pr_err("%s: Unexpected reference rate %lu\n",
806 __func__, parent_rate);
807 WARN_ON(1);
808 return -EINVAL;
809 }
810
811 val = step_a << pll_params->stepa_shift;
812 val |= step_b << pll_params->stepb_shift;
813 writel_relaxed(val, clk_base + pll_params->dyn_ramp_reg);
814
815 return 0;
816}
817
776static int clk_pll_iddq_enable(struct clk_hw *hw) 818static int clk_pll_iddq_enable(struct clk_hw *hw)
777{ 819{
778 struct tegra_clk_pll *pll = to_clk_pll(hw); 820 struct tegra_clk_pll *pll = to_clk_pll(hw);
@@ -1423,11 +1465,39 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
1423 spinlock_t *lock) 1465 spinlock_t *lock)
1424{ 1466{
1425 struct tegra_clk_pll *pll; 1467 struct tegra_clk_pll *pll;
1426 struct clk *clk; 1468 struct clk *clk, *parent;
1469 unsigned long parent_rate;
1470 int err;
1471 u32 val, val_iddq;
1472
1473 parent = __clk_lookup(parent_name);
1474 if (IS_ERR(parent)) {
1475 WARN(1, "parent clk %s of %s must be registered first\n",
1476 name, parent_name);
1477 return ERR_PTR(-EINVAL);
1478 }
1427 1479
1428 if (!pll_params->pdiv_tohw) 1480 if (!pll_params->pdiv_tohw)
1429 return ERR_PTR(-EINVAL); 1481 return ERR_PTR(-EINVAL);
1430 1482
1483 parent_rate = __clk_get_rate(parent);
1484
1485 pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate);
1486
1487 err = _setup_dynamic_ramp(pll_params, clk_base, parent_rate);
1488 if (err)
1489 return ERR_PTR(err);
1490
1491 val = readl_relaxed(clk_base + pll_params->base_reg);
1492 val_iddq = readl_relaxed(clk_base + pll_params->iddq_reg);
1493
1494 if (val & PLL_BASE_ENABLE)
1495 WARN_ON(val_iddq & BIT(pll_params->iddq_bit_idx));
1496 else {
1497 val_iddq |= BIT(pll_params->iddq_bit_idx);
1498 writel_relaxed(val_iddq, clk_base + pll_params->iddq_reg);
1499 }
1500
1431 pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; 1501 pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
1432 pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, 1502 pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
1433 freq_table, lock); 1503 freq_table, lock);
@@ -1455,6 +1525,9 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
1455 struct clk *clk; 1525 struct clk *clk;
1456 1526
1457 pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC; 1527 pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC;
1528
1529 pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate);
1530
1458 pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, 1531 pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
1459 freq_table, lock); 1532 freq_table, lock);
1460 if (IS_ERR(pll)) 1533 if (IS_ERR(pll))
@@ -1498,11 +1571,23 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
1498 spinlock_t *lock) 1571 spinlock_t *lock)
1499{ 1572{
1500 struct tegra_clk_pll *pll; 1573 struct tegra_clk_pll *pll;
1501 struct clk *clk; 1574 struct clk *clk, *parent;
1575 unsigned long parent_rate;
1502 1576
1503 if (!pll_params->pdiv_tohw) 1577 if (!pll_params->pdiv_tohw)
1504 return ERR_PTR(-EINVAL); 1578 return ERR_PTR(-EINVAL);
1505 1579
1580 parent = __clk_lookup(parent_name);
1581 if (IS_ERR(parent)) {
1582 WARN(1, "parent clk %s of %s must be registered first\n",
1583 name, parent_name);
1584 return ERR_PTR(-EINVAL);
1585 }
1586
1587 parent_rate = __clk_get_rate(parent);
1588
1589 pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate);
1590
1506 pll_flags |= TEGRA_PLL_BYPASS; 1591 pll_flags |= TEGRA_PLL_BYPASS;
1507 pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; 1592 pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
1508 pll_flags |= TEGRA_PLLM; 1593 pll_flags |= TEGRA_PLLM;
@@ -1543,14 +1628,16 @@ struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name,
1543 return ERR_PTR(-EINVAL); 1628 return ERR_PTR(-EINVAL);
1544 } 1629 }
1545 1630
1631 parent_rate = __clk_get_rate(parent);
1632
1633 pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate);
1634
1546 pll_flags |= TEGRA_PLL_BYPASS; 1635 pll_flags |= TEGRA_PLL_BYPASS;
1547 pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, 1636 pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
1548 freq_table, lock); 1637 freq_table, lock);
1549 if (IS_ERR(pll)) 1638 if (IS_ERR(pll))
1550 return ERR_CAST(pll); 1639 return ERR_CAST(pll);
1551 1640
1552 parent_rate = __clk_get_rate(parent);
1553
1554 /* 1641 /*
1555 * Most of PLLC register fields are shadowed, and can not be read 1642 * Most of PLLC register fields are shadowed, and can not be read
1556 * directly from PLL h/w. Hence, actual PLLC boot state is unknown. 1643 * directly from PLL h/w. Hence, actual PLLC boot state is unknown.
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
index 9729af823eaf..fa562e3e8f19 100644
--- a/drivers/clk/tegra/clk-tegra114.c
+++ b/drivers/clk/tegra/clk-tegra114.c
@@ -1077,63 +1077,6 @@ static __init void tegra114_utmi_param_configure(void __iomem *clk_base)
1077 writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); 1077 writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0);
1078} 1078}
1079 1079
1080static void __init _clip_vco_min(struct tegra_clk_pll_params *pll_params)
1081{
1082 pll_params->vco_min =
1083 DIV_ROUND_UP(pll_params->vco_min, pll_ref_freq) * pll_ref_freq;
1084}
1085
1086static int __init _setup_dynamic_ramp(struct tegra_clk_pll_params *pll_params,
1087 void __iomem *clk_base)
1088{
1089 u32 val;
1090 u32 step_a, step_b;
1091
1092 switch (pll_ref_freq) {
1093 case 12000000:
1094 case 13000000:
1095 case 26000000:
1096 step_a = 0x2B;
1097 step_b = 0x0B;
1098 break;
1099 case 16800000:
1100 step_a = 0x1A;
1101 step_b = 0x09;
1102 break;
1103 case 19200000:
1104 step_a = 0x12;
1105 step_b = 0x08;
1106 break;
1107 default:
1108 pr_err("%s: Unexpected reference rate %lu\n",
1109 __func__, pll_ref_freq);
1110 WARN_ON(1);
1111 return -EINVAL;
1112 }
1113
1114 val = step_a << pll_params->stepa_shift;
1115 val |= step_b << pll_params->stepb_shift;
1116 writel_relaxed(val, clk_base + pll_params->dyn_ramp_reg);
1117
1118 return 0;
1119}
1120
1121static void __init _init_iddq(struct tegra_clk_pll_params *pll_params,
1122 void __iomem *clk_base)
1123{
1124 u32 val, val_iddq;
1125
1126 val = readl_relaxed(clk_base + pll_params->base_reg);
1127 val_iddq = readl_relaxed(clk_base + pll_params->iddq_reg);
1128
1129 if (val & BIT(30))
1130 WARN_ON(val_iddq & BIT(pll_params->iddq_bit_idx));
1131 else {
1132 val_iddq |= BIT(pll_params->iddq_bit_idx);
1133 writel_relaxed(val_iddq, clk_base + pll_params->iddq_reg);
1134 }
1135}
1136
1137static void __init tegra114_pll_init(void __iomem *clk_base, 1080static void __init tegra114_pll_init(void __iomem *clk_base,
1138 void __iomem *pmc) 1081 void __iomem *pmc)
1139{ 1082{
@@ -1141,28 +1084,23 @@ static void __init tegra114_pll_init(void __iomem *clk_base,
1141 struct clk *clk; 1084 struct clk *clk;
1142 1085
1143 /* PLLC */ 1086 /* PLLC */
1144 _clip_vco_min(&pll_c_params); 1087 clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base,
1145 if (_setup_dynamic_ramp(&pll_c_params, clk_base) >= 0) { 1088 pmc, 0, 0, &pll_c_params, TEGRA_PLL_USE_LOCK,
1146 _init_iddq(&pll_c_params, clk_base); 1089 pll_c_freq_table, NULL);
1147 clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base, 1090 clk_register_clkdev(clk, "pll_c", NULL);
1148 pmc, 0, 0, &pll_c_params, TEGRA_PLL_USE_LOCK, 1091 clks[TEGRA114_CLK_PLL_C] = clk;
1149 pll_c_freq_table, NULL); 1092
1150 clk_register_clkdev(clk, "pll_c", NULL); 1093 /* PLLC_OUT1 */
1151 clks[TEGRA114_CLK_PLL_C] = clk; 1094 clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c",
1152 1095 clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
1153 /* PLLC_OUT1 */ 1096 8, 8, 1, NULL);
1154 clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", 1097 clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div",
1155 clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP, 1098 clk_base + PLLC_OUT, 1, 0,
1156 8, 8, 1, NULL); 1099 CLK_SET_RATE_PARENT, 0, NULL);
1157 clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", 1100 clk_register_clkdev(clk, "pll_c_out1", NULL);
1158 clk_base + PLLC_OUT, 1, 0, 1101 clks[TEGRA114_CLK_PLL_C_OUT1] = clk;
1159 CLK_SET_RATE_PARENT, 0, NULL);
1160 clk_register_clkdev(clk, "pll_c_out1", NULL);
1161 clks[TEGRA114_CLK_PLL_C_OUT1] = clk;
1162 }
1163 1102
1164 /* PLLC2 */ 1103 /* PLLC2 */
1165 _clip_vco_min(&pll_c2_params);
1166 clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, 0, 1104 clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, 0,
1167 &pll_c2_params, TEGRA_PLL_USE_LOCK, 1105 &pll_c2_params, TEGRA_PLL_USE_LOCK,
1168 pll_cx_freq_table, NULL); 1106 pll_cx_freq_table, NULL);
@@ -1170,7 +1108,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base,
1170 clks[TEGRA114_CLK_PLL_C2] = clk; 1108 clks[TEGRA114_CLK_PLL_C2] = clk;
1171 1109
1172 /* PLLC3 */ 1110 /* PLLC3 */
1173 _clip_vco_min(&pll_c3_params);
1174 clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, 0, 1111 clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, 0,
1175 &pll_c3_params, TEGRA_PLL_USE_LOCK, 1112 &pll_c3_params, TEGRA_PLL_USE_LOCK,
1176 pll_cx_freq_table, NULL); 1113 pll_cx_freq_table, NULL);
@@ -1232,7 +1169,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base,
1232 clks[TEGRA114_CLK_PLL_P_OUT4] = clk; 1169 clks[TEGRA114_CLK_PLL_P_OUT4] = clk;
1233 1170
1234 /* PLLM */ 1171 /* PLLM */
1235 _clip_vco_min(&pll_m_params);
1236 clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, 1172 clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc,
1237 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0, 1173 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0,
1238 &pll_m_params, TEGRA_PLL_USE_LOCK, 1174 &pll_m_params, TEGRA_PLL_USE_LOCK,
@@ -1255,15 +1191,11 @@ static void __init tegra114_pll_init(void __iomem *clk_base,
1255 CLK_SET_RATE_PARENT, 1, 1); 1191 CLK_SET_RATE_PARENT, 1, 1);
1256 1192
1257 /* PLLX */ 1193 /* PLLX */
1258 _clip_vco_min(&pll_x_params); 1194 clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base,
1259 if (_setup_dynamic_ramp(&pll_x_params, clk_base) >= 0) { 1195 pmc, CLK_IGNORE_UNUSED, 0, &pll_x_params,
1260 _init_iddq(&pll_x_params, clk_base); 1196 TEGRA_PLL_USE_LOCK, pll_x_freq_table, NULL);
1261 clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, 1197 clk_register_clkdev(clk, "pll_x", NULL);
1262 pmc, CLK_IGNORE_UNUSED, 0, &pll_x_params, 1198 clks[TEGRA114_CLK_PLL_X] = clk;
1263 TEGRA_PLL_USE_LOCK, pll_x_freq_table, NULL);
1264 clk_register_clkdev(clk, "pll_x", NULL);
1265 clks[TEGRA114_CLK_PLL_X] = clk;
1266 }
1267 1199
1268 /* PLLX_OUT0 */ 1200 /* PLLX_OUT0 */
1269 clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x", 1201 clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x",
@@ -1356,7 +1288,6 @@ static void __init tegra114_pll_init(void __iomem *clk_base,
1356 clks[TEGRA114_CLK_PLL_A_OUT0] = clk; 1288 clks[TEGRA114_CLK_PLL_A_OUT0] = clk;
1357 1289
1358 /* PLLRE */ 1290 /* PLLRE */
1359 _clip_vco_min(&pll_re_vco_params);
1360 clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc, 1291 clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc,
1361 0, 0, &pll_re_vco_params, TEGRA_PLL_USE_LOCK, 1292 0, 0, &pll_re_vco_params, TEGRA_PLL_USE_LOCK,
1362 NULL, &pll_re_lock, pll_ref_freq); 1293 NULL, &pll_re_lock, pll_ref_freq);