^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2013, 2018, The Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/rational.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/math64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/div64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "clk-rcg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define CMD_REG 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define CMD_UPDATE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define CMD_ROOT_EN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define CMD_DIRTY_CFG BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define CMD_DIRTY_N BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define CMD_DIRTY_M BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define CMD_DIRTY_D BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define CMD_ROOT_OFF BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define CFG_REG 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define CFG_SRC_DIV_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define CFG_SRC_SEL_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define CFG_SRC_SEL_MASK (0x7 << CFG_SRC_SEL_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define CFG_MODE_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define CFG_MODE_MASK (0x3 << CFG_MODE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define CFG_MODE_DUAL_EDGE (0x2 << CFG_MODE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define CFG_HW_CLK_CTRL_MASK BIT(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define M_REG 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define N_REG 0xc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define D_REG 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define RCG_CFG_OFFSET(rcg) ((rcg)->cmd_rcgr + (rcg)->cfg_off + CFG_REG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define RCG_M_OFFSET(rcg) ((rcg)->cmd_rcgr + (rcg)->cfg_off + M_REG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define RCG_N_OFFSET(rcg) ((rcg)->cmd_rcgr + (rcg)->cfg_off + N_REG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define RCG_D_OFFSET(rcg) ((rcg)->cmd_rcgr + (rcg)->cfg_off + D_REG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* Dynamic Frequency Scaling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define MAX_PERF_LEVEL 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define SE_CMD_DFSR_OFFSET 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define SE_CMD_DFS_EN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define SE_PERF_DFSR(level) (0x1c + 0x4 * (level))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define SE_PERF_M_DFSR(level) (0x5c + 0x4 * (level))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define SE_PERF_N_DFSR(level) (0x9c + 0x4 * (level))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) enum freq_policy {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) FLOOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) CEIL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static int clk_rcg2_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) u32 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return (cmd & CMD_ROOT_OFF) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static u8 clk_rcg2_get_parent(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int num_parents = clk_hw_get_num_parents(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) u32 cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) ret = regmap_read(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), &cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) cfg &= CFG_SRC_SEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) cfg >>= CFG_SRC_SEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) for (i = 0; i < num_parents; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (cfg == rcg->parent_map[i].cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) pr_debug("%s: Clock %s has invalid parent, using default.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) __func__, clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static int update_config(struct clk_rcg2 *rcg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int count, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u32 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct clk_hw *hw = &rcg->clkr.hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) const char *name = clk_hw_get_name(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) CMD_UPDATE, CMD_UPDATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* Wait for update to take effect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) for (count = 500; count > 0; count--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (!(cmd & CMD_UPDATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) WARN(1, "%s: rcg didn't update its configuration.", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) u32 cfg = rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ret = regmap_update_bits(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) CFG_SRC_SEL_MASK, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return update_config(rcg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * Calculate m/n:d rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * parent_rate m
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * rate = ----------- x ---
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * hid_div n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 hid_div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (hid_div) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) rate *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) rate /= hid_div + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) u64 tmp = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) tmp *= m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) do_div(tmp, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) rate = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) clk_rcg2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) u32 cfg, hid_div, m = 0, n = 0, mode = 0, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) regmap_read(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), &cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (rcg->mnd_width) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) mask = BIT(rcg->mnd_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) regmap_read(rcg->clkr.regmap, RCG_M_OFFSET(rcg), &m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) m &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) regmap_read(rcg->clkr.regmap, RCG_N_OFFSET(rcg), &n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) n = ~n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) n &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) n += m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) mode = cfg & CFG_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) mode >>= CFG_MODE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) mask = BIT(rcg->hid_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) hid_div = cfg >> CFG_SRC_DIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) hid_div &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return calc_rate(parent_rate, m, n, mode, hid_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct clk_rate_request *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) enum freq_policy policy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) unsigned long clk_flags, rate = req->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct clk_hw *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) switch (policy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case FLOOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) f = qcom_find_freq_floor(f, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) case CEIL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) f = qcom_find_freq(f, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (!f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) index = qcom_find_src_index(hw, rcg->parent_map, f->src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (index < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) clk_flags = clk_hw_get_flags(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) p = clk_hw_get_parent_by_index(hw, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (clk_flags & CLK_SET_RATE_PARENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) rate = f->freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (f->pre_div) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) rate = req->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) rate /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) rate *= f->pre_div + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (f->n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) u64 tmp = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) tmp = tmp * f->n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) do_div(tmp, f->m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) rate = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) rate = clk_hw_get_rate(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) req->best_parent_hw = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) req->best_parent_rate = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) req->rate = f->freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static int clk_rcg2_determine_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct clk_rate_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return _freq_tbl_determine_rate(hw, rcg->freq_tbl, req, CEIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int clk_rcg2_determine_floor_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct clk_rate_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return _freq_tbl_determine_rate(hw, rcg->freq_tbl, req, FLOOR);
^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) static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u32 cfg, mask, d_val, not2d_val, n_minus_m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct clk_hw *hw = &rcg->clkr.hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int ret, index = qcom_find_src_index(hw, rcg->parent_map, f->src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (index < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (rcg->mnd_width && f->n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) mask = BIT(rcg->mnd_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ret = regmap_update_bits(rcg->clkr.regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) RCG_M_OFFSET(rcg), mask, f->m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) ret = regmap_update_bits(rcg->clkr.regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) RCG_N_OFFSET(rcg), mask, ~(f->n - f->m));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* Calculate 2d value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) d_val = f->n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) n_minus_m = f->n - f->m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) n_minus_m *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) d_val = clamp_t(u32, d_val, f->m, n_minus_m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) not2d_val = ~d_val & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) ret = regmap_update_bits(rcg->clkr.regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) RCG_D_OFFSET(rcg), mask, not2d_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) mask = BIT(rcg->hid_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) mask |= CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) cfg = f->pre_div << CFG_SRC_DIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (rcg->mnd_width && f->n && (f->m != f->n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) cfg |= CFG_MODE_DUAL_EDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return regmap_update_bits(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) mask, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) ret = __clk_rcg2_configure(rcg, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return update_config(rcg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) enum freq_policy policy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) const struct freq_tbl *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) switch (policy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) case FLOOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) f = qcom_find_freq_floor(rcg->freq_tbl, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) case CEIL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) f = qcom_find_freq(rcg->freq_tbl, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (!f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return clk_rcg2_configure(rcg, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static int clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return __clk_rcg2_set_rate(hw, rate, CEIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static int clk_rcg2_set_floor_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return __clk_rcg2_set_rate(hw, rate, FLOOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static int clk_rcg2_set_rate_and_parent(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) unsigned long rate, unsigned long parent_rate, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return __clk_rcg2_set_rate(hw, rate, CEIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static int clk_rcg2_set_floor_rate_and_parent(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) unsigned long rate, unsigned long parent_rate, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return __clk_rcg2_set_rate(hw, rate, FLOOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) const struct clk_ops clk_rcg2_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .is_enabled = clk_rcg2_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .get_parent = clk_rcg2_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .set_parent = clk_rcg2_set_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .recalc_rate = clk_rcg2_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) .determine_rate = clk_rcg2_determine_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) .set_rate = clk_rcg2_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) .set_rate_and_parent = clk_rcg2_set_rate_and_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) EXPORT_SYMBOL_GPL(clk_rcg2_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) const struct clk_ops clk_rcg2_floor_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) .is_enabled = clk_rcg2_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) .get_parent = clk_rcg2_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) .set_parent = clk_rcg2_set_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) .recalc_rate = clk_rcg2_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) .determine_rate = clk_rcg2_determine_floor_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) .set_rate = clk_rcg2_set_floor_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) .set_rate_and_parent = clk_rcg2_set_floor_rate_and_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) EXPORT_SYMBOL_GPL(clk_rcg2_floor_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) struct frac_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) int den;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static const struct frac_entry frac_table_675m[] = { /* link rate of 270M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) { 52, 295 }, /* 119 M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) { 11, 57 }, /* 130.25 M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) { 63, 307 }, /* 138.50 M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) { 11, 50 }, /* 148.50 M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) { 47, 206 }, /* 154 M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) { 31, 100 }, /* 205.25 M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) { 107, 269 }, /* 268.50 M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static struct frac_entry frac_table_810m[] = { /* Link rate of 162M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) { 31, 211 }, /* 119 M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) { 32, 199 }, /* 130.25 M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) { 63, 307 }, /* 138.50 M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) { 11, 60 }, /* 148.50 M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) { 50, 263 }, /* 154 M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) { 31, 120 }, /* 205.25 M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) { 119, 359 }, /* 268.50 M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static int clk_edp_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) struct freq_tbl f = *rcg->freq_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) const struct frac_entry *frac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) int delta = 100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) s64 src_rate = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) s64 request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) u32 mask = BIT(rcg->hid_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) u32 hid_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (src_rate == 810000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) frac = frac_table_810m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) frac = frac_table_675m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) for (; frac->num; frac++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) request = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) request *= frac->den;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) request = div_s64(request, frac->num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if ((src_rate < (request - delta)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) (src_rate > (request + delta)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) &hid_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) f.pre_div = hid_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) f.pre_div >>= CFG_SRC_DIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) f.pre_div &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) f.m = frac->num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) f.n = frac->den;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return clk_rcg2_configure(rcg, &f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static int clk_edp_pixel_set_rate_and_parent(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) unsigned long rate, unsigned long parent_rate, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /* Parent index is set statically in frequency table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return clk_edp_pixel_set_rate(hw, rate, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) static int clk_edp_pixel_determine_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct clk_rate_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) const struct freq_tbl *f = rcg->freq_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) const struct frac_entry *frac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) int delta = 100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) s64 request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) u32 mask = BIT(rcg->hid_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) u32 hid_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) int index = qcom_find_src_index(hw, rcg->parent_map, f->src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /* Force the correct parent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) req->best_parent_hw = clk_hw_get_parent_by_index(hw, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) req->best_parent_rate = clk_hw_get_rate(req->best_parent_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (req->best_parent_rate == 810000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) frac = frac_table_810m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) frac = frac_table_675m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) for (; frac->num; frac++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) request = req->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) request *= frac->den;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) request = div_s64(request, frac->num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if ((req->best_parent_rate < (request - delta)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) (req->best_parent_rate > (request + delta)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) &hid_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) hid_div >>= CFG_SRC_DIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) hid_div &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) req->rate = calc_rate(req->best_parent_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) frac->num, frac->den,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) !!frac->den, hid_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) const struct clk_ops clk_edp_pixel_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .is_enabled = clk_rcg2_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) .get_parent = clk_rcg2_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) .set_parent = clk_rcg2_set_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) .recalc_rate = clk_rcg2_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) .set_rate = clk_edp_pixel_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) .set_rate_and_parent = clk_edp_pixel_set_rate_and_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) .determine_rate = clk_edp_pixel_determine_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) EXPORT_SYMBOL_GPL(clk_edp_pixel_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static int clk_byte_determine_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) struct clk_rate_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) const struct freq_tbl *f = rcg->freq_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) int index = qcom_find_src_index(hw, rcg->parent_map, f->src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) unsigned long parent_rate, div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) u32 mask = BIT(rcg->hid_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct clk_hw *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (req->rate == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) req->best_parent_hw = p = clk_hw_get_parent_by_index(hw, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) req->best_parent_rate = parent_rate = clk_hw_round_rate(p, req->rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) div = DIV_ROUND_UP((2 * parent_rate), req->rate) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) div = min_t(u32, div, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) req->rate = calc_rate(parent_rate, 0, 0, 0, div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static int clk_byte_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) struct freq_tbl f = *rcg->freq_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) unsigned long div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) u32 mask = BIT(rcg->hid_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) div = DIV_ROUND_UP((2 * parent_rate), rate) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) div = min_t(u32, div, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) f.pre_div = div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return clk_rcg2_configure(rcg, &f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static int clk_byte_set_rate_and_parent(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) unsigned long rate, unsigned long parent_rate, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /* Parent index is set statically in frequency table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return clk_byte_set_rate(hw, rate, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) const struct clk_ops clk_byte_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) .is_enabled = clk_rcg2_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) .get_parent = clk_rcg2_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .set_parent = clk_rcg2_set_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) .recalc_rate = clk_rcg2_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) .set_rate = clk_byte_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) .set_rate_and_parent = clk_byte_set_rate_and_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .determine_rate = clk_byte_determine_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) EXPORT_SYMBOL_GPL(clk_byte_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static int clk_byte2_determine_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) struct clk_rate_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) unsigned long parent_rate, div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) u32 mask = BIT(rcg->hid_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct clk_hw *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) unsigned long rate = req->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (rate == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) p = req->best_parent_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) req->best_parent_rate = parent_rate = clk_hw_round_rate(p, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) div = DIV_ROUND_UP((2 * parent_rate), rate) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) div = min_t(u32, div, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) req->rate = calc_rate(parent_rate, 0, 0, 0, div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static int clk_byte2_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct freq_tbl f = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) unsigned long div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) int i, num_parents = clk_hw_get_num_parents(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) u32 mask = BIT(rcg->hid_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) u32 cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) div = DIV_ROUND_UP((2 * parent_rate), rate) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) div = min_t(u32, div, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) f.pre_div = div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) cfg &= CFG_SRC_SEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) cfg >>= CFG_SRC_SEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) for (i = 0; i < num_parents; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (cfg == rcg->parent_map[i].cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) f.src = rcg->parent_map[i].src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return clk_rcg2_configure(rcg, &f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static int clk_byte2_set_rate_and_parent(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) unsigned long rate, unsigned long parent_rate, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /* Read the hardware to determine parent during set_rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return clk_byte2_set_rate(hw, rate, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) const struct clk_ops clk_byte2_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) .is_enabled = clk_rcg2_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .get_parent = clk_rcg2_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .set_parent = clk_rcg2_set_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) .recalc_rate = clk_rcg2_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) .set_rate = clk_byte2_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) .set_rate_and_parent = clk_byte2_set_rate_and_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) .determine_rate = clk_byte2_determine_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) EXPORT_SYMBOL_GPL(clk_byte2_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static const struct frac_entry frac_table_pixel[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) { 3, 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) { 2, 9 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) { 4, 9 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) { 1, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) { 2, 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static int clk_pixel_determine_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct clk_rate_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) unsigned long request, src_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) int delta = 100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) const struct frac_entry *frac = frac_table_pixel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) for (; frac->num; frac++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) request = (req->rate * frac->den) / frac->num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) src_rate = clk_hw_round_rate(req->best_parent_hw, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if ((src_rate < (request - delta)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) (src_rate > (request + delta)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) req->best_parent_rate = src_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) req->rate = (src_rate * frac->num) / frac->den;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return -EINVAL;
^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) static int clk_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct freq_tbl f = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) const struct frac_entry *frac = frac_table_pixel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) unsigned long request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) int delta = 100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) u32 mask = BIT(rcg->hid_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) u32 hid_div, cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) int i, num_parents = clk_hw_get_num_parents(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) cfg &= CFG_SRC_SEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) cfg >>= CFG_SRC_SEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) for (i = 0; i < num_parents; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (cfg == rcg->parent_map[i].cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) f.src = rcg->parent_map[i].src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) for (; frac->num; frac++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) request = (rate * frac->den) / frac->num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if ((parent_rate < (request - delta)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) (parent_rate > (request + delta)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) &hid_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) f.pre_div = hid_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) f.pre_div >>= CFG_SRC_DIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) f.pre_div &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) f.m = frac->num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) f.n = frac->den;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return clk_rcg2_configure(rcg, &f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) static int clk_pixel_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) unsigned long parent_rate, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return clk_pixel_set_rate(hw, rate, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) const struct clk_ops clk_pixel_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) .is_enabled = clk_rcg2_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) .get_parent = clk_rcg2_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) .set_parent = clk_rcg2_set_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) .recalc_rate = clk_rcg2_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) .set_rate = clk_pixel_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) .set_rate_and_parent = clk_pixel_set_rate_and_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) .determine_rate = clk_pixel_determine_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) EXPORT_SYMBOL_GPL(clk_pixel_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) static int clk_gfx3d_determine_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct clk_rate_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct clk_rate_request parent_req = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) struct clk_hw *p2, *p8, *p9, *xo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) unsigned long p9_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) xo = clk_hw_get_parent_by_index(hw, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (req->rate == clk_hw_get_rate(xo)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) req->best_parent_hw = xo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return 0;
^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) p9 = clk_hw_get_parent_by_index(hw, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) p2 = clk_hw_get_parent_by_index(hw, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) p8 = clk_hw_get_parent_by_index(hw, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /* PLL9 is a fixed rate PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) p9_rate = clk_hw_get_rate(p9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) parent_req.rate = req->rate = min(req->rate, p9_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (req->rate == p9_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) req->rate = req->best_parent_rate = p9_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) req->best_parent_hw = p9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (req->best_parent_hw == p9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) /* Are we going back to a previously used rate? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (clk_hw_get_rate(p8) == req->rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) req->best_parent_hw = p8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) req->best_parent_hw = p2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) } else if (req->best_parent_hw == p8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) req->best_parent_hw = p2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) req->best_parent_hw = p8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) ret = __clk_determine_rate(req->best_parent_hw, &parent_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) req->rate = req->best_parent_rate = parent_req.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return 0;
^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 int clk_gfx3d_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) unsigned long parent_rate, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) u32 cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /* Just mux it, we don't use the division or m/n hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) cfg = rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) ret = regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return update_config(rcg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) static int clk_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) * We should never get here; clk_gfx3d_determine_rate() should always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * make us use a different parent than what we're currently using, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * clk_gfx3d_set_rate_and_parent() should always be called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) const struct clk_ops clk_gfx3d_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) .is_enabled = clk_rcg2_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) .get_parent = clk_rcg2_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) .set_parent = clk_rcg2_set_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) .recalc_rate = clk_rcg2_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) .set_rate = clk_gfx3d_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) .set_rate_and_parent = clk_gfx3d_set_rate_and_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) .determine_rate = clk_gfx3d_determine_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) EXPORT_SYMBOL_GPL(clk_gfx3d_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) static int clk_rcg2_set_force_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) const char *name = clk_hw_get_name(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) int ret, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) CMD_ROOT_EN, CMD_ROOT_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) /* wait for RCG to turn ON */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) for (count = 500; count > 0; count--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (clk_rcg2_is_enabled(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) pr_err("%s: RCG did not turn on\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) static int clk_rcg2_clear_force_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) return regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) CMD_ROOT_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) clk_rcg2_shared_force_enable_clear(struct clk_hw *hw, const struct freq_tbl *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) ret = clk_rcg2_set_force_enable(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) ret = clk_rcg2_configure(rcg, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return clk_rcg2_clear_force_enable(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) const struct freq_tbl *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) f = qcom_find_freq(rcg->freq_tbl, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (!f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) * In case clock is disabled, update the CFG, M, N and D registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) * and don't hit the update bit of CMD register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (!__clk_is_enabled(hw->clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) return __clk_rcg2_configure(rcg, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) return clk_rcg2_shared_force_enable_clear(hw, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) static int clk_rcg2_shared_set_rate_and_parent(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) unsigned long rate, unsigned long parent_rate, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return clk_rcg2_shared_set_rate(hw, rate, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) static int clk_rcg2_shared_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) * Set the update bit because required configuration has already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) * been written in clk_rcg2_shared_set_rate()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) ret = clk_rcg2_set_force_enable(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) ret = update_config(rcg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return clk_rcg2_clear_force_enable(hw);
^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) static void clk_rcg2_shared_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) u32 cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * Store current configuration as switching to safe source would clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * the SRC and DIV of CFG register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) * Park the RCG at a safe configuration - sourced off of safe source.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) * Force enable and disable the RCG while configuring it to safeguard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) * against any update signal coming from the downstream clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) * The current parent is still prepared and enabled at this point, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * the safe source is always on while application processor subsystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) * is online. Therefore, the RCG can safely switch its parent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) clk_rcg2_set_force_enable(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) rcg->safe_src_index << CFG_SRC_SEL_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) update_config(rcg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) clk_rcg2_clear_force_enable(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) /* Write back the stored configuration corresponding to current rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) const struct clk_ops clk_rcg2_shared_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) .enable = clk_rcg2_shared_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) .disable = clk_rcg2_shared_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) .get_parent = clk_rcg2_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) .set_parent = clk_rcg2_set_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) .recalc_rate = clk_rcg2_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) .determine_rate = clk_rcg2_determine_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) .set_rate = clk_rcg2_shared_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) /* Common APIs to be used for DFS based RCGR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static void clk_rcg2_dfs_populate_freq(struct clk_hw *hw, unsigned int l,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) struct freq_tbl *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) struct clk_hw *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) unsigned long prate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) u32 val, mask, cfg, mode, src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) int i, num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_DFSR(l), &cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) mask = BIT(rcg->hid_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) f->pre_div = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (cfg & mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) f->pre_div = cfg & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) src = cfg & CFG_SRC_SEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) src >>= CFG_SRC_SEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) num_parents = clk_hw_get_num_parents(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) for (i = 0; i < num_parents; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (src == rcg->parent_map[i].cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) f->src = rcg->parent_map[i].src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) p = clk_hw_get_parent_by_index(&rcg->clkr.hw, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) prate = clk_hw_get_rate(p);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) mode = cfg & CFG_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) mode >>= CFG_MODE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) if (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) mask = BIT(rcg->mnd_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_M_DFSR(l),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) val &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) f->m = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_N_DFSR(l),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) val = ~val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) val &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) val += f->m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) f->n = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) f->freq = calc_rate(prate, f->m, f->n, mode, f->pre_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) static int clk_rcg2_dfs_populate_freq_table(struct clk_rcg2 *rcg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) struct freq_tbl *freq_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) /* Allocate space for 1 extra since table is NULL terminated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) freq_tbl = kcalloc(MAX_PERF_LEVEL + 1, sizeof(*freq_tbl), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) if (!freq_tbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) rcg->freq_tbl = freq_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) for (i = 0; i < MAX_PERF_LEVEL; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) clk_rcg2_dfs_populate_freq(&rcg->clkr.hw, i, freq_tbl + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) static int clk_rcg2_dfs_determine_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) struct clk_rate_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (!rcg->freq_tbl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) ret = clk_rcg2_dfs_populate_freq_table(rcg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) pr_err("Failed to update DFS tables for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) return clk_rcg2_determine_rate(hw, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) clk_rcg2_dfs_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) u32 level, mask, cfg, m = 0, n = 0, mode, pre_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) regmap_read(rcg->clkr.regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) rcg->cmd_rcgr + SE_CMD_DFSR_OFFSET, &level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) level &= GENMASK(4, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) level >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (rcg->freq_tbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return rcg->freq_tbl[level].freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) * Assume that parent_rate is actually the parent because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) * we can't do any better at figuring it out when the table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) * hasn't been populated yet. We only populate the table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) * in determine_rate because we can't guarantee the parents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) * will be registered with the framework until then.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_DFSR(level),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) &cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) mask = BIT(rcg->hid_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) pre_div = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (cfg & mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) pre_div = cfg & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) mode = cfg & CFG_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) mode >>= CFG_MODE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) mask = BIT(rcg->mnd_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) regmap_read(rcg->clkr.regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) rcg->cmd_rcgr + SE_PERF_M_DFSR(level), &m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) m &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) regmap_read(rcg->clkr.regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) rcg->cmd_rcgr + SE_PERF_N_DFSR(level), &n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) n = ~n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) n &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) n += m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) return calc_rate(parent_rate, m, n, mode, pre_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) static const struct clk_ops clk_rcg2_dfs_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) .is_enabled = clk_rcg2_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) .get_parent = clk_rcg2_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) .determine_rate = clk_rcg2_dfs_determine_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) .recalc_rate = clk_rcg2_dfs_recalc_rate,
^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 clk_rcg2_enable_dfs(const struct clk_rcg_dfs_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) struct regmap *regmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) struct clk_rcg2 *rcg = data->rcg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) struct clk_init_data *init = data->init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) ret = regmap_read(regmap, rcg->cmd_rcgr + SE_CMD_DFSR_OFFSET, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (!(val & SE_CMD_DFS_EN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) * Rate changes with consumer writing a register in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) * their own I/O region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) init->flags |= CLK_GET_RATE_NOCACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) init->ops = &clk_rcg2_dfs_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) rcg->freq_tbl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) int qcom_cc_register_rcg_dfs(struct regmap *regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) const struct clk_rcg_dfs_data *rcgs, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) ret = clk_rcg2_enable_dfs(&rcgs[i], regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) EXPORT_SYMBOL_GPL(qcom_cc_register_rcg_dfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) static int clk_rcg2_dp_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) struct freq_tbl f = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) u32 mask = BIT(rcg->hid_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) u32 hid_div, cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) int i, num_parents = clk_hw_get_num_parents(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) unsigned long num, den;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) rational_best_approximation(parent_rate, rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) GENMASK(rcg->mnd_width - 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) GENMASK(rcg->mnd_width - 1, 0), &den, &num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (!num || !den)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) hid_div = cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) cfg &= CFG_SRC_SEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) cfg >>= CFG_SRC_SEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) for (i = 0; i < num_parents; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (cfg == rcg->parent_map[i].cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) f.src = rcg->parent_map[i].src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) f.pre_div = hid_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) f.pre_div >>= CFG_SRC_DIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) f.pre_div &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (num != den) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) f.m = num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) f.n = den;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) f.m = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) f.n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) return clk_rcg2_configure(rcg, &f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) static int clk_rcg2_dp_set_rate_and_parent(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) unsigned long rate, unsigned long parent_rate, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) return clk_rcg2_dp_set_rate(hw, rate, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) static int clk_rcg2_dp_determine_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) struct clk_rate_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) struct clk_rcg2 *rcg = to_clk_rcg2(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) unsigned long num, den;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) u64 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) /* Parent rate is a fixed phy link rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) rational_best_approximation(req->best_parent_rate, req->rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) GENMASK(rcg->mnd_width - 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) GENMASK(rcg->mnd_width - 1, 0), &den, &num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) if (!num || !den)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) tmp = req->best_parent_rate * num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) do_div(tmp, den);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) req->rate = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) const struct clk_ops clk_dp_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) .is_enabled = clk_rcg2_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) .get_parent = clk_rcg2_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) .set_parent = clk_rcg2_set_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) .recalc_rate = clk_rcg2_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) .set_rate = clk_rcg2_dp_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) .set_rate_and_parent = clk_rcg2_dp_set_rate_and_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) .determine_rate = clk_rcg2_dp_determine_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) EXPORT_SYMBOL_GPL(clk_dp_ops);