^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2013 Samsung Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2013 Linaro Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This file contains the utility functions to register the pll clocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/hrtimer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "clk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "clk-pll.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define PLL_TIMEOUT_MS 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct samsung_clk_pll {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) void __iomem *lock_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) void __iomem *con_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* PLL enable control bit offset in @con_reg register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) unsigned short enable_offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* PLL lock status bit offset in @con_reg register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) unsigned short lock_offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) enum samsung_pll_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned int rate_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) const struct samsung_pll_rate_table *rate_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static const struct samsung_pll_rate_table *samsung_get_pll_settings(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct samsung_clk_pll *pll, unsigned long rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) const struct samsung_pll_rate_table *rate_table = pll->rate_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) for (i = 0; i < pll->rate_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (rate == rate_table[i].rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return &rate_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static long samsung_pll_round_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) unsigned long drate, unsigned long *prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) const struct samsung_pll_rate_table *rate_table = pll->rate_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* Assumming rate_table is in descending order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) for (i = 0; i < pll->rate_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (drate >= rate_table[i].rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return rate_table[i].rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* return minimum supported value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return rate_table[i - 1].rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static int samsung_pll3xxx_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) tmp = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) tmp |= BIT(pll->enable_offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) writel_relaxed(tmp, pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* wait lock time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) tmp = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) } while (!(tmp & BIT(pll->lock_offs)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static void samsung_pll3xxx_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) tmp = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) tmp &= ~BIT(pll->enable_offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) writel_relaxed(tmp, pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * PLL2126 Clock Type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define PLL2126_MDIV_MASK (0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define PLL2126_PDIV_MASK (0x3f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define PLL2126_SDIV_MASK (0x3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define PLL2126_MDIV_SHIFT (16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define PLL2126_PDIV_SHIFT (8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define PLL2126_SDIV_SHIFT (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static unsigned long samsung_pll2126_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u32 pll_con, mdiv, pdiv, sdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u64 fvco = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) pll_con = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) mdiv = (pll_con >> PLL2126_MDIV_SHIFT) & PLL2126_MDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) pdiv = (pll_con >> PLL2126_PDIV_SHIFT) & PLL2126_PDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) sdiv = (pll_con >> PLL2126_SDIV_SHIFT) & PLL2126_SDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) fvco *= (mdiv + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) do_div(fvco, (pdiv + 2) << sdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return (unsigned long)fvco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static const struct clk_ops samsung_pll2126_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .recalc_rate = samsung_pll2126_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * PLL3000 Clock Type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define PLL3000_MDIV_MASK (0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define PLL3000_PDIV_MASK (0x3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define PLL3000_SDIV_MASK (0x3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define PLL3000_MDIV_SHIFT (16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define PLL3000_PDIV_SHIFT (8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define PLL3000_SDIV_SHIFT (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static unsigned long samsung_pll3000_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) u32 pll_con, mdiv, pdiv, sdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u64 fvco = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) pll_con = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) mdiv = (pll_con >> PLL3000_MDIV_SHIFT) & PLL3000_MDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) pdiv = (pll_con >> PLL3000_PDIV_SHIFT) & PLL3000_PDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) sdiv = (pll_con >> PLL3000_SDIV_SHIFT) & PLL3000_SDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) fvco *= (2 * (mdiv + 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) do_div(fvco, pdiv << sdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return (unsigned long)fvco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static const struct clk_ops samsung_pll3000_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .recalc_rate = samsung_pll3000_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * PLL35xx Clock Type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* Maximum lock time can be 270 * PDIV cycles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define PLL35XX_LOCK_FACTOR (270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define PLL35XX_MDIV_MASK (0x3FF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define PLL35XX_PDIV_MASK (0x3F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define PLL35XX_SDIV_MASK (0x7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define PLL35XX_MDIV_SHIFT (16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define PLL35XX_PDIV_SHIFT (8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define PLL35XX_SDIV_SHIFT (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define PLL35XX_LOCK_STAT_SHIFT (29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define PLL35XX_ENABLE_SHIFT (31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u32 mdiv, pdiv, sdiv, pll_con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) u64 fvco = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) pll_con = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) fvco *= mdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) do_div(fvco, (pdiv << sdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return (unsigned long)fvco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static inline bool samsung_pll35xx_mp_change(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) const struct samsung_pll_rate_table *rate, u32 pll_con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) u32 old_mdiv, old_pdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) const struct samsung_pll_rate_table *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Get required rate settings from table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) rate = samsung_get_pll_settings(pll, drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) drate, clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) tmp = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (!(samsung_pll35xx_mp_change(rate, tmp))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* If only s change, change just s value only*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) writel_relaxed(tmp, pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* Set PLL lock time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) writel_relaxed(rate->pdiv * PLL35XX_LOCK_FACTOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) pll->lock_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /* Change PLL PMS values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) (PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) (PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) (rate->pdiv << PLL35XX_PDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) (rate->sdiv << PLL35XX_SDIV_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) writel_relaxed(tmp, pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /* Wait until the PLL is locked if it is enabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (tmp & BIT(pll->enable_offs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) tmp = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) } while (!(tmp & BIT(pll->lock_offs)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static const struct clk_ops samsung_pll35xx_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) .recalc_rate = samsung_pll35xx_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .round_rate = samsung_pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .set_rate = samsung_pll35xx_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) .enable = samsung_pll3xxx_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) .disable = samsung_pll3xxx_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static const struct clk_ops samsung_pll35xx_clk_min_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) .recalc_rate = samsung_pll35xx_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * PLL36xx Clock Type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* Maximum lock time can be 3000 * PDIV cycles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) #define PLL36XX_LOCK_FACTOR (3000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) #define PLL36XX_KDIV_MASK (0xFFFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) #define PLL36XX_MDIV_MASK (0x1FF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) #define PLL36XX_PDIV_MASK (0x3F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #define PLL36XX_SDIV_MASK (0x7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) #define PLL36XX_MDIV_SHIFT (16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) #define PLL36XX_PDIV_SHIFT (8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) #define PLL36XX_SDIV_SHIFT (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) #define PLL36XX_KDIV_SHIFT (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #define PLL36XX_LOCK_STAT_SHIFT (29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) #define PLL36XX_ENABLE_SHIFT (31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) s16 kdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) u64 fvco = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) pll_con0 = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) pll_con1 = readl_relaxed(pll->con_reg + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) kdiv = (s16)(pll_con1 & PLL36XX_KDIV_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) fvco *= (mdiv << 16) + kdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) do_div(fvco, (pdiv << sdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) fvco >>= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return (unsigned long)fvco;
^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) static inline bool samsung_pll36xx_mpk_change(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) u32 old_mdiv, old_pdiv, old_kdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) rate->kdiv != old_kdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) u32 tmp, pll_con0, pll_con1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) const struct samsung_pll_rate_table *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) rate = samsung_get_pll_settings(pll, drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) drate, clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) pll_con0 = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) pll_con1 = readl_relaxed(pll->con_reg + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* If only s change, change just s value only*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) writel_relaxed(pll_con0, pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /* Set PLL lock time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) writel_relaxed(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* Change PLL PMS values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) (PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) (PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) (rate->pdiv << PLL36XX_PDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) (rate->sdiv << PLL36XX_SDIV_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) writel_relaxed(pll_con0, pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) writel_relaxed(pll_con1, pll->con_reg + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* wait_lock_time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (pll_con0 & BIT(pll->enable_offs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) tmp = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) } while (!(tmp & BIT(pll->lock_offs)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static const struct clk_ops samsung_pll36xx_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .recalc_rate = samsung_pll36xx_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .set_rate = samsung_pll36xx_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .round_rate = samsung_pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) .enable = samsung_pll3xxx_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) .disable = samsung_pll3xxx_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static const struct clk_ops samsung_pll36xx_clk_min_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) .recalc_rate = samsung_pll36xx_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * PLL45xx Clock Type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) #define PLL4502_LOCK_FACTOR 400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) #define PLL4508_LOCK_FACTOR 240
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) #define PLL45XX_MDIV_MASK (0x3FF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) #define PLL45XX_PDIV_MASK (0x3F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) #define PLL45XX_SDIV_MASK (0x7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) #define PLL45XX_AFC_MASK (0x1F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) #define PLL45XX_MDIV_SHIFT (16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) #define PLL45XX_PDIV_SHIFT (8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) #define PLL45XX_SDIV_SHIFT (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) #define PLL45XX_AFC_SHIFT (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) #define PLL45XX_ENABLE BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) #define PLL45XX_LOCKED BIT(29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) u32 mdiv, pdiv, sdiv, pll_con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) u64 fvco = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) pll_con = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (pll->type == pll_4508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) sdiv = sdiv - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) fvco *= mdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) do_div(fvco, (pdiv << sdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return (unsigned long)fvco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static bool samsung_pll45xx_mp_change(u32 pll_con0, u32 pll_con1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) const struct samsung_pll_rate_table *rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) u32 old_mdiv, old_pdiv, old_afc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) old_mdiv = (pll_con0 >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) old_pdiv = (pll_con0 >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) old_afc = (pll_con1 >> PLL45XX_AFC_SHIFT) & PLL45XX_AFC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) || old_afc != rate->afc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) const struct samsung_pll_rate_table *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) u32 con0, con1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ktime_t start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /* Get required rate settings from table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) rate = samsung_get_pll_settings(pll, drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) drate, clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) con0 = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) con1 = readl_relaxed(pll->con_reg + 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (!(samsung_pll45xx_mp_change(con0, con1, rate))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* If only s change, change just s value only*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) con0 &= ~(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) con0 |= rate->sdiv << PLL45XX_SDIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) writel_relaxed(con0, pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /* Set PLL PMS values. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) con0 &= ~((PLL45XX_MDIV_MASK << PLL45XX_MDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) (PLL45XX_PDIV_MASK << PLL45XX_PDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) (PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) con0 |= (rate->mdiv << PLL45XX_MDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) (rate->pdiv << PLL45XX_PDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) (rate->sdiv << PLL45XX_SDIV_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /* Set PLL AFC value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) con1 = readl_relaxed(pll->con_reg + 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) con1 &= ~(PLL45XX_AFC_MASK << PLL45XX_AFC_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) con1 |= (rate->afc << PLL45XX_AFC_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /* Set PLL lock time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) switch (pll->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) case pll_4502:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) writel_relaxed(rate->pdiv * PLL4502_LOCK_FACTOR, pll->lock_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) case pll_4508:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) writel_relaxed(rate->pdiv * PLL4508_LOCK_FACTOR, pll->lock_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) /* Set new configuration. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) writel_relaxed(con1, pll->con_reg + 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) writel_relaxed(con0, pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* Wait for locking. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) start = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) while (!(readl_relaxed(pll->con_reg) & PLL45XX_LOCKED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ktime_t delta = ktime_sub(ktime_get(), start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) pr_err("%s: could not lock PLL %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) __func__, clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) static const struct clk_ops samsung_pll45xx_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) .recalc_rate = samsung_pll45xx_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) .round_rate = samsung_pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) .set_rate = samsung_pll45xx_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) static const struct clk_ops samsung_pll45xx_clk_min_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) .recalc_rate = samsung_pll45xx_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * PLL46xx Clock Type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) #define PLL46XX_LOCK_FACTOR 3000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) #define PLL46XX_VSEL_MASK (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) #define PLL46XX_MDIV_MASK (0x1FF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) #define PLL1460X_MDIV_MASK (0x3FF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) #define PLL46XX_PDIV_MASK (0x3F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) #define PLL46XX_SDIV_MASK (0x7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) #define PLL46XX_VSEL_SHIFT (27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) #define PLL46XX_MDIV_SHIFT (16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) #define PLL46XX_PDIV_SHIFT (8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) #define PLL46XX_SDIV_SHIFT (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) #define PLL46XX_KDIV_MASK (0xFFFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) #define PLL4650C_KDIV_MASK (0xFFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) #define PLL46XX_KDIV_SHIFT (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) #define PLL46XX_MFR_MASK (0x3F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) #define PLL46XX_MRR_MASK (0x1F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) #define PLL46XX_KDIV_SHIFT (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) #define PLL46XX_MFR_SHIFT (16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) #define PLL46XX_MRR_SHIFT (24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) #define PLL46XX_ENABLE BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) #define PLL46XX_LOCKED BIT(29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) #define PLL46XX_VSEL BIT(27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) u64 fvco = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) pll_con0 = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) pll_con1 = readl_relaxed(pll->con_reg + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & ((pll->type == pll_1460x) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) PLL1460X_MDIV_MASK : PLL46XX_MDIV_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) pll_con1 & PLL46XX_KDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) shift = ((pll->type == pll_4600) || (pll->type == pll_1460x)) ? 16 : 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) fvco *= (mdiv << shift) + kdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) do_div(fvco, (pdiv << sdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) fvco >>= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return (unsigned long)fvco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static bool samsung_pll46xx_mpk_change(u32 pll_con0, u32 pll_con1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) const struct samsung_pll_rate_table *rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) u32 old_mdiv, old_pdiv, old_kdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) old_mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) old_pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) old_kdiv = (pll_con1 >> PLL46XX_KDIV_SHIFT) & PLL46XX_KDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) || old_kdiv != rate->kdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) const struct samsung_pll_rate_table *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) u32 con0, con1, lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ktime_t start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /* Get required rate settings from table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) rate = samsung_get_pll_settings(pll, drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) drate, clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) con0 = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) con1 = readl_relaxed(pll->con_reg + 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (!(samsung_pll46xx_mpk_change(con0, con1, rate))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /* If only s change, change just s value only*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) con0 &= ~(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) con0 |= rate->sdiv << PLL46XX_SDIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) writel_relaxed(con0, pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /* Set PLL lock time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) lock = rate->pdiv * PLL46XX_LOCK_FACTOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (lock > 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /* Maximum lock time bitfield is 16-bit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) lock = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) /* Set PLL PMS and VSEL values. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (pll->type == pll_1460x) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) con0 &= ~((PLL1460X_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) (PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) con0 |= rate->vsel << PLL46XX_VSEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) (rate->pdiv << PLL46XX_PDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) (rate->sdiv << PLL46XX_SDIV_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) /* Set PLL K, MFR and MRR values. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) con1 = readl_relaxed(pll->con_reg + 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) con1 &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) (PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) (PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) con1 |= (rate->kdiv << PLL46XX_KDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) (rate->mfr << PLL46XX_MFR_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) (rate->mrr << PLL46XX_MRR_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) /* Write configuration to PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) writel_relaxed(lock, pll->lock_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) writel_relaxed(con0, pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) writel_relaxed(con1, pll->con_reg + 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /* Wait for locking. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) start = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) while (!(readl_relaxed(pll->con_reg) & PLL46XX_LOCKED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) ktime_t delta = ktime_sub(ktime_get(), start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) pr_err("%s: could not lock PLL %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) __func__, clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static const struct clk_ops samsung_pll46xx_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) .recalc_rate = samsung_pll46xx_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) .round_rate = samsung_pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) .set_rate = samsung_pll46xx_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) static const struct clk_ops samsung_pll46xx_clk_min_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) .recalc_rate = samsung_pll46xx_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * PLL6552 Clock Type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) #define PLL6552_MDIV_MASK 0x3ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) #define PLL6552_PDIV_MASK 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) #define PLL6552_SDIV_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) #define PLL6552_MDIV_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) #define PLL6552_MDIV_SHIFT_2416 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) #define PLL6552_PDIV_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) #define PLL6552_PDIV_SHIFT_2416 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) #define PLL6552_SDIV_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) u32 mdiv, pdiv, sdiv, pll_con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) u64 fvco = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) pll_con = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (pll->type == pll_6552_s3c2416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) mdiv = (pll_con >> PLL6552_MDIV_SHIFT_2416) & PLL6552_MDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) pdiv = (pll_con >> PLL6552_PDIV_SHIFT_2416) & PLL6552_PDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) fvco *= mdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) do_div(fvco, (pdiv << sdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return (unsigned long)fvco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static const struct clk_ops samsung_pll6552_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) .recalc_rate = samsung_pll6552_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) * PLL6553 Clock Type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) #define PLL6553_MDIV_MASK 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) #define PLL6553_PDIV_MASK 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) #define PLL6553_SDIV_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) #define PLL6553_KDIV_MASK 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) #define PLL6553_MDIV_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) #define PLL6553_PDIV_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) #define PLL6553_SDIV_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) #define PLL6553_KDIV_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) u64 fvco = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) pll_con0 = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) pll_con1 = readl_relaxed(pll->con_reg + 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) fvco *= (mdiv << 16) + kdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) do_div(fvco, (pdiv << sdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) fvco >>= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return (unsigned long)fvco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) static const struct clk_ops samsung_pll6553_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) .recalc_rate = samsung_pll6553_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * PLL Clock Type of S3C24XX before S3C2443
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) #define PLLS3C2410_MDIV_MASK (0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) #define PLLS3C2410_PDIV_MASK (0x1f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) #define PLLS3C2410_SDIV_MASK (0x3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) #define PLLS3C2410_MDIV_SHIFT (12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) #define PLLS3C2410_PDIV_SHIFT (4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) #define PLLS3C2410_SDIV_SHIFT (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) #define PLLS3C2410_ENABLE_REG_OFFSET 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) static unsigned long samsung_s3c2410_pll_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) u32 pll_con, mdiv, pdiv, sdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) u64 fvco = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) pll_con = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) fvco *= (mdiv + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) do_div(fvco, (pdiv + 2) << sdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return (unsigned int)fvco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) static unsigned long samsung_s3c2440_mpll_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) u32 pll_con, mdiv, pdiv, sdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) u64 fvco = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) pll_con = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) fvco *= (2 * (mdiv + 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) do_div(fvco, (pdiv + 2) << sdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return (unsigned int)fvco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) static int samsung_s3c2410_pll_set_rate(struct clk_hw *hw, unsigned long drate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) const struct samsung_pll_rate_table *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) /* Get required rate settings from table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) rate = samsung_get_pll_settings(pll, drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) drate, clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) tmp = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) /* Change PLL PMS values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) tmp &= ~((PLLS3C2410_MDIV_MASK << PLLS3C2410_MDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) (PLLS3C2410_PDIV_MASK << PLLS3C2410_PDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) (PLLS3C2410_SDIV_MASK << PLLS3C2410_SDIV_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) tmp |= (rate->mdiv << PLLS3C2410_MDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) (rate->pdiv << PLLS3C2410_PDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) (rate->sdiv << PLLS3C2410_SDIV_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) writel_relaxed(tmp, pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /* Time to settle according to the manual */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) udelay(300);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) static int samsung_s3c2410_pll_enable(struct clk_hw *hw, int bit, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) u32 pll_en = readl_relaxed(pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) u32 pll_en_orig = pll_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) pll_en &= ~BIT(bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) pll_en |= BIT(bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) writel_relaxed(pll_en, pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) /* if we started the UPLL, then allow to settle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (enable && (pll_en_orig & BIT(bit)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) udelay(300);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) static int samsung_s3c2410_mpll_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return samsung_s3c2410_pll_enable(hw, 5, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) static void samsung_s3c2410_mpll_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) samsung_s3c2410_pll_enable(hw, 5, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) static int samsung_s3c2410_upll_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return samsung_s3c2410_pll_enable(hw, 7, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) static void samsung_s3c2410_upll_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) samsung_s3c2410_pll_enable(hw, 7, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) static const struct clk_ops samsung_s3c2410_mpll_clk_min_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) .recalc_rate = samsung_s3c2410_pll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) .enable = samsung_s3c2410_mpll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) .disable = samsung_s3c2410_mpll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) static const struct clk_ops samsung_s3c2410_upll_clk_min_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) .recalc_rate = samsung_s3c2410_pll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) .enable = samsung_s3c2410_upll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) .disable = samsung_s3c2410_upll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) static const struct clk_ops samsung_s3c2440_mpll_clk_min_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) .recalc_rate = samsung_s3c2440_mpll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) .enable = samsung_s3c2410_mpll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) .disable = samsung_s3c2410_mpll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) static const struct clk_ops samsung_s3c2410_mpll_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) .recalc_rate = samsung_s3c2410_pll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) .enable = samsung_s3c2410_mpll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) .disable = samsung_s3c2410_mpll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) .round_rate = samsung_pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) .set_rate = samsung_s3c2410_pll_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) static const struct clk_ops samsung_s3c2410_upll_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) .recalc_rate = samsung_s3c2410_pll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) .enable = samsung_s3c2410_upll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) .disable = samsung_s3c2410_upll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) .round_rate = samsung_pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) .set_rate = samsung_s3c2410_pll_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) static const struct clk_ops samsung_s3c2440_mpll_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) .recalc_rate = samsung_s3c2440_mpll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) .enable = samsung_s3c2410_mpll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) .disable = samsung_s3c2410_mpll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) .round_rate = samsung_pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) .set_rate = samsung_s3c2410_pll_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) * PLL2550x Clock Type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) #define PLL2550X_R_MASK (0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) #define PLL2550X_P_MASK (0x3F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) #define PLL2550X_M_MASK (0x3FF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) #define PLL2550X_S_MASK (0x7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) #define PLL2550X_R_SHIFT (20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) #define PLL2550X_P_SHIFT (14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) #define PLL2550X_M_SHIFT (4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) #define PLL2550X_S_SHIFT (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) u32 r, p, m, s, pll_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) u64 fvco = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) pll_stat = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (!r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) p = (pll_stat >> PLL2550X_P_SHIFT) & PLL2550X_P_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) m = (pll_stat >> PLL2550X_M_SHIFT) & PLL2550X_M_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) s = (pll_stat >> PLL2550X_S_SHIFT) & PLL2550X_S_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) fvco *= m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) do_div(fvco, (p << s));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) return (unsigned long)fvco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) static const struct clk_ops samsung_pll2550x_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) .recalc_rate = samsung_pll2550x_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * PLL2550xx Clock Type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) /* Maximum lock time can be 270 * PDIV cycles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) #define PLL2550XX_LOCK_FACTOR 270
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) #define PLL2550XX_M_MASK 0x3FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) #define PLL2550XX_P_MASK 0x3F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) #define PLL2550XX_S_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) #define PLL2550XX_LOCK_STAT_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) #define PLL2550XX_M_SHIFT 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) #define PLL2550XX_P_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) #define PLL2550XX_S_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) #define PLL2550XX_LOCK_STAT_SHIFT 21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) static unsigned long samsung_pll2550xx_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) u32 mdiv, pdiv, sdiv, pll_con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) u64 fvco = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) pll_con = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) sdiv = (pll_con >> PLL2550XX_S_SHIFT) & PLL2550XX_S_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) fvco *= mdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) do_div(fvco, (pdiv << sdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) return (unsigned long)fvco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) static inline bool samsung_pll2550xx_mp_change(u32 mdiv, u32 pdiv, u32 pll_con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) u32 old_mdiv, old_pdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) old_mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) old_pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return mdiv != old_mdiv || pdiv != old_pdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static int samsung_pll2550xx_set_rate(struct clk_hw *hw, unsigned long drate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) const struct samsung_pll_rate_table *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) /* Get required rate settings from table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) rate = samsung_get_pll_settings(pll, drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) drate, clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) tmp = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (!(samsung_pll2550xx_mp_change(rate->mdiv, rate->pdiv, tmp))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) /* If only s change, change just s value only*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) tmp &= ~(PLL2550XX_S_MASK << PLL2550XX_S_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) tmp |= rate->sdiv << PLL2550XX_S_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) writel_relaxed(tmp, pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /* Set PLL lock time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) writel_relaxed(rate->pdiv * PLL2550XX_LOCK_FACTOR, pll->lock_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) /* Change PLL PMS values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) tmp &= ~((PLL2550XX_M_MASK << PLL2550XX_M_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) (PLL2550XX_P_MASK << PLL2550XX_P_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) (PLL2550XX_S_MASK << PLL2550XX_S_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) tmp |= (rate->mdiv << PLL2550XX_M_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) (rate->pdiv << PLL2550XX_P_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) (rate->sdiv << PLL2550XX_S_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) writel_relaxed(tmp, pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) /* wait_lock_time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) tmp = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) } while (!(tmp & (PLL2550XX_LOCK_STAT_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) << PLL2550XX_LOCK_STAT_SHIFT)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) static const struct clk_ops samsung_pll2550xx_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) .recalc_rate = samsung_pll2550xx_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) .round_rate = samsung_pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) .set_rate = samsung_pll2550xx_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) static const struct clk_ops samsung_pll2550xx_clk_min_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) .recalc_rate = samsung_pll2550xx_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) * PLL2650x Clock Type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) /* Maximum lock time can be 3000 * PDIV cycles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) #define PLL2650X_LOCK_FACTOR 3000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) #define PLL2650X_M_MASK 0x1ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) #define PLL2650X_P_MASK 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) #define PLL2650X_S_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) #define PLL2650X_K_MASK 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) #define PLL2650X_LOCK_STAT_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) #define PLL2650X_M_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) #define PLL2650X_P_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) #define PLL2650X_S_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) #define PLL2650X_K_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) #define PLL2650X_LOCK_STAT_SHIFT 29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) #define PLL2650X_PLL_ENABLE_SHIFT 31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) static unsigned long samsung_pll2650x_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) u64 fout = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) s16 kdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) pll_con0 = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) mdiv = (pll_con0 >> PLL2650X_M_SHIFT) & PLL2650X_M_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) pdiv = (pll_con0 >> PLL2650X_P_SHIFT) & PLL2650X_P_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) sdiv = (pll_con0 >> PLL2650X_S_SHIFT) & PLL2650X_S_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) pll_con1 = readl_relaxed(pll->con_reg + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) kdiv = (s16)((pll_con1 >> PLL2650X_K_SHIFT) & PLL2650X_K_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) fout *= (mdiv << 16) + kdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) do_div(fout, (pdiv << sdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) fout >>= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) return (unsigned long)fout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) static int samsung_pll2650x_set_rate(struct clk_hw *hw, unsigned long drate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) unsigned long prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) const struct samsung_pll_rate_table *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) u32 con0, con1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) /* Get required rate settings from table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) rate = samsung_get_pll_settings(pll, drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) drate, clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) con0 = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) con1 = readl_relaxed(pll->con_reg + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) /* Set PLL lock time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) writel_relaxed(rate->pdiv * PLL2650X_LOCK_FACTOR, pll->lock_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) /* Change PLL PMS values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) con0 &= ~((PLL2650X_M_MASK << PLL2650X_M_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) (PLL2650X_P_MASK << PLL2650X_P_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) (PLL2650X_S_MASK << PLL2650X_S_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) con0 |= (rate->mdiv << PLL2650X_M_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) (rate->pdiv << PLL2650X_P_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) (rate->sdiv << PLL2650X_S_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) con0 |= (1 << PLL2650X_PLL_ENABLE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) writel_relaxed(con0, pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) con1 &= ~(PLL2650X_K_MASK << PLL2650X_K_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) con1 |= ((rate->kdiv & PLL2650X_K_MASK) << PLL2650X_K_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) writel_relaxed(con1, pll->con_reg + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) con0 = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) } while (!(con0 & (PLL2650X_LOCK_STAT_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) << PLL2650X_LOCK_STAT_SHIFT)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) static const struct clk_ops samsung_pll2650x_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) .recalc_rate = samsung_pll2650x_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) .round_rate = samsung_pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) .set_rate = samsung_pll2650x_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) static const struct clk_ops samsung_pll2650x_clk_min_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) .recalc_rate = samsung_pll2650x_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) * PLL2650XX Clock Type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) /* Maximum lock time can be 3000 * PDIV cycles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) #define PLL2650XX_LOCK_FACTOR 3000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) #define PLL2650XX_MDIV_SHIFT 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) #define PLL2650XX_PDIV_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) #define PLL2650XX_SDIV_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) #define PLL2650XX_KDIV_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) #define PLL2650XX_MDIV_MASK 0x1ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) #define PLL2650XX_PDIV_MASK 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) #define PLL2650XX_SDIV_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) #define PLL2650XX_KDIV_MASK 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) #define PLL2650XX_PLL_ENABLE_SHIFT 23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) #define PLL2650XX_PLL_LOCKTIME_SHIFT 21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) #define PLL2650XX_PLL_FOUTMASK_SHIFT 31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) static unsigned long samsung_pll2650xx_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) u32 mdiv, pdiv, sdiv, pll_con0, pll_con2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) s16 kdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) u64 fvco = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) pll_con0 = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) pll_con2 = readl_relaxed(pll->con_reg + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) mdiv = (pll_con0 >> PLL2650XX_MDIV_SHIFT) & PLL2650XX_MDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) pdiv = (pll_con0 >> PLL2650XX_PDIV_SHIFT) & PLL2650XX_PDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) sdiv = (pll_con0 >> PLL2650XX_SDIV_SHIFT) & PLL2650XX_SDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) kdiv = (s16)(pll_con2 & PLL2650XX_KDIV_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) fvco *= (mdiv << 16) + kdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) do_div(fvco, (pdiv << sdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) fvco >>= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) return (unsigned long)fvco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) struct samsung_clk_pll *pll = to_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) u32 tmp, pll_con0, pll_con2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) const struct samsung_pll_rate_table *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) rate = samsung_get_pll_settings(pll, drate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) drate, clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) pll_con0 = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) pll_con2 = readl_relaxed(pll->con_reg + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) /* Change PLL PMS values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) pll_con0 &= ~(PLL2650XX_MDIV_MASK << PLL2650XX_MDIV_SHIFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) PLL2650XX_PDIV_MASK << PLL2650XX_PDIV_SHIFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) PLL2650XX_SDIV_MASK << PLL2650XX_SDIV_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) pll_con0 |= rate->mdiv << PLL2650XX_MDIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) pll_con0 |= rate->pdiv << PLL2650XX_PDIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) pll_con0 |= rate->sdiv << PLL2650XX_SDIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) pll_con0 |= 1 << PLL2650XX_PLL_ENABLE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) pll_con0 |= 1 << PLL2650XX_PLL_FOUTMASK_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) pll_con2 &= ~(PLL2650XX_KDIV_MASK << PLL2650XX_KDIV_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) pll_con2 |= ((~(rate->kdiv) + 1) & PLL2650XX_KDIV_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) << PLL2650XX_KDIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) /* Set PLL lock time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) writel_relaxed(PLL2650XX_LOCK_FACTOR * rate->pdiv, pll->lock_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) writel_relaxed(pll_con0, pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) writel_relaxed(pll_con2, pll->con_reg + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) tmp = readl_relaxed(pll->con_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) } while (!(tmp & (0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) static const struct clk_ops samsung_pll2650xx_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) .recalc_rate = samsung_pll2650xx_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) .set_rate = samsung_pll2650xx_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) .round_rate = samsung_pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) static const struct clk_ops samsung_pll2650xx_clk_min_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) .recalc_rate = samsung_pll2650xx_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) const struct samsung_pll_clock *pll_clk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) struct samsung_clk_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) int ret, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) pll = kzalloc(sizeof(*pll), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) if (!pll) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) pr_err("%s: could not allocate pll clk %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) __func__, pll_clk->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) init.name = pll_clk->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) init.flags = pll_clk->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) init.parent_names = &pll_clk->parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) if (pll_clk->rate_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) /* find count of rates in rate_table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) for (len = 0; pll_clk->rate_table[len].rate != 0; )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) pll->rate_count = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) pll->rate_table = kmemdup(pll_clk->rate_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) pll->rate_count *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) sizeof(struct samsung_pll_rate_table),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) WARN(!pll->rate_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) "%s: could not allocate rate table for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) __func__, pll_clk->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) switch (pll_clk->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) case pll_2126:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) init.ops = &samsung_pll2126_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) case pll_3000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) init.ops = &samsung_pll3000_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) /* clk_ops for 35xx and 2550 are similar */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) case pll_35xx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) case pll_2550:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) case pll_1450x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) case pll_1451x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) case pll_1452x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) pll->enable_offs = PLL35XX_ENABLE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) if (!pll->rate_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) init.ops = &samsung_pll35xx_clk_min_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) init.ops = &samsung_pll35xx_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) case pll_4500:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) init.ops = &samsung_pll45xx_clk_min_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) case pll_4502:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) case pll_4508:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) if (!pll->rate_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) init.ops = &samsung_pll45xx_clk_min_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) init.ops = &samsung_pll45xx_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) /* clk_ops for 36xx and 2650 are similar */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) case pll_36xx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) case pll_2650:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) pll->enable_offs = PLL36XX_ENABLE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) pll->lock_offs = PLL36XX_LOCK_STAT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (!pll->rate_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) init.ops = &samsung_pll36xx_clk_min_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) init.ops = &samsung_pll36xx_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) case pll_6552:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) case pll_6552_s3c2416:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) init.ops = &samsung_pll6552_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) case pll_6553:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) init.ops = &samsung_pll6553_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) case pll_4600:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) case pll_4650:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) case pll_4650c:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) case pll_1460x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) if (!pll->rate_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) init.ops = &samsung_pll46xx_clk_min_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) init.ops = &samsung_pll46xx_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) case pll_s3c2410_mpll:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) if (!pll->rate_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) init.ops = &samsung_s3c2410_mpll_clk_min_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) init.ops = &samsung_s3c2410_mpll_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) case pll_s3c2410_upll:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) if (!pll->rate_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) init.ops = &samsung_s3c2410_upll_clk_min_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) init.ops = &samsung_s3c2410_upll_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) case pll_s3c2440_mpll:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) if (!pll->rate_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) init.ops = &samsung_s3c2440_mpll_clk_min_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) init.ops = &samsung_s3c2440_mpll_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) case pll_2550x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) init.ops = &samsung_pll2550x_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) case pll_2550xx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) if (!pll->rate_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) init.ops = &samsung_pll2550xx_clk_min_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) init.ops = &samsung_pll2550xx_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) case pll_2650x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) if (!pll->rate_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) init.ops = &samsung_pll2650x_clk_min_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) init.ops = &samsung_pll2650x_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) case pll_2650xx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) if (!pll->rate_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) init.ops = &samsung_pll2650xx_clk_min_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) init.ops = &samsung_pll2650xx_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) pr_warn("%s: Unknown pll type for pll clk %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) __func__, pll_clk->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) pll->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) pll->type = pll_clk->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) pll->lock_reg = base + pll_clk->lock_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) pll->con_reg = base + pll_clk->con_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) ret = clk_hw_register(ctx->dev, &pll->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) pr_err("%s: failed to register pll clock %s : %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) __func__, pll_clk->name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) kfree(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) samsung_clk_add_lookup(ctx, &pll->hw, pll_clk->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) const struct samsung_pll_clock *pll_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) unsigned int nr_pll, void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) int cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) for (cnt = 0; cnt < nr_pll; cnt++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) _samsung_clk_register_pll(ctx, &pll_list[cnt], base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) }