^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) * Clock driver for TI Davinci PSC controllers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2017 David Lechner <david@lechnology.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on: drivers/clk/keystone/gate.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2013 Texas Instruments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Murali Karicheri <m-karicheri2@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Santosh Shilimkar <santosh.shilimkar@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * And: arch/arm/mach-davinci/psc.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Copyright (C) 2006 Texas Instruments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/clk/davinci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/clkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/pm_clock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/pm_domain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/reset-controller.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "psc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* PSC register offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define EPCPR 0x070
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define PTCMD 0x120
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define PTSTAT 0x128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define PDSTAT(n) (0x200 + 4 * (n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define PDCTL(n) (0x300 + 4 * (n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define MDSTAT(n) (0x800 + 4 * (n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define MDCTL(n) (0xa00 + 4 * (n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* PSC module states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) enum davinci_lpsc_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) LPSC_STATE_SWRSTDISABLE = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) LPSC_STATE_SYNCRST = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) LPSC_STATE_DISABLE = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) LPSC_STATE_ENABLE = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define MDSTAT_STATE_MASK GENMASK(5, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define MDSTAT_MCKOUT BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define PDSTAT_STATE_MASK GENMASK(4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define MDCTL_FORCE BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define MDCTL_LRESET BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define PDCTL_EPCGOOD BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define PDCTL_NEXT BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct davinci_psc_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct clk_onecell_data clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct genpd_onecell_data pm_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct reset_controller_dev rcdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^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) * struct davinci_lpsc_clk - LPSC clock structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * @dev: the device that provides this LPSC or NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * @hw: clk_hw for the LPSC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * @pm_domain: power domain for the LPSC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * @genpd_clk: clock reference owned by @pm_domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * @regmap: PSC MMIO region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * @md: Module domain (LPSC module id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * @pd: Power domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * @flags: LPSC_* quirk flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct davinci_lpsc_clk {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct generic_pm_domain pm_domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct clk *genpd_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) u32 md;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) u32 pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define to_davinci_psc_data(x) container_of(x, struct davinci_psc_data, x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define to_davinci_lpsc_clk(x) container_of(x, struct davinci_lpsc_clk, x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * best_dev_name - get the "best" device name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * @dev: the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * Returns the device tree compatible name if the device has a DT node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * otherwise return the device name. This is mainly needed because clkdev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * lookups are limited to 20 chars for dev_id and when using device tree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * dev_name(dev) is much longer than that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static inline const char *best_dev_name(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) const char *compatible;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (!of_property_read_string(dev->of_node, "compatible", &compatible))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return compatible;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return dev_name(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static void davinci_lpsc_config(struct davinci_lpsc_clk *lpsc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) enum davinci_lpsc_state next_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) u32 epcpr, pdstat, mdstat, ptstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) regmap_write_bits(lpsc->regmap, MDCTL(lpsc->md), MDSTAT_STATE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) next_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (lpsc->flags & LPSC_FORCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) regmap_write_bits(lpsc->regmap, MDCTL(lpsc->md), MDCTL_FORCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) MDCTL_FORCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) regmap_read(lpsc->regmap, PDSTAT(lpsc->pd), &pdstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if ((pdstat & PDSTAT_STATE_MASK) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) regmap_write_bits(lpsc->regmap, PDCTL(lpsc->pd), PDCTL_NEXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) PDCTL_NEXT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) regmap_write(lpsc->regmap, PTCMD, BIT(lpsc->pd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) regmap_read_poll_timeout(lpsc->regmap, EPCPR, epcpr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) epcpr & BIT(lpsc->pd), 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) regmap_write_bits(lpsc->regmap, PDCTL(lpsc->pd), PDCTL_EPCGOOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) PDCTL_EPCGOOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) regmap_write(lpsc->regmap, PTCMD, BIT(lpsc->pd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) regmap_read_poll_timeout(lpsc->regmap, PTSTAT, ptstat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) !(ptstat & BIT(lpsc->pd)), 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) regmap_read_poll_timeout(lpsc->regmap, MDSTAT(lpsc->md), mdstat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) (mdstat & MDSTAT_STATE_MASK) == next_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static int davinci_lpsc_clk_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) davinci_lpsc_config(lpsc, LPSC_STATE_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static void davinci_lpsc_clk_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) davinci_lpsc_config(lpsc, LPSC_STATE_DISABLE);
^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) static int davinci_lpsc_clk_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u32 mdstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) regmap_read(lpsc->regmap, MDSTAT(lpsc->md), &mdstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return (mdstat & MDSTAT_MCKOUT) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static const struct clk_ops davinci_lpsc_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) .enable = davinci_lpsc_clk_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) .disable = davinci_lpsc_clk_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .is_enabled = davinci_lpsc_clk_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static int davinci_psc_genpd_attach_dev(struct generic_pm_domain *pm_domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(pm_domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int ret;
^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) * pm_clk_remove_clk() will call clk_put(), so we have to use clk_get()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * to get the clock instead of using lpsc->hw.clk directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) clk = clk_get_sys(best_dev_name(lpsc->dev), clk_hw_get_name(&lpsc->hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return (PTR_ERR(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) ret = pm_clk_create(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) goto fail_clk_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) ret = pm_clk_add_clk(dev, clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) goto fail_pm_clk_destroy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) lpsc->genpd_clk = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) fail_pm_clk_destroy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) pm_clk_destroy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) fail_clk_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) clk_put(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return ret;
^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) static void davinci_psc_genpd_detach_dev(struct generic_pm_domain *pm_domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(pm_domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) pm_clk_remove_clk(dev, lpsc->genpd_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) pm_clk_destroy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) lpsc->genpd_clk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * davinci_lpsc_clk_register - register LPSC clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * @dev: the clocks's device or NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * @name: name of this clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * @parent_name: name of clock's parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * @regmap: PSC MMIO region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * @md: local PSC number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * @pd: power domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * @flags: LPSC_* flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static struct davinci_lpsc_clk *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) davinci_lpsc_clk_register(struct device *dev, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) const char *parent_name, struct regmap *regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) u32 md, u32 pd, u32 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct davinci_lpsc_clk *lpsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) bool is_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) lpsc = kzalloc(sizeof(*lpsc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (!lpsc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) init.ops = &davinci_lpsc_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) init.parent_names = (parent_name ? &parent_name : NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) init.num_parents = (parent_name ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) init.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (flags & LPSC_ALWAYS_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) init.flags |= CLK_IS_CRITICAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (flags & LPSC_SET_RATE_PARENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) init.flags |= CLK_SET_RATE_PARENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) lpsc->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) lpsc->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) lpsc->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) lpsc->md = md;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) lpsc->pd = pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) lpsc->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ret = clk_hw_register(dev, &lpsc->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) kfree(lpsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* for now, genpd is only registered when using device-tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (!dev || !dev->of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return lpsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* genpd attach needs a way to look up this clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ret = clk_hw_register_clkdev(&lpsc->hw, name, best_dev_name(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) lpsc->pm_domain.name = devm_kasprintf(dev, GFP_KERNEL, "%s: %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) best_dev_name(dev), name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) lpsc->pm_domain.attach_dev = davinci_psc_genpd_attach_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) lpsc->pm_domain.detach_dev = davinci_psc_genpd_detach_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) lpsc->pm_domain.flags = GENPD_FLAG_PM_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) is_on = davinci_lpsc_clk_is_enabled(&lpsc->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) pm_genpd_init(&lpsc->pm_domain, NULL, is_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return lpsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int davinci_lpsc_clk_reset(struct clk *clk, bool reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct clk_hw *hw = __clk_get_hw(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) u32 mdctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (IS_ERR_OR_NULL(lpsc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) mdctl = reset ? 0 : MDCTL_LRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) regmap_write_bits(lpsc->regmap, MDCTL(lpsc->md), MDCTL_LRESET, mdctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static int davinci_psc_reset_assert(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) unsigned long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) struct davinci_psc_data *psc = to_davinci_psc_data(rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct clk *clk = psc->clk_data.clks[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return davinci_lpsc_clk_reset(clk, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static int davinci_psc_reset_deassert(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) unsigned long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct davinci_psc_data *psc = to_davinci_psc_data(rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct clk *clk = psc->clk_data.clks[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return davinci_lpsc_clk_reset(clk, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static const struct reset_control_ops davinci_psc_reset_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) .assert = davinci_psc_reset_assert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) .deassert = davinci_psc_reset_deassert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static int davinci_psc_reset_of_xlate(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) const struct of_phandle_args *reset_spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct of_phandle_args clkspec = *reset_spec; /* discard const qualifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct clk_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct davinci_lpsc_clk *lpsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* the clock node is the same as the reset node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) clk = of_clk_get_from_provider(&clkspec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) hw = __clk_get_hw(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) lpsc = to_davinci_lpsc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) clk_put(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* not all modules support local reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (!(lpsc->flags & LPSC_LOCAL_RESET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return lpsc->md;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static const struct regmap_config davinci_psc_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static struct davinci_psc_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) __davinci_psc_register_clocks(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) const struct davinci_lpsc_clk_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) int num_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct davinci_psc_data *psc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct clk **clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct generic_pm_domain **pm_domains;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) psc = kzalloc(sizeof(*psc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (!psc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) clks = kmalloc_array(num_clks, sizeof(*clks), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (!clks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) goto err_free_psc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) psc->clk_data.clks = clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) psc->clk_data.clk_num = num_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * init array with error so that of_clk_src_onecell_get() doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * return NULL for gaps in the sparse array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) for (i = 0; i < num_clks; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) clks[i] = ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) pm_domains = kcalloc(num_clks, sizeof(*pm_domains), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (!pm_domains) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) goto err_free_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) psc->pm_data.domains = pm_domains;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) psc->pm_data.num_domains = num_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) regmap = regmap_init_mmio(dev, base, &davinci_psc_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (IS_ERR(regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) ret = PTR_ERR(regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) goto err_free_pm_domains;
^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) for (; info->name; info++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct davinci_lpsc_clk *lpsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) lpsc = davinci_lpsc_clk_register(dev, info->name, info->parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) regmap, info->md, info->pd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) info->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (IS_ERR(lpsc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) dev_warn(dev, "Failed to register %s (%ld)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) info->name, PTR_ERR(lpsc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) continue;
^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) clks[info->md] = lpsc->hw.clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) pm_domains[info->md] = &lpsc->pm_domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * for now, a reset controller is only registered when there is a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * to associate it with.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return psc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) psc->rcdev.ops = &davinci_psc_reset_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) psc->rcdev.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) psc->rcdev.dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) psc->rcdev.of_node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) psc->rcdev.of_reset_n_cells = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) psc->rcdev.of_xlate = davinci_psc_reset_of_xlate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) psc->rcdev.nr_resets = num_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) ret = devm_reset_controller_register(dev, &psc->rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) dev_warn(dev, "Failed to register reset controller (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return psc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) err_free_pm_domains:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) kfree(pm_domains);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) err_free_clks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) kfree(clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) err_free_psc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) kfree(psc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) int davinci_psc_register_clocks(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) const struct davinci_lpsc_clk_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) u8 num_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct davinci_psc_data *psc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) psc = __davinci_psc_register_clocks(dev, info, num_clks, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (IS_ERR(psc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return PTR_ERR(psc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) for (; info->name; info++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) const struct davinci_lpsc_clkdev_info *cdevs = info->cdevs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct clk *clk = psc->clk_data.clks[info->md];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (!cdevs || IS_ERR_OR_NULL(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) for (; cdevs->con_id || cdevs->dev_id; cdevs++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) clk_register_clkdev(clk, cdevs->con_id, cdevs->dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) int of_davinci_psc_clk_init(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) const struct davinci_lpsc_clk_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) u8 num_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct device_node *node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct davinci_psc_data *psc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) psc = __davinci_psc_register_clocks(dev, info, num_clks, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (IS_ERR(psc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return PTR_ERR(psc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) of_genpd_add_provider_onecell(node, &psc->pm_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) of_clk_add_provider(node, of_clk_src_onecell_get, &psc->clk_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static const struct of_device_id davinci_psc_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) #ifdef CONFIG_ARCH_DAVINCI_DA850
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) { .compatible = "ti,da850-psc0", .data = &of_da850_psc0_init_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) { .compatible = "ti,da850-psc1", .data = &of_da850_psc1_init_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) #endif
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static const struct platform_device_id davinci_psc_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) #ifdef CONFIG_ARCH_DAVINCI_DA830
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) { .name = "da830-psc0", .driver_data = (kernel_ulong_t)&da830_psc0_init_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) { .name = "da830-psc1", .driver_data = (kernel_ulong_t)&da830_psc1_init_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) #ifdef CONFIG_ARCH_DAVINCI_DA850
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) { .name = "da850-psc0", .driver_data = (kernel_ulong_t)&da850_psc0_init_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) { .name = "da850-psc1", .driver_data = (kernel_ulong_t)&da850_psc1_init_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) #ifdef CONFIG_ARCH_DAVINCI_DM355
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) { .name = "dm355-psc", .driver_data = (kernel_ulong_t)&dm355_psc_init_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) #ifdef CONFIG_ARCH_DAVINCI_DM365
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) { .name = "dm365-psc", .driver_data = (kernel_ulong_t)&dm365_psc_init_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) #ifdef CONFIG_ARCH_DAVINCI_DM644x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) { .name = "dm644x-psc", .driver_data = (kernel_ulong_t)&dm644x_psc_init_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) #ifdef CONFIG_ARCH_DAVINCI_DM646x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) { .name = "dm646x-psc", .driver_data = (kernel_ulong_t)&dm646x_psc_init_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) static int davinci_psc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) const struct of_device_id *of_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) const struct davinci_psc_init_data *init_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) of_id = of_match_device(davinci_psc_of_match, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (of_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) init_data = of_id->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) else if (pdev->id_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) init_data = (void *)pdev->id_entry->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (!init_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) dev_err(dev, "unable to find driver init data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (IS_ERR(base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return PTR_ERR(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) ret = devm_clk_bulk_get(dev, init_data->num_parent_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) init_data->parent_clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return init_data->psc_init(dev, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static struct platform_driver davinci_psc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) .probe = davinci_psc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .name = "davinci-psc-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) .of_match_table = davinci_psc_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) .id_table = davinci_psc_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) static int __init davinci_psc_driver_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) return platform_driver_register(&davinci_psc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /* has to be postcore_initcall because davinci_gpio depend on PSC clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) postcore_initcall(davinci_psc_driver_init);