Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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);