From: Dmitry Osipenko <digetx@gmail.com> To: Sowjanya Komatineni <skomatineni@nvidia.com>, thierry.reding@gmail.com, jonathanh@nvidia.com, mperttunen@nvidia.com, gregkh@linuxfoundation.org, sboyd@kernel.org, tglx@linutronix.de, robh+dt@kernel.org, mark.rutland@arm.com Cc: allison@lohutok.net, pdeschrijver@nvidia.com, pgaikwad@nvidia.com, mturquette@baylibre.com, horms+renesas@verge.net.au, Jisheng.Zhang@synaptics.com, krzk@kernel.org, arnd@arndb.de, spujar@nvidia.com, josephl@nvidia.com, vidyas@nvidia.com, daniel.lezcano@linaro.org, mmaddireddy@nvidia.com, markz@nvidia.com, devicetree@vger.kernel.org, linux-clk@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, alexios.zavras@intel.com, alsa-devel@alsa-project.org Subject: Re: [PATCH v3 03/15] soc: tegra: Add Tegra PMC clock registrations into PMC driver Date: Sat, 7 Dec 2019 17:28:17 +0300 [thread overview] Message-ID: <7cf4ff77-2f33-4ee5-0e09-5aa6aef3e8be@gmail.com> (raw) In-Reply-To: <1575600535-26877-4-git-send-email-skomatineni@nvidia.com> 06.12.2019 05:48, Sowjanya Komatineni пишет: > Tegra210 and prior Tegra PMC has clk_out_1, clk_out_2, clk_out_3 with > mux and gate for each of these clocks. > > Currently these PMC clocks are registered by Tegra clock driver using > clk_register_mux and clk_register_gate by passing PMC base address > and register offsets and PMC programming for these clocks happens > through direct PMC access by the clock driver. > > With this, when PMC is in secure mode any direct PMC access from the > non-secure world does not go through and these clocks will not be > functional. > > This patch adds these clocks registration with PMC as a clock provider > for these clocks. clk_ops callback implementations for these clocks > uses tegra_pmc_readl and tegra_pmc_writel which supports PMC programming > in secure mode and non-secure mode. > > Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com> > --- > drivers/soc/tegra/pmc.c | 305 ++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 305 insertions(+) > > diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c > index ea0e11a09c12..b8f6eb0ed8aa 100644 > --- a/drivers/soc/tegra/pmc.c > +++ b/drivers/soc/tegra/pmc.c > @@ -13,6 +13,9 @@ > > #include <linux/arm-smccc.h> > #include <linux/clk.h> > +#include <linux/clk-provider.h> > +#include <linux/clkdev.h> > +#include <linux/clk/clk-conf.h> > #include <linux/clk/tegra.h> > #include <linux/debugfs.h> > #include <linux/delay.h> > @@ -48,6 +51,7 @@ > #include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h> > #include <dt-bindings/gpio/tegra186-gpio.h> > #include <dt-bindings/gpio/tegra194-gpio.h> > +#include <dt-bindings/soc/tegra-pmc.h> > > #define PMC_CNTRL 0x0 > #define PMC_CNTRL_INTR_POLARITY BIT(17) /* inverts INTR polarity */ > @@ -100,6 +104,7 @@ > #define PMC_WAKE2_STATUS 0x168 > #define PMC_SW_WAKE2_STATUS 0x16c > > +#define PMC_CLK_OUT_CNTRL 0x1a8 > #define PMC_SENSOR_CTRL 0x1b0 > #define PMC_SENSOR_CTRL_SCRATCH_WRITE BIT(2) > #define PMC_SENSOR_CTRL_ENABLE_RST BIT(1) > @@ -155,6 +160,83 @@ > #define TEGRA_SMC_PMC_READ 0xaa > #define TEGRA_SMC_PMC_WRITE 0xbb > > +struct pmc_clk_mux { > + struct clk_hw hw; > + unsigned long offs; > + u32 mask; > + u32 shift; > +}; > + > +#define to_pmc_clk_mux(_hw) container_of(_hw, struct pmc_clk_mux, hw) > + > +struct pmc_clk_gate { > + struct clk_hw hw; > + unsigned long offs; > + u32 shift; > +}; > + > +#define to_pmc_clk_gate(_hw) container_of(_hw, struct pmc_clk_gate, hw) > + > +struct pmc_clk_init_data { > + char *mux_name; > + char *gate_name; > + const char **parents; > + int num_parents; > + int mux_id; > + int gate_id; > + char *dev_name; > + u8 mux_shift; > + u8 gate_shift; > +}; > + > +static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", > + "clk_m_div4", "extern1", > +}; > + > +static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2", > + "clk_m_div4", "extern2", > +}; > + > +static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", > + "clk_m_div4", "extern3", > +}; > + > +static const struct pmc_clk_init_data tegra_pmc_clks_data[] = { > + { > + .mux_name = "clk_out_1_mux", > + .gate_name = "clk_out_1", > + .parents = clk_out1_parents, > + .num_parents = ARRAY_SIZE(clk_out1_parents), > + .mux_id = TEGRA_PMC_CLK_OUT_1_MUX, > + .gate_id = TEGRA_PMC_CLK_OUT_1, > + .dev_name = "extern1", > + .mux_shift = 6, > + .gate_shift = 2, > + }, > + { > + .mux_name = "clk_out_2_mux", > + .gate_name = "clk_out_2", > + .parents = clk_out2_parents, > + .num_parents = ARRAY_SIZE(clk_out2_parents), > + .mux_id = TEGRA_PMC_CLK_OUT_2_MUX, > + .gate_id = TEGRA_PMC_CLK_OUT_2, > + .dev_name = "extern2", > + .mux_shift = 14, > + .gate_shift = 10, > + }, > + { > + .mux_name = "clk_out_3_mux", > + .gate_name = "clk_out_3", > + .parents = clk_out3_parents, > + .num_parents = ARRAY_SIZE(clk_out3_parents), > + .mux_id = TEGRA_PMC_CLK_OUT_3_MUX, > + .gate_id = TEGRA_PMC_CLK_OUT_3, > + .dev_name = "extern3", > + .mux_shift = 22, > + .gate_shift = 18, > + }, > +}; > + > struct tegra_powergate { > struct generic_pm_domain genpd; > struct tegra_pmc *pmc; > @@ -254,6 +336,9 @@ struct tegra_pmc_soc { > */ > const struct tegra_wake_event *wake_events; > unsigned int num_wake_events; > + > + const struct pmc_clk_init_data *pmc_clks_data; > + unsigned int num_pmc_clks; > }; > > static const char * const tegra186_reset_sources[] = { > @@ -2163,6 +2248,211 @@ static int tegra_pmc_clk_notify_cb(struct notifier_block *nb, > return NOTIFY_OK; > } > > +static void pmc_clk_fence_udelay(u32 offset) > +{ > + tegra_pmc_readl(pmc, offset); > + /* pmc clk propagation delay 2 us */ > + udelay(2); > +} > + > +static u8 pmc_clk_mux_get_parent(struct clk_hw *hw) > +{ > + struct pmc_clk_mux *mux = to_pmc_clk_mux(hw); > + int num_parents = clk_hw_get_num_parents(hw); > + u32 val; > + > + val = tegra_pmc_readl(pmc, mux->offs) >> mux->shift; > + val &= mux->mask; > + > + if (val >= num_parents) > + return -EINVAL; How this could ever happen? Why are you returning negative value for u8? It doesn't different from returning val >= num_parents. > + return val; > +} > + > +static int pmc_clk_mux_set_parent(struct clk_hw *hw, u8 index) > +{ > + struct pmc_clk_mux *mux = to_pmc_clk_mux(hw); > + u32 val; > + > + val = tegra_pmc_readl(pmc, mux->offs); > + val &= ~(mux->mask << mux->shift); > + val |= index << mux->shift; > + tegra_pmc_writel(pmc, val, mux->offs); > + pmc_clk_fence_udelay(mux->offs); > + > + return 0; > +} > + > +static const struct clk_ops pmc_clk_mux_ops = { > + .get_parent = pmc_clk_mux_get_parent, > + .set_parent = pmc_clk_mux_set_parent, > + .determine_rate = __clk_mux_determine_rate, > +}; > + > +static struct clk * > +tegra_pmc_clk_mux_register(const char *name, const char * const *parent_names, > + int num_parents, unsigned long flags, > + unsigned long offset, u32 shift, u32 mask) > +{ > + struct clk_init_data init; > + struct pmc_clk_mux *mux; > + > + mux = kzalloc(sizeof(*mux), GFP_KERNEL); > + if (!mux) > + return ERR_PTR(-ENOMEM); > + > + init.name = name; > + init.ops = &pmc_clk_mux_ops; > + init.parent_names = parent_names; > + init.num_parents = num_parents; > + init.flags = flags; > + > + mux->hw.init = &init; > + mux->offs = offset; > + mux->mask = mask; > + mux->shift = shift; > + > + return clk_register(NULL, &mux->hw); > +} > + > +static int pmc_clk_is_enabled(struct clk_hw *hw) > +{ > + struct pmc_clk_gate *gate = to_pmc_clk_gate(hw); > + > + return tegra_pmc_readl(pmc, gate->offs) & BIT(gate->shift) ? 1 : 0; > +} > + > +static void pmc_clk_set_state(struct clk_hw *hw, int state) > +{ > + struct pmc_clk_gate *gate = to_pmc_clk_gate(hw); > + u32 val; > + > + val = tegra_pmc_readl(pmc, gate->offs); > + val = state ? (val | BIT(gate->shift)) : (val & ~BIT(gate->shift)); > + tegra_pmc_writel(pmc, val, gate->offs); > + pmc_clk_fence_udelay(gate->offs); > +} > + > +static int pmc_clk_enable(struct clk_hw *hw) > +{ > + pmc_clk_set_state(hw, 1); > + > + return 0; > +} > + > +static void pmc_clk_disable(struct clk_hw *hw) > +{ > + pmc_clk_set_state(hw, 0); > +} > + > +static const struct clk_ops pmc_clk_gate_ops = { > + .is_enabled = pmc_clk_is_enabled, > + .enable = pmc_clk_enable, > + .disable = pmc_clk_disable, > +}; What's the benefit of separating GATE from the MUX? I think it could be a single clock. > +static struct clk * > +tegra_pmc_clk_gate_register(const char *name, const char *parent_name, > + unsigned long flags, unsigned long offset, > + u32 shift) > +{ > + struct clk_init_data init; > + struct pmc_clk_gate *gate; > + > + gate = kzalloc(sizeof(*gate), GFP_KERNEL); > + if (!gate) > + return ERR_PTR(-ENOMEM); > + > + init.name = name; > + init.ops = &pmc_clk_gate_ops; > + init.parent_names = &parent_name; > + init.num_parents = 1; > + init.flags = flags; > + > + gate->hw.init = &init; > + gate->offs = offset; > + gate->shift = shift; > + > + return clk_register(NULL, &gate->hw); > +} > + > +static void tegra_pmc_clock_register(struct tegra_pmc *pmc, > + struct device_node *np) > +{ > + struct clk *clkmux, *clk; > + struct clk_onecell_data *clk_data; > + unsigned int num_clks; > + int i, ret; > + > + /* each pmc clock output has a mux and a gate */ > + num_clks = pmc->soc->num_pmc_clks * 2; > + > + if (!num_clks) > + return; > + > + clk_data = kmalloc(sizeof(*clk_data), GFP_KERNEL); > + if (!clk_data) > + return; > + > + clk_data->clks = kcalloc(TEGRA_PMC_CLK_MAX, sizeof(*clk_data->clks), > + GFP_KERNEL); > + if (!clk_data->clks) > + goto free_clkdata; > + > + clk_data->clk_num = TEGRA_PMC_CLK_MAX; > + > + for (i = 0; i < TEGRA_PMC_CLK_MAX; i++) > + clk_data->clks[i] = ERR_PTR(-ENOENT); > + > + for (i = 0; i < pmc->soc->num_pmc_clks; i++) { > + const struct pmc_clk_init_data *data; > + > + data = pmc->soc->pmc_clks_data + i; > + > + clkmux = tegra_pmc_clk_mux_register(data->mux_name, > + data->parents, > + data->num_parents, > + CLK_SET_RATE_NO_REPARENT | > + CLK_SET_RATE_PARENT, > + PMC_CLK_OUT_CNTRL, > + data->mux_shift, 3); > + if (IS_ERR(clkmux)) > + goto free_clks; > + > + clk_data->clks[data->mux_id] = clkmux; > + > + clk = tegra_pmc_clk_gate_register(data->gate_name, > + data->mux_name, > + CLK_SET_RATE_PARENT, > + PMC_CLK_OUT_CNTRL, > + data->gate_shift); > + if (IS_ERR(clk)) > + goto free_clks; > + > + clk_data->clks[data->gate_id] = clk; > + > + ret = clk_set_parent(clk, clkmux); > + if (ret < 0) { > + pr_err("failed to set parent of %s to %s: %d\n", > + __clk_get_name(clk), > + __clk_get_name(clkmux), ret); > + } is this really needed? GATE clock has a single parent, the MUX.
WARNING: multiple messages have this Message-ID (diff)
From: Dmitry Osipenko <digetx@gmail.com> To: Sowjanya Komatineni <skomatineni@nvidia.com>, thierry.reding@gmail.com, jonathanh@nvidia.com, mperttunen@nvidia.com, gregkh@linuxfoundation.org, sboyd@kernel.org, tglx@linutronix.de, robh+dt@kernel.org, mark.rutland@arm.com Cc: alsa-devel@alsa-project.org, pgaikwad@nvidia.com, spujar@nvidia.com, linux-kernel@vger.kernel.org, josephl@nvidia.com, linux-clk@vger.kernel.org, arnd@arndb.de, daniel.lezcano@linaro.org, krzk@kernel.org, mturquette@baylibre.com, devicetree@vger.kernel.org, mmaddireddy@nvidia.com, markz@nvidia.com, alexios.zavras@intel.com, broonie@kernel.org, linux-tegra@vger.kernel.org, horms+renesas@verge.net.au, tiwai@suse.com, allison@lohutok.net, pdeschrijver@nvidia.com, lgirdwood@gmail.com, vidyas@nvidia.com, Jisheng.Zhang@synaptics.com Subject: Re: [alsa-devel] [PATCH v3 03/15] soc: tegra: Add Tegra PMC clock registrations into PMC driver Date: Sat, 7 Dec 2019 17:28:17 +0300 [thread overview] Message-ID: <7cf4ff77-2f33-4ee5-0e09-5aa6aef3e8be@gmail.com> (raw) In-Reply-To: <1575600535-26877-4-git-send-email-skomatineni@nvidia.com> 06.12.2019 05:48, Sowjanya Komatineni пишет: > Tegra210 and prior Tegra PMC has clk_out_1, clk_out_2, clk_out_3 with > mux and gate for each of these clocks. > > Currently these PMC clocks are registered by Tegra clock driver using > clk_register_mux and clk_register_gate by passing PMC base address > and register offsets and PMC programming for these clocks happens > through direct PMC access by the clock driver. > > With this, when PMC is in secure mode any direct PMC access from the > non-secure world does not go through and these clocks will not be > functional. > > This patch adds these clocks registration with PMC as a clock provider > for these clocks. clk_ops callback implementations for these clocks > uses tegra_pmc_readl and tegra_pmc_writel which supports PMC programming > in secure mode and non-secure mode. > > Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com> > --- > drivers/soc/tegra/pmc.c | 305 ++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 305 insertions(+) > > diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c > index ea0e11a09c12..b8f6eb0ed8aa 100644 > --- a/drivers/soc/tegra/pmc.c > +++ b/drivers/soc/tegra/pmc.c > @@ -13,6 +13,9 @@ > > #include <linux/arm-smccc.h> > #include <linux/clk.h> > +#include <linux/clk-provider.h> > +#include <linux/clkdev.h> > +#include <linux/clk/clk-conf.h> > #include <linux/clk/tegra.h> > #include <linux/debugfs.h> > #include <linux/delay.h> > @@ -48,6 +51,7 @@ > #include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h> > #include <dt-bindings/gpio/tegra186-gpio.h> > #include <dt-bindings/gpio/tegra194-gpio.h> > +#include <dt-bindings/soc/tegra-pmc.h> > > #define PMC_CNTRL 0x0 > #define PMC_CNTRL_INTR_POLARITY BIT(17) /* inverts INTR polarity */ > @@ -100,6 +104,7 @@ > #define PMC_WAKE2_STATUS 0x168 > #define PMC_SW_WAKE2_STATUS 0x16c > > +#define PMC_CLK_OUT_CNTRL 0x1a8 > #define PMC_SENSOR_CTRL 0x1b0 > #define PMC_SENSOR_CTRL_SCRATCH_WRITE BIT(2) > #define PMC_SENSOR_CTRL_ENABLE_RST BIT(1) > @@ -155,6 +160,83 @@ > #define TEGRA_SMC_PMC_READ 0xaa > #define TEGRA_SMC_PMC_WRITE 0xbb > > +struct pmc_clk_mux { > + struct clk_hw hw; > + unsigned long offs; > + u32 mask; > + u32 shift; > +}; > + > +#define to_pmc_clk_mux(_hw) container_of(_hw, struct pmc_clk_mux, hw) > + > +struct pmc_clk_gate { > + struct clk_hw hw; > + unsigned long offs; > + u32 shift; > +}; > + > +#define to_pmc_clk_gate(_hw) container_of(_hw, struct pmc_clk_gate, hw) > + > +struct pmc_clk_init_data { > + char *mux_name; > + char *gate_name; > + const char **parents; > + int num_parents; > + int mux_id; > + int gate_id; > + char *dev_name; > + u8 mux_shift; > + u8 gate_shift; > +}; > + > +static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", > + "clk_m_div4", "extern1", > +}; > + > +static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2", > + "clk_m_div4", "extern2", > +}; > + > +static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", > + "clk_m_div4", "extern3", > +}; > + > +static const struct pmc_clk_init_data tegra_pmc_clks_data[] = { > + { > + .mux_name = "clk_out_1_mux", > + .gate_name = "clk_out_1", > + .parents = clk_out1_parents, > + .num_parents = ARRAY_SIZE(clk_out1_parents), > + .mux_id = TEGRA_PMC_CLK_OUT_1_MUX, > + .gate_id = TEGRA_PMC_CLK_OUT_1, > + .dev_name = "extern1", > + .mux_shift = 6, > + .gate_shift = 2, > + }, > + { > + .mux_name = "clk_out_2_mux", > + .gate_name = "clk_out_2", > + .parents = clk_out2_parents, > + .num_parents = ARRAY_SIZE(clk_out2_parents), > + .mux_id = TEGRA_PMC_CLK_OUT_2_MUX, > + .gate_id = TEGRA_PMC_CLK_OUT_2, > + .dev_name = "extern2", > + .mux_shift = 14, > + .gate_shift = 10, > + }, > + { > + .mux_name = "clk_out_3_mux", > + .gate_name = "clk_out_3", > + .parents = clk_out3_parents, > + .num_parents = ARRAY_SIZE(clk_out3_parents), > + .mux_id = TEGRA_PMC_CLK_OUT_3_MUX, > + .gate_id = TEGRA_PMC_CLK_OUT_3, > + .dev_name = "extern3", > + .mux_shift = 22, > + .gate_shift = 18, > + }, > +}; > + > struct tegra_powergate { > struct generic_pm_domain genpd; > struct tegra_pmc *pmc; > @@ -254,6 +336,9 @@ struct tegra_pmc_soc { > */ > const struct tegra_wake_event *wake_events; > unsigned int num_wake_events; > + > + const struct pmc_clk_init_data *pmc_clks_data; > + unsigned int num_pmc_clks; > }; > > static const char * const tegra186_reset_sources[] = { > @@ -2163,6 +2248,211 @@ static int tegra_pmc_clk_notify_cb(struct notifier_block *nb, > return NOTIFY_OK; > } > > +static void pmc_clk_fence_udelay(u32 offset) > +{ > + tegra_pmc_readl(pmc, offset); > + /* pmc clk propagation delay 2 us */ > + udelay(2); > +} > + > +static u8 pmc_clk_mux_get_parent(struct clk_hw *hw) > +{ > + struct pmc_clk_mux *mux = to_pmc_clk_mux(hw); > + int num_parents = clk_hw_get_num_parents(hw); > + u32 val; > + > + val = tegra_pmc_readl(pmc, mux->offs) >> mux->shift; > + val &= mux->mask; > + > + if (val >= num_parents) > + return -EINVAL; How this could ever happen? Why are you returning negative value for u8? It doesn't different from returning val >= num_parents. > + return val; > +} > + > +static int pmc_clk_mux_set_parent(struct clk_hw *hw, u8 index) > +{ > + struct pmc_clk_mux *mux = to_pmc_clk_mux(hw); > + u32 val; > + > + val = tegra_pmc_readl(pmc, mux->offs); > + val &= ~(mux->mask << mux->shift); > + val |= index << mux->shift; > + tegra_pmc_writel(pmc, val, mux->offs); > + pmc_clk_fence_udelay(mux->offs); > + > + return 0; > +} > + > +static const struct clk_ops pmc_clk_mux_ops = { > + .get_parent = pmc_clk_mux_get_parent, > + .set_parent = pmc_clk_mux_set_parent, > + .determine_rate = __clk_mux_determine_rate, > +}; > + > +static struct clk * > +tegra_pmc_clk_mux_register(const char *name, const char * const *parent_names, > + int num_parents, unsigned long flags, > + unsigned long offset, u32 shift, u32 mask) > +{ > + struct clk_init_data init; > + struct pmc_clk_mux *mux; > + > + mux = kzalloc(sizeof(*mux), GFP_KERNEL); > + if (!mux) > + return ERR_PTR(-ENOMEM); > + > + init.name = name; > + init.ops = &pmc_clk_mux_ops; > + init.parent_names = parent_names; > + init.num_parents = num_parents; > + init.flags = flags; > + > + mux->hw.init = &init; > + mux->offs = offset; > + mux->mask = mask; > + mux->shift = shift; > + > + return clk_register(NULL, &mux->hw); > +} > + > +static int pmc_clk_is_enabled(struct clk_hw *hw) > +{ > + struct pmc_clk_gate *gate = to_pmc_clk_gate(hw); > + > + return tegra_pmc_readl(pmc, gate->offs) & BIT(gate->shift) ? 1 : 0; > +} > + > +static void pmc_clk_set_state(struct clk_hw *hw, int state) > +{ > + struct pmc_clk_gate *gate = to_pmc_clk_gate(hw); > + u32 val; > + > + val = tegra_pmc_readl(pmc, gate->offs); > + val = state ? (val | BIT(gate->shift)) : (val & ~BIT(gate->shift)); > + tegra_pmc_writel(pmc, val, gate->offs); > + pmc_clk_fence_udelay(gate->offs); > +} > + > +static int pmc_clk_enable(struct clk_hw *hw) > +{ > + pmc_clk_set_state(hw, 1); > + > + return 0; > +} > + > +static void pmc_clk_disable(struct clk_hw *hw) > +{ > + pmc_clk_set_state(hw, 0); > +} > + > +static const struct clk_ops pmc_clk_gate_ops = { > + .is_enabled = pmc_clk_is_enabled, > + .enable = pmc_clk_enable, > + .disable = pmc_clk_disable, > +}; What's the benefit of separating GATE from the MUX? I think it could be a single clock. > +static struct clk * > +tegra_pmc_clk_gate_register(const char *name, const char *parent_name, > + unsigned long flags, unsigned long offset, > + u32 shift) > +{ > + struct clk_init_data init; > + struct pmc_clk_gate *gate; > + > + gate = kzalloc(sizeof(*gate), GFP_KERNEL); > + if (!gate) > + return ERR_PTR(-ENOMEM); > + > + init.name = name; > + init.ops = &pmc_clk_gate_ops; > + init.parent_names = &parent_name; > + init.num_parents = 1; > + init.flags = flags; > + > + gate->hw.init = &init; > + gate->offs = offset; > + gate->shift = shift; > + > + return clk_register(NULL, &gate->hw); > +} > + > +static void tegra_pmc_clock_register(struct tegra_pmc *pmc, > + struct device_node *np) > +{ > + struct clk *clkmux, *clk; > + struct clk_onecell_data *clk_data; > + unsigned int num_clks; > + int i, ret; > + > + /* each pmc clock output has a mux and a gate */ > + num_clks = pmc->soc->num_pmc_clks * 2; > + > + if (!num_clks) > + return; > + > + clk_data = kmalloc(sizeof(*clk_data), GFP_KERNEL); > + if (!clk_data) > + return; > + > + clk_data->clks = kcalloc(TEGRA_PMC_CLK_MAX, sizeof(*clk_data->clks), > + GFP_KERNEL); > + if (!clk_data->clks) > + goto free_clkdata; > + > + clk_data->clk_num = TEGRA_PMC_CLK_MAX; > + > + for (i = 0; i < TEGRA_PMC_CLK_MAX; i++) > + clk_data->clks[i] = ERR_PTR(-ENOENT); > + > + for (i = 0; i < pmc->soc->num_pmc_clks; i++) { > + const struct pmc_clk_init_data *data; > + > + data = pmc->soc->pmc_clks_data + i; > + > + clkmux = tegra_pmc_clk_mux_register(data->mux_name, > + data->parents, > + data->num_parents, > + CLK_SET_RATE_NO_REPARENT | > + CLK_SET_RATE_PARENT, > + PMC_CLK_OUT_CNTRL, > + data->mux_shift, 3); > + if (IS_ERR(clkmux)) > + goto free_clks; > + > + clk_data->clks[data->mux_id] = clkmux; > + > + clk = tegra_pmc_clk_gate_register(data->gate_name, > + data->mux_name, > + CLK_SET_RATE_PARENT, > + PMC_CLK_OUT_CNTRL, > + data->gate_shift); > + if (IS_ERR(clk)) > + goto free_clks; > + > + clk_data->clks[data->gate_id] = clk; > + > + ret = clk_set_parent(clk, clkmux); > + if (ret < 0) { > + pr_err("failed to set parent of %s to %s: %d\n", > + __clk_get_name(clk), > + __clk_get_name(clkmux), ret); > + } is this really needed? GATE clock has a single parent, the MUX. _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org https://mailman.alsa-project.org/mailman/listinfo/alsa-devel
next prev parent reply other threads:[~2019-12-07 14:28 UTC|newest] Thread overview: 153+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-12-06 2:48 [PATCH v3 00/15] Move PMC clocks into Tegra PMC driver Sowjanya Komatineni 2019-12-06 2:48 ` [alsa-devel] " Sowjanya Komatineni 2019-12-06 2:48 ` Sowjanya Komatineni 2019-12-06 2:48 ` [PATCH v3 01/15] dt-bindings: soc: tegra-pmc: Add Tegra PMC clock bindings Sowjanya Komatineni 2019-12-06 2:48 ` [alsa-devel] " Sowjanya Komatineni 2019-12-06 2:48 ` Sowjanya Komatineni 2019-12-06 18:58 ` Michał Mirosław 2019-12-06 18:58 ` [alsa-devel] " Michał Mirosław 2019-12-06 2:48 ` [PATCH v3 02/15] dt-bindings: tegra: Convert Tegra PMC bindings to YAML Sowjanya Komatineni 2019-12-06 2:48 ` [alsa-devel] " Sowjanya Komatineni 2019-12-06 2:48 ` Sowjanya Komatineni 2019-12-06 2:48 ` [PATCH v3 03/15] soc: tegra: Add Tegra PMC clock registrations into PMC driver Sowjanya Komatineni 2019-12-06 2:48 ` [alsa-devel] " Sowjanya Komatineni 2019-12-06 2:48 ` Sowjanya Komatineni 2019-12-07 14:28 ` Dmitry Osipenko [this message] 2019-12-07 14:28 ` [alsa-devel] " Dmitry Osipenko 2019-12-07 15:47 ` Dmitry Osipenko 2019-12-07 15:47 ` [alsa-devel] " Dmitry Osipenko 2019-12-07 15:53 ` Dmitry Osipenko 2019-12-07 15:53 ` [alsa-devel] " Dmitry Osipenko 2019-12-07 16:00 ` Dmitry Osipenko 2019-12-07 16:00 ` [alsa-devel] " Dmitry Osipenko 2019-12-07 19:59 ` Sowjanya Komatineni 2019-12-07 19:59 ` Sowjanya Komatineni 2019-12-07 21:36 ` Sowjanya Komatineni 2019-12-07 21:36 ` Sowjanya Komatineni 2019-12-09 20:12 ` Dmitry Osipenko 2019-12-09 20:12 ` [alsa-devel] " Dmitry Osipenko 2019-12-09 20:46 ` Sowjanya Komatineni 2019-12-09 20:46 ` Sowjanya Komatineni 2019-12-09 23:03 ` Sowjanya Komatineni 2019-12-09 23:03 ` Sowjanya Komatineni 2019-12-10 16:53 ` Sowjanya Komatineni 2019-12-10 16:53 ` Sowjanya Komatineni 2019-12-10 17:41 ` Dmitry Osipenko 2019-12-10 17:41 ` [alsa-devel] " Dmitry Osipenko 2019-12-11 1:06 ` Sowjanya Komatineni 2019-12-11 1:06 ` Sowjanya Komatineni 2019-12-11 18:50 ` Sowjanya Komatineni 2019-12-11 18:50 ` Sowjanya Komatineni 2019-12-12 1:39 ` Dmitry Osipenko 2019-12-12 1:39 ` [alsa-devel] " Dmitry Osipenko 2019-12-12 3:45 ` Sowjanya Komatineni 2019-12-12 3:45 ` Sowjanya Komatineni 2019-12-12 3:54 ` Sowjanya Komatineni 2019-12-12 3:54 ` Sowjanya Komatineni 2019-12-12 22:13 ` Dmitry Osipenko 2019-12-12 22:13 ` [alsa-devel] " Dmitry Osipenko 2019-12-11 15:10 ` Peter De Schrijver 2019-12-11 15:10 ` [alsa-devel] " Peter De Schrijver 2019-12-11 15:10 ` Peter De Schrijver 2019-12-12 1:43 ` Dmitry Osipenko 2019-12-12 1:43 ` [alsa-devel] " Dmitry Osipenko 2019-12-16 12:20 ` Peter De Schrijver 2019-12-16 12:20 ` [alsa-devel] " Peter De Schrijver 2019-12-16 12:20 ` Peter De Schrijver 2019-12-16 14:23 ` Dmitry Osipenko 2019-12-16 14:23 ` [alsa-devel] " Dmitry Osipenko 2019-12-16 15:11 ` Peter De Schrijver 2019-12-16 15:11 ` [alsa-devel] " Peter De Schrijver 2019-12-16 15:11 ` Peter De Schrijver 2019-12-16 15:24 ` Peter De Schrijver 2019-12-16 15:24 ` [alsa-devel] " Peter De Schrijver 2019-12-16 15:24 ` Peter De Schrijver 2019-12-16 15:49 ` Dmitry Osipenko 2019-12-16 15:49 ` [alsa-devel] " Dmitry Osipenko 2019-12-10 17:41 ` Dmitry Osipenko 2019-12-10 17:41 ` [alsa-devel] " Dmitry Osipenko [not found] ` <22a2f8bd-561d-f4c6-4eef-bb61095c53b2@nvidia.com> 2019-12-10 18:30 ` Dmitry Osipenko 2019-12-10 18:30 ` [alsa-devel] " Dmitry Osipenko 2019-12-10 19:18 ` Sowjanya Komatineni 2019-12-10 19:18 ` Sowjanya Komatineni 2019-12-10 20:31 ` Dmitry Osipenko 2019-12-10 20:31 ` [alsa-devel] " Dmitry Osipenko 2019-12-06 2:48 ` [PATCH v3 04/15] dt-bindings: soc: tegra-pmc: Add id for Tegra PMC blink control Sowjanya Komatineni 2019-12-06 2:48 ` [alsa-devel] " Sowjanya Komatineni 2019-12-06 2:48 ` Sowjanya Komatineni 2019-12-06 2:48 ` [PATCH v3 05/15] soc: pmc: Add blink output clock registration to Tegra PMC Sowjanya Komatineni 2019-12-06 2:48 ` [alsa-devel] " Sowjanya Komatineni 2019-12-06 2:48 ` Sowjanya Komatineni 2019-12-06 2:48 ` [PATCH v3 06/15] clk: tegra: Remove tegra_pmc_clk_init along with clk ids Sowjanya Komatineni 2019-12-06 2:48 ` [alsa-devel] " Sowjanya Komatineni 2019-12-06 2:48 ` Sowjanya Komatineni 2019-12-07 14:33 ` Dmitry Osipenko 2019-12-07 14:33 ` [alsa-devel] " Dmitry Osipenko 2019-12-07 14:43 ` Dmitry Osipenko 2019-12-07 14:43 ` [alsa-devel] " Dmitry Osipenko 2019-12-07 15:04 ` Dmitry Osipenko 2019-12-07 15:04 ` [alsa-devel] " Dmitry Osipenko 2019-12-07 19:35 ` Sowjanya Komatineni 2019-12-07 19:35 ` Sowjanya Komatineni 2019-12-07 23:24 ` Dmitry Osipenko 2019-12-07 23:24 ` [alsa-devel] " Dmitry Osipenko 2019-12-06 2:48 ` [PATCH v3 07/15] dt-bindings: clock: tegra: Remove pmc clock ids from clock dt-bindings Sowjanya Komatineni 2019-12-06 2:48 ` [alsa-devel] " Sowjanya Komatineni 2019-12-06 2:48 ` Sowjanya Komatineni 2019-12-06 2:48 ` [PATCH v3 08/15] ASoC: tegra: Add audio mclk control through clk_out_1 and extern1 Sowjanya Komatineni 2019-12-06 2:48 ` [alsa-devel] " Sowjanya Komatineni 2019-12-06 2:48 ` Sowjanya Komatineni 2019-12-07 14:58 ` Dmitry Osipenko 2019-12-07 14:58 ` [alsa-devel] " Dmitry Osipenko 2019-12-07 19:20 ` Sowjanya Komatineni 2019-12-07 19:20 ` Sowjanya Komatineni 2019-12-09 20:06 ` Dmitry Osipenko 2019-12-09 20:06 ` [alsa-devel] " Dmitry Osipenko 2019-12-09 23:05 ` Sowjanya Komatineni 2019-12-09 23:05 ` Sowjanya Komatineni 2019-12-09 23:12 ` Dmitry Osipenko 2019-12-09 23:12 ` [alsa-devel] " Dmitry Osipenko 2019-12-10 0:54 ` Sowjanya Komatineni 2019-12-10 0:54 ` Sowjanya Komatineni 2019-12-17 1:29 ` Sowjanya Komatineni 2019-12-17 1:29 ` Sowjanya Komatineni 2019-12-17 15:36 ` Dmitry Osipenko 2019-12-17 15:36 ` [alsa-devel] " Dmitry Osipenko 2019-12-17 16:12 ` Sowjanya Komatineni 2019-12-17 16:12 ` Sowjanya Komatineni 2019-12-17 16:16 ` Dmitry Osipenko 2019-12-17 16:16 ` [alsa-devel] " Dmitry Osipenko 2019-12-17 16:39 ` Sowjanya Komatineni 2019-12-17 16:39 ` Sowjanya Komatineni 2019-12-17 16:46 ` Dmitry Osipenko 2019-12-17 16:46 ` [alsa-devel] " Dmitry Osipenko 2019-12-06 2:48 ` [PATCH v3 09/15] ASoC: tegra: Add fallback for audio mclk Sowjanya Komatineni 2019-12-06 2:48 ` [alsa-devel] " Sowjanya Komatineni 2019-12-06 2:48 ` Sowjanya Komatineni 2019-12-06 17:49 ` Sowjanya Komatineni 2019-12-06 17:49 ` [alsa-devel] " Sowjanya Komatineni 2019-12-06 17:49 ` Sowjanya Komatineni 2019-12-06 17:56 ` Greg KH 2019-12-06 17:56 ` [alsa-devel] " Greg KH 2019-12-09 16:40 ` Mark Brown 2019-12-09 16:40 ` [alsa-devel] " Mark Brown 2019-12-09 20:31 ` Dmitry Osipenko 2019-12-09 20:31 ` [alsa-devel] " Dmitry Osipenko 2019-12-09 20:47 ` Mark Brown 2019-12-09 20:47 ` [alsa-devel] " Mark Brown 2019-12-10 18:24 ` Dmitry Osipenko 2019-12-10 18:24 ` [alsa-devel] " Dmitry Osipenko 2019-12-10 18:59 ` Mark Brown 2019-12-10 18:59 ` [alsa-devel] " Mark Brown 2019-12-12 2:17 ` Dmitry Osipenko 2019-12-12 2:17 ` [alsa-devel] " Dmitry Osipenko 2019-12-06 2:48 ` [PATCH v3 10/15] clk: tegra: Remove extern1 and cdev1 from clocks inittable Sowjanya Komatineni 2019-12-06 2:48 ` [alsa-devel] " Sowjanya Komatineni 2019-12-06 2:48 ` Sowjanya Komatineni 2019-12-06 2:48 ` [PATCH v3 11/15] ARM: dts: tegra: Add clock-cells property to pmc Sowjanya Komatineni 2019-12-06 2:48 ` [alsa-devel] " Sowjanya Komatineni 2019-12-06 2:48 ` Sowjanya Komatineni 2019-12-07 14:26 ` [PATCH v3 00/15] Move PMC clocks into Tegra PMC driver Dmitry Osipenko 2019-12-07 14:26 ` [alsa-devel] " Dmitry Osipenko 2019-12-07 19:22 ` Sowjanya Komatineni 2019-12-07 19:22 ` Sowjanya Komatineni
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=7cf4ff77-2f33-4ee5-0e09-5aa6aef3e8be@gmail.com \ --to=digetx@gmail.com \ --cc=Jisheng.Zhang@synaptics.com \ --cc=alexios.zavras@intel.com \ --cc=allison@lohutok.net \ --cc=alsa-devel@alsa-project.org \ --cc=arnd@arndb.de \ --cc=broonie@kernel.org \ --cc=daniel.lezcano@linaro.org \ --cc=devicetree@vger.kernel.org \ --cc=gregkh@linuxfoundation.org \ --cc=horms+renesas@verge.net.au \ --cc=jonathanh@nvidia.com \ --cc=josephl@nvidia.com \ --cc=krzk@kernel.org \ --cc=lgirdwood@gmail.com \ --cc=linux-clk@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-tegra@vger.kernel.org \ --cc=mark.rutland@arm.com \ --cc=markz@nvidia.com \ --cc=mmaddireddy@nvidia.com \ --cc=mperttunen@nvidia.com \ --cc=mturquette@baylibre.com \ --cc=pdeschrijver@nvidia.com \ --cc=perex@perex.cz \ --cc=pgaikwad@nvidia.com \ --cc=robh+dt@kernel.org \ --cc=sboyd@kernel.org \ --cc=skomatineni@nvidia.com \ --cc=spujar@nvidia.com \ --cc=tglx@linutronix.de \ --cc=thierry.reding@gmail.com \ --cc=tiwai@suse.com \ --cc=vidyas@nvidia.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.