mbox series

[net-next,0/6] net: final GSI register updates

Message ID 20230215195352.755744-1-elder@linaro.org
Headers show
Series net: final GSI register updates | expand

Message

Alex Elder Feb. 15, 2023, 7:53 p.m. UTC
I believe this is the last set of changes required to allow IPA v5.0
to be supported.  There is a little cleanup work remaining, but that
can happen in the next Linux release cycle.  Otherwise we just need
config data and register definitions for IPA v5.0 (and DTS updates).
These are ready but won't be posted without further testing.

The first patch in this series fixes a minor bug in a patch just
posted, which I found too late.  The second eliminates the GSI
memory "adjustment"; this was done previously to avoid/delay the
need to implement a more general way to define GSI register offsets.
Note that this patch causes "checkpatch" warnings due to indentation
that aligns with an open parenthesis.

The third patch makes use of the newly-defined register offsets, to
eliminate the need for a function that hid a few details.  The next
modifies a different helper function to work properly for IPA v5.0+.
The fifth patch changes the way the event ring size is specified
based on how it's now done for IPA v5.0+.  And the last defines a
new register required for IPA v5.0+.

					-Alex

Alex Elder (6):
  net: ipa: fix an incorrect assignment
  net: ipa: kill gsi->virt_raw
  net: ipa: kill ev_ch_e_cntxt_1_length_encode()
  net: ipa: avoid setting an undefined field
  net: ipa: support different event ring encoding
  net: ipa: add HW_PARAM_4 GSI register

 drivers/net/ipa/gsi.c                |  36 ++++-----
 drivers/net/ipa/gsi.h                |   3 +-
 drivers/net/ipa/gsi_reg.c            |  35 ++------
 drivers/net/ipa/gsi_reg.h            |  23 ++++--
 drivers/net/ipa/reg/gsi_reg-v3.1.c   |  22 ++---
 drivers/net/ipa/reg/gsi_reg-v3.5.1.c |  22 ++---
 drivers/net/ipa/reg/gsi_reg-v4.0.c   |  22 ++---
 drivers/net/ipa/reg/gsi_reg-v4.11.c  | 116 ++++++++++++++-------------
 drivers/net/ipa/reg/gsi_reg-v4.5.c   |  64 ++++++++-------
 drivers/net/ipa/reg/gsi_reg-v4.9.c   |  74 ++++++++---------
 10 files changed, 205 insertions(+), 212 deletions(-)

Comments

Alexander Lobakin Feb. 16, 2023, 5:51 p.m. UTC | #1
From: Alex Elder <elder@linaro.org>
Date: Wed, 15 Feb 2023 13:53:48 -0600

> Starting at IPA v4.5, almost all GSI registers had their offsets
> changed by a fixed amount (shifted downward by 0xd000).  Rather than
> defining offsets for all those registers dependent on version, an
> adjustment was applied for most register accesses.  This was
> implemented in commit cdeee49f3ef7f ("net: ipa: adjust GSI register
> addresses").  It was later modified to be a bit more obvious about
> the adjusment, in commit 571b1e7e58ad3 ("net: ipa: use a separate
> pointer for adjusted GSI memory").

[...]

> @@ -142,27 +127,17 @@ int gsi_reg_init(struct gsi *gsi, struct platform_device *pdev)
>  		return -EINVAL;
>  	}
>  
> -	/* Make sure we can make our pointer adjustment if necessary */
> -	adjust = gsi->version < IPA_VERSION_4_5 ? 0 : GSI_EE_REG_ADJUST;
> -	if (res->start < adjust) {
> -		dev_err(dev, "DT memory resource \"gsi\" too low (< %u)\n",
> -			adjust);
> -		return -EINVAL;
> -	}
> -
>  	gsi->regs = gsi_regs(gsi);
>  	if (!gsi->regs) {
>  		dev_err(dev, "unsupported IPA version %u (?)\n", gsi->version);
>  		return -EINVAL;
>  	}
>  
> -	gsi->virt_raw = ioremap(res->start, size);
> -	if (!gsi->virt_raw) {
> +	gsi->virt = ioremap(res->start, size);

Now that at least one check above went away and the second one might be
or be not correct (I thought ioremap core takes care of this), can't
just devm_platform_ioremap_resource_byname() be used here for simplicity?

> +	if (!gsi->virt) {
>  		dev_err(dev, "unable to remap \"gsi\" memory\n");
>  		return -ENOMEM;
>  	}
> -	/* Most registers are accessed using an adjusted register range */
> -	gsi->virt = gsi->virt_raw - adjust;
>  
>  	return 0;
>  }
> @@ -170,7 +145,7 @@ int gsi_reg_init(struct gsi *gsi, struct platform_device *pdev)
>  /* Inverse of gsi_reg_init() */
>  void gsi_reg_exit(struct gsi *gsi)
>  {
> +	iounmap(gsi->virt);

(don't forget to remove this unmap if you decide to switch to devm_)

>  	gsi->virt = NULL;
> -	iounmap(gsi->virt_raw);
> -	gsi->virt_raw = NULL;
> +	gsi->regs = NULL;
>  }

[...]

> diff --git a/drivers/net/ipa/reg/gsi_reg-v3.1.c b/drivers/net/ipa/reg/gsi_reg-v3.1.c
> index 651c8a7ed6116..8451d3f8e421e 100644
> --- a/drivers/net/ipa/reg/gsi_reg-v3.1.c
> +++ b/drivers/net/ipa/reg/gsi_reg-v3.1.c
> @@ -8,16 +8,12 @@
>  #include "../reg.h"
>  #include "../gsi_reg.h"
>  
> -/* The inter-EE IRQ registers are relative to gsi->virt_raw (IPA v3.5+) */
> -
>  REG(INTER_EE_SRC_CH_IRQ_MSK, inter_ee_src_ch_irq_msk,
>      0x0000c020 + 0x1000 * GSI_EE_AP);
>  
>  REG(INTER_EE_SRC_EV_CH_IRQ_MSK, inter_ee_src_ev_ch_irq_msk,
>      0x0000c024 + 0x1000 * GSI_EE_AP);
>  
> -/* All other register offsets are relative to gsi->virt */
> -
>  static const u32 reg_ch_c_cntxt_0_fmask[] = {
>  	[CHTYPE_PROTOCOL]				= GENMASK(2, 0),
>  	[CHTYPE_DIR]					= BIT(3),
> @@ -66,10 +62,6 @@ static const u32 reg_error_log_fmask[] = {
>  	[ERR_EE]					= GENMASK(31, 28),
>  };
>  
> -REG_FIELDS(ERROR_LOG, error_log, 0x0001f200 + 0x4000 * GSI_EE_AP);
> -
> -REG(ERROR_LOG_CLR, error_log_clr, 0x0001f210 + 0x4000 * GSI_EE_AP);
> -
>  REG_STRIDE(CH_C_SCRATCH_0, ch_c_scratch_0,
>  	   0x0001c060 + 0x4000 * GSI_EE_AP, 0x80);
>  
> @@ -152,6 +144,7 @@ REG_FIELDS(GSI_STATUS, gsi_status, 0x0001f000 + 0x4000 * GSI_EE_AP);
>  
>  static const u32 reg_ch_cmd_fmask[] = {
>  	[CH_CHID]					= GENMASK(7, 0),
> +						/* Bits 8-23 reserved */
>  	[CH_OPCODE]					= GENMASK(31, 24),
>  };
>  
> @@ -159,6 +152,7 @@ REG_FIELDS(CH_CMD, ch_cmd, 0x0001f008 + 0x4000 * GSI_EE_AP);
>  
>  static const u32 reg_ev_ch_cmd_fmask[] = {
>  	[EV_CHID]					= GENMASK(7, 0),
> +						/* Bits 8-23 reserved */
>  	[EV_OPCODE]					= GENMASK(31, 24),
>  };
>  

[...]

(offtopic)

I hope all those gsi_reg-v*.c are autogenerated? They look pretty scary
to be written and edited manually each time :D

Thanks,
Olek
Alex Elder Feb. 16, 2023, 6:11 p.m. UTC | #2
On 2/16/23 11:51 AM, Alexander Lobakin wrote:
> From: Alex Elder <elder@linaro.org>
> Date: Wed, 15 Feb 2023 13:53:48 -0600
> 
>> Starting at IPA v4.5, almost all GSI registers had their offsets
>> changed by a fixed amount (shifted downward by 0xd000).  Rather than
>> defining offsets for all those registers dependent on version, an
>> adjustment was applied for most register accesses.  This was
>> implemented in commit cdeee49f3ef7f ("net: ipa: adjust GSI register
>> addresses").  It was later modified to be a bit more obvious about
>> the adjusment, in commit 571b1e7e58ad3 ("net: ipa: use a separate
>> pointer for adjusted GSI memory").
> 
> [...]
> 
>> @@ -142,27 +127,17 @@ int gsi_reg_init(struct gsi *gsi, struct platform_device *pdev)
>>   		return -EINVAL;
>>   	}
>>   
>> -	/* Make sure we can make our pointer adjustment if necessary */
>> -	adjust = gsi->version < IPA_VERSION_4_5 ? 0 : GSI_EE_REG_ADJUST;
>> -	if (res->start < adjust) {
>> -		dev_err(dev, "DT memory resource \"gsi\" too low (< %u)\n",
>> -			adjust);
>> -		return -EINVAL;
>> -	}
>> -
>>   	gsi->regs = gsi_regs(gsi);
>>   	if (!gsi->regs) {
>>   		dev_err(dev, "unsupported IPA version %u (?)\n", gsi->version);
>>   		return -EINVAL;
>>   	}
>>   
>> -	gsi->virt_raw = ioremap(res->start, size);
>> -	if (!gsi->virt_raw) {
>> +	gsi->virt = ioremap(res->start, size);
> 
> Now that at least one check above went away and the second one might be
> or be not correct (I thought ioremap core takes care of this), can't
> just devm_platform_ioremap_resource_byname() be used here for simplicity?

Previously, virt_raw would be the "real" re-mapped pointer, and then
virt would be adjusted downward from that.  It was a weird thing to
do, because the result pointed to a non-mapped address.  But all uses
of the virt pointer added an offset that was enough to put the result
into the mapped range.

The new code updates all offsets to account for what the adjustment
previously did.  The test that got removed isn't necessary any more.

> 
>> +	if (!gsi->virt) {
>>   		dev_err(dev, "unable to remap \"gsi\" memory\n");
>>   		return -ENOMEM;
>>   	}
>> -	/* Most registers are accessed using an adjusted register range */
>> -	gsi->virt = gsi->virt_raw - adjust;
>>   
>>   	return 0;
>>   }
>> @@ -170,7 +145,7 @@ int gsi_reg_init(struct gsi *gsi, struct platform_device *pdev)
>>   /* Inverse of gsi_reg_init() */
>>   void gsi_reg_exit(struct gsi *gsi)
>>   {
>> +	iounmap(gsi->virt);
> 
> (don't forget to remove this unmap if you decide to switch to devm_)

As far as devm_*() calls, I don't use those anywhere in the driver
currently.  If I were going to use them in one place I'd want do
it consistently, everywhere.  I don't want to do that.

>>   	gsi->virt = NULL;
>> -	iounmap(gsi->virt_raw);
>> -	gsi->virt_raw = NULL;
>> +	gsi->regs = NULL;
>>   }
> 
> [...]
> 
>> diff --git a/drivers/net/ipa/reg/gsi_reg-v3.1.c b/drivers/net/ipa/reg/gsi_reg-v3.1.c
>> index 651c8a7ed6116..8451d3f8e421e 100644
>> --- a/drivers/net/ipa/reg/gsi_reg-v3.1.c
>> +++ b/drivers/net/ipa/reg/gsi_reg-v3.1.c
>> @@ -8,16 +8,12 @@
>>   #include "../reg.h"
>>   #include "../gsi_reg.h"
>>   
>> -/* The inter-EE IRQ registers are relative to gsi->virt_raw (IPA v3.5+) */
>> -
>>   REG(INTER_EE_SRC_CH_IRQ_MSK, inter_ee_src_ch_irq_msk,
>>       0x0000c020 + 0x1000 * GSI_EE_AP);
>>   
>>   REG(INTER_EE_SRC_EV_CH_IRQ_MSK, inter_ee_src_ev_ch_irq_msk,
>>       0x0000c024 + 0x1000 * GSI_EE_AP);
>>   
>> -/* All other register offsets are relative to gsi->virt */
>> -
>>   static const u32 reg_ch_c_cntxt_0_fmask[] = {
>>   	[CHTYPE_PROTOCOL]				= GENMASK(2, 0),
>>   	[CHTYPE_DIR]					= BIT(3),
>> @@ -66,10 +62,6 @@ static const u32 reg_error_log_fmask[] = {
>>   	[ERR_EE]					= GENMASK(31, 28),
>>   };
>>   
>> -REG_FIELDS(ERROR_LOG, error_log, 0x0001f200 + 0x4000 * GSI_EE_AP);
>> -
>> -REG(ERROR_LOG_CLR, error_log_clr, 0x0001f210 + 0x4000 * GSI_EE_AP);
>> -
>>   REG_STRIDE(CH_C_SCRATCH_0, ch_c_scratch_0,
>>   	   0x0001c060 + 0x4000 * GSI_EE_AP, 0x80);
>>   
>> @@ -152,6 +144,7 @@ REG_FIELDS(GSI_STATUS, gsi_status, 0x0001f000 + 0x4000 * GSI_EE_AP);
>>   
>>   static const u32 reg_ch_cmd_fmask[] = {
>>   	[CH_CHID]					= GENMASK(7, 0),
>> +						/* Bits 8-23 reserved */
>>   	[CH_OPCODE]					= GENMASK(31, 24),
>>   };
>>   
>> @@ -159,6 +152,7 @@ REG_FIELDS(CH_CMD, ch_cmd, 0x0001f008 + 0x4000 * GSI_EE_AP);
>>   
>>   static const u32 reg_ev_ch_cmd_fmask[] = {
>>   	[EV_CHID]					= GENMASK(7, 0),
>> +						/* Bits 8-23 reserved */
>>   	[EV_OPCODE]					= GENMASK(31, 24),
>>   };
>>   
> 
> [...]
> 
> (offtopic)
> 
> I hope all those gsi_reg-v*.c are autogenerated? They look pretty scary
> to be written and edited manually each time :D

I know they look scary, but no, they're manually generated and
it's a real pain to review them.  I try to be consistent enough
that a "diff" is revealing and helpful.  For the GSI registers,
most of them don't change (until IPA v5.0).  I intend to modify
this a bit further so that registers that are the same as the
previous version don't have to be re-stated (so each new version
only has to highlight the differences).

All that said, once created, they don't change.

Thanks.

					-Alex

> 
> Thanks,
> Olek
Alexander Lobakin Feb. 17, 2023, 11:57 a.m. UTC | #3
From: Alex Elder <elder@linaro.org>
Date: Thu, 16 Feb 2023 12:11:11 -0600

> On 2/16/23 11:51 AM, Alexander Lobakin wrote:
>> From: Alex Elder <elder@linaro.org>
>> Date: Wed, 15 Feb 2023 13:53:48 -0600

[...]

>>>       gsi->regs = gsi_regs(gsi);
>>>       if (!gsi->regs) {
>>>           dev_err(dev, "unsupported IPA version %u (?)\n",
>>> gsi->version);
>>>           return -EINVAL;
>>>       }
>>>   -    gsi->virt_raw = ioremap(res->start, size);
>>> -    if (!gsi->virt_raw) {
>>> +    gsi->virt = ioremap(res->start, size);
>>
>> Now that at least one check above went away and the second one might be
>> or be not correct (I thought ioremap core takes care of this), can't
>> just devm_platform_ioremap_resource_byname() be used here for simplicity?
> 
> Previously, virt_raw would be the "real" re-mapped pointer, and then
> virt would be adjusted downward from that.  It was a weird thing to
> do, because the result pointed to a non-mapped address.  But all uses
> of the virt pointer added an offset that was enough to put the result
> into the mapped range.
> 
> The new code updates all offsets to account for what the adjustment
> previously did.  The test that got removed isn't necessary any more.

Yeah I got it, just asked that maybe you can now use
platform_ioremap_resource_byname() instead of
platform_get_resource_byname() + ioremap() :)

> 
>>
>>> +    if (!gsi->virt) {
>>>           dev_err(dev, "unable to remap \"gsi\" memory\n");
>>>           return -ENOMEM;
>>>       }
>>> -    /* Most registers are accessed using an adjusted register range */
>>> -    gsi->virt = gsi->virt_raw - adjust;
>>>         return 0;
>>>   }
>>> @@ -170,7 +145,7 @@ int gsi_reg_init(struct gsi *gsi, struct
>>> platform_device *pdev)
>>>   /* Inverse of gsi_reg_init() */
>>>   void gsi_reg_exit(struct gsi *gsi)
>>>   {
>>> +    iounmap(gsi->virt);
>>
>> (don't forget to remove this unmap if you decide to switch to devm_)
> 
> As far as devm_*() calls, I don't use those anywhere in the driver
> currently.  If I were going to use them in one place I'd want do
> it consistently, everywhere.  I don't want to do that.

+

> 
>>>       gsi->virt = NULL;
>>> -    iounmap(gsi->virt_raw);
>>> -    gsi->virt_raw = NULL;
>>> +    gsi->regs = NULL;

[...]

>> (offtopic)
>>
>> I hope all those gsi_reg-v*.c are autogenerated? They look pretty scary
>> to be written and edited manually each time :D
> 
> I know they look scary, but no, they're manually generated and
> it's a real pain to review them.  I try to be consistent enough
> that a "diff" is revealing and helpful.  For the GSI registers,
> most of them don't change (until IPA v5.0).  I intend to modify
> this a bit further so that registers that are the same as the
> previous version don't have to be re-stated (so each new version
> only has to highlight the differences).

No, it's +/- okay to review, as you say, they're pretty consistent in
terms of code.

> 
> All that said, once created, they don't change.
> 
> Thanks.
> 
>                     -Alex
Thanks,
Olek
Alex Elder Feb. 17, 2023, 1:04 p.m. UTC | #4
On 2/17/23 5:57 AM, Alexander Lobakin wrote:
>>> just devm_platform_ioremap_resource_byname() be used here for simplicity?
>> Previously, virt_raw would be the "real" re-mapped pointer, and then
>> virt would be adjusted downward from that.  It was a weird thing to
>> do, because the result pointed to a non-mapped address.  But all uses
>> of the virt pointer added an offset that was enough to put the result
>> into the mapped range.
>>
>> The new code updates all offsets to account for what the adjustment
>> previously did.  The test that got removed isn't necessary any more.
> Yeah I got it, just asked that maybe you can now use
> platform_ioremap_resource_byname() instead of
> platform_get_resource_byname() + ioremap() :)

Sorry, I focused on the "devm" part and not this part.
Yes I like that, but let me do that as a follow-on
patch, and I think I can do it in more than this
spot (possibly three, but I have to look closely).

Thanks.

					-Alex
patchwork-bot+netdevbpf@kernel.org Feb. 20, 2023, 7:30 a.m. UTC | #5
Hello:

This series was applied to netdev/net-next.git (master)
by Paolo Abeni <pabeni@redhat.com>:

On Wed, 15 Feb 2023 13:53:46 -0600 you wrote:
> I believe this is the last set of changes required to allow IPA v5.0
> to be supported.  There is a little cleanup work remaining, but that
> can happen in the next Linux release cycle.  Otherwise we just need
> config data and register definitions for IPA v5.0 (and DTS updates).
> These are ready but won't be posted without further testing.
> 
> The first patch in this series fixes a minor bug in a patch just
> posted, which I found too late.  The second eliminates the GSI
> memory "adjustment"; this was done previously to avoid/delay the
> need to implement a more general way to define GSI register offsets.
> Note that this patch causes "checkpatch" warnings due to indentation
> that aligns with an open parenthesis.
> 
> [...]

Here is the summary with links:
  - [net-next,1/6] net: ipa: fix an incorrect assignment
    https://git.kernel.org/netdev/net-next/c/ecfa80ce3b87
  - [net-next,2/6] net: ipa: kill gsi->virt_raw
    https://git.kernel.org/netdev/net-next/c/59b12b1d27f3
  - [net-next,3/6] net: ipa: kill ev_ch_e_cntxt_1_length_encode()
    https://git.kernel.org/netdev/net-next/c/f75f44ddd4cb
  - [net-next,4/6] net: ipa: avoid setting an undefined field
    https://git.kernel.org/netdev/net-next/c/62747512ebe6
  - [net-next,5/6] net: ipa: support different event ring encoding
    https://git.kernel.org/netdev/net-next/c/37cd29ec8401
  - [net-next,6/6] net: ipa: add HW_PARAM_4 GSI register
    https://git.kernel.org/netdev/net-next/c/f651334e1ef5

You are awesome, thank you!
Alex Elder March 5, 2023, 4:58 p.m. UTC | #6
On 2/17/23 7:04 AM, Alex Elder wrote:
> On 2/17/23 5:57 AM, Alexander Lobakin wrote:
>>>> just devm_platform_ioremap_resource_byname() be used here for 
>>>> simplicity?
>>> Previously, virt_raw would be the "real" re-mapped pointer, and then
>>> virt would be adjusted downward from that.  It was a weird thing to
>>> do, because the result pointed to a non-mapped address.  But all uses
>>> of the virt pointer added an offset that was enough to put the result
>>> into the mapped range.
>>>
>>> The new code updates all offsets to account for what the adjustment
>>> previously did.  The test that got removed isn't necessary any more.
>> Yeah I got it, just asked that maybe you can now use
>> platform_ioremap_resource_byname() instead of
>> platform_get_resource_byname() + ioremap() :)
> 
> Sorry, I focused on the "devm" part and not this part.
> Yes I like that, but let me do that as a follow-on
> patch, and I think I can do it in more than this
> spot (possibly three, but I have to look closely).

Looking at this today, the only OF functions that look up a
resource and I/O remap it in one call are devm_*() variants.
There is no platform_ioremap_resource_byname() function.

One that's available is devm_platform_ioremap_resource_byname(),
which could possibly be used in the two locations that call
platform_get_resource_byname() followed by ioremap().

As I said earlier, if I were to use any devm_*() function
calls the driver, I would want to convert *everything* to
use devm_*() variants, and I have no plans to do that at
this time.

So I will not be implementing your suggestion.

					-Alex

> Thanks.
> 
>                      -Alex
> 
>
Alexander Lobakin March 6, 2023, 10:30 a.m. UTC | #7
From: Alex Elder <elder@ieee.org>
Date: Sun, 5 Mar 2023 10:58:19 -0600

> On 2/17/23 7:04 AM, Alex Elder wrote:
>> On 2/17/23 5:57 AM, Alexander Lobakin wrote:
>>>>> just devm_platform_ioremap_resource_byname() be used here for
>>>>> simplicity?
>>>> Previously, virt_raw would be the "real" re-mapped pointer, and then
>>>> virt would be adjusted downward from that.  It was a weird thing to
>>>> do, because the result pointed to a non-mapped address.  But all uses
>>>> of the virt pointer added an offset that was enough to put the result
>>>> into the mapped range.
>>>>
>>>> The new code updates all offsets to account for what the adjustment
>>>> previously did.  The test that got removed isn't necessary any more.
>>> Yeah I got it, just asked that maybe you can now use
>>> platform_ioremap_resource_byname() instead of
>>> platform_get_resource_byname() + ioremap() :)
>>
>> Sorry, I focused on the "devm" part and not this part.
>> Yes I like that, but let me do that as a follow-on
>> patch, and I think I can do it in more than this
>> spot (possibly three, but I have to look closely).
> 
> Looking at this today, the only OF functions that look up a
> resource and I/O remap it in one call are devm_*() variants.
> There is no platform_ioremap_resource_byname() function.
> 
> One that's available is devm_platform_ioremap_resource_byname(),
> which could possibly be used in the two locations that call
> platform_get_resource_byname() followed by ioremap().
> 
> As I said earlier, if I were to use any devm_*() function
> calls the driver, I would want to convert *everything* to
> use devm_*() variants, and I have no plans to do that at
> this time.
> 
> So I will not be implementing your suggestion.

Sure. It's fully up to the developers as it doesn't make the code worse
in any way.

> 
>                     -Alex
> 
>> Thanks.
>>
>>                      -Alex
>>
>>
> 
Thanks,
Olek