^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2014 Marvell Technology Group Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Alexandre Belloni <alexandre.belloni@free-electrons.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "berlin2-avpll.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Berlin2 SoCs comprise up to two PLLs called AVPLL built upon a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * VCO with 8 channels each, channel 8 is the odd-one-out and does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * not provide mul/div.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Unfortunately, its registers are not named but just numbered. To
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * get in at least some kind of structure, we split each AVPLL into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * the VCOs and each channel into separate clock drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Also, here and there the VCO registers are a bit different with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * respect to bit shifts. Make sure to add a comment for those.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define NUM_CHANNELS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define AVPLL_CTRL(x) ((x) * 0x4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define VCO_CTRL0 AVPLL_CTRL(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* BG2/BG2CDs VCO_B has an additional shift of 4 for its VCO_CTRL0 reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define VCO_RESET BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define VCO_POWERUP BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define VCO_INTERPOL_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define VCO_INTERPOL_MASK (0xf << VCO_INTERPOL_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define VCO_REG1V45_SEL_SHIFT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define VCO_REG1V45_SEL(x) ((x) << VCO_REG1V45_SEL_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define VCO_REG1V45_SEL_1V40 VCO_REG1V45_SEL(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define VCO_REG1V45_SEL_1V45 VCO_REG1V45_SEL(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define VCO_REG1V45_SEL_1V50 VCO_REG1V45_SEL(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define VCO_REG1V45_SEL_1V55 VCO_REG1V45_SEL(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define VCO_REG1V45_SEL_MASK VCO_REG1V45_SEL(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define VCO_REG0V9_SEL_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define VCO_REG0V9_SEL_MASK (0xf << VCO_REG0V9_SEL_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define VCO_VTHCAL_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define VCO_VTHCAL(x) ((x) << VCO_VTHCAL_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define VCO_VTHCAL_0V90 VCO_VTHCAL(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define VCO_VTHCAL_0V95 VCO_VTHCAL(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define VCO_VTHCAL_1V00 VCO_VTHCAL(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define VCO_VTHCAL_1V05 VCO_VTHCAL(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define VCO_VTHCAL_MASK VCO_VTHCAL(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define VCO_KVCOEXT_SHIFT 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define VCO_KVCOEXT_MASK (0x3 << VCO_KVCOEXT_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define VCO_KVCOEXT_ENABLE BIT(17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define VCO_V2IEXT_SHIFT 18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define VCO_V2IEXT_MASK (0xf << VCO_V2IEXT_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define VCO_V2IEXT_ENABLE BIT(22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define VCO_SPEED_SHIFT 23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define VCO_SPEED(x) ((x) << VCO_SPEED_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define VCO_SPEED_1G08_1G21 VCO_SPEED(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define VCO_SPEED_1G21_1G40 VCO_SPEED(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define VCO_SPEED_1G40_1G61 VCO_SPEED(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define VCO_SPEED_1G61_1G86 VCO_SPEED(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define VCO_SPEED_1G86_2G00 VCO_SPEED(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define VCO_SPEED_2G00_2G22 VCO_SPEED(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define VCO_SPEED_2G22 VCO_SPEED(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define VCO_SPEED_MASK VCO_SPEED(0x7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define VCO_CLKDET_ENABLE BIT(26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define VCO_CTRL1 AVPLL_CTRL(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define VCO_REFDIV_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define VCO_REFDIV(x) ((x) << VCO_REFDIV_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define VCO_REFDIV_1 VCO_REFDIV(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define VCO_REFDIV_2 VCO_REFDIV(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define VCO_REFDIV_4 VCO_REFDIV(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define VCO_REFDIV_3 VCO_REFDIV(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define VCO_REFDIV_MASK VCO_REFDIV(0x3f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define VCO_FBDIV_SHIFT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define VCO_FBDIV(x) ((x) << VCO_FBDIV_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define VCO_FBDIV_MASK VCO_FBDIV(0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define VCO_ICP_SHIFT 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* PLL Charge Pump Current = 10uA * (x + 1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define VCO_ICP(x) ((x) << VCO_ICP_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define VCO_ICP_MASK VCO_ICP(0xf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define VCO_LOAD_CAP BIT(18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define VCO_CALIBRATION_START BIT(19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define VCO_FREQOFFSETn(x) AVPLL_CTRL(3 + (x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define VCO_FREQOFFSET_MASK 0x7ffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define VCO_CTRL10 AVPLL_CTRL(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define VCO_POWERUP_CH1 BIT(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define VCO_CTRL11 AVPLL_CTRL(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define VCO_CTRL12 AVPLL_CTRL(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define VCO_CTRL13 AVPLL_CTRL(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define VCO_CTRL14 AVPLL_CTRL(14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define VCO_CTRL15 AVPLL_CTRL(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define VCO_SYNC1n(x) AVPLL_CTRL(15 + (x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define VCO_SYNC1_MASK 0x1ffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define VCO_SYNC2n(x) AVPLL_CTRL(23 + (x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define VCO_SYNC2_MASK 0x1ffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define VCO_CTRL30 AVPLL_CTRL(30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define VCO_DPLL_CH1_ENABLE BIT(17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct berlin2_avpll_vco {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u8 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define to_avpll_vco(hw) container_of(hw, struct berlin2_avpll_vco, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static int berlin2_avpll_vco_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct berlin2_avpll_vco *vco = to_avpll_vco(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) reg = readl_relaxed(vco->base + VCO_CTRL0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (vco->flags & BERLIN2_AVPLL_BIT_QUIRK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) reg >>= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return !!(reg & VCO_POWERUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int berlin2_avpll_vco_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct berlin2_avpll_vco *vco = to_avpll_vco(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) reg = readl_relaxed(vco->base + VCO_CTRL0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (vco->flags & BERLIN2_AVPLL_BIT_QUIRK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) reg |= VCO_POWERUP << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) reg |= VCO_POWERUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) writel_relaxed(reg, vco->base + VCO_CTRL0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static void berlin2_avpll_vco_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct berlin2_avpll_vco *vco = to_avpll_vco(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) reg = readl_relaxed(vco->base + VCO_CTRL0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (vco->flags & BERLIN2_AVPLL_BIT_QUIRK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) reg &= ~(VCO_POWERUP << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) reg &= ~VCO_POWERUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) writel_relaxed(reg, vco->base + VCO_CTRL0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static u8 vco_refdiv[] = { 1, 2, 4, 3 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) berlin2_avpll_vco_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct berlin2_avpll_vco *vco = to_avpll_vco(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) u32 reg, refdiv, fbdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u64 freq = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* AVPLL VCO frequency: Fvco = (Fref / refdiv) * fbdiv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) reg = readl_relaxed(vco->base + VCO_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) refdiv = (reg & VCO_REFDIV_MASK) >> VCO_REFDIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) refdiv = vco_refdiv[refdiv];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) fbdiv = (reg & VCO_FBDIV_MASK) >> VCO_FBDIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) freq *= fbdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) do_div(freq, refdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return (unsigned long)freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static const struct clk_ops berlin2_avpll_vco_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .is_enabled = berlin2_avpll_vco_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .enable = berlin2_avpll_vco_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .disable = berlin2_avpll_vco_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .recalc_rate = berlin2_avpll_vco_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int __init berlin2_avpll_vco_register(void __iomem *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) const char *name, const char *parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) u8 vco_flags, unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct berlin2_avpll_vco *vco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) vco = kzalloc(sizeof(*vco), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (!vco)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) vco->base = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) vco->flags = vco_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) vco->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) init.ops = &berlin2_avpll_vco_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) init.parent_names = &parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) init.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return clk_hw_register(NULL, &vco->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct berlin2_avpll_channel {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) u8 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) u8 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #define to_avpll_channel(hw) container_of(hw, struct berlin2_avpll_channel, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static int berlin2_avpll_channel_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct berlin2_avpll_channel *ch = to_avpll_channel(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (ch->index == 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) reg = readl_relaxed(ch->base + VCO_CTRL10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) reg &= VCO_POWERUP_CH1 << ch->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return !!reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static int berlin2_avpll_channel_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct berlin2_avpll_channel *ch = to_avpll_channel(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) reg = readl_relaxed(ch->base + VCO_CTRL10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) reg |= VCO_POWERUP_CH1 << ch->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) writel_relaxed(reg, ch->base + VCO_CTRL10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static void berlin2_avpll_channel_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct berlin2_avpll_channel *ch = to_avpll_channel(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) reg = readl_relaxed(ch->base + VCO_CTRL10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) reg &= ~(VCO_POWERUP_CH1 << ch->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) writel_relaxed(reg, ch->base + VCO_CTRL10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static const u8 div_hdmi[] = { 1, 2, 4, 6 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static const u8 div_av1[] = { 1, 2, 5, 5 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) berlin2_avpll_channel_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct berlin2_avpll_channel *ch = to_avpll_channel(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) u32 reg, div_av2, div_av3, divider = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) u64 freq = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) reg = readl_relaxed(ch->base + VCO_CTRL30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if ((reg & (VCO_DPLL_CH1_ENABLE << ch->index)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) goto skip_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * Fch = (Fref * sync2) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * (sync1 * div_hdmi * div_av1 * div_av2 * div_av3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) reg = readl_relaxed(ch->base + VCO_SYNC1n(ch->index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* BG2/BG2CDs SYNC1 reg on AVPLL_B channel 1 is shifted by 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (ch->flags & BERLIN2_AVPLL_BIT_QUIRK && ch->index == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) reg >>= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) divider = reg & VCO_SYNC1_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) reg = readl_relaxed(ch->base + VCO_SYNC2n(ch->index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) freq *= reg & VCO_SYNC2_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* Channel 8 has no dividers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (ch->index == 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) goto skip_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * HDMI divider start at VCO_CTRL11, bit 7; MSB is enable, lower 2 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * determine divider.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) reg = readl_relaxed(ch->base + VCO_CTRL11) >> 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) reg = (reg >> (ch->index * 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (reg & BIT(2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) divider *= div_hdmi[reg & 0x3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * AV1 divider start at VCO_CTRL11, bit 28; MSB is enable, lower 2 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * determine divider.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (ch->index == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) reg = readl_relaxed(ch->base + VCO_CTRL11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) reg >>= 28;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) reg = readl_relaxed(ch->base + VCO_CTRL12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) reg >>= (ch->index-1) * 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (reg & BIT(2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) divider *= div_av1[reg & 0x3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * AV2 divider start at VCO_CTRL12, bit 18; each 7 bits wide,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * zero is not a valid value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (ch->index < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) reg = readl_relaxed(ch->base + VCO_CTRL12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) reg >>= 18 + (ch->index * 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) } else if (ch->index < 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) reg = readl_relaxed(ch->base + VCO_CTRL13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) reg >>= (ch->index - 2) * 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) reg = readl_relaxed(ch->base + VCO_CTRL14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) div_av2 = reg & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (div_av2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) divider *= div_av2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * AV3 divider start at VCO_CTRL14, bit 7; each 4 bits wide.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * AV2/AV3 form a fractional divider, where only specfic values for AV3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * are allowed. AV3 != 0 divides by AV2/2, AV3=0 is bypass.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (ch->index < 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) reg = readl_relaxed(ch->base + VCO_CTRL14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) reg >>= 7 + (ch->index * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) reg = readl_relaxed(ch->base + VCO_CTRL15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) div_av3 = reg & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (div_av2 && div_av3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) freq *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) skip_div:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) do_div(freq, divider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return (unsigned long)freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static const struct clk_ops berlin2_avpll_channel_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) .is_enabled = berlin2_avpll_channel_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) .enable = berlin2_avpll_channel_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) .disable = berlin2_avpll_channel_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) .recalc_rate = berlin2_avpll_channel_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * Another nice quirk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * On some production SoCs, AVPLL channels are scrambled with respect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * to the channel numbering in the registers but still referenced by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * their original channel numbers. We deal with it by having a flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * and a translation table for the index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static const u8 quirk_index[] __initconst = { 0, 6, 5, 4, 3, 2, 1, 7 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) int __init berlin2_avpll_channel_register(void __iomem *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) const char *name, u8 index, const char *parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) u8 ch_flags, unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) struct berlin2_avpll_channel *ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ch = kzalloc(sizeof(*ch), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (!ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) ch->base = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (ch_flags & BERLIN2_AVPLL_SCRAMBLE_QUIRK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) ch->index = quirk_index[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) ch->index = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ch->flags = ch_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) ch->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) init.ops = &berlin2_avpll_channel_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) init.parent_names = &parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) init.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return clk_hw_register(NULL, &ch->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }