* Re: [v5 1/2] dt-bindings: gpio: aspeed: Add SGPIO support
From: Andrew Jeffery @ 2019-07-22 1:42 UTC (permalink / raw)
To: Linus Walleij, Hongwei Zhang
Cc: open list:GPIO SUBSYSTEM, Joel Stanley,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
linux-aspeed, Bartosz Golaszewski, Rob Herring, Mark Rutland,
linux-kernel@vger.kernel.org, Linux ARM
In-Reply-To: <CACRpkdYhVoP75ZDfASW+DH5yf-a5diitiXsh7eLsJx5hsTC9sQ@mail.gmail.com>
On Sat, 20 Jul 2019, at 17:43, Linus Walleij wrote:
> Hi Hongwei,
>
> after looking close at the driver and bindings I have this feeback:
>
> On Fri, Jul 19, 2019 at 9:25 PM Hongwei Zhang <hongweiz@ami.com> wrote:
>
> +- reg : Address and length of the register set for the device
>
> This 0x100 range may look simple but in the driver it looks like
> this:
>
> +static const struct aspeed_sgpio_bank aspeed_sgpio_banks[] = {
> + {
> + .val_regs = 0x0000,
> + .rdata_reg = 0x0070,
> + .irq_regs = 0x0004,
> + .names = { "A", "B", "C", "D" },
> + },
> + {
> + .val_regs = 0x001C,
> + .rdata_reg = 0x0074,
> + .irq_regs = 0x0020,
> + .names = { "E", "F", "G", "H" },
> + },
> + {
> + .val_regs = 0x0038,
> + .rdata_reg = 0x0078,
> + .irq_regs = 0x003C,
> + .names = { "I", "J" },
> + },
> +};
>
> So first break this into up to 10 different instances with one device
> per bank instead.
>
> For each device:
>
> reg = <0x1e780200 4>, <x1e780204 ..>, <0x1e780270 ..>;
> reg-names = "val", "irq", "rdata";
>
> This way you use the device tree features for locating the
> register offsets instead of hard-coding it into the driver,
> which will make the driver simpler.
>
> > +- ngpios : number of GPIO pins to serialise.
> > + (should be multiple of 8, up to 80 pins)
>
> This is wrong. This should be split into 10 different devices providing
> 8 GPIO lines each. The "ngpios" is not intended to subdivide
> banks, but for the case where you use say bits 0..11 of 32 bits in
> a register by setting ngpios to 12.
>
> I see that they use the same clock divider and the same interrupt,
> but this is better to partition into a separate clock divider driver
> and up to 10 instances of GPIO devices with 8 GPIOs each.
>
> I also see that they use the same interrupt. This is fine, in your
> driver just grab a shared IRQ and all the IRQ handlers will be
> traversed. This is a well known pattern for all operating systems.
>
> > +- clocks : A phandle to the APB clock for SGPM clock division
> > +
> > +- bus-frequency : SGPM CLK frequency
>
> I see that there is a common clock control register in offset 0x54.
>
> Split this out to a separate clock driver that provides a divided clock
> that all GPIO blocks can get, no matter if you use 1, 2 .. 10 of these
> blocks.
>
> The fact that these GPIO banks and the clock register is in the same
> memory range does not really matter. Split up the memory range in
> on reg = per GPIO chip and one reg for the clock.
The issue that I see with this is that the SGPIO bus clock configuration
is not the only field in the SGPIO control register - it also contains the
number of GPIOs the bus should output along with a bus enable bit.
The clock, and particularly the number of GPIOs (due to the nature
of the SGPIO bus) both need to be configured before we set the
enable bit (or obviously all can be done simultaneously).
I'll explore some of the options below (it's a bit train-of-thought,
hopefully it makes sense):
If the clock driver owns the control register, it also needs to know how
many GPIOs we want to emit on the bus. This seems like an awkward
configuration parameter for a clock driver.
To avoid the weird parameter we could protect the control register
with a lock shared between the clock driver and the SGPIO driver. This
way the SGPIO driver could have the ngpios parameter, and request
the clock after its written the ngpios value to the control register. A
regmap would be useful here to avoid the resource clash and it also
provides the required lock.
However, you're also going down the path of splitting the driver such
that there's one instance per bank. With this approach we need to
solve two problems: Accounting for the total number of GPIOs, and
only enabling the bus after the last bank has had its driver probed.
The accounting might be handled by accumulating the number of
GPIOs in each bank in the control register itself, e.g. the driver
implementation does something like:
spin_lock(...)
ctrl = ioread32(...)
ngpios = FIELD_GET(ASPEED_SGPIO_CTRL_NGPIOS, ctrl);
ngpios += 8;
ctrl &= ~ASPEED_SGPIO_CTRL_NGPIOS;
ctrl |= FIELD_PREP(ASPEED_SGPIO_CTRL_NGPIOS, ngpios);
iowrite32(ctrl, ...);
spin_unlock(...);
This works on cold boot of the device when the ngpios field is set to
zero due to reset, however will fail on subsequent warm reboots if
the GPIO IP block is protected from reset by the SoC's watchdog
configuration: the field will not be zeroed in this case, and the
value of the field is represented by `NR_BOOTS * NR_GPIOS`,
which is incorrect. To do this correctly I guess we would need some
other global state held in the driver implementation (zeroed when
the kernel is loaded), and write the incremented value to the control
register on each probe() invocation.
However, that aside, we can't simply enable the bus in the clock
enable callback if enable is called per-bank, as it is called once on
the first request with further requests simply refcounted as you
mentioned. This is exactly the behaviour we can't tolerate with the
bus: it must only be enabled after the last GPIO bank is registered,
when we know the total number of GPIOs to emit. So we can only
call clk_prepare_enable() after the last bank is probed, or in the
probe() of the last bank if the driver has some way to tell it is the
last instance. In my mind per-bank clock management makes the
implementation more involved than it should be, and isn't really
reflective of what the clk subsystem is trying to achieve (violates
clk_prepare()/clk_enable() post conditions, or boils down to just
calling devm_clk_get() in probe() with no further action, which
seems kinda pointless).
Having a separate clk implementation whose instance is requested
once by a monolithic SGPIO driver matches how the hardware is
designed. However, given the issue of sharing the register with the
GPIO count, in my opinion it seems to make more sense to leave the
driver design as is and minimise the accidental complexity
introduced by the behavioural mismatch of the clk abstraction
and the addition of locking where it wasn't previously necessary.
Interested in your thoughts.
Andrew
^ permalink raw reply
* Re: [PATCH 1/2] [PATCH] gpio: Replace usage of bare 'unsigned' with 'unsigned int'
From: Phil Reid @ 2019-07-22 2:05 UTC (permalink / raw)
To: Hennie Muller, Linus Walleij, Bartosz Golaszewski, linux-gpio,
linux-kernel
In-Reply-To: <20190721125259.13990-1-hm@bitlabs.co.za>
G'day Hennie,
patch title should be:
gpio: viperboard: Replace usage of bare 'unsigned' with 'unsigned int'
On 21/07/2019 20:52, Hennie Muller wrote:
> Fixes a couple of warnings by checkpatch and sparse.
>
> Signed-off-by: Hennie Muller <hm@bitlabs.co.za>
> ---
> drivers/gpio/gpio-viperboard.c | 20 ++++++++++----------
> 1 file changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpio/gpio-viperboard.c b/drivers/gpio/gpio-viperboard.c
> index 9b604f13e302..c301c1d56dd2 100644
> --- a/drivers/gpio/gpio-viperboard.c
> +++ b/drivers/gpio/gpio-viperboard.c
> @@ -79,7 +79,7 @@ MODULE_PARM_DESC(gpioa_freq,
> /* ----- begin of gipo a chip -------------------------------------------- */
>
> static int vprbrd_gpioa_get(struct gpio_chip *chip,
> - unsigned offset)
> + unsigned int offset)
I've encountered these checkpatch warnings as well.
However 'struct gpio_chip' callbacks define the function signatures
as 'unsigned', not 'unsigned int'. So I've also left them as is, to explicitly
match the struct definition.
Be interested to know what the official take on this is.
> {
> int ret, answer, error = 0;
> struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
> @@ -129,7 +129,7 @@ static int vprbrd_gpioa_get(struct gpio_chip *chip,
> }
>
> static void vprbrd_gpioa_set(struct gpio_chip *chip,
> - unsigned offset, int value)
> + unsigned int offset, int value)
> {
> int ret;
> struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
> @@ -170,7 +170,7 @@ static void vprbrd_gpioa_set(struct gpio_chip *chip,
> }
>
> static int vprbrd_gpioa_direction_input(struct gpio_chip *chip,
> - unsigned offset)
> + unsigned int offset)
> {
> int ret;
> struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
> @@ -207,7 +207,7 @@ static int vprbrd_gpioa_direction_input(struct gpio_chip *chip,
> }
>
> static int vprbrd_gpioa_direction_output(struct gpio_chip *chip,
> - unsigned offset, int value)
> + unsigned int offset, int value)
> {
> int ret;
> struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
> @@ -251,8 +251,8 @@ static int vprbrd_gpioa_direction_output(struct gpio_chip *chip,
>
> /* ----- begin of gipo b chip -------------------------------------------- */
>
> -static int vprbrd_gpiob_setdir(struct vprbrd *vb, unsigned offset,
> - unsigned dir)
> +static int vprbrd_gpiob_setdir(struct vprbrd *vb, unsigned int offset,
> + unsigned int dir)
> {
> struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf;
> int ret;
> @@ -273,7 +273,7 @@ static int vprbrd_gpiob_setdir(struct vprbrd *vb, unsigned offset,
> }
>
> static int vprbrd_gpiob_get(struct gpio_chip *chip,
> - unsigned offset)
> + unsigned int offset)
> {
> int ret;
> u16 val;
> @@ -305,7 +305,7 @@ static int vprbrd_gpiob_get(struct gpio_chip *chip,
> }
>
> static void vprbrd_gpiob_set(struct gpio_chip *chip,
> - unsigned offset, int value)
> + unsigned int offset, int value)
> {
> int ret;
> struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
> @@ -338,7 +338,7 @@ static void vprbrd_gpiob_set(struct gpio_chip *chip,
> }
>
> static int vprbrd_gpiob_direction_input(struct gpio_chip *chip,
> - unsigned offset)
> + unsigned int offset)
> {
> int ret;
> struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
> @@ -359,7 +359,7 @@ static int vprbrd_gpiob_direction_input(struct gpio_chip *chip,
> }
>
> static int vprbrd_gpiob_direction_output(struct gpio_chip *chip,
> - unsigned offset, int value)
> + unsigned int offset, int value)
> {
> int ret;
> struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
>
--
Regards
Phil Reid
^ permalink raw reply
* Re: [PATCH V6 09/21] clk: tegra: clk-super: Fix to enable PLLP branches to CPU
From: Sowjanya Komatineni @ 2019-07-22 3:17 UTC (permalink / raw)
To: Dmitry Osipenko, thierry.reding, jonathanh, tglx, jason,
marc.zyngier, linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, linux-tegra, linux-kernel, mperttunen, spatra,
robh+dt, devicetree
In-Reply-To: <042f4b43-7b9c-533d-2548-d903b34363da@nvidia.com>
On 7/21/19 3:39 PM, Sowjanya Komatineni wrote:
>
> On 7/21/19 2:16 PM, Dmitry Osipenko wrote:
>> 21.07.2019 22:40, Sowjanya Komatineni пишет:
>>> This patch has a fix to enable PLLP branches to CPU before changing
>>> the CPU clusters clock source to PLLP for Gen5 Super clock.
>>>
>>> During system suspend entry and exit, CPU source will be switched
>>> to PLLP and this needs PLLP branches to be enabled to CPU prior to
>>> the switch.
>>>
>>> On system resume, warmboot code enables PLLP branches to CPU and
>>> powers up the CPU with PLLP clock source.
>>>
>>> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
>>> ---
>>> drivers/clk/tegra/clk-super.c | 11 +++++++++++
>>> drivers/clk/tegra/clk-tegra-super-gen4.c | 4 ++--
>>> drivers/clk/tegra/clk.h | 4 ++++
>>> 3 files changed, 17 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/clk/tegra/clk-super.c
>>> b/drivers/clk/tegra/clk-super.c
>>> index 39ef31b46df5..d73c587e4853 100644
>>> --- a/drivers/clk/tegra/clk-super.c
>>> +++ b/drivers/clk/tegra/clk-super.c
>>> @@ -28,6 +28,9 @@
>>> #define super_state_to_src_shift(m, s) ((m->width * s))
>>> #define super_state_to_src_mask(m) (((1 << m->width) - 1))
>>> +#define CCLK_SRC_PLLP_OUT0 4
>>> +#define CCLK_SRC_PLLP_OUT4 5
>>> +
>>> static u8 clk_super_get_parent(struct clk_hw *hw)
>>> {
>>> struct tegra_clk_super_mux *mux = to_clk_super_mux(hw);
>>> @@ -97,6 +100,14 @@ static int clk_super_set_parent(struct clk_hw
>>> *hw, u8 index)
>>> if (index == mux->div2_index)
>>> index = mux->pllx_index;
>>> }
>>> +
>>> + /*
>>> + * Enable PLLP branches to CPU before selecting PLLP source
>>> + */
>>> + if ((mux->flags & TEGRA_CPU_CLK) &&
>>> + ((index == CCLK_SRC_PLLP_OUT0) || (index ==
>>> CCLK_SRC_PLLP_OUT4)))
>>> + tegra_clk_set_pllp_out_cpu(true);
>> Should somewhere here be tegra_clk_set_pllp_out_cpu(false) when
>> switching from PLLP?
> PLLP may be used for other CPU clusters.
Though to avoid flag and check needed to make sure other CPU is not
using before disabling PLLP branch to CPU.
But leaving it enabled shouldn't impact much as clock source mux is
after this in design anyway.
But can add as well if its clear that way.
>>> val &= ~((super_state_to_src_mask(mux)) << shift);
>>> val |= (index & (super_state_to_src_mask(mux))) << shift;
>>> diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c
>>> b/drivers/clk/tegra/clk-tegra-super-gen4.c
>>> index cdfe7c9697e1..cd208d0eca2a 100644
>>> --- a/drivers/clk/tegra/clk-tegra-super-gen4.c
>>> +++ b/drivers/clk/tegra/clk-tegra-super-gen4.c
>>> @@ -180,7 +180,7 @@ static void __init tegra_super_clk_init(void
>>> __iomem *clk_base,
>>> gen_info->num_cclk_g_parents,
>>> CLK_SET_RATE_PARENT,
>>> clk_base + CCLKG_BURST_POLICY,
>>> - 0, 4, 8, 0, NULL);
>>> + TEGRA_CPU_CLK, 4, 8, 0, NULL);
>>> } else {
>>> clk = tegra_clk_register_super_mux("cclk_g",
>>> gen_info->cclk_g_parents,
>>> @@ -201,7 +201,7 @@ static void __init tegra_super_clk_init(void
>>> __iomem *clk_base,
>>> gen_info->num_cclk_lp_parents,
>>> CLK_SET_RATE_PARENT,
>>> clk_base + CCLKLP_BURST_POLICY,
>>> - 0, 4, 8, 0, NULL);
>>> + TEGRA_CPU_CLK, 4, 8, 0, NULL);
>>> } else {
>>> clk = tegra_clk_register_super_mux("cclk_lp",
>>> gen_info->cclk_lp_parents,
>>> diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
>>> index ac6de3a0b91f..c357b49e49b0 100644
>>> --- a/drivers/clk/tegra/clk.h
>>> +++ b/drivers/clk/tegra/clk.h
>>> @@ -694,6 +694,9 @@ struct clk *tegra_clk_register_periph_data(void
>>> __iomem *clk_base,
>>> * Flags:
>>> * TEGRA_DIVIDER_2 - LP cluster has additional divider. This flag
>>> indicates
>>> * that this is LP cluster clock.
>>> + * TEGRA_CPU_CLK - This flag indicates this is CPU cluster clock.
>>> To use PLLP
>>> + * for CPU clock source, need to enable PLLP branches to CPU by
>>> setting the
>>> + * additional bit PLLP_OUT_CPU for gen5 super clock.
>>> */
>>> struct tegra_clk_super_mux {
>>> struct clk_hw hw;
>>> @@ -710,6 +713,7 @@ struct tegra_clk_super_mux {
>>> #define to_clk_super_mux(_hw) container_of(_hw, struct
>>> tegra_clk_super_mux, hw)
>>> #define TEGRA_DIVIDER_2 BIT(0)
>>> +#define TEGRA_CPU_CLK BIT(1)
>> I'd name this TEGRA210_CPU_CLK for clarity.
>>
>>> extern const struct clk_ops tegra_clk_super_ops;
>>> struct clk *tegra_clk_register_super_mux(const char *name,
>>>
>> Will be better to move the tegra_clk_set_pllp_out_cpu() definition into
>> this patch, otherwise this looks inconsistent for reviewer.
> ok, Will move to this patch
^ permalink raw reply
* Re: [PATCH V6 06/21] clk: tegra: pll: Save and restore pll context
From: Sowjanya Komatineni @ 2019-07-22 3:22 UTC (permalink / raw)
To: Dmitry Osipenko, thierry.reding, jonathanh, tglx, jason,
marc.zyngier, linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, linux-tegra, linux-kernel, mperttunen, spatra,
robh+dt, devicetree
In-Reply-To: <e383bf0e-fee7-3aa2-a9af-c0fb36c44219@gmail.com>
On 7/21/19 3:21 PM, Dmitry Osipenko wrote:
> 21.07.2019 22:40, Sowjanya Komatineni пишет:
>> This patch implements save and restore of PLL context.
>>
>> During system suspend, core power goes off and looses the settings
>> of the Tegra CAR controller registers.
>>
>> So during suspend entry pll rate is stored and on resume it is
>> restored back along with its state.
>>
>> Acked-by: Thierry Reding <treding@nvidia.com>
>> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
>> ---
>> drivers/clk/tegra/clk-pll.c | 121 ++++++++++++++++++++++++++++-----------
>> drivers/clk/tegra/clk-tegra210.c | 2 +-
>> drivers/clk/tegra/clk.h | 10 +++-
>> 3 files changed, 99 insertions(+), 34 deletions(-)
>>
>> diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
>> index 1583f5fc992f..f136964e6c44 100644
>> --- a/drivers/clk/tegra/clk-pll.c
>> +++ b/drivers/clk/tegra/clk-pll.c
>> @@ -1008,6 +1008,59 @@ static unsigned long clk_plle_recalc_rate(struct clk_hw *hw,
>> return rate;
>> }
>>
>> +void tegra_clk_sync_state_pll(struct clk_hw *hw)
>> +{
>> + if (!__clk_get_enable_count(hw->clk))
>> + clk_pll_disable(hw);
>> + else
>> + clk_pll_enable(hw);
>> +}
>> +
>> +static int tegra_clk_pll_save_context(struct clk_hw *hw)
>> +{
>> + struct tegra_clk_pll *pll = to_clk_pll(hw);
>> + u32 val = 0;
>> +
>> + pll->rate = clk_hw_get_rate(hw);
> Again, clk_hw_get_rate() returns cached value. Why do you need to
> duplicate it?
true, will remove storing in next version. thanks.
>> + if (pll->params->flags & TEGRA_PLLMB)
>> + val = pll_readl_base(pll);
>> + else if (pll->params->flags & TEGRA_PLLRE)
>> + val = pll_readl_base(pll) & divp_mask_shifted(pll);
>> +
>> + pll->pllbase_ctx = val;
>> +
>> + return 0;
>> +}
>> +
>> +static void tegra_clk_pll_restore_context(struct clk_hw *hw)
>> +{
>> + struct tegra_clk_pll *pll = to_clk_pll(hw);
>> + struct clk_hw *parent = clk_hw_get_parent(hw);
>> + unsigned long parent_rate = clk_hw_get_rate(parent);
>> + u32 val;
>> +
>> + if (clk_pll_is_enabled(hw))
>> + return;
>> +
>> + if (pll->params->flags & TEGRA_PLLMB) {
>> + pll_writel_base(pll->pllbase_ctx, pll);
>> + } else if (pll->params->flags & TEGRA_PLLRE) {
>> + val = pll_readl_base(pll);
>> + val &= ~(divp_mask_shifted(pll));
>> + pll_writel_base(pll->pllbase_ctx | val, pll);
>> + }
>> +
>> + if (pll->params->set_defaults)
>> + pll->params->set_defaults(pll);
>> +
>> + clk_pll_set_rate(hw, pll->rate, parent_rate);
>> +
>> + /* do not sync pllx state here. pllx is sync'd after dfll resume */
>> + if (!(pll->params->flags & TEGRA_PLLX))
>> + tegra_clk_sync_state_pll(hw);
>> +}
>> +
>> const struct clk_ops tegra_clk_pll_ops = {
>> .is_enabled = clk_pll_is_enabled,
>> .enable = clk_pll_enable,
>> @@ -1015,6 +1068,8 @@ const struct clk_ops tegra_clk_pll_ops = {
>> .recalc_rate = clk_pll_recalc_rate,
>> .round_rate = clk_pll_round_rate,
>> .set_rate = clk_pll_set_rate,
>> + .save_context = tegra_clk_pll_save_context,
>> + .restore_context = tegra_clk_pll_restore_context,
>> };
>>
>> const struct clk_ops tegra_clk_plle_ops = {
>> @@ -1802,6 +1857,27 @@ static int clk_pllu_tegra114_enable(struct clk_hw *hw)
>>
>> return ret;
>> }
>> +
>> +static void _clk_plle_tegra_init_parent(struct tegra_clk_pll *pll)
>> +{
>> + u32 val, val_aux;
>> +
>> + /* ensure parent is set to pll_ref */
>> + val = pll_readl_base(pll);
>> + val_aux = pll_readl(pll->params->aux_reg, pll);
>> +
>> + if (val & PLL_BASE_ENABLE) {
>> + if ((val_aux & PLLE_AUX_PLLRE_SEL) ||
>> + (val_aux & PLLE_AUX_PLLP_SEL))
>> + WARN(1, "pll_e enabled with unsupported parent %s\n",
>> + (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" :
>> + "pll_re_vco");
>> + } else {
>> + val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL);
>> + pll_writel(val_aux, pll->params->aux_reg, pll);
>> + fence_udelay(1, pll->clk_base);
>> + }
>> +}
>> #endif
>>
>> static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base,
>> @@ -2214,27 +2290,12 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name,
>> {
>> struct tegra_clk_pll *pll;
>> struct clk *clk;
>> - u32 val, val_aux;
>>
>> pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
>> if (IS_ERR(pll))
>> return ERR_CAST(pll);
>>
>> - /* ensure parent is set to pll_re_vco */
>> -
>> - val = pll_readl_base(pll);
>> - val_aux = pll_readl(pll_params->aux_reg, pll);
>> -
>> - if (val & PLL_BASE_ENABLE) {
>> - if ((val_aux & PLLE_AUX_PLLRE_SEL) ||
>> - (val_aux & PLLE_AUX_PLLP_SEL))
>> - WARN(1, "pll_e enabled with unsupported parent %s\n",
>> - (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" :
>> - "pll_re_vco");
>> - } else {
>> - val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL);
>> - pll_writel(val_aux, pll_params->aux_reg, pll);
>> - }
>> + _clk_plle_tegra_init_parent(pll);
>>
>> clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
>> &tegra_clk_plle_tegra114_ops);
>> @@ -2276,6 +2337,8 @@ static const struct clk_ops tegra_clk_pllss_ops = {
>> .recalc_rate = clk_pll_recalc_rate,
>> .round_rate = clk_pll_ramp_round_rate,
>> .set_rate = clk_pllxc_set_rate,
>> + .save_context = tegra_clk_pll_save_context,
>> + .restore_context = tegra_clk_pll_restore_context,
>> };
>>
>> struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name,
>> @@ -2375,6 +2438,7 @@ struct clk *tegra_clk_register_pllre_tegra210(const char *name,
>> pll_params->vco_min = pll_params->adjust_vco(pll_params,
>> parent_rate);
>>
>> + pll_params->flags |= TEGRA_PLLRE;
>> pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
>> if (IS_ERR(pll))
>> return ERR_CAST(pll);
>> @@ -2520,11 +2584,19 @@ static void clk_plle_tegra210_disable(struct clk_hw *hw)
>> spin_unlock_irqrestore(pll->lock, flags);
>> }
>>
>> +static void tegra_clk_plle_t210_restore_context(struct clk_hw *hw)
>> +{
>> + struct tegra_clk_pll *pll = to_clk_pll(hw);
>> +
>> + _clk_plle_tegra_init_parent(pll);
>> +}
>> +
>> static const struct clk_ops tegra_clk_plle_tegra210_ops = {
>> .is_enabled = clk_plle_tegra210_is_enabled,
>> .enable = clk_plle_tegra210_enable,
>> .disable = clk_plle_tegra210_disable,
>> .recalc_rate = clk_pll_recalc_rate,
>> + .restore_context = tegra_clk_plle_t210_restore_context,
>> };
>>
>> struct clk *tegra_clk_register_plle_tegra210(const char *name,
>> @@ -2535,27 +2607,12 @@ struct clk *tegra_clk_register_plle_tegra210(const char *name,
>> {
>> struct tegra_clk_pll *pll;
>> struct clk *clk;
>> - u32 val, val_aux;
>>
>> pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
>> if (IS_ERR(pll))
>> return ERR_CAST(pll);
>>
>> - /* ensure parent is set to pll_re_vco */
>> -
>> - val = pll_readl_base(pll);
>> - val_aux = pll_readl(pll_params->aux_reg, pll);
>> -
>> - if (val & PLLE_BASE_ENABLE) {
>> - if ((val_aux & PLLE_AUX_PLLRE_SEL) ||
>> - (val_aux & PLLE_AUX_PLLP_SEL))
>> - WARN(1, "pll_e enabled with unsupported parent %s\n",
>> - (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" :
>> - "pll_re_vco");
>> - } else {
>> - val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL);
>> - pll_writel(val_aux, pll_params->aux_reg, pll);
>> - }
>> + _clk_plle_tegra_init_parent(pll);
>>
>> clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
>> &tegra_clk_plle_tegra210_ops);
>> diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
>> index 4721ee030d1c..58397f93166c 100644
>> --- a/drivers/clk/tegra/clk-tegra210.c
>> +++ b/drivers/clk/tegra/clk-tegra210.c
>> @@ -1602,7 +1602,7 @@ static struct tegra_clk_pll_params pll_x_params = {
>> .pdiv_tohw = pll_qlin_pdiv_to_hw,
>> .div_nmp = &pllx_nmp,
>> .freq_table = pll_x_freq_table,
>> - .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
>> + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLLX,
>> .dyn_ramp = tegra210_pllx_dyn_ramp,
>> .set_defaults = tegra210_pllx_set_defaults,
>> .calc_rate = tegra210_pll_fixed_mdiv_cfg,
>> diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
>> index fb29a8c27873..8532f5150091 100644
>> --- a/drivers/clk/tegra/clk.h
>> +++ b/drivers/clk/tegra/clk.h
>> @@ -235,6 +235,8 @@ struct tegra_clk_pll;
>> * TEGRA_PLLMB - PLLMB has should be treated similar to PLLM. This
>> * flag indicated that it is PLLMB.
>> * TEGRA_PLL_VCO_OUT - Used to indicate that the PLL has a VCO output
>> + * TEGRA_PLLRE - Used to indicate that it is PLLRE.
>> + * TEGRA_PLLX - Used to indicate that it is PLLX.
>> */
>> struct tegra_clk_pll_params {
>> unsigned long input_min;
>> @@ -301,6 +303,8 @@ struct tegra_clk_pll_params {
>> #define TEGRA_MDIV_NEW BIT(11)
>> #define TEGRA_PLLMB BIT(12)
>> #define TEGRA_PLL_VCO_OUT BIT(13)
>> +#define TEGRA_PLLRE BIT(14)
>> +#define TEGRA_PLLX BIT(15)
>>
>> /**
>> * struct tegra_clk_pll - Tegra PLL clock
>> @@ -310,6 +314,8 @@ struct tegra_clk_pll_params {
>> * @pmc: address of PMC, required to read override bits
>> * @lock: register lock
>> * @params: PLL parameters
>> + * @rate: rate during system suspend and resume
>> + * @pllbase_ctx: pll base register value during suspend and resume
>> */
>> struct tegra_clk_pll {
>> struct clk_hw hw;
>> @@ -317,6 +323,8 @@ struct tegra_clk_pll {
>> void __iomem *pmc;
>> spinlock_t *lock;
>> struct tegra_clk_pll_params *params;
>> + unsigned long rate;
>> + u32 pllbase_ctx;
>> };
>>
>> #define to_clk_pll(_hw) container_of(_hw, struct tegra_clk_pll, hw)
>> @@ -840,7 +848,7 @@ u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate);
>> int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div);
>> int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
>> u8 frac_width, u8 flags);
>> -
>> +void tegra_clk_sync_state_pll(struct clk_hw *hw);
>>
>> /* Combined read fence with delay */
>> #define fence_udelay(delay, reg) \
>>
^ permalink raw reply
* Re: [PATCH 1/2] [PATCH] gpio: Replace usage of bare 'unsigned' with 'unsigned int'
From: Hennie Muller @ 2019-07-22 4:51 UTC (permalink / raw)
To: Phil Reid; +Cc: Linus Walleij, Bartosz Golaszewski, linux-gpio, linux-kernel
In-Reply-To: <61045f29-73ca-cb62-ba6f-5b12970735a9@electromag.com.au>
On Mon, Jul 22, 2019 at 10:05:00AM +0800, Phil Reid wrote:
> G'day Hennie,
>
> patch title should be:
> gpio: viperboard: Replace usage of bare 'unsigned' with 'unsigned int'
Thanks Phil.
I'll go read up a bit on amending commit messages for review.
>
> On 21/07/2019 20:52, Hennie Muller wrote:
> > Fixes a couple of warnings by checkpatch and sparse.
> >
> > Signed-off-by: Hennie Muller <hm@bitlabs.co.za>
> > ---
> > drivers/gpio/gpio-viperboard.c | 20 ++++++++++----------
> > 1 file changed, 10 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/gpio/gpio-viperboard.c b/drivers/gpio/gpio-viperboard.c
> > index 9b604f13e302..c301c1d56dd2 100644
> > --- a/drivers/gpio/gpio-viperboard.c
> > +++ b/drivers/gpio/gpio-viperboard.c
> > @@ -79,7 +79,7 @@ MODULE_PARM_DESC(gpioa_freq,
> > /* ----- begin of gipo a chip -------------------------------------------- */
> > static int vprbrd_gpioa_get(struct gpio_chip *chip,
> > - unsigned offset)
> > + unsigned int offset)
>
> I've encountered these checkpatch warnings as well.
>
> However 'struct gpio_chip' callbacks define the function signatures
> as 'unsigned', not 'unsigned int'. So I've also left them as is, to explicitly
> match the struct definition.
>
> Be interested to know what the official take on this is.
In hindsight, I saw most of the other gpio drivers follow the same
convention as the viperboard driver. which means
a) my changes add no value and just creates inconsistency.
or
b) there's an opportunity to fix up the rest of the gpio drivers as
well? Which I'll be happy to do.
I'll be eagerly awaiting feedback.
>
>
> > {
> > int ret, answer, error = 0;
> > struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
> > @@ -129,7 +129,7 @@ static int vprbrd_gpioa_get(struct gpio_chip *chip,
> > }
> > static void vprbrd_gpioa_set(struct gpio_chip *chip,
> > - unsigned offset, int value)
> > + unsigned int offset, int value)
> > {
> > int ret;
> > struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
> > @@ -170,7 +170,7 @@ static void vprbrd_gpioa_set(struct gpio_chip *chip,
> > }
> > static int vprbrd_gpioa_direction_input(struct gpio_chip *chip,
> > - unsigned offset)
> > + unsigned int offset)
> > {
> > int ret;
> > struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
> > @@ -207,7 +207,7 @@ static int vprbrd_gpioa_direction_input(struct gpio_chip *chip,
> > }
> > static int vprbrd_gpioa_direction_output(struct gpio_chip *chip,
> > - unsigned offset, int value)
> > + unsigned int offset, int value)
> > {
> > int ret;
> > struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
> > @@ -251,8 +251,8 @@ static int vprbrd_gpioa_direction_output(struct gpio_chip *chip,
> > /* ----- begin of gipo b chip -------------------------------------------- */
> > -static int vprbrd_gpiob_setdir(struct vprbrd *vb, unsigned offset,
> > - unsigned dir)
> > +static int vprbrd_gpiob_setdir(struct vprbrd *vb, unsigned int offset,
> > + unsigned int dir)
> > {
> > struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf;
> > int ret;
> > @@ -273,7 +273,7 @@ static int vprbrd_gpiob_setdir(struct vprbrd *vb, unsigned offset,
> > }
> > static int vprbrd_gpiob_get(struct gpio_chip *chip,
> > - unsigned offset)
> > + unsigned int offset)
> > {
> > int ret;
> > u16 val;
> > @@ -305,7 +305,7 @@ static int vprbrd_gpiob_get(struct gpio_chip *chip,
> > }
> > static void vprbrd_gpiob_set(struct gpio_chip *chip,
> > - unsigned offset, int value)
> > + unsigned int offset, int value)
> > {
> > int ret;
> > struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
> > @@ -338,7 +338,7 @@ static void vprbrd_gpiob_set(struct gpio_chip *chip,
> > }
> > static int vprbrd_gpiob_direction_input(struct gpio_chip *chip,
> > - unsigned offset)
> > + unsigned int offset)
> > {
> > int ret;
> > struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
> > @@ -359,7 +359,7 @@ static int vprbrd_gpiob_direction_input(struct gpio_chip *chip,
> > }
> > static int vprbrd_gpiob_direction_output(struct gpio_chip *chip,
> > - unsigned offset, int value)
> > + unsigned int offset, int value)
> > {
> > int ret;
> > struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
> >
>
>
> --
> Regards
> Phil Reid
^ permalink raw reply
* [PATCH 09/18] dt-bindings: sdhci-iproc: Add brcm,bcm2711-emmc2
From: Stefan Wahren @ 2019-07-22 5:54 UTC (permalink / raw)
To: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
Nicolas Saenz Julienne, Matthias Brugger, Rob Herring,
Mark Rutland, Linus Walleij, Michael Turquette, Stephen Boyd,
Ulf Hansson, Adrian Hunter
Cc: bcm-kernel-feedback-list, linux-arm-kernel, linux-rpi-kernel,
linux-gpio, linux-mmc, Stefan Wahren
In-Reply-To: <1563774880-8061-1-git-send-email-wahrenst@gmx.net>
Add a new compatible for the additional emmc2 controller
on BCM2711 and clearify usage.
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
---
Documentation/devicetree/bindings/mmc/brcm,sdhci-iproc.txt | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/mmc/brcm,sdhci-iproc.txt b/Documentation/devicetree/bindings/mmc/brcm,sdhci-iproc.txt
index fa90d25..09d87cc 100644
--- a/Documentation/devicetree/bindings/mmc/brcm,sdhci-iproc.txt
+++ b/Documentation/devicetree/bindings/mmc/brcm,sdhci-iproc.txt
@@ -6,10 +6,12 @@ by mmc.txt and the properties that represent the IPROC SDHCI controller.
Required properties:
- compatible : Should be one of the following
"brcm,bcm2835-sdhci"
+ "brcm,bcm2711-emmc2"
"brcm,sdhci-iproc-cygnus"
"brcm,sdhci-iproc"
-Use brcm2835-sdhci for Rasperry PI.
+Use brcm2835-sdhci for the eMMC controller on the BCM2835 (Raspberry Pi) and
+bcm2711-emmc2 for the additional eMMC2 controller on BCM2711.
Use sdhci-iproc-cygnus for Broadcom SDHCI Controllers
restricted to 32bit host accesses to SDHCI registers.
--
2.7.4
^ permalink raw reply related
* [PATCH 01/18] ARM: bcm283x: Reduce register ranges for UART, SPI and I2C
From: Stefan Wahren @ 2019-07-22 5:54 UTC (permalink / raw)
To: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
Nicolas Saenz Julienne, Matthias Brugger, Rob Herring,
Mark Rutland, Linus Walleij, Michael Turquette, Stephen Boyd,
Ulf Hansson, Adrian Hunter
Cc: bcm-kernel-feedback-list, linux-arm-kernel, linux-rpi-kernel,
linux-gpio, linux-mmc, Stefan Wahren
In-Reply-To: <1563774880-8061-1-git-send-email-wahrenst@gmx.net>
The assigned register ranges for UART, SPI and I2C were too wasteful.
In order to avoid overlapping with the new functions on BCM2711
reduce the ranges.
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
---
arch/arm/boot/dts/bcm283x.dtsi | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 4b21ddb..2d191fc 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -397,7 +397,7 @@
uart0: serial@7e201000 {
compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
- reg = <0x7e201000 0x1000>;
+ reg = <0x7e201000 0x200>;
interrupts = <2 25>;
clocks = <&clocks BCM2835_CLOCK_UART>,
<&clocks BCM2835_CLOCK_VPU>;
@@ -428,7 +428,7 @@
spi: spi@7e204000 {
compatible = "brcm,bcm2835-spi";
- reg = <0x7e204000 0x1000>;
+ reg = <0x7e204000 0x200>;
interrupts = <2 22>;
clocks = <&clocks BCM2835_CLOCK_VPU>;
dmas = <&dma 6>, <&dma 7>;
@@ -440,7 +440,7 @@
i2c0: i2c@7e205000 {
compatible = "brcm,bcm2835-i2c";
- reg = <0x7e205000 0x1000>;
+ reg = <0x7e205000 0x200>;
interrupts = <2 21>;
clocks = <&clocks BCM2835_CLOCK_VPU>;
#address-cells = <1>;
--
2.7.4
^ permalink raw reply related
* [PATCH 03/18] ARM: dts: bcm283x: Move BCM2835/6/7 specific to bcm2835-common.dtsi
From: Stefan Wahren @ 2019-07-22 5:54 UTC (permalink / raw)
To: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
Nicolas Saenz Julienne, Matthias Brugger, Rob Herring,
Mark Rutland, Linus Walleij, Michael Turquette, Stephen Boyd,
Ulf Hansson, Adrian Hunter
Cc: bcm-kernel-feedback-list, linux-arm-kernel, linux-rpi-kernel,
linux-gpio, linux-mmc, Stefan Wahren
In-Reply-To: <1563774880-8061-1-git-send-email-wahrenst@gmx.net>
As preparation we want all common BCM2711 + BCM2835/6/7 functions in
bcm283x.dtsi and all BCM2835/6/7 specific in the new bcm2835-common.dtsi.
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
---
arch/arm/boot/dts/bcm2835-common.dtsi | 177 ++++++++++++++++++++++++++++++++++
arch/arm/boot/dts/bcm2835.dtsi | 1 +
arch/arm/boot/dts/bcm2836.dtsi | 1 +
arch/arm/boot/dts/bcm2837.dtsi | 1 +
arch/arm/boot/dts/bcm283x.dtsi | 152 +----------------------------
5 files changed, 181 insertions(+), 151 deletions(-)
create mode 100644 arch/arm/boot/dts/bcm2835-common.dtsi
diff --git a/arch/arm/boot/dts/bcm2835-common.dtsi b/arch/arm/boot/dts/bcm2835-common.dtsi
new file mode 100644
index 0000000..84c2e1b
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2835-common.dtsi
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* This include file covers the common peripherals and configuration between
+ * bcm2835, bcm2836 and bcm2837 implementations.
+ */
+
+/ {
+ interrupt-parent = <&intc>;
+
+ soc {
+ timer@7e003000 {
+ compatible = "brcm,bcm2835-system-timer";
+ reg = <0x7e003000 0x1000>;
+ interrupts = <1 0>, <1 1>, <1 2>, <1 3>;
+ /* This could be a reference to BCM2835_CLOCK_TIMER,
+ * but we don't have the driver using the common clock
+ * support yet.
+ */
+ clock-frequency = <1000000>;
+ };
+
+ dma: dma@7e007000 {
+ compatible = "brcm,bcm2835-dma";
+ reg = <0x7e007000 0xf00>;
+ interrupts = <1 16>,
+ <1 17>,
+ <1 18>,
+ <1 19>,
+ <1 20>,
+ <1 21>,
+ <1 22>,
+ <1 23>,
+ <1 24>,
+ <1 25>,
+ <1 26>,
+ /* dma channel 11-14 share one irq */
+ <1 27>,
+ <1 27>,
+ <1 27>,
+ <1 27>,
+ /* unused shared irq for all channels */
+ <1 28>;
+ interrupt-names = "dma0",
+ "dma1",
+ "dma2",
+ "dma3",
+ "dma4",
+ "dma5",
+ "dma6",
+ "dma7",
+ "dma8",
+ "dma9",
+ "dma10",
+ "dma11",
+ "dma12",
+ "dma13",
+ "dma14",
+ "dma-shared-all";
+ #dma-cells = <1>;
+ brcm,dma-channel-mask = <0x7f35>;
+ };
+
+ intc: interrupt-controller@7e00b200 {
+ compatible = "brcm,bcm2835-armctrl-ic";
+ reg = <0x7e00b200 0x200>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pm: watchdog@7e100000 {
+ compatible = "brcm,bcm2835-pm", "brcm,bcm2835-pm-wdt";
+ #power-domain-cells = <1>;
+ #reset-cells = <1>;
+ reg = <0x7e100000 0x114>,
+ <0x7e00a000 0x24>;
+ clocks = <&clocks BCM2835_CLOCK_V3D>,
+ <&clocks BCM2835_CLOCK_PERI_IMAGE>,
+ <&clocks BCM2835_CLOCK_H264>,
+ <&clocks BCM2835_CLOCK_ISP>;
+ clock-names = "v3d", "peri_image", "h264", "isp";
+ system-power-controller;
+ };
+
+ thermal: thermal@7e212000 {
+ compatible = "brcm,bcm2835-thermal";
+ reg = <0x7e212000 0x8>;
+ clocks = <&clocks BCM2835_CLOCK_TSENS>;
+ #thermal-sensor-cells = <0>;
+ status = "disabled";
+ };
+
+ v3d: v3d@7ec00000 {
+ compatible = "brcm,bcm2835-v3d";
+ reg = <0x7ec00000 0x1000>;
+ interrupts = <1 10>;
+ };
+
+ vc4: gpu {
+ compatible = "brcm,bcm2835-vc4";
+ };
+ };
+
+ usbphy: phy {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
+ };
+};
+
+&cpu_thermal {
+ thermal-sensors = <&thermal>;
+};
+
+&gpio {
+ i2c_slave_gpio18: i2c_slave_gpio18 {
+ brcm,pins = <18 19 20 21>;
+ brcm,function = <BCM2835_FSEL_ALT3>;
+ };
+
+ jtag_gpio4: jtag_gpio4 {
+ brcm,pins = <4 5 6 12 13>;
+ brcm,function = <BCM2835_FSEL_ALT5>;
+ };
+
+ pwm0_gpio12: pwm0_gpio12 {
+ brcm,pins = <12>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ pwm0_gpio18: pwm0_gpio18 {
+ brcm,pins = <18>;
+ brcm,function = <BCM2835_FSEL_ALT5>;
+ };
+ pwm0_gpio40: pwm0_gpio40 {
+ brcm,pins = <40>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ pwm1_gpio13: pwm1_gpio13 {
+ brcm,pins = <13>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ pwm1_gpio19: pwm1_gpio19 {
+ brcm,pins = <19>;
+ brcm,function = <BCM2835_FSEL_ALT5>;
+ };
+ pwm1_gpio41: pwm1_gpio41 {
+ brcm,pins = <41>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+ pwm1_gpio45: pwm1_gpio45 {
+ brcm,pins = <45>;
+ brcm,function = <BCM2835_FSEL_ALT0>;
+ };
+};
+
+&hdmi {
+ dmas = <&dma 17>;
+ dma-names = "audio-rx";
+};
+
+&i2s {
+ dmas = <&dma 2>, <&dma 3>;
+ dma-names = "tx", "rx";
+};
+
+&sdhost {
+ dmas = <&dma 13>;
+ dma-names = "rx-tx";
+};
+
+&spi {
+ dmas = <&dma 6>, <&dma 7>;
+ dma-names = "tx", "rx";
+};
+
+&usb {
+ phys = <&usbphy>;
+ phy-names = "usb2-phy";
+};
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index a5c3824..53bf457 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include "bcm283x.dtsi"
+#include "bcm2835-common.dtsi"
/ {
compatible = "brcm,bcm2835";
diff --git a/arch/arm/boot/dts/bcm2836.dtsi b/arch/arm/boot/dts/bcm2836.dtsi
index c933e84..82d6c46 100644
--- a/arch/arm/boot/dts/bcm2836.dtsi
+++ b/arch/arm/boot/dts/bcm2836.dtsi
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include "bcm283x.dtsi"
+#include "bcm2835-common.dtsi"
/ {
compatible = "brcm,bcm2836";
diff --git a/arch/arm/boot/dts/bcm2837.dtsi b/arch/arm/boot/dts/bcm2837.dtsi
index beb6c50..9e95fee 100644
--- a/arch/arm/boot/dts/bcm2837.dtsi
+++ b/arch/arm/boot/dts/bcm2837.dtsi
@@ -1,4 +1,5 @@
#include "bcm283x.dtsi"
+#include "bcm2835-common.dtsi"
/ {
compatible = "brcm,bcm2837";
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 2d191fc..4329b17 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -18,7 +18,6 @@
/ {
compatible = "brcm,bcm2835";
model = "BCM2835";
- interrupt-parent = <&intc>;
#address-cells = <1>;
#size-cells = <1>;
@@ -36,8 +35,6 @@
polling-delay-passive = <0>;
polling-delay = <1000>;
- thermal-sensors = <&thermal>;
-
trips {
cpu-crit {
temperature = <80000>;
@@ -56,85 +53,12 @@
#address-cells = <1>;
#size-cells = <1>;
- timer@7e003000 {
- compatible = "brcm,bcm2835-system-timer";
- reg = <0x7e003000 0x1000>;
- interrupts = <1 0>, <1 1>, <1 2>, <1 3>;
- /* This could be a reference to BCM2835_CLOCK_TIMER,
- * but we don't have the driver using the common clock
- * support yet.
- */
- clock-frequency = <1000000>;
- };
-
txp@7e004000 {
compatible = "brcm,bcm2835-txp";
reg = <0x7e004000 0x20>;
interrupts = <1 11>;
};
- dma: dma@7e007000 {
- compatible = "brcm,bcm2835-dma";
- reg = <0x7e007000 0xf00>;
- interrupts = <1 16>,
- <1 17>,
- <1 18>,
- <1 19>,
- <1 20>,
- <1 21>,
- <1 22>,
- <1 23>,
- <1 24>,
- <1 25>,
- <1 26>,
- /* dma channel 11-14 share one irq */
- <1 27>,
- <1 27>,
- <1 27>,
- <1 27>,
- /* unused shared irq for all channels */
- <1 28>;
- interrupt-names = "dma0",
- "dma1",
- "dma2",
- "dma3",
- "dma4",
- "dma5",
- "dma6",
- "dma7",
- "dma8",
- "dma9",
- "dma10",
- "dma11",
- "dma12",
- "dma13",
- "dma14",
- "dma-shared-all";
- #dma-cells = <1>;
- brcm,dma-channel-mask = <0x7f35>;
- };
-
- intc: interrupt-controller@7e00b200 {
- compatible = "brcm,bcm2835-armctrl-ic";
- reg = <0x7e00b200 0x200>;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- pm: watchdog@7e100000 {
- compatible = "brcm,bcm2835-pm", "brcm,bcm2835-pm-wdt";
- #power-domain-cells = <1>;
- #reset-cells = <1>;
- reg = <0x7e100000 0x114>,
- <0x7e00a000 0x24>;
- clocks = <&clocks BCM2835_CLOCK_V3D>,
- <&clocks BCM2835_CLOCK_PERI_IMAGE>,
- <&clocks BCM2835_CLOCK_H264>,
- <&clocks BCM2835_CLOCK_ISP>;
- clock-names = "v3d", "peri_image", "h264", "isp";
- system-power-controller;
- };
-
clocks: cprman@7e101000 {
compatible = "brcm,bcm2835-cprman";
#clock-cells = <1>;
@@ -184,8 +108,7 @@
interrupt-controller;
#interrupt-cells = <2>;
- /* Defines pin muxing groups according to
- * BCM2835-ARM-Peripherals.pdf page 102.
+ /* Defines common pin muxing groups
*
* While each pin can have its mux selected
* for various functions individually, some
@@ -263,15 +186,7 @@
brcm,pins = <44 45>;
brcm,function = <BCM2835_FSEL_ALT2>;
};
- i2c_slave_gpio18: i2c_slave_gpio18 {
- brcm,pins = <18 19 20 21>;
- brcm,function = <BCM2835_FSEL_ALT3>;
- };
- jtag_gpio4: jtag_gpio4 {
- brcm,pins = <4 5 6 12 13>;
- brcm,function = <BCM2835_FSEL_ALT5>;
- };
jtag_gpio22: jtag_gpio22 {
brcm,pins = <22 23 24 25 26 27>;
brcm,function = <BCM2835_FSEL_ALT4>;
@@ -286,35 +201,6 @@
brcm,function = <BCM2835_FSEL_ALT2>;
};
- pwm0_gpio12: pwm0_gpio12 {
- brcm,pins = <12>;
- brcm,function = <BCM2835_FSEL_ALT0>;
- };
- pwm0_gpio18: pwm0_gpio18 {
- brcm,pins = <18>;
- brcm,function = <BCM2835_FSEL_ALT5>;
- };
- pwm0_gpio40: pwm0_gpio40 {
- brcm,pins = <40>;
- brcm,function = <BCM2835_FSEL_ALT0>;
- };
- pwm1_gpio13: pwm1_gpio13 {
- brcm,pins = <13>;
- brcm,function = <BCM2835_FSEL_ALT0>;
- };
- pwm1_gpio19: pwm1_gpio19 {
- brcm,pins = <19>;
- brcm,function = <BCM2835_FSEL_ALT5>;
- };
- pwm1_gpio41: pwm1_gpio41 {
- brcm,pins = <41>;
- brcm,function = <BCM2835_FSEL_ALT0>;
- };
- pwm1_gpio45: pwm1_gpio45 {
- brcm,pins = <45>;
- brcm,function = <BCM2835_FSEL_ALT0>;
- };
-
sdhost_gpio48: sdhost_gpio48 {
brcm,pins = <48 49 50 51 52 53>;
brcm,function = <BCM2835_FSEL_ALT0>;
@@ -410,8 +296,6 @@
reg = <0x7e202000 0x100>;
interrupts = <2 24>;
clocks = <&clocks BCM2835_CLOCK_VPU>;
- dmas = <&dma 13>;
- dma-names = "rx-tx";
status = "disabled";
};
@@ -419,10 +303,6 @@
compatible = "brcm,bcm2835-i2s";
reg = <0x7e203000 0x24>;
clocks = <&clocks BCM2835_CLOCK_PCM>;
-
- dmas = <&dma 2>,
- <&dma 3>;
- dma-names = "tx", "rx";
status = "disabled";
};
@@ -431,8 +311,6 @@
reg = <0x7e204000 0x200>;
interrupts = <2 22>;
clocks = <&clocks BCM2835_CLOCK_VPU>;
- dmas = <&dma 6>, <&dma 7>;
- dma-names = "tx", "rx";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -490,14 +368,6 @@
};
- thermal: thermal@7e212000 {
- compatible = "brcm,bcm2835-thermal";
- reg = <0x7e212000 0x8>;
- clocks = <&clocks BCM2835_CLOCK_TSENS>;
- #thermal-sensor-cells = <0>;
- status = "disabled";
- };
-
aux: aux@7e215000 {
compatible = "brcm,bcm2835-aux";
#clock-cells = <1>;
@@ -620,8 +490,6 @@
clocks = <&clocks BCM2835_PLLH_PIX>,
<&clocks BCM2835_CLOCK_HSM>;
clock-names = "pixel", "hdmi";
- dmas = <&dma 17>;
- dma-names = "audio-rx";
status = "disabled";
};
@@ -633,19 +501,6 @@
#size-cells = <0>;
clocks = <&clk_usb>;
clock-names = "otg";
- phys = <&usbphy>;
- phy-names = "usb2-phy";
- };
-
- v3d: v3d@7ec00000 {
- compatible = "brcm,bcm2835-v3d";
- reg = <0x7ec00000 0x1000>;
- interrupts = <1 10>;
- power-domains = <&pm BCM2835_POWER_DOMAIN_GRAFX_V3D>;
- };
-
- vc4: gpu {
- compatible = "brcm,bcm2835-vc4";
};
};
@@ -671,9 +526,4 @@
clock-frequency = <480000000>;
};
};
-
- usbphy: phy {
- compatible = "usb-nop-xceiv";
- #phy-cells = <0>;
- };
};
--
2.7.4
^ permalink raw reply related
* [PATCH 06/18] dt-bindings: bcm2835-cprman: Add bcm2711 support
From: Stefan Wahren @ 2019-07-22 5:54 UTC (permalink / raw)
To: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
Nicolas Saenz Julienne, Matthias Brugger, Rob Herring,
Mark Rutland, Linus Walleij, Michael Turquette, Stephen Boyd,
Ulf Hansson, Adrian Hunter
Cc: bcm-kernel-feedback-list, linux-arm-kernel, linux-rpi-kernel,
linux-gpio, linux-mmc, Stefan Wahren
In-Reply-To: <1563774880-8061-1-git-send-email-wahrenst@gmx.net>
The new BCM2711 supports an additional clock for the emmc2 block.
So we need an additional compatible.
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
---
Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt | 4 +++-
include/dt-bindings/clock/bcm2835.h | 2 ++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt
index dd906db..9e0b03a 100644
--- a/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt
+++ b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt
@@ -12,7 +12,9 @@ clock generators, but a few (like the ARM or HDMI) will source from
the PLL dividers directly.
Required properties:
-- compatible: Should be "brcm,bcm2835-cprman"
+- compatible: should be one of the following,
+ "brcm,bcm2711-cprman"
+ "brcm,bcm2835-cprman"
- #clock-cells: Should be <1>. The permitted clock-specifier values can be
found in include/dt-bindings/clock/bcm2835.h
- reg: Specifies base physical address and size of the registers
diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h
index 2cec01f..b60c0343 100644
--- a/include/dt-bindings/clock/bcm2835.h
+++ b/include/dt-bindings/clock/bcm2835.h
@@ -58,3 +58,5 @@
#define BCM2835_CLOCK_DSI1E 48
#define BCM2835_CLOCK_DSI0P 49
#define BCM2835_CLOCK_DSI1P 50
+
+#define BCM2711_CLOCK_EMMC2 51
--
2.7.4
^ permalink raw reply related
* [PATCH 08/18] clk: bcm2835: Add BCM2711_CLOCK_EMMC2 support
From: Stefan Wahren @ 2019-07-22 5:54 UTC (permalink / raw)
To: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
Nicolas Saenz Julienne, Matthias Brugger, Rob Herring,
Mark Rutland, Linus Walleij, Michael Turquette, Stephen Boyd,
Ulf Hansson, Adrian Hunter
Cc: bcm-kernel-feedback-list, linux-arm-kernel, linux-rpi-kernel,
linux-gpio, linux-mmc, Stefan Wahren
In-Reply-To: <1563774880-8061-1-git-send-email-wahrenst@gmx.net>
The new BCM2711 supports an additional clock for the emmc2 block.
So add a new compatible and register this clock only for BCM2711.
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
---
drivers/clk/bcm/clk-bcm2835.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 3231b76..fbdc4e1 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -114,6 +114,8 @@
#define CM_AVEODIV 0x1bc
#define CM_EMMCCTL 0x1c0
#define CM_EMMCDIV 0x1c4
+#define CM_EMMC2CTL 0x1d0
+#define CM_EMMC2DIV 0x1d4
/* General bits for the CM_*CTL regs */
# define CM_ENABLE BIT(4)
@@ -290,7 +292,8 @@
#define BCM2835_MAX_FB_RATE 1750000000u
#define SOC_BCM2835 BIT(0)
-#define SOC_ALL (SOC_BCM2835)
+#define SOC_BCM2711 BIT(1)
+#define SOC_ALL (SOC_BCM2835 | SOC_BCM2711)
/*
* Names of clocks used within the driver that need to be replaced
@@ -1999,6 +2002,16 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 8,
.tcnt_mux = 39),
+ /* EMMC2 clock (only available for BCM2711) */
+ [BCM2711_CLOCK_EMMC2] = REGISTER_PER_CLK(
+ SOC_BCM2711,
+ .name = "emmc2",
+ .ctl_reg = CM_EMMC2CTL,
+ .div_reg = CM_EMMC2DIV,
+ .int_bits = 4,
+ .frac_bits = 8,
+ .tcnt_mux = 42),
+
/* General purpose (GPIO) clocks */
[BCM2835_CLOCK_GP0] = REGISTER_PER_CLK(
SOC_ALL,
@@ -2230,6 +2243,7 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
static const struct of_device_id bcm2835_clk_of_match[] = {
{ .compatible = "brcm,bcm2835-cprman", .data = (void *)SOC_BCM2835 },
+ { .compatible = "brcm,bcm2711-cprman", .data = (void *)SOC_BCM2711 },
{}
};
MODULE_DEVICE_TABLE(of, bcm2835_clk_of_match);
--
2.7.4
^ permalink raw reply related
* [PATCH 02/18] ARM: bcm2835: DMA can only address 1GB
From: Stefan Wahren @ 2019-07-22 5:54 UTC (permalink / raw)
To: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
Nicolas Saenz Julienne, Matthias Brugger, Rob Herring,
Mark Rutland, Linus Walleij, Michael Turquette, Stephen Boyd,
Ulf Hansson, Adrian Hunter
Cc: bcm-kernel-feedback-list, linux-arm-kernel, linux-rpi-kernel,
linux-gpio, linux-mmc, Phil Elwell, Stefan Wahren
In-Reply-To: <1563774880-8061-1-git-send-email-wahrenst@gmx.net>
From: Phil Elwell <phil@raspberrypi.org>
The legacy peripherals on BCM2711 & BCM2835 can only address the
first gigabyte of RAM, so ensure that DMA allocations are restricted to
that region.
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
---
arch/arm/mach-bcm/board_bcm2835.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c
index bfc556f..d2b31a9 100644
--- a/arch/arm/mach-bcm/board_bcm2835.c
+++ b/arch/arm/mach-bcm/board_bcm2835.c
@@ -24,6 +24,7 @@ static const char * const bcm2835_compat[] = {
};
DT_MACHINE_START(BCM2835, "BCM2835")
+ .dma_zone_size = SZ_1G,
.dt_compat = bcm2835_compat,
.smp = smp_ops(bcm2836_smp_ops),
MACHINE_END
--
2.7.4
^ permalink raw reply related
* [PATCH 04/18] ARM: dts: bcm283x: Define MMC interfaces at board level
From: Stefan Wahren @ 2019-07-22 5:54 UTC (permalink / raw)
To: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
Nicolas Saenz Julienne, Matthias Brugger, Rob Herring,
Mark Rutland, Linus Walleij, Michael Turquette, Stephen Boyd,
Ulf Hansson, Adrian Hunter
Cc: bcm-kernel-feedback-list, linux-arm-kernel, linux-rpi-kernel,
linux-gpio, linux-mmc, Stefan Wahren
In-Reply-To: <1563774880-8061-1-git-send-email-wahrenst@gmx.net>
Starting with RPi 4 this is the first board, which doesn't use sdhost
as default SD interface. So the MMC interfaces should be defined finally at
board level. Since all boards using sdhci already does this, we can drop the
pinctrl part from bcm2835-rpi.dtsi.
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
---
arch/arm/boot/dts/bcm2835-rpi-a-plus.dts | 7 +++++++
arch/arm/boot/dts/bcm2835-rpi-a.dts | 7 +++++++
arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 7 +++++++
arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 7 +++++++
arch/arm/boot/dts/bcm2835-rpi-b.dts | 7 +++++++
arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts | 7 +++++++
arch/arm/boot/dts/bcm2835-rpi-zero-w.dts | 7 +++++++
arch/arm/boot/dts/bcm2835-rpi-zero.dts | 7 +++++++
arch/arm/boot/dts/bcm2835-rpi.dtsi | 13 -------------
arch/arm/boot/dts/bcm2836-rpi-2-b.dts | 7 +++++++
arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts | 7 +++++++
11 files changed, 70 insertions(+), 13 deletions(-)
diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
index db8a601..cb3f08d 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
@@ -107,6 +107,13 @@
status = "okay";
};
+&sdhost {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhost_gpio48>;
+ bus-width = <4>;
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_gpio14>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts b/arch/arm/boot/dts/bcm2835-rpi-a.dts
index 067d1f0..2d167d9 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts
@@ -102,6 +102,13 @@
status = "okay";
};
+&sdhost {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhost_gpio48>;
+ bus-width = <4>;
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_gpio14>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
index 1e40d67..83a3a60 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
@@ -109,6 +109,13 @@
status = "okay";
};
+&sdhost {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhost_gpio48>;
+ bus-width = <4>;
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_gpio14>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
index 28e7513..b6b4fea 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
@@ -102,6 +102,13 @@
status = "okay";
};
+&sdhost {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhost_gpio48>;
+ bus-width = <4>;
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_gpio14>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts
index 31ff602..b5782fa 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
@@ -97,6 +97,13 @@
status = "okay";
};
+&sdhost {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhost_gpio48>;
+ bus-width = <4>;
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_gpio14>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts b/arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts
index 4764a25..41afea4 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts
@@ -81,6 +81,13 @@
hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
};
+&sdhost {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhost_gpio48>;
+ bus-width = <4>;
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_gpio14>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
index ba0167d..5ecc403 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
@@ -116,6 +116,13 @@
};
};
+&sdhost {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhost_gpio48>;
+ bus-width = <4>;
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_gpio32 &uart0_ctsrts_gpio30>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero.dts b/arch/arm/boot/dts/bcm2835-rpi-zero.dts
index 3b35a8a..84c7035 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-zero.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-zero.dts
@@ -98,6 +98,13 @@
hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
};
+&sdhost {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhost_gpio48>;
+ bus-width = <4>;
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_gpio14>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 715d50c..40bac52e 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -68,19 +68,6 @@
status = "okay";
};
-&sdhci {
- pinctrl-names = "default";
- pinctrl-0 = <&emmc_gpio48>;
- bus-width = <4>;
-};
-
-&sdhost {
- pinctrl-names = "default";
- pinctrl-0 = <&sdhost_gpio48>;
- status = "okay";
- bus-width = <4>;
-};
-
&usb {
power-domains = <&power RPI_POWER_DOMAIN_USB>;
};
diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
index 7b4e651..f97ec95 100644
--- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
+++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
@@ -113,6 +113,13 @@
status = "okay";
};
+&sdhost {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhost_gpio48>;
+ bus-width = <4>;
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_gpio14>;
diff --git a/arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts b/arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts
index 6c8233a..433e306 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts
+++ b/arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts
@@ -80,6 +80,13 @@
hpd-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
};
+&sdhost {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhost_gpio48>;
+ bus-width = <4>;
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_gpio14>;
--
2.7.4
^ permalink raw reply related
* [PATCH 07/18] clk: bcm2835: Introduce SoC specific clock registration
From: Stefan Wahren @ 2019-07-22 5:54 UTC (permalink / raw)
To: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
Nicolas Saenz Julienne, Matthias Brugger, Rob Herring,
Mark Rutland, Linus Walleij, Michael Turquette, Stephen Boyd,
Ulf Hansson, Adrian Hunter
Cc: bcm-kernel-feedback-list, linux-arm-kernel, linux-rpi-kernel,
linux-gpio, linux-mmc, Stefan Wahren
In-Reply-To: <1563774880-8061-1-git-send-email-wahrenst@gmx.net>
In order to support SoC specific clocks (e.g. emmc2 for BCM2711), we
extend the description with a SoC support flag. This approach avoids long
and mostly redundant lists of clock IDs.
Suggested-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
---
drivers/clk/bcm/clk-bcm2835.c | 103 +++++++++++++++++++++++++++++++++++-------
1 file changed, 86 insertions(+), 17 deletions(-)
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 867ae3c..3231b76 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -31,7 +31,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
-#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <dt-bindings/clock/bcm2835.h>
@@ -289,6 +289,9 @@
#define LOCK_TIMEOUT_NS 100000000
#define BCM2835_MAX_FB_RATE 1750000000u
+#define SOC_BCM2835 BIT(0)
+#define SOC_ALL (SOC_BCM2835)
+
/*
* Names of clocks used within the driver that need to be replaced
* with an external parent's name. This array is in the order that
@@ -1451,22 +1454,28 @@ typedef struct clk_hw *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman,
const void *data);
struct bcm2835_clk_desc {
bcm2835_clk_register clk_register;
+ unsigned int supported;
const void *data;
};
/* assignment helper macros for different clock types */
-#define _REGISTER(f, ...) { .clk_register = (bcm2835_clk_register)f, \
- .data = __VA_ARGS__ }
-#define REGISTER_PLL(...) _REGISTER(&bcm2835_register_pll, \
+#define _REGISTER(f, s, ...) { .clk_register = (bcm2835_clk_register)f, \
+ .supported = s, \
+ .data = __VA_ARGS__ }
+#define REGISTER_PLL(s, ...) _REGISTER(&bcm2835_register_pll, \
+ s, \
&(struct bcm2835_pll_data) \
{__VA_ARGS__})
-#define REGISTER_PLL_DIV(...) _REGISTER(&bcm2835_register_pll_divider, \
- &(struct bcm2835_pll_divider_data) \
- {__VA_ARGS__})
-#define REGISTER_CLK(...) _REGISTER(&bcm2835_register_clock, \
+#define REGISTER_PLL_DIV(s, ...) _REGISTER(&bcm2835_register_pll_divider, \
+ s, \
+ &(struct bcm2835_pll_divider_data) \
+ {__VA_ARGS__})
+#define REGISTER_CLK(s, ...) _REGISTER(&bcm2835_register_clock, \
+ s, \
&(struct bcm2835_clock_data) \
{__VA_ARGS__})
-#define REGISTER_GATE(...) _REGISTER(&bcm2835_register_gate, \
+#define REGISTER_GATE(s, ...) _REGISTER(&bcm2835_register_gate, \
+ s, \
&(struct bcm2835_gate_data) \
{__VA_ARGS__})
@@ -1480,7 +1489,8 @@ static const char *const bcm2835_clock_osc_parents[] = {
"testdebug1"
};
-#define REGISTER_OSC_CLK(...) REGISTER_CLK( \
+#define REGISTER_OSC_CLK(s, ...) REGISTER_CLK( \
+ s, \
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), \
.parents = bcm2835_clock_osc_parents, \
__VA_ARGS__)
@@ -1497,7 +1507,8 @@ static const char *const bcm2835_clock_per_parents[] = {
"pllh_aux",
};
-#define REGISTER_PER_CLK(...) REGISTER_CLK( \
+#define REGISTER_PER_CLK(s, ...) REGISTER_CLK( \
+ s, \
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), \
.parents = bcm2835_clock_per_parents, \
__VA_ARGS__)
@@ -1522,7 +1533,8 @@ static const char *const bcm2835_pcm_per_parents[] = {
"-",
};
-#define REGISTER_PCM_CLK(...) REGISTER_CLK( \
+#define REGISTER_PCM_CLK(s, ...) REGISTER_CLK( \
+ s, \
.num_mux_parents = ARRAY_SIZE(bcm2835_pcm_per_parents), \
.parents = bcm2835_pcm_per_parents, \
__VA_ARGS__)
@@ -1541,7 +1553,8 @@ static const char *const bcm2835_clock_vpu_parents[] = {
"pllc_core2",
};
-#define REGISTER_VPU_CLK(...) REGISTER_CLK( \
+#define REGISTER_VPU_CLK(s, ...) REGISTER_CLK( \
+ s, \
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), \
.parents = bcm2835_clock_vpu_parents, \
__VA_ARGS__)
@@ -1577,12 +1590,14 @@ static const char *const bcm2835_clock_dsi1_parents[] = {
"dsi1_byte_inv",
};
-#define REGISTER_DSI0_CLK(...) REGISTER_CLK( \
+#define REGISTER_DSI0_CLK(s, ...) REGISTER_CLK( \
+ s, \
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi0_parents), \
.parents = bcm2835_clock_dsi0_parents, \
__VA_ARGS__)
-#define REGISTER_DSI1_CLK(...) REGISTER_CLK( \
+#define REGISTER_DSI1_CLK(s, ...) REGISTER_CLK( \
+ s, \
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi1_parents), \
.parents = bcm2835_clock_dsi1_parents, \
__VA_ARGS__)
@@ -1602,6 +1617,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* AUDIO domain is on.
*/
[BCM2835_PLLA] = REGISTER_PLL(
+ SOC_ALL,
.name = "plla",
.cm_ctrl_reg = CM_PLLA,
.a2w_ctrl_reg = A2W_PLLA_CTRL,
@@ -1616,6 +1632,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.max_rate = 2400000000u,
.max_fb_rate = BCM2835_MAX_FB_RATE),
[BCM2835_PLLA_CORE] = REGISTER_PLL_DIV(
+ SOC_ALL,
.name = "plla_core",
.source_pll = "plla",
.cm_reg = CM_PLLA,
@@ -1625,6 +1642,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLA_PER] = REGISTER_PLL_DIV(
+ SOC_ALL,
.name = "plla_per",
.source_pll = "plla",
.cm_reg = CM_PLLA,
@@ -1634,6 +1652,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLA_DSI0] = REGISTER_PLL_DIV(
+ SOC_ALL,
.name = "plla_dsi0",
.source_pll = "plla",
.cm_reg = CM_PLLA,
@@ -1642,6 +1661,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.hold_mask = CM_PLLA_HOLDDSI0,
.fixed_divider = 1),
[BCM2835_PLLA_CCP2] = REGISTER_PLL_DIV(
+ SOC_ALL,
.name = "plla_ccp2",
.source_pll = "plla",
.cm_reg = CM_PLLA,
@@ -1663,6 +1683,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* AUDIO domain is on.
*/
[BCM2835_PLLC] = REGISTER_PLL(
+ SOC_ALL,
.name = "pllc",
.cm_ctrl_reg = CM_PLLC,
.a2w_ctrl_reg = A2W_PLLC_CTRL,
@@ -1677,6 +1698,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.max_rate = 3000000000u,
.max_fb_rate = BCM2835_MAX_FB_RATE),
[BCM2835_PLLC_CORE0] = REGISTER_PLL_DIV(
+ SOC_ALL,
.name = "pllc_core0",
.source_pll = "pllc",
.cm_reg = CM_PLLC,
@@ -1686,6 +1708,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV(
+ SOC_ALL,
.name = "pllc_core1",
.source_pll = "pllc",
.cm_reg = CM_PLLC,
@@ -1695,6 +1718,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV(
+ SOC_ALL,
.name = "pllc_core2",
.source_pll = "pllc",
.cm_reg = CM_PLLC,
@@ -1704,6 +1728,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLC_PER] = REGISTER_PLL_DIV(
+ SOC_ALL,
.name = "pllc_per",
.source_pll = "pllc",
.cm_reg = CM_PLLC,
@@ -1720,6 +1745,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* AUDIO domain is on.
*/
[BCM2835_PLLD] = REGISTER_PLL(
+ SOC_ALL,
.name = "plld",
.cm_ctrl_reg = CM_PLLD,
.a2w_ctrl_reg = A2W_PLLD_CTRL,
@@ -1734,6 +1760,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.max_rate = 2400000000u,
.max_fb_rate = BCM2835_MAX_FB_RATE),
[BCM2835_PLLD_CORE] = REGISTER_PLL_DIV(
+ SOC_ALL,
.name = "plld_core",
.source_pll = "plld",
.cm_reg = CM_PLLD,
@@ -1743,6 +1770,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLD_PER] = REGISTER_PLL_DIV(
+ SOC_ALL,
.name = "plld_per",
.source_pll = "plld",
.cm_reg = CM_PLLD,
@@ -1752,6 +1780,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLD_DSI0] = REGISTER_PLL_DIV(
+ SOC_ALL,
.name = "plld_dsi0",
.source_pll = "plld",
.cm_reg = CM_PLLD,
@@ -1760,6 +1789,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.hold_mask = CM_PLLD_HOLDDSI0,
.fixed_divider = 1),
[BCM2835_PLLD_DSI1] = REGISTER_PLL_DIV(
+ SOC_ALL,
.name = "plld_dsi1",
.source_pll = "plld",
.cm_reg = CM_PLLD,
@@ -1775,6 +1805,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* It is in the HDMI power domain.
*/
[BCM2835_PLLH] = REGISTER_PLL(
+ SOC_ALL,
"pllh",
.cm_ctrl_reg = CM_PLLH,
.a2w_ctrl_reg = A2W_PLLH_CTRL,
@@ -1789,6 +1820,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.max_rate = 3000000000u,
.max_fb_rate = BCM2835_MAX_FB_RATE),
[BCM2835_PLLH_RCAL] = REGISTER_PLL_DIV(
+ SOC_ALL,
.name = "pllh_rcal",
.source_pll = "pllh",
.cm_reg = CM_PLLH,
@@ -1798,6 +1830,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 10,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLH_AUX] = REGISTER_PLL_DIV(
+ SOC_ALL,
.name = "pllh_aux",
.source_pll = "pllh",
.cm_reg = CM_PLLH,
@@ -1807,6 +1840,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(
+ SOC_ALL,
.name = "pllh_pix",
.source_pll = "pllh",
.cm_reg = CM_PLLH,
@@ -1822,6 +1856,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
/* One Time Programmable Memory clock. Maximum 10Mhz. */
[BCM2835_CLOCK_OTP] = REGISTER_OSC_CLK(
+ SOC_ALL,
.name = "otp",
.ctl_reg = CM_OTPCTL,
.div_reg = CM_OTPDIV,
@@ -1833,6 +1868,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* bythe watchdog timer and the camera pulse generator.
*/
[BCM2835_CLOCK_TIMER] = REGISTER_OSC_CLK(
+ SOC_ALL,
.name = "timer",
.ctl_reg = CM_TIMERCTL,
.div_reg = CM_TIMERDIV,
@@ -1843,12 +1879,14 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* Generally run at 2Mhz, max 5Mhz.
*/
[BCM2835_CLOCK_TSENS] = REGISTER_OSC_CLK(
+ SOC_ALL,
.name = "tsens",
.ctl_reg = CM_TSENSCTL,
.div_reg = CM_TSENSDIV,
.int_bits = 5,
.frac_bits = 0),
[BCM2835_CLOCK_TEC] = REGISTER_OSC_CLK(
+ SOC_ALL,
.name = "tec",
.ctl_reg = CM_TECCTL,
.div_reg = CM_TECDIV,
@@ -1857,6 +1895,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
/* clocks with vpu parent mux */
[BCM2835_CLOCK_H264] = REGISTER_VPU_CLK(
+ SOC_ALL,
.name = "h264",
.ctl_reg = CM_H264CTL,
.div_reg = CM_H264DIV,
@@ -1864,6 +1903,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 8,
.tcnt_mux = 1),
[BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK(
+ SOC_ALL,
.name = "isp",
.ctl_reg = CM_ISPCTL,
.div_reg = CM_ISPDIV,
@@ -1876,6 +1916,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* in the SDRAM controller can't be used.
*/
[BCM2835_CLOCK_SDRAM] = REGISTER_VPU_CLK(
+ SOC_ALL,
.name = "sdram",
.ctl_reg = CM_SDCCTL,
.div_reg = CM_SDCDIV,
@@ -1883,6 +1924,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 0,
.tcnt_mux = 3),
[BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK(
+ SOC_ALL,
.name = "v3d",
.ctl_reg = CM_V3DCTL,
.div_reg = CM_V3DDIV,
@@ -1896,6 +1938,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* in various hardware documentation.
*/
[BCM2835_CLOCK_VPU] = REGISTER_VPU_CLK(
+ SOC_ALL,
.name = "vpu",
.ctl_reg = CM_VPUCTL,
.div_reg = CM_VPUDIV,
@@ -1907,6 +1950,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
/* clocks with per parent mux */
[BCM2835_CLOCK_AVEO] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "aveo",
.ctl_reg = CM_AVEOCTL,
.div_reg = CM_AVEODIV,
@@ -1914,6 +1958,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 0,
.tcnt_mux = 38),
[BCM2835_CLOCK_CAM0] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "cam0",
.ctl_reg = CM_CAM0CTL,
.div_reg = CM_CAM0DIV,
@@ -1921,6 +1966,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 8,
.tcnt_mux = 14),
[BCM2835_CLOCK_CAM1] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "cam1",
.ctl_reg = CM_CAM1CTL,
.div_reg = CM_CAM1DIV,
@@ -1928,12 +1974,14 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 8,
.tcnt_mux = 15),
[BCM2835_CLOCK_DFT] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "dft",
.ctl_reg = CM_DFTCTL,
.div_reg = CM_DFTDIV,
.int_bits = 5,
.frac_bits = 0),
[BCM2835_CLOCK_DPI] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "dpi",
.ctl_reg = CM_DPICTL,
.div_reg = CM_DPIDIV,
@@ -1943,6 +1991,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
/* Arasan EMMC clock */
[BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "emmc",
.ctl_reg = CM_EMMCCTL,
.div_reg = CM_EMMCDIV,
@@ -1952,6 +2001,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
/* General purpose (GPIO) clocks */
[BCM2835_CLOCK_GP0] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "gp0",
.ctl_reg = CM_GP0CTL,
.div_reg = CM_GP0DIV,
@@ -1960,6 +2010,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.is_mash_clock = true,
.tcnt_mux = 20),
[BCM2835_CLOCK_GP1] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "gp1",
.ctl_reg = CM_GP1CTL,
.div_reg = CM_GP1DIV,
@@ -1969,6 +2020,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.is_mash_clock = true,
.tcnt_mux = 21),
[BCM2835_CLOCK_GP2] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "gp2",
.ctl_reg = CM_GP2CTL,
.div_reg = CM_GP2DIV,
@@ -1978,6 +2030,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
/* HDMI state machine */
[BCM2835_CLOCK_HSM] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "hsm",
.ctl_reg = CM_HSMCTL,
.div_reg = CM_HSMDIV,
@@ -1985,6 +2038,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 8,
.tcnt_mux = 22),
[BCM2835_CLOCK_PCM] = REGISTER_PCM_CLK(
+ SOC_ALL,
.name = "pcm",
.ctl_reg = CM_PCMCTL,
.div_reg = CM_PCMDIV,
@@ -1994,6 +2048,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.low_jitter = true,
.tcnt_mux = 23),
[BCM2835_CLOCK_PWM] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "pwm",
.ctl_reg = CM_PWMCTL,
.div_reg = CM_PWMDIV,
@@ -2002,6 +2057,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.is_mash_clock = true,
.tcnt_mux = 24),
[BCM2835_CLOCK_SLIM] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "slim",
.ctl_reg = CM_SLIMCTL,
.div_reg = CM_SLIMDIV,
@@ -2010,6 +2066,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.is_mash_clock = true,
.tcnt_mux = 25),
[BCM2835_CLOCK_SMI] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "smi",
.ctl_reg = CM_SMICTL,
.div_reg = CM_SMIDIV,
@@ -2017,6 +2074,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 8,
.tcnt_mux = 27),
[BCM2835_CLOCK_UART] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "uart",
.ctl_reg = CM_UARTCTL,
.div_reg = CM_UARTDIV,
@@ -2026,6 +2084,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
/* TV encoder clock. Only operating frequency is 108Mhz. */
[BCM2835_CLOCK_VEC] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "vec",
.ctl_reg = CM_VECCTL,
.div_reg = CM_VECDIV,
@@ -2040,6 +2099,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
/* dsi clocks */
[BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "dsi0e",
.ctl_reg = CM_DSI0ECTL,
.div_reg = CM_DSI0EDIV,
@@ -2047,6 +2107,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 8,
.tcnt_mux = 18),
[BCM2835_CLOCK_DSI1E] = REGISTER_PER_CLK(
+ SOC_ALL,
.name = "dsi1e",
.ctl_reg = CM_DSI1ECTL,
.div_reg = CM_DSI1EDIV,
@@ -2054,6 +2115,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 8,
.tcnt_mux = 19),
[BCM2835_CLOCK_DSI0P] = REGISTER_DSI0_CLK(
+ SOC_ALL,
.name = "dsi0p",
.ctl_reg = CM_DSI0PCTL,
.div_reg = CM_DSI0PDIV,
@@ -2061,6 +2123,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 0,
.tcnt_mux = 12),
[BCM2835_CLOCK_DSI1P] = REGISTER_DSI1_CLK(
+ SOC_ALL,
.name = "dsi1p",
.ctl_reg = CM_DSI1PCTL,
.div_reg = CM_DSI1PDIV,
@@ -2077,6 +2140,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* non-stop vpu clock.
*/
[BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE(
+ SOC_ALL,
.name = "peri_image",
.parent = "vpu",
.ctl_reg = CM_PERIICTL),
@@ -2109,9 +2173,14 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
struct resource *res;
const struct bcm2835_clk_desc *desc;
const size_t asize = ARRAY_SIZE(clk_desc_array);
+ unsigned int soc;
size_t i;
int ret;
+ soc = (unsigned int)of_device_get_match_data(&pdev->dev);
+ if (!soc)
+ return -ENODEV;
+
cprman = devm_kzalloc(dev,
struct_size(cprman, onecell.hws, asize),
GFP_KERNEL);
@@ -2147,7 +2216,7 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
for (i = 0; i < asize; i++) {
desc = &clk_desc_array[i];
- if (desc->clk_register && desc->data)
+ if (desc->clk_register && desc->data && (desc->supported & soc))
hws[i] = desc->clk_register(cprman, desc->data);
}
@@ -2160,7 +2229,7 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
}
static const struct of_device_id bcm2835_clk_of_match[] = {
- { .compatible = "brcm,bcm2835-cprman", },
+ { .compatible = "brcm,bcm2835-cprman", .data = (void *)SOC_BCM2835 },
{}
};
MODULE_DEVICE_TABLE(of, bcm2835_clk_of_match);
--
2.7.4
^ permalink raw reply related
* [PATCH 05/18] ARM: dts: bcm283x: Define memory at board level
From: Stefan Wahren @ 2019-07-22 5:54 UTC (permalink / raw)
To: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
Nicolas Saenz Julienne, Matthias Brugger, Rob Herring,
Mark Rutland, Linus Walleij, Michael Turquette, Stephen Boyd,
Ulf Hansson, Adrian Hunter
Cc: bcm-kernel-feedback-list, linux-arm-kernel, linux-rpi-kernel,
linux-gpio, linux-mmc, Stefan Wahren
In-Reply-To: <1563774880-8061-1-git-send-email-wahrenst@gmx.net>
Now with the varity of several RPi boards, the memory should be defined
at board level. This step gives us the chance to fix the memory size
of the RPi 1 B+, Zero (incl. W) and Compute Module 1.
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
---
arch/arm/boot/dts/bcm2835-rpi-a-plus.dts | 5 +++++
arch/arm/boot/dts/bcm2835-rpi-a.dts | 5 +++++
arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 5 +++++
arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 5 +++++
arch/arm/boot/dts/bcm2835-rpi-b.dts | 5 +++++
arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi | 5 +++++
arch/arm/boot/dts/bcm2835-rpi-zero-w.dts | 5 +++++
arch/arm/boot/dts/bcm2835-rpi-zero.dts | 5 +++++
arch/arm/boot/dts/bcm2835-rpi.dtsi | 5 -----
arch/arm/boot/dts/bcm2836-rpi-2-b.dts | 1 +
arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts | 1 +
arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 1 +
arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 1 +
arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi | 1 +
14 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
index cb3f08d..5b42e9a 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
@@ -8,6 +8,11 @@
compatible = "raspberrypi,model-a-plus", "brcm,bcm2835";
model = "Raspberry Pi Model A+";
+ memory@0 {
+ device_type = "memory";
+ reg = <0 0x10000000>;
+ };
+
leds {
act {
gpios = <&gpio 47 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts b/arch/arm/boot/dts/bcm2835-rpi-a.dts
index 2d167d9..b716214 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts
@@ -8,6 +8,11 @@
compatible = "raspberrypi,model-a", "brcm,bcm2835";
model = "Raspberry Pi Model A";
+ memory@0 {
+ device_type = "memory";
+ reg = <0 0x10000000>;
+ };
+
leds {
act {
gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
index 83a3a60..3318082 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
@@ -9,6 +9,11 @@
compatible = "raspberrypi,model-b-plus", "brcm,bcm2835";
model = "Raspberry Pi Model B+";
+ memory@0 {
+ device_type = "memory";
+ reg = <0 0x20000000>;
+ };
+
leds {
act {
gpios = <&gpio 47 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
index b6b4fea..97d7eb5 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
@@ -9,6 +9,11 @@
compatible = "raspberrypi,model-b-rev2", "brcm,bcm2835";
model = "Raspberry Pi Model B rev2";
+ memory@0 {
+ device_type = "memory";
+ reg = <0 0x10000000>;
+ };
+
leds {
act {
gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts
index b5782fa..37e02a1 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
@@ -9,6 +9,11 @@
compatible = "raspberrypi,model-b", "brcm,bcm2835";
model = "Raspberry Pi Model B";
+ memory@0 {
+ device_type = "memory";
+ reg = <0 0x10000000>;
+ };
+
leds {
act {
gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi b/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi
index ef22c2d..58059c2 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi
@@ -10,6 +10,11 @@
};
};
+ memory@0 {
+ device_type = "memory";
+ reg = <0 0x20000000>;
+ };
+
reg_3v3: fixed-regulator {
compatible = "regulator-fixed";
regulator-name = "3V3";
diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
index 5ecc403..f38f388 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
@@ -12,6 +12,11 @@
compatible = "raspberrypi,model-zero-w", "brcm,bcm2835";
model = "Raspberry Pi Zero W";
+ memory@0 {
+ device_type = "memory";
+ reg = <0 0x20000000>;
+ };
+
chosen {
/* 8250 auxiliary UART instead of pl011 */
stdout-path = "serial1:115200n8";
diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero.dts b/arch/arm/boot/dts/bcm2835-rpi-zero.dts
index 84c7035..5fd0686 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-zero.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-zero.dts
@@ -12,6 +12,11 @@
compatible = "raspberrypi,model-zero", "brcm,bcm2835";
model = "Raspberry Pi Zero";
+ memory@0 {
+ device_type = "memory";
+ reg = <0 0x20000000>;
+ };
+
leds {
act {
gpios = <&gpio 47 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 40bac52e..f5125b7 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -1,11 +1,6 @@
#include <dt-bindings/power/raspberrypi-power.h>
/ {
- memory@0 {
- device_type = "memory";
- reg = <0 0x10000000>;
- };
-
leds {
compatible = "gpio-leds";
diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
index f97ec95..6a89999 100644
--- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
+++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
@@ -10,6 +10,7 @@
model = "Raspberry Pi 2 Model B";
memory@0 {
+ device_type = "memory";
reg = <0 0x40000000>;
};
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts b/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
index 7f4437a..0e29aaa 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
@@ -14,6 +14,7 @@
};
memory@0 {
+ device_type = "memory";
reg = <0 0x20000000>;
};
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
index c6fa34c..a1487ae 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
@@ -15,6 +15,7 @@
};
memory@0 {
+ device_type = "memory";
reg = <0 0x40000000>;
};
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
index ce71f57..a36bfdb 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
@@ -15,6 +15,7 @@
};
memory@0 {
+ device_type = "memory";
reg = <0 0x40000000>;
};
diff --git a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
index 81399b2..7c3cb7e 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
+++ b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
@@ -5,6 +5,7 @@
/ {
memory@0 {
+ device_type = "memory";
reg = <0 0x40000000>;
};
--
2.7.4
^ permalink raw reply related
* [PATCH 00/18] ARM: Add minimal Raspberry Pi 4 support
From: Stefan Wahren @ 2019-07-22 5:54 UTC (permalink / raw)
To: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
Nicolas Saenz Julienne, Matthias Brugger, Rob Herring,
Mark Rutland, Linus Walleij, Michael Turquette, Stephen Boyd,
Ulf Hansson, Adrian Hunter
Cc: bcm-kernel-feedback-list, linux-arm-kernel, linux-rpi-kernel,
linux-gpio, linux-mmc, Stefan Wahren
This series adds minimal support for the new Raspberry Pi 4, so we are able
to login via debug UART.
Patch 1-5: Prepare platform and DTS for the new SoC BMC2711
Patch 6-10: Enable support for emmc2 on BCM2711
Patch 11-12: Enable pinctrl for BCM2711
Patch 13-17: Add Raspberry Pi 4 DTS support
Patch 18: Update MAINTAINERS
Unfortunately the Raspberry Pi Foundation didn't released a
peripheral documentation for the new SoC yet. So we only have a preliminary
datasheet [1] and reduced schematics [2].
Changes since RFC:
- change BCM2838 -> BCM2711 as discussed in RFC
- update MAINTAINERS accordingly
- drop "spi: bcm2835: enable shared interrupt support" from series
- squash all pinctrl-bcm2835 changes into one patch
- introduce SoC specific clock registration as suggested by Florian
- fix watchdog probing for Raspberry Pi 4
- convert brcm,bcm2835.txt to json-schema
- move VC4 node to bcm2835-common.dtsi
- fallback to legacy pull config for Raspberry Pi 4
- revert unintended change of mailbox in bcm283x.dtsi
- add reference for arm64
[1] - https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/rpi_DATA_2711_1p0_preliminary.pdf
[2] - https://www.raspberrypi.org/documentation/hardware/raspberrypi/schematics/rpi_SCH_4b_4p0_reduced.pdf
Phil Elwell (1):
ARM: bcm2835: DMA can only address 1GB
Stefan Wahren (17):
ARM: bcm283x: Reduce register ranges for UART, SPI and I2C
ARM: dts: bcm283x: Move BCM2835/6/7 specific to bcm2835-common.dtsi
ARM: dts: bcm283x: Define MMC interfaces at board level
ARM: dts: bcm283x: Define memory at board level
dt-bindings: bcm2835-cprman: Add bcm2711 support
clk: bcm2835: Introduce SoC specific clock registration
clk: bcm2835: Add BCM2711_CLOCK_EMMC2 support
dt-bindings: sdhci-iproc: Add brcm,bcm2711-emmc2
mmc: sdhci-iproc: Add support for emmc2 of the BCM2711
dt-bindings: pinctrl: bcm2835: Add brcm,bcm2711 compatible
pinctrl: bcm2835: Add support for BCM2711 pull-up functionality
dt-bindings: arm: Convert BCM2835 board/soc bindings to json-schema
dt-bindings: arm: bcm2835: Add Raspberry Pi 4 to DT schema
ARM: bcm2835: Add bcm2711 compatible string
ARM: dts: Add minimal Raspberry Pi 4 support
arm64: dts: broadcom: Add reference to RPi 4 B
MAINTAINERS: Add BCM2711 to BCM2835 ARCH
.../devicetree/bindings/arm/bcm/bcm2835.yaml | 51 ++
.../devicetree/bindings/arm/bcm/brcm,bcm2835.txt | 67 ---
.../bindings/clock/brcm,bcm2835-cprman.txt | 4 +-
.../devicetree/bindings/mmc/brcm,sdhci-iproc.txt | 4 +-
.../bindings/pinctrl/brcm,bcm2835-gpio.txt | 1 +
MAINTAINERS | 3 +-
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 120 ++++
arch/arm/boot/dts/bcm2711.dtsi | 667 +++++++++++++++++++++
arch/arm/boot/dts/bcm2835-common.dtsi | 177 ++++++
arch/arm/boot/dts/bcm2835-rpi-a-plus.dts | 12 +
arch/arm/boot/dts/bcm2835-rpi-a.dts | 12 +
arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 12 +
arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 12 +
arch/arm/boot/dts/bcm2835-rpi-b.dts | 12 +
arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts | 7 +
arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi | 5 +
arch/arm/boot/dts/bcm2835-rpi-zero-w.dts | 12 +
arch/arm/boot/dts/bcm2835-rpi-zero.dts | 12 +
arch/arm/boot/dts/bcm2835-rpi.dtsi | 18 -
arch/arm/boot/dts/bcm2835.dtsi | 1 +
arch/arm/boot/dts/bcm2836-rpi-2-b.dts | 8 +
arch/arm/boot/dts/bcm2836.dtsi | 1 +
arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts | 1 +
arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 1 +
arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 1 +
arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts | 7 +
arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi | 1 +
arch/arm/boot/dts/bcm2837.dtsi | 1 +
arch/arm/boot/dts/bcm283x.dtsi | 160 +----
arch/arm/mach-bcm/board_bcm2835.c | 2 +
arch/arm64/boot/dts/broadcom/Makefile | 3 +-
arch/arm64/boot/dts/broadcom/bcm2711-rpi-4-b.dts | 2 +
drivers/clk/bcm/clk-bcm2835.c | 117 +++-
drivers/mmc/host/sdhci-iproc.c | 9 +
drivers/pinctrl/bcm/pinctrl-bcm2835.c | 105 +++-
include/dt-bindings/clock/bcm2835.h | 2 +
37 files changed, 1365 insertions(+), 266 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml
delete mode 100644 Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt
create mode 100644 arch/arm/boot/dts/bcm2711-rpi-4-b.dts
create mode 100644 arch/arm/boot/dts/bcm2711.dtsi
create mode 100644 arch/arm/boot/dts/bcm2835-common.dtsi
create mode 100644 arch/arm64/boot/dts/broadcom/bcm2711-rpi-4-b.dts
--
2.7.4
^ permalink raw reply
* Re: [PATCH V6 14/21] clk: tegra210: Add suspend and resume support
From: Dmitry Osipenko @ 2019-07-22 6:10 UTC (permalink / raw)
To: Sowjanya Komatineni, thierry.reding, jonathanh, tglx, jason,
marc.zyngier, linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, linux-tegra, linux-kernel, mperttunen, spatra,
robh+dt, devicetree
In-Reply-To: <88da46d2-b90d-f57e-7611-b8653b56bdf6@nvidia.com>
22.07.2019 1:45, Sowjanya Komatineni пишет:
>
> On 7/21/19 2:38 PM, Dmitry Osipenko wrote:
>> 21.07.2019 22:40, Sowjanya Komatineni пишет:
>>> This patch adds support for clk: tegra210: suspend-resume.
>>>
>>> All the CAR controller settings are lost on suspend when core
>>> power goes off.
>>>
>>> This patch has implementation for saving and restoring all PLLs
>>> and clocks context during system suspend and resume to have the
>>> clocks back to same state for normal operation.
>>>
>>> Acked-by: Thierry Reding <treding@nvidia.com>
>>> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
>>> ---
>>> drivers/clk/tegra/clk-tegra210.c | 68
>>> ++++++++++++++++++++++++++++++++++++++--
>>> drivers/clk/tegra/clk.c | 14 +++++++++
>>> drivers/clk/tegra/clk.h | 1 +
>>> 3 files changed, 80 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/clk/tegra/clk-tegra210.c
>>> b/drivers/clk/tegra/clk-tegra210.c
>>> index 55a88c0824a5..68271873acc1 100644
>>> --- a/drivers/clk/tegra/clk-tegra210.c
>>> +++ b/drivers/clk/tegra/clk-tegra210.c
>>> @@ -9,6 +9,7 @@
>>> #include <linux/clkdev.h>
>>> #include <linux/of.h>
>>> #include <linux/of_address.h>
>>> +#include <linux/syscore_ops.h>
>>> #include <linux/delay.h>
>>> #include <linux/export.h>
>>> #include <linux/mutex.h>
>>> @@ -220,11 +221,15 @@
>>> #define CLK_M_DIVISOR_SHIFT 2
>>> #define CLK_M_DIVISOR_MASK 0x3
>>> +#define CLK_MASK_ARM 0x44
>>> +#define MISC_CLK_ENB 0x48
>>> +
>>> #define RST_DFLL_DVCO 0x2f4
>>> #define DVFS_DFLL_RESET_SHIFT 0
>>> #define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8
>>> #define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac
>>> +#define CPU_SOFTRST_CTRL 0x380
>>> #define LVL2_CLK_GATE_OVRA 0xf8
>>> #define LVL2_CLK_GATE_OVRC 0x3a0
>>> @@ -2825,6 +2830,7 @@ static int tegra210_enable_pllu(void)
>>> struct tegra_clk_pll_freq_table *fentry;
>>> struct tegra_clk_pll pllu;
>>> u32 reg;
>>> + int ret;
>>> for (fentry = pll_u_freq_table; fentry->input_rate; fentry++) {
>>> if (fentry->input_rate == pll_ref_freq)
>>> @@ -2853,9 +2859,8 @@ static int tegra210_enable_pllu(void)
>>> reg |= PLL_ENABLE;
>>> writel(reg, clk_base + PLLU_BASE);
>>> - readl_relaxed_poll_timeout_atomic(clk_base + PLLU_BASE, reg,
>>> - reg & PLL_BASE_LOCK, 2, 1000);
>>> - if (!(reg & PLL_BASE_LOCK)) {
>>> + ret = tegra210_wait_for_mask(&pllu, PLLU_BASE, PLL_BASE_LOCK);
>>> + if (ret) {
>> Why this is needed? Was there a bug?
>>
> during resume pllu init is needed and to use same terga210_init_pllu,
> poll_timeout_atomic can't be used as its ony for atomic context.
>
> So changed to use wait_for_mask which should work in both cases.
Atomic variant could be used from any context, not sure what do you
mean. The 'atomic' part only means that function won't cause scheduling
and that's it.
>>> pr_err("Timed out waiting for PLL_U to lock\n");
>>> return -ETIMEDOUT;
>>> }
>>> @@ -3288,6 +3293,56 @@ static void tegra210_disable_cpu_clock(u32 cpu)
>>> }
>>> #ifdef CONFIG_PM_SLEEP
>>> +#define car_readl(_base, _off) readl_relaxed(clk_base + (_base) +
>>> ((_off) * 4))
>>> +#define car_writel(_val, _base, _off) \
>>> + writel_relaxed(_val, clk_base + (_base) + ((_off) * 4))
>>> +
>>> +static u32 spare_reg_ctx, misc_clk_enb_ctx, clk_msk_arm_ctx;
>>> +static u32 cpu_softrst_ctx[3];
>>> +
>>> +static int tegra210_clk_suspend(void)
>>> +{
>>> + unsigned int i;
>>> +
>>> + clk_save_context();
>>> +
>>> + /*
>>> + * save the bootloader configured clock registers SPARE_REG0,
>>> + * MISC_CLK_ENB, CLK_MASK_ARM, CPU_SOFTRST_CTRL
>> Nit: Start all multi-line comments with a capital letter and put dot in
>> the end of sentence.
>>
>>> + */
>>> + spare_reg_ctx = readl_relaxed(clk_base + SPARE_REG0);
>>> + misc_clk_enb_ctx = readl_relaxed(clk_base + MISC_CLK_ENB);
>>> + clk_msk_arm_ctx = readl_relaxed(clk_base + CLK_MASK_ARM);
>>> +
>>> + for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++)
>>> + cpu_softrst_ctx[i] = car_readl(CPU_SOFTRST_CTRL, i);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static void tegra210_clk_resume(void)
>>> +{
>>> + unsigned int i;
>>> +
>>> + tegra_clk_osc_resume(clk_base);
>>> +
>>> + /*
>>> + * restore the bootloader configured clock registers SPARE_REG0,
>>> + * MISC_CLK_ENB, CLK_MASK_ARM, CPU_SOFTRST_CTRL from saved context.
>> Same here.
>>
>>> + */
>>> + writel_relaxed(spare_reg_ctx, clk_base + SPARE_REG0);
>>> + writel_relaxed(misc_clk_enb_ctx, clk_base + MISC_CLK_ENB);
>>> + writel_relaxed(clk_msk_arm_ctx, clk_base + CLK_MASK_ARM);
>>> +
>>> + for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++)
>>> + car_writel(cpu_softrst_ctx[i], CPU_SOFTRST_CTRL, i);
>>> +
>>> + fence_udelay(5, clk_base);
>>> +
>>> + tegra210_init_pllu();
>>> + clk_restore_context();
>>> +}
>>> +
>>> static void tegra210_cpu_clock_suspend(void)
>>> {
>>> /* switch coresite to clk_m, save off original source */
>>> @@ -3303,6 +3358,11 @@ static void tegra210_cpu_clock_resume(void)
>>> }
>>> #endif
>>> +static struct syscore_ops tegra_clk_syscore_ops = {
>>> + .suspend = tegra210_clk_suspend,
>>> + .resume = tegra210_clk_resume,
>>> +};
>>> +
>>> static struct tegra_cpu_car_ops tegra210_cpu_car_ops = {
>>> .wait_for_reset = tegra210_wait_cpu_in_reset,
>>> .disable_clock = tegra210_disable_cpu_clock,
>>> @@ -3587,5 +3647,7 @@ static void __init tegra210_clock_init(struct
>>> device_node *np)
>>> tegra210_mbist_clk_init();
>>> tegra_cpu_car_ops = &tegra210_cpu_car_ops;
>>> +
>>> + register_syscore_ops(&tegra_clk_syscore_ops);
>>> }
>>> CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init);
>>> diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
>>> index 573e3c967ae1..eb08047fd02f 100644
>>> --- a/drivers/clk/tegra/clk.c
>>> +++ b/drivers/clk/tegra/clk.c
>>> @@ -23,6 +23,7 @@
>>> #define CLK_OUT_ENB_W 0x364
>>> #define CLK_OUT_ENB_X 0x280
>>> #define CLK_OUT_ENB_Y 0x298
>>> +#define CLK_ENB_PLLP_OUT_CPU BIT(31)
>>> #define CLK_OUT_ENB_SET_L 0x320
>>> #define CLK_OUT_ENB_CLR_L 0x324
>>> #define CLK_OUT_ENB_SET_H 0x328
>>> @@ -199,6 +200,19 @@ const struct tegra_clk_periph_regs
>>> *get_reg_bank(int clkid)
>>> }
>>> }
>>> +void tegra_clk_set_pllp_out_cpu(bool enable)
>>> +{
>>> + u32 val;
>>> +
>>> + val = readl_relaxed(clk_base + CLK_OUT_ENB_Y);
>>> + if (enable)
>>> + val |= CLK_ENB_PLLP_OUT_CPU;
>>> + else
>>> + val &= ~CLK_ENB_PLLP_OUT_CPU;
>>> +
>>> + writel_relaxed(val, clk_base + CLK_OUT_ENB_Y);
>>> +}
>>> +
>>> struct clk ** __init tegra_clk_init(void __iomem *regs, int num,
>>> int banks)
>>> {
>>> clk_base = regs;
>>> diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
>>> index 562a3ee2d537..0ffa763c755b 100644
>>> --- a/drivers/clk/tegra/clk.h
>>> +++ b/drivers/clk/tegra/clk.h
>>> @@ -863,6 +863,7 @@ int div_frac_get(unsigned long rate, unsigned
>>> parent_rate, u8 width,
>>> u8 frac_width, u8 flags);
>>> void tegra_clk_sync_state_pll(struct clk_hw *hw);
>>> void tegra_clk_osc_resume(void __iomem *clk_base);
>>> +void tegra_clk_set_pllp_out_cpu(bool enable);
>>> /* Combined read fence with delay */
>>> #define fence_udelay(delay, reg) \
>>>
^ permalink raw reply
* Re: [PATCH] gpio: don't WARN() on NULL descs if gpiolib is disabled
From: Bartosz Golaszewski @ 2019-07-22 6:14 UTC (permalink / raw)
To: Linus Walleij
Cc: Bartosz Golaszewski, open list:GPIO SUBSYSTEM,
linux-kernel@vger.kernel.org, Claus H . Stovgaard
In-Reply-To: <CACRpkdYkp0OnyEiUX_VQF_nu5JumkupdsX9fG4rWCf0apNtX5A@mail.gmail.com>
sob., 20 lip 2019 o 21:45 Linus Walleij <linus.walleij@linaro.org> napisał(a):
>
> On Sat, Jul 20, 2019 at 8:03 PM Bartosz Golaszewski
> <bgolaszewski@baylibre.com> wrote:
>
> > I'll apply it to my local tree and send it for v5.3-rc2.
>
> OK! Do you see it as bug fix so it should go in the rcs?
>
> It pretty much needs to be a regression to go in there,
> because this stub stuff blew up in my face before :/
>
> Thanks,
> Linus
It causes a warning every time someone writes to an at24 EEPROM
without GPIOLIB selected. To me it sounds like a bug that should go
into stable. Let me know if I'm wrong in thinking that, then I'll send
it for v5.4.
Bart
^ permalink raw reply
* [PATCH 11/18] dt-bindings: pinctrl: bcm2835: Add brcm,bcm2711 compatible
From: Stefan Wahren @ 2019-07-22 6:23 UTC (permalink / raw)
To: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
Nicolas Saenz Julienne, Matthias Brugger, Rob Herring,
Mark Rutland, Linus Walleij, Michael Turquette, Stephen Boyd,
Ulf Hansson, Adrian Hunter
Cc: bcm-kernel-feedback-list, linux-arm-kernel, linux-rpi-kernel,
linux-gpio, linux-mmc, Stefan Wahren
In-Reply-To: <1563776607-8368-1-git-send-email-wahrenst@gmx.net>
Add a new compatible for the BCM2711.
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
---
Documentation/devicetree/bindings/pinctrl/brcm,bcm2835-gpio.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm2835-gpio.txt b/Documentation/devicetree/bindings/pinctrl/brcm,bcm2835-gpio.txt
index ac6d614..3cab733 100644
--- a/Documentation/devicetree/bindings/pinctrl/brcm,bcm2835-gpio.txt
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm2835-gpio.txt
@@ -8,6 +8,7 @@ Required properties:
- compatible: should be one of:
"brcm,bcm2835-gpio" - BCM2835 compatible pinctrl
"brcm,bcm7211-gpio" - BCM7211 compatible pinctrl
+ "brcm,bcm2711-gpio" - BCM2711 compatible pinctrl
- reg: Should contain the physical address of the GPIO module's registers.
- gpio-controller: Marks the device node as a GPIO controller.
- #gpio-cells : Should be two. The first cell is the pin number and the
--
2.7.4
^ permalink raw reply related
* [PATCH 10/18] mmc: sdhci-iproc: Add support for emmc2 of the BCM2711
From: Stefan Wahren @ 2019-07-22 6:23 UTC (permalink / raw)
To: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
Nicolas Saenz Julienne, Matthias Brugger, Rob Herring,
Mark Rutland, Linus Walleij, Michael Turquette, Stephen Boyd,
Ulf Hansson, Adrian Hunter
Cc: bcm-kernel-feedback-list, linux-arm-kernel, linux-rpi-kernel,
linux-gpio, linux-mmc, Stefan Wahren
The additional emmc2 interface of the BCM2711 is an improved version
of the old emmc controller, which is able to provide DDR50 mode on the
Raspberry Pi 4. Except 32 bit only register access no other quirks are
known yet.
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
---
drivers/mmc/host/sdhci-iproc.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
index 2feb4ef..2b9cdcd 100644
--- a/drivers/mmc/host/sdhci-iproc.c
+++ b/drivers/mmc/host/sdhci-iproc.c
@@ -261,8 +261,17 @@ static const struct sdhci_iproc_data bcm2835_data = {
.mmc_caps = 0x00000000,
};
+static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = {
+ .ops = &sdhci_iproc_32only_ops,
+};
+
+static const struct sdhci_iproc_data bcm2711_data = {
+ .pdata = &sdhci_bcm2711_pltfm_data,
+};
+
static const struct of_device_id sdhci_iproc_of_match[] = {
{ .compatible = "brcm,bcm2835-sdhci", .data = &bcm2835_data },
+ { .compatible = "brcm,bcm2711-emmc2", .data = &bcm2711_data },
{ .compatible = "brcm,sdhci-iproc-cygnus", .data = &iproc_cygnus_data},
{ .compatible = "brcm,sdhci-iproc", .data = &iproc_data },
{ }
--
2.7.4
^ permalink raw reply related
* [PATCH 12/18] pinctrl: bcm2835: Add support for BCM2711 pull-up functionality
From: Stefan Wahren @ 2019-07-22 6:23 UTC (permalink / raw)
To: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
Nicolas Saenz Julienne, Matthias Brugger, Rob Herring,
Mark Rutland, Linus Walleij, Michael Turquette, Stephen Boyd,
Ulf Hansson, Adrian Hunter
Cc: bcm-kernel-feedback-list, linux-arm-kernel, linux-rpi-kernel,
linux-gpio, linux-mmc, Stefan Wahren
In-Reply-To: <1563776607-8368-1-git-send-email-wahrenst@gmx.net>
The BCM2711 has a new way of selecting the pull-up/pull-down setting
for a GPIO pin. The registers used for the BCM2835, GP_PUD and
GP_PUDCLKn0, are no longer connected. A new set of registers,
GP_GPIO_PUP_PDN_CNTRL_REGx must be used. This commit will add
a new compatible string "brcm,bcm2711-gpio" and the kernel
driver will use it to select which method is used to select
pull-up/pull-down.
This patch based on a patch by Al Cooper which was intended for the
BCM7211. This is a bugfixed and improved version.
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
---
drivers/pinctrl/bcm/pinctrl-bcm2835.c | 105 ++++++++++++++++++++++++++++++++--
1 file changed, 100 insertions(+), 5 deletions(-)
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index 183d1ff..a493205 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -57,15 +57,24 @@
#define GPAFEN0 0x88 /* Pin Async Falling Edge Detect */
#define GPPUD 0x94 /* Pin Pull-up/down Enable */
#define GPPUDCLK0 0x98 /* Pin Pull-up/down Enable Clock */
+#define GP_GPIO_PUP_PDN_CNTRL_REG0 0xe4 /* 2711 Pin Pull-up/down select */
#define FSEL_REG(p) (GPFSEL0 + (((p) / 10) * 4))
#define FSEL_SHIFT(p) (((p) % 10) * 3)
#define GPIO_REG_OFFSET(p) ((p) / 32)
#define GPIO_REG_SHIFT(p) ((p) % 32)
+#define PUD_2711_MASK 0x3
+#define PUD_2711_REG_OFFSET(p) ((p) / 16)
+#define PUD_2711_REG_SHIFT(p) (((p) % 16) * 2)
+
/* argument: bcm2835_pinconf_pull */
#define BCM2835_PINCONF_PARAM_PULL (PIN_CONFIG_END + 1)
+#define BCM2711_PULL_NONE 0x0
+#define BCM2711_PULL_UP 0x1
+#define BCM2711_PULL_DOWN 0x2
+
struct bcm2835_pinctrl {
struct device *dev;
void __iomem *base;
@@ -975,6 +984,77 @@ static const struct pinconf_ops bcm2835_pinconf_ops = {
.pin_config_set = bcm2835_pinconf_set,
};
+static void bcm2711_pull_config_set(struct bcm2835_pinctrl *pc,
+ unsigned int pin, unsigned int arg)
+{
+ u32 shifter;
+ u32 value;
+ u32 off;
+
+ off = PUD_2711_REG_OFFSET(pin);
+ shifter = PUD_2711_REG_SHIFT(pin);
+
+ value = bcm2835_gpio_rd(pc, GP_GPIO_PUP_PDN_CNTRL_REG0 + (off * 4));
+ value &= ~(PUD_2711_MASK << shifter);
+ value |= (arg << shifter);
+ bcm2835_gpio_wr(pc, GP_GPIO_PUP_PDN_CNTRL_REG0 + (off * 4), value);
+}
+
+static int bcm2711_pinconf_set(struct pinctrl_dev *pctldev,
+ unsigned int pin, unsigned long *configs,
+ unsigned int num_configs)
+{
+ struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+ u32 param, arg;
+ int i;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ /* convert legacy brcm,pull */
+ case BCM2835_PINCONF_PARAM_PULL:
+ if (arg == BCM2835_PUD_UP)
+ arg = BCM2711_PULL_UP;
+ else if (arg == BCM2835_PUD_DOWN)
+ arg = BCM2711_PULL_DOWN;
+ else
+ arg = BCM2711_PULL_NONE;
+
+ bcm2711_pull_config_set(pc, pin, arg);
+ break;
+
+ /* Set pull generic bindings */
+ case PIN_CONFIG_BIAS_DISABLE:
+ bcm2711_pull_config_set(pc, pin, BCM2711_PULL_NONE);
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ bcm2711_pull_config_set(pc, pin, BCM2711_PULL_DOWN);
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ bcm2711_pull_config_set(pc, pin, BCM2711_PULL_UP);
+ break;
+
+ /* Set output-high or output-low */
+ case PIN_CONFIG_OUTPUT:
+ bcm2835_gpio_set_bit(pc, arg ? GPSET0 : GPCLR0, pin);
+ break;
+
+ default:
+ return -ENOTSUPP;
+ }
+ } /* for each config */
+
+ return 0;
+}
+
+static const struct pinconf_ops bcm2711_pinconf_ops = {
+ .is_generic = true,
+ .pin_config_get = bcm2835_pinconf_get,
+ .pin_config_set = bcm2711_pinconf_set,
+};
+
static struct pinctrl_desc bcm2835_pinctrl_desc = {
.name = MODULE_NAME,
.pins = bcm2835_gpio_pins,
@@ -990,6 +1070,18 @@ static struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = {
.npins = BCM2835_NUM_GPIOS,
};
+static const struct of_device_id bcm2835_pinctrl_match[] = {
+ {
+ .compatible = "brcm,bcm2835-gpio",
+ .data = &bcm2835_pinconf_ops,
+ },
+ {
+ .compatible = "brcm,bcm2711-gpio",
+ .data = &bcm2711_pinconf_ops,
+ },
+ {}
+};
+
static int bcm2835_pinctrl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -997,6 +1089,8 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
struct bcm2835_pinctrl *pc;
struct resource iomem;
int err, i;
+ const struct of_device_id *match;
+
BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2835_NUM_GPIOS);
BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2835_NUM_GPIOS);
@@ -1073,6 +1167,12 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
bcm2835_gpio_irq_handler);
}
+ match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node);
+ if (match) {
+ bcm2835_pinctrl_desc.confops =
+ (const struct pinconf_ops *)match->data;
+ }
+
pc->pctl_dev = devm_pinctrl_register(dev, &bcm2835_pinctrl_desc, pc);
if (IS_ERR(pc->pctl_dev)) {
gpiochip_remove(&pc->gpio_chip);
@@ -1087,11 +1187,6 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
return 0;
}
-static const struct of_device_id bcm2835_pinctrl_match[] = {
- { .compatible = "brcm,bcm2835-gpio" },
- {}
-};
-
static struct platform_driver bcm2835_pinctrl_driver = {
.probe = bcm2835_pinctrl_probe,
.driver = {
--
2.7.4
^ permalink raw reply related
* Re: [PATCH V6 09/21] clk: tegra: clk-super: Fix to enable PLLP branches to CPU
From: Dmitry Osipenko @ 2019-07-22 6:32 UTC (permalink / raw)
To: Sowjanya Komatineni, thierry.reding, jonathanh, tglx, jason,
marc.zyngier, linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, linux-tegra, linux-kernel, mperttunen, spatra,
robh+dt, devicetree
In-Reply-To: <7933a83c-3208-b551-d41d-70285ae528e3@nvidia.com>
22.07.2019 6:17, Sowjanya Komatineni пишет:
>
> On 7/21/19 3:39 PM, Sowjanya Komatineni wrote:
>>
>> On 7/21/19 2:16 PM, Dmitry Osipenko wrote:
>>> 21.07.2019 22:40, Sowjanya Komatineni пишет:
>>>> This patch has a fix to enable PLLP branches to CPU before changing
>>>> the CPU clusters clock source to PLLP for Gen5 Super clock.
>>>>
>>>> During system suspend entry and exit, CPU source will be switched
>>>> to PLLP and this needs PLLP branches to be enabled to CPU prior to
>>>> the switch.
>>>>
>>>> On system resume, warmboot code enables PLLP branches to CPU and
>>>> powers up the CPU with PLLP clock source.
>>>>
>>>> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
>>>> ---
>>>> drivers/clk/tegra/clk-super.c | 11 +++++++++++
>>>> drivers/clk/tegra/clk-tegra-super-gen4.c | 4 ++--
>>>> drivers/clk/tegra/clk.h | 4 ++++
>>>> 3 files changed, 17 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/clk/tegra/clk-super.c
>>>> b/drivers/clk/tegra/clk-super.c
>>>> index 39ef31b46df5..d73c587e4853 100644
>>>> --- a/drivers/clk/tegra/clk-super.c
>>>> +++ b/drivers/clk/tegra/clk-super.c
>>>> @@ -28,6 +28,9 @@
>>>> #define super_state_to_src_shift(m, s) ((m->width * s))
>>>> #define super_state_to_src_mask(m) (((1 << m->width) - 1))
>>>> +#define CCLK_SRC_PLLP_OUT0 4
>>>> +#define CCLK_SRC_PLLP_OUT4 5
>>>> +
>>>> static u8 clk_super_get_parent(struct clk_hw *hw)
>>>> {
>>>> struct tegra_clk_super_mux *mux = to_clk_super_mux(hw);
>>>> @@ -97,6 +100,14 @@ static int clk_super_set_parent(struct clk_hw
>>>> *hw, u8 index)
>>>> if (index == mux->div2_index)
>>>> index = mux->pllx_index;
>>>> }
>>>> +
>>>> + /*
>>>> + * Enable PLLP branches to CPU before selecting PLLP source
>>>> + */
>>>> + if ((mux->flags & TEGRA_CPU_CLK) &&
>>>> + ((index == CCLK_SRC_PLLP_OUT0) || (index ==
>>>> CCLK_SRC_PLLP_OUT4)))
>>>> + tegra_clk_set_pllp_out_cpu(true);
>>> Should somewhere here be tegra_clk_set_pllp_out_cpu(false) when
>>> switching from PLLP?
>> PLLP may be used for other CPU clusters.
>
> Though to avoid flag and check needed to make sure other CPU is not
> using before disabling PLLP branch to CPU.
>
> But leaving it enabled shouldn't impact much as clock source mux is
> after this in design anyway.
>
> But can add as well if its clear that way.
The TRM doc says "The CPU subsystem supports a switch-cluster mode
meaning that only one of the clusters can be active at any given time".
Given that cluster-switching isn't supported in upstream, I don't think
that you need to care about the other cluster at all, at least for now.
The cluster-switching implementation in upstream is very complicated
because it requires a special "hotplugging" CPU governor, which
apparently no other platform needs.
[snip]
^ permalink raw reply
* Re: [PATCH V6 14/21] clk: tegra210: Add suspend and resume support
From: Sowjanya Komatineni @ 2019-07-22 6:52 UTC (permalink / raw)
To: Dmitry Osipenko, thierry.reding, jonathanh, tglx, jason,
marc.zyngier, linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, linux-tegra, linux-kernel, mperttunen, spatra,
robh+dt, devicetree
In-Reply-To: <ceedb802-7561-488f-3a89-67bee19f2fea@gmail.com>
On 7/21/19 11:10 PM, Dmitry Osipenko wrote:
> 22.07.2019 1:45, Sowjanya Komatineni пишет:
>> On 7/21/19 2:38 PM, Dmitry Osipenko wrote:
>>> 21.07.2019 22:40, Sowjanya Komatineni пишет:
>>>> This patch adds support for clk: tegra210: suspend-resume.
>>>>
>>>> All the CAR controller settings are lost on suspend when core
>>>> power goes off.
>>>>
>>>> This patch has implementation for saving and restoring all PLLs
>>>> and clocks context during system suspend and resume to have the
>>>> clocks back to same state for normal operation.
>>>>
>>>> Acked-by: Thierry Reding <treding@nvidia.com>
>>>> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
>>>> ---
>>>> drivers/clk/tegra/clk-tegra210.c | 68
>>>> ++++++++++++++++++++++++++++++++++++++--
>>>> drivers/clk/tegra/clk.c | 14 +++++++++
>>>> drivers/clk/tegra/clk.h | 1 +
>>>> 3 files changed, 80 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/drivers/clk/tegra/clk-tegra210.c
>>>> b/drivers/clk/tegra/clk-tegra210.c
>>>> index 55a88c0824a5..68271873acc1 100644
>>>> --- a/drivers/clk/tegra/clk-tegra210.c
>>>> +++ b/drivers/clk/tegra/clk-tegra210.c
>>>> @@ -9,6 +9,7 @@
>>>> #include <linux/clkdev.h>
>>>> #include <linux/of.h>
>>>> #include <linux/of_address.h>
>>>> +#include <linux/syscore_ops.h>
>>>> #include <linux/delay.h>
>>>> #include <linux/export.h>
>>>> #include <linux/mutex.h>
>>>> @@ -220,11 +221,15 @@
>>>> #define CLK_M_DIVISOR_SHIFT 2
>>>> #define CLK_M_DIVISOR_MASK 0x3
>>>> +#define CLK_MASK_ARM 0x44
>>>> +#define MISC_CLK_ENB 0x48
>>>> +
>>>> #define RST_DFLL_DVCO 0x2f4
>>>> #define DVFS_DFLL_RESET_SHIFT 0
>>>> #define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8
>>>> #define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac
>>>> +#define CPU_SOFTRST_CTRL 0x380
>>>> #define LVL2_CLK_GATE_OVRA 0xf8
>>>> #define LVL2_CLK_GATE_OVRC 0x3a0
>>>> @@ -2825,6 +2830,7 @@ static int tegra210_enable_pllu(void)
>>>> struct tegra_clk_pll_freq_table *fentry;
>>>> struct tegra_clk_pll pllu;
>>>> u32 reg;
>>>> + int ret;
>>>> for (fentry = pll_u_freq_table; fentry->input_rate; fentry++) {
>>>> if (fentry->input_rate == pll_ref_freq)
>>>> @@ -2853,9 +2859,8 @@ static int tegra210_enable_pllu(void)
>>>> reg |= PLL_ENABLE;
>>>> writel(reg, clk_base + PLLU_BASE);
>>>> - readl_relaxed_poll_timeout_atomic(clk_base + PLLU_BASE, reg,
>>>> - reg & PLL_BASE_LOCK, 2, 1000);
>>>> - if (!(reg & PLL_BASE_LOCK)) {
>>>> + ret = tegra210_wait_for_mask(&pllu, PLLU_BASE, PLL_BASE_LOCK);
>>>> + if (ret) {
>>> Why this is needed? Was there a bug?
>>>
>> during resume pllu init is needed and to use same terga210_init_pllu,
>> poll_timeout_atomic can't be used as its ony for atomic context.
>>
>> So changed to use wait_for_mask which should work in both cases.
> Atomic variant could be used from any context, not sure what do you
> mean. The 'atomic' part only means that function won't cause scheduling
> and that's it.
Sorry, replied incorrect. readx_poll_timeout_atomic uses ktime_get() and
during resume timekeeping suspend/resume happens later than clock
suspend/resume. So using tegra210_wait_for_mask.
both timekeeping and clk-tegra210 drivers are registered as syscore but
not ordered.
>>>> pr_err("Timed out waiting for PLL_U to lock\n");
>>>> return -ETIMEDOUT;
>>>> }
>>>> @@ -3288,6 +3293,56 @@ static void tegra210_disable_cpu_clock(u32 cpu)
>>>> }
>>>> #ifdef CONFIG_PM_SLEEP
>>>> +#define car_readl(_base, _off) readl_relaxed(clk_base + (_base) +
>>>> ((_off) * 4))
>>>> +#define car_writel(_val, _base, _off) \
>>>> + writel_relaxed(_val, clk_base + (_base) + ((_off) * 4))
>>>> +
>>>> +static u32 spare_reg_ctx, misc_clk_enb_ctx, clk_msk_arm_ctx;
>>>> +static u32 cpu_softrst_ctx[3];
>>>> +
>>>> +static int tegra210_clk_suspend(void)
>>>> +{
>>>> + unsigned int i;
>>>> +
>>>> + clk_save_context();
>>>> +
>>>> + /*
>>>> + * save the bootloader configured clock registers SPARE_REG0,
>>>> + * MISC_CLK_ENB, CLK_MASK_ARM, CPU_SOFTRST_CTRL
>>> Nit: Start all multi-line comments with a capital letter and put dot in
>>> the end of sentence.
>>>
>>>> + */
>>>> + spare_reg_ctx = readl_relaxed(clk_base + SPARE_REG0);
>>>> + misc_clk_enb_ctx = readl_relaxed(clk_base + MISC_CLK_ENB);
>>>> + clk_msk_arm_ctx = readl_relaxed(clk_base + CLK_MASK_ARM);
>>>> +
>>>> + for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++)
>>>> + cpu_softrst_ctx[i] = car_readl(CPU_SOFTRST_CTRL, i);
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static void tegra210_clk_resume(void)
>>>> +{
>>>> + unsigned int i;
>>>> +
>>>> + tegra_clk_osc_resume(clk_base);
>>>> +
>>>> + /*
>>>> + * restore the bootloader configured clock registers SPARE_REG0,
>>>> + * MISC_CLK_ENB, CLK_MASK_ARM, CPU_SOFTRST_CTRL from saved context.
>>> Same here.
>>>
>>>> + */
>>>> + writel_relaxed(spare_reg_ctx, clk_base + SPARE_REG0);
>>>> + writel_relaxed(misc_clk_enb_ctx, clk_base + MISC_CLK_ENB);
>>>> + writel_relaxed(clk_msk_arm_ctx, clk_base + CLK_MASK_ARM);
>>>> +
>>>> + for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++)
>>>> + car_writel(cpu_softrst_ctx[i], CPU_SOFTRST_CTRL, i);
>>>> +
>>>> + fence_udelay(5, clk_base);
>>>> +
>>>> + tegra210_init_pllu();
>>>> + clk_restore_context();
>>>> +}
>>>> +
>>>> static void tegra210_cpu_clock_suspend(void)
>>>> {
>>>> /* switch coresite to clk_m, save off original source */
>>>> @@ -3303,6 +3358,11 @@ static void tegra210_cpu_clock_resume(void)
>>>> }
>>>> #endif
>>>> +static struct syscore_ops tegra_clk_syscore_ops = {
>>>> + .suspend = tegra210_clk_suspend,
>>>> + .resume = tegra210_clk_resume,
>>>> +};
>>>> +
>>>> static struct tegra_cpu_car_ops tegra210_cpu_car_ops = {
>>>> .wait_for_reset = tegra210_wait_cpu_in_reset,
>>>> .disable_clock = tegra210_disable_cpu_clock,
>>>> @@ -3587,5 +3647,7 @@ static void __init tegra210_clock_init(struct
>>>> device_node *np)
>>>> tegra210_mbist_clk_init();
>>>> tegra_cpu_car_ops = &tegra210_cpu_car_ops;
>>>> +
>>>> + register_syscore_ops(&tegra_clk_syscore_ops);
>>>> }
>>>> CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init);
>>>> diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
>>>> index 573e3c967ae1..eb08047fd02f 100644
>>>> --- a/drivers/clk/tegra/clk.c
>>>> +++ b/drivers/clk/tegra/clk.c
>>>> @@ -23,6 +23,7 @@
>>>> #define CLK_OUT_ENB_W 0x364
>>>> #define CLK_OUT_ENB_X 0x280
>>>> #define CLK_OUT_ENB_Y 0x298
>>>> +#define CLK_ENB_PLLP_OUT_CPU BIT(31)
>>>> #define CLK_OUT_ENB_SET_L 0x320
>>>> #define CLK_OUT_ENB_CLR_L 0x324
>>>> #define CLK_OUT_ENB_SET_H 0x328
>>>> @@ -199,6 +200,19 @@ const struct tegra_clk_periph_regs
>>>> *get_reg_bank(int clkid)
>>>> }
>>>> }
>>>> +void tegra_clk_set_pllp_out_cpu(bool enable)
>>>> +{
>>>> + u32 val;
>>>> +
>>>> + val = readl_relaxed(clk_base + CLK_OUT_ENB_Y);
>>>> + if (enable)
>>>> + val |= CLK_ENB_PLLP_OUT_CPU;
>>>> + else
>>>> + val &= ~CLK_ENB_PLLP_OUT_CPU;
>>>> +
>>>> + writel_relaxed(val, clk_base + CLK_OUT_ENB_Y);
>>>> +}
>>>> +
>>>> struct clk ** __init tegra_clk_init(void __iomem *regs, int num,
>>>> int banks)
>>>> {
>>>> clk_base = regs;
>>>> diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
>>>> index 562a3ee2d537..0ffa763c755b 100644
>>>> --- a/drivers/clk/tegra/clk.h
>>>> +++ b/drivers/clk/tegra/clk.h
>>>> @@ -863,6 +863,7 @@ int div_frac_get(unsigned long rate, unsigned
>>>> parent_rate, u8 width,
>>>> u8 frac_width, u8 flags);
>>>> void tegra_clk_sync_state_pll(struct clk_hw *hw);
>>>> void tegra_clk_osc_resume(void __iomem *clk_base);
>>>> +void tegra_clk_set_pllp_out_cpu(bool enable);
>>>> /* Combined read fence with delay */
>>>> #define fence_udelay(delay, reg) \
>>>>
^ permalink raw reply
* Re: [PATCH V6 14/21] clk: tegra210: Add suspend and resume support
From: Dmitry Osipenko @ 2019-07-22 7:09 UTC (permalink / raw)
To: Sowjanya Komatineni, thierry.reding, jonathanh, tglx, jason,
marc.zyngier, linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, linux-tegra, linux-kernel, mperttunen, spatra,
robh+dt, devicetree
In-Reply-To: <e2d0e8cc-b4ea-1148-4af1-fee6bb266cca@nvidia.com>
22.07.2019 9:52, Sowjanya Komatineni пишет:
>
> On 7/21/19 11:10 PM, Dmitry Osipenko wrote:
>> 22.07.2019 1:45, Sowjanya Komatineni пишет:
>>> On 7/21/19 2:38 PM, Dmitry Osipenko wrote:
>>>> 21.07.2019 22:40, Sowjanya Komatineni пишет:
>>>>> This patch adds support for clk: tegra210: suspend-resume.
>>>>>
>>>>> All the CAR controller settings are lost on suspend when core
>>>>> power goes off.
>>>>>
>>>>> This patch has implementation for saving and restoring all PLLs
>>>>> and clocks context during system suspend and resume to have the
>>>>> clocks back to same state for normal operation.
>>>>>
>>>>> Acked-by: Thierry Reding <treding@nvidia.com>
>>>>> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
>>>>> ---
>>>>> drivers/clk/tegra/clk-tegra210.c | 68
>>>>> ++++++++++++++++++++++++++++++++++++++--
>>>>> drivers/clk/tegra/clk.c | 14 +++++++++
>>>>> drivers/clk/tegra/clk.h | 1 +
>>>>> 3 files changed, 80 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/drivers/clk/tegra/clk-tegra210.c
>>>>> b/drivers/clk/tegra/clk-tegra210.c
>>>>> index 55a88c0824a5..68271873acc1 100644
>>>>> --- a/drivers/clk/tegra/clk-tegra210.c
>>>>> +++ b/drivers/clk/tegra/clk-tegra210.c
>>>>> @@ -9,6 +9,7 @@
>>>>> #include <linux/clkdev.h>
>>>>> #include <linux/of.h>
>>>>> #include <linux/of_address.h>
>>>>> +#include <linux/syscore_ops.h>
>>>>> #include <linux/delay.h>
>>>>> #include <linux/export.h>
>>>>> #include <linux/mutex.h>
>>>>> @@ -220,11 +221,15 @@
>>>>> #define CLK_M_DIVISOR_SHIFT 2
>>>>> #define CLK_M_DIVISOR_MASK 0x3
>>>>> +#define CLK_MASK_ARM 0x44
>>>>> +#define MISC_CLK_ENB 0x48
>>>>> +
>>>>> #define RST_DFLL_DVCO 0x2f4
>>>>> #define DVFS_DFLL_RESET_SHIFT 0
>>>>> #define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8
>>>>> #define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac
>>>>> +#define CPU_SOFTRST_CTRL 0x380
>>>>> #define LVL2_CLK_GATE_OVRA 0xf8
>>>>> #define LVL2_CLK_GATE_OVRC 0x3a0
>>>>> @@ -2825,6 +2830,7 @@ static int tegra210_enable_pllu(void)
>>>>> struct tegra_clk_pll_freq_table *fentry;
>>>>> struct tegra_clk_pll pllu;
>>>>> u32 reg;
>>>>> + int ret;
>>>>> for (fentry = pll_u_freq_table; fentry->input_rate;
>>>>> fentry++) {
>>>>> if (fentry->input_rate == pll_ref_freq)
>>>>> @@ -2853,9 +2859,8 @@ static int tegra210_enable_pllu(void)
>>>>> reg |= PLL_ENABLE;
>>>>> writel(reg, clk_base + PLLU_BASE);
>>>>> - readl_relaxed_poll_timeout_atomic(clk_base + PLLU_BASE, reg,
>>>>> - reg & PLL_BASE_LOCK, 2, 1000);
>>>>> - if (!(reg & PLL_BASE_LOCK)) {
>>>>> + ret = tegra210_wait_for_mask(&pllu, PLLU_BASE, PLL_BASE_LOCK);
>>>>> + if (ret) {
>>>> Why this is needed? Was there a bug?
>>>>
>>> during resume pllu init is needed and to use same terga210_init_pllu,
>>> poll_timeout_atomic can't be used as its ony for atomic context.
>>>
>>> So changed to use wait_for_mask which should work in both cases.
>> Atomic variant could be used from any context, not sure what do you
>> mean. The 'atomic' part only means that function won't cause scheduling
>> and that's it.
>
> Sorry, replied incorrect. readx_poll_timeout_atomic uses ktime_get() and
> during resume timekeeping suspend/resume happens later than clock
> suspend/resume. So using tegra210_wait_for_mask.
>
> both timekeeping and clk-tegra210 drivers are registered as syscore but
> not ordered.
Okay, thank you for the clarification.
[snip]
^ permalink raw reply
* Re: [PATCH V6 09/21] clk: tegra: clk-super: Fix to enable PLLP branches to CPU
From: Sowjanya Komatineni @ 2019-07-22 7:12 UTC (permalink / raw)
To: Dmitry Osipenko, thierry.reding, jonathanh, tglx, jason,
marc.zyngier, linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, linux-tegra, linux-kernel, mperttunen, spatra,
robh+dt, devicetree
In-Reply-To: <f6ac50af-c3a5-1fef-2e0d-a9ecadeb2495@gmail.com>
On 7/21/19 11:32 PM, Dmitry Osipenko wrote:
> 22.07.2019 6:17, Sowjanya Komatineni пишет:
>> On 7/21/19 3:39 PM, Sowjanya Komatineni wrote:
>>> On 7/21/19 2:16 PM, Dmitry Osipenko wrote:
>>>> 21.07.2019 22:40, Sowjanya Komatineni пишет:
>>>>> This patch has a fix to enable PLLP branches to CPU before changing
>>>>> the CPU clusters clock source to PLLP for Gen5 Super clock.
>>>>>
>>>>> During system suspend entry and exit, CPU source will be switched
>>>>> to PLLP and this needs PLLP branches to be enabled to CPU prior to
>>>>> the switch.
>>>>>
>>>>> On system resume, warmboot code enables PLLP branches to CPU and
>>>>> powers up the CPU with PLLP clock source.
>>>>>
>>>>> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
>>>>> ---
>>>>> drivers/clk/tegra/clk-super.c | 11 +++++++++++
>>>>> drivers/clk/tegra/clk-tegra-super-gen4.c | 4 ++--
>>>>> drivers/clk/tegra/clk.h | 4 ++++
>>>>> 3 files changed, 17 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/drivers/clk/tegra/clk-super.c
>>>>> b/drivers/clk/tegra/clk-super.c
>>>>> index 39ef31b46df5..d73c587e4853 100644
>>>>> --- a/drivers/clk/tegra/clk-super.c
>>>>> +++ b/drivers/clk/tegra/clk-super.c
>>>>> @@ -28,6 +28,9 @@
>>>>> #define super_state_to_src_shift(m, s) ((m->width * s))
>>>>> #define super_state_to_src_mask(m) (((1 << m->width) - 1))
>>>>> +#define CCLK_SRC_PLLP_OUT0 4
>>>>> +#define CCLK_SRC_PLLP_OUT4 5
>>>>> +
>>>>> static u8 clk_super_get_parent(struct clk_hw *hw)
>>>>> {
>>>>> struct tegra_clk_super_mux *mux = to_clk_super_mux(hw);
>>>>> @@ -97,6 +100,14 @@ static int clk_super_set_parent(struct clk_hw
>>>>> *hw, u8 index)
>>>>> if (index == mux->div2_index)
>>>>> index = mux->pllx_index;
>>>>> }
>>>>> +
>>>>> + /*
>>>>> + * Enable PLLP branches to CPU before selecting PLLP source
>>>>> + */
>>>>> + if ((mux->flags & TEGRA_CPU_CLK) &&
>>>>> + ((index == CCLK_SRC_PLLP_OUT0) || (index ==
>>>>> CCLK_SRC_PLLP_OUT4)))
>>>>> + tegra_clk_set_pllp_out_cpu(true);
>>>> Should somewhere here be tegra_clk_set_pllp_out_cpu(false) when
>>>> switching from PLLP?
>>> PLLP may be used for other CPU clusters.
>> Though to avoid flag and check needed to make sure other CPU is not
>> using before disabling PLLP branch to CPU.
>>
>> But leaving it enabled shouldn't impact much as clock source mux is
>> after this in design anyway.
>>
>> But can add as well if its clear that way.
> The TRM doc says "The CPU subsystem supports a switch-cluster mode
> meaning that only one of the clusters can be active at any given time".
>
> Given that cluster-switching isn't supported in upstream, I don't think
> that you need to care about the other cluster at all, at least for now.
>
> The cluster-switching implementation in upstream is very complicated
> because it requires a special "hotplugging" CPU governor, which
> apparently no other platform needs.
>
> [snip]
This patch enables PLLP branches to CPU for both CPUG & CPULP if they
use PLLP source.
So, to disable PLLP out CPU when not in use, we still need check for
other cluster because during resume both LP CPU and G CPU gets restored.
CPUG runs from PLLP on resume and when it does super clk restore for LP
CPU which may not be using PLLP, but as both uses same super mux
clk_ops, without check (for PLLP branch to CPU in use) disabling PLLP
branch to CPU during LP CPU restore looses clock to CPU G as well which
is running from PLLP.
Will add check and disable PLLP if not in use in next version... this
need extern flag as well to mark PLLP usage with either of CPU's.
^ permalink raw reply
* Re: [PATCH V6 14/21] clk: tegra210: Add suspend and resume support
From: Dmitry Osipenko @ 2019-07-22 7:12 UTC (permalink / raw)
To: Sowjanya Komatineni, thierry.reding, jonathanh, tglx, jason,
marc.zyngier, linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, linux-tegra, linux-kernel, mperttunen, spatra,
robh+dt, devicetree
In-Reply-To: <5054f178-db27-9286-d123-3e2b2a885717@gmail.com>
22.07.2019 10:09, Dmitry Osipenko пишет:
> 22.07.2019 9:52, Sowjanya Komatineni пишет:
>>
>> On 7/21/19 11:10 PM, Dmitry Osipenko wrote:
>>> 22.07.2019 1:45, Sowjanya Komatineni пишет:
>>>> On 7/21/19 2:38 PM, Dmitry Osipenko wrote:
>>>>> 21.07.2019 22:40, Sowjanya Komatineni пишет:
>>>>>> This patch adds support for clk: tegra210: suspend-resume.
>>>>>>
>>>>>> All the CAR controller settings are lost on suspend when core
>>>>>> power goes off.
>>>>>>
>>>>>> This patch has implementation for saving and restoring all PLLs
>>>>>> and clocks context during system suspend and resume to have the
>>>>>> clocks back to same state for normal operation.
>>>>>>
>>>>>> Acked-by: Thierry Reding <treding@nvidia.com>
>>>>>> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
>>>>>> ---
>>>>>> drivers/clk/tegra/clk-tegra210.c | 68
>>>>>> ++++++++++++++++++++++++++++++++++++++--
>>>>>> drivers/clk/tegra/clk.c | 14 +++++++++
>>>>>> drivers/clk/tegra/clk.h | 1 +
>>>>>> 3 files changed, 80 insertions(+), 3 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/clk/tegra/clk-tegra210.c
>>>>>> b/drivers/clk/tegra/clk-tegra210.c
>>>>>> index 55a88c0824a5..68271873acc1 100644
>>>>>> --- a/drivers/clk/tegra/clk-tegra210.c
>>>>>> +++ b/drivers/clk/tegra/clk-tegra210.c
>>>>>> @@ -9,6 +9,7 @@
>>>>>> #include <linux/clkdev.h>
>>>>>> #include <linux/of.h>
>>>>>> #include <linux/of_address.h>
>>>>>> +#include <linux/syscore_ops.h>
>>>>>> #include <linux/delay.h>
>>>>>> #include <linux/export.h>
>>>>>> #include <linux/mutex.h>
>>>>>> @@ -220,11 +221,15 @@
>>>>>> #define CLK_M_DIVISOR_SHIFT 2
>>>>>> #define CLK_M_DIVISOR_MASK 0x3
>>>>>> +#define CLK_MASK_ARM 0x44
>>>>>> +#define MISC_CLK_ENB 0x48
>>>>>> +
>>>>>> #define RST_DFLL_DVCO 0x2f4
>>>>>> #define DVFS_DFLL_RESET_SHIFT 0
>>>>>> #define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8
>>>>>> #define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac
>>>>>> +#define CPU_SOFTRST_CTRL 0x380
>>>>>> #define LVL2_CLK_GATE_OVRA 0xf8
>>>>>> #define LVL2_CLK_GATE_OVRC 0x3a0
>>>>>> @@ -2825,6 +2830,7 @@ static int tegra210_enable_pllu(void)
>>>>>> struct tegra_clk_pll_freq_table *fentry;
>>>>>> struct tegra_clk_pll pllu;
>>>>>> u32 reg;
>>>>>> + int ret;
>>>>>> for (fentry = pll_u_freq_table; fentry->input_rate;
>>>>>> fentry++) {
>>>>>> if (fentry->input_rate == pll_ref_freq)
>>>>>> @@ -2853,9 +2859,8 @@ static int tegra210_enable_pllu(void)
>>>>>> reg |= PLL_ENABLE;
>>>>>> writel(reg, clk_base + PLLU_BASE);
>>>>>> - readl_relaxed_poll_timeout_atomic(clk_base + PLLU_BASE, reg,
>>>>>> - reg & PLL_BASE_LOCK, 2, 1000);
>>>>>> - if (!(reg & PLL_BASE_LOCK)) {
>>>>>> + ret = tegra210_wait_for_mask(&pllu, PLLU_BASE, PLL_BASE_LOCK);
>>>>>> + if (ret) {
>>>>> Why this is needed? Was there a bug?
>>>>>
>>>> during resume pllu init is needed and to use same terga210_init_pllu,
>>>> poll_timeout_atomic can't be used as its ony for atomic context.
>>>>
>>>> So changed to use wait_for_mask which should work in both cases.
>>> Atomic variant could be used from any context, not sure what do you
>>> mean. The 'atomic' part only means that function won't cause scheduling
>>> and that's it.
>>
>> Sorry, replied incorrect. readx_poll_timeout_atomic uses ktime_get() and
>> during resume timekeeping suspend/resume happens later than clock
>> suspend/resume. So using tegra210_wait_for_mask.
>>
>> both timekeeping and clk-tegra210 drivers are registered as syscore but
>> not ordered.
>
> Okay, thank you for the clarification.
>
> [snip]
>
You should remove the 'iopoll.h' then, since it's not used anymore.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox