|
58 | 58 | #define PLL_TEST_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U])
|
59 | 59 | #define PLL_TEST_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U1])
|
60 | 60 | #define PLL_TEST_CTL_U2(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U2])
|
| 61 | +#define PLL_TEST_CTL_U3(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U3]) |
61 | 62 | #define PLL_STATUS(p) ((p)->offset + (p)->regs[PLL_OFF_STATUS])
|
62 | 63 | #define PLL_OPMODE(p) ((p)->offset + (p)->regs[PLL_OFF_OPMODE])
|
63 | 64 | #define PLL_FRAC(p) ((p)->offset + (p)->regs[PLL_OFF_FRAC])
|
@@ -197,6 +198,23 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
|
197 | 198 | [PLL_OFF_TEST_CTL_U1] = 0x34,
|
198 | 199 | [PLL_OFF_TEST_CTL_U2] = 0x38,
|
199 | 200 | },
|
| 201 | + [CLK_ALPHA_PLL_TYPE_PONGO_ELU] = { |
| 202 | + [PLL_OFF_OPMODE] = 0x04, |
| 203 | + [PLL_OFF_STATE] = 0x08, |
| 204 | + [PLL_OFF_STATUS] = 0x0c, |
| 205 | + [PLL_OFF_L_VAL] = 0x10, |
| 206 | + [PLL_OFF_USER_CTL] = 0x14, |
| 207 | + [PLL_OFF_USER_CTL_U] = 0x18, |
| 208 | + [PLL_OFF_CONFIG_CTL] = 0x1c, |
| 209 | + [PLL_OFF_CONFIG_CTL_U] = 0x20, |
| 210 | + [PLL_OFF_CONFIG_CTL_U1] = 0x24, |
| 211 | + [PLL_OFF_CONFIG_CTL_U2] = 0x28, |
| 212 | + [PLL_OFF_TEST_CTL] = 0x2c, |
| 213 | + [PLL_OFF_TEST_CTL_U] = 0x30, |
| 214 | + [PLL_OFF_TEST_CTL_U1] = 0x34, |
| 215 | + [PLL_OFF_TEST_CTL_U2] = 0x38, |
| 216 | + [PLL_OFF_TEST_CTL_U3] = 0x3c, |
| 217 | + }, |
200 | 218 | [CLK_ALPHA_PLL_TYPE_TAYCAN_ELU] = {
|
201 | 219 | [PLL_OFF_OPMODE] = 0x04,
|
202 | 220 | [PLL_OFF_STATE] = 0x08,
|
@@ -337,6 +355,12 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
|
337 | 355 | #define LUCID_EVO_PLL_CAL_L_VAL_SHIFT 16
|
338 | 356 | #define LUCID_OLE_PLL_RINGOSC_CAL_L_VAL_SHIFT 24
|
339 | 357 |
|
| 358 | +/* PONGO ELU PLL specific setting and offsets */ |
| 359 | +#define PONGO_PLL_OUT_MASK GENMASK(1, 0) |
| 360 | +#define PONGO_PLL_L_VAL_MASK GENMASK(11, 0) |
| 361 | +#define PONGO_XO_PRESENT BIT(10) |
| 362 | +#define PONGO_CLOCK_SELECT BIT(12) |
| 363 | + |
340 | 364 | /* ZONDA PLL specific */
|
341 | 365 | #define ZONDA_PLL_OUT_MASK 0xf
|
342 | 366 | #define ZONDA_STAY_IN_CFA BIT(16)
|
@@ -366,7 +390,8 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
|
366 | 390 | if (ret)
|
367 | 391 | return ret;
|
368 | 392 |
|
369 |
| - for (count = 200; count > 0; count--) { |
| 393 | + /* Pongo PLLs using a 32KHz reference can take upwards of 1500us to lock. */ |
| 394 | + for (count = 1500; count > 0; count--) { |
370 | 395 | ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
|
371 | 396 | if (ret)
|
372 | 397 | return ret;
|
@@ -2510,6 +2535,144 @@ const struct clk_ops clk_alpha_pll_reset_lucid_evo_ops = {
|
2510 | 2535 | };
|
2511 | 2536 | EXPORT_SYMBOL_GPL(clk_alpha_pll_reset_lucid_evo_ops);
|
2512 | 2537 |
|
| 2538 | +static int alpha_pll_pongo_elu_prepare(struct clk_hw *hw) |
| 2539 | +{ |
| 2540 | + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); |
| 2541 | + struct regmap *regmap = pll->clkr.regmap; |
| 2542 | + int ret; |
| 2543 | + |
| 2544 | + /* Enable PLL intially to one-time calibrate against XO. */ |
| 2545 | + regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN); |
| 2546 | + regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); |
| 2547 | + regmap_update_bits(regmap, PLL_MODE(pll), PONGO_XO_PRESENT, PONGO_XO_PRESENT); |
| 2548 | + |
| 2549 | + /* Set regmap for wait_for_pll() */ |
| 2550 | + pll->clkr.regmap = regmap; |
| 2551 | + ret = wait_for_pll_enable_lock(pll); |
| 2552 | + if (ret) { |
| 2553 | + /* Reverse calibration - disable PLL output */ |
| 2554 | + regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0); |
| 2555 | + return ret; |
| 2556 | + } |
| 2557 | + |
| 2558 | + /* Disable PLL after one-time calibration. */ |
| 2559 | + regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY); |
| 2560 | + |
| 2561 | + /* Select internally generated clock. */ |
| 2562 | + regmap_update_bits(regmap, PLL_MODE(pll), PONGO_CLOCK_SELECT, |
| 2563 | + PONGO_CLOCK_SELECT); |
| 2564 | + |
| 2565 | + return 0; |
| 2566 | +} |
| 2567 | + |
| 2568 | +static int alpha_pll_pongo_elu_enable(struct clk_hw *hw) |
| 2569 | +{ |
| 2570 | + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); |
| 2571 | + struct regmap *regmap = pll->clkr.regmap; |
| 2572 | + int ret; |
| 2573 | + |
| 2574 | + /* Check if PLL is already enabled */ |
| 2575 | + if (trion_pll_is_enabled(pll, regmap)) |
| 2576 | + return 0; |
| 2577 | + |
| 2578 | + ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); |
| 2579 | + if (ret) |
| 2580 | + return ret; |
| 2581 | + |
| 2582 | + /* Set operation mode to RUN */ |
| 2583 | + regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN); |
| 2584 | + |
| 2585 | + ret = wait_for_pll_enable_lock(pll); |
| 2586 | + if (ret) |
| 2587 | + return ret; |
| 2588 | + |
| 2589 | + /* Enable the global PLL outputs */ |
| 2590 | + ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL); |
| 2591 | + if (ret) |
| 2592 | + return ret; |
| 2593 | + |
| 2594 | + /* Ensure that the write above goes through before returning. */ |
| 2595 | + mb(); |
| 2596 | + |
| 2597 | + return ret; |
| 2598 | +} |
| 2599 | + |
| 2600 | +static void alpha_pll_pongo_elu_disable(struct clk_hw *hw) |
| 2601 | +{ |
| 2602 | + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); |
| 2603 | + struct regmap *regmap = pll->clkr.regmap; |
| 2604 | + int ret; |
| 2605 | + |
| 2606 | + /* Disable the global PLL output */ |
| 2607 | + ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0); |
| 2608 | + if (ret) |
| 2609 | + return; |
| 2610 | + |
| 2611 | + /* Place the PLL mode in STANDBY */ |
| 2612 | + regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY); |
| 2613 | +} |
| 2614 | + |
| 2615 | +static unsigned long alpha_pll_pongo_elu_recalc_rate(struct clk_hw *hw, |
| 2616 | + unsigned long parent_rate) |
| 2617 | +{ |
| 2618 | + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); |
| 2619 | + struct regmap *regmap = pll->clkr.regmap; |
| 2620 | + u32 l; |
| 2621 | + |
| 2622 | + if (regmap_read(regmap, PLL_L_VAL(pll), &l)) |
| 2623 | + return 0; |
| 2624 | + |
| 2625 | + l &= PONGO_PLL_L_VAL_MASK; |
| 2626 | + |
| 2627 | + return alpha_pll_calc_rate(parent_rate, l, 0, pll_alpha_width(pll)); |
| 2628 | +} |
| 2629 | + |
| 2630 | +const struct clk_ops clk_alpha_pll_pongo_elu_ops = { |
| 2631 | + .prepare = alpha_pll_pongo_elu_prepare, |
| 2632 | + .enable = alpha_pll_pongo_elu_enable, |
| 2633 | + .disable = alpha_pll_pongo_elu_disable, |
| 2634 | + .recalc_rate = alpha_pll_pongo_elu_recalc_rate, |
| 2635 | +}; |
| 2636 | +EXPORT_SYMBOL_GPL(clk_alpha_pll_pongo_elu_ops); |
| 2637 | + |
| 2638 | +void clk_pongo_elu_pll_configure(struct clk_alpha_pll *pll, |
| 2639 | + struct regmap *regmap, |
| 2640 | + const struct alpha_pll_config *config) |
| 2641 | +{ |
| 2642 | + u32 val; |
| 2643 | + |
| 2644 | + regmap_update_bits(regmap, PLL_USER_CTL(pll), PONGO_PLL_OUT_MASK, |
| 2645 | + PONGO_PLL_OUT_MASK); |
| 2646 | + |
| 2647 | + if (trion_pll_is_enabled(pll, regmap)) |
| 2648 | + return; |
| 2649 | + |
| 2650 | + if (regmap_read(regmap, PLL_L_VAL(pll), &val)) |
| 2651 | + return; |
| 2652 | + val &= PONGO_PLL_L_VAL_MASK; |
| 2653 | + if (val) |
| 2654 | + return; |
| 2655 | + |
| 2656 | + clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l); |
| 2657 | + clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha); |
| 2658 | + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val); |
| 2659 | + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val); |
| 2660 | + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val); |
| 2661 | + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U2(pll), config->config_ctl_hi2_val); |
| 2662 | + clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), |
| 2663 | + config->user_ctl_val | PONGO_PLL_OUT_MASK); |
| 2664 | + clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll), config->user_ctl_hi_val); |
| 2665 | + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val); |
| 2666 | + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val); |
| 2667 | + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val); |
| 2668 | + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U2(pll), config->test_ctl_hi2_val); |
| 2669 | + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U3(pll), config->test_ctl_hi3_val); |
| 2670 | + |
| 2671 | + /* Disable PLL output */ |
| 2672 | + regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0); |
| 2673 | +} |
| 2674 | +EXPORT_SYMBOL_GPL(clk_pongo_elu_pll_configure); |
| 2675 | + |
2513 | 2676 | void clk_rivian_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
2514 | 2677 | const struct alpha_pll_config *config)
|
2515 | 2678 | {
|
|
0 commit comments