aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Zapolskiy <vz@mleia.com>2017-04-04 15:32:03 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-12 06:41:15 -0400
commite02a5d1d5a053374dffe9ed6300113a125121f29 (patch)
treec98efa84dcd3dddfc4b5aaf8de7f94f27f383a07
parent666d5f34d8972d1d159b9f79f56620b6e817cc8a (diff)
clk: lpc32xx: add a quirk for PWM and MS clock dividers
[ Upstream commit f84d42a9cffc4ecd96f1ce3a038f841782142eb2 ] In common clock framework CLK_DIVIDER_ONE_BASED or'ed with CLK_DIVIDER_ALLOW_ZERO flags indicates that 1) a divider clock may be set to zero value, 2) divider's zero value is interpreted as a non-divided clock. On the LPC32xx platform clock dividers of PWM and memory card clocks comply with the first condition, but zero value means a gated clock, thus it may happen that the divider value is not updated when the clock is enabled and the clock remains gated. The change adds one-shot quirks, which check for zero value of divider on initialization and set it to a non-zero value, therefore in runtime a gate clock will work as expected. Signed-off-by: Vladimir Zapolskiy <vz@mleia.com> Reviewed-by: Sylvain Lemieux <slemieux.tyco@gmail.com> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Sasha Levin <alexander.levin@verizon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/clk/nxp/clk-lpc32xx.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c
index 34c97353cdeb..5b98ff9076f3 100644
--- a/drivers/clk/nxp/clk-lpc32xx.c
+++ b/drivers/clk/nxp/clk-lpc32xx.c
@@ -1282,13 +1282,13 @@ static struct clk_hw_proto clk_hw_proto[LPC32XX_CLK_HW_MAX] = {
1282 1282
1283 LPC32XX_DEFINE_MUX(PWM1_MUX, PWMCLK_CTRL, 1, 0x1, NULL, 0), 1283 LPC32XX_DEFINE_MUX(PWM1_MUX, PWMCLK_CTRL, 1, 0x1, NULL, 0),
1284 LPC32XX_DEFINE_DIV(PWM1_DIV, PWMCLK_CTRL, 4, 4, NULL, 1284 LPC32XX_DEFINE_DIV(PWM1_DIV, PWMCLK_CTRL, 4, 4, NULL,
1285 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO), 1285 CLK_DIVIDER_ONE_BASED),
1286 LPC32XX_DEFINE_GATE(PWM1_GATE, PWMCLK_CTRL, 0, 0), 1286 LPC32XX_DEFINE_GATE(PWM1_GATE, PWMCLK_CTRL, 0, 0),
1287 LPC32XX_DEFINE_COMPOSITE(PWM1, PWM1_MUX, PWM1_DIV, PWM1_GATE), 1287 LPC32XX_DEFINE_COMPOSITE(PWM1, PWM1_MUX, PWM1_DIV, PWM1_GATE),
1288 1288
1289 LPC32XX_DEFINE_MUX(PWM2_MUX, PWMCLK_CTRL, 3, 0x1, NULL, 0), 1289 LPC32XX_DEFINE_MUX(PWM2_MUX, PWMCLK_CTRL, 3, 0x1, NULL, 0),
1290 LPC32XX_DEFINE_DIV(PWM2_DIV, PWMCLK_CTRL, 8, 4, NULL, 1290 LPC32XX_DEFINE_DIV(PWM2_DIV, PWMCLK_CTRL, 8, 4, NULL,
1291 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO), 1291 CLK_DIVIDER_ONE_BASED),
1292 LPC32XX_DEFINE_GATE(PWM2_GATE, PWMCLK_CTRL, 2, 0), 1292 LPC32XX_DEFINE_GATE(PWM2_GATE, PWMCLK_CTRL, 2, 0),
1293 LPC32XX_DEFINE_COMPOSITE(PWM2, PWM2_MUX, PWM2_DIV, PWM2_GATE), 1293 LPC32XX_DEFINE_COMPOSITE(PWM2, PWM2_MUX, PWM2_DIV, PWM2_GATE),
1294 1294
@@ -1335,8 +1335,7 @@ static struct clk_hw_proto clk_hw_proto[LPC32XX_CLK_HW_MAX] = {
1335 LPC32XX_DEFINE_GATE(USB_DIV_GATE, USB_CTRL, 17, 0), 1335 LPC32XX_DEFINE_GATE(USB_DIV_GATE, USB_CTRL, 17, 0),
1336 LPC32XX_DEFINE_COMPOSITE(USB_DIV, _NULL, USB_DIV_DIV, USB_DIV_GATE), 1336 LPC32XX_DEFINE_COMPOSITE(USB_DIV, _NULL, USB_DIV_DIV, USB_DIV_GATE),
1337 1337
1338 LPC32XX_DEFINE_DIV(SD_DIV, MS_CTRL, 0, 4, NULL, 1338 LPC32XX_DEFINE_DIV(SD_DIV, MS_CTRL, 0, 4, NULL, CLK_DIVIDER_ONE_BASED),
1339 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
1340 LPC32XX_DEFINE_CLK(SD_GATE, MS_CTRL, BIT(5) | BIT(9), BIT(5) | BIT(9), 1339 LPC32XX_DEFINE_CLK(SD_GATE, MS_CTRL, BIT(5) | BIT(9), BIT(5) | BIT(9),
1341 0x0, BIT(5) | BIT(9), 0x0, 0x0, clk_mask_ops), 1340 0x0, BIT(5) | BIT(9), 0x0, 0x0, clk_mask_ops),
1342 LPC32XX_DEFINE_COMPOSITE(SD, _NULL, SD_DIV, SD_GATE), 1341 LPC32XX_DEFINE_COMPOSITE(SD, _NULL, SD_DIV, SD_GATE),
@@ -1478,6 +1477,20 @@ static struct clk * __init lpc32xx_clk_register(u32 id)
1478 return clk; 1477 return clk;
1479} 1478}
1480 1479
1480static void __init lpc32xx_clk_div_quirk(u32 reg, u32 div_mask, u32 gate)
1481{
1482 u32 val;
1483
1484 regmap_read(clk_regmap, reg, &val);
1485
1486 if (!(val & div_mask)) {
1487 val &= ~gate;
1488 val |= BIT(__ffs(div_mask));
1489 }
1490
1491 regmap_update_bits(clk_regmap, reg, gate | div_mask, val);
1492}
1493
1481static void __init lpc32xx_clk_init(struct device_node *np) 1494static void __init lpc32xx_clk_init(struct device_node *np)
1482{ 1495{
1483 unsigned int i; 1496 unsigned int i;
@@ -1517,6 +1530,17 @@ static void __init lpc32xx_clk_init(struct device_node *np)
1517 return; 1530 return;
1518 } 1531 }
1519 1532
1533 /*
1534 * Divider part of PWM and MS clocks requires a quirk to avoid
1535 * a misinterpretation of formally valid zero value in register
1536 * bitfield, which indicates another clock gate. Instead of
1537 * adding complexity to a gate clock ensure that zero value in
1538 * divider clock is never met in runtime.
1539 */
1540 lpc32xx_clk_div_quirk(LPC32XX_CLKPWR_PWMCLK_CTRL, 0xf0, BIT(0));
1541 lpc32xx_clk_div_quirk(LPC32XX_CLKPWR_PWMCLK_CTRL, 0xf00, BIT(2));
1542 lpc32xx_clk_div_quirk(LPC32XX_CLKPWR_MS_CTRL, 0xf, BIT(5) | BIT(9));
1543
1520 for (i = 1; i < LPC32XX_CLK_MAX; i++) { 1544 for (i = 1; i < LPC32XX_CLK_MAX; i++) {
1521 clk[i] = lpc32xx_clk_register(i); 1545 clk[i] = lpc32xx_clk_register(i);
1522 if (IS_ERR(clk[i])) { 1546 if (IS_ERR(clk[i])) {