From yu.tu at amlogic.com  Sat Jan  1 05:30:12 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Sat, 1 Jan 2022 21:30:12 +0800
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate calculation
 is described using the common clock code. Also added S4 chip uart
 Compatible.
In-Reply-To: <CAFBinCB2nF0TwRE1uJ4UTB_avcqRBfOHR1CDSe29dB1o-YjEHQ@mail.gmail.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
 <CAFBinCCL-QaeSRCLzfyNXcRQZ7YC1D85rP2y4OGkAjCmQEqGgQ@mail.gmail.com>
 <3e1e40aa-7865-0f7a-5772-e2ad96c8141d@amlogic.com>
 <CAFBinCB2nF0TwRE1uJ4UTB_avcqRBfOHR1CDSe29dB1o-YjEHQ@mail.gmail.com>
Message-ID: <7278bace-a2b9-0cfc-55b3-c19311e3352e@amlogic.com>

Hi Martin,
     Thank you very much for your reply.

On 2021/12/31 23:32, Martin Blumenstingl wrote:
> [ EXTERNAL EMAIL ]
> 
> On Fri, Dec 31, 2021 at 12:24 PM Yu Tu <yu.tu at amlogic.com> wrote:
> [...]
>>>>    static int meson_uart_request_port(struct uart_port *port)
>>>>    {
>>>> +       struct meson_uart_data *private_data = port->private_data;
>>>> +       int ret;
>>>> +
>>>> +       ret = clk_prepare_enable(private_data->pclk);
>>>> +       if (ret)
>>>> +               return ret;
>>>> +
>>>> +       ret = clk_prepare_enable(private_data->baud_clk);
>>>> +       if (ret) {
>>>> +               clk_disable_unprepare(private_data->pclk);
>>>> +               return ret;
>>>> +       }
>>> This code is from my original suggestion - and I had a doubt there
>>> which I forgot to add as a comment originally:
>>> Can you confirm that accessing the UART controller registers works
>>> even when "pclk" is turned off?
>>> I am asking this because the common clock framework can access the
>>> clocks at any time.
>>> And I have seen SoCs which would hang when trying to access a module's
>>> registers while the module's pclk is turned off.
>> On all meson platforms, the default pclk for all UART is turned on
>> during the u-boot phase. When registering uart pclk in the kernel phase,
>> the CLK_IGNORE_UNUSED flag is added. So the real shutdown is when the
>> standby goes down, the parent clk shuts down.
> Interesting, thanks for sharing that u-boot turns these clocks on.
> Let's say someone wanted to make u-boot save power and turn off all
> UART clocks except the one for uart_AO (where we typically connect the
> serial console).
> In that case the pclk of uart_C (just to choose an example here) is
> turned off. Would there be a problem then accessing the registers of
> uart_C before clk_prepare_enable is called?
The way you describe it, it does hang. This would not be recommended on 
actual projects.

At present, AmLogic chips are older than S4 Soc, and we have no way to 
deal with this problem. We have to tell customers not to use it in this 
way?Customers rarely use it in real projects.On the S4 SOC we will use 
a clock like the UART pclk to control the shutdown using two registers, 
one safe (need to operate in EL3) and one normal (EL1). It will only be 
closed if both registers are closed. This mainly prevents misoperation.

With your experience, I'd like to know how you deal with this kind of 
problem.
> 
> [...]
>>>>           port->fifosize = 64;
>>> commit 27d44e05d7b85d ("tty: serial: meson: retrieve port FIFO size
>>> from DT") [0] from May 2021 has changed this line to:
>>>     port->fifosize = fifosize;
>>> So your patch currently does not apply to linux-next (or even Linus'
>>> mainline tree).
>>>
>> So do I need to wait for [0] patch merged before I can continue to make
>> changes ?
> These changes are already merged.
> 
>> What can I do before?
> You should base your changes on top of the tty.git/tty-next branch [1]
> where Greg (the maintainer of this tree) will pick up the patches once
> they are good (got enough Acked-by/Reviewed-by, etc.).
> I suspect that you based your changes on an older or stable kernel
> version (let's say 5.10). New functionality should always get into the
> -next tree where various auto-build robots will compile-test the
> changes and we even have Kernel CI where changes are tested on real
> hardware (BayLibre even maintains Amlogic boards in their Kernel CI
> labs). Let's say Amlogic updates to Linux 5.17 next year then the
> patches are already included in that kernel version - instead of being
> only available in Linux 5.10.
> 
I'm sorry, I did branch confirm there was a mistake, I have corrected.
> 
> Best regards,
> Martin
> 
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/log/?h=tty-next
> 


From martin.blumenstingl at googlemail.com  Sun Jan  2 11:36:48 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sun, 2 Jan 2022 20:36:48 +0100
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate calculation
 is described using the common clock code. Also added S4 chip uart
 Compatible.
In-Reply-To: <7278bace-a2b9-0cfc-55b3-c19311e3352e@amlogic.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
 <CAFBinCCL-QaeSRCLzfyNXcRQZ7YC1D85rP2y4OGkAjCmQEqGgQ@mail.gmail.com>
 <3e1e40aa-7865-0f7a-5772-e2ad96c8141d@amlogic.com>
 <CAFBinCB2nF0TwRE1uJ4UTB_avcqRBfOHR1CDSe29dB1o-YjEHQ@mail.gmail.com>
 <7278bace-a2b9-0cfc-55b3-c19311e3352e@amlogic.com>
Message-ID: <CAFBinCCwE1DbP+Y49o3WxNdeE11ZK=HcGbXa0Sq52tch+eNhrQ@mail.gmail.com>

Hi,

On Sat, Jan 1, 2022 at 2:30 PM Yu Tu <yu.tu at amlogic.com> wrote:
[...]
> > Interesting, thanks for sharing that u-boot turns these clocks on.
> > Let's say someone wanted to make u-boot save power and turn off all
> > UART clocks except the one for uart_AO (where we typically connect the
> > serial console).
> > In that case the pclk of uart_C (just to choose an example here) is
> > turned off. Would there be a problem then accessing the registers of
> > uart_C before clk_prepare_enable is called?
> The way you describe it, it does hang. This would not be recommended on
> actual projects.
>
> At present, AmLogic chips are older than S4 Soc, and we have no way to
> deal with this problem. We have to tell customers not to use it in this
> way?Customers rarely use it in real projects.On the S4 SOC we will use
> a clock like the UART pclk to control the shutdown using two registers,
> one safe (need to operate in EL3) and one normal (EL1). It will only be
> closed if both registers are closed. This mainly prevents misoperation.
oh, interesting that there's some updates specifically with the S4 SoCs :-)

> With your experience, I'd like to know how you deal with this kind of
> problem.
Before this patch the driver simply turns on the clock from within
meson_uart_probe() (specifically it does so in
meson_uart_probe_clock()).
I think there's advanced power-saving techniques. Maybe for now we
keep it simple and just enable the clock(s) at probe time and disable
them at driver remove time. What do you think?


Best regards,
Martin


From jbrunet at baylibre.com  Mon Jan  3 01:57:00 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 03 Jan 2022 10:57:00 +0100
Subject: [RESEND] Amlogic DPCM audio card(s) speaker placement issue
In-Reply-To: <3cd96113-3272-1efe-aa81-39de952d1e68@perex.cz>
References: <ECC56215-1E02-4735-82F3-B68E73F56CB4@gmail.com>
 <3cd96113-3272-1efe-aa81-39de952d1e68@perex.cz>
Message-ID: <1jk0fh86yj.fsf@starbuckisacylon.baylibre.com>


On Sun 26 Dec 2021 at 18:30, Jaroslav Kysela <perex at perex.cz> wrote:

> On 26. 12. 21 12:43, Christian Hewitt wrote:
>
>> **** List of PLAYBACK Hardware Devices ****
>> card 0: LIBRETECHCC [LIBRETECH-CC], device 0: fe.dai-link-0 (*) []
>>   Subdevices: 1/1
>>   Subdevice #0: subdevice #0
>
>> numid=12,iface=PCM,name='ELD',device=2
>> numid=11,iface=PCM,name='IEC958 Playback Default',device=2
>> numid=10,iface=PCM,name='IEC958 Playback Mask',device=2
>> numid=9,iface=PCM,name='Playback Channel Map',device=2
>> https://github.com/torvalds/linux/blob/master/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts#L136-L188
>
> Have you tried to reorder the dai-link-# sections in DT? It appears to me that sound/soc/codecs/hdmi-codec.c / hdmi_codec_pcm_new() gets the internal PCM
> device rather than the exported PCM device for the user space.
>
> If the DAI routing cannot be changed, then the hdmi-codec.c should be modified to export the correct device number for the user space:
>

The DAI routing is dynamic, especially on the AXG series.
There is actually two routing stages:

1) Between the user interfaces (DMA) and the i2s/TDM encoders/decoders:
   -> This is using DPCM

2) Between the i2s/TDM encoders and the HDMI controller:
   -> This is using Codec-to-Codec links

The problem exposed here is
 - How to get the get the "Playback Channel Map" related to the pcm
 device of a given playback ?

I don't really know how to answer this.
As you noted above, given the routing is dynamic, I don't think the
problem can be solved with a specific link ordering

However, on these platforms, there will only be one such control
AFAIK. The one you get is the one you are looking for. It's not ideal
but it's a start.

> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/sound/soc/codecs/hdmi-codec.c?h=v5.16-rc6#n805
>
> 						Jaroslav



From perex at perex.cz  Mon Jan  3 03:04:25 2022
From: perex at perex.cz (Jaroslav Kysela)
Date: Mon, 3 Jan 2022 12:04:25 +0100
Subject: [RESEND] Amlogic DPCM audio card(s) speaker placement issue
In-Reply-To: <1jk0fh86yj.fsf@starbuckisacylon.baylibre.com>
References: <ECC56215-1E02-4735-82F3-B68E73F56CB4@gmail.com>
 <3cd96113-3272-1efe-aa81-39de952d1e68@perex.cz>
 <1jk0fh86yj.fsf@starbuckisacylon.baylibre.com>
Message-ID: <125f4abc-a85e-7a8c-594c-4cf7ddee1d78@perex.cz>

On 03. 01. 22 10:57, Jerome Brunet wrote:
> 
> On Sun 26 Dec 2021 at 18:30, Jaroslav Kysela <perex at perex.cz> wrote:
> 
>> On 26. 12. 21 12:43, Christian Hewitt wrote:
>>
>>> **** List of PLAYBACK Hardware Devices ****
>>> card 0: LIBRETECHCC [LIBRETECH-CC], device 0: fe.dai-link-0 (*) []
>>>    Subdevices: 1/1
>>>    Subdevice #0: subdevice #0
>>
>>> numid=12,iface=PCM,name='ELD',device=2
>>> numid=11,iface=PCM,name='IEC958 Playback Default',device=2
>>> numid=10,iface=PCM,name='IEC958 Playback Mask',device=2
>>> numid=9,iface=PCM,name='Playback Channel Map',device=2
>>> https://github.com/torvalds/linux/blob/master/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts#L136-L188
>>
>> Have you tried to reorder the dai-link-# sections in DT? It appears to me that sound/soc/codecs/hdmi-codec.c / hdmi_codec_pcm_new() gets the internal PCM
>> device rather than the exported PCM device for the user space.
>>
>> If the DAI routing cannot be changed, then the hdmi-codec.c should be modified to export the correct device number for the user space:
>>
> 
> The DAI routing is dynamic, especially on the AXG series.
> There is actually two routing stages:
> 
> 1) Between the user interfaces (DMA) and the i2s/TDM encoders/decoders:
>     -> This is using DPCM
> 
> 2) Between the i2s/TDM encoders and the HDMI controller:
>     -> This is using Codec-to-Codec links
> 
> The problem exposed here is
>   - How to get the get the "Playback Channel Map" related to the pcm
>   device of a given playback ?

The PCM device exported to the user space should be able to export this 
information correctly. The kcontrols in hdmi-codec.c refers to an unknown 
(internal) PCM codec2codec device (from the user space view) which is created 
in the SoC layer.

It seems that kcontrols in hdmi-codec.c should not be created for the internal 
SoC PCMs. A new layer which translate the kcontrol handling between the 
exported (user space) PCM device and internal (SoC) PCM device is required.

Problematic code in hdmi_codec_pcm_new() / hdmi-codec.c:

- snd_pcm_add_chmap_ctls()
- kctl->id.device = rtd->pcm->device

						Jaroslav

-- 
Jaroslav Kysela <perex at perex.cz>
Linux Sound Maintainer; ALSA Project; Red Hat, Inc.


From narmstrong at baylibre.com  Mon Jan  3 03:16:22 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 12:16:22 +0100
Subject: [PATCH v2 1/1] dt-bindings: display: meson-vpu: Add missing
 amlogic,canvas property
In-Reply-To: <20211219094155.177206-1-alexander.stein@mailbox.org>
References: <20211219094155.177206-1-alexander.stein@mailbox.org>
Message-ID: <af0a8ecd-3c41-2eb8-43bf-dd439a958d53@baylibre.com>

On 19/12/2021 10:41, Alexander Stein wrote:
> This property was already mentioned in the old textual bindings
> amlogic,meson-vpu.txt, but got dropped during conversion.
> Adding it back similar to amlogic,gx-vdec.yaml.
> 
> Fixes: 6b9ebf1e0e67 ("dt-bindings: display: amlogic, meson-vpu: convert to yaml")
> Signed-off-by: Alexander Stein <alexander.stein at mailbox.org>
> ---
> Changes in v2:
> * Do not linebreak Fixes tag
> * Make amlogic,canvas mandatory as it was in textual binding already
> * Add amlogic,canvas to example
> 
>  .../devicetree/bindings/display/amlogic,meson-vpu.yaml      | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
> index 851cb0781217..047fd69e0377 100644
> --- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
> +++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
> @@ -78,6 +78,10 @@ properties:
>    interrupts:
>      maxItems: 1
>  
> +  amlogic,canvas:
> +    description: should point to a canvas provider node
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +
>    power-domains:
>      maxItems: 1
>      description: phandle to the associated power domain
> @@ -106,6 +110,7 @@ required:
>    - port at 1
>    - "#address-cells"
>    - "#size-cells"
> +  - amlogic,canvas
>  
>  additionalProperties: false
>  
> @@ -118,6 +123,7 @@ examples:
>          interrupts = <3>;
>          #address-cells = <1>;
>          #size-cells = <0>;
> +        amlogic,canvas = <&canvas>;
>  
>          /* CVBS VDAC output port */
>          port at 0 {
> 

Applying to drm-misc-fixes,

Thanks,
Neil


From narmstrong at baylibre.com  Mon Jan  3 03:22:26 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 12:22:26 +0100
Subject: [PATCH 2/2] drm/meson: Fix error handling when afbcd.ops->init
 fails
In-Reply-To: <20211230235515.1627522-3-martin.blumenstingl@googlemail.com>
References: <20211230235515.1627522-1-martin.blumenstingl@googlemail.com>
 <20211230235515.1627522-3-martin.blumenstingl@googlemail.com>
Message-ID: <386f5be4-eca0-6117-82f5-317b82ee66a7@baylibre.com>

On 31/12/2021 00:55, Martin Blumenstingl wrote:
> When afbcd.ops->init fails we need to free the struct drm_device. Also
> all errors which come after afbcd.ops->init was successful need to exit
> the AFBCD, just like meson_drv_unbind() does.
> 
> Fixes: d1b5e41e13a7e9 ("drm/meson: Add AFBCD module driver")
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> ---
>  drivers/gpu/drm/meson/meson_drv.c | 19 +++++++++++--------
>  1 file changed, 11 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
> index b919271a6e50..26aeaf0ab86e 100644
> --- a/drivers/gpu/drm/meson/meson_drv.c
> +++ b/drivers/gpu/drm/meson/meson_drv.c
> @@ -302,42 +302,42 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
>  	if (priv->afbcd.ops) {
>  		ret = priv->afbcd.ops->init(priv);
>  		if (ret)
> -			return ret;
> +			goto free_drm;
>  	}
>  
>  	/* Encoder Initialization */
>  
>  	ret = meson_encoder_cvbs_init(priv);
>  	if (ret)
> -		goto free_drm;
> +		goto exit_afbcd;
>  
>  	if (has_components) {
>  		ret = component_bind_all(drm->dev, drm);
>  		if (ret) {
>  			dev_err(drm->dev, "Couldn't bind all components\n");
> -			goto free_drm;
> +			goto exit_afbcd;
>  		}
>  	}
>  
>  	ret = meson_encoder_hdmi_init(priv);
>  	if (ret)
> -		goto free_drm;
> +		goto exit_afbcd;
>  
>  	ret = meson_plane_create(priv);
>  	if (ret)
> -		goto free_drm;
> +		goto exit_afbcd;
>  
>  	ret = meson_overlay_create(priv);
>  	if (ret)
> -		goto free_drm;
> +		goto exit_afbcd;
>  
>  	ret = meson_crtc_create(priv);
>  	if (ret)
> -		goto free_drm;
> +		goto exit_afbcd;
>  
>  	ret = request_irq(priv->vsync_irq, meson_irq, 0, drm->driver->name, drm);
>  	if (ret)
> -		goto free_drm;
> +		goto exit_afbcd;
>  
>  	drm_mode_config_reset(drm);
>  
> @@ -355,6 +355,9 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
>  
>  uninstall_irq:
>  	free_irq(priv->vsync_irq, drm);
> +exit_afbcd:
> +	if (priv->afbcd.ops)
> +		priv->afbcd.ops->exit(priv);
>  free_drm:
>  	drm_dev_put(drm);
>  
> 

Acked-by: Neil Armstrong <narmstrong at baylibre.com>

Thanks,

But this depends on patch 1, so I'll add the same Fixes tag on patch 1 and add to drm-misc-next so it won't pollute -fixes but will still be eventually be backported when landing on linus master.

Neil


From narmstrong at baylibre.com  Mon Jan  3 03:24:01 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 12:24:01 +0100
Subject: [PATCH 1/2] drm/meson: osd_afbcd: Add an exit callback to struct
 meson_afbcd_ops
In-Reply-To: <20211230235515.1627522-2-martin.blumenstingl@googlemail.com>
References: <20211230235515.1627522-1-martin.blumenstingl@googlemail.com>
 <20211230235515.1627522-2-martin.blumenstingl@googlemail.com>
Message-ID: <4a4b40fd-b9d7-b38d-b4d4-4aaaf03693f2@baylibre.com>

On 31/12/2021 00:55, Martin Blumenstingl wrote:
> Use this to simplify the driver shutdown. It will also come handy when
> fixing the error handling in meson_drv_bind_master().
> 
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> ---
>  drivers/gpu/drm/meson/meson_drv.c       |  6 ++--
>  drivers/gpu/drm/meson/meson_osd_afbcd.c | 41 ++++++++++++++++---------
>  drivers/gpu/drm/meson/meson_osd_afbcd.h |  1 +
>  3 files changed, 30 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
> index 80f1d439841a..b919271a6e50 100644
> --- a/drivers/gpu/drm/meson/meson_drv.c
> +++ b/drivers/gpu/drm/meson/meson_drv.c
> @@ -385,10 +385,8 @@ static void meson_drv_unbind(struct device *dev)
>  	free_irq(priv->vsync_irq, drm);
>  	drm_dev_put(drm);
>  
> -	if (priv->afbcd.ops) {
> -		priv->afbcd.ops->reset(priv);
> -		meson_rdma_free(priv);
> -	}
> +	if (priv->afbcd.ops)
> +		priv->afbcd.ops->exit(priv);
>  }
>  
>  static const struct component_master_ops meson_drv_master_ops = {
> diff --git a/drivers/gpu/drm/meson/meson_osd_afbcd.c b/drivers/gpu/drm/meson/meson_osd_afbcd.c
> index ffc6b584dbf8..0cdbe899402f 100644
> --- a/drivers/gpu/drm/meson/meson_osd_afbcd.c
> +++ b/drivers/gpu/drm/meson/meson_osd_afbcd.c
> @@ -79,11 +79,6 @@ static bool meson_gxm_afbcd_supported_fmt(u64 modifier, uint32_t format)
>  	return meson_gxm_afbcd_pixel_fmt(modifier, format) >= 0;
>  }
>  
> -static int meson_gxm_afbcd_init(struct meson_drm *priv)
> -{
> -	return 0;
> -}
> -
>  static int meson_gxm_afbcd_reset(struct meson_drm *priv)
>  {
>  	writel_relaxed(VIU_SW_RESET_OSD1_AFBCD,
> @@ -93,6 +88,16 @@ static int meson_gxm_afbcd_reset(struct meson_drm *priv)
>  	return 0;
>  }
>  
> +static int meson_gxm_afbcd_init(struct meson_drm *priv)
> +{
> +	return 0;
> +}
> +
> +static void meson_gxm_afbcd_exit(struct meson_drm *priv)
> +{
> +	meson_gxm_afbcd_reset(priv);
> +}
> +
>  static int meson_gxm_afbcd_enable(struct meson_drm *priv)
>  {
>  	writel_relaxed(FIELD_PREP(OSD1_AFBCD_ID_FIFO_THRD, 0x40) |
> @@ -172,6 +177,7 @@ static int meson_gxm_afbcd_setup(struct meson_drm *priv)
>  
>  struct meson_afbcd_ops meson_afbcd_gxm_ops = {
>  	.init = meson_gxm_afbcd_init,
> +	.exit = meson_gxm_afbcd_exit,
>  	.reset = meson_gxm_afbcd_reset,
>  	.enable = meson_gxm_afbcd_enable,
>  	.disable = meson_gxm_afbcd_disable,
> @@ -269,6 +275,18 @@ static bool meson_g12a_afbcd_supported_fmt(u64 modifier, uint32_t format)
>  	return meson_g12a_afbcd_pixel_fmt(modifier, format) >= 0;
>  }
>  
> +static int meson_g12a_afbcd_reset(struct meson_drm *priv)
> +{
> +	meson_rdma_reset(priv);
> +
> +	meson_rdma_writel_sync(priv, VIU_SW_RESET_G12A_AFBC_ARB |
> +			       VIU_SW_RESET_G12A_OSD1_AFBCD,
> +			       VIU_SW_RESET);
> +	meson_rdma_writel_sync(priv, 0, VIU_SW_RESET);
> +
> +	return 0;
> +}
> +
>  static int meson_g12a_afbcd_init(struct meson_drm *priv)
>  {
>  	int ret;
> @@ -286,16 +304,10 @@ static int meson_g12a_afbcd_init(struct meson_drm *priv)
>  	return 0;
>  }
>  
> -static int meson_g12a_afbcd_reset(struct meson_drm *priv)
> +static void meson_g12a_afbcd_exit(struct meson_drm *priv)
>  {
> -	meson_rdma_reset(priv);
> -
> -	meson_rdma_writel_sync(priv, VIU_SW_RESET_G12A_AFBC_ARB |
> -			       VIU_SW_RESET_G12A_OSD1_AFBCD,
> -			       VIU_SW_RESET);
> -	meson_rdma_writel_sync(priv, 0, VIU_SW_RESET);
> -
> -	return 0;
> +	meson_g12a_afbcd_reset(priv);
> +	meson_rdma_free(priv);
>  }
>  
>  static int meson_g12a_afbcd_enable(struct meson_drm *priv)
> @@ -380,6 +392,7 @@ static int meson_g12a_afbcd_setup(struct meson_drm *priv)
>  
>  struct meson_afbcd_ops meson_afbcd_g12a_ops = {
>  	.init = meson_g12a_afbcd_init,
> +	.exit = meson_g12a_afbcd_exit,
>  	.reset = meson_g12a_afbcd_reset,
>  	.enable = meson_g12a_afbcd_enable,
>  	.disable = meson_g12a_afbcd_disable,
> diff --git a/drivers/gpu/drm/meson/meson_osd_afbcd.h b/drivers/gpu/drm/meson/meson_osd_afbcd.h
> index 5e5523304f42..e77ddeb6416f 100644
> --- a/drivers/gpu/drm/meson/meson_osd_afbcd.h
> +++ b/drivers/gpu/drm/meson/meson_osd_afbcd.h
> @@ -14,6 +14,7 @@
>  
>  struct meson_afbcd_ops {
>  	int (*init)(struct meson_drm *priv);
> +	void (*exit)(struct meson_drm *priv);
>  	int (*reset)(struct meson_drm *priv);
>  	int (*enable)(struct meson_drm *priv);
>  	int (*disable)(struct meson_drm *priv);
> 

Acked-by: Neil Armstrong <narmstrong at baylibre.com>

Thanks for fixing this

Neil



From jbrunet at baylibre.com  Mon Jan  3 04:40:28 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 03 Jan 2022 13:40:28 +0100
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate
 calculation is described using the common clock code. Also added S4 chip
 uart Compatible.
In-Reply-To: <20211230102110.3861-5-yu.tu@amlogic.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
Message-ID: <1jfsq57wym.fsf@starbuckisacylon.baylibre.com>


On Thu 30 Dec 2021 at 18:21, Yu Tu <yu.tu at amlogic.com> wrote:

> Using the common Clock code to describe the UART baud rate clock makes
> it easier for the UART driver to be compatible with the baud rate
> requirements of the UART IP on different meson chips
>
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>  drivers/tty/serial/Kconfig      |   1 +
>  drivers/tty/serial/meson_uart.c | 311 ++++++++++++++++++++++++++------
>  2 files changed, 257 insertions(+), 55 deletions(-)
>
> diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
> index 780908d43557..32e238173036 100644
> --- a/drivers/tty/serial/Kconfig
> +++ b/drivers/tty/serial/Kconfig
> @@ -198,6 +198,7 @@ config SERIAL_KGDB_NMI
>  config SERIAL_MESON
>  	tristate "Meson serial port support"
>  	depends on ARCH_MESON
> +	depends on COMMON_CLK
>  	select SERIAL_CORE
>  	help
>  	  This enables the driver for the on-chip UARTs of the Amlogic
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 99efe62a1507..07eb1f40aaaa 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -6,6 +6,7 @@
>   */
>  
>  #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>  #include <linux/console.h>
>  #include <linux/delay.h>
>  #include <linux/init.h>
> @@ -65,9 +66,7 @@
>  #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>  
>  /* AML_UART_REG5 bits */
> -#define AML_UART_BAUD_MASK		0x7fffff
>  #define AML_UART_BAUD_USE		BIT(23)
> -#define AML_UART_BAUD_XTAL		BIT(24)
>  
>  #define AML_UART_PORT_NUM		12
>  #define AML_UART_PORT_OFFSET		6
> @@ -76,6 +75,21 @@
>  #define AML_UART_POLL_USEC		5
>  #define AML_UART_TIMEOUT_USEC		10000
>  
> +struct meson_uart_data {
> +	struct uart_port	port;
> +	struct clk		*pclk;
> +	struct clk		*baud_clk;
> +	struct clk_divider	baud_div;
> +	struct clk_mux		use_xtal_mux;
> +	struct clk_mux		xtal_clk_sel_mux;
> +	struct clk_mux		xtal2_clk_sel_mux;
> +	struct clk_fixed_factor	xtal_div2;
> +	struct clk_fixed_factor	xtal_div3;
> +	struct clk_fixed_factor	clk81_div4;

Keeping all these internal elements around is not useful since they are
registered using devm_

> +	bool			no_clk81_input;

What is this ?

> +	bool			has_xtal_clk_sel;
> +};
> +
>  static struct uart_driver meson_uart_driver;
>  
>  static struct uart_port *meson_ports[AML_UART_PORT_NUM];
> @@ -270,14 +284,11 @@ static void meson_uart_reset(struct uart_port *port)
>  static int meson_uart_startup(struct uart_port *port)
>  {
>  	u32 val;
> -	int ret = 0;
> +	int ret;
>  
> -	val = readl(port->membase + AML_UART_CONTROL);
> -	val |= AML_UART_CLEAR_ERR;
> -	writel(val, port->membase + AML_UART_CONTROL);
> -	val &= ~AML_UART_CLEAR_ERR;
> -	writel(val, port->membase + AML_UART_CONTROL);
> +	meson_uart_reset(port);
>  
> +	val = readl(port->membase + AML_UART_CONTROL);
>  	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>  	writel(val, port->membase + AML_UART_CONTROL);
>  
> @@ -295,19 +306,17 @@ static int meson_uart_startup(struct uart_port *port)
>  
>  static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
>  {
> +	struct meson_uart_data *private_data = port->private_data;
>  	u32 val;
>  
>  	while (!meson_uart_tx_empty(port))
>  		cpu_relax();
>  
> -	if (port->uartclk == 24000000) {

This check shows that previous code assumed bit 24 was left untouched
Below you can see that GXBB and newer used the XTAL path while older
used the other

Your change makes this dynamic which is another "unexpected" change.
Please make the bit 24 mux RO to start with so the behavior remains unchanged
for older SoCs.

> -		val = ((port->uartclk / 3) / baud) - 1;
> -		val |= AML_UART_BAUD_XTAL;
> -	} else {
> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
> -	}
> +	val = readl(port->membase + AML_UART_REG5);
>  	val |= AML_UART_BAUD_USE;
>  	writel(val, port->membase + AML_UART_REG5);
> +
> +	clk_set_rate(private_data->baud_clk, baud);
>  }
>  
>  static void meson_uart_set_termios(struct uart_port *port,
> @@ -397,11 +406,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>  
>  static void meson_uart_release_port(struct uart_port *port)
>  {
> -	/* nothing to do */
> +	struct meson_uart_data *private_data = port->private_data;
> +
> +	clk_disable_unprepare(private_data->baud_clk);
> +	clk_disable_unprepare(private_data->pclk);
>  }
>  
>  static int meson_uart_request_port(struct uart_port *port)
>  {
> +	struct meson_uart_data *private_data = port->private_data;
> +	int ret;
> +
> +	ret = clk_prepare_enable(private_data->pclk);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_prepare_enable(private_data->baud_clk);
> +	if (ret) {
> +		clk_disable_unprepare(private_data->pclk);
> +		return ret;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -629,56 +654,175 @@ static struct uart_driver meson_uart_driver = {
>  	.cons		= MESON_SERIAL_CONSOLE,
>  };
>  
> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
> -						 const char *id)
> +static int meson_uart_register_clk(struct uart_port *port,
> +				   const char *name_suffix,
> +				   const struct clk_parent_data *parent_data,
> +				   unsigned int num_parents,
> +				   const struct clk_ops *ops,
> +				   struct clk_hw *hw)
>  {
> -	struct clk *clk = NULL;
> +	struct clk_init_data init = { };
> +	char clk_name[32];
>  	int ret;
>  
> -	clk = devm_clk_get(dev, id);
> -	if (IS_ERR(clk))
> -		return clk;
> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
> +		 name_suffix);
>  
> -	ret = clk_prepare_enable(clk);
> -	if (ret) {
> -		dev_err(dev, "couldn't enable clk\n");
> -		return ERR_PTR(ret);
> -	}
> +	init.name = clk_name;
> +	init.ops = ops;
> +	init.flags = CLK_SET_RATE_PARENT;
> +	init.parent_data = parent_data;
> +	init.num_parents = num_parents;
> +
> +	hw->init = &init;
>  
> -	devm_add_action_or_reset(dev,
> -			(void(*)(void *))clk_disable_unprepare,
> -			clk);
> +	ret = devm_clk_hw_register(port->dev, hw);
> +	if (ret)
> +		return dev_err_probe(port->dev, ret,
> +				     "Failed to register the '%s' clock\n",
> +				     clk_name);
>  
> -	return clk;
> +	return ret;
>  }
>  
> -static int meson_uart_probe_clocks(struct platform_device *pdev,
> -				   struct uart_port *port)
> -{
> -	struct clk *clk_xtal = NULL;
> -	struct clk *clk_pclk = NULL;
> -	struct clk *clk_baud = NULL;
> +static int meson_uart_probe_clocks(struct uart_port *port,
> +				   bool register_clk81_div4)
> +{
> +	struct meson_uart_data *private_data = port->private_data;
> +	struct clk_parent_data use_xtal_mux_parents[2] = {
> +		{ .index = -1, },
> +		{ .index = -1, },
> +	};
> +	struct clk_parent_data xtal_clk_sel_mux_parents[2] = { };
> +	struct clk_parent_data xtal2_clk_sel_mux_parents[2] = { };
> +	struct clk_parent_data xtal_div_parent = { .fw_name = "xtal", };
> +	struct clk_parent_data clk81_div_parent = { .fw_name = "baud", };
> +	struct clk_parent_data baud_div_parent = { };
> +	struct clk *clk_baud, *clk_xtal;
> +	int ret;
>  
> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
> -	if (IS_ERR(clk_pclk))
> -		return PTR_ERR(clk_pclk);
> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
> +	if (IS_ERR(private_data->pclk))
> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
> +				     "Failed to get the 'pclk' clock\n");
> +
> +	clk_baud = devm_clk_get(port->dev, "baud");
> +	if (IS_ERR(clk_baud))
> +		return dev_err_probe(port->dev, PTR_ERR(clk_baud),
> +				     "Failed to get the 'baud' clock\n");
>  
> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>  	if (IS_ERR(clk_xtal))
> -		return PTR_ERR(clk_xtal);
> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
> +				     "Failed to get the 'xtal' clock\n");
> +
> +	private_data->xtal_div3.mult = 1;
> +	private_data->xtal_div3.div = 3;
> +	ret = meson_uart_register_clk(port, "xtal_div3", &xtal_div_parent,
> +				      1, &clk_fixed_factor_ops,
> +				      &private_data->xtal_div3.hw);
> +	if (ret)
> +		return ret;
>  
> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
> -	if (IS_ERR(clk_baud))
> -		return PTR_ERR(clk_baud);
> +	if (register_clk81_div4) {

Clock dividers represent HW elements. The presence of an HW element cannot
dependent on the current of the input clocks. There is no way this is right

> +		private_data->clk81_div4.mult = 1;
> +		private_data->clk81_div4.div = 4;
> +		ret = meson_uart_register_clk(port, "clk81_div4",
> +					      &clk81_div_parent, 1,
> +					      &clk_fixed_factor_ops,
> +					      &private_data->clk81_div4.hw);
> +		if (ret)
> +			return ret;
> +
> +		use_xtal_mux_parents[0].hw = &private_data->clk81_div4.hw;

This is only going to be used on meson8 and older. Worst case it should depend
on this compatible but I don't think this would be right here.

IMO, this shows that the UART "baud" input was actually fed by a
derivation of "fclk_div4" instead of "clk_81" on these older SoCs.

So instead of registering what I suspect to be a fake element, the
meson8 clock controller driver and DT should be fixed a this should go away.

> +	}
>  
> -	port->uartclk = clk_get_rate(clk_baud);
> +	if (private_data->has_xtal_clk_sel) {
> +		private_data->xtal_div2.mult = 1;
> +		private_data->xtal_div2.div = 2;
> +		ret = meson_uart_register_clk(port, "xtal_div2",
> +					      &xtal_div_parent, 1,
> +					      &clk_fixed_factor_ops,
> +					      &private_data->xtal_div2.hw);
> +		if (ret)
> +			return ret;
> +
> +		xtal_clk_sel_mux_parents[0].hw = &private_data->xtal_div3.hw;
> +		xtal_clk_sel_mux_parents[1].fw_name = "xtal";
> +
> +		private_data->xtal_clk_sel_mux.reg = port->membase + AML_UART_REG5;
> +		private_data->xtal_clk_sel_mux.mask = 0x1;
> +		private_data->xtal_clk_sel_mux.shift = 26;
> +		private_data->xtal_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
> +		ret = meson_uart_register_clk(port, "xtal_clk_sel",
> +					      xtal_clk_sel_mux_parents,
> +					      ARRAY_SIZE(xtal_clk_sel_mux_parents),
> +					      &clk_mux_ops,
> +					      &private_data->xtal_clk_sel_mux.hw);
> +		if (ret)
> +			return ret;
> +
> +		xtal2_clk_sel_mux_parents[0].hw = &private_data->xtal_clk_sel_mux.hw;
> +		xtal2_clk_sel_mux_parents[1].hw = &private_data->xtal_div2.hw;
> +
> +		private_data->xtal2_clk_sel_mux.reg = port->membase + AML_UART_REG5;
> +		private_data->xtal2_clk_sel_mux.mask = 0x1;
> +		private_data->xtal2_clk_sel_mux.shift = 27;
> +		private_data->xtal2_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
> +		ret = meson_uart_register_clk(port, "xtal2_clk_sel",
> +					      xtal2_clk_sel_mux_parents,
> +					      ARRAY_SIZE(xtal2_clk_sel_mux_parents),
> +					      &clk_mux_ops,
> +					      &private_data->xtal2_clk_sel_mux.hw);
> +		if (ret)
> +			return ret;
> +
> +		use_xtal_mux_parents[1].hw = &private_data->xtal2_clk_sel_mux.hw;
> +	} else {
> +		use_xtal_mux_parents[1].hw = &private_data->xtal_div3.hw;

Well the above is a bit over-complicated. If I summarize: 

GXBB and older used a fixed divider of 3. Bits 26 and 27 read
0 according to the documentation.

Chips after GXBB have 2 configurable divider of 2 and 3. bits 26 and 27
selects which of these dividers is used.

So the above could be replaced with a single divider covering bits 26 and 27
with the following divider table { 2, 2, 1, 3 }. The divider should use
RO ops and not have CLK_SET_RATE_PARENT. It can be used for all chips
variant like this, including the older ones.

The only information you need to carry if whether or not you want to
make this divider modifiable. This means using the dt data to store
clk_div_ops or clk_div_ro_ops pointer.

To avoid changing the behavior of the older platforms in this patch, I would
suggest to make everything use clk_div_ro_ops first, and make another
patch to use clk_div_ops if necessary.


> +	}
> +
> +	private_data->use_xtal_mux.reg = port->membase + AML_UART_REG5;
> +	private_data->use_xtal_mux.mask = 0x1;
> +	private_data->use_xtal_mux.shift = 24;
> +	private_data->use_xtal_mux.flags = CLK_MUX_ROUND_CLOSEST;
> +	ret = meson_uart_register_clk(port, "use_xtal", use_xtal_mux_parents,
> +				      ARRAY_SIZE(use_xtal_mux_parents),
> +				      &clk_mux_ops,

Use RO ops here to start with.
You can make this writable with another patch explicitly describing the change.

> +				      &private_data->use_xtal_mux.hw);
> +	if (ret)
> +		return ret;
> +
> +	baud_div_parent.hw = &private_data->use_xtal_mux.hw;
> +
> +	private_data->baud_div.reg = port->membase + AML_UART_REG5;
> +	private_data->baud_div.shift = 0;
> +	private_data->baud_div.width = 23;
> +	private_data->baud_div.flags = CLK_DIVIDER_ROUND_CLOSEST;
> +	ret = meson_uart_register_clk(port, "baud_div",
> +				      &baud_div_parent, 1,
> +				      &clk_divider_ops,
> +				      &private_data->baud_div.hw);
> +	if (ret)
> +		return ret;
> +
> +	private_data->baud_clk = devm_clk_hw_get_clk(port->dev,
> +						     &private_data->baud_div.hw,
> +						     "baud_rate");

There is a problem with this function in CCF. It will pin the driver to
itself, making it unremovable. It is an ongoing topic. For now, just use
"hw->clk" to get the struct *clk.

> +	if (IS_ERR(private_data->baud_clk))
> +		return dev_err_probe(port->dev,

I don't think anything can defer here, so dev_err_probe() is not
necessary I think

> +				     PTR_ERR(private_data->baud_clk),
> +				     "Failed to request the 'baud_rate' clock\n");
>  
>  	return 0;
>  }
>  
>  static int meson_uart_probe(struct platform_device *pdev)
>  {
> +	struct meson_uart_data *private_data;
>  	struct resource *res_mem, *res_irq;
> +	struct clk *clk_baud, *clk_xtal;
> +	bool register_clk81_div4;
>  	struct uart_port *port;
>  	int ret = 0;
>  	int id = -1;
> @@ -711,18 +855,37 @@ static int meson_uart_probe(struct platform_device *pdev)
>  		return -EBUSY;
>  	}
>  
> -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
> -	if (!port)
> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
> +				    GFP_KERNEL);
> +	if (!private_data)
>  		return -ENOMEM;
>  
> +	if (device_get_match_data(&pdev->dev))
> +		private_data->has_xtal_clk_sel = true;
> +
> +	private_data->pclk = devm_clk_get(&pdev->dev, "pclk");
> +	if (IS_ERR(private_data->pclk))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(private_data->pclk),
> +				     "Failed to get the 'pclk' clock\n");
> +
> +	clk_baud = devm_clk_get(&pdev->dev, "baud");
> +	if (IS_ERR(clk_baud))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk_baud),
> +				     "Failed to get the 'baud' clock\n");
> +
> +	clk_xtal = devm_clk_get(&pdev->dev, "xtal");
> +	if (IS_ERR(clk_xtal))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk_xtal),
> +				     "Failed to get the 'xtal' clock\n");
> +

This is second time you call devm_clk_get() on these clocks. One
instance has to go away

> +	register_clk81_div4 = clk_get_rate(clk_xtal) != clk_get_rate(clk_baud);
> +

The above is a ugly way to distinguish the meson8 (32bit) SoC family
from the rest. This definitely not the way to achieve it.

The right is the compatible data but here I think it is not
necessary. The clock input should be fixed.

> +	port = &private_data->port;
> +
>  	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>  	if (IS_ERR(port->membase))
>  		return PTR_ERR(port->membase);
>  
> -	ret = meson_uart_probe_clocks(pdev, port);
> -	if (ret)
> -		return ret;
> -
>  	port->iotype = UPIO_MEM;
>  	port->mapbase = res_mem->start;
>  	port->mapsize = resource_size(res_mem);
> @@ -735,6 +898,12 @@ static int meson_uart_probe(struct platform_device *pdev)
>  	port->x_char = 0;
>  	port->ops = &meson_uart_ops;
>  	port->fifosize = 64;
> +	port->uartclk = clk_get_rate(clk_baud);
> +	port->private_data = private_data;
> +
> +	ret = meson_uart_probe_clocks(port, register_clk81_div4);
> +	if (ret)
> +		return ret;
>  
>  	meson_ports[pdev->id] = port;
>  	platform_set_drvdata(pdev, port);
> @@ -761,10 +930,42 @@ static int meson_uart_remove(struct platform_device *pdev)
>  }
>  
>  static const struct of_device_id meson_uart_dt_match[] = {
> -	{ .compatible = "amlogic,meson6-uart" },
> -	{ .compatible = "amlogic,meson8-uart" },
> -	{ .compatible = "amlogic,meson8b-uart" },
> -	{ .compatible = "amlogic,meson-gx-uart" },
> +	{
> +		.compatible = "amlogic,meson6-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson8-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson8b-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson-gxbb-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson-gxl-uart",
> +		.data = (void *)true,
> +	},
> +	{
> +		.compatible = "amlogic,meson-g12a-uart",
> +		.data = (void *)true,
> +	},
> +	{
> +		.compatible = "amlogic,meson-s4-uart",
> +		.data = (void *)true,
> +	},
> +	/*
> +	 * deprecated, don't use anymore because it doesn't differentiate
> +	 * between GXBB and GXL which have different revisions of the UART IP.
> +	 */
> +	{
> +		.compatible = "amlogic,meson-gx-uart",
> +		.data = (void *)false,
> +	},
>  	{ /* sentinel */ },
>  };
>  MODULE_DEVICE_TABLE(of, meson_uart_dt_match);



From jbrunet at baylibre.com  Mon Jan  3 05:50:06 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 03 Jan 2022 14:50:06 +0100
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate
 calculation is described using the common clock code. Also added S4 chip
 uart Compatible.
In-Reply-To: <7278bace-a2b9-0cfc-55b3-c19311e3352e@amlogic.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
 <CAFBinCCL-QaeSRCLzfyNXcRQZ7YC1D85rP2y4OGkAjCmQEqGgQ@mail.gmail.com>
 <3e1e40aa-7865-0f7a-5772-e2ad96c8141d@amlogic.com>
 <CAFBinCB2nF0TwRE1uJ4UTB_avcqRBfOHR1CDSe29dB1o-YjEHQ@mail.gmail.com>
 <7278bace-a2b9-0cfc-55b3-c19311e3352e@amlogic.com>
Message-ID: <1jbl0s9b1w.fsf@starbuckisacylon.baylibre.com>


On Sat 01 Jan 2022 at 21:30, Yu Tu <yu.tu at amlogic.com> wrote:

> Hi Martin,
>     Thank you very much for your reply.
>
> On 2021/12/31 23:32, Martin Blumenstingl wrote:
>> [ EXTERNAL EMAIL ]
>> On Fri, Dec 31, 2021 at 12:24 PM Yu Tu <yu.tu at amlogic.com> wrote:
>> [...]
>>>>>    static int meson_uart_request_port(struct uart_port *port)
>>>>>    {
>>>>> +       struct meson_uart_data *private_data = port->private_data;
>>>>> +       int ret;
>>>>> +
>>>>> +       ret = clk_prepare_enable(private_data->pclk);
>>>>> +       if (ret)
>>>>> +               return ret;
>>>>> +
>>>>> +       ret = clk_prepare_enable(private_data->baud_clk);
>>>>> +       if (ret) {
>>>>> +               clk_disable_unprepare(private_data->pclk);
>>>>> +               return ret;
>>>>> +       }
>>>> This code is from my original suggestion - and I had a doubt there
>>>> which I forgot to add as a comment originally:
>>>> Can you confirm that accessing the UART controller registers works
>>>> even when "pclk" is turned off?
>>>> I am asking this because the common clock framework can access the
>>>> clocks at any time.
>>>> And I have seen SoCs which would hang when trying to access a module's
>>>> registers while the module's pclk is turned off.
>>> On all meson platforms, the default pclk for all UART is turned on
>>> during the u-boot phase. When registering uart pclk in the kernel phase,
>>> the CLK_IGNORE_UNUSED flag is added. So the real shutdown is when the
>>> standby goes down, the parent clk shuts down.
>> Interesting, thanks for sharing that u-boot turns these clocks on.
>> Let's say someone wanted to make u-boot save power and turn off all
>> UART clocks except the one for uart_AO (where we typically connect the
>> serial console).
>> In that case the pclk of uart_C (just to choose an example here) is
>> turned off. Would there be a problem then accessing the registers of
>> uart_C before clk_prepare_enable is called?
> The way you describe it, it does hang. This would not be recommended on
> actual projects.
>
> At present, AmLogic chips are older than S4 Soc, and we have no way to deal
> with this problem. We have to tell customers not to use it in this way?
> Customers rarely use it in real projects.On the S4 SOC we will use a clock
> like the UART pclk to control the shutdown using two registers, one safe
> (need to operate in EL3) and one normal (EL1). It will only be closed if
> both registers are closed. This mainly prevents misoperation.
>
> With your experience, I'd like to know how you deal with this kind of
> problem.

Relying on the CLK_IGNORE_UNUSED and the boot loader is unsafe.
As Martin is suggesting, the driver must ensure pclk is on before
touching any register.

This was done in the probe before in probe before your change which
seems safe but maybe not optimal.

Again, If you wish to optimize that, please do so in another dedicated
change so we can discuss it and make sure it is still safe

>> [...]
>>>>>           port->fifosize = 64;
>>>> commit 27d44e05d7b85d ("tty: serial: meson: retrieve port FIFO size
>>>> from DT") [0] from May 2021 has changed this line to:
>>>>     port->fifosize = fifosize;
>>>> So your patch currently does not apply to linux-next (or even Linus'
>>>> mainline tree).
>>>>
>>> So do I need to wait for [0] patch merged before I can continue to make
>>> changes ?
>> These changes are already merged.
>> 
>>> What can I do before?
>> You should base your changes on top of the tty.git/tty-next branch [1]
>> where Greg (the maintainer of this tree) will pick up the patches once
>> they are good (got enough Acked-by/Reviewed-by, etc.).
>> I suspect that you based your changes on an older or stable kernel
>> version (let's say 5.10). New functionality should always get into the
>> -next tree where various auto-build robots will compile-test the
>> changes and we even have Kernel CI where changes are tested on real
>> hardware (BayLibre even maintains Amlogic boards in their Kernel CI
>> labs). Let's say Amlogic updates to Linux 5.17 next year then the
>> patches are already included in that kernel version - instead of being
>> only available in Linux 5.10.
>> 
> I'm sorry, I did branch confirm there was a mistake, I have corrected.
>> Best regards,
>> Martin
>> 
>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/log/?h=tty-next
>> 



From narmstrong at baylibre.com  Mon Jan  3 06:43:38 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 15:43:38 +0100
Subject: [PATCH 0/3] ARM: dts: meson: fix UART device-tree schema
 validation
In-Reply-To: <CAFBinCC7iSKjZ=U5PN5FKF9js77tvaQBdWdHMPp_y+u+asaeoA@mail.gmail.com>
References: <20211227180026.4068352-1-martin.blumenstingl@googlemail.com>
 <CAFBinCC7iSKjZ=U5PN5FKF9js77tvaQBdWdHMPp_y+u+asaeoA@mail.gmail.com>
Message-ID: <2c5311fd-187a-d129-4e15-e83e49c14c09@baylibre.com>

Hi,

On 31/12/2021 16:38, Martin Blumenstingl wrote:
> Hi Neil,
> 
> On Mon, Dec 27, 2021 at 7:00 PM Martin Blumenstingl
> <martin.blumenstingl at googlemail.com> wrote:
>>
>> Hello,
>>
>> here are three UART device-tree schema related fixes for the 32-bit
>> ARM SoCs.
>> These patches don't fix any functionality which is why linux-stable
>> is not Cc'ed on them.
> The statement above still stands.
> I would like you to apply this series to a 5.17-fixes branch because
> of a change from the tty.git tree which will be going into 5.17 to
> drop the "amlogic,meson-uart" earlycon handling: [0]
> 
> To make it clear: Backporting this series to kernels older than 5.17
> won't break or fix anything.
> Only 5.17 and newer will need this due to a change [0] in the tty.git
> tree. Without the patches from this series the 32-bit SoCs won't have
> earlycon support in 5.17.

OK, I'll submit it as fixes for for 5.17

Neil

> 
> 
> Thank you!
> Martin
> 
> 
> [0] https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/commit/?h=tty-next&id=ad234e2bac274a43c9fa540bde8cd9f0c627b71f
> 
> _______________________________________________
> linux-amlogic mailing list
> linux-amlogic at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-amlogic
> 



From narmstrong at baylibre.com  Mon Jan  3 06:59:33 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 15:59:33 +0100
Subject: [PATCH V3 1/6] tty: serial: meson: Drop the legacy compatible
 strings and clock code
In-Reply-To: <CAFBinCA2V=sx95Q=+4nLDXFK1Os11XVWtK8KauxixVwYXLUz1Q@mail.gmail.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-2-yu.tu@amlogic.com>
 <CAFBinCCwjS36ss_4sU+o9m8gEprFsVZbqcxgpQxczTNohZqFdA@mail.gmail.com>
 <a296e666-368b-4cd5-427e-30fc66a15b49@amlogic.com>
 <CAFBinCA2V=sx95Q=+4nLDXFK1Os11XVWtK8KauxixVwYXLUz1Q@mail.gmail.com>
Message-ID: <3865f01c-83f7-a69d-6835-c26f662629b7@baylibre.com>

Hi Greg,

Martin just saw this patch was applied, but the serie wasn't reviewed enough and it will break
earlycon support on the ARMv7 Amlogic SoCs fore 5.17.

Anyway, I'll push the corresponding DT fixes for 5.17-rc1.

Would it be possible we also receive the notification when those patches are applied ?
Maybe a MAINTAINERS entry is missing so we can receive them ?

It would help me track those TTY and USB patches more easily.

Thanks !

Neil

On 31/12/2021 16:35, Martin Blumenstingl wrote:
> On Fri, Dec 31, 2021 at 11:27 AM Yu Tu <yu.tu at amlogic.com> wrote:
> [...]
>>>> -/* Legacy bindings, should be removed when no more used */
>>>> -OF_EARLYCON_DECLARE(meson, "amlogic,meson-uart",
>>>> -                   meson_serial_early_console_setup);
>>> This part is still needed as long as above series is not merged yet.
>>> If we remove this then earlycon will stop working on the 32-bit SoCs
>>> unless [0] is merged.
>>>
>>> All other code below - except the of_device_id entry - can still be
>>> removed since meson8.dtsi and meson8b.dtsi are using the non-legacy
>>> clocks already.
>>>
>>> Sorry for only noticing this now.
>>>
>> I will add it back in the next patch and delete it after your submission
>> is merged.
> I have just seen that Greg has already added this patch to the tty-next tree [1]
> In this case there's nothing to do on your end - I'll simply ask Neil
> to also queue my 32-bit SoC UART .dts fixes [0] for 5.17
> 
> 
> Best regards,
> Martin
> 
> 
> [0] https://patchwork.kernel.org/project/linux-amlogic/cover/20211227180026.4068352-1-martin.blumenstingl at googlemail.com/
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/commit/?h=tty-next&id=ad234e2bac274a43c9fa540bde8cd9f0c627b71f
> 



From narmstrong at baylibre.com  Mon Jan  3 07:13:44 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 16:13:44 +0100
Subject: [GIT PULL] amlogic fixes for v5.17-rc
Message-ID: <7e40328b-6645-4343-3050-73dcfb2cefcb@baylibre.com>

Hi,

Here's a couple of DT fixes for v5.17-rc1, they fix the UART compatibles of
the ARMv7 Amlogic SoCs and by the way keep earlycon working after [1] has been
applied by greg in the tty branch for 5.17.

I know it's early for 5.17-rc1, but at least it's in the pipe.

I based the changes on your dt-5.17 tag pushed to linus for 5.17-rc1,
if necessary I can rebase on v5.16-rcX.

Neil

[1] https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/commit/?h=tty-next&id=ad234e2bac274a43c9fa540bde8cd9f0c627b71f

The following changes since commit 8b0c59c622dc4dab970ec63264fb5b152944ac80:

  Revert "ARM: dts: BCM5301X: define RTL8365MB switch on Asus RT-AC88U" (2021-12-23 00:18:45 +0100)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git tags/amlogic-fixes-v5.17-rc

for you to fetch changes up to 7a31a29b35386b6d6aa622d68acd31739a3a8ac5:

  ARM: dts: meson8b: Fix the UART device-tree schema validation (2022-01-03 15:49:56 +0100)

----------------------------------------------------------------
Amlogic fixes for v5.17-rc
- meson6/meson8/meson8b UART compatible fixup to fix earlycon

----------------------------------------------------------------
Martin Blumenstingl (3):
      ARM: dts: meson: Fix the UART compatible strings
      ARM: dts: meson8: Fix the UART device-tree schema validation
      ARM: dts: meson8b: Fix the UART device-tree schema validation

 arch/arm/boot/dts/meson.dtsi   |  8 ++++----
 arch/arm/boot/dts/meson8.dtsi  | 24 ++++++++++++------------
 arch/arm/boot/dts/meson8b.dtsi | 24 ++++++++++++------------
 3 files changed, 28 insertions(+), 28 deletions(-)


From narmstrong at baylibre.com  Mon Jan  3 07:18:09 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 16:18:09 +0100
Subject: [PATCH] arm64: dts: meson-sm1: add spdifin spdifout nodes
In-Reply-To: <20211215030236.340841-1-art@khadas.com>
References: <20211215030236.340841-1-art@khadas.com>
Message-ID: <67d8cefc-d7c7-daba-bfe3-5935ded52beb@baylibre.com>

On 15/12/2021 04:02, Artem Lapkin wrote:
> Add spdifin spdifout nodes for Amlogic SM1 SoCs.
> 
> Signed-off-by: Artem Lapkin <art at khadas.com>
> ---
> 
> SPDIF IN and SPDIF OUT both tested and works fine for VIM3L (meson-sm1)
> same as for VIM3 (meson-g12)
> 
> SPDIF in and SPDIF OUT both pins available via GPIO header (SPDIF_OUT PIN
> 13 spdif_ao_out_pins and SPDIF_IN PIN 35 - same PWM_F spdif_in_h_pins)
> 
> https://lore.kernel.org/linux-arm-kernel/1jtuhwvqxa.fsf at starbuckisacylon.baylibre.com/t/
> 
> ALSA spdifin test example
> =========================
> 
> # arecord -fS16_LE -r48000 -c2 -Dplug:spdifin
> 
> # cat .asoundrc
> pcm.spdifin {
> type iec958
> slave {
> pcm "hw:0,1"
> format IEC958_SUBFRAME_LE
> }
> }
> 
> DT sound card configs for testing
> =================================
> 
> &spdifout {
>     pinctrl-0 = <&spdif_ao_out_pins>;
>     pinctrl-names = "default";
>     status = "okay";
> };
> 
> &spdifin {
>     pinctrl-0 = <&spdif_in_h_pins>;
>     pinctrl-names = "default";
>     status = "okay";
> };
> 
> ...
>     spdif_dit: audio-codec-1 {
> 	#sound-dai-cells = <0>;
> 	compatible = "linux,spdif-dit";
> 	status = "okay";
> 	sound-name-prefix = "DIT";
>     };
> 
>     spdif_dir: audio-codec-2 {
> 	#sound-dai-cells = <0>;
> 	compatible = "linux,spdif-dir";
> 	status = "okay";
> 	sound-name-prefix = "DIR";
>     };
> ...
> 	audio-routing = ...
> 		"TODDR_B IN 3", "SPDIFIN Capture",
> 		"SPDIFOUT IN 0", "FRDDR_A OUT 3";
> 
> ...
> 	dai-link-10 {
> 	    sound-dai = <&spdifout>;
> 
> 	    codec-0 {
> 		sound-dai = <&spdif_dit>;
> 	    };
> 	};
> 
> 	/* spdif or toslink interface */
> 	dai-link-11 {
> 	    sound-dai = <&spdifin>;
> 
> 	    codec-0 {
> 		sound-dai = <&spdif_dir>;
> 	    };
> 	};
> ...
> 
> ---
>  arch/arm64/boot/dts/amlogic/meson-sm1.dtsi | 27 ++++++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
> index 3d8b1f4f2001..1e0adf259d61 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
> @@ -356,6 +356,33 @@ tdmin_lb: audio-controller at 3c0 {
>  			status = "disabled";
>  		};
>  
> +		spdifin: audio-controller at 400 {
> +			compatible = "amlogic,g12a-spdifin",
> +			"amlogic,axg-spdifin";
> +			reg = <0x0 0x400 0x0 0x30>;
> +			#sound-dai-cells = <0>;
> +			sound-name-prefix = "SPDIFIN";
> +			interrupts = <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
> +			clocks = <&clkc_audio AUD_CLKID_SPDIFIN>,
> +			<&clkc_audio AUD_CLKID_SPDIFIN_CLK>;
> +			clock-names = "pclk", "refclk";
> +			resets = <&clkc_audio AUD_RESET_SPDIFIN>;
> +			status = "disabled";
> +		};
> +
> +		spdifout: audio-controller at 480 {
> +			compatible = "amlogic,g12a-spdifout",
> +			"amlogic,axg-spdifout";
> +			reg = <0x0 0x480 0x0 0x50>;
> +			#sound-dai-cells = <0>;
> +			sound-name-prefix = "SPDIFOUT";
> +			clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
> +			<&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
> +			clock-names = "pclk", "mclk";
> +			resets = <&clkc_audio AUD_RESET_SPDIFOUT>;
> +			status = "disabled";
> +		};
> +
>  		tdmout_a: audio-controller at 500 {
>  			compatible = "amlogic,sm1-tdmout";
>  			reg = <0x0 0x500 0x0 0x40>;
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>

Thanks,
Neil


From gregkh at linuxfoundation.org  Mon Jan  3 07:19:47 2022
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 3 Jan 2022 16:19:47 +0100
Subject: [PATCH V3 1/6] tty: serial: meson: Drop the legacy compatible
 strings and clock code
In-Reply-To: <3865f01c-83f7-a69d-6835-c26f662629b7@baylibre.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-2-yu.tu@amlogic.com>
 <CAFBinCCwjS36ss_4sU+o9m8gEprFsVZbqcxgpQxczTNohZqFdA@mail.gmail.com>
 <a296e666-368b-4cd5-427e-30fc66a15b49@amlogic.com>
 <CAFBinCA2V=sx95Q=+4nLDXFK1Os11XVWtK8KauxixVwYXLUz1Q@mail.gmail.com>
 <3865f01c-83f7-a69d-6835-c26f662629b7@baylibre.com>
Message-ID: <YdMUEzStFf99EeQ5@kroah.com>

A: http://en.wikipedia.org/wiki/Top_post
Q: Were do I find info about this thing called top-posting?
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing in e-mail?

A: No.
Q: Should I include quotations after my reply?

http://daringfireball.net/2007/07/on_top

On Mon, Jan 03, 2022 at 03:59:33PM +0100, Neil Armstrong wrote:
> Hi Greg,
> 
> Martin just saw this patch was applied, but the serie wasn't reviewed enough and it will break
> earlycon support on the ARMv7 Amlogic SoCs fore 5.17.

Ok, what should I revert?

> Anyway, I'll push the corresponding DT fixes for 5.17-rc1.

How did we get out of sync here?

> Would it be possible we also receive the notification when those patches are applied ?
> Maybe a MAINTAINERS entry is missing so we can receive them ?

That would be good, so that people can review the patches.  Otherwise I
have to just guess :)

> It would help me track those TTY and USB patches more easily.

I recommend MAINTAINERS entries for drivers that are not listed and that
you care about seeing the changes for.

thanks,

greg k-h


From narmstrong at baylibre.com  Mon Jan  3 07:21:16 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 16:21:16 +0100
Subject: [RFC PATCH 6/9] arm64: dts: meson: add initial device-trees for
 A95XF3-AIR
In-Reply-To: <20211130060523.19161-7-christianshewitt@gmail.com>
References: <20211130060523.19161-1-christianshewitt@gmail.com>
 <20211130060523.19161-7-christianshewitt@gmail.com>
Message-ID: <6ff128a6-91cb-5b83-737e-e703cab81743@baylibre.com>

Hi,

On 30/11/2021 07:05, Christian Hewitt wrote:
> The CYX A95XF3-AIR is based on Amlogic S905X3 reference board
> designs and ships in multiple configurations:
> 
> ? 4GB DDR3 + 64GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
> ? 4GB DDR3 + 32GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
> ? 2GB DDR3 + 16GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
> ...
> - HDMI 2.1 video
> - S/PDIF optical output
> - AV output
> - 1x USB 2.0 OTG port
> - 1x USB 3.0 port
> - IR receiver
> - 1x micro SD card slot (internal)
> - 1x Reset/Update button (in AV jack)
> - 7-segment VFD
> - Multicolour case LED 'arc'
> 
> The device-tree with -100 suffix supports models with 10/100 Ethernet
> and with -1000 suffix supports models with Gigabit Ethernet.

I thought about this, and I think we should have:
- meson-sm1-a95xf3-air.dts for 10/100 version
- meson-sm1-a95xf3-air-gbit.dts for gigabit 10/100/1000 version

With this, I'm ok to apply the serie.

Neil

> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/Makefile          |   2 +
>  .../dts/amlogic/meson-sm1-a95xf3-air-100.dts  | 108 +++++++++++++++
>  .../dts/amlogic/meson-sm1-a95xf3-air-1000.dts | 129 ++++++++++++++++++
>  3 files changed, 239 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-100.dts
>  create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-1000.dts
> 
> diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
> index a0c1a7fbae57..e198d17f2ea8 100644
> --- a/arch/arm64/boot/dts/amlogic/Makefile
> +++ b/arch/arm64/boot/dts/amlogic/Makefile
> @@ -51,6 +51,8 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-rbox-pro.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-gxm-s912-libretech-pc.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-gxm-vega-s96.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-gxm-wetek-core2.dtb
> +dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air-100.dtb
> +dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air-1000.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-sm1-bananapi-m5.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-100.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-100.dts
> new file mode 100644
> index 000000000000..5158cc40485e
> --- /dev/null
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-100.dts
> @@ -0,0 +1,108 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2019 BayLibre SAS. All rights reserved.
> + * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
> + */
> +
> +/dts-v1/;
> +
> +#include "meson-sm1-ac2xx.dtsi"
> +#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
> +
> +/ {
> +	compatible = "cyx,a95xf3-air-100", "amlogic,sm1";
> +	model = "Shenzhen CYX Industrial Co., Ltd A95XF3-AIR";
> +
> +	sound {
> +		compatible = "amlogic,axg-sound-card";
> +		model = "A95XF3-AIR";
> +		audio-aux-devs = <&tdmout_b>;
> +		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
> +				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
> +				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
> +				"TDM_B Playback", "TDMOUT_B OUT";
> +
> +		assigned-clocks = <&clkc CLKID_MPLL2>,
> +				  <&clkc CLKID_MPLL0>,
> +				  <&clkc CLKID_MPLL1>;
> +		assigned-clock-parents = <0>, <0>, <0>;
> +		assigned-clock-rates = <294912000>,
> +				       <270950400>,
> +				       <393216000>;
> +		status = "okay";
> +
> +		dai-link-0 {
> +			sound-dai = <&frddr_a>;
> +		};
> +
> +		dai-link-1 {
> +			sound-dai = <&frddr_b>;
> +		};
> +
> +		dai-link-2 {
> +			sound-dai = <&frddr_c>;
> +		};
> +
> +		/* 8ch hdmi interface */
> +		dai-link-3 {
> +			sound-dai = <&tdmif_b>;
> +			dai-format = "i2s";
> +			dai-tdm-slot-tx-mask-0 = <1 1>;
> +			dai-tdm-slot-tx-mask-1 = <1 1>;
> +			dai-tdm-slot-tx-mask-2 = <1 1>;
> +			dai-tdm-slot-tx-mask-3 = <1 1>;
> +			mclk-fs = <256>;
> +
> +			codec {
> +				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
> +			};
> +		};
> +
> +		/* hdmi glue */
> +		dai-link-4 {
> +			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
> +
> +			codec {
> +				sound-dai = <&hdmi_tx>;
> +			};
> +		};
> +	};
> +};
> +
> +&arb {
> +	status = "okay";
> +};
> +
> +&clkc_audio {
> +	status = "okay";
> +};
> +
> +&ethmac {
> +	status = "okay";
> +	phy-handle = <&internal_ephy>;
> +	phy-mode = "rmii";
> +};
> +
> +&frddr_a {
> +	status = "okay";
> +};
> +
> +&frddr_b {
> +	status = "okay";
> +};
> +
> +&frddr_c {
> +	status = "okay";
> +};
> +
> +&tdmif_b {
> +	status = "okay";
> +};
> +
> +&tdmout_b {
> +	status = "okay";
> +};
> +
> +&tohdmitx {
> +	status = "okay";
> +};
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-1000.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-1000.dts
> new file mode 100644
> index 000000000000..c87d948fa3e6
> --- /dev/null
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-1000.dts
> @@ -0,0 +1,129 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2019 BayLibre SAS. All rights reserved.
> + * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
> + */
> +
> +/dts-v1/;
> +
> +#include "meson-sm1-ac2xx.dtsi"
> +#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
> +
> +/ {
> +	compatible = "cyx,a95xf3-air-1000", "amlogic,sm1";
> +	model = "Shenzhen CYX Industrial Co., Ltd A95XF3-AIR";
> +
> +	sound {
> +		compatible = "amlogic,axg-sound-card";
> +		model = "A95XF3-AIR";
> +		audio-aux-devs = <&tdmout_b>;
> +		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
> +				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
> +				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
> +				"TDM_B Playback", "TDMOUT_B OUT";
> +
> +		assigned-clocks = <&clkc CLKID_MPLL2>,
> +				  <&clkc CLKID_MPLL0>,
> +				  <&clkc CLKID_MPLL1>;
> +		assigned-clock-parents = <0>, <0>, <0>;
> +		assigned-clock-rates = <294912000>,
> +				       <270950400>,
> +				       <393216000>;
> +		status = "okay";
> +
> +		dai-link-0 {
> +			sound-dai = <&frddr_a>;
> +		};
> +
> +		dai-link-1 {
> +			sound-dai = <&frddr_b>;
> +		};
> +
> +		dai-link-2 {
> +			sound-dai = <&frddr_c>;
> +		};
> +
> +		/* 8ch hdmi interface */
> +		dai-link-3 {
> +			sound-dai = <&tdmif_b>;
> +			dai-format = "i2s";
> +			dai-tdm-slot-tx-mask-0 = <1 1>;
> +			dai-tdm-slot-tx-mask-1 = <1 1>;
> +			dai-tdm-slot-tx-mask-2 = <1 1>;
> +			dai-tdm-slot-tx-mask-3 = <1 1>;
> +			mclk-fs = <256>;
> +
> +			codec {
> +				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
> +			};
> +		};
> +
> +		/* hdmi glue */
> +		dai-link-4 {
> +			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
> +
> +			codec {
> +				sound-dai = <&hdmi_tx>;
> +			};
> +		};
> +	};
> +};
> +
> +&arb {
> +	status = "okay";
> +};
> +
> +&clkc_audio {
> +	status = "okay";
> +};
> +
> +&ethmac {
> +	status = "okay";
> +
> +	pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
> +	pinctrl-names = "default";
> +	phy-mode = "rgmii-txid";
> +	phy-handle = <&external_phy>;
> +
> +	rx-internal-delay-ps = <800>;
> +};
> +
> +&ext_mdio {
> +	external_phy: ethernet-phy at 0 {
> +		/* Realtek RTL8211F (0x001cc916) */
> +		reg = <0>;
> +		max-speed = <1000>;
> +
> +		reset-assert-us = <10000>;
> +		reset-deassert-us = <80000>;
> +		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
> +
> +		interrupt-parent = <&gpio_intc>;
> +		/* MAC_INTR on GPIOZ_14 */
> +		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
> +	};
> +};
> +
> +&frddr_a {
> +	status = "okay";
> +};
> +
> +&frddr_b {
> +	status = "okay";
> +};
> +
> +&frddr_c {
> +	status = "okay";
> +};
> +
> +&tdmif_b {
> +	status = "okay";
> +};
> +
> +&tdmout_b {
> +	status = "okay";
> +};
> +
> +&tohdmitx {
> +	status = "okay";
> +};
> 



From christianshewitt at gmail.com  Mon Jan  3 07:26:49 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon, 3 Jan 2022 19:26:49 +0400
Subject: [RFC PATCH 6/9] arm64: dts: meson: add initial device-trees for
 A95XF3-AIR
In-Reply-To: <6ff128a6-91cb-5b83-737e-e703cab81743@baylibre.com>
References: <20211130060523.19161-1-christianshewitt@gmail.com>
 <20211130060523.19161-7-christianshewitt@gmail.com>
 <6ff128a6-91cb-5b83-737e-e703cab81743@baylibre.com>
Message-ID: <F8463510-1955-4826-BE05-20F3B4079ED4@gmail.com>


> On 3 Jan 2022, at 7:21 pm, Neil Armstrong <narmstrong at baylibre.com> wrote:
> 
> Hi,
> 
> On 30/11/2021 07:05, Christian Hewitt wrote:
>> The CYX A95XF3-AIR is based on Amlogic S905X3 reference board
>> designs and ships in multiple configurations:
>> 
>> ? 4GB DDR3 + 64GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
>> ? 4GB DDR3 + 32GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
>> ? 2GB DDR3 + 16GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
>> ...
>> - HDMI 2.1 video
>> - S/PDIF optical output
>> - AV output
>> - 1x USB 2.0 OTG port
>> - 1x USB 3.0 port
>> - IR receiver
>> - 1x micro SD card slot (internal)
>> - 1x Reset/Update button (in AV jack)
>> - 7-segment VFD
>> - Multicolour case LED 'arc'
>> 
>> The device-tree with -100 suffix supports models with 10/100 Ethernet
>> and with -1000 suffix supports models with Gigabit Ethernet.
> 
> I thought about this, and I think we should have:
> - meson-sm1-a95xf3-air.dts for 10/100 version
> - meson-sm1-a95xf3-air-gbit.dts for gigabit 10/100/1000 version
> 
> With this, I'm ok to apply the serie.
> 
> Neil

That?s fine with me, thanks for the review. I?ll rework the patches and
send a v2 series to the list.

Christian



From narmstrong at baylibre.com  Mon Jan  3 07:29:56 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 16:29:56 +0100
Subject: [PATCH V3 1/6] tty: serial: meson: Drop the legacy compatible
 strings and clock code
In-Reply-To: <YdMUEzStFf99EeQ5@kroah.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-2-yu.tu@amlogic.com>
 <CAFBinCCwjS36ss_4sU+o9m8gEprFsVZbqcxgpQxczTNohZqFdA@mail.gmail.com>
 <a296e666-368b-4cd5-427e-30fc66a15b49@amlogic.com>
 <CAFBinCA2V=sx95Q=+4nLDXFK1Os11XVWtK8KauxixVwYXLUz1Q@mail.gmail.com>
 <3865f01c-83f7-a69d-6835-c26f662629b7@baylibre.com>
 <YdMUEzStFf99EeQ5@kroah.com>
Message-ID: <df9e472e-ac17-26ed-d820-e80d5b7b0e80@baylibre.com>

Hi Greg,
On 03/01/2022 16:19, Greg Kroah-Hartman wrote:
> A: http://en.wikipedia.org/wiki/Top_post
> Q: Were do I find info about this thing called top-posting?
> A: Because it messes up the order in which people normally read text.
> Q: Why is top-posting such a bad thing?
> A: Top-posting.
> Q: What is the most annoying thing in e-mail?
> 
> A: No.
> Q: Should I include quotations after my reply?
> 
> http://daringfireball.net/2007/07/on_to>
> On Mon, Jan 03, 2022 at 03:59:33PM +0100, Neil Armstrong wrote:
>> Hi Greg,
>>
>> Martin just saw this patch was applied, but the serie wasn't reviewed enough and it will break
>> earlycon support on the ARMv7 Amlogic SoCs fore 5.17.
> 
> Ok, what should I revert?

None, we have a fix in the pipe

> 
>> Anyway, I'll push the corresponding DT fixes for 5.17-rc1.
> 
> How did we get out of sync here?

The serie wasn't fully reviewed, and I was out of office when it was applied.

> 
>> Would it be possible we also receive the notification when those patches are applied ?
>> Maybe a MAINTAINERS entry is missing so we can receive them ?
> 
> That would be good, so that people can review the patches.  Otherwise I
> have to just guess :)

exact, I naively thought it would be matched in the:
N:      meson
entry but it seems an proper entry for drivers/tty/serial/meson_uart.c is needed.

> 
>> It would help me track those TTY and USB patches more easily.
> 
> I recommend MAINTAINERS entries for drivers that are not listed and that
> you care about seeing the changes for.

This is why we have a regex to match these.

I can submit a patch to have a proper entry if the regex is not enough/appropriate.

BTW can you point us how are selected the recipients of the notification messages you send ?

Thanks,
Neil

> 
> thanks,
> 
> greg k-h
> 



From jbrunet at baylibre.com  Mon Jan  3 07:35:23 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 03 Jan 2022 16:35:23 +0100
Subject: [PATCH] arm64: dts: meson-sm1: add spdifin spdifout nodes
In-Reply-To: <20211215030236.340841-1-art@khadas.com>
References: <20211215030236.340841-1-art@khadas.com>
Message-ID: <1jtuekrfsf.fsf@starbuckisacylon.baylibre.com>


On Wed 15 Dec 2021 at 11:02, Artem Lapkin <email2tema at gmail.com> wrote:

> Add spdifin spdifout nodes for Amlogic SM1 SoCs.
             ^ add (same in the title)

>
> Signed-off-by: Artem Lapkin <art at khadas.com>
> ---
>
> SPDIF IN and SPDIF OUT both tested and works fine for VIM3L (meson-sm1)
> same as for VIM3 (meson-g12)
>
> SPDIF in and SPDIF OUT both pins available via GPIO header (SPDIF_OUT PIN
> 13 spdif_ao_out_pins and SPDIF_IN PIN 35 - same PWM_F spdif_in_h_pins)
>
> https://lore.kernel.org/linux-arm-kernel/1jtuhwvqxa.fsf at starbuckisacylon.baylibre.com/t/
>
> ALSA spdifin test example
> =========================
>
> # arecord -fS16_LE -r48000 -c2 -Dplug:spdifin
>
> # cat .asoundrc
> pcm.spdifin {
> type iec958
> slave {
> pcm "hw:0,1"
> format IEC958_SUBFRAME_LE
> }
> }
>
> DT sound card configs for testing
> =================================
>
> &spdifout {
>     pinctrl-0 = <&spdif_ao_out_pins>;
>     pinctrl-names = "default";
>     status = "okay";
> };
>
> &spdifin {
>     pinctrl-0 = <&spdif_in_h_pins>;
>     pinctrl-names = "default";
>     status = "okay";
> };
>
> ...
>     spdif_dit: audio-codec-1 {
> 	#sound-dai-cells = <0>;
> 	compatible = "linux,spdif-dit";
> 	status = "okay";
> 	sound-name-prefix = "DIT";
>     };
>
>     spdif_dir: audio-codec-2 {
> 	#sound-dai-cells = <0>;
> 	compatible = "linux,spdif-dir";
> 	status = "okay";
> 	sound-name-prefix = "DIR";
>     };
> ...
> 	audio-routing = ...
> 		"TODDR_B IN 3", "SPDIFIN Capture",
> 		"SPDIFOUT IN 0", "FRDDR_A OUT 3";
>
> ...
> 	dai-link-10 {
> 	    sound-dai = <&spdifout>;
>
> 	    codec-0 {
> 		sound-dai = <&spdif_dit>;
> 	    };
> 	};
>
> 	/* spdif or toslink interface */
> 	dai-link-11 {
> 	    sound-dai = <&spdifin>;
>
> 	    codec-0 {
> 		sound-dai = <&spdif_dir>;
> 	    };
> 	};
> ...
>
> ---
>  arch/arm64/boot/dts/amlogic/meson-sm1.dtsi | 27 ++++++++++++++++++++++
>  1 file changed, 27 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
> index 3d8b1f4f2001..1e0adf259d61 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
> @@ -356,6 +356,33 @@ tdmin_lb: audio-controller at 3c0 {
>  			status = "disabled";
>  		};
>  
> +		spdifin: audio-controller at 400 {
> +			compatible = "amlogic,g12a-spdifin",
> +			"amlogic,axg-spdifin";
> +			reg = <0x0 0x400 0x0 0x30>;
> +			#sound-dai-cells = <0>;
> +			sound-name-prefix = "SPDIFIN";
> +			interrupts = <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
> +			clocks = <&clkc_audio AUD_CLKID_SPDIFIN>,
> +			<&clkc_audio AUD_CLKID_SPDIFIN_CLK>;
> +			clock-names = "pclk", "refclk";
> +			resets = <&clkc_audio AUD_RESET_SPDIFIN>;
> +			status = "disabled";
> +		};
> +
> +		spdifout: audio-controller at 480 {

Node should still be named spdifout_a, even if the spdifout_b is not added yet

> +			compatible = "amlogic,g12a-spdifout",
> +			"amlogic,axg-spdifout";
> +			reg = <0x0 0x480 0x0 0x50>;
> +			#sound-dai-cells = <0>;
> +			sound-name-prefix = "SPDIFOUT";

Same here

> +			clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
> +			<&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
> +			clock-names = "pclk", "mclk";
> +			resets = <&clkc_audio AUD_RESET_SPDIFOUT>;
> +			status = "disabled";
> +		};
> +
>  		tdmout_a: audio-controller at 500 {
>  			compatible = "amlogic,sm1-tdmout";
>  			reg = <0x0 0x500 0x0 0x40>;



From gary.bisson at boundarydevices.com  Mon Jan  3 07:46:13 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Mon,  3 Jan 2022 16:46:13 +0100
Subject: [PATCH 0/3] meson-g12: add pwm and uart pin muxing options
Message-ID: <20220103154616.308376-1-gary.bisson@boundarydevices.com>

Hi,

This series adds a few pin muxing options needed for our HW platform (to
be submitted soon).

1- pwm_f: adding missing both GPIOZ_12 & GPIOA_11 options
  -> tested GPIOA_11 as mipi display backlight
  -> order for this patch is not alphabetical but follows doc order (to
match current order)
2- uart_ao_b: adding both options for ao_b uart + its rts/cts pins
  -> tested on custom hw too

Let me know if you have any questions.

Regards,
Gary

Gary Bisson (3):
  pinctrl: meson-g12a: add more pwm_f options
  arm64: dts: meson-g12-common: add more pwm_f options
  arm64: dts: meson-g12-common: add uart_ao_b pins muxing

 .../boot/dts/amlogic/meson-g12-common.dtsi    | 43 +++++++++++++++++++
 drivers/pinctrl/meson/pinctrl-meson-g12a.c    |  6 ++-
 2 files changed, 48 insertions(+), 1 deletion(-)

-- 
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
-- 
2.34.1



From gary.bisson at boundarydevices.com  Mon Jan  3 07:46:14 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Mon,  3 Jan 2022 16:46:14 +0100
Subject: [PATCH 1/3] pinctrl: meson-g12a: add more pwm_f options
In-Reply-To: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
Message-ID: <20220103154616.308376-2-gary.bisson@boundarydevices.com>

Add missing PWM_F pin muxing for GPIOA_11 and GPIOZ_12.

Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
---
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: linux-gpio at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 drivers/pinctrl/meson/pinctrl-meson-g12a.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/meson/pinctrl-meson-g12a.c b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
index cd9656b13836..d182a575981e 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-g12a.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
@@ -283,6 +283,8 @@ static const unsigned int pwm_d_x6_pins[]		= { GPIOX_6 };
 static const unsigned int pwm_e_pins[]			= { GPIOX_16 };
 
 /* pwm_f */
+static const unsigned int pwm_f_z_pins[]		= { GPIOZ_12 };
+static const unsigned int pwm_f_a_pins[]		= { GPIOA_11 };
 static const unsigned int pwm_f_x_pins[]		= { GPIOX_7 };
 static const unsigned int pwm_f_h_pins[]		= { GPIOH_5 };
 
@@ -618,6 +620,7 @@ static struct meson_pmx_group meson_g12a_periphs_groups[] = {
 	GROUP(tdm_c_dout2_z,		4),
 	GROUP(tdm_c_dout3_z,		4),
 	GROUP(mclk1_z,			4),
+	GROUP(pwm_f_z,			5),
 
 	/* bank GPIOX */
 	GROUP(sdio_d0,			1),
@@ -768,6 +771,7 @@ static struct meson_pmx_group meson_g12a_periphs_groups[] = {
 	GROUP(tdm_c_dout3_a,		2),
 	GROUP(mclk0_a,			1),
 	GROUP(mclk1_a,			2),
+	GROUP(pwm_f_a,			3),
 };
 
 /* uart_ao_a */
@@ -1069,7 +1073,7 @@ static const char * const pwm_e_groups[] = {
 };
 
 static const char * const pwm_f_groups[] = {
-	"pwm_f_x", "pwm_f_h",
+	"pwm_f_z", "pwm_f_a", "pwm_f_x", "pwm_f_h",
 };
 
 static const char * const cec_ao_a_h_groups[] = {
-- 
2.34.1



From gary.bisson at boundarydevices.com  Mon Jan  3 07:46:15 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Mon,  3 Jan 2022 16:46:15 +0100
Subject: [PATCH 2/3] arm64: dts: meson-g12-common: add more pwm_f options
In-Reply-To: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
Message-ID: <20220103154616.308376-3-gary.bisson@boundarydevices.com>

Add missing PWM_F pin muxing for GPIOA_11 and GPIOZ_12.

Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
---
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: devicetree at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 .../arm64/boot/dts/amlogic/meson-g12-common.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index 00c6f53290d4..af1357c48bee 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -894,6 +894,22 @@ mux {
 						};
 					};
 
+					pwm_f_z_pins: pwm-f-z {
+						mux {
+							groups = "pwm_f_z";
+							function = "pwm_f";
+							bias-disable;
+						};
+					};
+
+					pwm_f_a_pins: pwm-f-a {
+						mux {
+							groups = "pwm_f_a";
+							function = "pwm_f";
+							bias-disable;
+						};
+					};
+
 					pwm_f_x_pins: pwm-f-x {
 						mux {
 							groups = "pwm_f_x";
-- 
2.34.1



From gary.bisson at boundarydevices.com  Mon Jan  3 07:46:16 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Mon,  3 Jan 2022 16:46:16 +0100
Subject: [PATCH 3/3] arm64: dts: meson-g12-common: add uart_ao_b pins muxing
In-Reply-To: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
Message-ID: <20220103154616.308376-4-gary.bisson@boundarydevices.com>

- RX/TX signals can be mapped on 2 different pairs of pins so supporting
  both options
- RTS/CTS signals however only have 1 option available

Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
---
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: devicetree at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 .../boot/dts/amlogic/meson-g12-common.dtsi    | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index af1357c48bee..3a7773ffbd08 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -1952,6 +1952,33 @@ mux {
 						};
 					};
 
+					uart_ao_b_1_pins: uart-ao-b-1 {
+						mux {
+							groups = "uart_ao_b_tx_2",
+								 "uart_ao_b_rx_3";
+							function = "uart_ao_b";
+							bias-disable;
+						};
+					};
+
+					uart_ao_b_2_pins: uart-ao-b-2 {
+						mux {
+							groups = "uart_ao_b_tx_8",
+								 "uart_ao_b_rx_9";
+							function = "uart_ao_b";
+							bias-disable;
+						};
+					};
+
+					uart_ao_b_cts_rts_pins: uart-ao-b-cts-rts {
+						mux {
+							groups = "uart_ao_b_cts",
+								 "uart_ao_b_rts";
+							function = "uart_ao_b";
+							bias-disable;
+						};
+					};
+
 					pwm_a_e_pins: pwm-a-e {
 						mux {
 							groups = "pwm_a_e";
-- 
2.34.1



From gregkh at linuxfoundation.org  Mon Jan  3 08:29:39 2022
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 3 Jan 2022 17:29:39 +0100
Subject: [PATCH V3 1/6] tty: serial: meson: Drop the legacy compatible
 strings and clock code
In-Reply-To: <df9e472e-ac17-26ed-d820-e80d5b7b0e80@baylibre.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-2-yu.tu@amlogic.com>
 <CAFBinCCwjS36ss_4sU+o9m8gEprFsVZbqcxgpQxczTNohZqFdA@mail.gmail.com>
 <a296e666-368b-4cd5-427e-30fc66a15b49@amlogic.com>
 <CAFBinCA2V=sx95Q=+4nLDXFK1Os11XVWtK8KauxixVwYXLUz1Q@mail.gmail.com>
 <3865f01c-83f7-a69d-6835-c26f662629b7@baylibre.com>
 <YdMUEzStFf99EeQ5@kroah.com>
 <df9e472e-ac17-26ed-d820-e80d5b7b0e80@baylibre.com>
Message-ID: <YdMkc2YQcYjgR7Qk@kroah.com>

On Mon, Jan 03, 2022 at 04:29:56PM +0100, Neil Armstrong wrote:
> Hi Greg,
> On 03/01/2022 16:19, Greg Kroah-Hartman wrote:
> > A: http://en.wikipedia.org/wiki/Top_post
> > Q: Were do I find info about this thing called top-posting?
> > A: Because it messes up the order in which people normally read text.
> > Q: Why is top-posting such a bad thing?
> > A: Top-posting.
> > Q: What is the most annoying thing in e-mail?
> > 
> > A: No.
> > Q: Should I include quotations after my reply?
> > 
> > http://daringfireball.net/2007/07/on_to>
> > On Mon, Jan 03, 2022 at 03:59:33PM +0100, Neil Armstrong wrote:
> >> Hi Greg,
> >>
> >> Martin just saw this patch was applied, but the serie wasn't reviewed enough and it will break
> >> earlycon support on the ARMv7 Amlogic SoCs fore 5.17.
> > 
> > Ok, what should I revert?
> 
> None, we have a fix in the pipe
> 
> > 
> >> Anyway, I'll push the corresponding DT fixes for 5.17-rc1.
> > 
> > How did we get out of sync here?
> 
> The serie wasn't fully reviewed, and I was out of office when it was applied.
> 
> > 
> >> Would it be possible we also receive the notification when those patches are applied ?
> >> Maybe a MAINTAINERS entry is missing so we can receive them ?
> > 
> > That would be good, so that people can review the patches.  Otherwise I
> > have to just guess :)
> 
> exact, I naively thought it would be matched in the:
> N:      meson
> entry but it seems an proper entry for drivers/tty/serial/meson_uart.c is needed.

Try it, does that work when running get_maintainer.pl on this patch?

> >> It would help me track those TTY and USB patches more easily.
> > 
> > I recommend MAINTAINERS entries for drivers that are not listed and that
> > you care about seeing the changes for.
> 
> This is why we have a regex to match these.

Great, the submitter should have used that.

> I can submit a patch to have a proper entry if the regex is not enough/appropriate.

Whatever makes the tools work is fine with me.

> BTW can you point us how are selected the recipients of the notification messages you send ?

For when I apply a patch, everyone on the ack/signed-off-by/reviewed-by
list gets a response.  I do not hit mailing lists with the notification
as that's just too much noise.

Been doing it this way for well over a decade now, nothing new here :)

thanks,

greg k-h


From narmstrong at baylibre.com  Mon Jan  3 08:35:01 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 17:35:01 +0100
Subject: [PATCH V3 1/6] tty: serial: meson: Drop the legacy compatible
 strings and clock code
In-Reply-To: <YdMkc2YQcYjgR7Qk@kroah.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-2-yu.tu@amlogic.com>
 <CAFBinCCwjS36ss_4sU+o9m8gEprFsVZbqcxgpQxczTNohZqFdA@mail.gmail.com>
 <a296e666-368b-4cd5-427e-30fc66a15b49@amlogic.com>
 <CAFBinCA2V=sx95Q=+4nLDXFK1Os11XVWtK8KauxixVwYXLUz1Q@mail.gmail.com>
 <3865f01c-83f7-a69d-6835-c26f662629b7@baylibre.com>
 <YdMUEzStFf99EeQ5@kroah.com>
 <df9e472e-ac17-26ed-d820-e80d5b7b0e80@baylibre.com>
 <YdMkc2YQcYjgR7Qk@kroah.com>
Message-ID: <257d153c-960a-59fc-dfa9-5e160e42b68d@baylibre.com>

On 03/01/2022 17:29, Greg Kroah-Hartman wrote:
> On Mon, Jan 03, 2022 at 04:29:56PM +0100, Neil Armstrong wrote:
>>>> Would it be possible we also receive the notification when those patches are applied ?
>>>> Maybe a MAINTAINERS entry is missing so we can receive them ?
>>>
>>> That would be good, so that people can review the patches.  Otherwise I
>>> have to just guess :)
>>
>> exact, I naively thought it would be matched in the:
>> N:      meson
>> entry but it seems an proper entry for drivers/tty/serial/meson_uart.c is needed.
> 
> Try it, does that work when running get_maintainer.pl on this patch?

Yes it does work, so no problem here

> 
>>>> It would help me track those TTY and USB patches more easily.
>>>
>>> I recommend MAINTAINERS entries for drivers that are not listed and that
>>> you care about seeing the changes for.
>>
>> This is why we have a regex to match these.
> 
> Great, the submitter should have used that.
> 
>> I can submit a patch to have a proper entry if the regex is not enough/appropriate.
> 
> Whatever makes the tools work is fine with me.
> 
>> BTW can you point us how are selected the recipients of the notification messages you send ?
> 
> For when I apply a patch, everyone on the ack/signed-off-by/reviewed-by
> list gets a response.  I do not hit mailing lists with the notification
> as that's just too much noise.
> 
> Been doing it this way for well over a decade now, nothing new here :)

Ok right, no problem, other maintainers (e.g: net, sound) and default b4 behavior is to
send notification to same recipient as original patch.

It it fits everyone for a decade, no need to change ! We have very low patches for tty & usb anyway

Neil

> 
> thanks,
> 
> greg k-h
> 



From christianshewitt at gmail.com  Mon Jan  3 08:39:47 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:47 +0000
Subject: [PATCH v2 0/9] arm64: dts: meson: add support for aac2xx devices
Message-ID: <20220103163956.6581-1-christianshewitt@gmail.com>

This series adds support for several popular Amlogic S905X3 (SM1) Android
Set-Top Box devices. Like most Android box devices, they ship in variants
with multiple RAM, eMMC, WiFi and BT configurations. RAM and eMMC are not
something we need to consider to get a working boot, but we do need to get
the correct connectivity spec. Broadly speaking we see boxes with Higher
and Lower spec connectivity; High spec is Gigabit Ethernet and Faster dual
antennna WiFi, and Lower spec is Megabit Ethernet and a single antenna. In
some low-end boxes BT is omitted.

As initial distro setup is frequently performed over SSH or an HDMI GUI
app it is important for users to pick a device-tree with the correct
Ethernet PHY spec else connectivity is impossible. To aid this we append
a -gbit suffix to X96-AIR and A95XF3-AIR models using an external Gigabit
PHY, while 10/00 models with internal PHY have no suffix.

NB: At the current time the Realtek 8822CS and MT7668 WiFi/BT modules we
have seen on 'AIR' devices are not supported in the kernel so these are
deliberately omitted. The H96-Max uses a conventional Broadcom module
so has more complete support. For now the boxes have simple HDMI audio
support; wiring up the Headphone socket will be done at a later date.

Changes since RFC(v1) series:
- Add Robs binding acks on patches 4/7/8 (patches 2/5 still need acks)
- Rename and rework patches around -gbit (as requested by Neil)
- Correct 'manufacturer' typo on patch 8
- Rebase against v5.18/dt64 branch

Christian Hewitt (9):
  arm64: dts: meson: add common SM1 ac2xx dtsi
  dt-bindings: arm: amlogic: add X96-AIR bindings
  arm64: dts: meson: add initial device-trees for X96-AIR
  dt-bindings: vendor-prefixes: add cyx prefix
  dt-bindings: arm: amlogic: add A95XF3-AIR bindings
  arm64: dts: meson: add initial device-trees for A95XF3-AIR
  dt-bindings: vendor-prefixes: add haochuangyi prefix
  dt-bindings: arm: amlogic: add H96-Max bindings
  arm64: dts: meson: add initial device-tree for H96-Max

 .../devicetree/bindings/arm/amlogic.yaml      |   5 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   4 +
 arch/arm64/boot/dts/amlogic/Makefile          |   5 +
 .../dts/amlogic/meson-sm1-a95xf3-air-gbit.dts | 129 ++++++++
 .../boot/dts/amlogic/meson-sm1-a95xf3-air.dts | 108 +++++++
 .../boot/dts/amlogic/meson-sm1-ac2xx.dtsi     | 300 ++++++++++++++++++
 .../boot/dts/amlogic/meson-sm1-h96-max.dts    | 145 +++++++++
 .../dts/amlogic/meson-sm1-x96-air-gbit.dts    | 133 ++++++++
 .../boot/dts/amlogic/meson-sm1-x96-air.dts    | 112 +++++++
 9 files changed, 941 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts

-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:48 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:48 +0000
Subject: [PATCH v2 1/9] arm64: dts: meson: add common SM1 ac2xx dtsi
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-2-christianshewitt@gmail.com>

Add a common dtsi for Android STB devices based on the Amlogic S905X3
(AC213/AC214) and S905D3 (AC201/AC202) reference designs. The dtsi is
loosely based on the existing SEI610 device-tree.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 .../boot/dts/amlogic/meson-sm1-ac2xx.dtsi     | 300 ++++++++++++++++++
 1 file changed, 300 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
new file mode 100644
index 000000000000..46a34731f7e2
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ *
+ * AC200/AC202 = S905D3
+ * AC213/AC214 = S905X3
+ *
+ */
+
+#include "meson-sm1.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		serial0 = &uart_AO;
+		ethernet0 = &ethmac;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	emmc_pwrseq: emmc-pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
+	};
+
+	cvbs-connector {
+		compatible = "composite-video-connector";
+
+		port {
+			cvbs_connector_in: endpoint {
+				remote-endpoint = <&cvbs_vdac_out>;
+			};
+		};
+	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&hdmi_tx_tmds_out>;
+			};
+		};
+	};
+
+	memory at 0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x40000000>;
+	};
+
+	ao_5v: regulator-ao_5v {
+		compatible = "regulator-fixed";
+		regulator-name = "AO_5V";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_in>;
+		regulator-always-on;
+	};
+
+	dc_in: regulator-dc_in {
+		compatible = "regulator-fixed";
+		regulator-name = "DC_IN";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	emmc_1v8: regulator-emmc_1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "EMMC_1V8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vddao_3v3>;
+		regulator-always-on;
+	};
+
+	vddao_3v3: regulator-vddao_3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDAO_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&dc_in>;
+		regulator-always-on;
+	};
+
+	vddcpu: regulator-vddcpu {
+		compatible = "pwm-regulator";
+
+		regulator-name = "VDDCPU";
+		regulator-min-microvolt = <690000>;
+		regulator-max-microvolt = <1050000>;
+
+		vin-supply = <&dc_in>;
+
+		pwms = <&pwm_AO_cd 1 1500 0>;
+		pwm-dutycycle-range = <100 0>;
+
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	vddio_ao1v8: regulator-vddio_ao1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDIO_AO1V8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vddao_3v3>;
+		regulator-always-on;
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+		clocks = <&wifi32k>;
+		clock-names = "ext_clock";
+	};
+
+	wifi32k: wifi32k {
+		compatible = "pwm-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+	};
+};
+
+&cec_AO {
+	pinctrl-0 = <&cec_ao_a_h_pins>;
+	pinctrl-names = "default";
+	status = "disabled";
+	hdmi-phandle = <&hdmi_tx>;
+};
+
+&cecb_AO {
+	pinctrl-0 = <&cec_ao_b_h_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+	hdmi-phandle = <&hdmi_tx>;
+};
+
+&cpu0 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu1 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU1_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu2 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU2_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu3 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU3_CLK>;
+	clock-latency = <50000>;
+};
+
+&cvbs_vdac_port {
+	cvbs_vdac_out: endpoint {
+		remote-endpoint = <&cvbs_connector_in>;
+	};
+};
+
+&hdmi_tx {
+	status = "okay";
+	pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
+	pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+	hdmi_tx_tmds_out: endpoint {
+		remote-endpoint = <&hdmi_connector_in>;
+	};
+};
+
+&ir {
+	status = "okay";
+	pinctrl-0 = <&remote_input_ao_pins>;
+	pinctrl-names = "default";
+};
+
+&pwm_AO_ab {
+	status = "okay";
+	pinctrl-0 = <&pwm_ao_a_pins>;
+	pinctrl-names = "default";
+	clocks = <&xtal>;
+	clock-names = "clkin0";
+};
+
+&pwm_AO_cd {
+	pinctrl-0 = <&pwm_ao_d_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&xtal>;
+	clock-names = "clkin1";
+	status = "okay";
+};
+
+&pwm_ef {
+	status = "okay";
+	pinctrl-0 = <&pwm_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&xtal>;
+	clock-names = "clkin0";
+};
+
+&saradc {
+	status = "okay";
+	vref-supply = <&vddio_ao1v8>;
+};
+
+/* SDIO */
+&sd_emmc_a {
+	status = "okay";
+	pinctrl-0 = <&sdio_pins>;
+	pinctrl-1 = <&sdio_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	sd-uhs-sdr104;
+	max-frequency = <200000000>;
+
+	non-removable;
+	disable-wp;
+
+	/* WiFi firmware requires power to be kept while in suspend */
+	keep-power-in-suspend;
+
+	mmc-pwrseq = <&sdio_pwrseq>;
+
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddio_ao1v8>;
+};
+
+/* SD Card */
+&sd_emmc_b {
+	status = "okay";
+	pinctrl-0 = <&sdcard_c_pins>;
+	pinctrl-1 = <&sdcard_clk_gate_c_pins>;
+	pinctrl-names = "default", "clk-gate";
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	/* CRC errors are observed at 50MHz */
+	max-frequency = <35000000>;
+	disable-wp;
+
+	cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddao_3v3>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+	status = "okay";
+	pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
+	pinctrl-1 = <&emmc_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	max-frequency = <200000000>;
+	non-removable;
+	disable-wp;
+
+	mmc-pwrseq = <&emmc_pwrseq>;
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&emmc_1v8>;
+};
+
+&uart_AO {
+	status = "okay";
+	pinctrl-0 = <&uart_ao_a_pins>;
+	pinctrl-names = "default";
+};
+
+&usb {
+	status = "okay";
+	dr_mode = "otg";
+};
-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:49 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:49 +0000
Subject: [PATCH v2 2/9] dt-bindings: arm: amlogic: add X96-AIR bindings
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-3-christianshewitt@gmail.com>

Add board bindings for the Amediatech X96-AIR STB which ships with
model variants distiguished by Ethernet configuration: models using
an external Gigabit PHY have a -gbit suffix, while models using an
internal 10/100 PHY have no suffix.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 Documentation/devicetree/bindings/arm/amlogic.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 31df120d73b0..b5b995941d3b 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -170,6 +170,8 @@ properties:
       - description: Boards with the Amlogic Meson SM1 S905X3/D3/Y3 SoC
         items:
           - enum:
+              - amediatech,x96-air
+              - amediatech,x96-air-gbit
               - bananapi,bpi-m5
               - hardkernel,odroid-c4
               - hardkernel,odroid-hc4
-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:50 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:50 +0000
Subject: [PATCH v2 3/9] arm64: dts: meson: add initial device-trees for X96-AIR
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-4-christianshewitt@gmail.com>

The Amediatek X96-AIR is based on Amlogic S905X3 reference board
designs and ships in multiple configurations:

? 4GB DDR3 + 64GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
? 4GB DDR3 + 32GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
? 4GB DDR3 + 32GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
? 2GB DDR3 + 16GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
...
- HDMI 2.1 video
- S/PDIF optical output
- AV output
- 2x USB 2.0 inc. OTG port
- 1x USB 3.0 port
- IR receiver
- 1x micro SD card slot (internal)
- 1x Reset/Update button (in AV jack)
- 7-segment VFD

The device-tree with -gbit suffix supports models with Gigabit
Ethernet, and the device-tree with no suffix supports models
with 10/100 Ethernet.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/Makefile          |   2 +
 .../dts/amlogic/meson-sm1-x96-air-gbit.dts    | 133 ++++++++++++++++++
 .../boot/dts/amlogic/meson-sm1-x96-air.dts    | 112 +++++++++++++++
 3 files changed, 247 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 5148cd9e5146..1c0e554f54fc 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -56,4 +56,6 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air-gbit.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
new file mode 100644
index 000000000000..7e1a74046ba5
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "amediatech,x96-air-gbit", "amlogic,sm1";
+	model = "Shenzhen Amediatech Technology Co., Ltd X96 Air";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "X96-AIR";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+
+	pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+	pinctrl-names = "default";
+	phy-mode = "rgmii-txid";
+	phy-handle = <&external_phy>;
+
+	rx-internal-delay-ps = <800>;
+};
+
+&ext_mdio {
+	external_phy: ethernet-phy at 0 {
+		/* Realtek RTL8211F (0x001cc916) */
+		reg = <0>;
+		max-speed = <1000>;
+
+		reset-assert-us = <10000>;
+		reset-deassert-us = <80000>;
+		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+		interrupt-parent = <&gpio_intc>;
+		/* MAC_INTR on GPIOZ_14 */
+		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&ir {
+	linux,rc-map-name = "rc-x96max";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts
new file mode 100644
index 000000000000..cd93d798f2a3
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "amediatech,x96-air", "amlogic,sm1";
+	model = "Shenzhen Amediatech Technology Co., Ltd X96 Air";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "X96-AIR";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+	phy-handle = <&internal_ephy>;
+	phy-mode = "rmii";
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&ir {
+	linux,rc-map-name = "rc-beelink-gs1";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:51 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:51 +0000
Subject: [PATCH v2 4/9] dt-bindings: vendor-prefixes: add cyx prefix
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-5-christianshewitt@gmail.com>

Shenzhen CYX Industrial Co., Ltd are a manufacturer of Android
Set-Top Box devices.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index eb8ab0d82198..c9202a101d71 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -281,6 +281,8 @@ patternProperties:
     description: CUI Devices
   "^cypress,.*":
     description: Cypress Semiconductor Corporation
+  "^cyx,.*":
+    description: Shenzhen CYX Industrial Co., Ltd
   "^cznic,.*":
     description: CZ.NIC, z.s.p.o.
   "^dallas,.*":
-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:52 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:52 +0000
Subject: [PATCH v2 5/9] dt-bindings: arm: amlogic: add A95XF3-AIR bindings
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-6-christianshewitt@gmail.com>

Add board bindings for the CYX A95XF3-AIR set-top box which ships
with model variants distiguished by Ethernet configuration: models
using external Gigabit PHY have a -gbit suffix, while models using
an internal 10/100 PHY have no suffix.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 Documentation/devicetree/bindings/arm/amlogic.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index b5b995941d3b..2027ce81a834 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -173,6 +173,8 @@ properties:
               - amediatech,x96-air
               - amediatech,x96-air-gbit
               - bananapi,bpi-m5
+              - cyx,a95xf3-air
+              - cyx,a95xf3-air-gbit
               - hardkernel,odroid-c4
               - hardkernel,odroid-hc4
               - khadas,vim3l
-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:53 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:53 +0000
Subject: [PATCH v2 6/9] arm64: dts: meson: add initial device-trees for
 A95XF3-AIR
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-7-christianshewitt@gmail.com>

The CYX A95XF3-AIR is based on Amlogic S905X3 reference board
designs and ships in multiple configurations:

? 4GB DDR3 + 64GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
? 4GB DDR3 + 32GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
? 2GB DDR3 + 16GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
...
- HDMI 2.1 video
- S/PDIF optical output
- AV output
- 1x USB 2.0 OTG port
- 1x USB 3.0 port
- IR receiver
- 1x micro SD card slot (internal)
- 1x Reset/Update button (in AV jack)
- 7-segment VFD
- Multicolour case LED 'arc'

The device-tree with -gbit suffix supports models with Gigabit
Ethernet, and the device-tree with no suffix supports models
with 10/100 Ethernet.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/Makefile          |   2 +
 .../dts/amlogic/meson-sm1-a95xf3-air-gbit.dts | 129 ++++++++++++++++++
 .../boot/dts/amlogic/meson-sm1-a95xf3-air.dts | 108 +++++++++++++++
 3 files changed, 239 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 1c0e554f54fc..e87adc6593df 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -51,6 +51,8 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-rbox-pro.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-s912-libretech-pc.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-vega-s96.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-wetek-core2.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air-gbit.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-bananapi-m5.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
new file mode 100644
index 000000000000..d1debccdc1c2
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "cyx,a95xf3-air-gbit", "amlogic,sm1";
+	model = "Shenzhen CYX Industrial Co., Ltd A95XF3-AIR";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "A95XF3-AIR";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+
+	pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+	pinctrl-names = "default";
+	phy-mode = "rgmii-txid";
+	phy-handle = <&external_phy>;
+
+	rx-internal-delay-ps = <800>;
+};
+
+&ext_mdio {
+	external_phy: ethernet-phy at 0 {
+		/* Realtek RTL8211F (0x001cc916) */
+		reg = <0>;
+		max-speed = <1000>;
+
+		reset-assert-us = <10000>;
+		reset-deassert-us = <80000>;
+		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+		interrupt-parent = <&gpio_intc>;
+		/* MAC_INTR on GPIOZ_14 */
+		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts
new file mode 100644
index 000000000000..c94f2870b78b
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "cyx,a95xf3-air", "amlogic,sm1";
+	model = "Shenzhen CYX Industrial Co., Ltd A95XF3-AIR";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "A95XF3-AIR";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+	phy-handle = <&internal_ephy>;
+	phy-mode = "rmii";
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:54 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:54 +0000
Subject: [PATCH v2 7/9] dt-bindings: vendor-prefixes: add haochuangyi prefix
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-8-christianshewitt@gmail.com>

Shenzhen Haochuangyi Technology Co.,Ltd are a manufacturer of Android
Set-Top Box devices.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index c9202a101d71..f4160ee3b5df 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -485,6 +485,8 @@ patternProperties:
     deprecated: true
   "^hannstar,.*":
     description: HannStar Display Corporation
+  "^haochuangyi,.*":
+    description: Shenzhen Haochuangyi Technology Co.,Ltd
   "^haoyu,.*":
     description: Haoyu Microelectronic Co. Ltd.
   "^hardkernel,.*":
-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:55 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:55 +0000
Subject: [PATCH v2 8/9] dt-bindings: arm: amlogic: add H96-Max bindings
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-9-christianshewitt@gmail.com>

Add the board binding for the Haochuangyi H96-Max STB device.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 2027ce81a834..a073a959232c 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -177,6 +177,7 @@ properties:
               - cyx,a95xf3-air-gbit
               - hardkernel,odroid-c4
               - hardkernel,odroid-hc4
+              - haochuangyi,h96-max
               - khadas,vim3l
               - seirobotics,sei610
           - const: amlogic,sm1
-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:56 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:56 +0000
Subject: [PATCH v2 9/9] arm64: dts: meson: add initial device-tree for H96-Max
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-10-christianshewitt@gmail.com>

The Haochuangyi H96-Max is based on the Amlogic S905X3 reference
design with the following specs:

- 4GB DDR4 RAM
- 32/64/128GB eMMC
- HDMI 2.1 video
- S/PDIF optical output
- AV output
- 10/100/1000 Base-T Ethernet
- AP6356S Wireless (802.11 a/b/g/n/ac, BT 4.1)
- 1x USB 2.0 OTG port
- 1x USB 3.0 port
- IR receiver
- 1x micro SD card slot (internal)
- 1x Reset/Update button (in AV jack)
- 7-segment VFD

Tested-by: Benoit Masson <yahoo at perenite.com>
Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/Makefile          |   1 +
 .../boot/dts/amlogic/meson-sm1-h96-max.dts    | 145 ++++++++++++++++++
 2 files changed, 146 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index e87adc6593df..868d74044072 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -54,6 +54,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-wetek-core2.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air-gbit.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-bananapi-m5.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-h96-max.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts
new file mode 100644
index 000000000000..0f6660e68e72
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "haochuangyi,h96-max", "amlogic,sm1";
+	model = "Shenzhen Haochuangyi Technology Co., Ltd H96 Max";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "H96-MAX";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+
+	pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+	pinctrl-names = "default";
+	phy-mode = "rgmii-txid";
+	phy-handle = <&external_phy>;
+
+	rx-internal-delay-ps = <800>;
+};
+
+&ext_mdio {
+	external_phy: ethernet-phy at 0 {
+		/* Realtek RTL8211F (0x001cc916) */
+		reg = <0>;
+		max-speed = <1000>;
+
+		reset-assert-us = <10000>;
+		reset-deassert-us = <80000>;
+		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+		interrupt-parent = <&gpio_intc>;
+		/* MAC_INTR on GPIOZ_14 */
+		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
+
+&uart_A {
+	status = "okay";
+
+	pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+	pinctrl-names = "default";
+	uart-has-rtscts;
+
+	bluetooth {
+		compatible = "brcm,bcm43438-bt";
+		shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+		max-speed = <2000000>;
+		clocks = <&wifi32k>;
+		clock-names = "lpo";
+	};
+};
-- 
2.17.1



From narmstrong at baylibre.com  Mon Jan  3 08:49:05 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 17:49:05 +0100
Subject: [PATCH v2 1/9] arm64: dts: meson: add common SM1 ac2xx dtsi
In-Reply-To: <20220103163956.6581-2-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
 <20220103163956.6581-2-christianshewitt@gmail.com>
Message-ID: <ca79ab12-eb16-ac6d-a950-de59c6253eba@baylibre.com>

On 03/01/2022 17:39, Christian Hewitt wrote:
> Add a common dtsi for Android STB devices based on the Amlogic S905X3
> (AC213/AC214) and S905D3 (AC201/AC202) reference designs. The dtsi is
> loosely based on the existing SEI610 device-tree.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  .../boot/dts/amlogic/meson-sm1-ac2xx.dtsi     | 300 ++++++++++++++++++
>  1 file changed, 300 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
> new file mode 100644
> index 000000000000..46a34731f7e2
> --- /dev/null
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
> @@ -0,0 +1,300 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2019 BayLibre SAS. All rights reserved.
> + * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
> + *
> + * AC200/AC202 = S905D3
> + * AC213/AC214 = S905X3
> + *
> + */
> +
> +#include "meson-sm1.dtsi"
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/gpio/meson-g12a-gpio.h>
> +#include <dt-bindings/input/input.h>
> +
> +/ {
> +	aliases {
> +		serial0 = &uart_AO;
> +		ethernet0 = &ethmac;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	emmc_pwrseq: emmc-pwrseq {
> +		compatible = "mmc-pwrseq-emmc";
> +		reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
> +	};
> +
> +	cvbs-connector {
> +		compatible = "composite-video-connector";
> +
> +		port {
> +			cvbs_connector_in: endpoint {
> +				remote-endpoint = <&cvbs_vdac_out>;
> +			};
> +		};
> +	};
> +
> +	hdmi-connector {
> +		compatible = "hdmi-connector";
> +		type = "a";
> +
> +		port {
> +			hdmi_connector_in: endpoint {
> +				remote-endpoint = <&hdmi_tx_tmds_out>;
> +			};
> +		};
> +	};
> +
> +	memory at 0 {
> +		device_type = "memory";
> +		reg = <0x0 0x0 0x0 0x40000000>;
> +	};
> +
> +	ao_5v: regulator-ao_5v {
> +		compatible = "regulator-fixed";
> +		regulator-name = "AO_5V";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		vin-supply = <&dc_in>;
> +		regulator-always-on;
> +	};
> +
> +	dc_in: regulator-dc_in {
> +		compatible = "regulator-fixed";
> +		regulator-name = "DC_IN";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		regulator-always-on;
> +	};
> +
> +	emmc_1v8: regulator-emmc_1v8 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "EMMC_1V8";
> +		regulator-min-microvolt = <1800000>;
> +		regulator-max-microvolt = <1800000>;
> +		vin-supply = <&vddao_3v3>;
> +		regulator-always-on;
> +	};
> +
> +	vddao_3v3: regulator-vddao_3v3 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "VDDAO_3V3";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		vin-supply = <&dc_in>;
> +		regulator-always-on;
> +	};
> +
> +	vddcpu: regulator-vddcpu {
> +		compatible = "pwm-regulator";
> +
> +		regulator-name = "VDDCPU";
> +		regulator-min-microvolt = <690000>;
> +		regulator-max-microvolt = <1050000>;
> +
> +		vin-supply = <&dc_in>;
> +
> +		pwms = <&pwm_AO_cd 1 1500 0>;
> +		pwm-dutycycle-range = <100 0>;
> +
> +		regulator-boot-on;
> +		regulator-always-on;
> +	};
> +
> +	vddio_ao1v8: regulator-vddio_ao1v8 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "VDDIO_AO1V8";
> +		regulator-min-microvolt = <1800000>;
> +		regulator-max-microvolt = <1800000>;
> +		vin-supply = <&vddao_3v3>;
> +		regulator-always-on;
> +	};
> +
> +	sdio_pwrseq: sdio-pwrseq {
> +		compatible = "mmc-pwrseq-simple";
> +		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
> +		clocks = <&wifi32k>;
> +		clock-names = "ext_clock";
> +	};
> +
> +	wifi32k: wifi32k {
> +		compatible = "pwm-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <32768>;
> +		pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
> +	};
> +};
> +
> +&cec_AO {
> +	pinctrl-0 = <&cec_ao_a_h_pins>;
> +	pinctrl-names = "default";
> +	status = "disabled";
> +	hdmi-phandle = <&hdmi_tx>;
> +};
> +
> +&cecb_AO {
> +	pinctrl-0 = <&cec_ao_b_h_pins>;
> +	pinctrl-names = "default";
> +	status = "okay";
> +	hdmi-phandle = <&hdmi_tx>;
> +};
> +
> +&cpu0 {
> +	cpu-supply = <&vddcpu>;
> +	operating-points-v2 = <&cpu_opp_table>;
> +	clocks = <&clkc CLKID_CPU_CLK>;
> +	clock-latency = <50000>;
> +};
> +
> +&cpu1 {
> +	cpu-supply = <&vddcpu>;
> +	operating-points-v2 = <&cpu_opp_table>;
> +	clocks = <&clkc CLKID_CPU1_CLK>;
> +	clock-latency = <50000>;
> +};
> +
> +&cpu2 {
> +	cpu-supply = <&vddcpu>;
> +	operating-points-v2 = <&cpu_opp_table>;
> +	clocks = <&clkc CLKID_CPU2_CLK>;
> +	clock-latency = <50000>;
> +};
> +
> +&cpu3 {
> +	cpu-supply = <&vddcpu>;
> +	operating-points-v2 = <&cpu_opp_table>;
> +	clocks = <&clkc CLKID_CPU3_CLK>;
> +	clock-latency = <50000>;
> +};
> +
> +&cvbs_vdac_port {
> +	cvbs_vdac_out: endpoint {
> +		remote-endpoint = <&cvbs_connector_in>;
> +	};
> +};
> +
> +&hdmi_tx {
> +	status = "okay";
> +	pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
> +	pinctrl-names = "default";
> +};
> +
> +&hdmi_tx_tmds_port {
> +	hdmi_tx_tmds_out: endpoint {
> +		remote-endpoint = <&hdmi_connector_in>;
> +	};
> +};
> +
> +&ir {
> +	status = "okay";
> +	pinctrl-0 = <&remote_input_ao_pins>;
> +	pinctrl-names = "default";
> +};
> +
> +&pwm_AO_ab {
> +	status = "okay";
> +	pinctrl-0 = <&pwm_ao_a_pins>;
> +	pinctrl-names = "default";
> +	clocks = <&xtal>;
> +	clock-names = "clkin0";
> +};
> +
> +&pwm_AO_cd {
> +	pinctrl-0 = <&pwm_ao_d_e_pins>;
> +	pinctrl-names = "default";
> +	clocks = <&xtal>;
> +	clock-names = "clkin1";
> +	status = "okay";
> +};
> +
> +&pwm_ef {
> +	status = "okay";
> +	pinctrl-0 = <&pwm_e_pins>;
> +	pinctrl-names = "default";
> +	clocks = <&xtal>;
> +	clock-names = "clkin0";
> +};
> +
> +&saradc {
> +	status = "okay";
> +	vref-supply = <&vddio_ao1v8>;
> +};
> +
> +/* SDIO */
> +&sd_emmc_a {
> +	status = "okay";
> +	pinctrl-0 = <&sdio_pins>;
> +	pinctrl-1 = <&sdio_clk_gate_pins>;
> +	pinctrl-names = "default", "clk-gate";
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +
> +	bus-width = <4>;
> +	cap-sd-highspeed;
> +	sd-uhs-sdr104;
> +	max-frequency = <200000000>;
> +
> +	non-removable;
> +	disable-wp;
> +
> +	/* WiFi firmware requires power to be kept while in suspend */
> +	keep-power-in-suspend;
> +
> +	mmc-pwrseq = <&sdio_pwrseq>;
> +
> +	vmmc-supply = <&vddao_3v3>;
> +	vqmmc-supply = <&vddio_ao1v8>;
> +};
> +
> +/* SD Card */
> +&sd_emmc_b {
> +	status = "okay";
> +	pinctrl-0 = <&sdcard_c_pins>;
> +	pinctrl-1 = <&sdcard_clk_gate_c_pins>;
> +	pinctrl-names = "default", "clk-gate";
> +
> +	bus-width = <4>;
> +	cap-sd-highspeed;
> +	/* CRC errors are observed at 50MHz */
> +	max-frequency = <35000000>;
> +	disable-wp;
> +
> +	cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
> +	vmmc-supply = <&vddao_3v3>;
> +	vqmmc-supply = <&vddao_3v3>;
> +};
> +
> +/* eMMC */
> +&sd_emmc_c {
> +	status = "okay";
> +	pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
> +	pinctrl-1 = <&emmc_clk_gate_pins>;
> +	pinctrl-names = "default", "clk-gate";
> +
> +	bus-width = <8>;
> +	cap-mmc-highspeed;
> +	mmc-ddr-1_8v;
> +	mmc-hs200-1_8v;
> +	max-frequency = <200000000>;
> +	non-removable;
> +	disable-wp;
> +
> +	mmc-pwrseq = <&emmc_pwrseq>;
> +	vmmc-supply = <&vddao_3v3>;
> +	vqmmc-supply = <&emmc_1v8>;
> +};
> +
> +&uart_AO {
> +	status = "okay";
> +	pinctrl-0 = <&uart_ao_a_pins>;
> +	pinctrl-names = "default";
> +};
> +
> +&usb {
> +	status = "okay";
> +	dr_mode = "otg";
> +};
> 


Missing:
Tested-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com> # X96-Air with Gbit/s PHY


From narmstrong at baylibre.com  Mon Jan  3 08:49:34 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 17:49:34 +0100
Subject: [PATCH v2 3/9] arm64: dts: meson: add initial device-trees for
 X96-AIR
In-Reply-To: <20220103163956.6581-4-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
 <20220103163956.6581-4-christianshewitt@gmail.com>
Message-ID: <3a1c359b-7884-7072-4e08-55687b9f94cf@baylibre.com>

On 03/01/2022 17:39, Christian Hewitt wrote:
> The Amediatek X96-AIR is based on Amlogic S905X3 reference board
> designs and ships in multiple configurations:
> 
> ? 4GB DDR3 + 64GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
> ? 4GB DDR3 + 32GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
> ? 4GB DDR3 + 32GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
> ? 2GB DDR3 + 16GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
> ...
> - HDMI 2.1 video
> - S/PDIF optical output
> - AV output
> - 2x USB 2.0 inc. OTG port
> - 1x USB 3.0 port
> - IR receiver
> - 1x micro SD card slot (internal)
> - 1x Reset/Update button (in AV jack)
> - 7-segment VFD
> 
> The device-tree with -gbit suffix supports models with Gigabit
> Ethernet, and the device-tree with no suffix supports models
> with 10/100 Ethernet.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/Makefile          |   2 +
>  .../dts/amlogic/meson-sm1-x96-air-gbit.dts    | 133 ++++++++++++++++++
>  .../boot/dts/amlogic/meson-sm1-x96-air.dts    | 112 +++++++++++++++
>  3 files changed, 247 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
>  create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts
> 
> diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
> index 5148cd9e5146..1c0e554f54fc 100644
> --- a/arch/arm64/boot/dts/amlogic/Makefile
> +++ b/arch/arm64/boot/dts/amlogic/Makefile
> @@ -56,4 +56,6 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
> +dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air.dtb
> +dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air-gbit.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
> new file mode 100644
> index 000000000000..7e1a74046ba5
> --- /dev/null
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
> @@ -0,0 +1,133 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2019 BayLibre SAS. All rights reserved.
> + * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
> + */
> +
> +/dts-v1/;
> +
> +#include "meson-sm1-ac2xx.dtsi"
> +#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
> +
> +/ {
> +	compatible = "amediatech,x96-air-gbit", "amlogic,sm1";
> +	model = "Shenzhen Amediatech Technology Co., Ltd X96 Air";
> +
> +	sound {
> +		compatible = "amlogic,axg-sound-card";
> +		model = "X96-AIR";
> +		audio-aux-devs = <&tdmout_b>;
> +		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
> +				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
> +				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
> +				"TDM_B Playback", "TDMOUT_B OUT";
> +
> +		assigned-clocks = <&clkc CLKID_MPLL2>,
> +				  <&clkc CLKID_MPLL0>,
> +				  <&clkc CLKID_MPLL1>;
> +		assigned-clock-parents = <0>, <0>, <0>;
> +		assigned-clock-rates = <294912000>,
> +				       <270950400>,
> +				       <393216000>;
> +		status = "okay";
> +
> +		dai-link-0 {
> +			sound-dai = <&frddr_a>;
> +		};
> +
> +		dai-link-1 {
> +			sound-dai = <&frddr_b>;
> +		};
> +
> +		dai-link-2 {
> +			sound-dai = <&frddr_c>;
> +		};
> +
> +		/* 8ch hdmi interface */
> +		dai-link-3 {
> +			sound-dai = <&tdmif_b>;
> +			dai-format = "i2s";
> +			dai-tdm-slot-tx-mask-0 = <1 1>;
> +			dai-tdm-slot-tx-mask-1 = <1 1>;
> +			dai-tdm-slot-tx-mask-2 = <1 1>;
> +			dai-tdm-slot-tx-mask-3 = <1 1>;
> +			mclk-fs = <256>;
> +
> +			codec {
> +				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
> +			};
> +		};
> +
> +		/* hdmi glue */
> +		dai-link-4 {
> +			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
> +
> +			codec {
> +				sound-dai = <&hdmi_tx>;
> +			};
> +		};
> +	};
> +};
> +
> +&arb {
> +	status = "okay";
> +};
> +
> +&clkc_audio {
> +	status = "okay";
> +};
> +
> +&ethmac {
> +	status = "okay";
> +
> +	pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
> +	pinctrl-names = "default";
> +	phy-mode = "rgmii-txid";
> +	phy-handle = <&external_phy>;
> +
> +	rx-internal-delay-ps = <800>;
> +};
> +
> +&ext_mdio {
> +	external_phy: ethernet-phy at 0 {
> +		/* Realtek RTL8211F (0x001cc916) */
> +		reg = <0>;
> +		max-speed = <1000>;
> +
> +		reset-assert-us = <10000>;
> +		reset-deassert-us = <80000>;
> +		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
> +
> +		interrupt-parent = <&gpio_intc>;
> +		/* MAC_INTR on GPIOZ_14 */
> +		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
> +	};
> +};
> +
> +&frddr_a {
> +	status = "okay";
> +};
> +
> +&frddr_b {
> +	status = "okay";
> +};
> +
> +&frddr_c {
> +	status = "okay";
> +};
> +
> +&ir {
> +	linux,rc-map-name = "rc-x96max";
> +};
> +
> +&tdmif_b {
> +	status = "okay";
> +};
> +
> +&tdmout_b {
> +	status = "okay";
> +};
> +
> +&tohdmitx {
> +	status = "okay";
> +};
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts
> new file mode 100644
> index 000000000000..cd93d798f2a3
> --- /dev/null
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts
> @@ -0,0 +1,112 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2019 BayLibre SAS. All rights reserved.
> + * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
> + */
> +
> +/dts-v1/;
> +
> +#include "meson-sm1-ac2xx.dtsi"
> +#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
> +
> +/ {
> +	compatible = "amediatech,x96-air", "amlogic,sm1";
> +	model = "Shenzhen Amediatech Technology Co., Ltd X96 Air";
> +
> +	sound {
> +		compatible = "amlogic,axg-sound-card";
> +		model = "X96-AIR";
> +		audio-aux-devs = <&tdmout_b>;
> +		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
> +				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
> +				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
> +				"TDM_B Playback", "TDMOUT_B OUT";
> +
> +		assigned-clocks = <&clkc CLKID_MPLL2>,
> +				  <&clkc CLKID_MPLL0>,
> +				  <&clkc CLKID_MPLL1>;
> +		assigned-clock-parents = <0>, <0>, <0>;
> +		assigned-clock-rates = <294912000>,
> +				       <270950400>,
> +				       <393216000>;
> +		status = "okay";
> +
> +		dai-link-0 {
> +			sound-dai = <&frddr_a>;
> +		};
> +
> +		dai-link-1 {
> +			sound-dai = <&frddr_b>;
> +		};
> +
> +		dai-link-2 {
> +			sound-dai = <&frddr_c>;
> +		};
> +
> +		/* 8ch hdmi interface */
> +		dai-link-3 {
> +			sound-dai = <&tdmif_b>;
> +			dai-format = "i2s";
> +			dai-tdm-slot-tx-mask-0 = <1 1>;
> +			dai-tdm-slot-tx-mask-1 = <1 1>;
> +			dai-tdm-slot-tx-mask-2 = <1 1>;
> +			dai-tdm-slot-tx-mask-3 = <1 1>;
> +			mclk-fs = <256>;
> +
> +			codec {
> +				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
> +			};
> +		};
> +
> +		/* hdmi glue */
> +		dai-link-4 {
> +			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
> +
> +			codec {
> +				sound-dai = <&hdmi_tx>;
> +			};
> +		};
> +	};
> +};
> +
> +&arb {
> +	status = "okay";
> +};
> +
> +&clkc_audio {
> +	status = "okay";
> +};
> +
> +&ethmac {
> +	status = "okay";
> +	phy-handle = <&internal_ephy>;
> +	phy-mode = "rmii";
> +};
> +
> +&frddr_a {
> +	status = "okay";
> +};
> +
> +&frddr_b {
> +	status = "okay";
> +};
> +
> +&frddr_c {
> +	status = "okay";
> +};
> +
> +&ir {
> +	linux,rc-map-name = "rc-beelink-gs1";
> +};
> +
> +&tdmif_b {
> +	status = "okay";
> +};
> +
> +&tdmout_b {
> +	status = "okay";
> +};
> +
> +&tohdmitx {
> +	status = "okay";
> +};
> 

Missing:
Tested-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com> # X96-Air with Gbit/s PHY
Tested-by: Piotr Oniszczuk <piotr.oniszczuk at gmail.com> # X96-Air with 10/100 Eth


From yu.tu at amlogic.com  Tue Jan  4 00:20:33 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 4 Jan 2022 16:20:33 +0800
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate calculation
 is described using the common clock code. Also added S4 chip uart
 Compatible.
In-Reply-To: <CAFBinCCwE1DbP+Y49o3WxNdeE11ZK=HcGbXa0Sq52tch+eNhrQ@mail.gmail.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
 <CAFBinCCL-QaeSRCLzfyNXcRQZ7YC1D85rP2y4OGkAjCmQEqGgQ@mail.gmail.com>
 <3e1e40aa-7865-0f7a-5772-e2ad96c8141d@amlogic.com>
 <CAFBinCB2nF0TwRE1uJ4UTB_avcqRBfOHR1CDSe29dB1o-YjEHQ@mail.gmail.com>
 <7278bace-a2b9-0cfc-55b3-c19311e3352e@amlogic.com>
 <CAFBinCCwE1DbP+Y49o3WxNdeE11ZK=HcGbXa0Sq52tch+eNhrQ@mail.gmail.com>
Message-ID: <1f16f430-677e-d1f0-1a7f-bf1d1a7c3c47@amlogic.com>

Hi Martin,
	Thank you very much for your reply.
On 2022/1/3 3:36, Martin Blumenstingl wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi,
> 
> On Sat, Jan 1, 2022 at 2:30 PM Yu Tu <yu.tu at amlogic.com> wrote:
> [...]
>>> Interesting, thanks for sharing that u-boot turns these clocks on.
>>> Let's say someone wanted to make u-boot save power and turn off all
>>> UART clocks except the one for uart_AO (where we typically connect the
>>> serial console).
>>> In that case the pclk of uart_C (just to choose an example here) is
>>> turned off. Would there be a problem then accessing the registers of
>>> uart_C before clk_prepare_enable is called?
>> The way you describe it, it does hang. This would not be recommended on
>> actual projects.
>>
>> At present, AmLogic chips are older than S4 Soc, and we have no way to
>> deal with this problem. We have to tell customers not to use it in this
>> way?Customers rarely use it in real projects.On the S4 SOC we will use
>> a clock like the UART pclk to control the shutdown using two registers,
>> one safe (need to operate in EL3) and one normal (EL1). It will only be
>> closed if both registers are closed. This mainly prevents misoperation.
> oh, interesting that there's some updates specifically with the S4 SoCs :-)
> 
>> With your experience, I'd like to know how you deal with this kind of
>> problem.
> Before this patch the driver simply turns on the clock from within
> meson_uart_probe() (specifically it does so in
> meson_uart_probe_clock()).
> I think there's advanced power-saving techniques. Maybe for now we
> keep it simple and just enable the clock(s) at probe time and disable
> them at driver remove time. What do you think?
> 
I agree with you.
> 
> Best regards,
> Martin
> 


From yu.tu at amlogic.com  Tue Jan  4 01:57:03 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 4 Jan 2022 17:57:03 +0800
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate calculation
 is described using the common clock code. Also added S4 chip uart
 Compatible.
In-Reply-To: <1jfsq57wym.fsf@starbuckisacylon.baylibre.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
 <1jfsq57wym.fsf@starbuckisacylon.baylibre.com>
Message-ID: <264367c8-2de1-ebd1-0843-e4e33a8407a6@amlogic.com>

Hi Jerome,
	Thank you very much for your reply.

On 2022/1/3 20:40, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> 
> On Thu 30 Dec 2021 at 18:21, Yu Tu <yu.tu at amlogic.com> wrote:
> 
>> Using the common Clock code to describe the UART baud rate clock makes
>> it easier for the UART driver to be compatible with the baud rate
>> requirements of the UART IP on different meson chips
>>
>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>> ---
>>   drivers/tty/serial/Kconfig      |   1 +
>>   drivers/tty/serial/meson_uart.c | 311 ++++++++++++++++++++++++++------
>>   2 files changed, 257 insertions(+), 55 deletions(-)
>>
>> diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
>> index 780908d43557..32e238173036 100644
>> --- a/drivers/tty/serial/Kconfig
>> +++ b/drivers/tty/serial/Kconfig
>> @@ -198,6 +198,7 @@ config SERIAL_KGDB_NMI
>>   config SERIAL_MESON
>>   	tristate "Meson serial port support"
>>   	depends on ARCH_MESON
>> +	depends on COMMON_CLK
>>   	select SERIAL_CORE
>>   	help
>>   	  This enables the driver for the on-chip UARTs of the Amlogic
>> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
>> index 99efe62a1507..07eb1f40aaaa 100644
>> --- a/drivers/tty/serial/meson_uart.c
>> +++ b/drivers/tty/serial/meson_uart.c
>> @@ -6,6 +6,7 @@
>>    */
>>   
>>   #include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>>   #include <linux/console.h>
>>   #include <linux/delay.h>
>>   #include <linux/init.h>
>> @@ -65,9 +66,7 @@
>>   #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>>   
>>   /* AML_UART_REG5 bits */
>> -#define AML_UART_BAUD_MASK		0x7fffff
>>   #define AML_UART_BAUD_USE		BIT(23)
>> -#define AML_UART_BAUD_XTAL		BIT(24)
>>   
>>   #define AML_UART_PORT_NUM		12
>>   #define AML_UART_PORT_OFFSET		6
>> @@ -76,6 +75,21 @@
>>   #define AML_UART_POLL_USEC		5
>>   #define AML_UART_TIMEOUT_USEC		10000
>>   
>> +struct meson_uart_data {
>> +	struct uart_port	port;
>> +	struct clk		*pclk;
>> +	struct clk		*baud_clk;
>> +	struct clk_divider	baud_div;
>> +	struct clk_mux		use_xtal_mux;
>> +	struct clk_mux		xtal_clk_sel_mux;
>> +	struct clk_mux		xtal2_clk_sel_mux;
>> +	struct clk_fixed_factor	xtal_div2;
>> +	struct clk_fixed_factor	xtal_div3;
>> +	struct clk_fixed_factor	clk81_div4;
> 
> Keeping all these internal elements around is not useful since they are
> registered using devm_
> 
I'm sorry. I don't know what you mean. That's exactly what you said, but 
what's wrong, I don't understand. Do you have any better suggestions, 
please specify specific points, preferably give examples.
>> +	bool			no_clk81_input;
> 
> What is this ?
> 
To distinguish between clK81 and XTAL.
>> +	bool			has_xtal_clk_sel;
>> +};
>> +
>>   static struct uart_driver meson_uart_driver;
>>   
>>   static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>> @@ -270,14 +284,11 @@ static void meson_uart_reset(struct uart_port *port)
>>   static int meson_uart_startup(struct uart_port *port)
>>   {
>>   	u32 val;
>> -	int ret = 0;
>> +	int ret;
>>   
>> -	val = readl(port->membase + AML_UART_CONTROL);
>> -	val |= AML_UART_CLEAR_ERR;
>> -	writel(val, port->membase + AML_UART_CONTROL);
>> -	val &= ~AML_UART_CLEAR_ERR;
>> -	writel(val, port->membase + AML_UART_CONTROL);
>> +	meson_uart_reset(port);
>>   
>> +	val = readl(port->membase + AML_UART_CONTROL);
>>   	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>>   	writel(val, port->membase + AML_UART_CONTROL);
>>   
>> @@ -295,19 +306,17 @@ static int meson_uart_startup(struct uart_port *port)
>>   
>>   static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
>>   {
>> +	struct meson_uart_data *private_data = port->private_data;
>>   	u32 val;
>>   
>>   	while (!meson_uart_tx_empty(port))
>>   		cpu_relax();
>>   
>> -	if (port->uartclk == 24000000) {
> 
> This check shows that previous code assumed bit 24 was left untouched
> Below you can see that GXBB and newer used the XTAL path while older
> used the other
> 
> Your change makes this dynamic which is another "unexpected" change.
> Please make the bit 24 mux RO to start with so the behavior remains unchanged
> for older SoCs.
I agree with what you say, and I will correct it.
> 
>> -		val = ((port->uartclk / 3) / baud) - 1;
>> -		val |= AML_UART_BAUD_XTAL;
>> -	} else {
>> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>> -	}
>> +	val = readl(port->membase + AML_UART_REG5);
>>   	val |= AML_UART_BAUD_USE;
>>   	writel(val, port->membase + AML_UART_REG5);
>> +
>> +	clk_set_rate(private_data->baud_clk, baud);
>>   }
>>   
>>   static void meson_uart_set_termios(struct uart_port *port,
>> @@ -397,11 +406,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>>   
>>   static void meson_uart_release_port(struct uart_port *port)
>>   {
>> -	/* nothing to do */
>> +	struct meson_uart_data *private_data = port->private_data;
>> +
>> +	clk_disable_unprepare(private_data->baud_clk);
>> +	clk_disable_unprepare(private_data->pclk);
>>   }
>>   
>>   static int meson_uart_request_port(struct uart_port *port)
>>   {
>> +	struct meson_uart_data *private_data = port->private_data;
>> +	int ret;
>> +
>> +	ret = clk_prepare_enable(private_data->pclk);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = clk_prepare_enable(private_data->baud_clk);
>> +	if (ret) {
>> +		clk_disable_unprepare(private_data->pclk);
>> +		return ret;
>> +	}
>> +
>>   	return 0;
>>   }
>>   
>> @@ -629,56 +654,175 @@ static struct uart_driver meson_uart_driver = {
>>   	.cons		= MESON_SERIAL_CONSOLE,
>>   };
>>   
>> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>> -						 const char *id)
>> +static int meson_uart_register_clk(struct uart_port *port,
>> +				   const char *name_suffix,
>> +				   const struct clk_parent_data *parent_data,
>> +				   unsigned int num_parents,
>> +				   const struct clk_ops *ops,
>> +				   struct clk_hw *hw)
>>   {
>> -	struct clk *clk = NULL;
>> +	struct clk_init_data init = { };
>> +	char clk_name[32];
>>   	int ret;
>>   
>> -	clk = devm_clk_get(dev, id);
>> -	if (IS_ERR(clk))
>> -		return clk;
>> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
>> +		 name_suffix);
>>   
>> -	ret = clk_prepare_enable(clk);
>> -	if (ret) {
>> -		dev_err(dev, "couldn't enable clk\n");
>> -		return ERR_PTR(ret);
>> -	}
>> +	init.name = clk_name;
>> +	init.ops = ops;
>> +	init.flags = CLK_SET_RATE_PARENT;
>> +	init.parent_data = parent_data;
>> +	init.num_parents = num_parents;
>> +
>> +	hw->init = &init;
>>   
>> -	devm_add_action_or_reset(dev,
>> -			(void(*)(void *))clk_disable_unprepare,
>> -			clk);
>> +	ret = devm_clk_hw_register(port->dev, hw);
>> +	if (ret)
>> +		return dev_err_probe(port->dev, ret,
>> +				     "Failed to register the '%s' clock\n",
>> +				     clk_name);
>>   
>> -	return clk;
>> +	return ret;
>>   }
>>   
>> -static int meson_uart_probe_clocks(struct platform_device *pdev,
>> -				   struct uart_port *port)
>> -{
>> -	struct clk *clk_xtal = NULL;
>> -	struct clk *clk_pclk = NULL;
>> -	struct clk *clk_baud = NULL;
>> +static int meson_uart_probe_clocks(struct uart_port *port,
>> +				   bool register_clk81_div4)
>> +{
>> +	struct meson_uart_data *private_data = port->private_data;
>> +	struct clk_parent_data use_xtal_mux_parents[2] = {
>> +		{ .index = -1, },
>> +		{ .index = -1, },
>> +	};
>> +	struct clk_parent_data xtal_clk_sel_mux_parents[2] = { };
>> +	struct clk_parent_data xtal2_clk_sel_mux_parents[2] = { };
>> +	struct clk_parent_data xtal_div_parent = { .fw_name = "xtal", };
>> +	struct clk_parent_data clk81_div_parent = { .fw_name = "baud", };
>> +	struct clk_parent_data baud_div_parent = { };
>> +	struct clk *clk_baud, *clk_xtal;
>> +	int ret;
>>   
>> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>> -	if (IS_ERR(clk_pclk))
>> -		return PTR_ERR(clk_pclk);
>> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
>> +	if (IS_ERR(private_data->pclk))
>> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
>> +				     "Failed to get the 'pclk' clock\n");
>> +
>> +	clk_baud = devm_clk_get(port->dev, "baud");
>> +	if (IS_ERR(clk_baud))
>> +		return dev_err_probe(port->dev, PTR_ERR(clk_baud),
>> +				     "Failed to get the 'baud' clock\n");
>>   
>> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>>   	if (IS_ERR(clk_xtal))
>> -		return PTR_ERR(clk_xtal);
>> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>> +				     "Failed to get the 'xtal' clock\n");
>> +
>> +	private_data->xtal_div3.mult = 1;
>> +	private_data->xtal_div3.div = 3;
>> +	ret = meson_uart_register_clk(port, "xtal_div3", &xtal_div_parent,
>> +				      1, &clk_fixed_factor_ops,
>> +				      &private_data->xtal_div3.hw);
>> +	if (ret)
>> +		return ret;
>>   
>> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>> -	if (IS_ERR(clk_baud))
>> -		return PTR_ERR(clk_baud);
>> +	if (register_clk81_div4) {
> 
> Clock dividers represent HW elements. The presence of an HW element cannot
> dependent on the current of the input clocks. There is no way this is right
> 
>> +		private_data->clk81_div4.mult = 1;
>> +		private_data->clk81_div4.div = 4;
>> +		ret = meson_uart_register_clk(port, "clk81_div4",
>> +					      &clk81_div_parent, 1,
>> +					      &clk_fixed_factor_ops,
>> +					      &private_data->clk81_div4.hw);
>> +		if (ret)
>> +			return ret;
>> +
>> +		use_xtal_mux_parents[0].hw = &private_data->clk81_div4.hw;
> 
> This is only going to be used on meson8 and older. Worst case it should depend
> on this compatible but I don't think this would be right here.
> 
> IMO, this shows that the UART "baud" input was actually fed by a
> derivation of "fclk_div4" instead of "clk_81" on these older SoCs.
> 
> So instead of registering what I suspect to be a fake element, the
> meson8 clock controller driver and DT should be fixed a this should go away.
> 
Virtually all UART controllers are supported, but they are not used 
after Meson8. So the description is more reasonable in UART driver.
>> +	}
>>   
>> -	port->uartclk = clk_get_rate(clk_baud);
>> +	if (private_data->has_xtal_clk_sel) {
>> +		private_data->xtal_div2.mult = 1;
>> +		private_data->xtal_div2.div = 2;
>> +		ret = meson_uart_register_clk(port, "xtal_div2",
>> +					      &xtal_div_parent, 1,
>> +					      &clk_fixed_factor_ops,
>> +					      &private_data->xtal_div2.hw);
>> +		if (ret)
>> +			return ret;
>> +
>> +		xtal_clk_sel_mux_parents[0].hw = &private_data->xtal_div3.hw;
>> +		xtal_clk_sel_mux_parents[1].fw_name = "xtal";
>> +
>> +		private_data->xtal_clk_sel_mux.reg = port->membase + AML_UART_REG5;
>> +		private_data->xtal_clk_sel_mux.mask = 0x1;
>> +		private_data->xtal_clk_sel_mux.shift = 26;
>> +		private_data->xtal_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
>> +		ret = meson_uart_register_clk(port, "xtal_clk_sel",
>> +					      xtal_clk_sel_mux_parents,
>> +					      ARRAY_SIZE(xtal_clk_sel_mux_parents),
>> +					      &clk_mux_ops,
>> +					      &private_data->xtal_clk_sel_mux.hw);
>> +		if (ret)
>> +			return ret;
>> +
>> +		xtal2_clk_sel_mux_parents[0].hw = &private_data->xtal_clk_sel_mux.hw;
>> +		xtal2_clk_sel_mux_parents[1].hw = &private_data->xtal_div2.hw;
>> +
>> +		private_data->xtal2_clk_sel_mux.reg = port->membase + AML_UART_REG5;
>> +		private_data->xtal2_clk_sel_mux.mask = 0x1;
>> +		private_data->xtal2_clk_sel_mux.shift = 27;
>> +		private_data->xtal2_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
>> +		ret = meson_uart_register_clk(port, "xtal2_clk_sel",
>> +					      xtal2_clk_sel_mux_parents,
>> +					      ARRAY_SIZE(xtal2_clk_sel_mux_parents),
>> +					      &clk_mux_ops,
>> +					      &private_data->xtal2_clk_sel_mux.hw);
>> +		if (ret)
>> +			return ret;
>> +
>> +		use_xtal_mux_parents[1].hw = &private_data->xtal2_clk_sel_mux.hw;
>> +	} else {
>> +		use_xtal_mux_parents[1].hw = &private_data->xtal_div3.hw;
> 
> Well the above is a bit over-complicated. If I summarize:
> 
> GXBB and older used a fixed divider of 3. Bits 26 and 27 read
> 0 according to the documentation.
> 
> Chips after GXBB have 2 configurable divider of 2 and 3. bits 26 and 27
> selects which of these dividers is used.
> 
> So the above could be replaced with a single divider covering bits 26 and 27
> with the following divider table { 2, 2, 1, 3 }. The divider should use
> RO ops and not have CLK_SET_RATE_PARENT. It can be used for all chips
> variant like this, including the older ones.
> 
As you say, the way you say it is complicated. I think you're 
complicating things.I don't understand what you're trying to achieve.
Can you be more specific?

> The only information you need to carry if whether or not you want to
> make this divider modifiable. This means using the dt data to store
> clk_div_ops or clk_div_ro_ops pointer.
> 
> To avoid changing the behavior of the older platforms in this patch, I would
> suggest to make everything use clk_div_ro_ops first, and make another
> patch to use clk_div_ops if necessary.
> 
> 
>> +	}
>> +
>> +	private_data->use_xtal_mux.reg = port->membase + AML_UART_REG5;
>> +	private_data->use_xtal_mux.mask = 0x1;
>> +	private_data->use_xtal_mux.shift = 24;
>> +	private_data->use_xtal_mux.flags = CLK_MUX_ROUND_CLOSEST;
>> +	ret = meson_uart_register_clk(port, "use_xtal", use_xtal_mux_parents,
>> +				      ARRAY_SIZE(use_xtal_mux_parents),
>> +				      &clk_mux_ops,
> 
> Use RO ops here to start with.
> You can make this writable with another patch explicitly describing the change.
I agree with what you say, and I will correct it.
> 
>> +				      &private_data->use_xtal_mux.hw);
>> +	if (ret)
>> +		return ret;
>> +
>> +	baud_div_parent.hw = &private_data->use_xtal_mux.hw;
>> +
>> +	private_data->baud_div.reg = port->membase + AML_UART_REG5;
>> +	private_data->baud_div.shift = 0;
>> +	private_data->baud_div.width = 23;
>> +	private_data->baud_div.flags = CLK_DIVIDER_ROUND_CLOSEST;
>> +	ret = meson_uart_register_clk(port, "baud_div",
>> +				      &baud_div_parent, 1,
>> +				      &clk_divider_ops,
>> +				      &private_data->baud_div.hw);
>> +	if (ret)
>> +		return ret;
>> +
>> +	private_data->baud_clk = devm_clk_hw_get_clk(port->dev,
>> +						     &private_data->baud_div.hw,
>> +						     "baud_rate");
> 
> There is a problem with this function in CCF. It will pin the driver to
> itself, making it unremovable. It is an ongoing topic. For now, just use
> "hw->clk" to get the struct *clk.
> 
>> +	if (IS_ERR(private_data->baud_clk))
>> +		return dev_err_probe(port->dev,
> 
> I don't think anything can defer here, so dev_err_probe() is not
> necessary I think
> 
I agree with what you say, and I will correct it.
>> +				     PTR_ERR(private_data->baud_clk),
>> +				     "Failed to request the 'baud_rate' clock\n");
>>   
>>   	return 0;
>>   }
>>   
>>   static int meson_uart_probe(struct platform_device *pdev)
>>   {
>> +	struct meson_uart_data *private_data;
>>   	struct resource *res_mem, *res_irq;
>> +	struct clk *clk_baud, *clk_xtal;
>> +	bool register_clk81_div4;
>>   	struct uart_port *port;
>>   	int ret = 0;
>>   	int id = -1;
>> @@ -711,18 +855,37 @@ static int meson_uart_probe(struct platform_device *pdev)
>>   		return -EBUSY;
>>   	}
>>   
>> -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
>> -	if (!port)
>> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
>> +				    GFP_KERNEL);
>> +	if (!private_data)
>>   		return -ENOMEM;
>>   
>> +	if (device_get_match_data(&pdev->dev))
>> +		private_data->has_xtal_clk_sel = true;
>> +
>> +	private_data->pclk = devm_clk_get(&pdev->dev, "pclk");
>> +	if (IS_ERR(private_data->pclk))
>> +		return dev_err_probe(&pdev->dev, PTR_ERR(private_data->pclk),
>> +				     "Failed to get the 'pclk' clock\n");
>> +
>> +	clk_baud = devm_clk_get(&pdev->dev, "baud");
>> +	if (IS_ERR(clk_baud))
>> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk_baud),
>> +				     "Failed to get the 'baud' clock\n");
>> +
>> +	clk_xtal = devm_clk_get(&pdev->dev, "xtal");
>> +	if (IS_ERR(clk_xtal))
>> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk_xtal),
>> +				     "Failed to get the 'xtal' clock\n");
>> +
> 
> This is second time you call devm_clk_get() on these clocks. One
> instance has to go away
> 
I agree with what you say, and I will correct it.
>> +	register_clk81_div4 = clk_get_rate(clk_xtal) != clk_get_rate(clk_baud);
>> +
> 
> The above is a ugly way to distinguish the meson8 (32bit) SoC family
> from the rest. This definitely not the way to achieve it.
> 
> The right is the compatible data but here I think it is not
> necessary. The clock input should be fixed.
> 
>> +	port = &private_data->port;
>> +
>>   	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>>   	if (IS_ERR(port->membase))
>>   		return PTR_ERR(port->membase);
>>   
>> -	ret = meson_uart_probe_clocks(pdev, port);
>> -	if (ret)
>> -		return ret;
>> -
>>   	port->iotype = UPIO_MEM;
>>   	port->mapbase = res_mem->start;
>>   	port->mapsize = resource_size(res_mem);
>> @@ -735,6 +898,12 @@ static int meson_uart_probe(struct platform_device *pdev)
>>   	port->x_char = 0;
>>   	port->ops = &meson_uart_ops;
>>   	port->fifosize = 64;
>> +	port->uartclk = clk_get_rate(clk_baud);
>> +	port->private_data = private_data;
>> +
>> +	ret = meson_uart_probe_clocks(port, register_clk81_div4);
>> +	if (ret)
>> +		return ret;
>>   
>>   	meson_ports[pdev->id] = port;
>>   	platform_set_drvdata(pdev, port);
>> @@ -761,10 +930,42 @@ static int meson_uart_remove(struct platform_device *pdev)
>>   }
>>   
>>   static const struct of_device_id meson_uart_dt_match[] = {
>> -	{ .compatible = "amlogic,meson6-uart" },
>> -	{ .compatible = "amlogic,meson8-uart" },
>> -	{ .compatible = "amlogic,meson8b-uart" },
>> -	{ .compatible = "amlogic,meson-gx-uart" },
>> +	{
>> +		.compatible = "amlogic,meson6-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson8-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson8b-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-gxbb-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-gxl-uart",
>> +		.data = (void *)true,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-g12a-uart",
>> +		.data = (void *)true,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-s4-uart",
>> +		.data = (void *)true,
>> +	},
>> +	/*
>> +	 * deprecated, don't use anymore because it doesn't differentiate
>> +	 * between GXBB and GXL which have different revisions of the UART IP.
>> +	 */
>> +	{
>> +		.compatible = "amlogic,meson-gx-uart",
>> +		.data = (void *)false,
>> +	},
>>   	{ /* sentinel */ },
>>   };
>>   MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
> 


From jbrunet at baylibre.com  Tue Jan  4 02:36:25 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Tue, 04 Jan 2022 11:36:25 +0100
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate
 calculation is described using the common clock code. Also added S4 chip
 uart Compatible.
In-Reply-To: <264367c8-2de1-ebd1-0843-e4e33a8407a6@amlogic.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
 <1jfsq57wym.fsf@starbuckisacylon.baylibre.com>
 <264367c8-2de1-ebd1-0843-e4e33a8407a6@amlogic.com>
Message-ID: <1jpmp7rc1z.fsf@starbuckisacylon.baylibre.com>


On Tue 04 Jan 2022 at 17:57, Yu Tu <yu.tu at amlogic.com> wrote:

> Hi Jerome,
> 	Thank you very much for your reply.
>
> On 2022/1/3 20:40, Jerome Brunet wrote:
>> [ EXTERNAL EMAIL ]
>> 
>> On Thu 30 Dec 2021 at 18:21, Yu Tu <yu.tu at amlogic.com> wrote:
>> 
>>> Using the common Clock code to describe the UART baud rate clock makes
>>> it easier for the UART driver to be compatible with the baud rate
>>> requirements of the UART IP on different meson chips
>>>
>>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>>> ---
>>>   drivers/tty/serial/Kconfig      |   1 +
>>>   drivers/tty/serial/meson_uart.c | 311 ++++++++++++++++++++++++++------
>>>   2 files changed, 257 insertions(+), 55 deletions(-)
>>>
>>> diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
>>> index 780908d43557..32e238173036 100644
>>> --- a/drivers/tty/serial/Kconfig
>>> +++ b/drivers/tty/serial/Kconfig
>>> @@ -198,6 +198,7 @@ config SERIAL_KGDB_NMI
>>>   config SERIAL_MESON
>>>   	tristate "Meson serial port support"
>>>   	depends on ARCH_MESON
>>> +	depends on COMMON_CLK
>>>   	select SERIAL_CORE
>>>   	help
>>>   	  This enables the driver for the on-chip UARTs of the Amlogic
>>> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
>>> index 99efe62a1507..07eb1f40aaaa 100644
>>> --- a/drivers/tty/serial/meson_uart.c
>>> +++ b/drivers/tty/serial/meson_uart.c
>>> @@ -6,6 +6,7 @@
>>>    */
>>>     #include <linux/clk.h>
>>> +#include <linux/clk-provider.h>
>>>   #include <linux/console.h>
>>>   #include <linux/delay.h>
>>>   #include <linux/init.h>
>>> @@ -65,9 +66,7 @@
>>>   #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>>>     /* AML_UART_REG5 bits */
>>> -#define AML_UART_BAUD_MASK		0x7fffff
>>>   #define AML_UART_BAUD_USE		BIT(23)
>>> -#define AML_UART_BAUD_XTAL		BIT(24)
>>>     #define AML_UART_PORT_NUM		12
>>>   #define AML_UART_PORT_OFFSET		6
>>> @@ -76,6 +75,21 @@
>>>   #define AML_UART_POLL_USEC		5
>>>   #define AML_UART_TIMEOUT_USEC		10000
>>>   +struct meson_uart_data {
>>> +	struct uart_port	port;
>>> +	struct clk		*pclk;
>>> +	struct clk		*baud_clk;
>>> +	struct clk_divider	baud_div;
>>> +	struct clk_mux		use_xtal_mux;
>>> +	struct clk_mux		xtal_clk_sel_mux;
>>> +	struct clk_mux		xtal2_clk_sel_mux;
>>> +	struct clk_fixed_factor	xtal_div2;
>>> +	struct clk_fixed_factor	xtal_div3;
>>> +	struct clk_fixed_factor	clk81_div4;
>> Keeping all these internal elements around is not useful since they are
>> registered using devm_
>> 
> I'm sorry. I don't know what you mean. That's exactly what you said, but
> what's wrong, I don't understand. Do you have any better suggestions, 
> please specify specific points, preferably give examples.

I'm saying that you don't need to keep reference to the internal
elements of the clock tree you have registered since devm_ will take
care of the removal later on. IOW, Once they are registered, the pointer
is never used again so you don't need it in the private data.


>>> +	bool			no_clk81_input;
>> What is this ?
>> 
> To distinguish between clK81 and XTAL.

... Yet, it is not used

>>> +	bool			has_xtal_clk_sel;
>>> +};
>>> +
>>>   static struct uart_driver meson_uart_driver;
>>>     static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>>> @@ -270,14 +284,11 @@ static void meson_uart_reset(struct uart_port *port)
>>>   static int meson_uart_startup(struct uart_port *port)
>>>   {
>>>   	u32 val;
>>> -	int ret = 0;
>>> +	int ret;
>>>   -	val = readl(port->membase + AML_UART_CONTROL);
>>> -	val |= AML_UART_CLEAR_ERR;
>>> -	writel(val, port->membase + AML_UART_CONTROL);
>>> -	val &= ~AML_UART_CLEAR_ERR;
>>> -	writel(val, port->membase + AML_UART_CONTROL);
>>> +	meson_uart_reset(port);
>>>   +	val = readl(port->membase + AML_UART_CONTROL);
>>>   	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>>>   	writel(val, port->membase + AML_UART_CONTROL);
>>>   @@ -295,19 +306,17 @@ static int meson_uart_startup(struct uart_port
>>> *port)
>>>     static void meson_uart_change_speed(struct uart_port *port, unsigned
>>> long baud)
>>>   {
>>> +	struct meson_uart_data *private_data = port->private_data;
>>>   	u32 val;
>>>     	while (!meson_uart_tx_empty(port))
>>>   		cpu_relax();
>>>   -	if (port->uartclk == 24000000) {
>> This check shows that previous code assumed bit 24 was left untouched
>> Below you can see that GXBB and newer used the XTAL path while older
>> used the other
>> Your change makes this dynamic which is another "unexpected" change.
>> Please make the bit 24 mux RO to start with so the behavior remains unchanged
>> for older SoCs.
> I agree with what you say, and I will correct it.
>> 
>>> -		val = ((port->uartclk / 3) / baud) - 1;
>>> -		val |= AML_UART_BAUD_XTAL;
>>> -	} else {
>>> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>>> -	}
>>> +	val = readl(port->membase + AML_UART_REG5);
>>>   	val |= AML_UART_BAUD_USE;
>>>   	writel(val, port->membase + AML_UART_REG5);
>>> +
>>> +	clk_set_rate(private_data->baud_clk, baud);
>>>   }
>>>     static void meson_uart_set_termios(struct uart_port *port,
>>> @@ -397,11 +406,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>>>     static void meson_uart_release_port(struct uart_port *port)
>>>   {
>>> -	/* nothing to do */
>>> +	struct meson_uart_data *private_data = port->private_data;
>>> +
>>> +	clk_disable_unprepare(private_data->baud_clk);
>>> +	clk_disable_unprepare(private_data->pclk);
>>>   }
>>>     static int meson_uart_request_port(struct uart_port *port)
>>>   {
>>> +	struct meson_uart_data *private_data = port->private_data;
>>> +	int ret;
>>> +
>>> +	ret = clk_prepare_enable(private_data->pclk);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	ret = clk_prepare_enable(private_data->baud_clk);
>>> +	if (ret) {
>>> +		clk_disable_unprepare(private_data->pclk);
>>> +		return ret;
>>> +	}
>>> +
>>>   	return 0;
>>>   }
>>>   @@ -629,56 +654,175 @@ static struct uart_driver meson_uart_driver = {
>>>   	.cons		= MESON_SERIAL_CONSOLE,
>>>   };
>>>   -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>>> -						 const char *id)
>>> +static int meson_uart_register_clk(struct uart_port *port,
>>> +				   const char *name_suffix,
>>> +				   const struct clk_parent_data *parent_data,
>>> +				   unsigned int num_parents,
>>> +				   const struct clk_ops *ops,
>>> +				   struct clk_hw *hw)
>>>   {
>>> -	struct clk *clk = NULL;
>>> +	struct clk_init_data init = { };
>>> +	char clk_name[32];
>>>   	int ret;
>>>   -	clk = devm_clk_get(dev, id);
>>> -	if (IS_ERR(clk))
>>> -		return clk;
>>> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
>>> +		 name_suffix);
>>>   -	ret = clk_prepare_enable(clk);
>>> -	if (ret) {
>>> -		dev_err(dev, "couldn't enable clk\n");
>>> -		return ERR_PTR(ret);
>>> -	}
>>> +	init.name = clk_name;
>>> +	init.ops = ops;
>>> +	init.flags = CLK_SET_RATE_PARENT;
>>> +	init.parent_data = parent_data;
>>> +	init.num_parents = num_parents;
>>> +
>>> +	hw->init = &init;
>>>   -	devm_add_action_or_reset(dev,
>>> -			(void(*)(void *))clk_disable_unprepare,
>>> -			clk);
>>> +	ret = devm_clk_hw_register(port->dev, hw);
>>> +	if (ret)
>>> +		return dev_err_probe(port->dev, ret,
>>> +				     "Failed to register the '%s' clock\n",
>>> +				     clk_name);
>>>   -	return clk;
>>> +	return ret;
>>>   }
>>>   -static int meson_uart_probe_clocks(struct platform_device *pdev,
>>> -				   struct uart_port *port)
>>> -{
>>> -	struct clk *clk_xtal = NULL;
>>> -	struct clk *clk_pclk = NULL;
>>> -	struct clk *clk_baud = NULL;
>>> +static int meson_uart_probe_clocks(struct uart_port *port,
>>> +				   bool register_clk81_div4)
>>> +{
>>> +	struct meson_uart_data *private_data = port->private_data;
>>> +	struct clk_parent_data use_xtal_mux_parents[2] = {
>>> +		{ .index = -1, },
>>> +		{ .index = -1, },
>>> +	};
>>> +	struct clk_parent_data xtal_clk_sel_mux_parents[2] = { };
>>> +	struct clk_parent_data xtal2_clk_sel_mux_parents[2] = { };
>>> +	struct clk_parent_data xtal_div_parent = { .fw_name = "xtal", };
>>> +	struct clk_parent_data clk81_div_parent = { .fw_name = "baud", };
>>> +	struct clk_parent_data baud_div_parent = { };
>>> +	struct clk *clk_baud, *clk_xtal;
>>> +	int ret;
>>>   -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>>> -	if (IS_ERR(clk_pclk))
>>> -		return PTR_ERR(clk_pclk);
>>> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
>>> +	if (IS_ERR(private_data->pclk))
>>> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
>>> +				     "Failed to get the 'pclk' clock\n");
>>> +
>>> +	clk_baud = devm_clk_get(port->dev, "baud");
>>> +	if (IS_ERR(clk_baud))
>>> +		return dev_err_probe(port->dev, PTR_ERR(clk_baud),
>>> +				     "Failed to get the 'baud' clock\n");
>>>   -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>>> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>>>   	if (IS_ERR(clk_xtal))
>>> -		return PTR_ERR(clk_xtal);
>>> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>>> +				     "Failed to get the 'xtal' clock\n");
>>> +
>>> +	private_data->xtal_div3.mult = 1;
>>> +	private_data->xtal_div3.div = 3;
>>> +	ret = meson_uart_register_clk(port, "xtal_div3", &xtal_div_parent,
>>> +				      1, &clk_fixed_factor_ops,
>>> +				      &private_data->xtal_div3.hw);
>>> +	if (ret)
>>> +		return ret;
>>>   -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>>> -	if (IS_ERR(clk_baud))
>>> -		return PTR_ERR(clk_baud);
>>> +	if (register_clk81_div4) {
>> Clock dividers represent HW elements. The presence of an HW element
>> cannot
>> dependent on the current of the input clocks. There is no way this is right
>> 
>>> +		private_data->clk81_div4.mult = 1;
>>> +		private_data->clk81_div4.div = 4;
>>> +		ret = meson_uart_register_clk(port, "clk81_div4",
>>> +					      &clk81_div_parent, 1,
>>> +					      &clk_fixed_factor_ops,
>>> +					      &private_data->clk81_div4.hw);
>>> +		if (ret)
>>> +			return ret;
>>> +
>>> +		use_xtal_mux_parents[0].hw = &private_data->clk81_div4.hw;
>> This is only going to be used on meson8 and older. Worst case it should
>> depend
>> on this compatible but I don't think this would be right here.
>> IMO, this shows that the UART "baud" input was actually fed by a
>> derivation of "fclk_div4" instead of "clk_81" on these older SoCs.
>> So instead of registering what I suspect to be a fake element, the
>> meson8 clock controller driver and DT should be fixed a this should go away.
>> 
> Virtually all UART controllers are supported, but they are not used after
> Meson8. So the description is more reasonable in UART driver.

No it is not. It's not virtual, the support for meson8 is there in
mainline.

Unless you tell me there is an actual /4 divider in the UART block of
the meson8 and older and that is was removed from the newer SoC,
the bit above should be removed and the meson8 clock tree fixed.

I think it is more probable that the /4 was never there to begin with,
and that clk81/4 aka "fclk_div4", which is already available from the
clock controller, was actually routed on these older SoCs.

>>> +	}
>>>   -	port->uartclk = clk_get_rate(clk_baud);
>>> +	if (private_data->has_xtal_clk_sel) {
>>> +		private_data->xtal_div2.mult = 1;
>>> +		private_data->xtal_div2.div = 2;
>>> +		ret = meson_uart_register_clk(port, "xtal_div2",
>>> +					      &xtal_div_parent, 1,
>>> +					      &clk_fixed_factor_ops,
>>> +					      &private_data->xtal_div2.hw);
>>> +		if (ret)
>>> +			return ret;
>>> +
>>> +		xtal_clk_sel_mux_parents[0].hw = &private_data->xtal_div3.hw;
>>> +		xtal_clk_sel_mux_parents[1].fw_name = "xtal";
>>> +
>>> +		private_data->xtal_clk_sel_mux.reg = port->membase + AML_UART_REG5;
>>> +		private_data->xtal_clk_sel_mux.mask = 0x1;
>>> +		private_data->xtal_clk_sel_mux.shift = 26;
>>> +		private_data->xtal_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
>>> +		ret = meson_uart_register_clk(port, "xtal_clk_sel",
>>> +					      xtal_clk_sel_mux_parents,
>>> +					      ARRAY_SIZE(xtal_clk_sel_mux_parents),
>>> +					      &clk_mux_ops,
>>> +					      &private_data->xtal_clk_sel_mux.hw);
>>> +		if (ret)
>>> +			return ret;
>>> +
>>> +		xtal2_clk_sel_mux_parents[0].hw = &private_data->xtal_clk_sel_mux.hw;
>>> +		xtal2_clk_sel_mux_parents[1].hw = &private_data->xtal_div2.hw;
>>> +
>>> +		private_data->xtal2_clk_sel_mux.reg = port->membase + AML_UART_REG5;
>>> +		private_data->xtal2_clk_sel_mux.mask = 0x1;
>>> +		private_data->xtal2_clk_sel_mux.shift = 27;
>>> +		private_data->xtal2_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
>>> +		ret = meson_uart_register_clk(port, "xtal2_clk_sel",
>>> +					      xtal2_clk_sel_mux_parents,
>>> +					      ARRAY_SIZE(xtal2_clk_sel_mux_parents),
>>> +					      &clk_mux_ops,
>>> +					      &private_data->xtal2_clk_sel_mux.hw);
>>> +		if (ret)
>>> +			return ret;
>>> +
>>> +		use_xtal_mux_parents[1].hw = &private_data->xtal2_clk_sel_mux.hw;
>>> +	} else {
>>> +		use_xtal_mux_parents[1].hw = &private_data->xtal_div3.hw;
>> Well the above is a bit over-complicated. If I summarize:
>> GXBB and older used a fixed divider of 3. Bits 26 and 27 read
>> 0 according to the documentation.
>> Chips after GXBB have 2 configurable divider of 2 and 3. bits 26 and 27
>> selects which of these dividers is used.
>> So the above could be replaced with a single divider covering bits 26 and
>> 27
>> with the following divider table { 2, 2, 1, 3 }. The divider should use
>> RO ops and not have CLK_SET_RATE_PARENT. It can be used for all chips
>> variant like this, including the older ones.
>> 
> As you say, the way you say it is complicated. I think you're complicating
> things.I don't understand what you're trying to achieve.
> Can you be more specific?

I'm proposing to replace the 4 elements above, paths, parent_table and
all with a single divider with a specific table. It accomplishes the same thing.

|--------+--------+-----------|
| Bit 27 | Bit 26 | Div Value |
|--------+--------+-----------|
|      0 |      0 |         3 |
|--------+--------+-----------|
|      0 |      1 |         1 |
|--------+--------+-----------|
|      1 |      0 |         2 |
|--------+--------+-----------|
|      1 |      1 |         2 |
|--------+--------+-----------|

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/clk-provider.h?h=v5.16-rc8#n602

something like:

static struct clk_div_table reg5_table[] = {
	{ 0, 3 },
        { 1, 1 },
        { 2, 2 },
        { 3, 2 },
};

I'm also pointing out that, since bit 26 and 27 reads 0 on the older
SoCs, the divider would work for these too, as long as the Ops is
read-only. So you don't even need to register different element
depending on the SoC which simplify things a bit more.

If you prefer to keep a fixed divider for the older ones, It's fine by
me. It gives a bit more work but it is closer to reality. The newer SoC
could still use the custom divider regardless.

Last, and as explained on other bits, that part of the clock path should
remain RO at first, to keep behavior stable with this change. You may
change that later on, in a dedicated patch describing the change.

>
>> The only information you need to carry if whether or not you want to
>> make this divider modifiable. This means using the dt data to store
>> clk_div_ops or clk_div_ro_ops pointer.
>> To avoid changing the behavior of the older platforms in this patch, I
>> would
>> suggest to make everything use clk_div_ro_ops first, and make another
>> patch to use clk_div_ops if necessary.
>> 
>>> +	}
>>> +
>>> +	private_data->use_xtal_mux.reg = port->membase + AML_UART_REG5;
>>> +	private_data->use_xtal_mux.mask = 0x1;
>>> +	private_data->use_xtal_mux.shift = 24;
>>> +	private_data->use_xtal_mux.flags = CLK_MUX_ROUND_CLOSEST;
>>> +	ret = meson_uart_register_clk(port, "use_xtal", use_xtal_mux_parents,
>>> +				      ARRAY_SIZE(use_xtal_mux_parents),
>>> +				      &clk_mux_ops,
>> Use RO ops here to start with.
>> You can make this writable with another patch explicitly describing the change.
> I agree with what you say, and I will correct it.
>> 
>>> +				      &private_data->use_xtal_mux.hw);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	baud_div_parent.hw = &private_data->use_xtal_mux.hw;
>>> +
>>> +	private_data->baud_div.reg = port->membase + AML_UART_REG5;
>>> +	private_data->baud_div.shift = 0;
>>> +	private_data->baud_div.width = 23;
>>> +	private_data->baud_div.flags = CLK_DIVIDER_ROUND_CLOSEST;
>>> +	ret = meson_uart_register_clk(port, "baud_div",
>>> +				      &baud_div_parent, 1,
>>> +				      &clk_divider_ops,
>>> +				      &private_data->baud_div.hw);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	private_data->baud_clk = devm_clk_hw_get_clk(port->dev,
>>> +						     &private_data->baud_div.hw,
>>> +						     "baud_rate");
>> There is a problem with this function in CCF. It will pin the driver to
>> itself, making it unremovable. It is an ongoing topic. For now, just use
>> "hw->clk" to get the struct *clk.
>> 
>>> +	if (IS_ERR(private_data->baud_clk))
>>> +		return dev_err_probe(port->dev,
>> I don't think anything can defer here, so dev_err_probe() is not
>> necessary I think
>> 
> I agree with what you say, and I will correct it.
>>> +				     PTR_ERR(private_data->baud_clk),
>>> +				     "Failed to request the 'baud_rate' clock\n");
>>>     	return 0;
>>>   }
>>>     static int meson_uart_probe(struct platform_device *pdev)
>>>   {
>>> +	struct meson_uart_data *private_data;
>>>   	struct resource *res_mem, *res_irq;
>>> +	struct clk *clk_baud, *clk_xtal;
>>> +	bool register_clk81_div4;
>>>   	struct uart_port *port;
>>>   	int ret = 0;
>>>   	int id = -1;
>>> @@ -711,18 +855,37 @@ static int meson_uart_probe(struct platform_device *pdev)
>>>   		return -EBUSY;
>>>   	}
>>>   -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port),
>>> GFP_KERNEL);
>>> -	if (!port)
>>> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
>>> +				    GFP_KERNEL);
>>> +	if (!private_data)
>>>   		return -ENOMEM;
>>>   +	if (device_get_match_data(&pdev->dev))
>>> +		private_data->has_xtal_clk_sel = true;
>>> +
>>> +	private_data->pclk = devm_clk_get(&pdev->dev, "pclk");
>>> +	if (IS_ERR(private_data->pclk))
>>> +		return dev_err_probe(&pdev->dev, PTR_ERR(private_data->pclk),
>>> +				     "Failed to get the 'pclk' clock\n");
>>> +
>>> +	clk_baud = devm_clk_get(&pdev->dev, "baud");
>>> +	if (IS_ERR(clk_baud))
>>> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk_baud),
>>> +				     "Failed to get the 'baud' clock\n");
>>> +
>>> +	clk_xtal = devm_clk_get(&pdev->dev, "xtal");
>>> +	if (IS_ERR(clk_xtal))
>>> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk_xtal),
>>> +				     "Failed to get the 'xtal' clock\n");
>>> +
>> This is second time you call devm_clk_get() on these clocks. One
>> instance has to go away
>> 
> I agree with what you say, and I will correct it.
>>> +	register_clk81_div4 = clk_get_rate(clk_xtal) != clk_get_rate(clk_baud);
>>> +
>> The above is a ugly way to distinguish the meson8 (32bit) SoC family
>> from the rest. This definitely not the way to achieve it.
>> The right is the compatible data but here I think it is not
>> necessary. The clock input should be fixed.
>> 
>>> +	port = &private_data->port;
>>> +
>>>   	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>>>   	if (IS_ERR(port->membase))
>>>   		return PTR_ERR(port->membase);
>>>   -	ret = meson_uart_probe_clocks(pdev, port);
>>> -	if (ret)
>>> -		return ret;
>>> -
>>>   	port->iotype = UPIO_MEM;
>>>   	port->mapbase = res_mem->start;
>>>   	port->mapsize = resource_size(res_mem);
>>> @@ -735,6 +898,12 @@ static int meson_uart_probe(struct platform_device *pdev)
>>>   	port->x_char = 0;
>>>   	port->ops = &meson_uart_ops;
>>>   	port->fifosize = 64;
>>> +	port->uartclk = clk_get_rate(clk_baud);
>>> +	port->private_data = private_data;
>>> +
>>> +	ret = meson_uart_probe_clocks(port, register_clk81_div4);
>>> +	if (ret)
>>> +		return ret;
>>>     	meson_ports[pdev->id] = port;
>>>   	platform_set_drvdata(pdev, port);
>>> @@ -761,10 +930,42 @@ static int meson_uart_remove(struct platform_device *pdev)
>>>   }
>>>     static const struct of_device_id meson_uart_dt_match[] = {
>>> -	{ .compatible = "amlogic,meson6-uart" },
>>> -	{ .compatible = "amlogic,meson8-uart" },
>>> -	{ .compatible = "amlogic,meson8b-uart" },
>>> -	{ .compatible = "amlogic,meson-gx-uart" },
>>> +	{
>>> +		.compatible = "amlogic,meson6-uart",
>>> +		.data = (void *)false,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson8-uart",
>>> +		.data = (void *)false,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson8b-uart",
>>> +		.data = (void *)false,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson-gxbb-uart",
>>> +		.data = (void *)false,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson-gxl-uart",
>>> +		.data = (void *)true,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson-g12a-uart",
>>> +		.data = (void *)true,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson-s4-uart",
>>> +		.data = (void *)true,
>>> +	},
>>> +	/*
>>> +	 * deprecated, don't use anymore because it doesn't differentiate
>>> +	 * between GXBB and GXL which have different revisions of the UART IP.
>>> +	 */
>>> +	{
>>> +		.compatible = "amlogic,meson-gx-uart",
>>> +		.data = (void *)false,
>>> +	},
>>>   	{ /* sentinel */ },
>>>   };
>>>   MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
>> 



From yu.tu at amlogic.com  Tue Jan  4 06:35:54 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 4 Jan 2022 22:35:54 +0800
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate calculation
 is described using the common clock code. Also added S4 chip uart
 Compatible.
In-Reply-To: <1jpmp7rc1z.fsf@starbuckisacylon.baylibre.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
 <1jfsq57wym.fsf@starbuckisacylon.baylibre.com>
 <264367c8-2de1-ebd1-0843-e4e33a8407a6@amlogic.com>
 <1jpmp7rc1z.fsf@starbuckisacylon.baylibre.com>
Message-ID: <318ec2df-b73b-520b-f5ac-d0d2fce0eff0@amlogic.com>

Hi Jerome,
	Thank you very much for your patient reply. I have learned a lot from it.

On 2022/1/4 18:36, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> 
> On Tue 04 Jan 2022 at 17:57, Yu Tu <yu.tu at amlogic.com> wrote:
> 
>> Hi Jerome,
>> 	Thank you very much for your reply.
>>
>> On 2022/1/3 20:40, Jerome Brunet wrote:
>>> [ EXTERNAL EMAIL ]
>>>
>>> On Thu 30 Dec 2021 at 18:21, Yu Tu <yu.tu at amlogic.com> wrote:
>>>
>>>> Using the common Clock code to describe the UART baud rate clock makes
>>>> it easier for the UART driver to be compatible with the baud rate
>>>> requirements of the UART IP on different meson chips
>>>>
>>>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>>>> ---
>>>>    drivers/tty/serial/Kconfig      |   1 +
>>>>    drivers/tty/serial/meson_uart.c | 311 ++++++++++++++++++++++++++------
>>>>    2 files changed, 257 insertions(+), 55 deletions(-)
>>>>
>>>> diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
>>>> index 780908d43557..32e238173036 100644
>>>> --- a/drivers/tty/serial/Kconfig
>>>> +++ b/drivers/tty/serial/Kconfig
>>>> @@ -198,6 +198,7 @@ config SERIAL_KGDB_NMI
>>>>    config SERIAL_MESON
>>>>    	tristate "Meson serial port support"
>>>>    	depends on ARCH_MESON
>>>> +	depends on COMMON_CLK
>>>>    	select SERIAL_CORE
>>>>    	help
>>>>    	  This enables the driver for the on-chip UARTs of the Amlogic
>>>> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
>>>> index 99efe62a1507..07eb1f40aaaa 100644
>>>> --- a/drivers/tty/serial/meson_uart.c
>>>> +++ b/drivers/tty/serial/meson_uart.c
>>>> @@ -6,6 +6,7 @@
>>>>     */
>>>>      #include <linux/clk.h>
>>>> +#include <linux/clk-provider.h>
>>>>    #include <linux/console.h>
>>>>    #include <linux/delay.h>
>>>>    #include <linux/init.h>
>>>> @@ -65,9 +66,7 @@
>>>>    #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>>>>      /* AML_UART_REG5 bits */
>>>> -#define AML_UART_BAUD_MASK		0x7fffff
>>>>    #define AML_UART_BAUD_USE		BIT(23)
>>>> -#define AML_UART_BAUD_XTAL		BIT(24)
>>>>      #define AML_UART_PORT_NUM		12
>>>>    #define AML_UART_PORT_OFFSET		6
>>>> @@ -76,6 +75,21 @@
>>>>    #define AML_UART_POLL_USEC		5
>>>>    #define AML_UART_TIMEOUT_USEC		10000
>>>>    +struct meson_uart_data {
>>>> +	struct uart_port	port;
>>>> +	struct clk		*pclk;
>>>> +	struct clk		*baud_clk;
>>>> +	struct clk_divider	baud_div;
>>>> +	struct clk_mux		use_xtal_mux;
>>>> +	struct clk_mux		xtal_clk_sel_mux;
>>>> +	struct clk_mux		xtal2_clk_sel_mux;
>>>> +	struct clk_fixed_factor	xtal_div2;
>>>> +	struct clk_fixed_factor	xtal_div3;
>>>> +	struct clk_fixed_factor	clk81_div4;
>>> Keeping all these internal elements around is not useful since they are
>>> registered using devm_
>>>
>> I'm sorry. I don't know what you mean. That's exactly what you said, but
>> what's wrong, I don't understand. Do you have any better suggestions,
>> please specify specific points, preferably give examples.
> 
> I'm saying that you don't need to keep reference to the internal
> elements of the clock tree you have registered since devm_ will take
> care of the removal later on. IOW, Once they are registered, the pointer
> is never used again so you don't need it in the private data.
> 
I understand you now. What you say is right. I will correct it.
> 
>>>> +	bool			no_clk81_input;
>>> What is this ?
>>>
>> To distinguish between clK81 and XTAL.
> 
> ... Yet, it is not used
> 
>>>> +	bool			has_xtal_clk_sel;
>>>> +};
>>>> +
>>>>    static struct uart_driver meson_uart_driver;
>>>>      static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>>>> @@ -270,14 +284,11 @@ static void meson_uart_reset(struct uart_port *port)
>>>>    static int meson_uart_startup(struct uart_port *port)
>>>>    {
>>>>    	u32 val;
>>>> -	int ret = 0;
>>>> +	int ret;
>>>>    -	val = readl(port->membase + AML_UART_CONTROL);
>>>> -	val |= AML_UART_CLEAR_ERR;
>>>> -	writel(val, port->membase + AML_UART_CONTROL);
>>>> -	val &= ~AML_UART_CLEAR_ERR;
>>>> -	writel(val, port->membase + AML_UART_CONTROL);
>>>> +	meson_uart_reset(port);
>>>>    +	val = readl(port->membase + AML_UART_CONTROL);
>>>>    	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>>>>    	writel(val, port->membase + AML_UART_CONTROL);
>>>>    @@ -295,19 +306,17 @@ static int meson_uart_startup(struct uart_port
>>>> *port)
>>>>      static void meson_uart_change_speed(struct uart_port *port, unsigned
>>>> long baud)
>>>>    {
>>>> +	struct meson_uart_data *private_data = port->private_data;
>>>>    	u32 val;
>>>>      	while (!meson_uart_tx_empty(port))
>>>>    		cpu_relax();
>>>>    -	if (port->uartclk == 24000000) {
>>> This check shows that previous code assumed bit 24 was left untouched
>>> Below you can see that GXBB and newer used the XTAL path while older
>>> used the other
>>> Your change makes this dynamic which is another "unexpected" change.
>>> Please make the bit 24 mux RO to start with so the behavior remains unchanged
>>> for older SoCs.
>> I agree with what you say, and I will correct it.
>>>
>>>> -		val = ((port->uartclk / 3) / baud) - 1;
>>>> -		val |= AML_UART_BAUD_XTAL;
>>>> -	} else {
>>>> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>>>> -	}
>>>> +	val = readl(port->membase + AML_UART_REG5);
>>>>    	val |= AML_UART_BAUD_USE;
>>>>    	writel(val, port->membase + AML_UART_REG5);
>>>> +
>>>> +	clk_set_rate(private_data->baud_clk, baud);
>>>>    }
>>>>      static void meson_uart_set_termios(struct uart_port *port,
>>>> @@ -397,11 +406,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>>>>      static void meson_uart_release_port(struct uart_port *port)
>>>>    {
>>>> -	/* nothing to do */
>>>> +	struct meson_uart_data *private_data = port->private_data;
>>>> +
>>>> +	clk_disable_unprepare(private_data->baud_clk);
>>>> +	clk_disable_unprepare(private_data->pclk);
>>>>    }
>>>>      static int meson_uart_request_port(struct uart_port *port)
>>>>    {
>>>> +	struct meson_uart_data *private_data = port->private_data;
>>>> +	int ret;
>>>> +
>>>> +	ret = clk_prepare_enable(private_data->pclk);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	ret = clk_prepare_enable(private_data->baud_clk);
>>>> +	if (ret) {
>>>> +		clk_disable_unprepare(private_data->pclk);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>>    	return 0;
>>>>    }
>>>>    @@ -629,56 +654,175 @@ static struct uart_driver meson_uart_driver = {
>>>>    	.cons		= MESON_SERIAL_CONSOLE,
>>>>    };
>>>>    -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>>>> -						 const char *id)
>>>> +static int meson_uart_register_clk(struct uart_port *port,
>>>> +				   const char *name_suffix,
>>>> +				   const struct clk_parent_data *parent_data,
>>>> +				   unsigned int num_parents,
>>>> +				   const struct clk_ops *ops,
>>>> +				   struct clk_hw *hw)
>>>>    {
>>>> -	struct clk *clk = NULL;
>>>> +	struct clk_init_data init = { };
>>>> +	char clk_name[32];
>>>>    	int ret;
>>>>    -	clk = devm_clk_get(dev, id);
>>>> -	if (IS_ERR(clk))
>>>> -		return clk;
>>>> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
>>>> +		 name_suffix);
>>>>    -	ret = clk_prepare_enable(clk);
>>>> -	if (ret) {
>>>> -		dev_err(dev, "couldn't enable clk\n");
>>>> -		return ERR_PTR(ret);
>>>> -	}
>>>> +	init.name = clk_name;
>>>> +	init.ops = ops;
>>>> +	init.flags = CLK_SET_RATE_PARENT;
>>>> +	init.parent_data = parent_data;
>>>> +	init.num_parents = num_parents;
>>>> +
>>>> +	hw->init = &init;
>>>>    -	devm_add_action_or_reset(dev,
>>>> -			(void(*)(void *))clk_disable_unprepare,
>>>> -			clk);
>>>> +	ret = devm_clk_hw_register(port->dev, hw);
>>>> +	if (ret)
>>>> +		return dev_err_probe(port->dev, ret,
>>>> +				     "Failed to register the '%s' clock\n",
>>>> +				     clk_name);
>>>>    -	return clk;
>>>> +	return ret;
>>>>    }
>>>>    -static int meson_uart_probe_clocks(struct platform_device *pdev,
>>>> -				   struct uart_port *port)
>>>> -{
>>>> -	struct clk *clk_xtal = NULL;
>>>> -	struct clk *clk_pclk = NULL;
>>>> -	struct clk *clk_baud = NULL;
>>>> +static int meson_uart_probe_clocks(struct uart_port *port,
>>>> +				   bool register_clk81_div4)
>>>> +{
>>>> +	struct meson_uart_data *private_data = port->private_data;
>>>> +	struct clk_parent_data use_xtal_mux_parents[2] = {
>>>> +		{ .index = -1, },
>>>> +		{ .index = -1, },
>>>> +	};
>>>> +	struct clk_parent_data xtal_clk_sel_mux_parents[2] = { };
>>>> +	struct clk_parent_data xtal2_clk_sel_mux_parents[2] = { };
>>>> +	struct clk_parent_data xtal_div_parent = { .fw_name = "xtal", };
>>>> +	struct clk_parent_data clk81_div_parent = { .fw_name = "baud", };
>>>> +	struct clk_parent_data baud_div_parent = { };
>>>> +	struct clk *clk_baud, *clk_xtal;
>>>> +	int ret;
>>>>    -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>>>> -	if (IS_ERR(clk_pclk))
>>>> -		return PTR_ERR(clk_pclk);
>>>> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
>>>> +	if (IS_ERR(private_data->pclk))
>>>> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
>>>> +				     "Failed to get the 'pclk' clock\n");
>>>> +
>>>> +	clk_baud = devm_clk_get(port->dev, "baud");
>>>> +	if (IS_ERR(clk_baud))
>>>> +		return dev_err_probe(port->dev, PTR_ERR(clk_baud),
>>>> +				     "Failed to get the 'baud' clock\n");
>>>>    -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>>>> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>>>>    	if (IS_ERR(clk_xtal))
>>>> -		return PTR_ERR(clk_xtal);
>>>> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>>>> +				     "Failed to get the 'xtal' clock\n");
>>>> +
>>>> +	private_data->xtal_div3.mult = 1;
>>>> +	private_data->xtal_div3.div = 3;
>>>> +	ret = meson_uart_register_clk(port, "xtal_div3", &xtal_div_parent,
>>>> +				      1, &clk_fixed_factor_ops,
>>>> +				      &private_data->xtal_div3.hw);
>>>> +	if (ret)
>>>> +		return ret;
>>>>    -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>>>> -	if (IS_ERR(clk_baud))
>>>> -		return PTR_ERR(clk_baud);
>>>> +	if (register_clk81_div4) {
>>> Clock dividers represent HW elements. The presence of an HW element
>>> cannot
>>> dependent on the current of the input clocks. There is no way this is right
>>>
>>>> +		private_data->clk81_div4.mult = 1;
>>>> +		private_data->clk81_div4.div = 4;
>>>> +		ret = meson_uart_register_clk(port, "clk81_div4",
>>>> +					      &clk81_div_parent, 1,
>>>> +					      &clk_fixed_factor_ops,
>>>> +					      &private_data->clk81_div4.hw);
>>>> +		if (ret)
>>>> +			return ret;
>>>> +
>>>> +		use_xtal_mux_parents[0].hw = &private_data->clk81_div4.hw;
>>> This is only going to be used on meson8 and older. Worst case it should
>>> depend
>>> on this compatible but I don't think this would be right here.
>>> IMO, this shows that the UART "baud" input was actually fed by a
>>> derivation of "fclk_div4" instead of "clk_81" on these older SoCs.
>>> So instead of registering what I suspect to be a fake element, the
>>> meson8 clock controller driver and DT should be fixed a this should go away.
>>>
>> Virtually all UART controllers are supported, but they are not used after
>> Meson8. So the description is more reasonable in UART driver.
> 
> No it is not. It's not virtual, the support for meson8 is there in
> mainline.
> 
> Unless you tell me there is an actual /4 divider in the UART block of
> the meson8 and older and that is was removed from the newer SoC,
> the bit above should be removed and the meson8 clock tree fixed.
> 
> I think it is more probable that the /4 was never there to begin with,
> and that clk81/4 aka "fclk_div4", which is already available from the
> clock controller, was actually routed on these older SoCs.
I will check with the chip design department if it is divided by 4. I'll 
get back to you.
> 
>>>> +	}
>>>>    -	port->uartclk = clk_get_rate(clk_baud);
>>>> +	if (private_data->has_xtal_clk_sel) {
>>>> +		private_data->xtal_div2.mult = 1;
>>>> +		private_data->xtal_div2.div = 2;
>>>> +		ret = meson_uart_register_clk(port, "xtal_div2",
>>>> +					      &xtal_div_parent, 1,
>>>> +					      &clk_fixed_factor_ops,
>>>> +					      &private_data->xtal_div2.hw);
>>>> +		if (ret)
>>>> +			return ret;
>>>> +
>>>> +		xtal_clk_sel_mux_parents[0].hw = &private_data->xtal_div3.hw;
>>>> +		xtal_clk_sel_mux_parents[1].fw_name = "xtal";
>>>> +
>>>> +		private_data->xtal_clk_sel_mux.reg = port->membase + AML_UART_REG5;
>>>> +		private_data->xtal_clk_sel_mux.mask = 0x1;
>>>> +		private_data->xtal_clk_sel_mux.shift = 26;
>>>> +		private_data->xtal_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
>>>> +		ret = meson_uart_register_clk(port, "xtal_clk_sel",
>>>> +					      xtal_clk_sel_mux_parents,
>>>> +					      ARRAY_SIZE(xtal_clk_sel_mux_parents),
>>>> +					      &clk_mux_ops,
>>>> +					      &private_data->xtal_clk_sel_mux.hw);
>>>> +		if (ret)
>>>> +			return ret;
>>>> +
>>>> +		xtal2_clk_sel_mux_parents[0].hw = &private_data->xtal_clk_sel_mux.hw;
>>>> +		xtal2_clk_sel_mux_parents[1].hw = &private_data->xtal_div2.hw;
>>>> +
>>>> +		private_data->xtal2_clk_sel_mux.reg = port->membase + AML_UART_REG5;
>>>> +		private_data->xtal2_clk_sel_mux.mask = 0x1;
>>>> +		private_data->xtal2_clk_sel_mux.shift = 27;
>>>> +		private_data->xtal2_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
>>>> +		ret = meson_uart_register_clk(port, "xtal2_clk_sel",
>>>> +					      xtal2_clk_sel_mux_parents,
>>>> +					      ARRAY_SIZE(xtal2_clk_sel_mux_parents),
>>>> +					      &clk_mux_ops,
>>>> +					      &private_data->xtal2_clk_sel_mux.hw);
>>>> +		if (ret)
>>>> +			return ret;
>>>> +
>>>> +		use_xtal_mux_parents[1].hw = &private_data->xtal2_clk_sel_mux.hw;
>>>> +	} else {
>>>> +		use_xtal_mux_parents[1].hw = &private_data->xtal_div3.hw;
>>> Well the above is a bit over-complicated. If I summarize:
>>> GXBB and older used a fixed divider of 3. Bits 26 and 27 read
>>> 0 according to the documentation.
>>> Chips after GXBB have 2 configurable divider of 2 and 3. bits 26 and 27
>>> selects which of these dividers is used.
>>> So the above could be replaced with a single divider covering bits 26 and
>>> 27
>>> with the following divider table { 2, 2, 1, 3 }. The divider should use
>>> RO ops and not have CLK_SET_RATE_PARENT. It can be used for all chips
>>> variant like this, including the older ones.
>>>
>> As you say, the way you say it is complicated. I think you're complicating
>> things.I don't understand what you're trying to achieve.
>> Can you be more specific?
> 
> I'm proposing to replace the 4 elements above, paths, parent_table and
> all with a single divider with a specific table. It accomplishes the same thing.
> 
> |--------+--------+-----------|
> | Bit 27 | Bit 26 | Div Value |
> |--------+--------+-----------|
> |      0 |      0 |         3 |
> |--------+--------+-----------|
> |      0 |      1 |         1 |
> |--------+--------+-----------|
> |      1 |      0 |         2 |
> |--------+--------+-----------|
> |      1 |      1 |         2 |
> |--------+--------+-----------|
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/clk-provider.h?h=v5.16-rc8#n602
> 
> something like:
> 
> static struct clk_div_table reg5_table[] = {
> 	{ 0, 3 },
>          { 1, 1 },
>          { 2, 2 },
>          { 3, 2 },
> };
> 
> I'm also pointing out that, since bit 26 and 27 reads 0 on the older
> SoCs, the divider would work for these too, as long as the Ops is
> read-only. So you don't even need to register different element
> depending on the SoC which simplify things a bit more.
> 
> If you prefer to keep a fixed divider for the older ones, It's fine by
> me. It gives a bit more work but it is closer to reality. The newer SoC
> could still use the custom divider regardless.
> 
> Last, and as explained on other bits, that part of the clock path should
> remain RO at first, to keep behavior stable with this change. You may
> change that later on, in a dedicated patch describing the change.
> 
I understand what you mean, and i will try to realize it. I hope you can 
help review and give me your suggestions.
>>
>>> The only information you need to carry if whether or not you want to
>>> make this divider modifiable. This means using the dt data to store
>>> clk_div_ops or clk_div_ro_ops pointer.
>>> To avoid changing the behavior of the older platforms in this patch, I
>>> would
>>> suggest to make everything use clk_div_ro_ops first, and make another
>>> patch to use clk_div_ops if necessary.
>>>
>>>> +	}
>>>> +
>>>> +	private_data->use_xtal_mux.reg = port->membase + AML_UART_REG5;
>>>> +	private_data->use_xtal_mux.mask = 0x1;
>>>> +	private_data->use_xtal_mux.shift = 24;
>>>> +	private_data->use_xtal_mux.flags = CLK_MUX_ROUND_CLOSEST;
>>>> +	ret = meson_uart_register_clk(port, "use_xtal", use_xtal_mux_parents,
>>>> +				      ARRAY_SIZE(use_xtal_mux_parents),
>>>> +				      &clk_mux_ops,
>>> Use RO ops here to start with.
>>> You can make this writable with another patch explicitly describing the change.
>> I agree with what you say, and I will correct it.
>>>
>>>> +				      &private_data->use_xtal_mux.hw);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	baud_div_parent.hw = &private_data->use_xtal_mux.hw;
>>>> +
>>>> +	private_data->baud_div.reg = port->membase + AML_UART_REG5;
>>>> +	private_data->baud_div.shift = 0;
>>>> +	private_data->baud_div.width = 23;
>>>> +	private_data->baud_div.flags = CLK_DIVIDER_ROUND_CLOSEST;
>>>> +	ret = meson_uart_register_clk(port, "baud_div",
>>>> +				      &baud_div_parent, 1,
>>>> +				      &clk_divider_ops,
>>>> +				      &private_data->baud_div.hw);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	private_data->baud_clk = devm_clk_hw_get_clk(port->dev,
>>>> +						     &private_data->baud_div.hw,
>>>> +						     "baud_rate");
>>> There is a problem with this function in CCF. It will pin the driver to
>>> itself, making it unremovable. It is an ongoing topic. For now, just use
>>> "hw->clk" to get the struct *clk.
>>>
>>>> +	if (IS_ERR(private_data->baud_clk))
>>>> +		return dev_err_probe(port->dev,
>>> I don't think anything can defer here, so dev_err_probe() is not
>>> necessary I think
>>>
>> I agree with what you say, and I will correct it.
>>>> +				     PTR_ERR(private_data->baud_clk),
>>>> +				     "Failed to request the 'baud_rate' clock\n");
>>>>      	return 0;
>>>>    }
>>>>      static int meson_uart_probe(struct platform_device *pdev)
>>>>    {
>>>> +	struct meson_uart_data *private_data;
>>>>    	struct resource *res_mem, *res_irq;
>>>> +	struct clk *clk_baud, *clk_xtal;
>>>> +	bool register_clk81_div4;
>>>>    	struct uart_port *port;
>>>>    	int ret = 0;
>>>>    	int id = -1;
>>>> @@ -711,18 +855,37 @@ static int meson_uart_probe(struct platform_device *pdev)
>>>>    		return -EBUSY;
>>>>    	}
>>>>    -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port),
>>>> GFP_KERNEL);
>>>> -	if (!port)
>>>> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
>>>> +				    GFP_KERNEL);
>>>> +	if (!private_data)
>>>>    		return -ENOMEM;
>>>>    +	if (device_get_match_data(&pdev->dev))
>>>> +		private_data->has_xtal_clk_sel = true;
>>>> +
>>>> +	private_data->pclk = devm_clk_get(&pdev->dev, "pclk");
>>>> +	if (IS_ERR(private_data->pclk))
>>>> +		return dev_err_probe(&pdev->dev, PTR_ERR(private_data->pclk),
>>>> +				     "Failed to get the 'pclk' clock\n");
>>>> +
>>>> +	clk_baud = devm_clk_get(&pdev->dev, "baud");
>>>> +	if (IS_ERR(clk_baud))
>>>> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk_baud),
>>>> +				     "Failed to get the 'baud' clock\n");
>>>> +
>>>> +	clk_xtal = devm_clk_get(&pdev->dev, "xtal");
>>>> +	if (IS_ERR(clk_xtal))
>>>> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk_xtal),
>>>> +				     "Failed to get the 'xtal' clock\n");
>>>> +
>>> This is second time you call devm_clk_get() on these clocks. One
>>> instance has to go away
>>>
>> I agree with what you say, and I will correct it.
>>>> +	register_clk81_div4 = clk_get_rate(clk_xtal) != clk_get_rate(clk_baud);
>>>> +
>>> The above is a ugly way to distinguish the meson8 (32bit) SoC family
>>> from the rest. This definitely not the way to achieve it.
>>> The right is the compatible data but here I think it is not
>>> necessary. The clock input should be fixed.
>>>
>>>> +	port = &private_data->port;
>>>> +
>>>>    	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>>>>    	if (IS_ERR(port->membase))
>>>>    		return PTR_ERR(port->membase);
>>>>    -	ret = meson_uart_probe_clocks(pdev, port);
>>>> -	if (ret)
>>>> -		return ret;
>>>> -
>>>>    	port->iotype = UPIO_MEM;
>>>>    	port->mapbase = res_mem->start;
>>>>    	port->mapsize = resource_size(res_mem);
>>>> @@ -735,6 +898,12 @@ static int meson_uart_probe(struct platform_device *pdev)
>>>>    	port->x_char = 0;
>>>>    	port->ops = &meson_uart_ops;
>>>>    	port->fifosize = 64;
>>>> +	port->uartclk = clk_get_rate(clk_baud);
>>>> +	port->private_data = private_data;
>>>> +
>>>> +	ret = meson_uart_probe_clocks(port, register_clk81_div4);
>>>> +	if (ret)
>>>> +		return ret;
>>>>      	meson_ports[pdev->id] = port;
>>>>    	platform_set_drvdata(pdev, port);
>>>> @@ -761,10 +930,42 @@ static int meson_uart_remove(struct platform_device *pdev)
>>>>    }
>>>>      static const struct of_device_id meson_uart_dt_match[] = {
>>>> -	{ .compatible = "amlogic,meson6-uart" },
>>>> -	{ .compatible = "amlogic,meson8-uart" },
>>>> -	{ .compatible = "amlogic,meson8b-uart" },
>>>> -	{ .compatible = "amlogic,meson-gx-uart" },
>>>> +	{
>>>> +		.compatible = "amlogic,meson6-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson8-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson8b-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson-gxbb-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson-gxl-uart",
>>>> +		.data = (void *)true,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson-g12a-uart",
>>>> +		.data = (void *)true,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson-s4-uart",
>>>> +		.data = (void *)true,
>>>> +	},
>>>> +	/*
>>>> +	 * deprecated, don't use anymore because it doesn't differentiate
>>>> +	 * between GXBB and GXL which have different revisions of the UART IP.
>>>> +	 */
>>>> +	{
>>>> +		.compatible = "amlogic,meson-gx-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>>    	{ /* sentinel */ },
>>>>    };
>>>>    MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
>>>
> 


From yu.tu at amlogic.com  Tue Jan  4 21:53:56 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Wed, 5 Jan 2022 13:53:56 +0800
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate calculation
 is described using the common clock code. Also added S4 chip uart
 Compatible.
In-Reply-To: <318ec2df-b73b-520b-f5ac-d0d2fce0eff0@amlogic.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
 <1jfsq57wym.fsf@starbuckisacylon.baylibre.com>
 <264367c8-2de1-ebd1-0843-e4e33a8407a6@amlogic.com>
 <1jpmp7rc1z.fsf@starbuckisacylon.baylibre.com>
 <318ec2df-b73b-520b-f5ac-d0d2fce0eff0@amlogic.com>
Message-ID: <61568e98-b450-c9c0-a60b-1e7c850591c7@amlogic.com>

  Hi Jerome,

On 2022/1/4 22:35, Yu Tu wrote:
> Hi Jerome,
>  ????Thank you very much for your patient reply. I have learned a lot 
> from it.
> 
> On 2022/1/4 18:36, Jerome Brunet wrote:
>> [ EXTERNAL EMAIL ]
>>
>>
>> On Tue 04 Jan 2022 at 17:57, Yu Tu <yu.tu at amlogic.com> wrote:
>>
>>> Hi Jerome,
>>> ????Thank you very much for your reply.
>>>
>>> On 2022/1/3 20:40, Jerome Brunet wrote:
>>>> [ EXTERNAL EMAIL ]
>>>>
>>>> On Thu 30 Dec 2021 at 18:21, Yu Tu <yu.tu at amlogic.com> wrote:
>>>>
>>>>> Using the common Clock code to describe the UART baud rate clock makes
>>>>> it easier for the UART driver to be compatible with the baud rate
>>>>> requirements of the UART IP on different meson chips
>>>>>
>>>>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>>>>> ---
>>>>> ?? drivers/tty/serial/Kconfig????? |?? 1 +
>>>>> ?? drivers/tty/serial/meson_uart.c | 311 
>>>>> ++++++++++++++++++++++++++------
>>>>> ?? 2 files changed, 257 insertions(+), 55 deletions(-)
>>>>>
>>>>> diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
>>>>> index 780908d43557..32e238173036 100644
>>>>> --- a/drivers/tty/serial/Kconfig
>>>>> +++ b/drivers/tty/serial/Kconfig
>>>>> @@ -198,6 +198,7 @@ config SERIAL_KGDB_NMI
>>>>> ?? config SERIAL_MESON
>>>>> ?????? tristate "Meson serial port support"
>>>>> ?????? depends on ARCH_MESON
>>>>> +??? depends on COMMON_CLK
>>>>> ?????? select SERIAL_CORE
>>>>> ?????? help
>>>>> ???????? This enables the driver for the on-chip UARTs of the Amlogic
>>>>> diff --git a/drivers/tty/serial/meson_uart.c 
>>>>> b/drivers/tty/serial/meson_uart.c
>>>>> index 99efe62a1507..07eb1f40aaaa 100644
>>>>> --- a/drivers/tty/serial/meson_uart.c
>>>>> +++ b/drivers/tty/serial/meson_uart.c
>>>>> @@ -6,6 +6,7 @@
>>>>> ??? */
>>>>> ???? #include <linux/clk.h>
>>>>> +#include <linux/clk-provider.h>
>>>>> ?? #include <linux/console.h>
>>>>> ?? #include <linux/delay.h>
>>>>> ?? #include <linux/init.h>
>>>>> @@ -65,9 +66,7 @@
>>>>> ?? #define AML_UART_RECV_IRQ(c)??????? ((c) & 0xff)
>>>>> ???? /* AML_UART_REG5 bits */
>>>>> -#define AML_UART_BAUD_MASK??????? 0x7fffff
>>>>> ?? #define AML_UART_BAUD_USE??????? BIT(23)
>>>>> -#define AML_UART_BAUD_XTAL??????? BIT(24)
>>>>> ???? #define AML_UART_PORT_NUM??????? 12
>>>>> ?? #define AML_UART_PORT_OFFSET??????? 6
>>>>> @@ -76,6 +75,21 @@
>>>>> ?? #define AML_UART_POLL_USEC??????? 5
>>>>> ?? #define AML_UART_TIMEOUT_USEC??????? 10000
>>>>> ?? +struct meson_uart_data {
>>>>> +??? struct uart_port??? port;
>>>>> +??? struct clk??????? *pclk;
>>>>> +??? struct clk??????? *baud_clk;
>>>>> +??? struct clk_divider??? baud_div;
>>>>> +??? struct clk_mux??????? use_xtal_mux;
>>>>> +??? struct clk_mux??????? xtal_clk_sel_mux;
>>>>> +??? struct clk_mux??????? xtal2_clk_sel_mux;
>>>>> +??? struct clk_fixed_factor??? xtal_div2;
>>>>> +??? struct clk_fixed_factor??? xtal_div3;
>>>>> +??? struct clk_fixed_factor??? clk81_div4;
>>>> Keeping all these internal elements around is not useful since they are
>>>> registered using devm_
>>>>
>>> I'm sorry. I don't know what you mean. That's exactly what you said, but
>>> what's wrong, I don't understand. Do you have any better suggestions,
>>> please specify specific points, preferably give examples.
>>
>> I'm saying that you don't need to keep reference to the internal
>> elements of the clock tree you have registered since devm_ will take
>> care of the removal later on. IOW, Once they are registered, the pointer
>> is never used again so you don't need it in the private data.
>>
> I understand you now. What you say is right. I will correct it.
>>
>>>>> +??? bool??????????? no_clk81_input;
>>>> What is this ?
>>>>
>>> To distinguish between clK81 and XTAL.
>>
>> ... Yet, it is not used
>>
>>>>> +??? bool??????????? has_xtal_clk_sel;
>>>>> +};
>>>>> +
>>>>> ?? static struct uart_driver meson_uart_driver;
>>>>> ???? static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>>>>> @@ -270,14 +284,11 @@ static void meson_uart_reset(struct uart_port 
>>>>> *port)
>>>>> ?? static int meson_uart_startup(struct uart_port *port)
>>>>> ?? {
>>>>> ?????? u32 val;
>>>>> -??? int ret = 0;
>>>>> +??? int ret;
>>>>> ?? -??? val = readl(port->membase + AML_UART_CONTROL);
>>>>> -??? val |= AML_UART_CLEAR_ERR;
>>>>> -??? writel(val, port->membase + AML_UART_CONTROL);
>>>>> -??? val &= ~AML_UART_CLEAR_ERR;
>>>>> -??? writel(val, port->membase + AML_UART_CONTROL);
>>>>> +??? meson_uart_reset(port);
>>>>> ?? +??? val = readl(port->membase + AML_UART_CONTROL);
>>>>> ?????? val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>>>>> ?????? writel(val, port->membase + AML_UART_CONTROL);
>>>>> ?? @@ -295,19 +306,17 @@ static int meson_uart_startup(struct 
>>>>> uart_port
>>>>> *port)
>>>>> ???? static void meson_uart_change_speed(struct uart_port *port, 
>>>>> unsigned
>>>>> long baud)
>>>>> ?? {
>>>>> +??? struct meson_uart_data *private_data = port->private_data;
>>>>> ?????? u32 val;
>>>>> ???????? while (!meson_uart_tx_empty(port))
>>>>> ?????????? cpu_relax();
>>>>> ?? -??? if (port->uartclk == 24000000) {
>>>> This check shows that previous code assumed bit 24 was left untouched
>>>> Below you can see that GXBB and newer used the XTAL path while older
>>>> used the other
>>>> Your change makes this dynamic which is another "unexpected" change.
>>>> Please make the bit 24 mux RO to start with so the behavior remains 
>>>> unchanged
>>>> for older SoCs.
>>> I agree with what you say, and I will correct it.
>>>>
>>>>> -??????? val = ((port->uartclk / 3) / baud) - 1;
>>>>> -??????? val |= AML_UART_BAUD_XTAL;
>>>>> -??? } else {
>>>>> -??????? val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>>>>> -??? }
>>>>> +??? val = readl(port->membase + AML_UART_REG5);
>>>>> ?????? val |= AML_UART_BAUD_USE;
>>>>> ?????? writel(val, port->membase + AML_UART_REG5);
>>>>> +
>>>>> +??? clk_set_rate(private_data->baud_clk, baud);
>>>>> ?? }
>>>>> ???? static void meson_uart_set_termios(struct uart_port *port,
>>>>> @@ -397,11 +406,27 @@ static int meson_uart_verify_port(struct 
>>>>> uart_port *port,
>>>>> ???? static void meson_uart_release_port(struct uart_port *port)
>>>>> ?? {
>>>>> -??? /* nothing to do */
>>>>> +??? struct meson_uart_data *private_data = port->private_data;
>>>>> +
>>>>> +??? clk_disable_unprepare(private_data->baud_clk);
>>>>> +??? clk_disable_unprepare(private_data->pclk);
>>>>> ?? }
>>>>> ???? static int meson_uart_request_port(struct uart_port *port)
>>>>> ?? {
>>>>> +??? struct meson_uart_data *private_data = port->private_data;
>>>>> +??? int ret;
>>>>> +
>>>>> +??? ret = clk_prepare_enable(private_data->pclk);
>>>>> +??? if (ret)
>>>>> +??????? return ret;
>>>>> +
>>>>> +??? ret = clk_prepare_enable(private_data->baud_clk);
>>>>> +??? if (ret) {
>>>>> +??????? clk_disable_unprepare(private_data->pclk);
>>>>> +??????? return ret;
>>>>> +??? }
>>>>> +
>>>>> ?????? return 0;
>>>>> ?? }
>>>>> ?? @@ -629,56 +654,175 @@ static struct uart_driver 
>>>>> meson_uart_driver = {
>>>>> ?????? .cons??????? = MESON_SERIAL_CONSOLE,
>>>>> ?? };
>>>>> ?? -static inline struct clk *meson_uart_probe_clock(struct device 
>>>>> *dev,
>>>>> -???????????????????????? const char *id)
>>>>> +static int meson_uart_register_clk(struct uart_port *port,
>>>>> +?????????????????? const char *name_suffix,
>>>>> +?????????????????? const struct clk_parent_data *parent_data,
>>>>> +?????????????????? unsigned int num_parents,
>>>>> +?????????????????? const struct clk_ops *ops,
>>>>> +?????????????????? struct clk_hw *hw)
>>>>> ?? {
>>>>> -??? struct clk *clk = NULL;
>>>>> +??? struct clk_init_data init = { };
>>>>> +??? char clk_name[32];
>>>>> ?????? int ret;
>>>>> ?? -??? clk = devm_clk_get(dev, id);
>>>>> -??? if (IS_ERR(clk))
>>>>> -??????? return clk;
>>>>> +??? snprintf(clk_name, sizeof(clk_name), "%s#%s", 
>>>>> dev_name(port->dev),
>>>>> +???????? name_suffix);
>>>>> ?? -??? ret = clk_prepare_enable(clk);
>>>>> -??? if (ret) {
>>>>> -??????? dev_err(dev, "couldn't enable clk\n");
>>>>> -??????? return ERR_PTR(ret);
>>>>> -??? }
>>>>> +??? init.name = clk_name;
>>>>> +??? init.ops = ops;
>>>>> +??? init.flags = CLK_SET_RATE_PARENT;
>>>>> +??? init.parent_data = parent_data;
>>>>> +??? init.num_parents = num_parents;
>>>>> +
>>>>> +??? hw->init = &init;
>>>>> ?? -??? devm_add_action_or_reset(dev,
>>>>> -??????????? (void(*)(void *))clk_disable_unprepare,
>>>>> -??????????? clk);
>>>>> +??? ret = devm_clk_hw_register(port->dev, hw);
>>>>> +??? if (ret)
>>>>> +??????? return dev_err_probe(port->dev, ret,
>>>>> +???????????????????? "Failed to register the '%s' clock\n",
>>>>> +???????????????????? clk_name);
>>>>> ?? -??? return clk;
>>>>> +??? return ret;
>>>>> ?? }
>>>>> ?? -static int meson_uart_probe_clocks(struct platform_device *pdev,
>>>>> -?????????????????? struct uart_port *port)
>>>>> -{
>>>>> -??? struct clk *clk_xtal = NULL;
>>>>> -??? struct clk *clk_pclk = NULL;
>>>>> -??? struct clk *clk_baud = NULL;
>>>>> +static int meson_uart_probe_clocks(struct uart_port *port,
>>>>> +?????????????????? bool register_clk81_div4)
>>>>> +{
>>>>> +??? struct meson_uart_data *private_data = port->private_data;
>>>>> +??? struct clk_parent_data use_xtal_mux_parents[2] = {
>>>>> +??????? { .index = -1, },
>>>>> +??????? { .index = -1, },
>>>>> +??? };
>>>>> +??? struct clk_parent_data xtal_clk_sel_mux_parents[2] = { };
>>>>> +??? struct clk_parent_data xtal2_clk_sel_mux_parents[2] = { };
>>>>> +??? struct clk_parent_data xtal_div_parent = { .fw_name = "xtal", };
>>>>> +??? struct clk_parent_data clk81_div_parent = { .fw_name = "baud", };
>>>>> +??? struct clk_parent_data baud_div_parent = { };
>>>>> +??? struct clk *clk_baud, *clk_xtal;
>>>>> +??? int ret;
>>>>> ?? -??? clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>>>>> -??? if (IS_ERR(clk_pclk))
>>>>> -??????? return PTR_ERR(clk_pclk);
>>>>> +??? private_data->pclk = devm_clk_get(port->dev, "pclk");
>>>>> +??? if (IS_ERR(private_data->pclk))
>>>>> +??????? return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
>>>>> +???????????????????? "Failed to get the 'pclk' clock\n");
>>>>> +
>>>>> +??? clk_baud = devm_clk_get(port->dev, "baud");
>>>>> +??? if (IS_ERR(clk_baud))
>>>>> +??????? return dev_err_probe(port->dev, PTR_ERR(clk_baud),
>>>>> +???????????????????? "Failed to get the 'baud' clock\n");
>>>>> ?? -??? clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>>>>> +??? clk_xtal = devm_clk_get(port->dev, "xtal");
>>>>> ?????? if (IS_ERR(clk_xtal))
>>>>> -??????? return PTR_ERR(clk_xtal);
>>>>> +??????? return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>>>>> +???????????????????? "Failed to get the 'xtal' clock\n");
>>>>> +
>>>>> +??? private_data->xtal_div3.mult = 1;
>>>>> +??? private_data->xtal_div3.div = 3;
>>>>> +??? ret = meson_uart_register_clk(port, "xtal_div3", 
>>>>> &xtal_div_parent,
>>>>> +????????????????????? 1, &clk_fixed_factor_ops,
>>>>> +????????????????????? &private_data->xtal_div3.hw);
>>>>> +??? if (ret)
>>>>> +??????? return ret;
>>>>> ?? -??? clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>>>>> -??? if (IS_ERR(clk_baud))
>>>>> -??????? return PTR_ERR(clk_baud);
>>>>> +??? if (register_clk81_div4) {
>>>> Clock dividers represent HW elements. The presence of an HW element
>>>> cannot
>>>> dependent on the current of the input clocks. There is no way this 
>>>> is right
>>>>
>>>>> +??????? private_data->clk81_div4.mult = 1;
>>>>> +??????? private_data->clk81_div4.div = 4;
>>>>> +??????? ret = meson_uart_register_clk(port, "clk81_div4",
>>>>> +????????????????????????? &clk81_div_parent, 1,
>>>>> +????????????????????????? &clk_fixed_factor_ops,
>>>>> +????????????????????????? &private_data->clk81_div4.hw);
>>>>> +??????? if (ret)
>>>>> +??????????? return ret;
>>>>> +
>>>>> +??????? use_xtal_mux_parents[0].hw = &private_data->clk81_div4.hw;
>>>> This is only going to be used on meson8 and older. Worst case it should
>>>> depend
>>>> on this compatible but I don't think this would be right here.
>>>> IMO, this shows that the UART "baud" input was actually fed by a
>>>> derivation of "fclk_div4" instead of "clk_81" on these older SoCs.
>>>> So instead of registering what I suspect to be a fake element, the
>>>> meson8 clock controller driver and DT should be fixed a this should 
>>>> go away.
>>>>
>>> Virtually all UART controllers are supported, but they are not used 
>>> after
>>> Meson8. So the description is more reasonable in UART driver.
>>
>> No it is not. It's not virtual, the support for meson8 is there in
>> mainline.
>>
>> Unless you tell me there is an actual /4 divider in the UART block of
>> the meson8 and older and that is was removed from the newer SoC,
>> the bit above should be removed and the meson8 clock tree fixed.
>>
>> I think it is more probable that the /4 was never there to begin with,
>> and that clk81/4 aka "fclk_div4", which is already available from the
>> clock controller, was actually routed on these older SoCs.
> I will check with the chip design department if it is divided by 4. I'll 
> get back to you.
I confirmed with the chip design department that there is a 4 divider 
inside. So I'm going to use the divider 4 for the description, but only 
the older meson8 is in use, so I'm going to pass the parameter through 
compatible. Do you have any better suggestions?

>>
>>>>> +??? }
>>>>> ?? -??? port->uartclk = clk_get_rate(clk_baud);
>>>>> +??? if (private_data->has_xtal_clk_sel) {
>>>>> +??????? private_data->xtal_div2.mult = 1;
>>>>> +??????? private_data->xtal_div2.div = 2;
>>>>> +??????? ret = meson_uart_register_clk(port, "xtal_div2",
>>>>> +????????????????????????? &xtal_div_parent, 1,
>>>>> +????????????????????????? &clk_fixed_factor_ops,
>>>>> +????????????????????????? &private_data->xtal_div2.hw);
>>>>> +??????? if (ret)
>>>>> +??????????? return ret;
>>>>> +
>>>>> +??????? xtal_clk_sel_mux_parents[0].hw = &private_data->xtal_div3.hw;
>>>>> +??????? xtal_clk_sel_mux_parents[1].fw_name = "xtal";
>>>>> +
>>>>> +??????? private_data->xtal_clk_sel_mux.reg = port->membase + 
>>>>> AML_UART_REG5;
>>>>> +??????? private_data->xtal_clk_sel_mux.mask = 0x1;
>>>>> +??????? private_data->xtal_clk_sel_mux.shift = 26;
>>>>> +??????? private_data->xtal_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
>>>>> +??????? ret = meson_uart_register_clk(port, "xtal_clk_sel",
>>>>> +????????????????????????? xtal_clk_sel_mux_parents,
>>>>> +????????????????????????? ARRAY_SIZE(xtal_clk_sel_mux_parents),
>>>>> +????????????????????????? &clk_mux_ops,
>>>>> +????????????????????????? &private_data->xtal_clk_sel_mux.hw);
>>>>> +??????? if (ret)
>>>>> +??????????? return ret;
>>>>> +
>>>>> +??????? xtal2_clk_sel_mux_parents[0].hw = 
>>>>> &private_data->xtal_clk_sel_mux.hw;
>>>>> +??????? xtal2_clk_sel_mux_parents[1].hw = 
>>>>> &private_data->xtal_div2.hw;
>>>>> +
>>>>> +??????? private_data->xtal2_clk_sel_mux.reg = port->membase + 
>>>>> AML_UART_REG5;
>>>>> +??????? private_data->xtal2_clk_sel_mux.mask = 0x1;
>>>>> +??????? private_data->xtal2_clk_sel_mux.shift = 27;
>>>>> +??????? private_data->xtal2_clk_sel_mux.flags = 
>>>>> CLK_MUX_ROUND_CLOSEST;
>>>>> +??????? ret = meson_uart_register_clk(port, "xtal2_clk_sel",
>>>>> +????????????????????????? xtal2_clk_sel_mux_parents,
>>>>> +????????????????????????? ARRAY_SIZE(xtal2_clk_sel_mux_parents),
>>>>> +????????????????????????? &clk_mux_ops,
>>>>> +????????????????????????? &private_data->xtal2_clk_sel_mux.hw);
>>>>> +??????? if (ret)
>>>>> +??????????? return ret;
>>>>> +
>>>>> +??????? use_xtal_mux_parents[1].hw = 
>>>>> &private_data->xtal2_clk_sel_mux.hw;
>>>>> +??? } else {
>>>>> +??????? use_xtal_mux_parents[1].hw = &private_data->xtal_div3.hw;
>>>> Well the above is a bit over-complicated. If I summarize:
>>>> GXBB and older used a fixed divider of 3. Bits 26 and 27 read
>>>> 0 according to the documentation.
>>>> Chips after GXBB have 2 configurable divider of 2 and 3. bits 26 and 27
>>>> selects which of these dividers is used.
>>>> So the above could be replaced with a single divider covering bits 
>>>> 26 and
>>>> 27
>>>> with the following divider table { 2, 2, 1, 3 }. The divider should use
>>>> RO ops and not have CLK_SET_RATE_PARENT. It can be used for all chips
>>>> variant like this, including the older ones.
>>>>
>>> As you say, the way you say it is complicated. I think you're 
>>> complicating
>>> things.I don't understand what you're trying to achieve.
>>> Can you be more specific?
>>
>> I'm proposing to replace the 4 elements above, paths, parent_table and
>> all with a single divider with a specific table. It accomplishes the 
>> same thing.
>>
>> |--------+--------+-----------|
>> | Bit 27 | Bit 26 | Div Value |
>> |--------+--------+-----------|
>> |????? 0 |????? 0 |???????? 3 |
>> |--------+--------+-----------|
>> |????? 0 |????? 1 |???????? 1 |
>> |--------+--------+-----------|
>> |????? 1 |????? 0 |???????? 2 |
>> |--------+--------+-----------|
>> |????? 1 |????? 1 |???????? 2 |
>> |--------+--------+-----------|
>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/clk-provider.h?h=v5.16-rc8#n602 
>>
>>
>> something like:
>>
>> static struct clk_div_table reg5_table[] = {
>> ????{ 0, 3 },
>> ???????? { 1, 1 },
>> ???????? { 2, 2 },
>> ???????? { 3, 2 },
>> };
>>
>> I'm also pointing out that, since bit 26 and 27 reads 0 on the older
>> SoCs, the divider would work for these too, as long as the Ops is
>> read-only. So you don't even need to register different element
>> depending on the SoC which simplify things a bit more.
>>
>> If you prefer to keep a fixed divider for the older ones, It's fine by
>> me. It gives a bit more work but it is closer to reality. The newer SoC
>> could still use the custom divider regardless.
>>
>> Last, and as explained on other bits, that part of the clock path should
>> remain RO at first, to keep behavior stable with this change. You may
>> change that later on, in a dedicated patch describing the change.
>>
> I understand what you mean, and i will try to realize it. I hope you can 
> help review and give me your suggestions.
>>>
>>>> The only information you need to carry if whether or not you want to
>>>> make this divider modifiable. This means using the dt data to store
>>>> clk_div_ops or clk_div_ro_ops pointer.
>>>> To avoid changing the behavior of the older platforms in this patch, I
>>>> would
>>>> suggest to make everything use clk_div_ro_ops first, and make another
>>>> patch to use clk_div_ops if necessary.
>>>>
>>>>> +??? }
>>>>> +
>>>>> +??? private_data->use_xtal_mux.reg = port->membase + AML_UART_REG5;
>>>>> +??? private_data->use_xtal_mux.mask = 0x1;
>>>>> +??? private_data->use_xtal_mux.shift = 24;
>>>>> +??? private_data->use_xtal_mux.flags = CLK_MUX_ROUND_CLOSEST;
>>>>> +??? ret = meson_uart_register_clk(port, "use_xtal", 
>>>>> use_xtal_mux_parents,
>>>>> +????????????????????? ARRAY_SIZE(use_xtal_mux_parents),
>>>>> +????????????????????? &clk_mux_ops,
>>>> Use RO ops here to start with.
>>>> You can make this writable with another patch explicitly describing 
>>>> the change.
>>> I agree with what you say, and I will correct it.
>>>>
>>>>> +????????????????????? &private_data->use_xtal_mux.hw);
>>>>> +??? if (ret)
>>>>> +??????? return ret;
>>>>> +
>>>>> +??? baud_div_parent.hw = &private_data->use_xtal_mux.hw;
>>>>> +
>>>>> +??? private_data->baud_div.reg = port->membase + AML_UART_REG5;
>>>>> +??? private_data->baud_div.shift = 0;
>>>>> +??? private_data->baud_div.width = 23;
>>>>> +??? private_data->baud_div.flags = CLK_DIVIDER_ROUND_CLOSEST;
>>>>> +??? ret = meson_uart_register_clk(port, "baud_div",
>>>>> +????????????????????? &baud_div_parent, 1,
>>>>> +????????????????????? &clk_divider_ops,
>>>>> +????????????????????? &private_data->baud_div.hw);
>>>>> +??? if (ret)
>>>>> +??????? return ret;
>>>>> +
>>>>> +??? private_data->baud_clk = devm_clk_hw_get_clk(port->dev,
>>>>> +???????????????????????????? &private_data->baud_div.hw,
>>>>> +???????????????????????????? "baud_rate");
>>>> There is a problem with this function in CCF. It will pin the driver to
>>>> itself, making it unremovable. It is an ongoing topic. For now, just 
>>>> use
>>>> "hw->clk" to get the struct *clk.
>>>>
>>>>> +??? if (IS_ERR(private_data->baud_clk))
>>>>> +??????? return dev_err_probe(port->dev,
>>>> I don't think anything can defer here, so dev_err_probe() is not
>>>> necessary I think
>>>>
>>> I agree with what you say, and I will correct it.
>>>>> +???????????????????? PTR_ERR(private_data->baud_clk),
>>>>> +???????????????????? "Failed to request the 'baud_rate' clock\n");
>>>>> ???????? return 0;
>>>>> ?? }
>>>>> ???? static int meson_uart_probe(struct platform_device *pdev)
>>>>> ?? {
>>>>> +??? struct meson_uart_data *private_data;
>>>>> ?????? struct resource *res_mem, *res_irq;
>>>>> +??? struct clk *clk_baud, *clk_xtal;
>>>>> +??? bool register_clk81_div4;
>>>>> ?????? struct uart_port *port;
>>>>> ?????? int ret = 0;
>>>>> ?????? int id = -1;
>>>>> @@ -711,18 +855,37 @@ static int meson_uart_probe(struct 
>>>>> platform_device *pdev)
>>>>> ?????????? return -EBUSY;
>>>>> ?????? }
>>>>> ?? -??? port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port),
>>>>> GFP_KERNEL);
>>>>> -??? if (!port)
>>>>> +??? private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
>>>>> +??????????????????? GFP_KERNEL);
>>>>> +??? if (!private_data)
>>>>> ?????????? return -ENOMEM;
>>>>> ?? +??? if (device_get_match_data(&pdev->dev))
>>>>> +??????? private_data->has_xtal_clk_sel = true;
>>>>> +
>>>>> +??? private_data->pclk = devm_clk_get(&pdev->dev, "pclk");
>>>>> +??? if (IS_ERR(private_data->pclk))
>>>>> +??????? return dev_err_probe(&pdev->dev, PTR_ERR(private_data->pclk),
>>>>> +???????????????????? "Failed to get the 'pclk' clock\n");
>>>>> +
>>>>> +??? clk_baud = devm_clk_get(&pdev->dev, "baud");
>>>>> +??? if (IS_ERR(clk_baud))
>>>>> +??????? return dev_err_probe(&pdev->dev, PTR_ERR(clk_baud),
>>>>> +???????????????????? "Failed to get the 'baud' clock\n");
>>>>> +
>>>>> +??? clk_xtal = devm_clk_get(&pdev->dev, "xtal");
>>>>> +??? if (IS_ERR(clk_xtal))
>>>>> +??????? return dev_err_probe(&pdev->dev, PTR_ERR(clk_xtal),
>>>>> +???????????????????? "Failed to get the 'xtal' clock\n");
>>>>> +
>>>> This is second time you call devm_clk_get() on these clocks. One
>>>> instance has to go away
>>>>
>>> I agree with what you say, and I will correct it.
>>>>> +??? register_clk81_div4 = clk_get_rate(clk_xtal) != 
>>>>> clk_get_rate(clk_baud);
>>>>> +
>>>> The above is a ugly way to distinguish the meson8 (32bit) SoC family
>>>> from the rest. This definitely not the way to achieve it.
>>>> The right is the compatible data but here I think it is not
>>>> necessary. The clock input should be fixed.
>>>>
>>>>> +??? port = &private_data->port;
>>>>> +
>>>>> ?????? port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>>>>> ?????? if (IS_ERR(port->membase))
>>>>> ?????????? return PTR_ERR(port->membase);
>>>>> ?? -??? ret = meson_uart_probe_clocks(pdev, port);
>>>>> -??? if (ret)
>>>>> -??????? return ret;
>>>>> -
>>>>> ?????? port->iotype = UPIO_MEM;
>>>>> ?????? port->mapbase = res_mem->start;
>>>>> ?????? port->mapsize = resource_size(res_mem);
>>>>> @@ -735,6 +898,12 @@ static int meson_uart_probe(struct 
>>>>> platform_device *pdev)
>>>>> ?????? port->x_char = 0;
>>>>> ?????? port->ops = &meson_uart_ops;
>>>>> ?????? port->fifosize = 64;
>>>>> +??? port->uartclk = clk_get_rate(clk_baud);
>>>>> +??? port->private_data = private_data;
>>>>> +
>>>>> +??? ret = meson_uart_probe_clocks(port, register_clk81_div4);
>>>>> +??? if (ret)
>>>>> +??????? return ret;
>>>>> ???????? meson_ports[pdev->id] = port;
>>>>> ?????? platform_set_drvdata(pdev, port);
>>>>> @@ -761,10 +930,42 @@ static int meson_uart_remove(struct 
>>>>> platform_device *pdev)
>>>>> ?? }
>>>>> ???? static const struct of_device_id meson_uart_dt_match[] = {
>>>>> -??? { .compatible = "amlogic,meson6-uart" },
>>>>> -??? { .compatible = "amlogic,meson8-uart" },
>>>>> -??? { .compatible = "amlogic,meson8b-uart" },
>>>>> -??? { .compatible = "amlogic,meson-gx-uart" },
>>>>> +??? {
>>>>> +??????? .compatible = "amlogic,meson6-uart",
>>>>> +??????? .data = (void *)false,
>>>>> +??? },
>>>>> +??? {
>>>>> +??????? .compatible = "amlogic,meson8-uart",
>>>>> +??????? .data = (void *)false,
>>>>> +??? },
>>>>> +??? {
>>>>> +??????? .compatible = "amlogic,meson8b-uart",
>>>>> +??????? .data = (void *)false,
>>>>> +??? },
>>>>> +??? {
>>>>> +??????? .compatible = "amlogic,meson-gxbb-uart",
>>>>> +??????? .data = (void *)false,
>>>>> +??? },
>>>>> +??? {
>>>>> +??????? .compatible = "amlogic,meson-gxl-uart",
>>>>> +??????? .data = (void *)true,
>>>>> +??? },
>>>>> +??? {
>>>>> +??????? .compatible = "amlogic,meson-g12a-uart",
>>>>> +??????? .data = (void *)true,
>>>>> +??? },
>>>>> +??? {
>>>>> +??????? .compatible = "amlogic,meson-s4-uart",
>>>>> +??????? .data = (void *)true,
>>>>> +??? },
>>>>> +??? /*
>>>>> +???? * deprecated, don't use anymore because it doesn't differentiate
>>>>> +???? * between GXBB and GXL which have different revisions of the 
>>>>> UART IP.
>>>>> +???? */
>>>>> +??? {
>>>>> +??????? .compatible = "amlogic,meson-gx-uart",
>>>>> +??????? .data = (void *)false,
>>>>> +??? },
>>>>> ?????? { /* sentinel */ },
>>>>> ?? };
>>>>> ?? MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
>>>>
>>


From liang.yang at amlogic.com  Wed Jan  5 19:25:04 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Thu, 6 Jan 2022 11:25:04 +0800
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
Message-ID: <20220106032504.23310-1-liang.yang@amlogic.com>

Because EMMC and NAND have the same control clock register, so we
implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:

	sd_emmc_c_clkc: mmc at 7000 {
		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
		reg = <0x0 0x7000 0x0 0x800>;
	};

	nand-controller at 7800 {
		......

		clocks = <&clkc CLKID_SD_EMMC_C>,
			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
		clock-names = "core", "device", "rx", "tx";
		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;

		......
	}

but in fact, above implementation is rejected. so now registering
a nand_divider.

Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
 1 file changed, 49 insertions(+), 39 deletions(-)

diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
index ac3be92872d0..4472363059c2 100644
--- a/drivers/mtd/nand/raw/meson_nand.c
+++ b/drivers/mtd/nand/raw/meson_nand.c
@@ -2,7 +2,7 @@
 /*
  * Amlogic Meson Nand Flash Controller Driver
  *
- * Copyright (c) 2018 Amlogic, inc.
+ * Copyright (c) 2018-2021 Amlogic, inc.
  * Author: Liang Yang <liang.yang at amlogic.com>
  */
 
@@ -10,6 +10,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/mtd/rawnand.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mfd/syscon.h>
@@ -55,6 +56,7 @@
 #define NFC_REG_VER		0x38
 
 #define NFC_RB_IRQ_EN		BIT(21)
+#define NFC_CMD_FIFO_RESET	BIT(31)
 
 #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)	\
 	(								\
@@ -104,6 +106,9 @@
 
 #define PER_INFO_BYTE		8
 
+#define CLK_DIV_SHIFT		0
+#define CLK_DIV_WIDTH		6
+
 struct meson_nfc_nand_chip {
 	struct list_head node;
 	struct nand_chip nand;
@@ -151,15 +156,15 @@ struct meson_nfc {
 	struct nand_controller controller;
 	struct clk *core_clk;
 	struct clk *device_clk;
-	struct clk *phase_tx;
-	struct clk *phase_rx;
+	struct clk *nand_clk;
+	struct clk_divider nand_divider;
 
 	unsigned long clk_rate;
 	u32 bus_timing;
 
 	struct device *dev;
 	void __iomem *reg_base;
-	struct regmap *reg_clk;
+	void __iomem *reg_clk;
 	struct completion completion;
 	struct list_head chips;
 	const struct meson_nfc_data *data;
@@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
 	cmd = NFC_CMD_RB | NFC_CMD_RB_INT
 		| nfc->param.chip_select | nfc->timing.tbers_max;
 	writel(cmd, nfc->reg_base + NFC_REG_CMD);
-
+	meson_nfc_drain_cmd(nfc);
 	ret = wait_for_completion_timeout(&nfc->completion,
 					  msecs_to_jiffies(timeout_ms));
 	if (ret == 0)
 		ret = -1;
 
+	/* reset command fifo to avoid lock */
+	writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);
 	return ret;
 }
 
@@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
 static int meson_nfc_clk_init(struct meson_nfc *nfc)
 {
 	int ret;
+	struct clk_init_data init = {0};
+	const char *fix_div2_pll_name[1];
 
-	/* request core clock */
 	nfc->core_clk = devm_clk_get(nfc->dev, "core");
 	if (IS_ERR(nfc->core_clk)) {
 		dev_err(nfc->dev, "failed to get core clock\n");
@@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
 		return PTR_ERR(nfc->device_clk);
 	}
 
-	nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
-	if (IS_ERR(nfc->phase_tx)) {
-		dev_err(nfc->dev, "failed to get TX clk\n");
-		return PTR_ERR(nfc->phase_tx);
-	}
-
-	nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
-	if (IS_ERR(nfc->phase_rx)) {
-		dev_err(nfc->dev, "failed to get RX clk\n");
-		return PTR_ERR(nfc->phase_rx);
-	}
+	init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
+	init.ops = &clk_divider_ops;
+	fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);
+	init.parent_names = fix_div2_pll_name;
+	init.num_parents = 1;
+	nfc->nand_divider.reg = nfc->reg_clk;
+	nfc->nand_divider.shift = CLK_DIV_SHIFT;
+	nfc->nand_divider.width = CLK_DIV_WIDTH;
+	nfc->nand_divider.hw.init = &init;
+	nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
+				  CLK_DIVIDER_ROUND_CLOSEST |
+          			  CLK_DIVIDER_ALLOW_ZERO;
+
+	nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
+	if (IS_ERR(nfc->nand_clk))
+		return PTR_ERR(nfc->nand_clk);
 
 	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
-	regmap_update_bits(nfc->reg_clk,
-			   0, CLK_SELECT_NAND, CLK_SELECT_NAND);
+	writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
 
 	ret = clk_prepare_enable(nfc->core_clk);
 	if (ret) {
@@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
 		goto err_device_clk;
 	}
 
-	ret = clk_prepare_enable(nfc->phase_tx);
+	ret = clk_prepare_enable(nfc->nand_clk);
 	if (ret) {
-		dev_err(nfc->dev, "failed to enable TX clock\n");
-		goto err_phase_tx;
-	}
-
-	ret = clk_prepare_enable(nfc->phase_rx);
-	if (ret) {
-		dev_err(nfc->dev, "failed to enable RX clock\n");
-		goto err_phase_rx;
+		dev_err(nfc->dev, "pre enable NFC divider fail\n");
+		goto err_nand_clk;
 	}
 
 	ret = clk_set_rate(nfc->device_clk, 24000000);
 	if (ret)
-		goto err_disable_rx;
+		goto err_disable_clk;
 
 	return 0;
 
-err_disable_rx:
-	clk_disable_unprepare(nfc->phase_rx);
-err_phase_rx:
-	clk_disable_unprepare(nfc->phase_tx);
-err_phase_tx:
+err_disable_clk:
+	clk_disable_unprepare(nfc->nand_clk);
+err_nand_clk:
 	clk_disable_unprepare(nfc->device_clk);
 err_device_clk:
 	clk_disable_unprepare(nfc->core_clk);
@@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
 
 static void meson_nfc_disable_clk(struct meson_nfc *nfc)
 {
-	clk_disable_unprepare(nfc->phase_rx);
-	clk_disable_unprepare(nfc->phase_tx);
+	clk_disable_unprepare(nfc->nand_clk);
 	clk_disable_unprepare(nfc->device_clk);
 	clk_disable_unprepare(nfc->core_clk);
 }
@@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct meson_nfc *nfc;
 	struct resource *res;
+	u32 ext_clk_reg;
 	int ret, irq;
 
 	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
@@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
 	if (IS_ERR(nfc->reg_base))
 		return PTR_ERR(nfc->reg_base);
 
-	nfc->reg_clk =
-		syscon_regmap_lookup_by_phandle(dev->of_node,
-						"amlogic,mmc-syscon");
+	ret = of_property_read_u32(pdev->dev.of_node,
+				   "sd_emmc_c_clkc",
+				   &ext_clk_reg);
+	if (ret) {
+		dev_err(dev, "failed to get NAND external clock register\n");
+		return ret;
+	}
+
+	nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));
 	if (IS_ERR(nfc->reg_clk)) {
 		dev_err(dev, "Failed to lookup clock base\n");
 		return PTR_ERR(nfc->reg_clk);
-- 
2.34.1



From liang.yang at amlogic.com  Wed Jan  5 19:31:30 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Thu, 6 Jan 2022 11:31:30 +0800
Subject: [PATCH] dt-bindings: nand: meson: fix controller clock
Message-ID: <20220106033130.37623-1-liang.yang@amlogic.com>

Change-Id: I1425b491d8b95061e1ce358ef33143433fc94d24
---
 .../bindings/mtd/amlogic,meson-nand.txt        | 18 +++---------------
 1 file changed, 3 insertions(+), 15 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
index 5794ab1147c1..37f16fe4fe66 100644
--- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
@@ -14,11 +14,6 @@ Required properties:
 - clock-names: Should contain the following:
 	"core" - NFC module gate clock
 	"device" - device clock from eMMC sub clock controller
-	"rx" - rx clock phase
-	"tx" - tx clock phase
-
-- amlogic,mmc-syscon	: Required for NAND clocks, it's shared with SD/eMMC
-				controller port C
 
 Optional children nodes:
 Children nodes represent the available nand chips.
@@ -28,11 +23,6 @@ see Documentation/devicetree/bindings/mtd/nand-controller.yaml for generic bindi
 
 Example demonstrate on AXG SoC:
 
-	sd_emmc_c_clkc: mmc at 7000 {
-		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
-		reg = <0x0 0x7000 0x0 0x800>;
-	};
-
 	nand-controller at 7800 {
 		compatible = "amlogic,meson-axg-nfc";
 		reg = <0x0 0x7800 0x0 0x100>;
@@ -41,11 +31,9 @@ Example demonstrate on AXG SoC:
 		interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
 
 		clocks = <&clkc CLKID_SD_EMMC_C>,
-			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
-			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
-			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
-		clock-names = "core", "device", "rx", "tx";
-		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
+			<&clkc CLKID_FCLK_DIV2>;
+		clock-names = "core", "device";
+		sd_emmc_c_clkc = <0xffe07000>;
 
 		pinctrl-names = "default";
 		pinctrl-0 = <&nand_pins>;
-- 
2.34.1



From xianwei.zhao at amlogic.com  Wed Jan  5 21:47:24 2022
From: xianwei.zhao at amlogic.com (Xianwei Zhao)
Date: Thu, 6 Jan 2022 13:47:24 +0800
Subject: [PATCH V3] arm64: dts: add support for S4 based Amlogic AQ222
Message-ID: <20220106054724.18637-1-xianwei.zhao@amlogic.com>

Add basic support for the Amlogic S4 based Amlogic AQ222 board:
which describe components as follows: CPU, GIC, IRQ, Timer, UART.
It's capable of booting up into the serial console.

Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
---
V2 -> V3: add of dts board  compatible family
V1 -> V2: cleaned up coding style, modify CPU affinity of timer interrups,
          and modify GIC reg defintions.
---
 arch/arm64/boot/dts/amlogic/Makefile          |  1 +
 .../dts/amlogic/meson-s4-s805x2-aq222.dts     | 30 ++++++
 arch/arm64/boot/dts/amlogic/meson-s4.dtsi     | 99 +++++++++++++++++++
 3 files changed, 130 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4.dtsi

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 5148cd9e5146..faea74a45994 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -57,3 +57,4 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-s4-s805x2-aq222.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
new file mode 100644
index 000000000000..a942d7e06d6e
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "meson-s4.dtsi"
+
+/ {
+	model = "Amlogic Meson S4 AQ222 Development Board";
+	compatible = "amlogic,aq222", "amlogic,s4";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		serial0 = &uart_B;
+	};
+
+	memory at 00000000 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x40000000>;
+	};
+
+};
+
+&uart_B {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
new file mode 100644
index 000000000000..d7083c93d3d0
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	cpus:cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		CPU0:cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35","arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+		};
+
+		CPU1:cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35","arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+		};
+
+		CPU2:cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35","arm,armv8";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+		};
+
+		CPU3:cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35","arm,armv8";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	xtal: xtal-clk {
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "xtal";
+		#clock-cells = <0>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gic: interrupt-controller at fff01000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0x0 0xfff01000 0 0x1000>,
+			      <0x0 0xfff02000 0 0x2000>,
+			      <0x0 0xfff04000 0 0x2000>,
+			      <0x0 0xfff06000 0 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+		};
+
+		apb4: apb4 at fe000000 {
+			compatible = "simple-bus";
+			reg = <0x0 0xfe000000 0x0 0x480000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;
+
+			uart_B: serial at 7a000 {
+				compatible = "amlogic,meson-s4-uart",
+					     "amlogic,meson-ao-uart";
+				reg = <0x0 0x7a000 0x0 0x18>;
+				interrupts = <GIC_SPI 169 IRQ_TYPE_EDGE_RISING>;
+				status = "disabled";
+				clocks = <&xtal>, <&xtal>, <&xtal>;
+				clock-names = "xtal", "pclk", "baud";
+			};
+		};
+	};
+};

base-commit: c5468e3c930d4d2937d3a842a85df0f74e95e152
-- 
2.30.2



From miquel.raynal at bootlin.com  Thu Jan  6 00:08:32 2022
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Thu, 6 Jan 2022 09:08:32 +0100
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <20220106032504.23310-1-liang.yang@amlogic.com>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
Message-ID: <20220106090832.42225c49@xps13>

Hi Liang,

liang.yang at amlogic.com wrote on Thu, 6 Jan 2022 11:25:04 +0800:

> Because EMMC and NAND have the same control clock register, so we
> implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:
> 
> 	sd_emmc_c_clkc: mmc at 7000 {
> 		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
> 		reg = <0x0 0x7000 0x0 0x800>;
> 	};
> 
> 	nand-controller at 7800 {
> 		......
> 
> 		clocks = <&clkc CLKID_SD_EMMC_C>,
> 			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
> 		clock-names = "core", "device", "rx", "tx";
> 		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
> 
> 		......
> 	}
> 
> but in fact, above implementation is rejected. so now registering
> a nand_divider.

What is rejected?
Why is it rejected?
What is nand_divider?


> 
> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997

Change Ids are not expected in the upstream kernel.

But if you fix something you should have a Fixes:.

> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
> ---
>  drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
>  1 file changed, 49 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
> index ac3be92872d0..4472363059c2 100644
> --- a/drivers/mtd/nand/raw/meson_nand.c
> +++ b/drivers/mtd/nand/raw/meson_nand.c
> @@ -2,7 +2,7 @@
>  /*
>   * Amlogic Meson Nand Flash Controller Driver
>   *
> - * Copyright (c) 2018 Amlogic, inc.
> + * Copyright (c) 2018-2021 Amlogic, inc.
>   * Author: Liang Yang <liang.yang at amlogic.com>
>   */
>  
> @@ -10,6 +10,7 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/interrupt.h>
>  #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>  #include <linux/mtd/rawnand.h>
>  #include <linux/mtd/mtd.h>
>  #include <linux/mfd/syscon.h>
> @@ -55,6 +56,7 @@
>  #define NFC_REG_VER		0x38
>  
>  #define NFC_RB_IRQ_EN		BIT(21)
> +#define NFC_CMD_FIFO_RESET	BIT(31)
>  
>  #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)	\
>  	(								\
> @@ -104,6 +106,9 @@
>  
>  #define PER_INFO_BYTE		8
>  
> +#define CLK_DIV_SHIFT		0
> +#define CLK_DIV_WIDTH		6
> +
>  struct meson_nfc_nand_chip {
>  	struct list_head node;
>  	struct nand_chip nand;
> @@ -151,15 +156,15 @@ struct meson_nfc {
>  	struct nand_controller controller;
>  	struct clk *core_clk;
>  	struct clk *device_clk;
> -	struct clk *phase_tx;
> -	struct clk *phase_rx;
> +	struct clk *nand_clk;
> +	struct clk_divider nand_divider;
>  
>  	unsigned long clk_rate;
>  	u32 bus_timing;
>  
>  	struct device *dev;
>  	void __iomem *reg_base;
> -	struct regmap *reg_clk;
> +	void __iomem *reg_clk;
>  	struct completion completion;
>  	struct list_head chips;
>  	const struct meson_nfc_data *data;
> @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
>  	cmd = NFC_CMD_RB | NFC_CMD_RB_INT
>  		| nfc->param.chip_select | nfc->timing.tbers_max;
>  	writel(cmd, nfc->reg_base + NFC_REG_CMD);
> -
> +	meson_nfc_drain_cmd(nfc);
>  	ret = wait_for_completion_timeout(&nfc->completion,
>  					  msecs_to_jiffies(timeout_ms));
>  	if (ret == 0)
>  		ret = -1;
>  
> +	/* reset command fifo to avoid lock */
> +	writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);
>  	return ret;
>  }
>  
> @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
>  static int meson_nfc_clk_init(struct meson_nfc *nfc)
>  {
>  	int ret;
> +	struct clk_init_data init = {0};
> +	const char *fix_div2_pll_name[1];
>  
> -	/* request core clock */
>  	nfc->core_clk = devm_clk_get(nfc->dev, "core");
>  	if (IS_ERR(nfc->core_clk)) {
>  		dev_err(nfc->dev, "failed to get core clock\n");
> @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>  		return PTR_ERR(nfc->device_clk);
>  	}
>  
> -	nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
> -	if (IS_ERR(nfc->phase_tx)) {
> -		dev_err(nfc->dev, "failed to get TX clk\n");
> -		return PTR_ERR(nfc->phase_tx);
> -	}
> -
> -	nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
> -	if (IS_ERR(nfc->phase_rx)) {
> -		dev_err(nfc->dev, "failed to get RX clk\n");
> -		return PTR_ERR(nfc->phase_rx);
> -	}
> +	init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
> +	init.ops = &clk_divider_ops;
> +	fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);
> +	init.parent_names = fix_div2_pll_name;
> +	init.num_parents = 1;
> +	nfc->nand_divider.reg = nfc->reg_clk;
> +	nfc->nand_divider.shift = CLK_DIV_SHIFT;
> +	nfc->nand_divider.width = CLK_DIV_WIDTH;
> +	nfc->nand_divider.hw.init = &init;
> +	nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
> +				  CLK_DIVIDER_ROUND_CLOSEST |
> +          			  CLK_DIVIDER_ALLOW_ZERO;
> +
> +	nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
> +	if (IS_ERR(nfc->nand_clk))
> +		return PTR_ERR(nfc->nand_clk);
>  
>  	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
> -	regmap_update_bits(nfc->reg_clk,
> -			   0, CLK_SELECT_NAND, CLK_SELECT_NAND);
> +	writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
>  
>  	ret = clk_prepare_enable(nfc->core_clk);
>  	if (ret) {
> @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>  		goto err_device_clk;
>  	}
>  
> -	ret = clk_prepare_enable(nfc->phase_tx);
> +	ret = clk_prepare_enable(nfc->nand_clk);
>  	if (ret) {
> -		dev_err(nfc->dev, "failed to enable TX clock\n");
> -		goto err_phase_tx;
> -	}
> -
> -	ret = clk_prepare_enable(nfc->phase_rx);
> -	if (ret) {
> -		dev_err(nfc->dev, "failed to enable RX clock\n");
> -		goto err_phase_rx;
> +		dev_err(nfc->dev, "pre enable NFC divider fail\n");
> +		goto err_nand_clk;
>  	}
>  
>  	ret = clk_set_rate(nfc->device_clk, 24000000);
>  	if (ret)
> -		goto err_disable_rx;
> +		goto err_disable_clk;
>  
>  	return 0;
>  
> -err_disable_rx:
> -	clk_disable_unprepare(nfc->phase_rx);
> -err_phase_rx:
> -	clk_disable_unprepare(nfc->phase_tx);
> -err_phase_tx:
> +err_disable_clk:
> +	clk_disable_unprepare(nfc->nand_clk);
> +err_nand_clk:
>  	clk_disable_unprepare(nfc->device_clk);
>  err_device_clk:
>  	clk_disable_unprepare(nfc->core_clk);
> @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>  
>  static void meson_nfc_disable_clk(struct meson_nfc *nfc)
>  {
> -	clk_disable_unprepare(nfc->phase_rx);
> -	clk_disable_unprepare(nfc->phase_tx);
> +	clk_disable_unprepare(nfc->nand_clk);
>  	clk_disable_unprepare(nfc->device_clk);
>  	clk_disable_unprepare(nfc->core_clk);
>  }
> @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
>  	struct device *dev = &pdev->dev;
>  	struct meson_nfc *nfc;
>  	struct resource *res;
> +	u32 ext_clk_reg;
>  	int ret, irq;
>  
>  	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
> @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
>  	if (IS_ERR(nfc->reg_base))
>  		return PTR_ERR(nfc->reg_base);
>  
> -	nfc->reg_clk =
> -		syscon_regmap_lookup_by_phandle(dev->of_node,
> -						"amlogic,mmc-syscon");
> +	ret = of_property_read_u32(pdev->dev.of_node,
> +				   "sd_emmc_c_clkc",
> +				   &ext_clk_reg);
> +	if (ret) {
> +		dev_err(dev, "failed to get NAND external clock register\n");
> +		return ret;
> +	}
> +
> +	nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));
>  	if (IS_ERR(nfc->reg_clk)) {
>  		dev_err(dev, "Failed to lookup clock base\n");
>  		return PTR_ERR(nfc->reg_clk);


Thanks,
Miqu?l


From miquel.raynal at bootlin.com  Thu Jan  6 00:12:09 2022
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Thu, 6 Jan 2022 09:12:09 +0100
Subject: [PATCH] dt-bindings: nand: meson: fix controller clock
In-Reply-To: <20220106033130.37623-1-liang.yang@amlogic.com>
References: <20220106033130.37623-1-liang.yang@amlogic.com>
Message-ID: <20220106091209.6b97cf3c@xps13>

Hello,

liang.yang at amlogic.com wrote on Thu, 6 Jan 2022 11:31:30 +0800:

This patch should be in a series with "mtd: rawnand: meson: fix the
clock after discarding sd_emmc_c_clk" and possibly come first.

You miss a commit message which is _very_ important given the type of
change you propose.
 
> Change-Id: I1425b491d8b95061e1ce358ef33143433fc94d24

Change IDs have nothing to do here.

However a Fixes and a Signed-off-by are welcome.

You'll also need to Cc: Rob H. in your v2.

> ---
>  .../bindings/mtd/amlogic,meson-nand.txt        | 18 +++---------------
>  1 file changed, 3 insertions(+), 15 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> index 5794ab1147c1..37f16fe4fe66 100644
> --- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> @@ -14,11 +14,6 @@ Required properties:
>  - clock-names: Should contain the following:
>  	"core" - NFC module gate clock
>  	"device" - device clock from eMMC sub clock controller
> -	"rx" - rx clock phase
> -	"tx" - tx clock phase
> -
> -- amlogic,mmc-syscon	: Required for NAND clocks, it's shared with SD/eMMC
> -				controller port C
>  
>  Optional children nodes:
>  Children nodes represent the available nand chips.
> @@ -28,11 +23,6 @@ see Documentation/devicetree/bindings/mtd/nand-controller.yaml for generic bindi
>  
>  Example demonstrate on AXG SoC:
>  
> -	sd_emmc_c_clkc: mmc at 7000 {
> -		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
> -		reg = <0x0 0x7000 0x0 0x800>;
> -	};
> -
>  	nand-controller at 7800 {
>  		compatible = "amlogic,meson-axg-nfc";
>  		reg = <0x0 0x7800 0x0 0x100>;
> @@ -41,11 +31,9 @@ Example demonstrate on AXG SoC:
>  		interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
>  
>  		clocks = <&clkc CLKID_SD_EMMC_C>,
> -			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
> -		clock-names = "core", "device", "rx", "tx";
> -		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
> +			<&clkc CLKID_FCLK_DIV2>;
> +		clock-names = "core", "device";
> +		sd_emmc_c_clkc = <0xffe07000>;
>  
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&nand_pins>;


Thanks,
Miqu?l


From miquel.raynal at bootlin.com  Thu Jan  6 00:12:46 2022
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Thu, 6 Jan 2022 09:12:46 +0100
Subject: [PATCH] dt-bindings: nand: meson: fix controller clock
In-Reply-To: <20220106033130.37623-1-liang.yang@amlogic.com>
References: <20220106033130.37623-1-liang.yang@amlogic.com>
Message-ID: <20220106091246.08ca66e0@xps13>



liang.yang at amlogic.com wrote on Thu, 6 Jan 2022 11:31:30 +0800:

> Change-Id: I1425b491d8b95061e1ce358ef33143433fc94d24
> ---
>  .../bindings/mtd/amlogic,meson-nand.txt        | 18 +++---------------

I forgot to mention, while you're at it, after fixing the bindings,
could you please convert it to yaml?

>  1 file changed, 3 insertions(+), 15 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> index 5794ab1147c1..37f16fe4fe66 100644
> --- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> @@ -14,11 +14,6 @@ Required properties:
>  - clock-names: Should contain the following:
>  	"core" - NFC module gate clock
>  	"device" - device clock from eMMC sub clock controller
> -	"rx" - rx clock phase
> -	"tx" - tx clock phase
> -
> -- amlogic,mmc-syscon	: Required for NAND clocks, it's shared with SD/eMMC
> -				controller port C
>  
>  Optional children nodes:
>  Children nodes represent the available nand chips.
> @@ -28,11 +23,6 @@ see Documentation/devicetree/bindings/mtd/nand-controller.yaml for generic bindi
>  
>  Example demonstrate on AXG SoC:
>  
> -	sd_emmc_c_clkc: mmc at 7000 {
> -		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
> -		reg = <0x0 0x7000 0x0 0x800>;
> -	};
> -
>  	nand-controller at 7800 {
>  		compatible = "amlogic,meson-axg-nfc";
>  		reg = <0x0 0x7800 0x0 0x100>;
> @@ -41,11 +31,9 @@ Example demonstrate on AXG SoC:
>  		interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
>  
>  		clocks = <&clkc CLKID_SD_EMMC_C>,
> -			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
> -		clock-names = "core", "device", "rx", "tx";
> -		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
> +			<&clkc CLKID_FCLK_DIV2>;
> +		clock-names = "core", "device";
> +		sd_emmc_c_clkc = <0xffe07000>;
>  
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&nand_pins>;


Thanks,
Miqu?l


From narmstrong at baylibre.com  Thu Jan  6 00:19:09 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 6 Jan 2022 09:19:09 +0100
Subject: [PATCH] dt-bindings: nand: meson: fix controller clock
In-Reply-To: <20220106033130.37623-1-liang.yang@amlogic.com>
References: <20220106033130.37623-1-liang.yang@amlogic.com>
Message-ID: <8439ec98-694e-0391-2a00-89e856024823@baylibre.com>

Hi,

On 06/01/2022 04:31, Liang Yang wrote:
> Change-Id: I1425b491d8b95061e1ce358ef33143433fc94d24
> ---
>  .../bindings/mtd/amlogic,meson-nand.txt        | 18 +++---------------
>  1 file changed, 3 insertions(+), 15 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> index 5794ab1147c1..37f16fe4fe66 100644
> --- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> @@ -14,11 +14,6 @@ Required properties:
>  - clock-names: Should contain the following:
>  	"core" - NFC module gate clock
>  	"device" - device clock from eMMC sub clock controller
> -	"rx" - rx clock phase
> -	"tx" - tx clock phase
> -
> -- amlogic,mmc-syscon	: Required for NAND clocks, it's shared with SD/eMMC
> -				controller port C
>  
>  Optional children nodes:
>  Children nodes represent the available nand chips.
> @@ -28,11 +23,6 @@ see Documentation/devicetree/bindings/mtd/nand-controller.yaml for generic bindi
>  
>  Example demonstrate on AXG SoC:
>  
> -	sd_emmc_c_clkc: mmc at 7000 {
> -		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
> -		reg = <0x0 0x7000 0x0 0x800>;
> -	};
> -
>  	nand-controller at 7800 {
>  		compatible = "amlogic,meson-axg-nfc";
>  		reg = <0x0 0x7800 0x0 0x100>;
> @@ -41,11 +31,9 @@ Example demonstrate on AXG SoC:
>  		interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
>  
>  		clocks = <&clkc CLKID_SD_EMMC_C>,
> -			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
> -		clock-names = "core", "device", "rx", "tx";
> -		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
> +			<&clkc CLKID_FCLK_DIV2>;
> +		clock-names = "core", "device";
> +		sd_emmc_c_clkc = <0xffe07000>;


sd_emmc_c_clkc should be documented, but it should be either:
- a syscon
- in reg

but since 0xffe07000 is part of the emmc memory space, you can't simply
put this address like that and pass it to a random undocumented property.

Adding "syscon" to the sd_emmc_c compatibles, and passing the sd_emmc_c node as syscon
could actually work.

Neil

>  
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&nand_pins>;
> 



From jbrunet at baylibre.com  Thu Jan  6 00:16:44 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Thu, 06 Jan 2022 09:16:44 +0100
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <20220106032504.23310-1-liang.yang@amlogic.com>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
Message-ID: <1jfsq1z22l.fsf@starbuckisacylon.baylibre.com>


On Thu 06 Jan 2022 at 11:25, Liang Yang <liang.yang at amlogic.com> wrote:

> Because EMMC and NAND have the same control clock register, so we
> implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:
>
> 	sd_emmc_c_clkc: mmc at 7000 {
> 		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
> 		reg = <0x0 0x7000 0x0 0x800>;
> 	};
>
> 	nand-controller at 7800 {
> 		......
>
> 		clocks = <&clkc CLKID_SD_EMMC_C>,
> 			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
> 		clock-names = "core", "device", "rx", "tx";
> 		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>
> 		......
> 	}
>
> but in fact, above implementation is rejected. so now registering
> a nand_divider.

Can you give a bit of context ? a link to the discussion rejecting this

As far as remember, things were getting done for A1 and stopped before
clock part was finished. I'm saying the change is wrong, just that a
discussion is needed before a decision is made.

>
> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
> ---
>  drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
>  1 file changed, 49 insertions(+), 39 deletions(-)
>
> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
> index ac3be92872d0..4472363059c2 100644
> --- a/drivers/mtd/nand/raw/meson_nand.c
> +++ b/drivers/mtd/nand/raw/meson_nand.c
> @@ -2,7 +2,7 @@
>  /*
>   * Amlogic Meson Nand Flash Controller Driver
>   *
> - * Copyright (c) 2018 Amlogic, inc.
> + * Copyright (c) 2018-2021 Amlogic, inc.
>   * Author: Liang Yang <liang.yang at amlogic.com>
>   */
>  
> @@ -10,6 +10,7 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/interrupt.h>
>  #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>  #include <linux/mtd/rawnand.h>
>  #include <linux/mtd/mtd.h>
>  #include <linux/mfd/syscon.h>
> @@ -55,6 +56,7 @@
>  #define NFC_REG_VER		0x38
>  
>  #define NFC_RB_IRQ_EN		BIT(21)
> +#define NFC_CMD_FIFO_RESET	BIT(31)
>  
>  #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)	\
>  	(								\
> @@ -104,6 +106,9 @@
>  
>  #define PER_INFO_BYTE		8
>  
> +#define CLK_DIV_SHIFT		0
> +#define CLK_DIV_WIDTH		6
> +
>  struct meson_nfc_nand_chip {
>  	struct list_head node;
>  	struct nand_chip nand;
> @@ -151,15 +156,15 @@ struct meson_nfc {
>  	struct nand_controller controller;
>  	struct clk *core_clk;
>  	struct clk *device_clk;
> -	struct clk *phase_tx;
> -	struct clk *phase_rx;

I would have been nice to explain why these clock are no longer
required, in the change description maybe ?

> +	struct clk *nand_clk;
> +	struct clk_divider nand_divider;
>  
>  	unsigned long clk_rate;
>  	u32 bus_timing;
>  
>  	struct device *dev;
>  	void __iomem *reg_base;
> -	struct regmap *reg_clk;
> +	void __iomem *reg_clk;
>  	struct completion completion;
>  	struct list_head chips;
>  	const struct meson_nfc_data *data;
> @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
>  	cmd = NFC_CMD_RB | NFC_CMD_RB_INT
>  		| nfc->param.chip_select | nfc->timing.tbers_max;
>  	writel(cmd, nfc->reg_base + NFC_REG_CMD);
> -
> +	meson_nfc_drain_cmd(nfc);

is this clock related ?

>  	ret = wait_for_completion_timeout(&nfc->completion,
>  					  msecs_to_jiffies(timeout_ms));
>  	if (ret == 0)
>  		ret = -1;
>  
> +	/* reset command fifo to avoid lock */
> +	writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);

Again, not seem to be clock related - does not belong in this patch

>  	return ret;
>  }
>  
> @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
>  static int meson_nfc_clk_init(struct meson_nfc *nfc)
>  {
>  	int ret;
> +	struct clk_init_data init = {0};
> +	const char *fix_div2_pll_name[1];
>  
> -	/* request core clock */

Why is the comment bothering you ?

>  	nfc->core_clk = devm_clk_get(nfc->dev, "core");
>  	if (IS_ERR(nfc->core_clk)) {
>  		dev_err(nfc->dev, "failed to get core clock\n");
> @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>  		return PTR_ERR(nfc->device_clk);
>  	}
>  
> -	nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
> -	if (IS_ERR(nfc->phase_tx)) {
> -		dev_err(nfc->dev, "failed to get TX clk\n");
> -		return PTR_ERR(nfc->phase_tx);
> -	}
> -
> -	nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
> -	if (IS_ERR(nfc->phase_rx)) {
> -		dev_err(nfc->dev, "failed to get RX clk\n");
> -		return PTR_ERR(nfc->phase_rx);
> -	}
> +	init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
> +	init.ops = &clk_divider_ops;
> +	fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);

You should be using "fw_name" so CCF looks a DT directly, instead of this

> +	init.parent_names = fix_div2_pll_name;
> +	init.num_parents = 1;
> +	nfc->nand_divider.reg = nfc->reg_clk;
> +	nfc->nand_divider.shift = CLK_DIV_SHIFT;
> +	nfc->nand_divider.width = CLK_DIV_WIDTH;
> +	nfc->nand_divider.hw.init = &init;
> +	nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
> +				  CLK_DIVIDER_ROUND_CLOSEST |
> +          			  CLK_DIVIDER_ALLOW_ZERO;
> +
> +	nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
> +	if (IS_ERR(nfc->nand_clk))
> +		return PTR_ERR(nfc->nand_clk);
>  
>  	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
> -	regmap_update_bits(nfc->reg_clk,
> -			   0, CLK_SELECT_NAND, CLK_SELECT_NAND);
> +	writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
>  
>  	ret = clk_prepare_enable(nfc->core_clk);
>  	if (ret) {
> @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>  		goto err_device_clk;
>  	}
>  
> -	ret = clk_prepare_enable(nfc->phase_tx);
> +	ret = clk_prepare_enable(nfc->nand_clk);
>  	if (ret) {
> -		dev_err(nfc->dev, "failed to enable TX clock\n");
> -		goto err_phase_tx;
> -	}
> -
> -	ret = clk_prepare_enable(nfc->phase_rx);
> -	if (ret) {
> -		dev_err(nfc->dev, "failed to enable RX clock\n");
> -		goto err_phase_rx;
> +		dev_err(nfc->dev, "pre enable NFC divider fail\n");
> +		goto err_nand_clk;
>  	}
>  
>  	ret = clk_set_rate(nfc->device_clk, 24000000);
>  	if (ret)
> -		goto err_disable_rx;
> +		goto err_disable_clk;
>  
>  	return 0;
>  
> -err_disable_rx:
> -	clk_disable_unprepare(nfc->phase_rx);
> -err_phase_rx:
> -	clk_disable_unprepare(nfc->phase_tx);
> -err_phase_tx:
> +err_disable_clk:
> +	clk_disable_unprepare(nfc->nand_clk);
> +err_nand_clk:
>  	clk_disable_unprepare(nfc->device_clk);
>  err_device_clk:
>  	clk_disable_unprepare(nfc->core_clk);
> @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>  
>  static void meson_nfc_disable_clk(struct meson_nfc *nfc)
>  {
> -	clk_disable_unprepare(nfc->phase_rx);
> -	clk_disable_unprepare(nfc->phase_tx);
> +	clk_disable_unprepare(nfc->nand_clk);
>  	clk_disable_unprepare(nfc->device_clk);
>  	clk_disable_unprepare(nfc->core_clk);
>  }
> @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
>  	struct device *dev = &pdev->dev;
>  	struct meson_nfc *nfc;
>  	struct resource *res;
> +	u32 ext_clk_reg;
>  	int ret, irq;
>  
>  	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
> @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
>  	if (IS_ERR(nfc->reg_base))
>  		return PTR_ERR(nfc->reg_base);
>  
> -	nfc->reg_clk =
> -		syscon_regmap_lookup_by_phandle(dev->of_node,
> -						"amlogic,mmc-syscon");
> +	ret = of_property_read_u32(pdev->dev.of_node,
> +				   "sd_emmc_c_clkc",
> +				   &ext_clk_reg);
> +	if (ret) {
> +		dev_err(dev, "failed to get NAND external clock register\n");
> +		return ret;
> +	}
> +
> +	nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));

That's how you should get a register region.
If you want an example of a device claiming several region on amlogic,
have a look at the pinctrl driver. 

>  	if (IS_ERR(nfc->reg_clk)) {
>  		dev_err(dev, "Failed to lookup clock base\n");
>  		return PTR_ERR(nfc->reg_clk);



From jbrunet at baylibre.com  Thu Jan  6 00:43:56 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Thu, 06 Jan 2022 09:43:56 +0100
Subject: [PATCH] dt-bindings: nand: meson: fix controller clock
In-Reply-To: <20220106091246.08ca66e0@xps13>
References: <20220106033130.37623-1-liang.yang@amlogic.com>
 <20220106091246.08ca66e0@xps13>
Message-ID: <1jbl0pz1t4.fsf@starbuckisacylon.baylibre.com>


On Thu 06 Jan 2022 at 09:12, Miquel Raynal <miquel.raynal at bootlin.com> wrote:

> liang.yang at amlogic.com wrote on Thu, 6 Jan 2022 11:31:30 +0800:
>
>> Change-Id: I1425b491d8b95061e1ce358ef33143433fc94d24
>> ---
>>  .../bindings/mtd/amlogic,meson-nand.txt        | 18 +++---------------
>
> I forgot to mention, while you're at it, after fixing the bindings,
> could you please convert it to yaml?
>
>>  1 file changed, 3 insertions(+), 15 deletions(-)
>> 
>> diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
>> index 5794ab1147c1..37f16fe4fe66 100644
>> --- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
>> +++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
>> @@ -14,11 +14,6 @@ Required properties:
>>  - clock-names: Should contain the following:
>>  	"core" - NFC module gate clock
>>  	"device" - device clock from eMMC sub clock controller

If I refer to the related driver change, this is not true anymore and
should be updated

>> -	"rx" - rx clock phase
>> -	"tx" - tx clock phase
>> -
>> -- amlogic,mmc-syscon	: Required for NAND clocks, it's shared with SD/eMMC
>> -				controller port C
>>  
>>  Optional children nodes:
>>  Children nodes represent the available nand chips.
>> @@ -28,11 +23,6 @@ see Documentation/devicetree/bindings/mtd/nand-controller.yaml for generic bindi
>>  
>>  Example demonstrate on AXG SoC:
>>  
>> -	sd_emmc_c_clkc: mmc at 7000 {
>> -		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
>> -		reg = <0x0 0x7000 0x0 0x800>;
>> -	};
>> -
>>  	nand-controller at 7800 {
>>  		compatible = "amlogic,meson-axg-nfc";
>>  		reg = <0x0 0x7800 0x0 0x100>;
>> @@ -41,11 +31,9 @@ Example demonstrate on AXG SoC:
>>  		interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
>>  
>>  		clocks = <&clkc CLKID_SD_EMMC_C>,
>> -			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
>> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
>> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
>> -		clock-names = "core", "device", "rx", "tx";
>> -		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>> +			<&clkc CLKID_FCLK_DIV2>;
>> +		clock-names = "core", "device";

If you want to re-implement the mmc clock part directly in the nand
driver, you should provide both clock inputs, like the mmc driver (in
addition to the pclk) ... Even if you plan on using only FDIV2 in the
driver, this what the HW is.

Something like:

clock-names = "core", "clkin0", "clkin1";
clocks = <&clkc CLKID_SD_EMMC_C>,
         <&clkc CLKID_SD_EMMC_C_CLK0>,
	 <&clkc CLKID_FCLK_DIV2>;

>> +		sd_emmc_c_clkc = <0xffe07000>;

This is not how you provide memory regions

>>  
>>  		pinctrl-names = "default";
>>  		pinctrl-0 = <&nand_pins>;
>
>
> Thanks,
> Miqu?l



From jbrunet at baylibre.com  Thu Jan  6 02:41:21 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Thu, 06 Jan 2022 11:41:21 +0100
Subject: [PATCH V3] arm64: dts: add support for S4 based Amlogic AQ222
In-Reply-To: <20220106054724.18637-1-xianwei.zhao@amlogic.com>
References: <20220106054724.18637-1-xianwei.zhao@amlogic.com>
Message-ID: <1jv8yx5ekq.fsf@starbuckisacylon.baylibre.com>


On Thu 06 Jan 2022 at 13:47, Xianwei Zhao <xianwei.zhao at amlogic.com> wrote:

> Add basic support for the Amlogic S4 based Amlogic AQ222 board:
> which describe components as follows: CPU, GIC, IRQ, Timer, UART.
> It's capable of booting up into the serial console.
>
> Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
> ---
> V2 -> V3: add of dts board  compatible family
> V1 -> V2: cleaned up coding style, modify CPU affinity of timer interrups,
>           and modify GIC reg defintions.
> ---
>  arch/arm64/boot/dts/amlogic/Makefile          |  1 +
>  .../dts/amlogic/meson-s4-s805x2-aq222.dts     | 30 ++++++
>  arch/arm64/boot/dts/amlogic/meson-s4.dtsi     | 99 +++++++++++++++++++
>  3 files changed, 130 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
>  create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4.dtsi
>
> diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
> index 5148cd9e5146..faea74a45994 100644
> --- a/arch/arm64/boot/dts/amlogic/Makefile
> +++ b/arch/arm64/boot/dts/amlogic/Makefile
> @@ -57,3 +57,4 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
> +dtb-$(CONFIG_ARCH_MESON) += meson-s4-s805x2-aq222.dtb
> diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
> new file mode 100644
> index 000000000000..a942d7e06d6e
> --- /dev/null
> +++ b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
> @@ -0,0 +1,30 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
> + */
> +
> +/dts-v1/;
> +
> +#include "meson-s4.dtsi"
> +
> +/ {
> +	model = "Amlogic Meson S4 AQ222 Development Board";
> +	compatible = "amlogic,aq222", "amlogic,s4";
> +	interrupt-parent = <&gic>;
> +	#address-cells = <2>;
> +	#size-cells = <2>;
> +
> +	aliases {
> +		serial0 = &uart_B;
> +	};
> +
> +	memory at 00000000 {
> +		device_type = "memory";
> +		reg = <0x0 0x0 0x0 0x40000000>;
> +	};
> +
> +};
> +
> +&uart_B {
> +	status = "okay";
> +};
> diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
> new file mode 100644
> index 000000000000..d7083c93d3d0
> --- /dev/null
> +++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
> @@ -0,0 +1,99 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
> + */
> +
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +/ {
> +	cpus:cpus {
            ^ space after : ?

Do we need the alias here ?

> +		#address-cells = <2>;
> +		#size-cells = <0>;
> +
> +		CPU0:cpu at 0 {
                    ^ space after : ?

Why is the alias uppercase ?

same for the other nodes

> +			device_type = "cpu";
> +			compatible = "arm,cortex-a35","arm,armv8";
> +			reg = <0x0 0x0>;
> +			enable-method = "psci";
> +		};
> +
> +		CPU1:cpu at 1 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a35","arm,armv8";
> +			reg = <0x0 0x1>;
> +			enable-method = "psci";
> +		};
> +
> +		CPU2:cpu at 2 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a35","arm,armv8";
> +			reg = <0x0 0x2>;
> +			enable-method = "psci";
> +		};
> +
> +		CPU3:cpu at 3 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a35","arm,armv8";
> +			reg = <0x0 0x3>;
> +			enable-method = "psci";
> +		};
> +	};
> +
> +	timer {
> +		compatible = "arm,armv8-timer";
> +		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> +			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> +			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> +			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
> +	};
> +
> +	psci {
> +		compatible = "arm,psci-1.0";
> +		method = "smc";
> +	};
> +
> +	xtal: xtal-clk {
> +		compatible = "fixed-clock";
> +		clock-frequency = <24000000>;
> +		clock-output-names = "xtal";
> +		#clock-cells = <0>;
> +	};
> +
> +	soc {
> +		compatible = "simple-bus";
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		gic: interrupt-controller at fff01000 {
> +			compatible = "arm,gic-400";
> +			#interrupt-cells = <3>;
> +			#address-cells = <0>;
> +			interrupt-controller;
> +			reg = <0x0 0xfff01000 0 0x1000>,
> +			      <0x0 0xfff02000 0 0x2000>,
> +			      <0x0 0xfff04000 0 0x2000>,
> +			      <0x0 0xfff06000 0 0x2000>;
> +			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
> +		};
> +
> +		apb4: apb4 at fe000000 {
> +			compatible = "simple-bus";
> +			reg = <0x0 0xfe000000 0x0 0x480000>;
> +			#address-cells = <2>;
> +			#size-cells = <2>;
> +			ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;
> +
> +			uart_B: serial at 7a000 {
> +				compatible = "amlogic,meson-s4-uart",
> +					     "amlogic,meson-ao-uart";
> +				reg = <0x0 0x7a000 0x0 0x18>;
> +				interrupts = <GIC_SPI 169 IRQ_TYPE_EDGE_RISING>;
> +				status = "disabled";
> +				clocks = <&xtal>, <&xtal>, <&xtal>;
> +				clock-names = "xtal", "pclk", "baud";
> +			};
> +		};
> +	};
> +};
>
> base-commit: c5468e3c930d4d2937d3a842a85df0f74e95e152



From rong.chen at amlogic.com  Thu Jan  6 02:54:53 2022
From: rong.chen at amlogic.com (Rong Chen)
Date: Thu, 6 Jan 2022 18:54:53 +0800
Subject: [PATCH] mmc: meson: Fix usage of meson_mmc_post_req()
Message-ID: <20220106105453.3875119-1-rong.chen@amlogic.com>

To ensure the DMA moves data correctly from memory to
peripherals, DMA unmapping when the MMC request done
with calls meson_mmc_post_req().

Signed-off-by: Rong Chen <rong.chen at amlogic.com>
---
 drivers/mmc/host/meson-gx-mmc.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
index 8f36536cb1b6..6a9554ae4b1c 100644
--- a/drivers/mmc/host/meson-gx-mmc.c
+++ b/drivers/mmc/host/meson-gx-mmc.c
@@ -173,6 +173,7 @@ struct meson_host {
 	int irq;
 
 	bool vqmmc_enabled;
+	bool needs_pre_post_req;
 };
 
 #define CMD_CFG_LENGTH_MASK GENMASK(8, 0)
@@ -663,6 +664,8 @@ static void meson_mmc_request_done(struct mmc_host *mmc,
 	struct meson_host *host = mmc_priv(mmc);
 
 	host->cmd = NULL;
+	if (host->needs_pre_post_req)
+		meson_mmc_post_req(mmc, mrq, 0);
 	mmc_request_done(host->mmc, mrq);
 }
 
@@ -880,7 +883,7 @@ static int meson_mmc_validate_dram_access(struct mmc_host *mmc, struct mmc_data
 static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
 	struct meson_host *host = mmc_priv(mmc);
-	bool needs_pre_post_req = mrq->data &&
+	host->needs_pre_post_req = mrq->data &&
 			!(mrq->data->host_cookie & SD_EMMC_PRE_REQ_DONE);
 
 	/*
@@ -896,22 +899,19 @@ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 		}
 	}
 
-	if (needs_pre_post_req) {
+	if (host->needs_pre_post_req) {
 		meson_mmc_get_transfer_mode(mmc, mrq);
 		if (!meson_mmc_desc_chain_mode(mrq->data))
-			needs_pre_post_req = false;
+			host->needs_pre_post_req = false;
 	}
 
-	if (needs_pre_post_req)
+	if (host->needs_pre_post_req)
 		meson_mmc_pre_req(mmc, mrq);
 
 	/* Stop execution */
 	writel(0, host->regs + SD_EMMC_START);
 
 	meson_mmc_start_cmd(mmc, mrq->sbc ?: mrq->cmd);
-
-	if (needs_pre_post_req)
-		meson_mmc_post_req(mmc, mrq, 0);
 }
 
 static void meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command *cmd)

base-commit: 356f3f2c5756bbb67a515760966a40fc7043cdda
-- 
2.25.1



From xianwei.zhao at amlogic.com  Thu Jan  6 03:20:13 2022
From: xianwei.zhao at amlogic.com (xianwei.zhao)
Date: Thu, 6 Jan 2022 19:20:13 +0800
Subject: [PATCH V3] arm64: dts: add support for S4 based Amlogic AQ222
In-Reply-To: <1jv8yx5ekq.fsf@starbuckisacylon.baylibre.com>
References: <20220106054724.18637-1-xianwei.zhao@amlogic.com>
 <1jv8yx5ekq.fsf@starbuckisacylon.baylibre.com>
Message-ID: <d21728fd-2258-c967-f518-ebca6ec3d9b4@amlogic.com>

Hi Jerome,

     I will modify those lines and update the patch later.

Thanks!




Best regards,





xianwei.zhao

On 2022/1/6 ??6:41, Jerome Brunet wrote:
> 
> 
> On Thu 06 Jan 2022 at 13:47, Xianwei Zhao <xianwei.zhao at amlogic.com> wrote:
> 
>> Add basic support for the Amlogic S4 based Amlogic AQ222 board:
>> which describe components as follows: CPU, GIC, IRQ, Timer, UART.
>> It's capable of booting up into the serial console.
>>
>> Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
>> ---
>> V2 -> V3: add of dts board  compatible family
>> V1 -> V2: cleaned up coding style, modify CPU affinity of timer interrups,
>>            and modify GIC reg defintions.
>> ---
>>   arch/arm64/boot/dts/amlogic/Makefile          |  1 +
>>   .../dts/amlogic/meson-s4-s805x2-aq222.dts     | 30 ++++++
>>   arch/arm64/boot/dts/amlogic/meson-s4.dtsi     | 99 +++++++++++++++++++
>>   3 files changed, 130 insertions(+)
>>   create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
>>   create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4.dtsi
>>
>> diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
>> index 5148cd9e5146..faea74a45994 100644
>> --- a/arch/arm64/boot/dts/amlogic/Makefile
>> +++ b/arch/arm64/boot/dts/amlogic/Makefile
>> @@ -57,3 +57,4 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
>>   dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
>>   dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
>>   dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
>> +dtb-$(CONFIG_ARCH_MESON) += meson-s4-s805x2-aq222.dtb
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
>> new file mode 100644
>> index 000000000000..a942d7e06d6e
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
>> @@ -0,0 +1,30 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>> +/*
>> + * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
>> + */
>> +
>> +/dts-v1/;
>> +
>> +#include "meson-s4.dtsi"
>> +
>> +/ {
>> +	model = "Amlogic Meson S4 AQ222 Development Board";
>> +	compatible = "amlogic,aq222", "amlogic,s4";
>> +	interrupt-parent = <&gic>;
>> +	#address-cells = <2>;
>> +	#size-cells = <2>;
>> +
>> +	aliases {
>> +		serial0 = &uart_B;
>> +	};
>> +
>> +	memory at 00000000 {
>> +		device_type = "memory";
>> +		reg = <0x0 0x0 0x0 0x40000000>;
>> +	};
>> +
>> +};
>> +
>> +&uart_B {
>> +	status = "okay";
>> +};
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
>> new file mode 100644
>> index 000000000000..d7083c93d3d0
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
>> @@ -0,0 +1,99 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>> +/*
>> + * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
>> + */
>> +
>> +#include <dt-bindings/interrupt-controller/irq.h>
>> +#include <dt-bindings/interrupt-controller/arm-gic.h>
>> +
>> +/ {
>> +	cpus:cpus {
>              ^ space after : ?
> 
> Do we need the alias here ?
> 
>> +		#address-cells = <2>;
>> +		#size-cells = <0>;
>> +
>> +		CPU0:cpu at 0 {
>                      ^ space after : ?
> 
> Why is the alias uppercase ?
> 
> same for the other nodes
> 
>> +			device_type = "cpu";
>> +			compatible = "arm,cortex-a35","arm,armv8";
>> +			reg = <0x0 0x0>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		CPU1:cpu at 1 {
>> +			device_type = "cpu";
>> +			compatible = "arm,cortex-a35","arm,armv8";
>> +			reg = <0x0 0x1>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		CPU2:cpu at 2 {
>> +			device_type = "cpu";
>> +			compatible = "arm,cortex-a35","arm,armv8";
>> +			reg = <0x0 0x2>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		CPU3:cpu at 3 {
>> +			device_type = "cpu";
>> +			compatible = "arm,cortex-a35","arm,armv8";
>> +			reg = <0x0 0x3>;
>> +			enable-method = "psci";
>> +		};
>> +	};
>> +
>> +	timer {
>> +		compatible = "arm,armv8-timer";
>> +		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
>> +			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
>> +			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
>> +			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
>> +	};
>> +
>> +	psci {
>> +		compatible = "arm,psci-1.0";
>> +		method = "smc";
>> +	};
>> +
>> +	xtal: xtal-clk {
>> +		compatible = "fixed-clock";
>> +		clock-frequency = <24000000>;
>> +		clock-output-names = "xtal";
>> +		#clock-cells = <0>;
>> +	};
>> +
>> +	soc {
>> +		compatible = "simple-bus";
>> +		#address-cells = <2>;
>> +		#size-cells = <2>;
>> +		ranges;
>> +
>> +		gic: interrupt-controller at fff01000 {
>> +			compatible = "arm,gic-400";
>> +			#interrupt-cells = <3>;
>> +			#address-cells = <0>;
>> +			interrupt-controller;
>> +			reg = <0x0 0xfff01000 0 0x1000>,
>> +			      <0x0 0xfff02000 0 0x2000>,
>> +			      <0x0 0xfff04000 0 0x2000>,
>> +			      <0x0 0xfff06000 0 0x2000>;
>> +			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
>> +		};
>> +
>> +		apb4: apb4 at fe000000 {
>> +			compatible = "simple-bus";
>> +			reg = <0x0 0xfe000000 0x0 0x480000>;
>> +			#address-cells = <2>;
>> +			#size-cells = <2>;
>> +			ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;
>> +
>> +			uart_B: serial at 7a000 {
>> +				compatible = "amlogic,meson-s4-uart",
>> +					     "amlogic,meson-ao-uart";
>> +				reg = <0x0 0x7a000 0x0 0x18>;
>> +				interrupts = <GIC_SPI 169 IRQ_TYPE_EDGE_RISING>;
>> +				status = "disabled";
>> +				clocks = <&xtal>, <&xtal>, <&xtal>;
>> +				clock-names = "xtal", "pclk", "baud";
>> +			};
>> +		};
>> +	};
>> +};
>>
>> base-commit: c5468e3c930d4d2937d3a842a85df0f74e95e152
> 
> .
>


From xianwei.zhao at amlogic.com  Thu Jan  6 03:22:14 2022
From: xianwei.zhao at amlogic.com (Xianwei Zhao)
Date: Thu, 6 Jan 2022 19:22:14 +0800
Subject: [PATCH V4] arm64: dts: add support for S4 based Amlogic AQ222
Message-ID: <20220106112214.6987-1-xianwei.zhao@amlogic.com>

Add basic support for the Amlogic S4 based Amlogic AQ222 board:
which describe components as follows: CPU, GIC, IRQ, Timer, UART.
It's capable of booting up into the serial console.

Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
---
V3 -> V4: cleaned up coding style.
V2 -> V3: add of dts board  compatible family.
V1 -> V2: cleaned up coding style, modify CPU affinity of timer interrups,
          and modify GIC reg defintions.
---
 arch/arm64/boot/dts/amlogic/Makefile          |  1 +
 .../dts/amlogic/meson-s4-s805x2-aq222.dts     | 30 ++++++
 arch/arm64/boot/dts/amlogic/meson-s4.dtsi     | 99 +++++++++++++++++++
 3 files changed, 130 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4.dtsi

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 5148cd9e5146..faea74a45994 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -57,3 +57,4 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-s4-s805x2-aq222.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
new file mode 100644
index 000000000000..a942d7e06d6e
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "meson-s4.dtsi"
+
+/ {
+	model = "Amlogic Meson S4 AQ222 Development Board";
+	compatible = "amlogic,aq222", "amlogic,s4";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		serial0 = &uart_B;
+	};
+
+	memory at 00000000 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x40000000>;
+	};
+
+};
+
+&uart_B {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
new file mode 100644
index 000000000000..bf9ae1e1016b
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35","arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+		};
+
+		cpu1: cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35","arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+		};
+
+		cpu2: cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35","arm,armv8";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+		};
+
+		cpu3: cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35","arm,armv8";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	xtal: xtal-clk {
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "xtal";
+		#clock-cells = <0>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gic: interrupt-controller at fff01000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0x0 0xfff01000 0 0x1000>,
+			      <0x0 0xfff02000 0 0x2000>,
+			      <0x0 0xfff04000 0 0x2000>,
+			      <0x0 0xfff06000 0 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+		};
+
+		apb4: apb4 at fe000000 {
+			compatible = "simple-bus";
+			reg = <0x0 0xfe000000 0x0 0x480000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;
+
+			uart_B: serial at 7a000 {
+				compatible = "amlogic,meson-s4-uart",
+					     "amlogic,meson-ao-uart";
+				reg = <0x0 0x7a000 0x0 0x18>;
+				interrupts = <GIC_SPI 169 IRQ_TYPE_EDGE_RISING>;
+				status = "disabled";
+				clocks = <&xtal>, <&xtal>, <&xtal>;
+				clock-names = "xtal", "pclk", "baud";
+			};
+		};
+	};
+};

base-commit: c5468e3c930d4d2937d3a842a85df0f74e95e152
-- 
2.30.2



From khilman at baylibre.com  Thu Jan  6 11:06:10 2022
From: khilman at baylibre.com (Kevin Hilman)
Date: Thu, 06 Jan 2022 11:06:10 -0800
Subject: [PATCH v5 0/3] usb: meson: fix shared reset control use
In-Reply-To: <20211212201844.114949-1-aouledameur@baylibre.com>
References: <20211212201844.114949-1-aouledameur@baylibre.com>
Message-ID: <7hv8ywr8f1.fsf@baylibre.com>

Hi Amjad,

Amjad Ouled-Ameur <aouledameur at baylibre.com> writes:

> This patchset fixes a usb suspend warning seen on the libretech-cc by
> using reset_control_rearm() call of the reset framework API. 
> This call allows a reset consummer to release the reset line even when 
> just triggered so that it may be triggered again by other reset
> consummers.
>
> reset_control_(de)assert() calls are called, in some meson usb drivers, 
> on a shared reset line when reset_control_reset has been used. This is not
> allowed by the reset framework.
>
> Finally the meson usb drivers are updated to use this new call, which
> solves the suspend issue addressed by the previous reverted 
> commit 7a410953d1fb ("usb: dwc3: meson-g12a: fix shared reset control
> use").
>
> changes since v4:
> - call reset_control_rearm() after clk_prepare_enable() fails
>
> Amjad Ouled-Ameur (3):
>   phy: amlogic: phy-meson-gxl-usb2: fix shared reset controller use
>   phy: amlogic: meson8b-usb2: Use dev_err_probe()
>   phy: amlogic: meson8b-usb2: fix shared reset control use
>
>  drivers/phy/amlogic/phy-meson-gxl-usb2.c | 5 ++++-
>  drivers/phy/amlogic/phy-meson8b-usb2.c   | 9 +++++++--
>  2 files changed, 11 insertions(+), 3 deletions(-)

The cover letter prefix is "usb: meson" but all the patches are for
drivers/phy.

Could you collect the reviewed-by etc tags and resend to the PHY
maintainers and linux-phy list?

Thanks,

Kevin




From zelong.dong at amlogic.com  Thu Jan  6 18:39:28 2022
From: zelong.dong at amlogic.com (Zelong Dong)
Date: Fri, 7 Jan 2022 10:39:28 +0800
Subject: [PATCH 0/3] reset: meson-s4: add reset driver
Message-ID: <20220107023931.13251-1-zelong.dong@amlogic.com>


This patchset adds Reset controller driver support for Meson-S4 SoC.
Meson-S4 Reset Controller has 6 banks (the number of reset register)
and the level-reset register offset is 0x40.


Zelong Dong (3):
  dt-bindings: reset: Add compatible for Meson-S4 Reset Controller
  dt-bindings: reset: add bindings for the Meson-S4 SoC Reset Controller
  reset: reset-meson: add support for the Meson-S4 SoC Reset Controller

 .../bindings/reset/amlogic,meson-reset.yaml   |   1 +
 drivers/reset/reset-meson.c                   |   6 +
 .../reset/amlogic,meson-s4-reset.h            | 125 ++++++++++++++++++
 3 files changed, 132 insertions(+)
 create mode 100644 include/dt-bindings/reset/amlogic,meson-s4-reset.h

-- 
2.34.1



From zelong.dong at amlogic.com  Thu Jan  6 18:39:29 2022
From: zelong.dong at amlogic.com (Zelong Dong)
Date: Fri, 7 Jan 2022 10:39:29 +0800
Subject: [PATCH 1/3] dt-bindings: reset: Add compatible for Meson-S4 Reset
 Controller
In-Reply-To: <20220107023931.13251-1-zelong.dong@amlogic.com>
References: <20220107023931.13251-1-zelong.dong@amlogic.com>
Message-ID: <20220107023931.13251-2-zelong.dong@amlogic.com>

Add new compatible for Amlogic's Meson-S4 Reset Controller

Signed-off-by: Zelong Dong <zelong.dong at amlogic.com>
---
 Documentation/devicetree/bindings/reset/amlogic,meson-reset.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/reset/amlogic,meson-reset.yaml b/Documentation/devicetree/bindings/reset/amlogic,meson-reset.yaml
index 92922d3afd14..494a454928ce 100644
--- a/Documentation/devicetree/bindings/reset/amlogic,meson-reset.yaml
+++ b/Documentation/devicetree/bindings/reset/amlogic,meson-reset.yaml
@@ -17,6 +17,7 @@ properties:
       - amlogic,meson-gxbb-reset # Reset Controller on GXBB and compatible SoCs
       - amlogic,meson-axg-reset # Reset Controller on AXG and compatible SoCs
       - amlogic,meson-a1-reset # Reset Controller on A1 and compatible SoCs
+      - amlogic,meson-s4-reset # Reset Controller on S4 and compatible SoCs
 
   reg:
     maxItems: 1
-- 
2.34.1



From zelong.dong at amlogic.com  Thu Jan  6 18:39:30 2022
From: zelong.dong at amlogic.com (Zelong Dong)
Date: Fri, 7 Jan 2022 10:39:30 +0800
Subject: [PATCH 2/3] dt-bindings: reset: add bindings for the Meson-S4 SoC
 Reset Controller
In-Reply-To: <20220107023931.13251-1-zelong.dong@amlogic.com>
References: <20220107023931.13251-1-zelong.dong@amlogic.com>
Message-ID: <20220107023931.13251-3-zelong.dong@amlogic.com>

Add DT bindings for the Meson-S4 SoC Reset Controller include file.

Signed-off-by: Zelong Dong <zelong.dong at amlogic.com>
---
 .../reset/amlogic,meson-s4-reset.h            | 125 ++++++++++++++++++
 1 file changed, 125 insertions(+)
 create mode 100644 include/dt-bindings/reset/amlogic,meson-s4-reset.h

diff --git a/include/dt-bindings/reset/amlogic,meson-s4-reset.h b/include/dt-bindings/reset/amlogic,meson-s4-reset.h
new file mode 100644
index 000000000000..eab428eb8ad6
--- /dev/null
+++ b/include/dt-bindings/reset/amlogic,meson-s4-reset.h
@@ -0,0 +1,125 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
+ * Author: Zelong Dong <zelong.dong at amlogic.com>
+ *
+ */
+
+#ifndef _DT_BINDINGS_AMLOGIC_MESON_S4_RESET_H
+#define _DT_BINDINGS_AMLOGIC_MESON_S4_RESET_H
+
+/*	RESET0					*/
+#define RESET_USB_DDR0			0
+#define RESET_USB_DDR1			1
+#define RESET_USB_DDR2			2
+#define RESET_USB_DDR3			3
+#define RESET_USBCTRL			4
+/*					5-7	*/
+#define RESET_USBPHY20			8
+#define RESET_USBPHY21			9
+/*					10-15	*/
+#define RESET_HDMITX_APB		16
+#define RESET_BRG_VCBUS_DEC		17
+#define RESET_VCBUS			18
+#define RESET_VID_PLL_DIV		19
+#define RESET_VDI6			20
+#define RESET_GE2D			21
+#define RESET_HDMITXPHY			22
+#define RESET_VID_LOCK			23
+#define RESET_VENCL			24
+#define RESET_VDAC			25
+#define RESET_VENCP			26
+#define RESET_VENCI			27
+#define RESET_RDMA			28
+#define RESET_HDMI_TX			29
+#define RESET_VIU			30
+#define RESET_VENC			31
+
+/*	RESET1					*/
+#define RESET_AUDIO			32
+#define RESET_MALI_APB			33
+#define RESET_MALI			34
+#define RESET_DDR_APB			35
+#define RESET_DDR			36
+#define RESET_DOS_APB			37
+#define RESET_DOS			38
+/*					39-47	*/
+#define RESET_ETH			48
+/*					49-51	*/
+#define RESET_DEMOD			52
+/*					53-63	*/
+
+/*	RESET2					*/
+#define RESET_ABUS_ARB			64
+#define RESET_IR_CTRL			65
+#define RESET_TEMPSENSOR_DDR		66
+#define RESET_TEMPSENSOR_PLL		67
+/*					68-71	*/
+#define RESET_SMART_CARD		72
+#define RESET_SPICC0			73
+/*					74	*/
+#define RESET_RSA			75
+/*					76-79	*/
+#define RESET_MSR_CLK			80
+#define RESET_SPIFC			81
+#define RESET_SARADC			82
+/*					83-87	*/
+#define RESET_ACODEC			88
+#define RESET_CEC			89
+#define RESET_AFIFO			90
+#define RESET_WATCHDOG			91
+/*					92-95	*/
+
+/*	RESET3					*/
+/*					96-127	*/
+
+/*	RESET4					*/
+/*					128-131	*/
+#define RESET_PWM_AB			132
+#define RESET_PWM_CD			133
+#define RESET_PWM_EF			134
+#define RESET_PWM_GH			135
+#define RESET_PWM_IJ			136
+/*					137	*/
+#define RESET_UART_A			138
+#define RESET_UART_B			139
+#define RESET_UART_C			140
+#define RESET_UART_D			141
+#define RESET_UART_E			142
+/*					143	*/
+#define RESET_I2C_S_A			144
+#define RESET_I2C_M_A			145
+#define RESET_I2C_M_B			146
+#define RESET_I2C_M_C			147
+#define RESET_I2C_M_D			148
+#define RESET_I2C_M_E			149
+/*					150-151	*/
+#define RESET_SD_EMMC_A			152
+#define RESET_SD_EMMC_B			153
+#define RESET_NAND_EMMC			154
+/*					155-159	*/
+
+/* RESET5 */
+#define RESET_BRG_VDEC_PIPL0		160
+#define RESET_BRG_HEVCF_PIPL0		161
+/*					162	*/
+#define RESET_BRG_HCODEC_PIPL0		163
+#define RESET_BRG_GE2D_PIPL0		164
+#define RESET_BRG_VPU_PIPL0		165
+#define RESET_BRG_CPU_PIPL0		166
+#define RESET_BRG_MALI_PIPL0		167
+/*					168	*/
+#define RESET_BRG_MALI_PIPL1		169
+/*					170-171	*/
+#define RESET_BRG_HEVCF_PIPL1		172
+#define RESET_BRG_HEVCB_PIPL1		173
+/*					174-183	*/
+#define RESET_RAMA			184
+/*					185-186	*/
+#define RESET_BRG_NIC_VAPB		187
+#define RESET_BRG_NIC_DSU		188
+#define RESET_BRG_NIC_SYSCLK		189
+#define RESET_BRG_NIC_MAIN		190
+#define RESET_BRG_NIC_ALL		191
+
+#endif
-- 
2.34.1



From zelong.dong at amlogic.com  Thu Jan  6 18:39:31 2022
From: zelong.dong at amlogic.com (Zelong Dong)
Date: Fri, 7 Jan 2022 10:39:31 +0800
Subject: [PATCH 3/3] reset: reset-meson: add support for the Meson-S4 SoC
 Reset Controller
In-Reply-To: <20220107023931.13251-1-zelong.dong@amlogic.com>
References: <20220107023931.13251-1-zelong.dong@amlogic.com>
Message-ID: <20220107023931.13251-4-zelong.dong@amlogic.com>

Compared to the A1 SoCs the number of RESET registers is different
and the offset for the level registers is the same. Add a new
compatible string and struct meson_reset_param to add support for the
reset controller on the S4 SoC.

Signed-off-by: Zelong Dong <zelong.dong at amlogic.com>
---
 drivers/reset/reset-meson.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/reset/reset-meson.c b/drivers/reset/reset-meson.c
index c9bc325ad65a..26dc54778615 100644
--- a/drivers/reset/reset-meson.c
+++ b/drivers/reset/reset-meson.c
@@ -98,11 +98,17 @@ static const struct meson_reset_param meson_a1_param = {
 	.level_offset	= 0x40,
 };
 
+static const struct meson_reset_param meson_s4_param = {
+	.reg_count	= 6,
+	.level_offset	= 0x40,
+};
+
 static const struct of_device_id meson_reset_dt_ids[] = {
 	 { .compatible = "amlogic,meson8b-reset",    .data = &meson8b_param},
 	 { .compatible = "amlogic,meson-gxbb-reset", .data = &meson8b_param},
 	 { .compatible = "amlogic,meson-axg-reset",  .data = &meson8b_param},
 	 { .compatible = "amlogic,meson-a1-reset",   .data = &meson_a1_param},
+	 { .compatible = "amlogic,meson-s4-reset",   .data = &meson_s4_param},
 	 { /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, meson_reset_dt_ids);
-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan  6 18:40:35 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 7 Jan 2022 10:40:35 +0800
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <20220106090832.42225c49@xps13>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
 <20220106090832.42225c49@xps13>
Message-ID: <9c7b1d77-cff1-b40c-6d02-f67ca8b9b683@amlogic.com>

Hi Miquel,

Meson NFC clock depends on the implementation of sd_emmc_c_clkc, but i 
don't find the commit in
linux mainline. then the information i got from 
[jianxin.pan at amlogic.com] is the rejection of
serial patches. I just look into the corresponding emails in link:
 
https://lore.kernel.org/all/86789d73-5a6c-7729-ecd1-dcd342b2fcde at amlogic.com/
it seems the patch never go on since V6, so [jianxin.pan at amlogic.com], 
could you help to clear it?
let us address the discussion in another email from [jbrunet at baylibre.com].

On 2022/1/6 16:08, Miquel Raynal wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi Liang,
> 
> liang.yang at amlogic.com wrote on Thu, 6 Jan 2022 11:25:04 +0800:
> 
>> Because EMMC and NAND have the same control clock register, so we
>> implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:
>>
>> 	sd_emmc_c_clkc: mmc at 7000 {
>> 		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
>> 		reg = <0x0 0x7000 0x0 0x800>;
>> 	};
>>
>> 	nand-controller at 7800 {
>> 		......
>>
>> 		clocks = <&clkc CLKID_SD_EMMC_C>,
>> 			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
>> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
>> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
>> 		clock-names = "core", "device", "rx", "tx";
>> 		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>>
>> 		......
>> 	}
>>
>> but in fact, above implementation is rejected. so now registering
>> a nand_divider.
> 
> What is rejected?
> Why is it rejected?
> What is nand_divider?
i simplify our clock framework below, so nand divider is 
SD_EMMC_CLOCK[5:0] here.
			   -----          -----		    -----
	   the other------|	\        |     |	   |	 |
          		  | mux	| -----  |  N  | ----------| NFC/|
	   FCLK_DIV2------|     |        |     |	   | EMMC|
			   -----/         ----- 	    -----
		    SD_EMMC_CLOCK[7:6] SD_EMMC_CLOCK[5:0]
> 
> 
>>
>> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
> 
> Change Ids are not expected in the upstream kernel.
> 
> But if you fix something you should have a Fixes:.
> 
>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>> ---
>>   drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
>>   1 file changed, 49 insertions(+), 39 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>> index ac3be92872d0..4472363059c2 100644
>> --- a/drivers/mtd/nand/raw/meson_nand.c
>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>> @@ -2,7 +2,7 @@
>>   /*
>>    * Amlogic Meson Nand Flash Controller Driver
>>    *
>> - * Copyright (c) 2018 Amlogic, inc.
>> + * Copyright (c) 2018-2021 Amlogic, inc.
>>    * Author: Liang Yang <liang.yang at amlogic.com>
>>    */
>>   
>> @@ -10,6 +10,7 @@
>>   #include <linux/dma-mapping.h>
>>   #include <linux/interrupt.h>
>>   #include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>>   #include <linux/mtd/rawnand.h>
>>   #include <linux/mtd/mtd.h>
>>   #include <linux/mfd/syscon.h>
>> @@ -55,6 +56,7 @@
>>   #define NFC_REG_VER		0x38
>>   
>>   #define NFC_RB_IRQ_EN		BIT(21)
>> +#define NFC_CMD_FIFO_RESET	BIT(31)
>>   
>>   #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)	\
>>   	(								\
>> @@ -104,6 +106,9 @@
>>   
>>   #define PER_INFO_BYTE		8
>>   
>> +#define CLK_DIV_SHIFT		0
>> +#define CLK_DIV_WIDTH		6
>> +
>>   struct meson_nfc_nand_chip {
>>   	struct list_head node;
>>   	struct nand_chip nand;
>> @@ -151,15 +156,15 @@ struct meson_nfc {
>>   	struct nand_controller controller;
>>   	struct clk *core_clk;
>>   	struct clk *device_clk;
>> -	struct clk *phase_tx;
>> -	struct clk *phase_rx;
>> +	struct clk *nand_clk;
>> +	struct clk_divider nand_divider;
>>   
>>   	unsigned long clk_rate;
>>   	u32 bus_timing;
>>   
>>   	struct device *dev;
>>   	void __iomem *reg_base;
>> -	struct regmap *reg_clk;
>> +	void __iomem *reg_clk;
>>   	struct completion completion;
>>   	struct list_head chips;
>>   	const struct meson_nfc_data *data;
>> @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
>>   	cmd = NFC_CMD_RB | NFC_CMD_RB_INT
>>   		| nfc->param.chip_select | nfc->timing.tbers_max;
>>   	writel(cmd, nfc->reg_base + NFC_REG_CMD);
>> -
>> +	meson_nfc_drain_cmd(nfc);
>>   	ret = wait_for_completion_timeout(&nfc->completion,
>>   					  msecs_to_jiffies(timeout_ms));
>>   	if (ret == 0)
>>   		ret = -1;
>>   
>> +	/* reset command fifo to avoid lock */
>> +	writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);
>>   	return ret;
>>   }
>>   
>> @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
>>   static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>   {
>>   	int ret;
>> +	struct clk_init_data init = {0};
>> +	const char *fix_div2_pll_name[1];
>>   
>> -	/* request core clock */
>>   	nfc->core_clk = devm_clk_get(nfc->dev, "core");
>>   	if (IS_ERR(nfc->core_clk)) {
>>   		dev_err(nfc->dev, "failed to get core clock\n");
>> @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>   		return PTR_ERR(nfc->device_clk);
>>   	}
>>   
>> -	nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
>> -	if (IS_ERR(nfc->phase_tx)) {
>> -		dev_err(nfc->dev, "failed to get TX clk\n");
>> -		return PTR_ERR(nfc->phase_tx);
>> -	}
>> -
>> -	nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
>> -	if (IS_ERR(nfc->phase_rx)) {
>> -		dev_err(nfc->dev, "failed to get RX clk\n");
>> -		return PTR_ERR(nfc->phase_rx);
>> -	}
>> +	init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
>> +	init.ops = &clk_divider_ops;
>> +	fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);
>> +	init.parent_names = fix_div2_pll_name;
>> +	init.num_parents = 1;
>> +	nfc->nand_divider.reg = nfc->reg_clk;
>> +	nfc->nand_divider.shift = CLK_DIV_SHIFT;
>> +	nfc->nand_divider.width = CLK_DIV_WIDTH;
>> +	nfc->nand_divider.hw.init = &init;
>> +	nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
>> +				  CLK_DIVIDER_ROUND_CLOSEST |
>> +          			  CLK_DIVIDER_ALLOW_ZERO;
>> +
>> +	nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
>> +	if (IS_ERR(nfc->nand_clk))
>> +		return PTR_ERR(nfc->nand_clk);
>>   
>>   	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
>> -	regmap_update_bits(nfc->reg_clk,
>> -			   0, CLK_SELECT_NAND, CLK_SELECT_NAND);
>> +	writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
>>   
>>   	ret = clk_prepare_enable(nfc->core_clk);
>>   	if (ret) {
>> @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>   		goto err_device_clk;
>>   	}
>>   
>> -	ret = clk_prepare_enable(nfc->phase_tx);
>> +	ret = clk_prepare_enable(nfc->nand_clk);
>>   	if (ret) {
>> -		dev_err(nfc->dev, "failed to enable TX clock\n");
>> -		goto err_phase_tx;
>> -	}
>> -
>> -	ret = clk_prepare_enable(nfc->phase_rx);
>> -	if (ret) {
>> -		dev_err(nfc->dev, "failed to enable RX clock\n");
>> -		goto err_phase_rx;
>> +		dev_err(nfc->dev, "pre enable NFC divider fail\n");
>> +		goto err_nand_clk;
>>   	}
>>   
>>   	ret = clk_set_rate(nfc->device_clk, 24000000);
>>   	if (ret)
>> -		goto err_disable_rx;
>> +		goto err_disable_clk;
>>   
>>   	return 0;
>>   
>> -err_disable_rx:
>> -	clk_disable_unprepare(nfc->phase_rx);
>> -err_phase_rx:
>> -	clk_disable_unprepare(nfc->phase_tx);
>> -err_phase_tx:
>> +err_disable_clk:
>> +	clk_disable_unprepare(nfc->nand_clk);
>> +err_nand_clk:
>>   	clk_disable_unprepare(nfc->device_clk);
>>   err_device_clk:
>>   	clk_disable_unprepare(nfc->core_clk);
>> @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>   
>>   static void meson_nfc_disable_clk(struct meson_nfc *nfc)
>>   {
>> -	clk_disable_unprepare(nfc->phase_rx);
>> -	clk_disable_unprepare(nfc->phase_tx);
>> +	clk_disable_unprepare(nfc->nand_clk);
>>   	clk_disable_unprepare(nfc->device_clk);
>>   	clk_disable_unprepare(nfc->core_clk);
>>   }
>> @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>   	struct device *dev = &pdev->dev;
>>   	struct meson_nfc *nfc;
>>   	struct resource *res;
>> +	u32 ext_clk_reg;
>>   	int ret, irq;
>>   
>>   	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
>> @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>   	if (IS_ERR(nfc->reg_base))
>>   		return PTR_ERR(nfc->reg_base);
>>   
>> -	nfc->reg_clk =
>> -		syscon_regmap_lookup_by_phandle(dev->of_node,
>> -						"amlogic,mmc-syscon");
>> +	ret = of_property_read_u32(pdev->dev.of_node,
>> +				   "sd_emmc_c_clkc",
>> +				   &ext_clk_reg);
>> +	if (ret) {
>> +		dev_err(dev, "failed to get NAND external clock register\n");
>> +		return ret;
>> +	}
>> +
>> +	nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));
>>   	if (IS_ERR(nfc->reg_clk)) {
>>   		dev_err(dev, "Failed to lookup clock base\n");
>>   		return PTR_ERR(nfc->reg_clk);
> 
> 
> Thanks,
> Miqu?l
> 
> .


From liang.yang at amlogic.com  Thu Jan  6 18:48:08 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 7 Jan 2022 10:48:08 +0800
Subject: [PATCH] dt-bindings: nand: meson: fix controller clock
In-Reply-To: <20220106091209.6b97cf3c@xps13>
References: <20220106033130.37623-1-liang.yang@amlogic.com>
 <20220106091209.6b97cf3c@xps13>
Message-ID: <e4e1c378-81de-5e45-e5da-68193148e1e1@amlogic.com>

Hi Miquel,

On 2022/1/6 16:12, Miquel Raynal wrote:
> [ EXTERNAL EMAIL ]
> 
> Hello,
> 
> liang.yang at amlogic.com wrote on Thu, 6 Jan 2022 11:31:30 +0800:
> 
> This patch should be in a series with "mtd: rawnand: meson: fix the
> clock after discarding sd_emmc_c_clk" and possibly come first.
> 
> You miss a commit message which is _very_ important given the type of
> change you propose.
>   
>> Change-Id: I1425b491d8b95061e1ce358ef33143433fc94d24
> 
> Change IDs have nothing to do here.
> 
> However a Fixes and a Signed-off-by are welcome.
> 
> You'll also need to Cc: Rob H. in your v2.
> 
ok, i will fix these once we clarify the patch about sd_emmc_c_clk and 
decide to use this patch.
>> ---
>>   .../bindings/mtd/amlogic,meson-nand.txt        | 18 +++---------------
>>   1 file changed, 3 insertions(+), 15 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
>> index 5794ab1147c1..37f16fe4fe66 100644
>> --- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
>> +++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
>> @@ -14,11 +14,6 @@ Required properties:
>>   - clock-names: Should contain the following:
>>   	"core" - NFC module gate clock
>>   	"device" - device clock from eMMC sub clock controller
>> -	"rx" - rx clock phase
>> -	"tx" - tx clock phase
>> -
>> -- amlogic,mmc-syscon	: Required for NAND clocks, it's shared with SD/eMMC
>> -				controller port C
>>   
>>   Optional children nodes:
>>   Children nodes represent the available nand chips.
>> @@ -28,11 +23,6 @@ see Documentation/devicetree/bindings/mtd/nand-controller.yaml for generic bindi
>>   
>>   Example demonstrate on AXG SoC:
>>   
>> -	sd_emmc_c_clkc: mmc at 7000 {
>> -		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
>> -		reg = <0x0 0x7000 0x0 0x800>;
>> -	};
>> -
>>   	nand-controller at 7800 {
>>   		compatible = "amlogic,meson-axg-nfc";
>>   		reg = <0x0 0x7800 0x0 0x100>;
>> @@ -41,11 +31,9 @@ Example demonstrate on AXG SoC:
>>   		interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
>>   
>>   		clocks = <&clkc CLKID_SD_EMMC_C>,
>> -			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
>> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
>> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
>> -		clock-names = "core", "device", "rx", "tx";
>> -		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>> +			<&clkc CLKID_FCLK_DIV2>;
>> +		clock-names = "core", "device";
>> +		sd_emmc_c_clkc = <0xffe07000>;
>>   
>>   		pinctrl-names = "default";
>>   		pinctrl-0 = <&nand_pins>;
> 
> 
> Thanks,
> Miqu?l
> 
> .


From liang.yang at amlogic.com  Thu Jan  6 20:04:46 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 7 Jan 2022 12:04:46 +0800
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <1jfsq1z22l.fsf@starbuckisacylon.baylibre.com>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
 <1jfsq1z22l.fsf@starbuckisacylon.baylibre.com>
Message-ID: <151ded4b-a28b-dac9-31e1-5b817cd9dc44@amlogic.com>

Hi Jerome,

On 2022/1/6 16:16, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> 
> On Thu 06 Jan 2022 at 11:25, Liang Yang <liang.yang at amlogic.com> wrote:
> 
>> Because EMMC and NAND have the same control clock register, so we
>> implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:
>>
>> 	sd_emmc_c_clkc: mmc at 7000 {
>> 		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
>> 		reg = <0x0 0x7000 0x0 0x800>;
>> 	};
>>
>> 	nand-controller at 7800 {
>> 		......
>>
>> 		clocks = <&clkc CLKID_SD_EMMC_C>,
>> 			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
>> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
>> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
>> 		clock-names = "core", "device", "rx", "tx";
>> 		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>>
>> 		......
>> 	}
>>
>> but in fact, above implementation is rejected. so now registering
>> a nand_divider.
> 
> Can you give a bit of context ? a link to the discussion rejecting this
> 
Maybe I mistake the meaning of [jianxin.pan at amlogic.com], so i need him 
to clarify it.
> As far as remember, things were getting done for A1 and stopped before
> clock part was finished. I'm saying the change is wrong, just that a
> discussion is needed before a decision is made.
>
ok.
previous discussion in this link:
https://lore.kernel.org/all/86789d73-5a6c-7729-ecd1-dcd342b2fcde at amlogic.com/
it never go on since v6.

>>
>> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>> ---
>>   drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
>>   1 file changed, 49 insertions(+), 39 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>> index ac3be92872d0..4472363059c2 100644
>> --- a/drivers/mtd/nand/raw/meson_nand.c
>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>> @@ -2,7 +2,7 @@
>>   /*
>>    * Amlogic Meson Nand Flash Controller Driver
>>    *
>> - * Copyright (c) 2018 Amlogic, inc.
>> + * Copyright (c) 2018-2021 Amlogic, inc.
>>    * Author: Liang Yang <liang.yang at amlogic.com>
>>    */
>>   
>> @@ -10,6 +10,7 @@
>>   #include <linux/dma-mapping.h>
>>   #include <linux/interrupt.h>
>>   #include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>>   #include <linux/mtd/rawnand.h>
>>   #include <linux/mtd/mtd.h>
>>   #include <linux/mfd/syscon.h>
>> @@ -55,6 +56,7 @@
>>   #define NFC_REG_VER		0x38
>>   
>>   #define NFC_RB_IRQ_EN		BIT(21)
>> +#define NFC_CMD_FIFO_RESET	BIT(31)
>>   
>>   #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)	\
>>   	(								\
>> @@ -104,6 +106,9 @@
>>   
>>   #define PER_INFO_BYTE		8
>>   
>> +#define CLK_DIV_SHIFT		0
>> +#define CLK_DIV_WIDTH		6
>> +
>>   struct meson_nfc_nand_chip {
>>   	struct list_head node;
>>   	struct nand_chip nand;
>> @@ -151,15 +156,15 @@ struct meson_nfc {
>>   	struct nand_controller controller;
>>   	struct clk *core_clk;
>>   	struct clk *device_clk;
>> -	struct clk *phase_tx;
>> -	struct clk *phase_rx;
> 
> I would have been nice to explain why these clock are no longer
> required, in the change description maybe ?

i got the reply from our vlsi members that rx and tx doesn't make sense 
to meson NFC timing. so previous commit about this should be wrong.
> 
>> +	struct clk *nand_clk;
>> +	struct clk_divider nand_divider;
>>   
>>   	unsigned long clk_rate;
>>   	u32 bus_timing;
>>   
>>   	struct device *dev;
>>   	void __iomem *reg_base;
>> -	struct regmap *reg_clk;
>> +	void __iomem *reg_clk;
>>   	struct completion completion;
>>   	struct list_head chips;
>>   	const struct meson_nfc_data *data;
>> @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
>>   	cmd = NFC_CMD_RB | NFC_CMD_RB_INT
>>   		| nfc->param.chip_select | nfc->timing.tbers_max;
>>   	writel(cmd, nfc->reg_base + NFC_REG_CMD);
>> -
>> +	meson_nfc_drain_cmd(nfc);
> 
> is this clock related ?
ok, i will split it in another patch.
> 
>>   	ret = wait_for_completion_timeout(&nfc->completion,
>>   					  msecs_to_jiffies(timeout_ms));
>>   	if (ret == 0)
>>   		ret = -1;
>>   
>> +	/* reset command fifo to avoid lock */
>> +	writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);
> 
> Again, not seem to be clock related - does not belong in this patch
ok, i will split it in another patch.
> 
>>   	return ret;
>>   }
>>   
>> @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
>>   static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>   {
>>   	int ret;
>> +	struct clk_init_data init = {0};
>> +	const char *fix_div2_pll_name[1];
>>   
>> -	/* request core clock */
> 
> Why is the comment bothering you ?
> 
>>   	nfc->core_clk = devm_clk_get(nfc->dev, "core");
>>   	if (IS_ERR(nfc->core_clk)) {
>>   		dev_err(nfc->dev, "failed to get core clock\n");
>> @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>   		return PTR_ERR(nfc->device_clk);
>>   	}
>>   
>> -	nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
>> -	if (IS_ERR(nfc->phase_tx)) {
>> -		dev_err(nfc->dev, "failed to get TX clk\n");
>> -		return PTR_ERR(nfc->phase_tx);
>> -	}
>> -
>> -	nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
>> -	if (IS_ERR(nfc->phase_rx)) {
>> -		dev_err(nfc->dev, "failed to get RX clk\n");
>> -		return PTR_ERR(nfc->phase_rx);
>> -	}
>> +	init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
>> +	init.ops = &clk_divider_ops;
>> +	fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);
> 
> You should be using "fw_name" so CCF looks a DT directly, instead of this
ok
> 
>> +	init.parent_names = fix_div2_pll_name;
>> +	init.num_parents = 1;
>> +	nfc->nand_divider.reg = nfc->reg_clk;
>> +	nfc->nand_divider.shift = CLK_DIV_SHIFT;
>> +	nfc->nand_divider.width = CLK_DIV_WIDTH;
>> +	nfc->nand_divider.hw.init = &init;
>> +	nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
>> +				  CLK_DIVIDER_ROUND_CLOSEST |
>> +          			  CLK_DIVIDER_ALLOW_ZERO;
>> +
>> +	nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
>> +	if (IS_ERR(nfc->nand_clk))
>> +		return PTR_ERR(nfc->nand_clk);
>>   
>>   	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
>> -	regmap_update_bits(nfc->reg_clk,
>> -			   0, CLK_SELECT_NAND, CLK_SELECT_NAND);
>> +	writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
>>   
>>   	ret = clk_prepare_enable(nfc->core_clk);
>>   	if (ret) {
>> @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>   		goto err_device_clk;
>>   	}
>>   
>> -	ret = clk_prepare_enable(nfc->phase_tx);
>> +	ret = clk_prepare_enable(nfc->nand_clk);
>>   	if (ret) {
>> -		dev_err(nfc->dev, "failed to enable TX clock\n");
>> -		goto err_phase_tx;
>> -	}
>> -
>> -	ret = clk_prepare_enable(nfc->phase_rx);
>> -	if (ret) {
>> -		dev_err(nfc->dev, "failed to enable RX clock\n");
>> -		goto err_phase_rx;
>> +		dev_err(nfc->dev, "pre enable NFC divider fail\n");
>> +		goto err_nand_clk;
>>   	}
>>   
>>   	ret = clk_set_rate(nfc->device_clk, 24000000);
>>   	if (ret)
>> -		goto err_disable_rx;
>> +		goto err_disable_clk;
>>   
>>   	return 0;
>>   
>> -err_disable_rx:
>> -	clk_disable_unprepare(nfc->phase_rx);
>> -err_phase_rx:
>> -	clk_disable_unprepare(nfc->phase_tx);
>> -err_phase_tx:
>> +err_disable_clk:
>> +	clk_disable_unprepare(nfc->nand_clk);
>> +err_nand_clk:
>>   	clk_disable_unprepare(nfc->device_clk);
>>   err_device_clk:
>>   	clk_disable_unprepare(nfc->core_clk);
>> @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>   
>>   static void meson_nfc_disable_clk(struct meson_nfc *nfc)
>>   {
>> -	clk_disable_unprepare(nfc->phase_rx);
>> -	clk_disable_unprepare(nfc->phase_tx);
>> +	clk_disable_unprepare(nfc->nand_clk);
>>   	clk_disable_unprepare(nfc->device_clk);
>>   	clk_disable_unprepare(nfc->core_clk);
>>   }
>> @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>   	struct device *dev = &pdev->dev;
>>   	struct meson_nfc *nfc;
>>   	struct resource *res;
>> +	u32 ext_clk_reg;
>>   	int ret, irq;
>>   
>>   	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
>> @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>   	if (IS_ERR(nfc->reg_base))
>>   		return PTR_ERR(nfc->reg_base);
>>   
>> -	nfc->reg_clk =
>> -		syscon_regmap_lookup_by_phandle(dev->of_node,
>> -						"amlogic,mmc-syscon");
>> +	ret = of_property_read_u32(pdev->dev.of_node,
>> +				   "sd_emmc_c_clkc",
>> +				   &ext_clk_reg);
>> +	if (ret) {
>> +		dev_err(dev, "failed to get NAND external clock register\n");
>> +		return ret;
>> +	}
>> +
>> +	nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));
> 
> That's how you should get a register region.
> If you want an example of a device claiming several region on amlogic,
> have a look at the pinctrl driver.
ok
> 
>>   	if (IS_ERR(nfc->reg_clk)) {
>>   		dev_err(dev, "Failed to lookup clock base\n");
>>   		return PTR_ERR(nfc->reg_clk);
> 
> .


From liang.yang at amlogic.com  Thu Jan  6 20:08:39 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 7 Jan 2022 12:08:39 +0800
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <9c7b1d77-cff1-b40c-6d02-f67ca8b9b683@amlogic.com>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
 <20220106090832.42225c49@xps13>
 <9c7b1d77-cff1-b40c-6d02-f67ca8b9b683@amlogic.com>
Message-ID: <3d4eff52-431d-438d-bbe6-3267d87e2d37@amlogic.com>

Hi Miquel,

refine the clock framework diagram.

On 2022/1/7 10:40, Liang Yang wrote:
>> What is nand_divider?
> i simplify our clock framework below, so nand divider is 
> SD_EMMC_CLOCK[5:0] here.
>  ?????????????? -----????????? -----??????????? -----
>  ?????? the other------|??? \??????? |???? |?????? |???? |
>  ?????????????????? | mux??? | -----? |? N? | ----------| NFC/|
>  ?????? FCLK_DIV2------|???? |??????? |???? |?????? | EMMC|
>  ?????????????? -----/???????? -----???????? -----
>  ??????????? SD_EMMC_CLOCK[7:6] SD_EMMC_CLOCK[5:0]


                          -----           -------         --------
               the other-|      \        |       |       |        |
                         | mux  |--------|  N    |-------|   NFC/ |
                         |      |        |       |       |   EMMC |
               fclk_div2-|      /        |       |       |        |
                          -----           -------         --------
                   SD_EMMC_CLOCK[7:6]   SD_EMMC_CLOCK[5:0]


From linmq006 at gmail.com  Thu Jan  6 23:54:24 2022
From: linmq006 at gmail.com (Miaoqian Lin)
Date: Fri,  7 Jan 2022 07:54:24 +0000
Subject: [PATCH] spi: spi-meson-spifc: Add missing pm_runtime_disable() in
 meson_spifc_probe
Message-ID: <20220107075424.7774-1-linmq006@gmail.com>

If the probe fails, we should use pm_runtime_disable() to balance
pm_runtime_enable().
Add missing pm_runtime_disable() for meson_spifc_probe.

Fixes: c3e4bc5434d2 ("spi: meson: Add support for Amlogic Meson SPIFC")
Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
---
 drivers/spi/spi-meson-spifc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/spi/spi-meson-spifc.c b/drivers/spi/spi-meson-spifc.c
index 8eca6f24cb79..c8ed7815c4ba 100644
--- a/drivers/spi/spi-meson-spifc.c
+++ b/drivers/spi/spi-meson-spifc.c
@@ -349,6 +349,7 @@ static int meson_spifc_probe(struct platform_device *pdev)
 	return 0;
 out_clk:
 	clk_disable_unprepare(spifc->clk);
+	pm_runtime_disable(spifc->dev);
 out_err:
 	spi_master_put(master);
 	return ret;
-- 
2.17.1



From jbrunet at baylibre.com  Thu Jan  6 23:54:45 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Fri, 07 Jan 2022 08:54:45 +0100
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <9c7b1d77-cff1-b40c-6d02-f67ca8b9b683@amlogic.com>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
 <20220106090832.42225c49@xps13>
 <9c7b1d77-cff1-b40c-6d02-f67ca8b9b683@amlogic.com>
Message-ID: <1jh7agou4i.fsf@starbuckisacylon.baylibre.com>


On Fri 07 Jan 2022 at 10:40, Liang Yang <liang.yang at amlogic.com> wrote:

> Hi Miquel,
>
> Meson NFC clock depends on the implementation of sd_emmc_c_clkc, but i
> don't find the commit in
> linux mainline. then the information i got from [jianxin.pan at amlogic.com]
> is the rejection of
> serial patches. I just look into the corresponding emails in link:
>
> https://lore.kernel.org/all/86789d73-5a6c-7729-ecd1-dcd342b2fcde at amlogic.com/
> it seems the patch never go on since V6, so [jianxin.pan at amlogic.com],
> could you help to clear it?
> let us address the discussion in another email from
> [jbrunet at baylibre.com].

That V6 was "rejected" because some comments from thre V5 were still not
addressed. 

>
> On 2022/1/6 16:08, Miquel Raynal wrote:
>> [ EXTERNAL EMAIL ]
>> Hi Liang,
>> liang.yang at amlogic.com wrote on Thu, 6 Jan 2022 11:25:04 +0800:
>> 
>>> Because EMMC and NAND have the same control clock register, so we
>>> implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:
>>>
>>> 	sd_emmc_c_clkc: mmc at 7000 {
>>> 		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
>>> 		reg = <0x0 0x7000 0x0 0x800>;
>>> 	};
>>>
>>> 	nand-controller at 7800 {
>>> 		......
>>>
>>> 		clocks = <&clkc CLKID_SD_EMMC_C>,
>>> 			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
>>> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
>>> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
>>> 		clock-names = "core", "device", "rx", "tx";
>>> 		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>>>
>>> 		......
>>> 	}
>>>
>>> but in fact, above implementation is rejected. so now registering
>>> a nand_divider.
>> What is rejected?
>> Why is it rejected?
>> What is nand_divider?
> i simplify our clock framework below, so nand divider is SD_EMMC_CLOCK[5:0]
> here.
> 			   -----          -----		    -----
> 	   the other------|	\        |     |	   |	 |
>          		  | mux	| -----  |  N  | ----------| NFC/|
> 	   FCLK_DIV2------|     |        |     |	   | EMMC|
> 			   -----/         ----- 	    -----
> 		    SD_EMMC_CLOCK[7:6] SD_EMMC_CLOCK[5:0]
>> 
>>>
>>> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
>> Change Ids are not expected in the upstream kernel.
>> But if you fix something you should have a Fixes:.
>> 
>>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>>> ---
>>>   drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
>>>   1 file changed, 49 insertions(+), 39 deletions(-)
>>>
>>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>>> index ac3be92872d0..4472363059c2 100644
>>> --- a/drivers/mtd/nand/raw/meson_nand.c
>>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>>> @@ -2,7 +2,7 @@
>>>   /*
>>>    * Amlogic Meson Nand Flash Controller Driver
>>>    *
>>> - * Copyright (c) 2018 Amlogic, inc.
>>> + * Copyright (c) 2018-2021 Amlogic, inc.
>>>    * Author: Liang Yang <liang.yang at amlogic.com>
>>>    */
>>>   @@ -10,6 +10,7 @@
>>>   #include <linux/dma-mapping.h>
>>>   #include <linux/interrupt.h>
>>>   #include <linux/clk.h>
>>> +#include <linux/clk-provider.h>
>>>   #include <linux/mtd/rawnand.h>
>>>   #include <linux/mtd/mtd.h>
>>>   #include <linux/mfd/syscon.h>
>>> @@ -55,6 +56,7 @@
>>>   #define NFC_REG_VER		0x38
>>>     #define NFC_RB_IRQ_EN		BIT(21)
>>> +#define NFC_CMD_FIFO_RESET	BIT(31)
>>>     #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)
>>> \
>>>   	(								\
>>> @@ -104,6 +106,9 @@
>>>     #define PER_INFO_BYTE		8
>>>   +#define CLK_DIV_SHIFT		0
>>> +#define CLK_DIV_WIDTH		6
>>> +
>>>   struct meson_nfc_nand_chip {
>>>   	struct list_head node;
>>>   	struct nand_chip nand;
>>> @@ -151,15 +156,15 @@ struct meson_nfc {
>>>   	struct nand_controller controller;
>>>   	struct clk *core_clk;
>>>   	struct clk *device_clk;
>>> -	struct clk *phase_tx;
>>> -	struct clk *phase_rx;
>>> +	struct clk *nand_clk;
>>> +	struct clk_divider nand_divider;
>>>     	unsigned long clk_rate;
>>>   	u32 bus_timing;
>>>     	struct device *dev;
>>>   	void __iomem *reg_base;
>>> -	struct regmap *reg_clk;
>>> +	void __iomem *reg_clk;
>>>   	struct completion completion;
>>>   	struct list_head chips;
>>>   	const struct meson_nfc_data *data;
>>> @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
>>>   	cmd = NFC_CMD_RB | NFC_CMD_RB_INT
>>>   		| nfc->param.chip_select | nfc->timing.tbers_max;
>>>   	writel(cmd, nfc->reg_base + NFC_REG_CMD);
>>> -
>>> +	meson_nfc_drain_cmd(nfc);
>>>   	ret = wait_for_completion_timeout(&nfc->completion,
>>>   					  msecs_to_jiffies(timeout_ms));
>>>   	if (ret == 0)
>>>   		ret = -1;
>>>   +	/* reset command fifo to avoid lock */
>>> +	writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);
>>>   	return ret;
>>>   }
>>>   @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops
>>> meson_ooblayout_ops = {
>>>   static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>   {
>>>   	int ret;
>>> +	struct clk_init_data init = {0};
>>> +	const char *fix_div2_pll_name[1];
>>>   -	/* request core clock */
>>>   	nfc->core_clk = devm_clk_get(nfc->dev, "core");
>>>   	if (IS_ERR(nfc->core_clk)) {
>>>   		dev_err(nfc->dev, "failed to get core clock\n");
>>> @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>   		return PTR_ERR(nfc->device_clk);
>>>   	}
>>>   -	nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
>>> -	if (IS_ERR(nfc->phase_tx)) {
>>> -		dev_err(nfc->dev, "failed to get TX clk\n");
>>> -		return PTR_ERR(nfc->phase_tx);
>>> -	}
>>> -
>>> -	nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
>>> -	if (IS_ERR(nfc->phase_rx)) {
>>> -		dev_err(nfc->dev, "failed to get RX clk\n");
>>> -		return PTR_ERR(nfc->phase_rx);
>>> -	}
>>> +	init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
>>> +	init.ops = &clk_divider_ops;
>>> +	fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);
>>> +	init.parent_names = fix_div2_pll_name;
>>> +	init.num_parents = 1;
>>> +	nfc->nand_divider.reg = nfc->reg_clk;
>>> +	nfc->nand_divider.shift = CLK_DIV_SHIFT;
>>> +	nfc->nand_divider.width = CLK_DIV_WIDTH;
>>> +	nfc->nand_divider.hw.init = &init;
>>> +	nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
>>> +				  CLK_DIVIDER_ROUND_CLOSEST |
>>> +          			  CLK_DIVIDER_ALLOW_ZERO;
>>> +
>>> +	nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
>>> +	if (IS_ERR(nfc->nand_clk))
>>> +		return PTR_ERR(nfc->nand_clk);
>>>     	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
>>> -	regmap_update_bits(nfc->reg_clk,
>>> -			   0, CLK_SELECT_NAND, CLK_SELECT_NAND);
>>> +	writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
>>>     	ret = clk_prepare_enable(nfc->core_clk);
>>>   	if (ret) {
>>> @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>   		goto err_device_clk;
>>>   	}
>>>   -	ret = clk_prepare_enable(nfc->phase_tx);
>>> +	ret = clk_prepare_enable(nfc->nand_clk);
>>>   	if (ret) {
>>> -		dev_err(nfc->dev, "failed to enable TX clock\n");
>>> -		goto err_phase_tx;
>>> -	}
>>> -
>>> -	ret = clk_prepare_enable(nfc->phase_rx);
>>> -	if (ret) {
>>> -		dev_err(nfc->dev, "failed to enable RX clock\n");
>>> -		goto err_phase_rx;
>>> +		dev_err(nfc->dev, "pre enable NFC divider fail\n");
>>> +		goto err_nand_clk;
>>>   	}
>>>     	ret = clk_set_rate(nfc->device_clk, 24000000);
>>>   	if (ret)
>>> -		goto err_disable_rx;
>>> +		goto err_disable_clk;
>>>     	return 0;
>>>   -err_disable_rx:
>>> -	clk_disable_unprepare(nfc->phase_rx);
>>> -err_phase_rx:
>>> -	clk_disable_unprepare(nfc->phase_tx);
>>> -err_phase_tx:
>>> +err_disable_clk:
>>> +	clk_disable_unprepare(nfc->nand_clk);
>>> +err_nand_clk:
>>>   	clk_disable_unprepare(nfc->device_clk);
>>>   err_device_clk:
>>>   	clk_disable_unprepare(nfc->core_clk);
>>> @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>     static void meson_nfc_disable_clk(struct meson_nfc *nfc)
>>>   {
>>> -	clk_disable_unprepare(nfc->phase_rx);
>>> -	clk_disable_unprepare(nfc->phase_tx);
>>> +	clk_disable_unprepare(nfc->nand_clk);
>>>   	clk_disable_unprepare(nfc->device_clk);
>>>   	clk_disable_unprepare(nfc->core_clk);
>>>   }
>>> @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>>   	struct device *dev = &pdev->dev;
>>>   	struct meson_nfc *nfc;
>>>   	struct resource *res;
>>> +	u32 ext_clk_reg;
>>>   	int ret, irq;
>>>     	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
>>> @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>>   	if (IS_ERR(nfc->reg_base))
>>>   		return PTR_ERR(nfc->reg_base);
>>>   -	nfc->reg_clk =
>>> -		syscon_regmap_lookup_by_phandle(dev->of_node,
>>> -						"amlogic,mmc-syscon");
>>> +	ret = of_property_read_u32(pdev->dev.of_node,
>>> +				   "sd_emmc_c_clkc",
>>> +				   &ext_clk_reg);
>>> +	if (ret) {
>>> +		dev_err(dev, "failed to get NAND external clock register\n");
>>> +		return ret;
>>> +	}
>>> +
>>> +	nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));
>>>   	if (IS_ERR(nfc->reg_clk)) {
>>>   		dev_err(dev, "Failed to lookup clock base\n");
>>>   		return PTR_ERR(nfc->reg_clk);
>> 
>> Thanks,
>> Miqu?l
>> .



From narmstrong at baylibre.com  Fri Jan  7 01:57:53 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri, 7 Jan 2022 10:57:53 +0100
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <151ded4b-a28b-dac9-31e1-5b817cd9dc44@amlogic.com>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
 <1jfsq1z22l.fsf@starbuckisacylon.baylibre.com>
 <151ded4b-a28b-dac9-31e1-5b817cd9dc44@amlogic.com>
Message-ID: <e4942f0e-3670-fb52-5cfa-b131a037320a@baylibre.com>

Hi,

On 07/01/2022 05:04, Liang Yang wrote:
> Hi Jerome,
> 
> On 2022/1/6 16:16, Jerome Brunet wrote:
>> [ EXTERNAL EMAIL ]
>>
>>
>> On Thu 06 Jan 2022 at 11:25, Liang Yang <liang.yang at amlogic.com> wrote:
>>
>>> Because EMMC and NAND have the same control clock register, so we
>>> implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:
>>>
>>> ????sd_emmc_c_clkc: mmc at 7000 {
>>> ??????? compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
>>> ??????? reg = <0x0 0x7000 0x0 0x800>;
>>> ????};
>>>
>>> ????nand-controller at 7800 {
>>> ??????? ......
>>>
>>> ??????? clocks = <&clkc CLKID_SD_EMMC_C>,
>>> ??????????? <&sd_emmc_c_clkc CLKID_MMC_DIV>,
>>> ??????????? <&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
>>> ??????????? <&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
>>> ??????? clock-names = "core", "device", "rx", "tx";
>>> ??????? amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>>>
>>> ??????? ......
>>> ????}
>>>
>>> but in fact, above implementation is rejected. so now registering
>>> a nand_divider.
>>
>> Can you give a bit of context ? a link to the discussion rejecting this
>>
> Maybe I mistake the meaning of [jianxin.pan at amlogic.com], so i need him to clarify it.
>> As far as remember, things were getting done for A1 and stopped before
>> clock part was finished. I'm saying the change is wrong, just that a
>> discussion is needed before a decision is made.
>>
> ok.
> previous discussion in this link:
> https://lore.kernel.org/all/86789d73-5a6c-7729-ecd1-dcd342b2fcde at amlogic.com/
> it never go on since v6.

Looking at the serie I don't see any major blockers, if you're willing to take ownership
of this patchset and send a v6 with all issues/comments addressed, it would be easier than
restarting the whole design discussion

Neil

> 
>>>
>>> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
>>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>>> ---
>>> ? drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
>>> ? 1 file changed, 49 insertions(+), 39 deletions(-)
>>>
>>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>>> index ac3be92872d0..4472363059c2 100644
>>> --- a/drivers/mtd/nand/raw/meson_nand.c
>>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>>> @@ -2,7 +2,7 @@
>>> ? /*
>>> ?? * Amlogic Meson Nand Flash Controller Driver
>>> ?? *
>>> - * Copyright (c) 2018 Amlogic, inc.
>>> + * Copyright (c) 2018-2021 Amlogic, inc.
>>> ?? * Author: Liang Yang <liang.yang at amlogic.com>
>>> ?? */
>>> ? @@ -10,6 +10,7 @@
>>> ? #include <linux/dma-mapping.h>
>>> ? #include <linux/interrupt.h>
>>> ? #include <linux/clk.h>
>>> +#include <linux/clk-provider.h>
>>> ? #include <linux/mtd/rawnand.h>
>>> ? #include <linux/mtd/mtd.h>
>>> ? #include <linux/mfd/syscon.h>
>>> @@ -55,6 +56,7 @@
>>> ? #define NFC_REG_VER??????? 0x38
>>> ? ? #define NFC_RB_IRQ_EN??????? BIT(21)
>>> +#define NFC_CMD_FIFO_RESET??? BIT(31)
>>> ? ? #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)??? \
>>> ????? (??????????????????????????????? \
>>> @@ -104,6 +106,9 @@
>>> ? ? #define PER_INFO_BYTE??????? 8
>>> ? +#define CLK_DIV_SHIFT??????? 0
>>> +#define CLK_DIV_WIDTH??????? 6
>>> +
>>> ? struct meson_nfc_nand_chip {
>>> ????? struct list_head node;
>>> ????? struct nand_chip nand;
>>> @@ -151,15 +156,15 @@ struct meson_nfc {
>>> ????? struct nand_controller controller;
>>> ????? struct clk *core_clk;
>>> ????? struct clk *device_clk;
>>> -??? struct clk *phase_tx;
>>> -??? struct clk *phase_rx;
>>
>> I would have been nice to explain why these clock are no longer
>> required, in the change description maybe ?
> 
> i got the reply from our vlsi members that rx and tx doesn't make sense to meson NFC timing. so previous commit about this should be wrong.
>>
>>> +??? struct clk *nand_clk;
>>> +??? struct clk_divider nand_divider;
>>> ? ????? unsigned long clk_rate;
>>> ????? u32 bus_timing;
>>> ? ????? struct device *dev;
>>> ????? void __iomem *reg_base;
>>> -??? struct regmap *reg_clk;
>>> +??? void __iomem *reg_clk;
>>> ????? struct completion completion;
>>> ????? struct list_head chips;
>>> ????? const struct meson_nfc_data *data;
>>> @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
>>> ????? cmd = NFC_CMD_RB | NFC_CMD_RB_INT
>>> ????????? | nfc->param.chip_select | nfc->timing.tbers_max;
>>> ????? writel(cmd, nfc->reg_base + NFC_REG_CMD);
>>> -
>>> +??? meson_nfc_drain_cmd(nfc);
>>
>> is this clock related ?
> ok, i will split it in another patch.
>>
>>> ????? ret = wait_for_completion_timeout(&nfc->completion,
>>> ??????????????????????? msecs_to_jiffies(timeout_ms));
>>> ????? if (ret == 0)
>>> ????????? ret = -1;
>>> ? +??? /* reset command fifo to avoid lock */
>>> +??? writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);
>>
>> Again, not seem to be clock related - does not belong in this patch
> ok, i will split it in another patch.
>>
>>> ????? return ret;
>>> ? }
>>> ? @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
>>> ? static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>> ? {
>>> ????? int ret;
>>> +??? struct clk_init_data init = {0};
>>> +??? const char *fix_div2_pll_name[1];
>>> ? -??? /* request core clock */
>>
>> Why is the comment bothering you ?
>>
>>> ????? nfc->core_clk = devm_clk_get(nfc->dev, "core");
>>> ????? if (IS_ERR(nfc->core_clk)) {
>>> ????????? dev_err(nfc->dev, "failed to get core clock\n");
>>> @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>> ????????? return PTR_ERR(nfc->device_clk);
>>> ????? }
>>> ? -??? nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
>>> -??? if (IS_ERR(nfc->phase_tx)) {
>>> -??????? dev_err(nfc->dev, "failed to get TX clk\n");
>>> -??????? return PTR_ERR(nfc->phase_tx);
>>> -??? }
>>> -
>>> -??? nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
>>> -??? if (IS_ERR(nfc->phase_rx)) {
>>> -??????? dev_err(nfc->dev, "failed to get RX clk\n");
>>> -??????? return PTR_ERR(nfc->phase_rx);
>>> -??? }
>>> +??? init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
>>> +??? init.ops = &clk_divider_ops;
>>> +??? fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);
>>
>> You should be using "fw_name" so CCF looks a DT directly, instead of this
> ok
>>
>>> +??? init.parent_names = fix_div2_pll_name;
>>> +??? init.num_parents = 1;
>>> +??? nfc->nand_divider.reg = nfc->reg_clk;
>>> +??? nfc->nand_divider.shift = CLK_DIV_SHIFT;
>>> +??? nfc->nand_divider.width = CLK_DIV_WIDTH;
>>> +??? nfc->nand_divider.hw.init = &init;
>>> +??? nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
>>> +????????????????? CLK_DIVIDER_ROUND_CLOSEST |
>>> +??????????????????????? CLK_DIVIDER_ALLOW_ZERO;
>>> +
>>> +??? nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
>>> +??? if (IS_ERR(nfc->nand_clk))
>>> +??????? return PTR_ERR(nfc->nand_clk);
>>> ? ????? /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
>>> -??? regmap_update_bits(nfc->reg_clk,
>>> -?????????????? 0, CLK_SELECT_NAND, CLK_SELECT_NAND);
>>> +??? writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
>>> ? ????? ret = clk_prepare_enable(nfc->core_clk);
>>> ????? if (ret) {
>>> @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>> ????????? goto err_device_clk;
>>> ????? }
>>> ? -??? ret = clk_prepare_enable(nfc->phase_tx);
>>> +??? ret = clk_prepare_enable(nfc->nand_clk);
>>> ????? if (ret) {
>>> -??????? dev_err(nfc->dev, "failed to enable TX clock\n");
>>> -??????? goto err_phase_tx;
>>> -??? }
>>> -
>>> -??? ret = clk_prepare_enable(nfc->phase_rx);
>>> -??? if (ret) {
>>> -??????? dev_err(nfc->dev, "failed to enable RX clock\n");
>>> -??????? goto err_phase_rx;
>>> +??????? dev_err(nfc->dev, "pre enable NFC divider fail\n");
>>> +??????? goto err_nand_clk;
>>> ????? }
>>> ? ????? ret = clk_set_rate(nfc->device_clk, 24000000);
>>> ????? if (ret)
>>> -??????? goto err_disable_rx;
>>> +??????? goto err_disable_clk;
>>> ? ????? return 0;
>>> ? -err_disable_rx:
>>> -??? clk_disable_unprepare(nfc->phase_rx);
>>> -err_phase_rx:
>>> -??? clk_disable_unprepare(nfc->phase_tx);
>>> -err_phase_tx:
>>> +err_disable_clk:
>>> +??? clk_disable_unprepare(nfc->nand_clk);
>>> +err_nand_clk:
>>> ????? clk_disable_unprepare(nfc->device_clk);
>>> ? err_device_clk:
>>> ????? clk_disable_unprepare(nfc->core_clk);
>>> @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>> ? ? static void meson_nfc_disable_clk(struct meson_nfc *nfc)
>>> ? {
>>> -??? clk_disable_unprepare(nfc->phase_rx);
>>> -??? clk_disable_unprepare(nfc->phase_tx);
>>> +??? clk_disable_unprepare(nfc->nand_clk);
>>> ????? clk_disable_unprepare(nfc->device_clk);
>>> ????? clk_disable_unprepare(nfc->core_clk);
>>> ? }
>>> @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>> ????? struct device *dev = &pdev->dev;
>>> ????? struct meson_nfc *nfc;
>>> ????? struct resource *res;
>>> +??? u32 ext_clk_reg;
>>> ????? int ret, irq;
>>> ? ????? nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
>>> @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>> ????? if (IS_ERR(nfc->reg_base))
>>> ????????? return PTR_ERR(nfc->reg_base);
>>> ? -??? nfc->reg_clk =
>>> -??????? syscon_regmap_lookup_by_phandle(dev->of_node,
>>> -??????????????????????? "amlogic,mmc-syscon");
>>> +??? ret = of_property_read_u32(pdev->dev.of_node,
>>> +?????????????????? "sd_emmc_c_clkc",
>>> +?????????????????? &ext_clk_reg);
>>> +??? if (ret) {
>>> +??????? dev_err(dev, "failed to get NAND external clock register\n");
>>> +??????? return ret;
>>> +??? }
>>> +
>>> +??? nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));
>>
>> That's how you should get a register region.
>> If you want an example of a device claiming several region on amlogic,
>> have a look at the pinctrl driver.
> ok
>>
>>> ????? if (IS_ERR(nfc->reg_clk)) {
>>> ????????? dev_err(dev, "Failed to lookup clock base\n");
>>> ????????? return PTR_ERR(nfc->reg_clk);
>>
>> .



From broonie at kernel.org  Fri Jan  7 06:33:19 2022
From: broonie at kernel.org (Mark Brown)
Date: Fri, 07 Jan 2022 14:33:19 +0000
Subject: [PATCH] spi: spi-meson-spifc: Add missing pm_runtime_disable() in
 meson_spifc_probe
In-Reply-To: <20220107075424.7774-1-linmq006@gmail.com>
References: <20220107075424.7774-1-linmq006@gmail.com>
Message-ID: <164156599935.2077509.18070348001401229585.b4-ty@kernel.org>

On Fri, 7 Jan 2022 07:54:24 +0000, Miaoqian Lin wrote:
> If the probe fails, we should use pm_runtime_disable() to balance
> pm_runtime_enable().
> Add missing pm_runtime_disable() for meson_spifc_probe.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: spi-meson-spifc: Add missing pm_runtime_disable() in meson_spifc_probe
      commit: 69c1b87516e327a60b39f96b778fe683259408bf

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From narmstrong at baylibre.com  Fri Jan  7 06:55:09 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 15:55:09 +0100
Subject: [PATCH 0/6] drm/meson: add support for MIPI DSI Display
Message-ID: <20220107145515.613009-1-narmstrong@baylibre.com>

The Amlogic G12A, G12B & SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
glue on the same Amlogic SoCs.

This adds support for the glue managing the transceiver, mimicing the init flow provided
by Amlogic to setup the ENCL encoder, the glue, the transceiver, the digital D-PHY and the
Analog PHY in the proper way.

The DW-MIPI-DSI transceiver + D-PHY are clocked by the GP0 PLL, and the ENCL encoder + VIU
pixel reader by the VCLK2 clock using the HDMI PLL.

The DW-MIPI-DSI transceiver gets this pixel stream as input clocked with the VCLK2 clock.

An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
DW-MIPI-DSI transceiver.

This patchset is based on an earlier attempt at [1] for the AXG SoCs, but:
- the AXG has a single clock source for both transceiver + pixel, which makes it an
  exception instead of a rule, it's simpler to add support for G12A then add AXG on it
- previous glue code was a single monolitic code mixing encoders & bridges, this version
  is aligned on the previous cleanup done on HDMI & CVBS bridges architecture at [2]
- since the only output of AXG is DSI, AXG VPU support is post-poned until we implement
  single-clock DSI support specific case on top of this.

[1] https://lore.kernel.org/r/20200907081825.1654-1-narmstrong at baylibre.com
[2] https://lore.kernel.org/r/20211020123947.2585572-1-narmstrong at baylibre.com

Neil Armstrong (6):
  dt-bindings: display: add Amlogic MIPI DSI Host Controller bindings
  dt-bindings: display: meson-vpu: add third DPI output port
  drm/meson: venc: add ENCL encoder setup for MIPI-DSI output
  drm/meson: vclk: add DSI clock config
  drm/meson: add DSI encoder
  drm/meson: add support for MIPI-DSI transceiver

 .../display/amlogic,meson-dw-mipi-dsi.yaml    | 118 ++++++
 .../bindings/display/amlogic,meson-vpu.yaml   |   5 +
 drivers/gpu/drm/meson/Kconfig                 |   7 +
 drivers/gpu/drm/meson/Makefile                |   3 +-
 drivers/gpu/drm/meson/meson_drv.c             |   7 +
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c     | 383 ++++++++++++++++++
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h     | 115 ++++++
 drivers/gpu/drm/meson/meson_encoder_dsi.c     | 159 ++++++++
 drivers/gpu/drm/meson/meson_encoder_dsi.h     |  12 +
 drivers/gpu/drm/meson/meson_vclk.c            |  47 +++
 drivers/gpu/drm/meson/meson_vclk.h            |   1 +
 drivers/gpu/drm/meson/meson_venc.c            | 230 ++++++++++-
 drivers/gpu/drm/meson/meson_venc.h            |   6 +
 drivers/gpu/drm/meson/meson_vpp.h             |   2 +
 14 files changed, 1092 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
 create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
 create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
 create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.c
 create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.h

-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 06:55:11 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 15:55:11 +0100
Subject: [PATCH 2/6] dt-bindings: display: meson-vpu: add third DPI output port
In-Reply-To: <20220107145515.613009-1-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
Message-ID: <20220107145515.613009-3-narmstrong@baylibre.com>

Add third port corresponding to the ENCL DPI encoder used to connect
to DSI or LVDS transceivers.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 .../devicetree/bindings/display/amlogic,meson-vpu.yaml       | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
index 851cb0781217..525a01a38568 100644
--- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
+++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
@@ -92,6 +92,11 @@ properties:
     description:
       A port node pointing to the HDMI-TX port node.
 
+  port at 2:
+    $ref: /schemas/graph.yaml#/properties/port
+    description:
+      A port node pointing to the DPI port node (e.g. DSI or LVDS transceiver).
+
   "#address-cells":
     const: 1
 
-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 06:55:10 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 15:55:10 +0100
Subject: [PATCH 1/6] dt-bindings: display: add Amlogic MIPI DSI Host
 Controller bindings
In-Reply-To: <20220107145515.613009-1-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
Message-ID: <20220107145515.613009-2-narmstrong@baylibre.com>

The Amlogic G12A, G12B & SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI Glue
on the same Amlogic SoCs.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 .../display/amlogic,meson-dw-mipi-dsi.yaml    | 118 ++++++++++++++++++
 1 file changed, 118 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml

diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
new file mode 100644
index 000000000000..f3070783d606
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
@@ -0,0 +1,118 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2020 BayLibre, SAS
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/display/amlogic,meson-dw-mipi-dsi.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Amlogic specific extensions to the Synopsys Designware MIPI DSI Host Controller
+
+maintainers:
+  - Neil Armstrong <narmstrong at baylibre.com>
+
+description: |
+  The Amlogic Meson Synopsys Designware Integration is composed of
+  - A Synopsys DesignWare MIPI DSI Host Controller IP
+  - A TOP control block controlling the Clocks & Resets of the IP
+
+allOf:
+  - $ref: dsi-controller.yaml#
+
+properties:
+  compatible:
+    enum:
+      - amlogic,meson-g12a-dw-mipi-dsi
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    minItems: 2
+
+  clock-names:
+    minItems: 2
+    items:
+      - const: pclk
+      - const: px_clk
+      - const: meas_clk
+
+  resets:
+    minItems: 1
+
+  reset-names:
+    items:
+      - const: top
+
+  phys:
+    minItems: 1
+
+  phy-names:
+    items:
+      - const: dphy
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description: Input node to receive pixel data.
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description: DSI output node to panel.
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - phys
+  - phy-names
+  - ports
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    dsi at 7000 {
+          compatible = "amlogic,meson-g12a-dw-mipi-dsi";
+          reg = <0x6000 0x400>;
+          resets = <&reset_top>;
+          reset-names = "top";
+          clocks = <&clk_pclk>, <&clk_px>;
+          clock-names = "pclk", "px_clk";
+          phys = <&mipi_dphy>;
+          phy-names = "dphy";
+
+          ports {
+              #address-cells = <1>;
+              #size-cells = <0>;
+
+              /* VPU VENC Input */
+              mipi_dsi_venc_port: port at 0 {
+                  reg = <0>;
+
+                  mipi_dsi_in: endpoint {
+                       remote-endpoint = <&dpi_out>;
+                  };
+              };
+
+              /* DSI Output */
+              mipi_dsi_panel_port: port at 1 {
+                  reg = <1>;
+
+                  mipi_out_panel: endpoint {
+                      remote-endpoint = <&mipi_in_panel>;
+                  };
+              };
+          };
+    };
-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 06:55:13 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 15:55:13 +0100
Subject: [PATCH 4/6] drm/meson: vclk: add DSI clock config
In-Reply-To: <20220107145515.613009-1-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
Message-ID: <20220107145515.613009-5-narmstrong@baylibre.com>

The DSI path used the ENCL pixel encoder, thus this adds a clock
config using the HDMI PLL in order to feed the ENCL encoder via the
VCLK2 path and the CTS_ENCL clock output.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpu/drm/meson/meson_vclk.c | 47 ++++++++++++++++++++++++++++++
 drivers/gpu/drm/meson/meson_vclk.h |  1 +
 2 files changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
index 2a82119eb58e..5e4d982be1c8 100644
--- a/drivers/gpu/drm/meson/meson_vclk.c
+++ b/drivers/gpu/drm/meson/meson_vclk.c
@@ -55,6 +55,8 @@
 #define VCLK2_DIV_MASK		0xff
 #define VCLK2_DIV_EN		BIT(16)
 #define VCLK2_DIV_RESET		BIT(17)
+#define CTS_ENCL_SEL_MASK	(0xf << 12)
+#define CTS_ENCL_SEL_SHIFT	12
 #define CTS_VDAC_SEL_MASK	(0xf << 28)
 #define CTS_VDAC_SEL_SHIFT	28
 #define HHI_VIID_CLK_CNTL	0x12c /* 0x4b offset in data sheet */
@@ -83,6 +85,7 @@
 #define VCLK_DIV12_EN		BIT(4)
 #define HHI_VID_CLK_CNTL2	0x194 /* 0x65 offset in data sheet */
 #define CTS_ENCI_EN		BIT(0)
+#define CTS_ENCL_EN		BIT(3)
 #define CTS_ENCP_EN		BIT(2)
 #define CTS_VDAC_EN		BIT(4)
 #define HDMI_TX_PIXEL_EN	BIT(5)
@@ -1024,6 +1027,47 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
 	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
 }
 
+static void meson_dsi_clock_config(struct meson_drm *priv, unsigned int freq)
+{
+	meson_hdmi_pll_generic_set(priv, freq * 10);
+
+	/* Setup vid_pll divider value /5 */
+	meson_vid_pll_set(priv, VID_PLL_DIV_5);
+
+	/* Disable VCLK2 */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, 0);
+
+	/* Setup the VCLK2 divider value /2 */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV, VCLK2_DIV_MASK, 2 - 1);
+
+	/* select vid_pll for vclk2 */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
+			   VCLK2_SEL_MASK, (0 << VCLK2_SEL_SHIFT));
+
+	/* enable vclk2 gate */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN);
+
+	/* select vclk2_div1 for encl */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
+			   CTS_ENCL_SEL_MASK, (8 << CTS_ENCL_SEL_SHIFT));
+
+	/* release vclk2_div_reset and enable vclk2_div */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV, VCLK2_DIV_EN | VCLK2_DIV_RESET,
+			   VCLK2_DIV_EN);
+
+	/* enable vclk2_div1 gate */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_DIV1_EN, VCLK2_DIV1_EN);
+
+	/* reset vclk2 */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_SOFT_RESET, VCLK2_SOFT_RESET);
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_SOFT_RESET, 0);
+
+	/* enable encl_clk */
+	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2, CTS_ENCL_EN, CTS_ENCL_EN);
+
+	usleep_range(10000, 11000);
+}
+
 void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
 		      unsigned int phy_freq, unsigned int vclk_freq,
 		      unsigned int venc_freq, unsigned int dac_freq,
@@ -1050,6 +1094,9 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
 		meson_vclk_set(priv, phy_freq, 0, 0, 0,
 			       VID_PLL_DIV_5, 2, 1, 1, false, false);
 		return;
+	} else if (target == MESON_VCLK_TARGET_DSI) {
+		meson_dsi_clock_config(priv, phy_freq);
+		return;
 	}
 
 	hdmi_tx_div = vclk_freq / dac_freq;
diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h
index 60617aaf18dd..1152b3af8d2e 100644
--- a/drivers/gpu/drm/meson/meson_vclk.h
+++ b/drivers/gpu/drm/meson/meson_vclk.h
@@ -17,6 +17,7 @@ enum {
 	MESON_VCLK_TARGET_CVBS = 0,
 	MESON_VCLK_TARGET_HDMI = 1,
 	MESON_VCLK_TARGET_DMT = 2,
+	MESON_VCLK_TARGET_DSI = 3,
 };
 
 /* 27MHz is the CVBS Pixel Clock */
-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 06:55:14 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 15:55:14 +0100
Subject: [PATCH 5/6] drm/meson: add DSI encoder
In-Reply-To: <20220107145515.613009-1-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
Message-ID: <20220107145515.613009-6-narmstrong@baylibre.com>

This adds an encoder bridge designed to drive a MIPI-DSI display
by using the ENCL encoder through the internal MIPI DSI transceiver
connected to the output of the ENCL pixel encoder.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpu/drm/meson/Makefile            |   2 +-
 drivers/gpu/drm/meson/meson_drv.c         |   7 +
 drivers/gpu/drm/meson/meson_encoder_dsi.c | 159 ++++++++++++++++++++++
 drivers/gpu/drm/meson/meson_encoder_dsi.h |  12 ++
 4 files changed, 179 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.c
 create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.h

diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
index 3afa31bdc950..833e18c20603 100644
--- a/drivers/gpu/drm/meson/Makefile
+++ b/drivers/gpu/drm/meson/Makefile
@@ -2,7 +2,7 @@
 meson-drm-y := meson_drv.o meson_plane.o meson_crtc.o meson_encoder_cvbs.o
 meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_overlay.o
 meson-drm-y += meson_rdma.o meson_osd_afbcd.o
-meson-drm-y += meson_encoder_hdmi.o
+meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o
 
 obj-$(CONFIG_DRM_MESON) += meson-drm.o
 obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index 80f1d439841a..ff278a2b9e6e 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -33,6 +33,7 @@
 #include "meson_registers.h"
 #include "meson_encoder_cvbs.h"
 #include "meson_encoder_hdmi.h"
+#include "meson_encoder_dsi.h"
 #include "meson_viu.h"
 #include "meson_vpp.h"
 #include "meson_rdma.h"
@@ -323,6 +324,12 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
 	if (ret)
 		goto free_drm;
 
+	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
+		ret = meson_encoder_dsi_init(priv);
+		if (ret)
+			goto free_drm;
+	}
+
 	ret = meson_plane_create(priv);
 	if (ret)
 		goto free_drm;
diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.c b/drivers/gpu/drm/meson/meson_encoder_dsi.c
new file mode 100644
index 000000000000..90347821cf96
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_encoder_dsi.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
+#include <drm/drm_device.h>
+#include <drm/drm_probe_helper.h>
+
+#include "meson_drv.h"
+#include "meson_encoder_dsi.h"
+#include "meson_registers.h"
+#include "meson_venc.h"
+#include "meson_vclk.h"
+
+struct meson_encoder_dsi {
+	struct drm_encoder encoder;
+	struct drm_bridge bridge;
+	struct drm_bridge *next_bridge;
+	struct meson_drm *priv;
+};
+
+#define bridge_to_meson_encoder_dsi(x) \
+	container_of(x, struct meson_encoder_dsi, bridge)
+
+static int meson_encoder_dsi_attach(struct drm_bridge *bridge,
+				    enum drm_bridge_attach_flags flags)
+{
+	struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
+
+	return drm_bridge_attach(bridge->encoder, encoder_dsi->next_bridge,
+				 &encoder_dsi->bridge, flags);
+}
+
+static void meson_encoder_dsi_mode_set(struct drm_bridge *bridge,
+				       const struct drm_display_mode *mode,
+				       const struct drm_display_mode *adjusted_mode)
+{
+	struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
+	struct meson_drm *priv = encoder_dsi->priv;
+
+	meson_vclk_setup(priv, MESON_VCLK_TARGET_DSI, mode->clock, 0, 0, 0, false);
+
+	meson_venc_mipi_dsi_mode_set(priv, mode);
+	meson_encl_load_gamma(priv);
+
+	writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
+
+	writel_bits_relaxed(BIT(3), BIT(3), priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_EN));
+}
+
+static void meson_encoder_dsi_atomic_enable(struct drm_bridge *bridge,
+					    struct drm_bridge_state *bridge_state)
+{
+	struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
+	struct meson_drm *priv = encoder_dsi->priv;
+
+	writel_bits_relaxed(BIT(0), 0, priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL));
+
+	writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
+}
+
+static void meson_encoder_dsi_atomic_disable(struct drm_bridge *bridge,
+					     struct drm_bridge_state *bridge_state)
+{
+	struct meson_encoder_dsi *meson_encoder_dsi =
+					bridge_to_meson_encoder_dsi(bridge);
+	struct meson_drm *priv = meson_encoder_dsi->priv;
+
+	writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
+
+	writel_bits_relaxed(BIT(0), BIT(0), priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL));
+}
+
+static const struct drm_bridge_funcs meson_encoder_dsi_bridge_funcs = {
+	.attach	= meson_encoder_dsi_attach,
+	/*
+	 * TOFIX: remove when dw-mipi-dsi moves out of mode_set
+	 * We should get rid of mode_set, but until dw-mipi-dsi uses it
+	 * we need to setup the pixel clock before the following
+	 * bridge tries to setup the HW.
+	 */
+	.mode_set = meson_encoder_dsi_mode_set,
+	.atomic_enable = meson_encoder_dsi_atomic_enable,
+	.atomic_disable	= meson_encoder_dsi_atomic_disable,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+};
+
+int meson_encoder_dsi_init(struct meson_drm *priv)
+{
+	struct meson_encoder_dsi *meson_encoder_dsi;
+	struct device_node *remote;
+	int ret;
+
+	meson_encoder_dsi = devm_kzalloc(priv->dev, sizeof(*meson_encoder_dsi), GFP_KERNEL);
+	if (!meson_encoder_dsi)
+		return -ENOMEM;
+
+	/* DSI Transceiver Bridge */
+	remote = of_graph_get_remote_node(priv->dev->of_node, 2, 0);
+	if (!remote) {
+		dev_err(priv->dev, "DSI transceiver device is disabled");
+		return 0;
+	}
+
+	meson_encoder_dsi->next_bridge = of_drm_find_bridge(remote);
+	if (!meson_encoder_dsi->next_bridge) {
+		dev_dbg(priv->dev, "Failed to find DSI transceiver bridge: %d\n", ret);
+		return -EPROBE_DEFER;
+	}
+
+	/* DSI Encoder Bridge */
+	meson_encoder_dsi->bridge.funcs = &meson_encoder_dsi_bridge_funcs;
+	meson_encoder_dsi->bridge.of_node = priv->dev->of_node;
+	meson_encoder_dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
+
+	drm_bridge_add(&meson_encoder_dsi->bridge);
+
+	meson_encoder_dsi->priv = priv;
+
+	/* Encoder */
+	ret = drm_simple_encoder_init(priv->drm, &meson_encoder_dsi->encoder,
+				      DRM_MODE_ENCODER_DSI);
+	if (ret) {
+		dev_err(priv->dev, "Failed to init DSI encoder: %d\n", ret);
+		return ret;
+	}
+
+	meson_encoder_dsi->encoder.possible_crtcs = BIT(0);
+
+	/* Attach DSI Encoder Bridge to Encoder */
+	ret = drm_bridge_attach(&meson_encoder_dsi->encoder, &meson_encoder_dsi->bridge, NULL, 0);
+	if (ret) {
+		dev_err(priv->dev, "Failed to attach bridge: %d\n", ret);
+		return ret;
+	}
+
+	/*
+	 * We should have now in place:
+	 * encoder->[dsi encoder bridge]->[dw-mipi-dsi bridge]->[panel bridge]->[panel]
+	 */
+
+	dev_dbg(priv->dev, "DSI encoder initialized\n");
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.h b/drivers/gpu/drm/meson/meson_encoder_dsi.h
new file mode 100644
index 000000000000..0f4b641eb633
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_encoder_dsi.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2021 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ */
+
+#ifndef __MESON_ENCODER_DSI_H
+#define __MESON_ENCODER_DSI_H
+
+int meson_encoder_dsi_init(struct meson_drm *priv);
+
+#endif /* __MESON_ENCODER_DSI_H */
-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 06:55:12 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 15:55:12 +0100
Subject: [PATCH 3/6] drm/meson: venc: add ENCL encoder setup for MIPI-DSI
 output
In-Reply-To: <20220107145515.613009-1-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
Message-ID: <20220107145515.613009-4-narmstrong@baylibre.com>

This adds supports for the ENCL encoder connected to a MIPI-DSI transceiver on the
Amlogic AXG SoCs.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpu/drm/meson/meson_venc.c | 230 ++++++++++++++++++++++++++++-
 drivers/gpu/drm/meson/meson_venc.h |   6 +
 drivers/gpu/drm/meson/meson_vpp.h  |   2 +
 3 files changed, 236 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
index 3c55ed003359..b430dc06aa34 100644
--- a/drivers/gpu/drm/meson/meson_venc.c
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/export.h>
+#include <linux/iopoll.h>
 
 #include <drm/drm_modes.h>
 
@@ -1557,6 +1558,224 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
 }
 EXPORT_SYMBOL_GPL(meson_venc_hdmi_mode_set);
 
+static unsigned short meson_encl_gamma_table[256] = {
+	0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
+	64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
+	128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188,
+	192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252,
+	256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 304, 308, 312, 316,
+	320, 324, 328, 332, 336, 340, 344, 348, 352, 356, 360, 364, 368, 372, 376, 380,
+	384, 388, 392, 396, 400, 404, 408, 412, 416, 420, 424, 428, 432, 436, 440, 444,
+	448, 452, 456, 460, 464, 468, 472, 476, 480, 484, 488, 492, 496, 500, 504, 508,
+	512, 516, 520, 524, 528, 532, 536, 540, 544, 548, 552, 556, 560, 564, 568, 572,
+	576, 580, 584, 588, 592, 596, 600, 604, 608, 612, 616, 620, 624, 628, 632, 636,
+	640, 644, 648, 652, 656, 660, 664, 668, 672, 676, 680, 684, 688, 692, 696, 700,
+	704, 708, 712, 716, 720, 724, 728, 732, 736, 740, 744, 748, 752, 756, 760, 764,
+	768, 772, 776, 780, 784, 788, 792, 796, 800, 804, 808, 812, 816, 820, 824, 828,
+	832, 836, 840, 844, 848, 852, 856, 860, 864, 868, 872, 876, 880, 884, 888, 892,
+	896, 900, 904, 908, 912, 916, 920, 924, 928, 932, 936, 940, 944, 948, 952, 956,
+	960, 964, 968, 972, 976, 980, 984, 988, 992, 996, 1000, 1004, 1008, 1012, 1016, 1020,
+};
+
+#define GAMMA_VCOM_POL    7     /* RW */
+#define GAMMA_RVS_OUT     6     /* RW */
+#define ADR_RDY           5     /* Read Only */
+#define WR_RDY            4     /* Read Only */
+#define RD_RDY            3     /* Read Only */
+#define GAMMA_TR          2     /* RW */
+#define GAMMA_SET         1     /* RW */
+#define GAMMA_EN          0     /* RW */
+
+#define H_RD              12
+#define H_AUTO_INC        11
+#define H_SEL_R           10
+#define H_SEL_G           9
+#define H_SEL_B           8
+#define HADR_MSB          7            /* 7:0 */
+#define HADR              0            /* 7:0 */
+
+#define GAMMA_RETRY       1000
+
+static void meson_encl_set_gamma_table(struct meson_drm *priv, u16 *data,
+				       u32 rgb_mask)
+{
+	int i, ret;
+	u32 reg;
+
+	writel_bits_relaxed(BIT(GAMMA_EN), 0,
+			    priv->io_base + _REG(L_GAMMA_CNTL_PORT));
+
+	ret = readl_relaxed_poll_timeout(priv->io_base +
+						_REG(L_GAMMA_CNTL_PORT),
+					 reg, reg & BIT(ADR_RDY), 10, 10000);
+	if (ret)
+		pr_warn("%s: GAMMA ADR_RDY timeout\n", __func__);
+
+	writel_relaxed(BIT(H_AUTO_INC) |
+		       BIT(rgb_mask) |
+		       (0 << HADR),
+		       priv->io_base + _REG(L_GAMMA_ADDR_PORT));
+
+	for (i = 0; i < 256; i++) {
+		ret = readl_relaxed_poll_timeout(priv->io_base +
+							_REG(L_GAMMA_CNTL_PORT),
+						 reg, reg & BIT(WR_RDY),
+						 10, 10000);
+		if (ret)
+			pr_warn_once("%s: GAMMA WR_RDY timeout\n", __func__);
+
+		writel_relaxed(data[i],
+			       priv->io_base + _REG(L_GAMMA_DATA_PORT));
+	}
+
+	ret = readl_relaxed_poll_timeout(priv->io_base +
+						_REG(L_GAMMA_CNTL_PORT),
+					 reg, reg & BIT(ADR_RDY), 10, 10000);
+	if (ret)
+		pr_warn("%s: GAMMA ADR_RDY timeout\n", __func__);
+
+	writel_relaxed(BIT(H_AUTO_INC) |
+		       BIT(rgb_mask) |
+		       (0x23 << HADR),
+		       priv->io_base + _REG(L_GAMMA_ADDR_PORT));
+}
+
+void meson_encl_load_gamma(struct meson_drm *priv)
+{
+	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, H_SEL_R);
+	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, H_SEL_G);
+	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, H_SEL_B);
+
+	writel_bits_relaxed(BIT(GAMMA_EN), BIT(GAMMA_EN),
+			    priv->io_base + _REG(L_GAMMA_CNTL_PORT));
+}
+
+void meson_venc_mipi_dsi_mode_set(struct meson_drm *priv,
+				  const struct drm_display_mode *mode)
+{
+	unsigned int max_pxcnt;
+	unsigned int max_lncnt;
+	unsigned int havon_begin;
+	unsigned int havon_end;
+	unsigned int vavon_bline;
+	unsigned int vavon_eline;
+	unsigned int hso_begin;
+	unsigned int hso_end;
+	unsigned int vso_begin;
+	unsigned int vso_end;
+	unsigned int vso_bline;
+	unsigned int vso_eline;
+
+	max_pxcnt = mode->htotal - 1;
+	max_lncnt = mode->vtotal - 1;
+	havon_begin = mode->htotal - mode->hsync_start;
+	havon_end = havon_begin + mode->hdisplay - 1;
+	vavon_bline = mode->vtotal - mode->vsync_start;
+	vavon_eline = vavon_bline + mode->vdisplay - 1;
+	hso_begin = 0;
+	hso_end = mode->hsync_end - mode->hsync_start;
+	vso_begin = 0;
+	vso_end = 0;
+	vso_bline = 0;
+	vso_eline = mode->vsync_end - mode->vsync_start;
+
+	meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCL);
+
+	writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
+
+	writel_relaxed(0x8000, priv->io_base + _REG(ENCL_VIDEO_MODE));
+	writel_relaxed(0x0418, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
+
+	writel_relaxed(0x1000, priv->io_base + _REG(ENCL_VIDEO_FILT_CTRL));
+	writel_relaxed(max_pxcnt, priv->io_base + _REG(ENCL_VIDEO_MAX_PXCNT));
+	writel_relaxed(max_lncnt, priv->io_base + _REG(ENCL_VIDEO_MAX_LNCNT));
+	writel_relaxed(havon_begin, priv->io_base + _REG(ENCL_VIDEO_HAVON_BEGIN));
+	writel_relaxed(havon_end, priv->io_base + _REG(ENCL_VIDEO_HAVON_END));
+	writel_relaxed(vavon_bline, priv->io_base + _REG(ENCL_VIDEO_VAVON_BLINE));
+	writel_relaxed(vavon_eline, priv->io_base + _REG(ENCL_VIDEO_VAVON_ELINE));
+
+	writel_relaxed(hso_begin, priv->io_base + _REG(ENCL_VIDEO_HSO_BEGIN));
+	writel_relaxed(hso_end, priv->io_base + _REG(ENCL_VIDEO_HSO_END));
+	writel_relaxed(vso_begin, priv->io_base + _REG(ENCL_VIDEO_VSO_BEGIN));
+	writel_relaxed(vso_end, priv->io_base + _REG(ENCL_VIDEO_VSO_END));
+	writel_relaxed(vso_bline, priv->io_base + _REG(ENCL_VIDEO_VSO_BLINE));
+	writel_relaxed(vso_eline, priv->io_base + _REG(ENCL_VIDEO_VSO_ELINE));
+	writel_relaxed(3, priv->io_base + _REG(ENCL_VIDEO_RGBIN_CTRL));
+
+	/* default black pattern */
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_MDSEL));
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_Y));
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CB));
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CR));
+	writel_relaxed(1, priv->io_base + _REG(ENCL_TST_EN));
+	writel_bits_relaxed(BIT(3), 0, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
+
+	writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
+
+	writel_relaxed(0, priv->io_base + _REG(L_RGB_BASE_ADDR));
+	writel_relaxed(0x400, priv->io_base + _REG(L_RGB_COEFF_ADDR));
+	writel_relaxed(0x400, priv->io_base + _REG(L_DITH_CNTL_ADDR));
+
+	/* DE signal for TTL */
+	writel_relaxed(havon_begin, priv->io_base + _REG(L_OEH_HS_ADDR));
+	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_OEH_HE_ADDR));
+	writel_relaxed(vavon_bline, priv->io_base + _REG(L_OEH_VS_ADDR));
+	writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEH_VE_ADDR));
+
+	/* DE signal for TTL */
+	writel_relaxed(havon_begin, priv->io_base + _REG(L_OEV1_HS_ADDR));
+	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_OEV1_HE_ADDR));
+	writel_relaxed(vavon_bline, priv->io_base + _REG(L_OEV1_VS_ADDR));
+	writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEV1_VE_ADDR));
+
+	/* Hsync signal for TTL */
+	if (mode->flags & DRM_MODE_FLAG_PHSYNC) {
+		writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HS_ADDR));
+		writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HE_ADDR));
+	} else {
+		writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HS_ADDR));
+		writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HE_ADDR));
+	}
+	writel_relaxed(0, priv->io_base + _REG(L_STH1_VS_ADDR));
+	writel_relaxed(max_lncnt, priv->io_base + _REG(L_STH1_VE_ADDR));
+
+	/* Vsync signal for TTL */
+	writel_relaxed(vso_begin, priv->io_base + _REG(L_STV1_HS_ADDR));
+	writel_relaxed(vso_end, priv->io_base + _REG(L_STV1_HE_ADDR));
+	if (mode->flags & DRM_MODE_FLAG_PVSYNC) {
+		writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VS_ADDR));
+		writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VE_ADDR));
+	} else {
+		writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VS_ADDR));
+		writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VE_ADDR));
+	}
+
+	/* DE signal */
+	writel_relaxed(havon_begin, priv->io_base + _REG(L_DE_HS_ADDR));
+	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_DE_HE_ADDR));
+	writel_relaxed(vavon_bline, priv->io_base + _REG(L_DE_VS_ADDR));
+	writel_relaxed(vavon_eline, priv->io_base + _REG(L_DE_VE_ADDR));
+
+	/* Hsync signal */
+	writel_relaxed(hso_begin, priv->io_base + _REG(L_HSYNC_HS_ADDR));
+	writel_relaxed(hso_end, priv->io_base + _REG(L_HSYNC_HE_ADDR));
+	writel_relaxed(0, priv->io_base + _REG(L_HSYNC_VS_ADDR));
+	writel_relaxed(max_lncnt, priv->io_base + _REG(L_HSYNC_VE_ADDR));
+
+	/* Vsync signal */
+	writel_relaxed(vso_begin, priv->io_base + _REG(L_VSYNC_HS_ADDR));
+	writel_relaxed(vso_end, priv->io_base + _REG(L_VSYNC_HE_ADDR));
+	writel_relaxed(vso_bline, priv->io_base + _REG(L_VSYNC_VS_ADDR));
+	writel_relaxed(vso_eline, priv->io_base + _REG(L_VSYNC_VE_ADDR));
+
+	writel_relaxed(0, priv->io_base + _REG(L_INV_CNT_ADDR));
+	writel_relaxed(BIT(4) | BIT(5),
+		       priv->io_base + _REG(L_TCON_MISC_SEL_ADDR));
+
+	priv->venc.current_mode = MESON_VENC_MODE_MIPI_DSI;
+}
+EXPORT_SYMBOL_GPL(meson_venc_mipi_dsi_mode_set);
+
 void meson_venci_cvbs_mode_set(struct meson_drm *priv,
 			       struct meson_cvbs_enci_mode *mode)
 {
@@ -1747,8 +1966,15 @@ unsigned int meson_venci_get_field(struct meson_drm *priv)
 
 void meson_venc_enable_vsync(struct meson_drm *priv)
 {
-	writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
-		       priv->io_base + _REG(VENC_INTCTRL));
+	switch (priv->venc.current_mode) {
+	case MESON_VENC_MODE_MIPI_DSI:
+		writel_relaxed(0x200,
+			       priv->io_base + _REG(VENC_INTCTRL));
+		break;
+	default:
+		writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
+			       priv->io_base + _REG(VENC_INTCTRL));
+	}
 	regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25));
 }
 
diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h
index 9138255ffc9e..0f59adb1c6db 100644
--- a/drivers/gpu/drm/meson/meson_venc.h
+++ b/drivers/gpu/drm/meson/meson_venc.h
@@ -21,6 +21,7 @@ enum {
 	MESON_VENC_MODE_CVBS_PAL,
 	MESON_VENC_MODE_CVBS_NTSC,
 	MESON_VENC_MODE_HDMI,
+	MESON_VENC_MODE_MIPI_DSI,
 };
 
 struct meson_cvbs_enci_mode {
@@ -47,6 +48,9 @@ struct meson_cvbs_enci_mode {
 	unsigned int analog_sync_adj;
 };
 
+/* LCD Encoder gamma setup */
+void meson_encl_load_gamma(struct meson_drm *priv);
+
 /* HDMI Clock parameters */
 enum drm_mode_status
 meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode);
@@ -63,6 +67,8 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
 			      unsigned int ycrcb_map,
 			      bool yuv420_mode,
 			      const struct drm_display_mode *mode);
+void meson_venc_mipi_dsi_mode_set(struct meson_drm *priv,
+				  const struct drm_display_mode *mode);
 unsigned int meson_venci_get_field(struct meson_drm *priv);
 
 void meson_venc_enable_vsync(struct meson_drm *priv);
diff --git a/drivers/gpu/drm/meson/meson_vpp.h b/drivers/gpu/drm/meson/meson_vpp.h
index afc9553ed8d3..b790042a1650 100644
--- a/drivers/gpu/drm/meson/meson_vpp.h
+++ b/drivers/gpu/drm/meson/meson_vpp.h
@@ -12,6 +12,8 @@
 struct drm_rect;
 struct meson_drm;
 
+/* Mux VIU/VPP to ENCL */
+#define MESON_VIU_VPP_MUX_ENCL	0x0
 /* Mux VIU/VPP to ENCI */
 #define MESON_VIU_VPP_MUX_ENCI	0x5
 /* Mux VIU/VPP to ENCP */
-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 06:55:15 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 15:55:15 +0100
Subject: [PATCH 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <20220107145515.613009-1-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
Message-ID: <20220107145515.613009-7-narmstrong@baylibre.com>

The Amlogic G12A/G12B/SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
Glue on other Amlogic SoCs.

This adds support for the Glue managing the transceiver, mimicing the init flow provided
by Amlogic to setup the ENCL encoder, the glue, the transceiver, the digital D-PHY and the
Analog PHY in the proper way.

An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
DW-MIPI-DSI transceiver.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpu/drm/meson/Kconfig             |   7 +
 drivers/gpu/drm/meson/Makefile            |   1 +
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 383 ++++++++++++++++++++++
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h | 115 +++++++
 4 files changed, 506 insertions(+)
 create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
 create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h

diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
index 6c70fc3214af..71a1364b51e1 100644
--- a/drivers/gpu/drm/meson/Kconfig
+++ b/drivers/gpu/drm/meson/Kconfig
@@ -17,3 +17,10 @@ config DRM_MESON_DW_HDMI
 	default y if DRM_MESON
 	select DRM_DW_HDMI
 	imply DRM_DW_HDMI_I2S_AUDIO
+
+config DRM_MESON_DW_MIPI_DSI
+	tristate "MIPI DSI Synopsys Controller support for Amlogic Meson Display"
+	depends on DRM_MESON
+	default y if DRM_MESON
+	select DRM_DW_MIPI_DSI
+	select GENERIC_PHY_MIPI_DPHY
diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
index 833e18c20603..43071bdbd4b9 100644
--- a/drivers/gpu/drm/meson/Makefile
+++ b/drivers/gpu/drm/meson/Makefile
@@ -6,3 +6,4 @@ meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o
 
 obj-$(CONFIG_DRM_MESON) += meson-drm.o
 obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
+obj-$(CONFIG_DRM_MESON_DW_MIPI_DSI) += meson_dw_mipi_dsi.o
diff --git a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
new file mode 100644
index 000000000000..75af3eec1b74
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
@@ -0,0 +1,383 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2021 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/reset.h>
+#include <linux/phy/phy.h>
+
+#include <video/mipi_display.h>
+
+#include <drm/bridge/dw_mipi_dsi.h>
+#include <drm/drm_mipi_dsi.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_device.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_print.h>
+
+#include "meson_drv.h"
+#include "meson_dw_mipi_dsi.h"
+#include "meson_registers.h"
+#include "meson_venc.h"
+
+#define DRIVER_NAME "meson-dw-mipi-dsi"
+#define DRIVER_DESC "Amlogic Meson MIPI-DSI DRM driver"
+
+/*  MIPI DSI/VENC Color Format Definitions */
+#define MIPI_DSI_VENC_COLOR_30B   0x0
+#define MIPI_DSI_VENC_COLOR_24B   0x1
+#define MIPI_DSI_VENC_COLOR_18B   0x2
+#define MIPI_DSI_VENC_COLOR_16B   0x3
+
+#define COLOR_16BIT_CFG_1         0x0
+#define COLOR_16BIT_CFG_2         0x1
+#define COLOR_16BIT_CFG_3         0x2
+#define COLOR_18BIT_CFG_1         0x3
+#define COLOR_18BIT_CFG_2         0x4
+#define COLOR_24BIT               0x5
+#define COLOR_20BIT_LOOSE         0x6
+#define COLOR_24_BIT_YCBCR        0x7
+#define COLOR_16BIT_YCBCR         0x8
+#define COLOR_30BIT               0x9
+#define COLOR_36BIT               0xa
+#define COLOR_12BIT               0xb
+#define COLOR_RGB_111             0xc
+#define COLOR_RGB_332             0xd
+#define COLOR_RGB_444             0xe
+
+/*  MIPI DSI Relative REGISTERs Definitions */
+/* For MIPI_DSI_TOP_CNTL */
+#define BIT_DPI_COLOR_MODE        20
+#define BIT_IN_COLOR_MODE         16
+#define BIT_CHROMA_SUBSAMPLE      14
+#define BIT_COMP2_SEL             12
+#define BIT_COMP1_SEL             10
+#define BIT_COMP0_SEL              8
+#define BIT_DE_POL                 6
+#define BIT_HSYNC_POL              5
+#define BIT_VSYNC_POL              4
+#define BIT_DPICOLORM              3
+#define BIT_DPISHUTDN              2
+#define BIT_EDPITE_INTR_PULSE      1
+#define BIT_ERR_INTR_PULSE         0
+
+struct meson_dw_mipi_dsi {
+	struct meson_drm *priv;
+	struct device *dev;
+	void __iomem *base;
+	struct phy *phy;
+	union phy_configure_opts phy_opts;
+	struct dw_mipi_dsi *dmd;
+	struct dw_mipi_dsi_plat_data pdata;
+	struct mipi_dsi_device *dsi_device;
+	const struct drm_display_mode *mode;
+	struct clk *px_clk;
+};
+
+#define encoder_to_meson_dw_mipi_dsi(x) \
+	container_of(x, struct meson_dw_mipi_dsi, encoder)
+
+static void meson_dw_mipi_dsi_hw_init(struct meson_dw_mipi_dsi *mipi_dsi)
+{
+	writel_relaxed((1 << 4) | (1 << 5) | (0 << 6),
+		       mipi_dsi->base + MIPI_DSI_TOP_CNTL);
+
+	writel_bits_relaxed(0xf, 0xf, mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);
+	writel_bits_relaxed(0xf, 0, mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);
+
+	writel_bits_relaxed(0x3, 0x3, mipi_dsi->base + MIPI_DSI_TOP_CLK_CNTL);
+
+	writel_relaxed(0, mipi_dsi->base + MIPI_DSI_TOP_MEM_PD);
+}
+
+static int dw_mipi_dsi_phy_init(void *priv_data)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+	unsigned int dpi_data_format, venc_data_width;
+	int ret;
+
+	ret = clk_set_rate(mipi_dsi->px_clk, mipi_dsi->phy_opts.mipi_dphy.hs_clk_rate);
+	if (ret) {
+		pr_err("Failed to set DSI PLL rate %lu\n",
+		       mipi_dsi->phy_opts.mipi_dphy.hs_clk_rate);
+
+		return ret;
+	}
+
+	switch (mipi_dsi->dsi_device->format) {
+	case MIPI_DSI_FMT_RGB888:
+		dpi_data_format = COLOR_24BIT;
+		venc_data_width = MIPI_DSI_VENC_COLOR_24B;
+		break;
+	case MIPI_DSI_FMT_RGB666:
+		dpi_data_format = COLOR_18BIT_CFG_2;
+		venc_data_width = MIPI_DSI_VENC_COLOR_18B;
+		break;
+	case MIPI_DSI_FMT_RGB666_PACKED:
+	case MIPI_DSI_FMT_RGB565:
+		return -EINVAL;
+	};
+
+	/* Configure color format for DPI register */
+	writel_relaxed((dpi_data_format  << BIT_DPI_COLOR_MODE)  |
+		       (venc_data_width  << BIT_IN_COLOR_MODE) |
+			0 << BIT_COMP0_SEL |
+			1 << BIT_COMP1_SEL |
+			2 << BIT_COMP2_SEL |
+			(mipi_dsi->mode->flags & DRM_MODE_FLAG_NHSYNC ? 0 : BIT(BIT_HSYNC_POL)) |
+			(mipi_dsi->mode->flags & DRM_MODE_FLAG_NVSYNC ? 0 : BIT(BIT_VSYNC_POL)),
+			mipi_dsi->base + MIPI_DSI_TOP_CNTL);
+
+	phy_power_on(mipi_dsi->phy);
+
+	return 0;
+}
+
+static void dw_mipi_dsi_phy_power_off(void *priv_data)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+
+	phy_power_off(mipi_dsi->phy);
+}
+
+static int
+dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
+			  unsigned long mode_flags, u32 lanes, u32 format,
+			  unsigned int *lane_mbps)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+	int bpp;
+
+	mipi_dsi->mode = mode;
+
+	bpp = mipi_dsi_pixel_format_to_bpp(mipi_dsi->dsi_device->format);
+
+	phy_mipi_dphy_get_default_config(mode->clock * 1000,
+					 bpp, mipi_dsi->dsi_device->lanes,
+					 &mipi_dsi->phy_opts.mipi_dphy);
+
+	phy_configure(mipi_dsi->phy, &mipi_dsi->phy_opts);
+
+	*lane_mbps = mipi_dsi->phy_opts.mipi_dphy.hs_clk_rate / 1000000;
+
+	return 0;
+}
+
+static int
+dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
+			   struct dw_mipi_dsi_dphy_timing *timing)
+{
+	/* TOFIX handle other cases */
+
+	timing->clk_lp2hs = 37;
+	timing->clk_hs2lp = 135;
+	timing->data_lp2hs = 50;
+	timing->data_hs2lp = 3;
+
+	return 0;
+}
+
+static int
+dw_mipi_dsi_get_esc_clk_rate(void *priv_data, unsigned int *esc_clk_rate)
+{
+	*esc_clk_rate = 4; /* Mhz */
+
+	return 0;
+}
+
+static const struct dw_mipi_dsi_phy_ops meson_dw_mipi_dsi_phy_ops = {
+	.init = dw_mipi_dsi_phy_init,
+	.power_off = dw_mipi_dsi_phy_power_off,
+	.get_lane_mbps = dw_mipi_dsi_get_lane_mbps,
+	.get_timing = dw_mipi_dsi_phy_get_timing,
+	.get_esc_clk_rate = dw_mipi_dsi_get_esc_clk_rate,
+};
+
+static int meson_dw_mipi_dsi_bind(struct device *dev, struct device *master, void *data)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = dev_get_drvdata(dev);
+	struct drm_device *drm = data;
+	struct meson_drm *priv = drm->dev_private;
+
+	/* Check before if we are supposed to have a sub-device... */
+	if (!mipi_dsi->dsi_device) {
+		dw_mipi_dsi_remove(mipi_dsi->dmd);
+		return -EPROBE_DEFER;
+	}
+
+	mipi_dsi->priv = priv;
+
+	meson_dw_mipi_dsi_hw_init(mipi_dsi);
+
+	return 0;
+}
+
+static const struct component_ops meson_dw_mipi_dsi_ops = {
+	.bind	= meson_dw_mipi_dsi_bind,
+};
+
+static int meson_dw_mipi_dsi_host_attach(void *priv_data,
+					 struct mipi_dsi_device *device)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+
+	mipi_dsi->dsi_device = device;
+
+	switch (device->format) {
+	case MIPI_DSI_FMT_RGB888:
+		break;
+	case MIPI_DSI_FMT_RGB666:
+		break;
+	case MIPI_DSI_FMT_RGB666_PACKED:
+	case MIPI_DSI_FMT_RGB565:
+		DRM_DEV_ERROR(mipi_dsi->dev, "invalid pixel format %d\n", device->format);
+		return -EINVAL;
+	};
+
+	phy_init(mipi_dsi->phy);
+
+	return 0;
+}
+
+static int meson_dw_mipi_dsi_host_detach(void *priv_data,
+					 struct mipi_dsi_device *device)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+
+	if (device == mipi_dsi->dsi_device)
+		mipi_dsi->dsi_device = NULL;
+	else
+		return -EINVAL;
+
+	phy_exit(mipi_dsi->phy);
+
+	return 0;
+}
+
+static const struct dw_mipi_dsi_host_ops meson_dw_mipi_dsi_host_ops = {
+	.attach = meson_dw_mipi_dsi_host_attach,
+	.detach = meson_dw_mipi_dsi_host_detach,
+};
+
+static int meson_dw_mipi_dsi_probe(struct platform_device *pdev)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi;
+	struct reset_control *top_rst;
+	struct resource *res;
+	int ret;
+
+	mipi_dsi = devm_kzalloc(&pdev->dev, sizeof(*mipi_dsi), GFP_KERNEL);
+	if (!mipi_dsi)
+		return -ENOMEM;
+
+	mipi_dsi->dev = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mipi_dsi->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mipi_dsi->base))
+		return PTR_ERR(mipi_dsi->base);
+
+	mipi_dsi->phy = devm_phy_get(&pdev->dev, "dphy");
+	if (IS_ERR(mipi_dsi->phy)) {
+		ret = PTR_ERR(mipi_dsi->phy);
+		dev_err(&pdev->dev, "failed to get mipi dphy: %d\n", ret);
+		return ret;
+	}
+
+	mipi_dsi->px_clk = devm_clk_get(&pdev->dev, "px_clk");
+	if (IS_ERR(mipi_dsi->px_clk)) {
+		dev_err(&pdev->dev, "Unable to get PLL clk\n");
+		return PTR_ERR(mipi_dsi->px_clk);
+	}
+
+	/*
+	 * We use a TOP reset signal because the APB reset signal
+	 * is handled by the TOP control registers.
+	 */
+	top_rst = devm_reset_control_get_exclusive(&pdev->dev, "top");
+	if (IS_ERR(top_rst)) {
+		ret = PTR_ERR(top_rst);
+
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Unable to get reset control: %d\n", ret);
+
+		return ret;
+	}
+
+	ret = clk_prepare_enable(mipi_dsi->px_clk);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to prepare/enable PX clock\n");
+		return ret;
+	}
+
+	reset_control_assert(top_rst);
+	usleep_range(10, 20);
+	reset_control_deassert(top_rst);
+
+	/* MIPI DSI Controller */
+
+	mipi_dsi->pdata.base = mipi_dsi->base;
+	mipi_dsi->pdata.max_data_lanes = 4;
+	mipi_dsi->pdata.phy_ops = &meson_dw_mipi_dsi_phy_ops;
+	mipi_dsi->pdata.host_ops = &meson_dw_mipi_dsi_host_ops;
+	mipi_dsi->pdata.priv_data = mipi_dsi;
+	platform_set_drvdata(pdev, mipi_dsi);
+
+	mipi_dsi->dmd = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata);
+	if (IS_ERR(mipi_dsi->dmd)) {
+		ret = PTR_ERR(mipi_dsi->dmd);
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev,
+				"Failed to probe dw_mipi_dsi: %d\n", ret);
+		goto err_clkdisable;
+	}
+
+	return component_add(mipi_dsi->dev, &meson_dw_mipi_dsi_ops);
+
+err_clkdisable:
+	clk_disable_unprepare(mipi_dsi->px_clk);
+
+	return ret;
+}
+
+static int meson_dw_mipi_dsi_remove(struct platform_device *pdev)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = dev_get_drvdata(&pdev->dev);
+
+	dw_mipi_dsi_remove(mipi_dsi->dmd);
+
+	component_del(mipi_dsi->dev, &meson_dw_mipi_dsi_ops);
+
+	clk_disable_unprepare(mipi_dsi->px_clk);
+
+	return 0;
+}
+
+static const struct of_device_id meson_dw_mipi_dsi_of_table[] = {
+	{ .compatible = "amlogic,meson-g12a-dw-mipi-dsi", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, meson_dw_mipi_dsi_of_table);
+
+static struct platform_driver meson_dw_mipi_dsi_platform_driver = {
+	.probe		= meson_dw_mipi_dsi_probe,
+	.remove		= meson_dw_mipi_dsi_remove,
+	.driver		= {
+		.name		= DRIVER_NAME,
+		.of_match_table	= meson_dw_mipi_dsi_of_table,
+	},
+};
+module_platform_driver(meson_dw_mipi_dsi_platform_driver);
+
+MODULE_AUTHOR("Neil Armstrong <narmstrong at baylibre.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.h b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
new file mode 100644
index 000000000000..4075a132e005
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ * Copyright (C) 2018 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __MESON_DW_MIPI_DSI_H
+#define __MESON_DW_MIPI_DSI_H
+
+/* Top-level registers */
+/* [31: 3]    Reserved.     Default 0.
+ *     [2] RW dpi_rst_n: Default 1.
+ *		1=Assert SW reset on mipi_dsi_host_dpi block.   0=Release reset.
+ *     [1] RW intr_rst_n: Default 1.
+ *		1=Assert SW reset on mipi_dsi_host_intr block.  0=Release reset.
+ *     [0] RW dwc_rst_n:  Default 1.
+ *		1=Assert SW reset on IP core.   0=Release reset.
+ */
+#define MIPI_DSI_TOP_SW_RESET                      0x3c0
+/* [31: 5] Reserved.   Default 0.
+ *     [4] RW manual_edpihalt: Default 0.
+ *		1=Manual suspend VencL; 0=do not suspend VencL.
+ *     [3] RW auto_edpihalt_en: Default 0.
+ *		1=Enable IP's edpihalt signal to suspend VencL;
+ *		0=IP's edpihalt signal does not affect VencL.
+ *     [2] RW clock_freerun: Apply to auto-clock gate only. Default 0.
+ *		0=Default, use auto-clock gating to save power;
+ *		1=use free-run clock, disable auto-clock gating, for debug mode.
+ *     [1] RW enable_pixclk: A manual clock gate option, due to DWC IP does not
+ *		have auto-clock gating. 1=Enable pixclk.      Default 0.
+ *     [0] RW enable_sysclk: A manual clock gate option, due to DWC IP does not
+ *		have auto-clock gating. 1=Enable sysclk.      Default 0.
+ */
+#define MIPI_DSI_TOP_CLK_CNTL                      0x3c4
+/* [31:24]    Reserved. Default 0.
+ * [23:20] RW dpi_color_mode: Define DPI pixel format. Default 0.
+ *		0=16-bit RGB565 config 1;
+ *		1=16-bit RGB565 config 2;
+ *		2=16-bit RGB565 config 3;
+ *		3=18-bit RGB666 config 1;
+ *		4=18-bit RGB666 config 2;
+ *		5=24-bit RGB888;
+ *		6=20-bit YCbCr 4:2:2;
+ *		7=24-bit YCbCr 4:2:2;
+ *		8=16-bit YCbCr 4:2:2;
+ *		9=30-bit RGB;
+ *		10=36-bit RGB;
+ *		11=12-bit YCbCr 4:2:0.
+ *    [19] Reserved. Default 0.
+ * [18:16] RW in_color_mode:  Define VENC data width. Default 0.
+ *		0=30-bit pixel;
+ *		1=24-bit pixel;
+ *		2=18-bit pixel, RGB666;
+ *		3=16-bit pixel, RGB565.
+ * [15:14] RW chroma_subsample: Define method of chroma subsampling. Default 0.
+ *		Applicable to YUV422 or YUV420 only.
+ *		0=Use even pixel's chroma;
+ *		1=Use odd pixel's chroma;
+ *		2=Use averaged value between even and odd pair.
+ * [13:12] RW comp2_sel:  Select which component to be Cr or B: Default 2.
+ *		0=comp0; 1=comp1; 2=comp2.
+ * [11:10] RW comp1_sel:  Select which component to be Cb or G: Default 1.
+ *		0=comp0; 1=comp1; 2=comp2.
+ *  [9: 8] RW comp0_sel:  Select which component to be Y  or R: Default 0.
+ *		0=comp0; 1=comp1; 2=comp2.
+ *     [7]    Reserved. Default 0.
+ *     [6] RW de_pol:  Default 0.
+ *		If DE input is active low, set to 1 to invert to active high.
+ *     [5] RW hsync_pol: Default 0.
+ *		If HS input is active low, set to 1 to invert to active high.
+ *     [4] RW vsync_pol: Default 0.
+ *		If VS input is active low, set to 1 to invert to active high.
+ *     [3] RW dpicolorm: Signal to IP.   Default 0.
+ *     [2] RW dpishutdn: Signal to IP.   Default 0.
+ *     [1]    Reserved.  Default 0.
+ *     [0]    Reserved.  Default 0.
+ */
+#define MIPI_DSI_TOP_CNTL                          0x3c8
+#define MIPI_DSI_TOP_SUSPEND_CNTL                  0x3cc
+#define MIPI_DSI_TOP_SUSPEND_LINE                  0x3d0
+#define MIPI_DSI_TOP_SUSPEND_PIX                   0x3d4
+#define MIPI_DSI_TOP_MEAS_CNTL                     0x3d8
+/* [0] R  stat_edpihalt:  edpihalt signal from IP.    Default 0. */
+#define MIPI_DSI_TOP_STAT                          0x3dc
+#define MIPI_DSI_TOP_MEAS_STAT_TE0                 0x3e0
+#define MIPI_DSI_TOP_MEAS_STAT_TE1                 0x3e4
+#define MIPI_DSI_TOP_MEAS_STAT_VS0                 0x3e8
+#define MIPI_DSI_TOP_MEAS_STAT_VS1                 0x3ec
+/* [31:16] RW intr_stat/clr. Default 0.
+ *		For each bit, read as this interrupt level status,
+ *		write 1 to clear.
+ * [31:22] Reserved
+ * [   21] stat/clr of eof interrupt
+ * [   21] vde_fall interrupt
+ * [   19] stat/clr of de_rise interrupt
+ * [   18] stat/clr of vs_fall interrupt
+ * [   17] stat/clr of vs_rise interrupt
+ * [   16] stat/clr of dwc_edpite interrupt
+ * [15: 0] RW intr_enable. Default 0.
+ *		For each bit, 1=enable this interrupt, 0=disable.
+ *	[15: 6] Reserved
+ *	[    5] eof interrupt
+ *	[    4] de_fall interrupt
+ *	[    3] de_rise interrupt
+ *	[    2] vs_fall interrupt
+ *	[    1] vs_rise interrupt
+ *	[    0] dwc_edpite interrupt
+ */
+#define MIPI_DSI_TOP_INTR_CNTL_STAT                0x3f0
+// 31: 2    Reserved.   Default 0.
+//  1: 0 RW mem_pd.     Default 3.
+#define MIPI_DSI_TOP_MEM_PD                        0x3f4
+
+#endif /* __MESON_DW_MIPI_DSI_H */
-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 07:05:11 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 16:05:11 +0100
Subject: [PATCH v3 1/2] dt-bindings: phy: add Amlogic G12A Analog MIPI D-PHY
 bindings
In-Reply-To: <20220107150512.614423-1-narmstrong@baylibre.com>
References: <20220107150512.614423-1-narmstrong@baylibre.com>
Message-ID: <20220107150512.614423-2-narmstrong@baylibre.com>

The Amlogic G12A SoCs embeds an Analog MIPI D-PHY to communicate with DSI
panels, this adds the bindings.

This Analog D-PHY works with a separate Digital MIPI D-PHY.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 .../phy/amlogic,g12a-mipi-dphy-analog.yaml    | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/amlogic,g12a-mipi-dphy-analog.yaml

diff --git a/Documentation/devicetree/bindings/phy/amlogic,g12a-mipi-dphy-analog.yaml b/Documentation/devicetree/bindings/phy/amlogic,g12a-mipi-dphy-analog.yaml
new file mode 100644
index 000000000000..7aa0c05d6ce4
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/amlogic,g12a-mipi-dphy-analog.yaml
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/phy/amlogic,g12a-mipi-dphy-analog.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Amlogic G12A MIPI analog PHY
+
+maintainers:
+  - Neil Armstrong <narmstrong at baylibre.com>
+
+properties:
+  compatible:
+    const: amlogic,g12a-mipi-dphy-analog
+
+  "#phy-cells":
+    const: 0
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    phy at 0 {
+          compatible = "amlogic,g12a-mipi-dphy-analog";
+          reg = <0x0 0xc>;
+          #phy-cells = <0>;
+    };
-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 07:05:10 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 16:05:10 +0100
Subject: [PATCH v3 0/2] phy: amlogic: Add support for the G12A Analog MIPI
 D-PHY
Message-ID: <20220107150512.614423-1-narmstrong@baylibre.com>

The Amlogic G12A SoCs embeds an Analog MIPI D-PHY to communicate with DSI
panels, this adds the bindings.
    
This Analog D-PHY works with a separate Digital MIPI D-PHY.

This serie adds the Bindings and the PHY driver.

Changes from v2 at [2]:
- Bindings example fix

Changes from v1 at [1]:
- Bindings fixes

[1] https://lore.kernel.org/r/20201123145157.300456-1-narmstrong at baylibre.com
[2] https://lore.kernel.org/r/20210210080736.771803-1-narmstrong at baylibre.com

Neil Armstrong (2):
  dt-bindings: phy: add Amlogic G12A Analog MIPI D-PHY bindings
  phy: amlogic: Add G12A Analog MIPI D-PHY driver

 .../phy/amlogic,g12a-mipi-dphy-analog.yaml    |  35 ++++
 drivers/phy/amlogic/Kconfig                   |  12 ++
 drivers/phy/amlogic/Makefile                  |   1 +
 .../amlogic/phy-meson-g12a-mipi-dphy-analog.c | 177 ++++++++++++++++++
 4 files changed, 225 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/amlogic,g12a-mipi-dphy-analog.yaml
 create mode 100644 drivers/phy/amlogic/phy-meson-g12a-mipi-dphy-analog.c

-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 07:05:12 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 16:05:12 +0100
Subject: [PATCH v3 2/2] phy: amlogic: Add G12A Analog MIPI D-PHY driver
In-Reply-To: <20220107150512.614423-1-narmstrong@baylibre.com>
References: <20220107150512.614423-1-narmstrong@baylibre.com>
Message-ID: <20220107150512.614423-3-narmstrong@baylibre.com>

The Amlogic G12A SoCs embeds an Analog MIPI D-PHY used to communicate with DSI
panels.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/phy/amlogic/Kconfig                   |  12 ++
 drivers/phy/amlogic/Makefile                  |   1 +
 .../amlogic/phy-meson-g12a-mipi-dphy-analog.c | 177 ++++++++++++++++++
 3 files changed, 190 insertions(+)
 create mode 100644 drivers/phy/amlogic/phy-meson-g12a-mipi-dphy-analog.c

diff --git a/drivers/phy/amlogic/Kconfig b/drivers/phy/amlogic/Kconfig
index db5d0cd757e3..ac898a102bcc 100644
--- a/drivers/phy/amlogic/Kconfig
+++ b/drivers/phy/amlogic/Kconfig
@@ -49,6 +49,18 @@ config PHY_MESON_G12A_USB3_PCIE
 	  in Meson G12A SoCs.
 	  If unsure, say N.
 
+config PHY_MESON_G12A_MIPI_DPHY_ANALOG
+	tristate "Meson G12A MIPI Analog DPHY driver"
+	default ARCH_MESON
+	depends on OF && (ARCH_MESON || COMPILE_TEST)
+	select GENERIC_PHY
+	select REGMAP_MMIO
+	select GENERIC_PHY_MIPI_DPHY
+	help
+	  Enable this to support the Meson MIPI Analog DPHY found in Meson G12A
+	  SoCs.
+	  If unsure, say N.
+
 config PHY_MESON_AXG_PCIE
 	tristate "Meson AXG PCIE PHY driver"
 	default ARCH_MESON
diff --git a/drivers/phy/amlogic/Makefile b/drivers/phy/amlogic/Makefile
index 8fa07fbd0d92..2eada0a683ca 100644
--- a/drivers/phy/amlogic/Makefile
+++ b/drivers/phy/amlogic/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_PHY_MESON8B_USB2)			+= phy-meson8b-usb2.o
 obj-$(CONFIG_PHY_MESON_GXL_USB2)		+= phy-meson-gxl-usb2.o
 obj-$(CONFIG_PHY_MESON_G12A_USB2)		+= phy-meson-g12a-usb2.o
 obj-$(CONFIG_PHY_MESON_G12A_USB3_PCIE)		+= phy-meson-g12a-usb3-pcie.o
+obj-$(CONFIG_PHY_MESON_G12A_MIPI_DPHY_ANALOG)	+= phy-meson-g12a-mipi-dphy-analog.o
 obj-$(CONFIG_PHY_MESON_AXG_PCIE)		+= phy-meson-axg-pcie.o
 obj-$(CONFIG_PHY_MESON_AXG_MIPI_PCIE_ANALOG)	+= phy-meson-axg-mipi-pcie-analog.o
 obj-$(CONFIG_PHY_MESON_AXG_MIPI_DPHY)		+= phy-meson-axg-mipi-dphy.o
diff --git a/drivers/phy/amlogic/phy-meson-g12a-mipi-dphy-analog.c b/drivers/phy/amlogic/phy-meson-g12a-mipi-dphy-analog.c
new file mode 100644
index 000000000000..6e9d416c0552
--- /dev/null
+++ b/drivers/phy/amlogic/phy-meson-g12a-mipi-dphy-analog.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Meson G12A MIPI DSI Analog PHY
+ *
+ * Copyright (C) 2018 Amlogic, Inc. All rights reserved
+ * Copyright (C) 2020 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ */
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/phy/phy.h>
+
+#define HHI_MIPI_CNTL0 0x00
+#define		HHI_MIPI_CNTL0_DIF_REF_CTL1	GENMASK(31, 16)
+#define		HHI_MIPI_CNTL0_DIF_REF_CTL0	GENMASK(15, 0)
+
+#define HHI_MIPI_CNTL1 0x04
+#define		HHI_MIPI_CNTL1_BANDGAP		BIT(16)
+#define		HHI_MIPI_CNTL2_DIF_REF_CTL2	GENMASK(15, 0)
+
+#define HHI_MIPI_CNTL2 0x08
+#define		HHI_MIPI_CNTL2_DIF_TX_CTL1	GENMASK(31, 16)
+#define		HHI_MIPI_CNTL2_CH_EN		GENMASK(15, 11)
+#define		HHI_MIPI_CNTL2_DIF_TX_CTL0	GENMASK(10, 0)
+
+#define DSI_LANE_0				BIT(4)
+#define DSI_LANE_1				BIT(3)
+#define DSI_LANE_CLK				BIT(2)
+#define DSI_LANE_2				BIT(1)
+#define DSI_LANE_3				BIT(0)
+
+struct phy_g12a_mipi_dphy_analog_priv {
+	struct phy *phy;
+	struct regmap *regmap;
+	struct phy_configure_opts_mipi_dphy config;
+};
+
+static int phy_g12a_mipi_dphy_analog_configure(struct phy *phy,
+					       union phy_configure_opts *opts)
+{
+	struct phy_g12a_mipi_dphy_analog_priv *priv = phy_get_drvdata(phy);
+	int ret;
+
+	ret = phy_mipi_dphy_config_validate(&opts->mipi_dphy);
+	if (ret)
+		return ret;
+
+	memcpy(&priv->config, opts, sizeof(priv->config));
+
+	return 0;
+}
+
+static int phy_g12a_mipi_dphy_analog_power_on(struct phy *phy)
+{
+	struct phy_g12a_mipi_dphy_analog_priv *priv = phy_get_drvdata(phy);
+	unsigned int reg;
+
+	regmap_write(priv->regmap, HHI_MIPI_CNTL0,
+		     FIELD_PREP(HHI_MIPI_CNTL0_DIF_REF_CTL0, 0x8) |
+		     FIELD_PREP(HHI_MIPI_CNTL0_DIF_REF_CTL1, 0xa487));
+
+	regmap_write(priv->regmap, HHI_MIPI_CNTL1,
+		     FIELD_PREP(HHI_MIPI_CNTL2_DIF_REF_CTL2, 0x2e) |
+		     HHI_MIPI_CNTL1_BANDGAP);
+
+	regmap_write(priv->regmap, HHI_MIPI_CNTL2,
+		     FIELD_PREP(HHI_MIPI_CNTL2_DIF_TX_CTL0, 0x459) |
+		     FIELD_PREP(HHI_MIPI_CNTL2_DIF_TX_CTL1, 0x2680));
+
+	reg = DSI_LANE_CLK;
+	switch (priv->config.lanes) {
+	case 4:
+		reg |= DSI_LANE_3;
+		fallthrough;
+	case 3:
+		reg |= DSI_LANE_2;
+		fallthrough;
+	case 2:
+		reg |= DSI_LANE_1;
+		fallthrough;
+	case 1:
+		reg |= DSI_LANE_0;
+		break;
+	default:
+		reg = 0;
+	}
+
+	regmap_update_bits(priv->regmap, HHI_MIPI_CNTL2,
+			   HHI_MIPI_CNTL2_CH_EN,
+			   FIELD_PREP(HHI_MIPI_CNTL2_CH_EN, reg));
+
+	return 0;
+}
+
+static int phy_g12a_mipi_dphy_analog_power_off(struct phy *phy)
+{
+	struct phy_g12a_mipi_dphy_analog_priv *priv = phy_get_drvdata(phy);
+
+	regmap_write(priv->regmap, HHI_MIPI_CNTL0, 0);
+	regmap_write(priv->regmap, HHI_MIPI_CNTL1, 0);
+	regmap_write(priv->regmap, HHI_MIPI_CNTL2, 0);
+
+	return 0;
+}
+
+static const struct phy_ops phy_g12a_mipi_dphy_analog_ops = {
+	.configure = phy_g12a_mipi_dphy_analog_configure,
+	.power_on = phy_g12a_mipi_dphy_analog_power_on,
+	.power_off = phy_g12a_mipi_dphy_analog_power_off,
+	.owner = THIS_MODULE,
+};
+
+static int phy_g12a_mipi_dphy_analog_probe(struct platform_device *pdev)
+{
+	struct phy_provider *phy;
+	struct device *dev = &pdev->dev;
+	struct phy_g12a_mipi_dphy_analog_priv *priv;
+	struct device_node *np = dev->of_node;
+	struct regmap *map;
+	int ret;
+
+	priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	/* Get the hhi system controller node */
+	map = syscon_node_to_regmap(of_get_parent(dev->of_node));
+	if (IS_ERR(map)) {
+		dev_err(dev,
+			"failed to get HHI regmap\n");
+		return PTR_ERR(map);
+	}
+
+	priv->regmap = map;
+
+	priv->phy = devm_phy_create(dev, np, &phy_g12a_mipi_dphy_analog_ops);
+	if (IS_ERR(priv->phy)) {
+		ret = PTR_ERR(priv->phy);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "failed to create PHY\n");
+		return ret;
+	}
+
+	phy_set_drvdata(priv->phy, priv);
+	dev_set_drvdata(dev, priv);
+
+	phy = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy);
+}
+
+static const struct of_device_id phy_g12a_mipi_dphy_analog_of_match[] = {
+	{
+		.compatible = "amlogic,g12a-mipi-dphy-analog",
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, phy_g12a_mipi_dphy_analog_of_match);
+
+static struct platform_driver phy_g12a_mipi_dphy_analog_driver = {
+	.probe = phy_g12a_mipi_dphy_analog_probe,
+	.driver = {
+		.name = "phy-meson-g12a-mipi-dphy-analog",
+		.of_match_table = phy_g12a_mipi_dphy_analog_of_match,
+	},
+};
+module_platform_driver(phy_g12a_mipi_dphy_analog_driver);
+
+MODULE_AUTHOR("Neil Armstrong <narmstrong at baylibre.com>");
+MODULE_DESCRIPTION("Meson G12A MIPI Analog D-PHY driver");
+MODULE_LICENSE("GPL v2");
-- 
2.25.1



From martin.blumenstingl at googlemail.com  Fri Jan  7 13:56:52 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 22:56:52 +0100
Subject: [PATCH 1/3] dt-bindings: reset: Add compatible for Meson-S4 Reset
 Controller
In-Reply-To: <20220107023931.13251-2-zelong.dong@amlogic.com>
References: <20220107023931.13251-1-zelong.dong@amlogic.com>
 <20220107023931.13251-2-zelong.dong@amlogic.com>
Message-ID: <CAFBinCDrfpjCDu4Atwx9n0KAafDyCQnBSd5fNFV5NgM1xgU-NA@mail.gmail.com>

On Fri, Jan 7, 2022 at 3:40 AM Zelong Dong <zelong.dong at amlogic.com> wrote:
>
> Add new compatible for Amlogic's Meson-S4 Reset Controller
>
> Signed-off-by: Zelong Dong <zelong.dong at amlogic.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>


From martin.blumenstingl at googlemail.com  Fri Jan  7 13:57:05 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 22:57:05 +0100
Subject: [PATCH 2/3] dt-bindings: reset: add bindings for the Meson-S4 SoC
 Reset Controller
In-Reply-To: <20220107023931.13251-3-zelong.dong@amlogic.com>
References: <20220107023931.13251-1-zelong.dong@amlogic.com>
 <20220107023931.13251-3-zelong.dong@amlogic.com>
Message-ID: <CAFBinCCmTwPcmuMAFP-rgu_v5NR0Z3B5bp-WTEvnaf+UMY5MRA@mail.gmail.com>

On Fri, Jan 7, 2022 at 3:40 AM Zelong Dong <zelong.dong at amlogic.com> wrote:
>
> Add DT bindings for the Meson-S4 SoC Reset Controller include file.
>
> Signed-off-by: Zelong Dong <zelong.dong at amlogic.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>


From martin.blumenstingl at googlemail.com  Fri Jan  7 13:58:23 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 22:58:23 +0100
Subject: [PATCH 3/3] reset: reset-meson: add support for the Meson-S4 SoC
 Reset Controller
In-Reply-To: <20220107023931.13251-4-zelong.dong@amlogic.com>
References: <20220107023931.13251-1-zelong.dong@amlogic.com>
 <20220107023931.13251-4-zelong.dong@amlogic.com>
Message-ID: <CAFBinCAP66AHM4252BwJ2FMLtyw2RzUsoitahpK0jNdgZaJLXg@mail.gmail.com>

On Fri, Jan 7, 2022 at 3:40 AM Zelong Dong <zelong.dong at amlogic.com> wrote:
>
> Compared to the A1 SoCs the number of RESET registers is different
> and the offset for the level registers is the same. Add a new
> compatible string and struct meson_reset_param to add support for the
> reset controller on the S4 SoC.
>
> Signed-off-by: Zelong Dong <zelong.dong at amlogic.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>


From martin.blumenstingl at googlemail.com  Fri Jan  7 14:09:13 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 23:09:13 +0100
Subject: [PATCH v3 2/2] phy: amlogic: Add G12A Analog MIPI D-PHY driver
In-Reply-To: <20220107150512.614423-3-narmstrong@baylibre.com>
References: <20220107150512.614423-1-narmstrong@baylibre.com>
 <20220107150512.614423-3-narmstrong@baylibre.com>
Message-ID: <CAFBinCC9J_w9JM-TmrXp7SXT27V7Ze37wrxHZZQ1==N4y2-0dg@mail.gmail.com>

Hi Neil,

On Fri, Jan 7, 2022 at 4:06 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
[...]
> +#define HHI_MIPI_CNTL2 0x08
> +#define                HHI_MIPI_CNTL2_DIF_TX_CTL1      GENMASK(31, 16)
> +#define                HHI_MIPI_CNTL2_CH_EN            GENMASK(15, 11)
> +#define                HHI_MIPI_CNTL2_DIF_TX_CTL0      GENMASK(10, 0)
> +
> +#define DSI_LANE_0                             BIT(4)
> +#define DSI_LANE_1                             BIT(3)
> +#define DSI_LANE_CLK                           BIT(2)
> +#define DSI_LANE_2                             BIT(1)
> +#define DSI_LANE_3                             BIT(0)
At first I thought that these should be named
HHI_MIPI_CNTL2_DSI_LANE_0 (and similar).
But then I understood that they aren't bits directly in HHI_MIPI_CNTL2
but they belong to HHI_MIPI_CNTL2_CH_EN.
Have you considered naming them for example
HHI_MIPI_CNTL2_CH_EN_DSI_LANE_0 to make this more clear?

[...]
> +       if (IS_ERR(map)) {
> +               dev_err(dev,
> +                       "failed to get HHI regmap\n");
> +               return PTR_ERR(map);
I suggest using:
  return dev_err_probe(dev, PTR_ERR(map), "failed to get HHI regmap\n");
to simplify the code

[...]
> +       if (IS_ERR(priv->phy)) {
> +               ret = PTR_ERR(priv->phy);
> +               if (ret != -EPROBE_DEFER)
> +                       dev_err(dev, "failed to create PHY\n");
> +               return ret;
and similar here:
  return dev_err_probe(dev, PTR_ERR(priv->phy), "failed to create PHY\n");

[...]
> +static const struct of_device_id phy_g12a_mipi_dphy_analog_of_match[] = {
> +       {
> +               .compatible = "amlogic,g12a-mipi-dphy-analog",
> +       },
> +       { },
In the past I was suggested to use:
  { /* sentinel */ }
meaning: no trailing comma here so nobody can add entries after the
sentinel by accident.
I suggest doing the same here if you re-spin this series.


Thank you!
Martin


From martin.blumenstingl at googlemail.com  Fri Jan  7 14:13:42 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 23:13:42 +0100
Subject: [PATCH v3 1/2] dt-bindings: phy: add Amlogic G12A Analog MIPI
 D-PHY bindings
In-Reply-To: <20220107150512.614423-2-narmstrong@baylibre.com>
References: <20220107150512.614423-1-narmstrong@baylibre.com>
 <20220107150512.614423-2-narmstrong@baylibre.com>
Message-ID: <CAFBinCDRx6VaaAubr6VRLnX=G4Ez8cGg-=6e-9GWrH8FwwBs-g@mail.gmail.com>

Hi Neil,

On Fri, Jan 7, 2022 at 4:05 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
[...]
> +required:
> +  - compatible
> +  - reg
> +  - "#phy-cells"
I also found a "MIPI DSI PHY clock" and "MIPI DSI PHY interrupt" in
the datasheet.
I'm no expert on this and I'm just asking in case you have missed one of these:
Can you confirm that these belong to some other IP?


Best regards,
Martin


From martin.blumenstingl at googlemail.com  Fri Jan  7 14:14:41 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 23:14:41 +0100
Subject: [PATCH 2/6] dt-bindings: display: meson-vpu: add third DPI output
 port
In-Reply-To: <20220107145515.613009-3-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-3-narmstrong@baylibre.com>
Message-ID: <CAFBinCArnZ8XtaBtWa0smmPTc-sHvAdD7_-3iTywxUJ08-uyMw@mail.gmail.com>

On Fri, Jan 7, 2022 at 3:56 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> Add third port corresponding to the ENCL DPI encoder used to connect
> to DSI or LVDS transceivers.
>
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>


From martin.blumenstingl at googlemail.com  Fri Jan  7 14:33:14 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 23:33:14 +0100
Subject: [PATCH 3/6] drm/meson: venc: add ENCL encoder setup for MIPI-DSI
 output
In-Reply-To: <20220107145515.613009-4-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-4-narmstrong@baylibre.com>
Message-ID: <CAFBinCA-df8Sedqh8Arh_BsMCHYv6-Kb3owrkFBd=W_EY2qxSA@mail.gmail.com>

 Hi Neil,

On Fri, Jan 7, 2022 at 3:57 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> This adds supports for the ENCL encoder connected to a MIPI-DSI transceiver on the
> Amlogic AXG SoCs.
Should this be "AXG and newer SoCs" or is this really AXG specific?

[...]
> +#define GAMMA_VCOM_POL    7     /* RW */
> +#define GAMMA_RVS_OUT     6     /* RW */
> +#define ADR_RDY           5     /* Read Only */
> +#define WR_RDY            4     /* Read Only */
> +#define RD_RDY            3     /* Read Only */
> +#define GAMMA_TR          2     /* RW */
> +#define GAMMA_SET         1     /* RW */
> +#define GAMMA_EN          0     /* RW */
> +
> +#define H_RD              12
> +#define H_AUTO_INC        11
> +#define H_SEL_R           10
> +#define H_SEL_G           9
> +#define H_SEL_B           8
I think all values above can be wrapped in the BIT() macro, then you
don't need that below.

> +#define HADR_MSB          7            /* 7:0 */
> +#define HADR              0            /* 7:0 */
Here GENMASK(7, 0) can be used for HADR

Also I think prefixing all macros above with their register name
(L_GAMMA_CNTL_PORT_ or L_GAMMA_ADDR_PORT_) will make the code easier
to read.

[...]
> +       writel_relaxed(0x8000, priv->io_base + _REG(ENCL_VIDEO_MODE));
The public S905 datasheet calls 0x8000 ENCL_PX_LN_CNT_SHADOW_EN

> +       writel_relaxed(0x0418, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
According to the public S905 datasheet this is:
- BIT(3): ENCL_VIDEO_MODE_ADV_VFIFO_EN
- BIT(4): ENCL_VIDEO_MODE_ADV_GAIN_HDTV
- BIT(10): ENCL_SEL_GAMMA_RGB_IN

> +       writel_relaxed(0x1000, priv->io_base + _REG(ENCL_VIDEO_FILT_CTRL));
I don't know the exact name but the 32-bit vendor kernel sources have
a comment [0] saying that 0x1000 is "bypass filter"
But maybe we can simply call it ENCL_VIDEO_FILT_CTRL_BYPASS_FILTER

[...]
> +       writel_relaxed(3, priv->io_base + _REG(ENCL_VIDEO_RGBIN_CTRL));
The public S905 datasheet says:
- BIT(0): USE RGB data from VIU, furthermore a comment in the 3.10
kernel sources make this more clear: bit[0] 1:RGB, 0:YUV
- BIT(1): CFG_VIDEO_RGBIN_ZBLK

> +       /* default black pattern */
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_MDSEL));
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_Y));
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CB));
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CR));
> +       writel_relaxed(1, priv->io_base + _REG(ENCL_TST_EN));
> +       writel_bits_relaxed(BIT(3), 0, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
same as above: ENCL_VIDEO_MODE_ADV_VFIFO_EN

> +
> +       writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
> +
> +       writel_relaxed(0, priv->io_base + _REG(L_RGB_BASE_ADDR));
> +       writel_relaxed(0x400, priv->io_base + _REG(L_RGB_COEFF_ADDR));
note to self: L_RGB_COEFF_ADDR seems to contain some "magic" value,
there's no further info in the 3.10 kernel sources or datasheet

> +       writel_relaxed(0x400, priv->io_base + _REG(L_DITH_CNTL_ADDR));
According to the public S905 datasheet BIT(10) is DITH10_EN (10-bits
Dithering to 8 Bits Enable).
I am not sure if this would belong to the selected video mode/bit depth.
I'll let other reviewers decide if this is relevant or not because I don't know.

[...]
> +       writel_relaxed(0, priv->io_base + _REG(L_INV_CNT_ADDR));
> +       writel_relaxed(BIT(4) | BIT(5),
> +                      priv->io_base + _REG(L_TCON_MISC_SEL_ADDR));
the public S905 datasheet states:
- BIT(4): STV1_SEL (STV1 is frame Signal)
- BIT(5): STV2_SEL (STV2 is frame Signal)
This doesn't seem helpful to me though, but maybe you can still create
preprocessor macros for this (for consistency)?

[...]
> +       switch (priv->venc.current_mode) {
> +       case MESON_VENC_MODE_MIPI_DSI:
> +               writel_relaxed(0x200,
> +                              priv->io_base + _REG(VENC_INTCTRL));
the public S905 datasheet documents this as:
- BIT(9): ENCP_LNRST_INT_EN (Progressive encoder filed change interrupt enable)
Please add a preprocessor macro to make it consistent with
VENC_INTCTRL_ENCI_LNRST_INT_EN which already exists and is used below.


Best regards,
Martin


From martin.blumenstingl at googlemail.com  Fri Jan  7 14:35:16 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 23:35:16 +0100
Subject: [PATCH 5/6] drm/meson: add DSI encoder
In-Reply-To: <20220107145515.613009-6-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-6-narmstrong@baylibre.com>
Message-ID: <CAFBinCCR4zftkvJWgX4T068BRsjVp9YhRbzgdBOR+tuMcGSZ3w@mail.gmail.com>

Hi Neil,

On Fri, Jan 7, 2022 at 3:57 PM Neil Armstrong <narmstrong at baylibre.com> wrote:

[...]
> +       writel_bits_relaxed(BIT(3), BIT(3), priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
see my comment on patch #3 from this series for BIT(3)


Best regards,
Martin


From martin.blumenstingl at googlemail.com  Fri Jan  7 14:49:15 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 23:49:15 +0100
Subject: [PATCH 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <20220107145515.613009-7-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-7-narmstrong@baylibre.com>
Message-ID: <CAFBinCB3+dSjQFRp5CBpGk5Qi8zoxRDRaobuCtXzU6VtM8+ryQ@mail.gmail.com>

Hi Neil,

some high-level comments from me below.

On Fri, Jan 7, 2022 at 3:58 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
[...]
> +/*  MIPI DSI Relative REGISTERs Definitions */
> +/* For MIPI_DSI_TOP_CNTL */
> +#define BIT_DPI_COLOR_MODE        20
> +#define BIT_IN_COLOR_MODE         16
> +#define BIT_CHROMA_SUBSAMPLE      14
> +#define BIT_COMP2_SEL             12
> +#define BIT_COMP1_SEL             10
> +#define BIT_COMP0_SEL              8
> +#define BIT_DE_POL                 6
> +#define BIT_HSYNC_POL              5
> +#define BIT_VSYNC_POL              4
> +#define BIT_DPICOLORM              3
> +#define BIT_DPISHUTDN              2
> +#define BIT_EDPITE_INTR_PULSE      1
> +#define BIT_ERR_INTR_PULSE         0
Why not use BIT() and GENMASK() for these and prefixing them with
MIPI_DSI_TOP_CNTL_?
That would make them consistent with other parts of the meson sub-driver.

[...]
> +static void meson_dw_mipi_dsi_hw_init(struct meson_dw_mipi_dsi *mipi_dsi)
> +{
> +       writel_relaxed((1 << 4) | (1 << 5) | (0 << 6),
> +                      mipi_dsi->base + MIPI_DSI_TOP_CNTL);
please use the macros from above

> +       writel_bits_relaxed(0xf, 0xf, mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);
> +       writel_bits_relaxed(0xf, 0, mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);

[...]
> +       phy_power_on(mipi_dsi->phy);
Please propagate the error code here.
Also shouldn't this go to a new dw_mipi_dsi_phy_power_on() as the PHY
driver uses the updated settings from phy_configure only in it's
.power_on callback?

[...]
> +       phy_configure(mipi_dsi->phy, &mipi_dsi->phy_opts);
please propagate the error code here as the PHY driver has some
explicit code to return an error in it's .phy_configure callback

[...]
> +       phy_init(mipi_dsi->phy);
please propagate the error code here

[...]
> +       phy_exit(mipi_dsi->phy);
please propagate the error code here

[...]
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       mipi_dsi->base = devm_ioremap_resource(&pdev->dev, res);
other parts of the meson DRM driver have been converted to use
devm_platform_ioremap_resource()
I suggest updating this as well to simplify the code here

[...]
> +       mipi_dsi->phy = devm_phy_get(&pdev->dev, "dphy");
> +       if (IS_ERR(mipi_dsi->phy)) {
> +               ret = PTR_ERR(mipi_dsi->phy);
> +               dev_err(&pdev->dev, "failed to get mipi dphy: %d\n", ret);
> +               return ret;
you can simplify this with:
  return dev_err_probe(&pdev->dev, PTR_ERR(mipi_dsi->phy, "failed to
get mipi dphy\n");

[...]
> +       mipi_dsi->px_clk = devm_clk_get(&pdev->dev, "px_clk");
> +       if (IS_ERR(mipi_dsi->px_clk)) {
> +               dev_err(&pdev->dev, "Unable to get PLL clk\n");
> +               return PTR_ERR(mipi_dsi->px_clk);
you can simplify this with:
  return dev_err_probe(&pdev->dev, PTR_ERR(mipi_dsi->px_clk, "Unable
to get PLL clk\n");
Also should it say s/PLL clk/px clock/?

[...]
> +       top_rst = devm_reset_control_get_exclusive(&pdev->dev, "top");
> +       if (IS_ERR(top_rst)) {
> +               ret = PTR_ERR(top_rst);
> +
> +               if (ret != -EPROBE_DEFER)
> +                       dev_err(&pdev->dev, "Unable to get reset control: %d\n", ret);
> +
> +               return ret;
you can simplify this with:
  return dev_err_probe(&pdev->dev, PTR_ERR(top_rst, "Unable to get
reset control\n");

[...]
> +       mipi_dsi->dmd = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata);
> +       if (IS_ERR(mipi_dsi->dmd)) {
> +               ret = PTR_ERR(mipi_dsi->dmd);
> +               if (ret != -EPROBE_DEFER)
> +                       dev_err(&pdev->dev,
> +                               "Failed to probe dw_mipi_dsi: %d\n", ret);
you can simplify this with:
  dev_err_probe(&pdev->dev, ret, "Failed to probe dw_mipi_dsi\n");


Best regards,
Martin


From qianggui.song at amlogic.com  Sat Jan  8 00:42:14 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Sat, 8 Jan 2022 16:42:14 +0800
Subject: [PATCH 0/4] irqchip/meson-gpio: Add support for Meson-S4 SoC
Message-ID: <20220108084218.31877-1-qianggui.song@amlogic.com>

This patchset add support for GPIO interrupt controller of Meson-S4 SoC
Which has somethings different with current other meson chips. To
support the new chips, current gpio irqchip driver need to rework as
below:
1. support more than 8 gpio irq line.
2. add a set trigger type callback function.

With above work, add support for S4 gpio irqchip

Qianggui Song (4):
  dt-bindings: interrupt-controller: New binding for Meson-S4 SoCs
  irqchip/meson-gpio: support more than 8 channels gpio irq line
  irqchip/meson-gpio: add select trigger type callback
  irqchip/meson-gpio: Add support for meson s4 SoCs

 .../amlogic,meson-gpio-intc.txt               |  1 +
 drivers/irqchip/irq-meson-gpio.c              | 97 ++++++++++++++++---
 2 files changed, 86 insertions(+), 12 deletions(-)

-- 
2.34.1



From qianggui.song at amlogic.com  Sat Jan  8 00:42:15 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Sat, 8 Jan 2022 16:42:15 +0800
Subject: [PATCH 1/4] dt-bindings: interrupt-controller: New binding for
 Meson-S4 SoCs
In-Reply-To: <20220108084218.31877-1-qianggui.song@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
Message-ID: <20220108084218.31877-2-qianggui.song@amlogic.com>

Update dt-binding document for GPIO interrupt controller of Meson-S4 SoCs

Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 .../bindings/interrupt-controller/amlogic,meson-gpio-intc.txt    | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
index 23b18b92c558..9300736bf1ed 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
@@ -18,6 +18,7 @@ Required properties:
     "amlogic,meson-g12a-gpio-intc" for G12A SoCs (S905D2, S905X2, S905Y2)
     "amlogic,meson-sm1-gpio-intc" for SM1 SoCs (S905D3, S905X3, S905Y3)
     "amlogic,meson-a1-gpio-intc" for A1 SoCs (A113L)
+    "amlogic,meson-a1-gpio-intc" for S4 SoCs (S802X2, S905Y4, S805X2G, S905W2)
 - reg : Specifies base physical address and size of the registers.
 - interrupt-controller : Identifies the node as an interrupt controller.
 - #interrupt-cells : Specifies the number of cells needed to encode an
-- 
2.34.1



From qianggui.song at amlogic.com  Sat Jan  8 00:42:16 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Sat, 8 Jan 2022 16:42:16 +0800
Subject: [PATCH 2/4] irqchip/meson-gpio: support more than 8 channels gpio irq
 line
In-Reply-To: <20220108084218.31877-1-qianggui.song@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
Message-ID: <20220108084218.31877-3-qianggui.song@amlogic.com>

Current meson gpio irqchip driver only support 8 channels for gpio irq
line, later chips may have more then 8 channels, so need to modify code
to support more.

Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 drivers/irqchip/irq-meson-gpio.c | 33 +++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
index d90ff0b92480..6a7b4fb13452 100644
--- a/drivers/irqchip/irq-meson-gpio.c
+++ b/drivers/irqchip/irq-meson-gpio.c
@@ -16,7 +16,6 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 
-#define NUM_CHANNEL 8
 #define MAX_INPUT_MUX 256
 
 #define REG_EDGE_POL	0x00
@@ -60,6 +59,7 @@ struct irq_ctl_ops {
 
 struct meson_gpio_irq_params {
 	unsigned int nr_hwirq;
+	unsigned int channel_num;
 	bool support_edge_both;
 	unsigned int edge_both_offset;
 	unsigned int edge_single_offset;
@@ -81,6 +81,7 @@ struct meson_gpio_irq_params {
 	.edge_single_offset = 0,				\
 	.pol_low_offset = 16,					\
 	.pin_sel_mask = 0xff,					\
+	.channel_num = 8,					\
 
 #define INIT_MESON_A1_COMMON_DATA(irqs)				\
 	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
@@ -90,6 +91,7 @@ struct meson_gpio_irq_params {
 	.edge_single_offset = 8,				\
 	.pol_low_offset = 0,					\
 	.pin_sel_mask = 0x7f,					\
+	.channel_num = 8,					\
 
 static const struct meson_gpio_irq_params meson8_params = {
 	INIT_MESON8_COMMON_DATA(134)
@@ -136,8 +138,9 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
 struct meson_gpio_irq_controller {
 	const struct meson_gpio_irq_params *params;
 	void __iomem *base;
-	u32 channel_irqs[NUM_CHANNEL];
-	DECLARE_BITMAP(channel_map, NUM_CHANNEL);
+	u32 *channel_irqs;
+	unsigned long *channel_map;
+	u8 channel_num;
 	spinlock_t lock;
 };
 
@@ -207,8 +210,8 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
 	spin_lock_irqsave(&ctl->lock, flags);
 
 	/* Find a free channel */
-	idx = find_first_zero_bit(ctl->channel_map, NUM_CHANNEL);
-	if (idx >= NUM_CHANNEL) {
+	idx = find_first_zero_bit(ctl->channel_map, ctl->channel_num);
+	if (idx >= ctl->channel_num) {
 		spin_unlock_irqrestore(&ctl->lock, flags);
 		pr_err("No channel available\n");
 		return -ENOSPC;
@@ -447,13 +450,25 @@ static int meson_gpio_irq_parse_dt(struct device_node *node, struct meson_gpio_i
 
 	ctl->params = match->data;
 
+	ctl->channel_num = ctl->params->channel_num;
+	ctl->channel_irqs = kcalloc(ctl->channel_num,
+				    sizeof(*ctl->channel_irqs), GFP_KERNEL);
+	if (!ctl->channel_irqs)
+		return -ENOMEM;
+
+	ctl->channel_map = bitmap_zalloc(ctl->params->channel_num, GFP_KERNEL);
+	if (!ctl->channel_map) {
+		kfree(ctl->channel_irqs);
+		return -ENOMEM;
+	}
+
 	ret = of_property_read_variable_u32_array(node,
 						  "amlogic,channel-interrupts",
 						  ctl->channel_irqs,
-						  NUM_CHANNEL,
-						  NUM_CHANNEL);
+						  ctl->channel_num,
+						  ctl->channel_num);
 	if (ret < 0) {
-		pr_err("can't get %d channel interrupts\n", NUM_CHANNEL);
+		pr_err("can't get %d channel interrupts\n", ctl->channel_num);
 		return ret;
 	}
 
@@ -507,7 +522,7 @@ static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *
 	}
 
 	pr_info("%d to %d gpio interrupt mux initialized\n",
-		ctl->params->nr_hwirq, NUM_CHANNEL);
+		ctl->params->nr_hwirq, ctl->channel_num);
 
 	return 0;
 
-- 
2.34.1



From qianggui.song at amlogic.com  Sat Jan  8 00:42:17 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Sat, 8 Jan 2022 16:42:17 +0800
Subject: [PATCH 3/4] irqchip/meson-gpio: add select trigger type callback
In-Reply-To: <20220108084218.31877-1-qianggui.song@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
Message-ID: <20220108084218.31877-4-qianggui.song@amlogic.com>

Due to some chips may use different registers and offset, provide
a set trigger type call back.

Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 drivers/irqchip/irq-meson-gpio.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
index 6a7b4fb13452..98419428fcbd 100644
--- a/drivers/irqchip/irq-meson-gpio.c
+++ b/drivers/irqchip/irq-meson-gpio.c
@@ -55,6 +55,8 @@ struct irq_ctl_ops {
 	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
 				 unsigned int channel, unsigned long hwirq);
 	void (*gpio_irq_init)(struct meson_gpio_irq_controller *ctl);
+	unsigned int (*gpio_irq_sel_type)(struct meson_gpio_irq_controller *ctl,
+					  unsigned int idx, u32 val);
 };
 
 struct meson_gpio_irq_params {
@@ -68,16 +70,17 @@ struct meson_gpio_irq_params {
 	struct irq_ctl_ops ops;
 };
 
-#define INIT_MESON_COMMON(irqs, init, sel)			\
+#define INIT_MESON_COMMON(irqs, init, sel, type)		\
 	.nr_hwirq = irqs,					\
 	.ops = {						\
 		.gpio_irq_init = init,				\
 		.gpio_irq_sel_pin = sel,			\
+		.gpio_irq_sel_type = type,			\
 	},
 
 #define INIT_MESON8_COMMON_DATA(irqs)				\
 	INIT_MESON_COMMON(irqs, meson_gpio_irq_init_dummy,	\
-			  meson8_gpio_irq_sel_pin)		\
+			  meson8_gpio_irq_sel_pin, NULL)	\
 	.edge_single_offset = 0,				\
 	.pol_low_offset = 16,					\
 	.pin_sel_mask = 0xff,					\
@@ -85,7 +88,7 @@ struct meson_gpio_irq_params {
 
 #define INIT_MESON_A1_COMMON_DATA(irqs)				\
 	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
-			  meson_a1_gpio_irq_sel_pin)		\
+			  meson_a1_gpio_irq_sel_pin, NULL)	\
 	.support_edge_both = true,				\
 	.edge_both_offset = 16,					\
 	.edge_single_offset = 8,				\
@@ -279,6 +282,10 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
 	 */
 	type &= IRQ_TYPE_SENSE_MASK;
 
+	/* Some controllers may have different calculation method*/
+	if (params->ops.gpio_irq_sel_type)
+		return params->ops.gpio_irq_sel_type(ctl, idx, type);
+
 	/*
 	 * New controller support EDGE_BOTH trigger. This setting takes
 	 * precedence over the other edge/polarity settings
-- 
2.34.1



From qianggui.song at amlogic.com  Sat Jan  8 00:42:18 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Sat, 8 Jan 2022 16:42:18 +0800
Subject: [PATCH 4/4] irqchip/meson-gpio: Add support for meson s4 SoCs
In-Reply-To: <20220108084218.31877-1-qianggui.song@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
Message-ID: <20220108084218.31877-5-qianggui.song@amlogic.com>

The meson s4 SoCs support 12 gpio irq lines compared with previous
serial chips and have something different, details are as below.

IRQ Number:
- 80:68 13 pins on bank Z
- 67:48 20 pins on bank X
- 47:36 12 pins on bank H
- 35:24 12 pins on bank D
- 23:22 2  pins on bank E
- 21:14 8  pins on bank C
- 13:0  13 pins on bank B

- PADCTRL_GPIO_IRQ_CTRL0
  bit[31]:    enable/disable the whole irq lines
  bit[12-23]: single edge trigger
  bit[0-11]:  poll trigger

- PADCTRL_GPIO_IRQ_CTRL[X]
- bit[0-16]: 7 bits to chooge gpio source for irq line 2*[X] - 2
- bit[16-22]:7 bits to chooge gpio source for irq line 2*[X] - 1
  where X = 1-6

- PADCTRL_GPIO_IRQ_CTRL[7]
  bit[0-11]: both edge trigger

Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 drivers/irqchip/irq-meson-gpio.c | 51 ++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
index 98419428fcbd..c5d20a866c37 100644
--- a/drivers/irqchip/irq-meson-gpio.c
+++ b/drivers/irqchip/irq-meson-gpio.c
@@ -42,6 +42,11 @@
 #define REG_PIN_SEL_SHIFT(x)	(((x) % 4) * 8)
 #define REG_FILTER_SEL_SHIFT(x)	((x) * 4)
 
+/* use for s4 chips */
+#define REG_EDGE_POL_S4	0x1c
+#define REG_EDGE_POL_MASK_S4(x)				\
+	({typeof(x) _x = (x); BIT(_x) | BIT(12 + (_x)); })
+
 struct meson_gpio_irq_controller;
 static void meson8_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
 				    unsigned int channel, unsigned long hwirq);
@@ -50,6 +55,9 @@ static void meson_a1_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
 				      unsigned int channel,
 				      unsigned long hwirq);
 static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl);
+static unsigned int
+meson_s4_gpio_irq_sel_type(struct meson_gpio_irq_controller *ctl,
+			   unsigned int idx, u32 val);
 
 struct irq_ctl_ops {
 	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
@@ -96,6 +104,17 @@ struct meson_gpio_irq_params {
 	.pin_sel_mask = 0x7f,					\
 	.channel_num = 8,					\
 
+#define INIT_MESON_S4_COMMON_DATA(irqs)                         \
+	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,         \
+			  meson_a1_gpio_irq_sel_pin,            \
+			  meson_s4_gpio_irq_sel_type)           \
+	.support_edge_both = true,				\
+	.edge_both_offset = 0,					\
+	.edge_single_offset = 12,				\
+	.pol_low_offset = 0,					\
+	.pin_sel_mask = 0xff,					\
+	.channel_num = 12,					\
+
 static const struct meson_gpio_irq_params meson8_params = {
 	INIT_MESON8_COMMON_DATA(134)
 };
@@ -126,6 +145,10 @@ static const struct meson_gpio_irq_params a1_params = {
 	INIT_MESON_A1_COMMON_DATA(62)
 };
 
+static const struct meson_gpio_irq_params s4_params = {
+	INIT_MESON_S4_COMMON_DATA(82)
+};
+
 static const struct of_device_id meson_irq_gpio_matches[] = {
 	{ .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params },
 	{ .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params },
@@ -135,6 +158,7 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
 	{ .compatible = "amlogic,meson-g12a-gpio-intc", .data = &axg_params },
 	{ .compatible = "amlogic,meson-sm1-gpio-intc", .data = &sm1_params },
 	{ .compatible = "amlogic,meson-a1-gpio-intc", .data = &a1_params },
+	{ .compatible = "amlogic,meson-s4-gpio-intc", .data = &s4_params },
 	{ }
 };
 
@@ -202,6 +226,33 @@ static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl)
 	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL, BIT(31), BIT(31));
 }
 
+static unsigned int
+meson_s4_gpio_irq_sel_type(struct meson_gpio_irq_controller *ctl,
+			   unsigned int idx, unsigned int type)
+{
+	unsigned int val = 0;
+
+	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4, BIT(0 + (idx)), 0);
+
+	if (type == IRQ_TYPE_EDGE_BOTH) {
+		val |= BIT(ctl->params->edge_both_offset + (idx));
+		meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4,
+					   BIT(ctl->params->edge_both_offset + (idx)), val);
+		return 0;
+	}
+
+	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
+		val |= BIT(ctl->params->pol_low_offset + (idx));
+
+	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+		val |= BIT(ctl->params->edge_single_offset  + (idx));
+
+	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
+				   REG_EDGE_POL_MASK_S4(idx), val);
+
+	return 0;
+};
+
 static int
 meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
 			       unsigned long  hwirq,
-- 
2.34.1



From maz at kernel.org  Sat Jan  8 02:37:52 2022
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 08 Jan 2022 10:37:52 +0000
Subject: [PATCH 2/4] irqchip/meson-gpio: support more than 8 channels gpio
 irq line
In-Reply-To: <20220108084218.31877-3-qianggui.song@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-3-qianggui.song@amlogic.com>
Message-ID: <87tueetsvz.wl-maz@kernel.org>

On Sat, 08 Jan 2022 08:42:16 +0000,
Qianggui Song <qianggui.song at amlogic.com> wrote:
> 
> Current meson gpio irqchip driver only support 8 channels for gpio irq
> line, later chips may have more then 8 channels, so need to modify code
> to support more.
> 
> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
> ---
>  drivers/irqchip/irq-meson-gpio.c | 33 +++++++++++++++++++++++---------
>  1 file changed, 24 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
> index d90ff0b92480..6a7b4fb13452 100644
> --- a/drivers/irqchip/irq-meson-gpio.c
> +++ b/drivers/irqchip/irq-meson-gpio.c
> @@ -16,7 +16,6 @@
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  
> -#define NUM_CHANNEL 8
>  #define MAX_INPUT_MUX 256
>  
>  #define REG_EDGE_POL	0x00
> @@ -60,6 +59,7 @@ struct irq_ctl_ops {
>  
>  struct meson_gpio_irq_params {
>  	unsigned int nr_hwirq;
> +	unsigned int channel_num;

For consistency, please name this nr_channels.

>  	bool support_edge_both;
>  	unsigned int edge_both_offset;
>  	unsigned int edge_single_offset;
> @@ -81,6 +81,7 @@ struct meson_gpio_irq_params {
>  	.edge_single_offset = 0,				\
>  	.pol_low_offset = 16,					\
>  	.pin_sel_mask = 0xff,					\
> +	.channel_num = 8,					\
>  
>  #define INIT_MESON_A1_COMMON_DATA(irqs)				\
>  	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
> @@ -90,6 +91,7 @@ struct meson_gpio_irq_params {
>  	.edge_single_offset = 8,				\
>  	.pol_low_offset = 0,					\
>  	.pin_sel_mask = 0x7f,					\
> +	.channel_num = 8,					\
>  
>  static const struct meson_gpio_irq_params meson8_params = {
>  	INIT_MESON8_COMMON_DATA(134)
> @@ -136,8 +138,9 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
>  struct meson_gpio_irq_controller {
>  	const struct meson_gpio_irq_params *params;
>  	void __iomem *base;
> -	u32 channel_irqs[NUM_CHANNEL];
> -	DECLARE_BITMAP(channel_map, NUM_CHANNEL);
> +	u32 *channel_irqs;
> +	unsigned long *channel_map;
> +	u8 channel_num;

Same thing. Though this is completely superfluous, see below.

>  	spinlock_t lock;
>  };
>  
> @@ -207,8 +210,8 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
>  	spin_lock_irqsave(&ctl->lock, flags);
>  
>  	/* Find a free channel */
> -	idx = find_first_zero_bit(ctl->channel_map, NUM_CHANNEL);
> -	if (idx >= NUM_CHANNEL) {
> +	idx = find_first_zero_bit(ctl->channel_map, ctl->channel_num);
> +	if (idx >= ctl->channel_num) {
>  		spin_unlock_irqrestore(&ctl->lock, flags);
>  		pr_err("No channel available\n");
>  		return -ENOSPC;
> @@ -447,13 +450,25 @@ static int meson_gpio_irq_parse_dt(struct device_node *node, struct meson_gpio_i
>  
>  	ctl->params = match->data;
>  
> +	ctl->channel_num = ctl->params->channel_num;

Since you already have a pointer to params, why do you need to
duplicate this information?

> +	ctl->channel_irqs = kcalloc(ctl->channel_num,
> +				    sizeof(*ctl->channel_irqs), GFP_KERNEL);
> +	if (!ctl->channel_irqs)
> +		return -ENOMEM;
> +
> +	ctl->channel_map = bitmap_zalloc(ctl->params->channel_num, GFP_KERNEL);
> +	if (!ctl->channel_map) {
> +		kfree(ctl->channel_irqs);
> +		return -ENOMEM;
> +	}
> +
>  	ret = of_property_read_variable_u32_array(node,
>  						  "amlogic,channel-interrupts",
>  						  ctl->channel_irqs,
> -						  NUM_CHANNEL,
> -						  NUM_CHANNEL);
> +						  ctl->channel_num,
> +						  ctl->channel_num);
>  	if (ret < 0) {
> -		pr_err("can't get %d channel interrupts\n", NUM_CHANNEL);
> +		pr_err("can't get %d channel interrupts\n", ctl->channel_num);
>  		return ret;

You are now leaking the bitmap and channel_map allocations.

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Sat Jan  8 02:44:59 2022
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 08 Jan 2022 10:44:59 +0000
Subject: [PATCH 3/4] irqchip/meson-gpio: add select trigger type callback
In-Reply-To: <20220108084218.31877-4-qianggui.song@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-4-qianggui.song@amlogic.com>
Message-ID: <87sftytsk4.wl-maz@kernel.org>

On Sat, 08 Jan 2022 08:42:17 +0000,
Qianggui Song <qianggui.song at amlogic.com> wrote:
> 
> Due to some chips may use different registers and offset, provide
> a set trigger type call back.
> 
> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
> ---
>  drivers/irqchip/irq-meson-gpio.c | 13 ++++++++++---
>  1 file changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
> index 6a7b4fb13452..98419428fcbd 100644
> --- a/drivers/irqchip/irq-meson-gpio.c
> +++ b/drivers/irqchip/irq-meson-gpio.c
> @@ -55,6 +55,8 @@ struct irq_ctl_ops {
>  	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
>  				 unsigned int channel, unsigned long hwirq);
>  	void (*gpio_irq_init)(struct meson_gpio_irq_controller *ctl);
> +	unsigned int (*gpio_irq_sel_type)(struct meson_gpio_irq_controller *ctl,
> +					  unsigned int idx, u32 val);
>  };
>  
>  struct meson_gpio_irq_params {
> @@ -68,16 +70,17 @@ struct meson_gpio_irq_params {
>  	struct irq_ctl_ops ops;
>  };
>  
> -#define INIT_MESON_COMMON(irqs, init, sel)			\
> +#define INIT_MESON_COMMON(irqs, init, sel, type)		\
>  	.nr_hwirq = irqs,					\
>  	.ops = {						\
>  		.gpio_irq_init = init,				\
>  		.gpio_irq_sel_pin = sel,			\
> +		.gpio_irq_sel_type = type,			\
>  	},
>  
>  #define INIT_MESON8_COMMON_DATA(irqs)				\
>  	INIT_MESON_COMMON(irqs, meson_gpio_irq_init_dummy,	\
> -			  meson8_gpio_irq_sel_pin)		\
> +			  meson8_gpio_irq_sel_pin, NULL)	\
>  	.edge_single_offset = 0,				\
>  	.pol_low_offset = 16,					\
>  	.pin_sel_mask = 0xff,					\
> @@ -85,7 +88,7 @@ struct meson_gpio_irq_params {
>  
>  #define INIT_MESON_A1_COMMON_DATA(irqs)				\
>  	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
> -			  meson_a1_gpio_irq_sel_pin)		\
> +			  meson_a1_gpio_irq_sel_pin, NULL)	\
>  	.support_edge_both = true,				\
>  	.edge_both_offset = 16,					\
>  	.edge_single_offset = 8,				\
> @@ -279,6 +282,10 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
>  	 */
>  	type &= IRQ_TYPE_SENSE_MASK;
>  
> +	/* Some controllers may have different calculation method*/
> +	if (params->ops.gpio_irq_sel_type)
> +		return params->ops.gpio_irq_sel_type(ctl, idx, type);
> +

No. If you are going to indirect these things, indirect them for all
implementations and keep the code clean.

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Sat Jan  8 03:06:42 2022
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 08 Jan 2022 11:06:42 +0000
Subject: [PATCH 4/4] irqchip/meson-gpio: Add support for meson s4 SoCs
In-Reply-To: <20220108084218.31877-5-qianggui.song@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-5-qianggui.song@amlogic.com>
Message-ID: <87r19itrjx.wl-maz@kernel.org>

On Sat, 08 Jan 2022 08:42:18 +0000,
Qianggui Song <qianggui.song at amlogic.com> wrote:
> 
> The meson s4 SoCs support 12 gpio irq lines compared with previous
> serial chips and have something different, details are as below.
> 
> IRQ Number:
> - 80:68 13 pins on bank Z
> - 67:48 20 pins on bank X
> - 47:36 12 pins on bank H
> - 35:24 12 pins on bank D
> - 23:22 2  pins on bank E
> - 21:14 8  pins on bank C
> - 13:0  13 pins on bank B
> 
> - PADCTRL_GPIO_IRQ_CTRL0
>   bit[31]:    enable/disable the whole irq lines

s/the whole/all the/

>   bit[12-23]: single edge trigger
>   bit[0-11]:  poll trigger
> 
> - PADCTRL_GPIO_IRQ_CTRL[X]
> - bit[0-16]: 7 bits to chooge gpio source for irq line 2*[X] - 2

choose?

> - bit[16-22]:7 bits to chooge gpio source for irq line 2*[X] - 1
>   where X = 1-6
> 
> - PADCTRL_GPIO_IRQ_CTRL[7]
>   bit[0-11]: both edge trigger

This information would fit better in the code than in the commit
message.

> 
> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
> ---
>  drivers/irqchip/irq-meson-gpio.c | 51 ++++++++++++++++++++++++++++++++
>  1 file changed, 51 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
> index 98419428fcbd..c5d20a866c37 100644
> --- a/drivers/irqchip/irq-meson-gpio.c
> +++ b/drivers/irqchip/irq-meson-gpio.c
> @@ -42,6 +42,11 @@
>  #define REG_PIN_SEL_SHIFT(x)	(((x) % 4) * 8)
>  #define REG_FILTER_SEL_SHIFT(x)	((x) * 4)
>  
> +/* use for s4 chips */

s/use/Used/

> +#define REG_EDGE_POL_S4	0x1c
> +#define REG_EDGE_POL_MASK_S4(x)				\
> +	({typeof(x) _x = (x); BIT(_x) | BIT(12 + (_x)); })

Why on Earth should this macro handle multiple types?

> +
>  struct meson_gpio_irq_controller;
>  static void meson8_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
>  				    unsigned int channel, unsigned long hwirq);
> @@ -50,6 +55,9 @@ static void meson_a1_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
>  				      unsigned int channel,
>  				      unsigned long hwirq);
>  static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl);
> +static unsigned int
> +meson_s4_gpio_irq_sel_type(struct meson_gpio_irq_controller *ctl,
> +			   unsigned int idx, u32 val);
>  
>  struct irq_ctl_ops {
>  	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
> @@ -96,6 +104,17 @@ struct meson_gpio_irq_params {
>  	.pin_sel_mask = 0x7f,					\
>  	.channel_num = 8,					\
>  
> +#define INIT_MESON_S4_COMMON_DATA(irqs)                         \
> +	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,         \
> +			  meson_a1_gpio_irq_sel_pin,            \
> +			  meson_s4_gpio_irq_sel_type)           \
> +	.support_edge_both = true,				\
> +	.edge_both_offset = 0,					\
> +	.edge_single_offset = 12,				\
> +	.pol_low_offset = 0,					\
> +	.pin_sel_mask = 0xff,					\
> +	.channel_num = 12,					\
> +
>  static const struct meson_gpio_irq_params meson8_params = {
>  	INIT_MESON8_COMMON_DATA(134)
>  };
> @@ -126,6 +145,10 @@ static const struct meson_gpio_irq_params a1_params = {
>  	INIT_MESON_A1_COMMON_DATA(62)
>  };
>  
> +static const struct meson_gpio_irq_params s4_params = {
> +	INIT_MESON_S4_COMMON_DATA(82)
> +};
> +
>  static const struct of_device_id meson_irq_gpio_matches[] = {
>  	{ .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params },
>  	{ .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params },
> @@ -135,6 +158,7 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
>  	{ .compatible = "amlogic,meson-g12a-gpio-intc", .data = &axg_params },
>  	{ .compatible = "amlogic,meson-sm1-gpio-intc", .data = &sm1_params },
>  	{ .compatible = "amlogic,meson-a1-gpio-intc", .data = &a1_params },
> +	{ .compatible = "amlogic,meson-s4-gpio-intc", .data = &s4_params },
>  	{ }
>  };
>  
> @@ -202,6 +226,33 @@ static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl)
>  	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL, BIT(31), BIT(31));
>  }
>  
> +static unsigned int
> +meson_s4_gpio_irq_sel_type(struct meson_gpio_irq_controller *ctl,
> +			   unsigned int idx, unsigned int type)

An 'unsigned int' return type, directly returned by a caller that
has 'int' as its return type. What could possibly go wrong?

> +{
> +	unsigned int val = 0;
> +
> +	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4, BIT(0 + (idx)), 0);

Drop the 0 + as well as the useless bracketing all over this function.

> +
> +	if (type == IRQ_TYPE_EDGE_BOTH) {
> +		val |= BIT(ctl->params->edge_both_offset + (idx));
> +		meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4,
> +					   BIT(ctl->params->edge_both_offset + (idx)), val);
> +		return 0;
> +	}
> +
> +	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
> +		val |= BIT(ctl->params->pol_low_offset + (idx));
> +
> +	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
> +		val |= BIT(ctl->params->edge_single_offset  + (idx));
> +
> +	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
> +				   REG_EDGE_POL_MASK_S4(idx), val);
> +
> +	return 0;
> +};
> +
>  static int
>  meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
>  			       unsigned long  hwirq,

	M.

-- 
Without deviation from the norm, progress is not possible.


From olof at lixom.net  Sat Jan  8 13:26:21 2022
From: olof at lixom.net (Olof Johansson)
Date: Sat, 8 Jan 2022 13:26:21 -0800
Subject: [GIT PULL] amlogic fixes for v5.17-rc
In-Reply-To: <7e40328b-6645-4343-3050-73dcfb2cefcb@baylibre.com>
References: <7e40328b-6645-4343-3050-73dcfb2cefcb@baylibre.com>
Message-ID: <YdoBffKeAvtOeRSe@lx2k>

On Mon, Jan 03, 2022 at 04:13:44PM +0100, Neil Armstrong wrote:
> Hi,
> 
> Here's a couple of DT fixes for v5.17-rc1, they fix the UART compatibles of
> the ARMv7 Amlogic SoCs and by the way keep earlycon working after [1] has been
> applied by greg in the tty branch for 5.17.
> 
> I know it's early for 5.17-rc1, but at least it's in the pipe.
> 
> I based the changes on your dt-5.17 tag pushed to linus for 5.17-rc1,
> if necessary I can rebase on v5.16-rcX.

Hi Neil,

It looks like this branch is based on our arm/dt branch? Please don't base your
topics on our branches, it'll be awkward if we ever need to rebuild them (it's
happened a few times, but we try very hard to avoid it).

In this case, you should have based your contents on top of your latest dt
branch (if it would have had conflicts), not ours.

Mind rebuilding and send a new pull request?

Thanks,


-Olof



From christianshewitt at gmail.com  Sun Jan  9 07:27:25 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Sun, 9 Jan 2022 19:27:25 +0400
Subject: [PATCH 1/4] dt-bindings: interrupt-controller: New binding for
 Meson-S4 SoCs
In-Reply-To: <20220108084218.31877-2-qianggui.song@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-2-qianggui.song@amlogic.com>
Message-ID: <A4441A27-7B49-4A9A-83FD-05144A63E705@gmail.com>


> On 8 Jan 2022, at 12:42 pm, Qianggui Song <qianggui.song at amlogic.com> wrote:
> 
> Update dt-binding document for GPIO interrupt controller of Meson-S4 SoCs
> 
> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
> ---
> .../bindings/interrupt-controller/amlogic,meson-gpio-intc.txt    | 1 +
> 1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
> index 23b18b92c558..9300736bf1ed 100644
> --- a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
> +++ b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
> @@ -18,6 +18,7 @@ Required properties:
>     "amlogic,meson-g12a-gpio-intc" for G12A SoCs (S905D2, S905X2, S905Y2)
>     "amlogic,meson-sm1-gpio-intc" for SM1 SoCs (S905D3, S905X3, S905Y3)
>     "amlogic,meson-a1-gpio-intc" for A1 SoCs (A113L)
> +    "amlogic,meson-a1-gpio-intc" for S4 SoCs (S802X2, S905Y4, S805X2G, S905W2)

^ should be "amlogic,meson-s4-gpio-intc? ?

Christian

> - reg : Specifies base physical address and size of the registers.
> - interrupt-controller : Identifies the node as an interrupt controller.
> - #interrupt-cells : Specifies the number of cells needed to encode an
> -- 
> 2.34.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 



From liang.yang at amlogic.com  Sun Jan  9 19:28:46 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Mon, 10 Jan 2022 11:28:46 +0800
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <e4942f0e-3670-fb52-5cfa-b131a037320a@baylibre.com>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
 <1jfsq1z22l.fsf@starbuckisacylon.baylibre.com>
 <151ded4b-a28b-dac9-31e1-5b817cd9dc44@amlogic.com>
 <e4942f0e-3670-fb52-5cfa-b131a037320a@baylibre.com>
Message-ID: <5fd77688-922c-d8f4-1a09-41967fa52f89@amlogic.com>

Hi,

On 2022/1/7 17:57, Neil Armstrong wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi,
> 
> On 07/01/2022 05:04, Liang Yang wrote:
>> Hi Jerome,
>>
>> On 2022/1/6 16:16, Jerome Brunet wrote:
>>> [ EXTERNAL EMAIL ]
>>>
>>>
>>> On Thu 06 Jan 2022 at 11:25, Liang Yang <liang.yang at amlogic.com> wrote:
>>>
>>>> Because EMMC and NAND have the same control clock register, so we
>>>> implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:
>>>>
>>>>  ????sd_emmc_c_clkc: mmc at 7000 {
>>>>  ??????? compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
>>>>  ??????? reg = <0x0 0x7000 0x0 0x800>;
>>>>  ????};
>>>>
>>>>  ????nand-controller at 7800 {
>>>>  ??????? ......
>>>>
>>>>  ??????? clocks = <&clkc CLKID_SD_EMMC_C>,
>>>>  ??????????? <&sd_emmc_c_clkc CLKID_MMC_DIV>,
>>>>  ??????????? <&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
>>>>  ??????????? <&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
>>>>  ??????? clock-names = "core", "device", "rx", "tx";
>>>>  ??????? amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>>>>
>>>>  ??????? ......
>>>>  ????}
>>>>
>>>> but in fact, above implementation is rejected. so now registering
>>>> a nand_divider.
>>>
>>> Can you give a bit of context ? a link to the discussion rejecting this
>>>
>> Maybe I mistake the meaning of [jianxin.pan at amlogic.com], so i need him to clarify it.
>>> As far as remember, things were getting done for A1 and stopped before
>>> clock part was finished. I'm saying the change is wrong, just that a
>>> discussion is needed before a decision is made.
>>>
>> ok.
>> previous discussion in this link:
>> https://lore.kernel.org/all/86789d73-5a6c-7729-ecd1-dcd342b2fcde at amlogic.com/
>> it never go on since v6.
> 
> Looking at the serie I don't see any major blockers, if you're willing to take ownership
> of this patchset and send a v6 with all issues/comments addressed, it would be easier than
> restarting the whole design discussion
> 
> Neil


Hi Neil, thanks for your advice.
After talking with [jianxin.pan], form this link 
<https://lkml.org/lkml/2019/1/8/441>, it already moves futher and on v9, 
so we decide to continue to work hard on it.

> 
>>
>>>>
>>>> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
>>>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>>>> ---
>>>>  ? drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
>>>>  ? 1 file changed, 49 insertions(+), 39 deletions(-)
>>>>
>>>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>>>> index ac3be92872d0..4472363059c2 100644
>>>> --- a/drivers/mtd/nand/raw/meson_nand.c
>>>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>>>> @@ -2,7 +2,7 @@
>>>>  ? /*
>>>>  ?? * Amlogic Meson Nand Flash Controller Driver
>>>>  ?? *
>>>> - * Copyright (c) 2018 Amlogic, inc.
>>>> + * Copyright (c) 2018-2021 Amlogic, inc.
>>>>  ?? * Author: Liang Yang <liang.yang at amlogic.com>
>>>>  ?? */
>>>>  ? @@ -10,6 +10,7 @@
>>>>  ? #include <linux/dma-mapping.h>
>>>>  ? #include <linux/interrupt.h>
>>>>  ? #include <linux/clk.h>
>>>> +#include <linux/clk-provider.h>
>>>>  ? #include <linux/mtd/rawnand.h>
>>>>  ? #include <linux/mtd/mtd.h>
>>>>  ? #include <linux/mfd/syscon.h>
>>>> @@ -55,6 +56,7 @@
>>>>  ? #define NFC_REG_VER??????? 0x38
>>>>  ? ? #define NFC_RB_IRQ_EN??????? BIT(21)
>>>> +#define NFC_CMD_FIFO_RESET??? BIT(31)
>>>>  ? ? #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)??? \
>>>>  ????? (??????????????????????????????? \
>>>> @@ -104,6 +106,9 @@
>>>>  ? ? #define PER_INFO_BYTE??????? 8
>>>>  ? +#define CLK_DIV_SHIFT??????? 0
>>>> +#define CLK_DIV_WIDTH??????? 6
>>>> +
>>>>  ? struct meson_nfc_nand_chip {
>>>>  ????? struct list_head node;
>>>>  ????? struct nand_chip nand;
>>>> @@ -151,15 +156,15 @@ struct meson_nfc {
>>>>  ????? struct nand_controller controller;
>>>>  ????? struct clk *core_clk;
>>>>  ????? struct clk *device_clk;
>>>> -??? struct clk *phase_tx;
>>>> -??? struct clk *phase_rx;
>>>
>>> I would have been nice to explain why these clock are no longer
>>> required, in the change description maybe ?
>>
>> i got the reply from our vlsi members that rx and tx doesn't make sense to meson NFC timing. so previous commit about this should be wrong.
>>>
>>>> +??? struct clk *nand_clk;
>>>> +??? struct clk_divider nand_divider;
>>>>  ? ????? unsigned long clk_rate;
>>>>  ????? u32 bus_timing;
>>>>  ? ????? struct device *dev;
>>>>  ????? void __iomem *reg_base;
>>>> -??? struct regmap *reg_clk;
>>>> +??? void __iomem *reg_clk;
>>>>  ????? struct completion completion;
>>>>  ????? struct list_head chips;
>>>>  ????? const struct meson_nfc_data *data;
>>>> @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
>>>>  ????? cmd = NFC_CMD_RB | NFC_CMD_RB_INT
>>>>  ????????? | nfc->param.chip_select | nfc->timing.tbers_max;
>>>>  ????? writel(cmd, nfc->reg_base + NFC_REG_CMD);
>>>> -
>>>> +??? meson_nfc_drain_cmd(nfc);
>>>
>>> is this clock related ?
>> ok, i will split it in another patch.
>>>
>>>>  ????? ret = wait_for_completion_timeout(&nfc->completion,
>>>>  ??????????????????????? msecs_to_jiffies(timeout_ms));
>>>>  ????? if (ret == 0)
>>>>  ????????? ret = -1;
>>>>  ? +??? /* reset command fifo to avoid lock */
>>>> +??? writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);
>>>
>>> Again, not seem to be clock related - does not belong in this patch
>> ok, i will split it in another patch.
>>>
>>>>  ????? return ret;
>>>>  ? }
>>>>  ? @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
>>>>  ? static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>>  ? {
>>>>  ????? int ret;
>>>> +??? struct clk_init_data init = {0};
>>>> +??? const char *fix_div2_pll_name[1];
>>>>  ? -??? /* request core clock */
>>>
>>> Why is the comment bothering you ?
>>>
>>>>  ????? nfc->core_clk = devm_clk_get(nfc->dev, "core");
>>>>  ????? if (IS_ERR(nfc->core_clk)) {
>>>>  ????????? dev_err(nfc->dev, "failed to get core clock\n");
>>>> @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>>  ????????? return PTR_ERR(nfc->device_clk);
>>>>  ????? }
>>>>  ? -??? nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
>>>> -??? if (IS_ERR(nfc->phase_tx)) {
>>>> -??????? dev_err(nfc->dev, "failed to get TX clk\n");
>>>> -??????? return PTR_ERR(nfc->phase_tx);
>>>> -??? }
>>>> -
>>>> -??? nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
>>>> -??? if (IS_ERR(nfc->phase_rx)) {
>>>> -??????? dev_err(nfc->dev, "failed to get RX clk\n");
>>>> -??????? return PTR_ERR(nfc->phase_rx);
>>>> -??? }
>>>> +??? init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
>>>> +??? init.ops = &clk_divider_ops;
>>>> +??? fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);
>>>
>>> You should be using "fw_name" so CCF looks a DT directly, instead of this
>> ok
>>>
>>>> +??? init.parent_names = fix_div2_pll_name;
>>>> +??? init.num_parents = 1;
>>>> +??? nfc->nand_divider.reg = nfc->reg_clk;
>>>> +??? nfc->nand_divider.shift = CLK_DIV_SHIFT;
>>>> +??? nfc->nand_divider.width = CLK_DIV_WIDTH;
>>>> +??? nfc->nand_divider.hw.init = &init;
>>>> +??? nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
>>>> +????????????????? CLK_DIVIDER_ROUND_CLOSEST |
>>>> +??????????????????????? CLK_DIVIDER_ALLOW_ZERO;
>>>> +
>>>> +??? nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
>>>> +??? if (IS_ERR(nfc->nand_clk))
>>>> +??????? return PTR_ERR(nfc->nand_clk);
>>>>  ? ????? /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
>>>> -??? regmap_update_bits(nfc->reg_clk,
>>>> -?????????????? 0, CLK_SELECT_NAND, CLK_SELECT_NAND);
>>>> +??? writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
>>>>  ? ????? ret = clk_prepare_enable(nfc->core_clk);
>>>>  ????? if (ret) {
>>>> @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>>  ????????? goto err_device_clk;
>>>>  ????? }
>>>>  ? -??? ret = clk_prepare_enable(nfc->phase_tx);
>>>> +??? ret = clk_prepare_enable(nfc->nand_clk);
>>>>  ????? if (ret) {
>>>> -??????? dev_err(nfc->dev, "failed to enable TX clock\n");
>>>> -??????? goto err_phase_tx;
>>>> -??? }
>>>> -
>>>> -??? ret = clk_prepare_enable(nfc->phase_rx);
>>>> -??? if (ret) {
>>>> -??????? dev_err(nfc->dev, "failed to enable RX clock\n");
>>>> -??????? goto err_phase_rx;
>>>> +??????? dev_err(nfc->dev, "pre enable NFC divider fail\n");
>>>> +??????? goto err_nand_clk;
>>>>  ????? }
>>>>  ? ????? ret = clk_set_rate(nfc->device_clk, 24000000);
>>>>  ????? if (ret)
>>>> -??????? goto err_disable_rx;
>>>> +??????? goto err_disable_clk;
>>>>  ? ????? return 0;
>>>>  ? -err_disable_rx:
>>>> -??? clk_disable_unprepare(nfc->phase_rx);
>>>> -err_phase_rx:
>>>> -??? clk_disable_unprepare(nfc->phase_tx);
>>>> -err_phase_tx:
>>>> +err_disable_clk:
>>>> +??? clk_disable_unprepare(nfc->nand_clk);
>>>> +err_nand_clk:
>>>>  ????? clk_disable_unprepare(nfc->device_clk);
>>>>  ? err_device_clk:
>>>>  ????? clk_disable_unprepare(nfc->core_clk);
>>>> @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>>  ? ? static void meson_nfc_disable_clk(struct meson_nfc *nfc)
>>>>  ? {
>>>> -??? clk_disable_unprepare(nfc->phase_rx);
>>>> -??? clk_disable_unprepare(nfc->phase_tx);
>>>> +??? clk_disable_unprepare(nfc->nand_clk);
>>>>  ????? clk_disable_unprepare(nfc->device_clk);
>>>>  ????? clk_disable_unprepare(nfc->core_clk);
>>>>  ? }
>>>> @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>>>  ????? struct device *dev = &pdev->dev;
>>>>  ????? struct meson_nfc *nfc;
>>>>  ????? struct resource *res;
>>>> +??? u32 ext_clk_reg;
>>>>  ????? int ret, irq;
>>>>  ? ????? nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
>>>> @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>>>  ????? if (IS_ERR(nfc->reg_base))
>>>>  ????????? return PTR_ERR(nfc->reg_base);
>>>>  ? -??? nfc->reg_clk =
>>>> -??????? syscon_regmap_lookup_by_phandle(dev->of_node,
>>>> -??????????????????????? "amlogic,mmc-syscon");
>>>> +??? ret = of_property_read_u32(pdev->dev.of_node,
>>>> +?????????????????? "sd_emmc_c_clkc",
>>>> +?????????????????? &ext_clk_reg);
>>>> +??? if (ret) {
>>>> +??????? dev_err(dev, "failed to get NAND external clock register\n");
>>>> +??????? return ret;
>>>> +??? }
>>>> +
>>>> +??? nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));
>>>
>>> That's how you should get a register region.
>>> If you want an example of a device claiming several region on amlogic,
>>> have a look at the pinctrl driver.
>> ok
>>>
>>>>  ????? if (IS_ERR(nfc->reg_clk)) {
>>>>  ????????? dev_err(dev, "Failed to lookup clock base\n");
>>>>  ????????? return PTR_ERR(nfc->reg_clk);
>>>
>>> .
> 
> .


From liang.yang at amlogic.com  Sun Jan  9 19:32:52 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Mon, 10 Jan 2022 11:32:52 +0800
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <1jh7agou4i.fsf@starbuckisacylon.baylibre.com>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
 <20220106090832.42225c49@xps13>
 <9c7b1d77-cff1-b40c-6d02-f67ca8b9b683@amlogic.com>
 <1jh7agou4i.fsf@starbuckisacylon.baylibre.com>
Message-ID: <b3e5cec5-9eed-a2cd-ee0b-7e49672cc9f6@amlogic.com>

Hello Jerome,

On 2022/1/7 15:54, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> 
> On Fri 07 Jan 2022 at 10:40, Liang Yang <liang.yang at amlogic.com> wrote:
> 
>> Hi Miquel,
>>
>> Meson NFC clock depends on the implementation of sd_emmc_c_clkc, but i
>> don't find the commit in
>> linux mainline. then the information i got from [jianxin.pan at amlogic.com]
>> is the rejection of
>> serial patches. I just look into the corresponding emails in link:
>>
>> https://lore.kernel.org/all/86789d73-5a6c-7729-ecd1-dcd342b2fcde at amlogic.com/
>> it seems the patch never go on since V6, so [jianxin.pan at amlogic.com],
>> could you help to clear it?
>> let us address the discussion in another email from
>> [jbrunet at baylibre.com].
> 
> That V6 was "rejected" because some comments from thre V5 were still not
> addressed.
> 
em, we decide to continue to work on sd_emmc_c_clkc and it already has a 
longer trip, see this link <https://lkml.org/lkml/2019/1/8/441>. thanks.

>>
>> On 2022/1/6 16:08, Miquel Raynal wrote:
>>> [ EXTERNAL EMAIL ]
>>> Hi Liang,
>>> liang.yang at amlogic.com wrote on Thu, 6 Jan 2022 11:25:04 +0800:
>>>
>>>> Because EMMC and NAND have the same control clock register, so we
>>>> implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:
>>>>
>>>> 	sd_emmc_c_clkc: mmc at 7000 {
>>>> 		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
>>>> 		reg = <0x0 0x7000 0x0 0x800>;
>>>> 	};
>>>>
>>>> 	nand-controller at 7800 {
>>>> 		......
>>>>
>>>> 		clocks = <&clkc CLKID_SD_EMMC_C>,
>>>> 			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
>>>> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
>>>> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
>>>> 		clock-names = "core", "device", "rx", "tx";
>>>> 		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>>>>
>>>> 		......
>>>> 	}
>>>>
>>>> but in fact, above implementation is rejected. so now registering
>>>> a nand_divider.
>>> What is rejected?
>>> Why is it rejected?
>>> What is nand_divider?
>> i simplify our clock framework below, so nand divider is SD_EMMC_CLOCK[5:0]
>> here.
>> 			   -----          -----		    -----
>> 	   the other------|	\        |     |	   |	 |
>>           		  | mux	| -----  |  N  | ----------| NFC/|
>> 	   FCLK_DIV2------|     |        |     |	   | EMMC|
>> 			   -----/         ----- 	    -----
>> 		    SD_EMMC_CLOCK[7:6] SD_EMMC_CLOCK[5:0]
>>>
>>>>
>>>> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
>>> Change Ids are not expected in the upstream kernel.
>>> But if you fix something you should have a Fixes:.
>>>
>>>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>>>> ---
>>>>    drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
>>>>    1 file changed, 49 insertions(+), 39 deletions(-)
>>>>
>>>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>>>> index ac3be92872d0..4472363059c2 100644
>>>> --- a/drivers/mtd/nand/raw/meson_nand.c
>>>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>>>> @@ -2,7 +2,7 @@
>>>>    /*
>>>>     * Amlogic Meson Nand Flash Controller Driver
>>>>     *
>>>> - * Copyright (c) 2018 Amlogic, inc.
>>>> + * Copyright (c) 2018-2021 Amlogic, inc.
>>>>     * Author: Liang Yang <liang.yang at amlogic.com>
>>>>     */
>>>>    @@ -10,6 +10,7 @@
>>>>    #include <linux/dma-mapping.h>
>>>>    #include <linux/interrupt.h>
>>>>    #include <linux/clk.h>
>>>> +#include <linux/clk-provider.h>
>>>>    #include <linux/mtd/rawnand.h>
>>>>    #include <linux/mtd/mtd.h>
>>>>    #include <linux/mfd/syscon.h>
>>>> @@ -55,6 +56,7 @@
>>>>    #define NFC_REG_VER		0x38
>>>>      #define NFC_RB_IRQ_EN		BIT(21)
>>>> +#define NFC_CMD_FIFO_RESET	BIT(31)
>>>>      #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)
>>>> \
>>>>    	(								\
>>>> @@ -104,6 +106,9 @@
>>>>      #define PER_INFO_BYTE		8
>>>>    +#define CLK_DIV_SHIFT		0
>>>> +#define CLK_DIV_WIDTH		6
>>>> +
>>>>    struct meson_nfc_nand_chip {
>>>>    	struct list_head node;
>>>>    	struct nand_chip nand;
>>>> @@ -151,15 +156,15 @@ struct meson_nfc {
>>>>    	struct nand_controller controller;
>>>>    	struct clk *core_clk;
>>>>    	struct clk *device_clk;
>>>> -	struct clk *phase_tx;
>>>> -	struct clk *phase_rx;
>>>> +	struct clk *nand_clk;
>>>> +	struct clk_divider nand_divider;
>>>>      	unsigned long clk_rate;
>>>>    	u32 bus_timing;
>>>>      	struct device *dev;
>>>>    	void __iomem *reg_base;
>>>> -	struct regmap *reg_clk;
>>>> +	void __iomem *reg_clk;
>>>>    	struct completion completion;
>>>>    	struct list_head chips;
>>>>    	const struct meson_nfc_data *data;
>>>> @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
>>>>    	cmd = NFC_CMD_RB | NFC_CMD_RB_INT
>>>>    		| nfc->param.chip_select | nfc->timing.tbers_max;
>>>>    	writel(cmd, nfc->reg_base + NFC_REG_CMD);
>>>> -
>>>> +	meson_nfc_drain_cmd(nfc);
>>>>    	ret = wait_for_completion_timeout(&nfc->completion,
>>>>    					  msecs_to_jiffies(timeout_ms));
>>>>    	if (ret == 0)
>>>>    		ret = -1;
>>>>    +	/* reset command fifo to avoid lock */
>>>> +	writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);
>>>>    	return ret;
>>>>    }
>>>>    @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops
>>>> meson_ooblayout_ops = {
>>>>    static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>>    {
>>>>    	int ret;
>>>> +	struct clk_init_data init = {0};
>>>> +	const char *fix_div2_pll_name[1];
>>>>    -	/* request core clock */
>>>>    	nfc->core_clk = devm_clk_get(nfc->dev, "core");
>>>>    	if (IS_ERR(nfc->core_clk)) {
>>>>    		dev_err(nfc->dev, "failed to get core clock\n");
>>>> @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>>    		return PTR_ERR(nfc->device_clk);
>>>>    	}
>>>>    -	nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
>>>> -	if (IS_ERR(nfc->phase_tx)) {
>>>> -		dev_err(nfc->dev, "failed to get TX clk\n");
>>>> -		return PTR_ERR(nfc->phase_tx);
>>>> -	}
>>>> -
>>>> -	nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
>>>> -	if (IS_ERR(nfc->phase_rx)) {
>>>> -		dev_err(nfc->dev, "failed to get RX clk\n");
>>>> -		return PTR_ERR(nfc->phase_rx);
>>>> -	}
>>>> +	init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
>>>> +	init.ops = &clk_divider_ops;
>>>> +	fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);
>>>> +	init.parent_names = fix_div2_pll_name;
>>>> +	init.num_parents = 1;
>>>> +	nfc->nand_divider.reg = nfc->reg_clk;
>>>> +	nfc->nand_divider.shift = CLK_DIV_SHIFT;
>>>> +	nfc->nand_divider.width = CLK_DIV_WIDTH;
>>>> +	nfc->nand_divider.hw.init = &init;
>>>> +	nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
>>>> +				  CLK_DIVIDER_ROUND_CLOSEST |
>>>> +          			  CLK_DIVIDER_ALLOW_ZERO;
>>>> +
>>>> +	nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
>>>> +	if (IS_ERR(nfc->nand_clk))
>>>> +		return PTR_ERR(nfc->nand_clk);
>>>>      	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
>>>> -	regmap_update_bits(nfc->reg_clk,
>>>> -			   0, CLK_SELECT_NAND, CLK_SELECT_NAND);
>>>> +	writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
>>>>      	ret = clk_prepare_enable(nfc->core_clk);
>>>>    	if (ret) {
>>>> @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>>    		goto err_device_clk;
>>>>    	}
>>>>    -	ret = clk_prepare_enable(nfc->phase_tx);
>>>> +	ret = clk_prepare_enable(nfc->nand_clk);
>>>>    	if (ret) {
>>>> -		dev_err(nfc->dev, "failed to enable TX clock\n");
>>>> -		goto err_phase_tx;
>>>> -	}
>>>> -
>>>> -	ret = clk_prepare_enable(nfc->phase_rx);
>>>> -	if (ret) {
>>>> -		dev_err(nfc->dev, "failed to enable RX clock\n");
>>>> -		goto err_phase_rx;
>>>> +		dev_err(nfc->dev, "pre enable NFC divider fail\n");
>>>> +		goto err_nand_clk;
>>>>    	}
>>>>      	ret = clk_set_rate(nfc->device_clk, 24000000);
>>>>    	if (ret)
>>>> -		goto err_disable_rx;
>>>> +		goto err_disable_clk;
>>>>      	return 0;
>>>>    -err_disable_rx:
>>>> -	clk_disable_unprepare(nfc->phase_rx);
>>>> -err_phase_rx:
>>>> -	clk_disable_unprepare(nfc->phase_tx);
>>>> -err_phase_tx:
>>>> +err_disable_clk:
>>>> +	clk_disable_unprepare(nfc->nand_clk);
>>>> +err_nand_clk:
>>>>    	clk_disable_unprepare(nfc->device_clk);
>>>>    err_device_clk:
>>>>    	clk_disable_unprepare(nfc->core_clk);
>>>> @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>>      static void meson_nfc_disable_clk(struct meson_nfc *nfc)
>>>>    {
>>>> -	clk_disable_unprepare(nfc->phase_rx);
>>>> -	clk_disable_unprepare(nfc->phase_tx);
>>>> +	clk_disable_unprepare(nfc->nand_clk);
>>>>    	clk_disable_unprepare(nfc->device_clk);
>>>>    	clk_disable_unprepare(nfc->core_clk);
>>>>    }
>>>> @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>>>    	struct device *dev = &pdev->dev;
>>>>    	struct meson_nfc *nfc;
>>>>    	struct resource *res;
>>>> +	u32 ext_clk_reg;
>>>>    	int ret, irq;
>>>>      	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
>>>> @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>>>    	if (IS_ERR(nfc->reg_base))
>>>>    		return PTR_ERR(nfc->reg_base);
>>>>    -	nfc->reg_clk =
>>>> -		syscon_regmap_lookup_by_phandle(dev->of_node,
>>>> -						"amlogic,mmc-syscon");
>>>> +	ret = of_property_read_u32(pdev->dev.of_node,
>>>> +				   "sd_emmc_c_clkc",
>>>> +				   &ext_clk_reg);
>>>> +	if (ret) {
>>>> +		dev_err(dev, "failed to get NAND external clock register\n");
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));
>>>>    	if (IS_ERR(nfc->reg_clk)) {
>>>>    		dev_err(dev, "Failed to lookup clock base\n");
>>>>    		return PTR_ERR(nfc->reg_clk);
>>>
>>> Thanks,
>>> Miqu?l
>>> .
> 
> .


From yu.tu at amlogic.com  Mon Jan 10 00:26:09 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:26:09 +0800
Subject: [PATCH 1/2] dt-bindings: serial: meson: Drop compatible = amlogic,
 meson-gx-uart.
Message-ID: <20220110082616.13474-1-yu.tu@amlogic.com>

Deprecated, don't use anymore because compatible =
amlogic,meson-gx-uart. Don't differentiate between GXBB, GXL
and G12A which have different revisions of the UART IP.
So it's split into GXBB, GXL and G12A.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 .../devicetree/bindings/serial/amlogic,meson-uart.yaml | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
index 72e8868db3e0..ad9f1f4537a0 100644
--- a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
+++ b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
@@ -28,7 +28,10 @@ properties:
               - amlogic,meson6-uart
               - amlogic,meson8-uart
               - amlogic,meson8b-uart
-              - amlogic,meson-gx-uart
+              - amlogic,meson-gx-uart # deprecated, use revision specific property below
+              - amlogic,meson-gxbb-uart
+              - amlogic,meson-gxl-uart
+              - amlogic,meson-g12a-uart
               - amlogic,meson-s4-uart
           - const: amlogic,meson-ao-uart
       - description: Everything-Else power domain UART controller
@@ -36,7 +39,10 @@ properties:
           - amlogic,meson6-uart
           - amlogic,meson8-uart
           - amlogic,meson8b-uart
-          - amlogic,meson-gx-uart
+          - amlogic,meson-gx-uart # deprecated, use revision specific property below
+          - amlogic,meson-gxbb-uart
+          - amlogic,meson-gxl-uart
+          - amlogic,meson-g12a-uart
           - amlogic,meson-s4-uart
 
   reg:

base-commit: 99a507a8ea28542ec196e2dd80096708e2482735
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:26:10 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:26:10 +0800
Subject: [PATCH] tty: serial: meson: Change request_irq to devm_request_irq
 and move devm_request_irq to meson_uart_probe()
In-Reply-To: <20220110082616.13474-1-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
Message-ID: <20220110082616.13474-2-yu.tu@amlogic.com>

Because an interrupt error occurs when the user opens /dev/ttyAML* but
don't close it, and then opens the same port again. This problem is
encountered in actual projects.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 45e41f20cba3..0dd3f5b35768 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -135,8 +135,6 @@ static void meson_uart_shutdown(struct uart_port *port)
 	unsigned long flags;
 	u32 val;
 
-	free_irq(port->irq, port);
-
 	spin_lock_irqsave(&port->lock, flags);
 
 	val = readl(port->membase + AML_UART_CONTROL);
@@ -284,7 +282,6 @@ static void meson_uart_reset(struct uart_port *port)
 static int meson_uart_startup(struct uart_port *port)
 {
 	u32 val;
-	int ret;
 
 	meson_uart_reset(port);
 
@@ -298,10 +295,7 @@ static int meson_uart_startup(struct uart_port *port)
 	val = (AML_UART_RECV_IRQ(1) | AML_UART_XMIT_IRQ(port->fifosize / 2));
 	writel(val, port->membase + AML_UART_MISC);
 
-	ret = request_irq(port->irq, meson_uart_interrupt, 0,
-			  port->name, port);
-
-	return ret;
+	return 0;
 }
 
 static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
@@ -908,6 +902,14 @@ static int meson_uart_probe(struct platform_device *pdev)
 	meson_ports[pdev->id] = port;
 	platform_set_drvdata(pdev, port);
 
+	ret = devm_request_irq(&pdev->dev, port->irq, meson_uart_interrupt,
+			       0, dev_name(&pdev->dev), port);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to request uart irq: %d\n",
+			ret);
+		return ret;
+	}
+
 	/* reset port before registering (and possibly registering console) */
 	meson_uart_reset(port);
 

base-commit: b3a9e3b9622ae10064826dccb4f7a52bd88c7407
prerequisite-patch-id: 97a514f3447511cb204179ce03ae99dc1d5902d9
prerequisite-patch-id: a2e4756ff85f0df0efe111d7e2cb51b8e26e226f
prerequisite-patch-id: af9e3acc8f6ff7602d3a68a57c008e5ec362b353
prerequisite-patch-id: 7af8c81b4c2163240725e96625b1487c280f4f30
prerequisite-patch-id: 8791f6362b14e7c4ff4f85cce550f06abeb1af7a
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:26:11 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:26:11 +0800
Subject: [PATCH] tty: serial: meson: Make the bit24 and bit [26,
 27] of the UART_REG5 register writable
In-Reply-To: <20220110082616.13474-1-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
Message-ID: <20220110082616.13474-3-yu.tu@amlogic.com>

The UART_REG5 register defaults to 0. The console port is set in
ROMCODE. But other UART ports default to 0, so make bit24 and
bit[26,27] writable so that the UART can choose a more
appropriate clock.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 7c3f30cea68e..b0551750dff8 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -693,7 +693,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
 							CLK_SET_RATE_NO_REPARENT,
 							port->membase + AML_UART_REG5,
 							26, 2,
-							CLK_DIVIDER_READ_ONLY,
+							CLK_DIVIDER_ROUND_CLOSEST,
 							xtal_div_table, NULL);
 		if (IS_ERR(hw))
 			return PTR_ERR(hw);
@@ -719,7 +719,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
 					CLK_SET_RATE_PARENT,
 					port->membase + AML_UART_REG5,
 					24, 0x1,
-					CLK_MUX_READ_ONLY,
+					CLK_MUX_ROUND_CLOSEST,
 					NULL, NULL);
 	if (IS_ERR(hw))
 		return PTR_ERR(hw);

base-commit: 93a770b7e16772530196674ffc79bb13fa927dc6
prerequisite-patch-id: 95191c926509964c8e9bf4128b8bbad8a277b84a
prerequisite-patch-id: a2e4756ff85f0df0efe111d7e2cb51b8e26e226f
prerequisite-patch-id: 4e4d909acabcb7533da20e2207207be73454a88c
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:26:12 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:26:12 +0800
Subject: [PATCH] tty: serial: meson: meson_uart_shutdown omit clear
 AML_UART_TX_EN bit
In-Reply-To: <20220110082616.13474-1-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
Message-ID: <20220110082616.13474-4-yu.tu@amlogic.com>

This change is an improvement. The meson_uart_shutdown function
should have the opposite operation to the meson_uart_startup
function, but the meson_uart_shutdown of AML_UART_TX_EN is logically
missing.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 9b07e3534969..c17109d6d441 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -140,7 +140,7 @@ static void meson_uart_shutdown(struct uart_port *port)
 	spin_lock_irqsave(&port->lock, flags);
 
 	val = readl(port->membase + AML_UART_CONTROL);
-	val &= ~AML_UART_RX_EN;
+	val &= ~(AML_UART_RX_EN | AML_UART_TX_EN);
 	val &= ~(AML_UART_RX_INT_EN | AML_UART_TX_INT_EN);
 	writel(val, port->membase + AML_UART_CONTROL);
 

base-commit: b3a9e3b9622ae10064826dccb4f7a52bd88c7407
prerequisite-patch-id: 97a514f3447511cb204179ce03ae99dc1d5902d9
prerequisite-patch-id: a2e4756ff85f0df0efe111d7e2cb51b8e26e226f
prerequisite-patch-id: af9e3acc8f6ff7602d3a68a57c008e5ec362b353
prerequisite-patch-id: a44e5da7009d9b815eb87395cbd7d14e7d953a09
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:26:13 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:26:13 +0800
Subject: [PATCH] tty: serial: meson: Request the register region in
 meson_uart_probe()
In-Reply-To: <20220110082616.13474-1-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
Message-ID: <20220110082616.13474-5-yu.tu@amlogic.com>

This simplifies resetting the UART controller during probe and will make
it easier to integrate the common clock code which will require the
registers at probe time as well.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 24 ++++++------------------
 1 file changed, 6 insertions(+), 18 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index c9a37602ffd0..99efe62a1507 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -397,24 +397,11 @@ static int meson_uart_verify_port(struct uart_port *port,
 
 static void meson_uart_release_port(struct uart_port *port)
 {
-	devm_iounmap(port->dev, port->membase);
-	port->membase = NULL;
-	devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
+	/* nothing to do */
 }
 
 static int meson_uart_request_port(struct uart_port *port)
 {
-	if (!devm_request_mem_region(port->dev, port->mapbase, port->mapsize,
-				     dev_name(port->dev))) {
-		dev_err(port->dev, "Memory region busy\n");
-		return -EBUSY;
-	}
-
-	port->membase = devm_ioremap(port->dev, port->mapbase,
-					     port->mapsize);
-	if (!port->membase)
-		return -ENOMEM;
-
 	return 0;
 }
 
@@ -728,6 +715,10 @@ static int meson_uart_probe(struct platform_device *pdev)
 	if (!port)
 		return -ENOMEM;
 
+	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
+	if (IS_ERR(port->membase))
+		return PTR_ERR(port->membase);
+
 	ret = meson_uart_probe_clocks(pdev, port);
 	if (ret)
 		return ret;
@@ -749,10 +740,7 @@ static int meson_uart_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, port);
 
 	/* reset port before registering (and possibly registering console) */
-	if (meson_uart_request_port(port) >= 0) {
-		meson_uart_reset(port);
-		meson_uart_release_port(port);
-	}
+	meson_uart_reset(port);
 
 	ret = uart_add_one_port(&meson_uart_driver, port);
 	if (ret)

base-commit: b3a9e3b9622ae10064826dccb4f7a52bd88c7407
prerequisite-patch-id: 97a514f3447511cb204179ce03ae99dc1d5902d9
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:26:14 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:26:14 +0800
Subject: [PATCH 1/2] tty: serial: meson: The UART baud rate calculation is
 described using the common clock code.
In-Reply-To: <20220110082616.13474-1-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
Message-ID: <20220110082616.13474-6-yu.tu@amlogic.com>

Using the common Clock code to describe the UART baud rate clock
makes it easier for the UART driver to be compatible with the
baud rate requirements of the UART IP on different meson chips.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
 1 file changed, 163 insertions(+), 61 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 7570958d010c..1004fd0b0c9e 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -65,9 +66,7 @@
 #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
 
 /* AML_UART_REG5 bits */
-#define AML_UART_BAUD_MASK		0x7fffff
 #define AML_UART_BAUD_USE		BIT(23)
-#define AML_UART_BAUD_XTAL		BIT(24)
 
 #define AML_UART_PORT_NUM		12
 #define AML_UART_PORT_OFFSET		6
@@ -76,6 +75,13 @@
 #define AML_UART_POLL_USEC		5
 #define AML_UART_TIMEOUT_USEC		10000
 
+struct meson_uart_data {
+	struct uart_port	port;
+	struct clk		*pclk;
+	struct clk		*baud_clk;
+	bool			use_xtal_clk;
+};
+
 static struct uart_driver meson_uart_driver;
 
 static struct uart_port *meson_ports[AML_UART_PORT_NUM];
@@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
 static int meson_uart_startup(struct uart_port *port)
 {
 	u32 val;
-	int ret = 0;
+	int ret;
 
-	val = readl(port->membase + AML_UART_CONTROL);
-	val |= AML_UART_CLEAR_ERR;
-	writel(val, port->membase + AML_UART_CONTROL);
-	val &= ~AML_UART_CLEAR_ERR;
-	writel(val, port->membase + AML_UART_CONTROL);
+	meson_uart_reset(port);
 
+	val = readl(port->membase + AML_UART_CONTROL);
 	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
 	writel(val, port->membase + AML_UART_CONTROL);
 
@@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port *port)
 
 static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
 {
+	struct meson_uart_data *private_data = port->private_data;
 	u32 val;
 
 	while (!meson_uart_tx_empty(port))
 		cpu_relax();
 
-	if (port->uartclk == 24000000) {
-		val = ((port->uartclk / 3) / baud) - 1;
-		val |= AML_UART_BAUD_XTAL;
-	} else {
-		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
-	}
+	val = readl(port->membase + AML_UART_REG5);
 	val |= AML_UART_BAUD_USE;
 	writel(val, port->membase + AML_UART_REG5);
+
+	clk_set_rate(private_data->baud_clk, baud);
 }
 
 static void meson_uart_set_termios(struct uart_port *port,
@@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
 
 static void meson_uart_release_port(struct uart_port *port)
 {
-	/* nothing to do */
+	struct meson_uart_data *private_data = port->private_data;
+
+	clk_disable_unprepare(private_data->baud_clk);
+	clk_disable_unprepare(private_data->pclk);
 }
 
 static int meson_uart_request_port(struct uart_port *port)
 {
+	struct meson_uart_data *private_data = port->private_data;
+	int ret;
+
+	ret = clk_prepare_enable(private_data->pclk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(private_data->baud_clk);
+	if (ret) {
+		clk_disable_unprepare(private_data->pclk);
+		return ret;
+	}
+
 	return 0;
 }
 
@@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
 	.cons		= MESON_SERIAL_CONSOLE,
 };
 
-static inline struct clk *meson_uart_probe_clock(struct device *dev,
-						 const char *id)
+#define CLK_NAME(name) \
+({\
+	char clk_name[32];\
+	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
+	clk_name;\
+})
+
+static struct clk_div_table xtal_div_table[] = {
+	{ 0, 3  },
+	{ 1, 1  },
+	{ 2, 2  },
+	{ 3, 2  },
+};
+
+static int meson_uart_probe_clocks(struct uart_port *port)
 {
-	struct clk *clk = NULL;
-	int ret;
+	struct meson_uart_data *private_data = port->private_data;
+	struct clk *clk_baud, *clk_xtal;
+	struct clk_hw *hw;
+	struct clk_parent_data use_xtal_mux_parents[2] = {
+		{ .index = -1, },
+		{ .index = -1, },
+	};
 
-	clk = devm_clk_get(dev, id);
-	if (IS_ERR(clk))
-		return clk;
+	private_data->pclk = devm_clk_get(port->dev, "pclk");
+	if (IS_ERR(private_data->pclk))
+		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
+				     "Failed to get the 'pclk' clock\n");
 
-	ret = clk_prepare_enable(clk);
-	if (ret) {
-		dev_err(dev, "couldn't enable clk\n");
-		return ERR_PTR(ret);
+	clk_baud = devm_clk_get(port->dev, "baud");
+	if (IS_ERR(clk_baud)) {
+		dev_err(port->dev, "Failed to get the 'baud' clock\n");
+		return PTR_ERR(clk_baud);
 	}
 
-	devm_add_action_or_reset(dev,
-			(void(*)(void *))clk_disable_unprepare,
-			clk);
-
-	return clk;
-}
-
-static int meson_uart_probe_clocks(struct platform_device *pdev,
-				   struct uart_port *port)
-{
-	struct clk *clk_xtal = NULL;
-	struct clk *clk_pclk = NULL;
-	struct clk *clk_baud = NULL;
-
-	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
-	if (IS_ERR(clk_pclk))
-		return PTR_ERR(clk_pclk);
-
-	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
+	clk_xtal = devm_clk_get(port->dev, "xtal");
 	if (IS_ERR(clk_xtal))
-		return PTR_ERR(clk_xtal);
-
-	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
-	if (IS_ERR(clk_baud))
-		return PTR_ERR(clk_baud);
+		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
+				     "Failed to get the 'xtal' clock\n");
+
+	if (private_data->use_xtal_clk) {
+		hw = devm_clk_hw_register_divider_table(port->dev,
+							CLK_NAME(xtal_div),
+							__clk_get_name(clk_baud),
+							CLK_SET_RATE_NO_REPARENT,
+							port->membase + AML_UART_REG5,
+							26, 2,
+							CLK_DIVIDER_READ_ONLY,
+							xtal_div_table, NULL);
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		use_xtal_mux_parents[1].hw = hw;
+	} else {
+		hw = devm_clk_hw_register_fixed_factor(port->dev,
+						       CLK_NAME(clk81_div4),
+						       __clk_get_name(clk_baud),
+						       CLK_SET_RATE_NO_REPARENT,
+						       1, 4);
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		use_xtal_mux_parents[0].hw = hw;
+	}
 
-	port->uartclk = clk_get_rate(clk_baud);
+	hw = __devm_clk_hw_register_mux(port->dev, NULL,
+					CLK_NAME(use_xtal),
+					ARRAY_SIZE(use_xtal_mux_parents),
+					NULL, NULL,
+					use_xtal_mux_parents,
+					CLK_SET_RATE_PARENT,
+					port->membase + AML_UART_REG5,
+					24, 0x1,
+					CLK_MUX_READ_ONLY,
+					NULL, NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	port->uartclk = clk_hw_get_rate(hw);
+
+	hw = devm_clk_hw_register_divider(port->dev,
+					  CLK_NAME(baud_div),
+					  clk_hw_get_name(hw),
+					  CLK_SET_RATE_PARENT,
+					  port->membase + AML_UART_REG5,
+					  0, 23,
+					  CLK_DIVIDER_ROUND_CLOSEST,
+					  NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
 
 	return 0;
 }
 
 static int meson_uart_probe(struct platform_device *pdev)
 {
+	struct meson_uart_data *private_data;
 	struct resource *res_mem;
 	struct uart_port *port;
 	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
@@ -716,18 +783,20 @@ static int meson_uart_probe(struct platform_device *pdev)
 		return -EBUSY;
 	}
 
-	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
-	if (!port)
+	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
+				    GFP_KERNEL);
+	if (!private_data)
 		return -ENOMEM;
 
+	if (device_get_match_data(&pdev->dev))
+		private_data->use_xtal_clk = true;
+
+	port = &private_data->port;
+
 	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
 	if (IS_ERR(port->membase))
 		return PTR_ERR(port->membase);
 
-	ret = meson_uart_probe_clocks(pdev, port);
-	if (ret)
-		return ret;
-
 	port->iotype = UPIO_MEM;
 	port->mapbase = res_mem->start;
 	port->mapsize = resource_size(res_mem);
@@ -740,7 +809,11 @@ static int meson_uart_probe(struct platform_device *pdev)
 	port->x_char = 0;
 	port->ops = &meson_uart_ops;
 	port->fifosize = fifosize;
+	port->private_data = private_data;
 
+	ret = meson_uart_probe_clocks(port);
+	if (ret)
+		return ret;
 	meson_ports[pdev->id] = port;
 	platform_set_drvdata(pdev, port);
 
@@ -766,10 +839,39 @@ static int meson_uart_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id meson_uart_dt_match[] = {
-	{ .compatible = "amlogic,meson6-uart" },
-	{ .compatible = "amlogic,meson8-uart" },
-	{ .compatible = "amlogic,meson8b-uart" },
-	{ .compatible = "amlogic,meson-gx-uart" },
+	{
+		.compatible = "amlogic,meson6-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson8-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson8b-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson-gxbb-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson-gxl-uart",
+		.data = (void *)true,
+	},
+	{
+		.compatible = "amlogic,meson-g12a-uart",
+		.data = (void *)true,
+	},
+	/*
+	 * deprecated, don't use anymore because it doesn't differentiate
+	 * between GXBB, GXL and G12A which have different revisions
+	 * of the UART IP.
+	 */
+	{
+		.compatible = "amlogic,meson-gx-uart",
+		.data = (void *)false,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, meson_uart_dt_match);

base-commit: 93a770b7e16772530196674ffc79bb13fa927dc6
prerequisite-patch-id: 95191c926509964c8e9bf4128b8bbad8a277b84a
prerequisite-patch-id: a2e4756ff85f0df0efe111d7e2cb51b8e26e226f
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:54:39 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:54:39 +0800
Subject: [PATCH 1/2] dt-bindings: serial: meson: Drop compatible =
 amlogic,meson-gx-uart.
In-Reply-To: <20220110082616.13474-1-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
Message-ID: <f16843d4-c3c7-9b24-e262-3ca5472e07a7@amlogic.com>

Hi All,
	I'm really sorry for sending the wrong specified file. Please ignore 
the email. I will resend V4.

On 2022/1/10 16:26, Yu Tu wrote:
> Deprecated, don't use anymore because compatible =
> amlogic,meson-gx-uart. Don't differentiate between GXBB, GXL
> and G12A which have different revisions of the UART IP.
> So it's split into GXBB, GXL and G12A.
> 
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>   .../devicetree/bindings/serial/amlogic,meson-uart.yaml | 10 ++++++++--
>   1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
> index 72e8868db3e0..ad9f1f4537a0 100644
> --- a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
> +++ b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
> @@ -28,7 +28,10 @@ properties:
>                 - amlogic,meson6-uart
>                 - amlogic,meson8-uart
>                 - amlogic,meson8b-uart
> -              - amlogic,meson-gx-uart
> +              - amlogic,meson-gx-uart # deprecated, use revision specific property below
> +              - amlogic,meson-gxbb-uart
> +              - amlogic,meson-gxl-uart
> +              - amlogic,meson-g12a-uart
>                 - amlogic,meson-s4-uart
>             - const: amlogic,meson-ao-uart
>         - description: Everything-Else power domain UART controller
> @@ -36,7 +39,10 @@ properties:
>             - amlogic,meson6-uart
>             - amlogic,meson8-uart
>             - amlogic,meson8b-uart
> -          - amlogic,meson-gx-uart
> +          - amlogic,meson-gx-uart # deprecated, use revision specific property below
> +          - amlogic,meson-gxbb-uart
> +          - amlogic,meson-gxl-uart
> +          - amlogic,meson-g12a-uart
>             - amlogic,meson-s4-uart
>   
>     reg:
> 
> base-commit: 99a507a8ea28542ec196e2dd80096708e2482735


From yu.tu at amlogic.com  Mon Jan 10 00:54:57 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:54:57 +0800
Subject: [PATCH] tty: serial: meson: Change request_irq to
 devm_request_irq and move devm_request_irq to meson_uart_probe()
In-Reply-To: <20220110082616.13474-2-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
 <20220110082616.13474-2-yu.tu@amlogic.com>
Message-ID: <79e4a4d1-eefd-9fa2-d365-192f28f4c9c8@amlogic.com>

Hi All,
	I'm really sorry for sending the wrong specified file. Please ignore 
the email. I will resend V4.

On 2022/1/10 16:26, Yu Tu wrote:
> Because an interrupt error occurs when the user opens /dev/ttyAML* but
> don't close it, and then opens the same port again. This problem is
> encountered in actual projects.
> 
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>   drivers/tty/serial/meson_uart.c | 16 +++++++++-------
>   1 file changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 45e41f20cba3..0dd3f5b35768 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -135,8 +135,6 @@ static void meson_uart_shutdown(struct uart_port *port)
>   	unsigned long flags;
>   	u32 val;
>   
> -	free_irq(port->irq, port);
> -
>   	spin_lock_irqsave(&port->lock, flags);
>   
>   	val = readl(port->membase + AML_UART_CONTROL);
> @@ -284,7 +282,6 @@ static void meson_uart_reset(struct uart_port *port)
>   static int meson_uart_startup(struct uart_port *port)
>   {
>   	u32 val;
> -	int ret;
>   
>   	meson_uart_reset(port);
>   
> @@ -298,10 +295,7 @@ static int meson_uart_startup(struct uart_port *port)
>   	val = (AML_UART_RECV_IRQ(1) | AML_UART_XMIT_IRQ(port->fifosize / 2));
>   	writel(val, port->membase + AML_UART_MISC);
>   
> -	ret = request_irq(port->irq, meson_uart_interrupt, 0,
> -			  port->name, port);
> -
> -	return ret;
> +	return 0;
>   }
>   
>   static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
> @@ -908,6 +902,14 @@ static int meson_uart_probe(struct platform_device *pdev)
>   	meson_ports[pdev->id] = port;
>   	platform_set_drvdata(pdev, port);
>   
> +	ret = devm_request_irq(&pdev->dev, port->irq, meson_uart_interrupt,
> +			       0, dev_name(&pdev->dev), port);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to request uart irq: %d\n",
> +			ret);
> +		return ret;
> +	}
> +
>   	/* reset port before registering (and possibly registering console) */
>   	meson_uart_reset(port);
>   
> 
> base-commit: b3a9e3b9622ae10064826dccb4f7a52bd88c7407
> prerequisite-patch-id: 97a514f3447511cb204179ce03ae99dc1d5902d9
> prerequisite-patch-id: a2e4756ff85f0df0efe111d7e2cb51b8e26e226f
> prerequisite-patch-id: af9e3acc8f6ff7602d3a68a57c008e5ec362b353
> prerequisite-patch-id: 7af8c81b4c2163240725e96625b1487c280f4f30
> prerequisite-patch-id: 8791f6362b14e7c4ff4f85cce550f06abeb1af7a


From yu.tu at amlogic.com  Mon Jan 10 00:55:05 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:55:05 +0800
Subject: [PATCH] tty: serial: meson: Make the bit24 and bit [26, 27] of the
 UART_REG5 register writable
In-Reply-To: <20220110082616.13474-3-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
 <20220110082616.13474-3-yu.tu@amlogic.com>
Message-ID: <b553aea7-cb78-830a-4a4c-51d2ee2a1850@amlogic.com>

Hi All,
	I'm really sorry for sending the wrong specified file. Please ignore 
the email. I will resend V4.

On 2022/1/10 16:26, Yu Tu wrote:
> The UART_REG5 register defaults to 0. The console port is set in
> ROMCODE. But other UART ports default to 0, so make bit24 and
> bit[26,27] writable so that the UART can choose a more
> appropriate clock.
> 
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>   drivers/tty/serial/meson_uart.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 7c3f30cea68e..b0551750dff8 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -693,7 +693,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
>   							CLK_SET_RATE_NO_REPARENT,
>   							port->membase + AML_UART_REG5,
>   							26, 2,
> -							CLK_DIVIDER_READ_ONLY,
> +							CLK_DIVIDER_ROUND_CLOSEST,
>   							xtal_div_table, NULL);
>   		if (IS_ERR(hw))
>   			return PTR_ERR(hw);
> @@ -719,7 +719,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
>   					CLK_SET_RATE_PARENT,
>   					port->membase + AML_UART_REG5,
>   					24, 0x1,
> -					CLK_MUX_READ_ONLY,
> +					CLK_MUX_ROUND_CLOSEST,
>   					NULL, NULL);
>   	if (IS_ERR(hw))
>   		return PTR_ERR(hw);
> 
> base-commit: 93a770b7e16772530196674ffc79bb13fa927dc6
> prerequisite-patch-id: 95191c926509964c8e9bf4128b8bbad8a277b84a
> prerequisite-patch-id: a2e4756ff85f0df0efe111d7e2cb51b8e26e226f
> prerequisite-patch-id: 4e4d909acabcb7533da20e2207207be73454a88c


From yu.tu at amlogic.com  Mon Jan 10 00:55:14 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:55:14 +0800
Subject: [PATCH] tty: serial: meson: meson_uart_shutdown omit clear
 AML_UART_TX_EN bit
In-Reply-To: <20220110082616.13474-4-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
 <20220110082616.13474-4-yu.tu@amlogic.com>
Message-ID: <f16770c3-fc9c-3353-8b5c-5f3029cda240@amlogic.com>

Hi All,
	I'm really sorry for sending the wrong specified file. Please ignore 
the email. I will resend V4.

On 2022/1/10 16:26, Yu Tu wrote:
> This change is an improvement. The meson_uart_shutdown function
> should have the opposite operation to the meson_uart_startup
> function, but the meson_uart_shutdown of AML_UART_TX_EN is logically
> missing.
> 
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>   drivers/tty/serial/meson_uart.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 9b07e3534969..c17109d6d441 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -140,7 +140,7 @@ static void meson_uart_shutdown(struct uart_port *port)
>   	spin_lock_irqsave(&port->lock, flags);
>   
>   	val = readl(port->membase + AML_UART_CONTROL);
> -	val &= ~AML_UART_RX_EN;
> +	val &= ~(AML_UART_RX_EN | AML_UART_TX_EN);
>   	val &= ~(AML_UART_RX_INT_EN | AML_UART_TX_INT_EN);
>   	writel(val, port->membase + AML_UART_CONTROL);
>   
> 
> base-commit: b3a9e3b9622ae10064826dccb4f7a52bd88c7407
> prerequisite-patch-id: 97a514f3447511cb204179ce03ae99dc1d5902d9
> prerequisite-patch-id: a2e4756ff85f0df0efe111d7e2cb51b8e26e226f
> prerequisite-patch-id: af9e3acc8f6ff7602d3a68a57c008e5ec362b353
> prerequisite-patch-id: a44e5da7009d9b815eb87395cbd7d14e7d953a09


From yu.tu at amlogic.com  Mon Jan 10 00:55:21 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:55:21 +0800
Subject: [PATCH] tty: serial: meson: Request the register region in
 meson_uart_probe()
In-Reply-To: <20220110082616.13474-5-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
 <20220110082616.13474-5-yu.tu@amlogic.com>
Message-ID: <936e828c-15e0-5223-7daa-94b2fafc2602@amlogic.com>

Hi All,
	I'm really sorry for sending the wrong specified file. Please ignore 
the email. I will resend V4.

On 2022/1/10 16:26, Yu Tu wrote:
> This simplifies resetting the UART controller during probe and will make
> it easier to integrate the common clock code which will require the
> registers at probe time as well.
> 
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>   drivers/tty/serial/meson_uart.c | 24 ++++++------------------
>   1 file changed, 6 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index c9a37602ffd0..99efe62a1507 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -397,24 +397,11 @@ static int meson_uart_verify_port(struct uart_port *port,
>   
>   static void meson_uart_release_port(struct uart_port *port)
>   {
> -	devm_iounmap(port->dev, port->membase);
> -	port->membase = NULL;
> -	devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
> +	/* nothing to do */
>   }
>   
>   static int meson_uart_request_port(struct uart_port *port)
>   {
> -	if (!devm_request_mem_region(port->dev, port->mapbase, port->mapsize,
> -				     dev_name(port->dev))) {
> -		dev_err(port->dev, "Memory region busy\n");
> -		return -EBUSY;
> -	}
> -
> -	port->membase = devm_ioremap(port->dev, port->mapbase,
> -					     port->mapsize);
> -	if (!port->membase)
> -		return -ENOMEM;
> -
>   	return 0;
>   }
>   
> @@ -728,6 +715,10 @@ static int meson_uart_probe(struct platform_device *pdev)
>   	if (!port)
>   		return -ENOMEM;
>   
> +	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
> +	if (IS_ERR(port->membase))
> +		return PTR_ERR(port->membase);
> +
>   	ret = meson_uart_probe_clocks(pdev, port);
>   	if (ret)
>   		return ret;
> @@ -749,10 +740,7 @@ static int meson_uart_probe(struct platform_device *pdev)
>   	platform_set_drvdata(pdev, port);
>   
>   	/* reset port before registering (and possibly registering console) */
> -	if (meson_uart_request_port(port) >= 0) {
> -		meson_uart_reset(port);
> -		meson_uart_release_port(port);
> -	}
> +	meson_uart_reset(port);
>   
>   	ret = uart_add_one_port(&meson_uart_driver, port);
>   	if (ret)
> 
> base-commit: b3a9e3b9622ae10064826dccb4f7a52bd88c7407
> prerequisite-patch-id: 97a514f3447511cb204179ce03ae99dc1d5902d9


From yu.tu at amlogic.com  Mon Jan 10 00:55:33 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:55:33 +0800
Subject: [PATCH 1/2] tty: serial: meson: The UART baud rate calculation is
 described using the common clock code.
In-Reply-To: <20220110082616.13474-6-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
 <20220110082616.13474-6-yu.tu@amlogic.com>
Message-ID: <84c9dc1e-c514-cd34-60c6-7973ade7883d@amlogic.com>

Hi All,
	I'm really sorry for sending the wrong specified file. Please ignore 
the email. I will resend V4.

On 2022/1/10 16:26, Yu Tu wrote:
> Using the common Clock code to describe the UART baud rate clock
> makes it easier for the UART driver to be compatible with the
> baud rate requirements of the UART IP on different meson chips.
> 
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>   drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
>   1 file changed, 163 insertions(+), 61 deletions(-)
> 
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 7570958d010c..1004fd0b0c9e 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -6,6 +6,7 @@
>    */
>   
>   #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>   #include <linux/console.h>
>   #include <linux/delay.h>
>   #include <linux/init.h>
> @@ -65,9 +66,7 @@
>   #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>   
>   /* AML_UART_REG5 bits */
> -#define AML_UART_BAUD_MASK		0x7fffff
>   #define AML_UART_BAUD_USE		BIT(23)
> -#define AML_UART_BAUD_XTAL		BIT(24)
>   
>   #define AML_UART_PORT_NUM		12
>   #define AML_UART_PORT_OFFSET		6
> @@ -76,6 +75,13 @@
>   #define AML_UART_POLL_USEC		5
>   #define AML_UART_TIMEOUT_USEC		10000
>   
> +struct meson_uart_data {
> +	struct uart_port	port;
> +	struct clk		*pclk;
> +	struct clk		*baud_clk;
> +	bool			use_xtal_clk;
> +};
> +
>   static struct uart_driver meson_uart_driver;
>   
>   static struct uart_port *meson_ports[AML_UART_PORT_NUM];
> @@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
>   static int meson_uart_startup(struct uart_port *port)
>   {
>   	u32 val;
> -	int ret = 0;
> +	int ret;
>   
> -	val = readl(port->membase + AML_UART_CONTROL);
> -	val |= AML_UART_CLEAR_ERR;
> -	writel(val, port->membase + AML_UART_CONTROL);
> -	val &= ~AML_UART_CLEAR_ERR;
> -	writel(val, port->membase + AML_UART_CONTROL);
> +	meson_uart_reset(port);
>   
> +	val = readl(port->membase + AML_UART_CONTROL);
>   	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>   	writel(val, port->membase + AML_UART_CONTROL);
>   
> @@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port *port)
>   
>   static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
>   {
> +	struct meson_uart_data *private_data = port->private_data;
>   	u32 val;
>   
>   	while (!meson_uart_tx_empty(port))
>   		cpu_relax();
>   
> -	if (port->uartclk == 24000000) {
> -		val = ((port->uartclk / 3) / baud) - 1;
> -		val |= AML_UART_BAUD_XTAL;
> -	} else {
> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
> -	}
> +	val = readl(port->membase + AML_UART_REG5);
>   	val |= AML_UART_BAUD_USE;
>   	writel(val, port->membase + AML_UART_REG5);
> +
> +	clk_set_rate(private_data->baud_clk, baud);
>   }
>   
>   static void meson_uart_set_termios(struct uart_port *port,
> @@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>   
>   static void meson_uart_release_port(struct uart_port *port)
>   {
> -	/* nothing to do */
> +	struct meson_uart_data *private_data = port->private_data;
> +
> +	clk_disable_unprepare(private_data->baud_clk);
> +	clk_disable_unprepare(private_data->pclk);
>   }
>   
>   static int meson_uart_request_port(struct uart_port *port)
>   {
> +	struct meson_uart_data *private_data = port->private_data;
> +	int ret;
> +
> +	ret = clk_prepare_enable(private_data->pclk);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_prepare_enable(private_data->baud_clk);
> +	if (ret) {
> +		clk_disable_unprepare(private_data->pclk);
> +		return ret;
> +	}
> +
>   	return 0;
>   }
>   
> @@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
>   	.cons		= MESON_SERIAL_CONSOLE,
>   };
>   
> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
> -						 const char *id)
> +#define CLK_NAME(name) \
> +({\
> +	char clk_name[32];\
> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
> +	clk_name;\
> +})
> +
> +static struct clk_div_table xtal_div_table[] = {
> +	{ 0, 3  },
> +	{ 1, 1  },
> +	{ 2, 2  },
> +	{ 3, 2  },
> +};
> +
> +static int meson_uart_probe_clocks(struct uart_port *port)
>   {
> -	struct clk *clk = NULL;
> -	int ret;
> +	struct meson_uart_data *private_data = port->private_data;
> +	struct clk *clk_baud, *clk_xtal;
> +	struct clk_hw *hw;
> +	struct clk_parent_data use_xtal_mux_parents[2] = {
> +		{ .index = -1, },
> +		{ .index = -1, },
> +	};
>   
> -	clk = devm_clk_get(dev, id);
> -	if (IS_ERR(clk))
> -		return clk;
> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
> +	if (IS_ERR(private_data->pclk))
> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
> +				     "Failed to get the 'pclk' clock\n");
>   
> -	ret = clk_prepare_enable(clk);
> -	if (ret) {
> -		dev_err(dev, "couldn't enable clk\n");
> -		return ERR_PTR(ret);
> +	clk_baud = devm_clk_get(port->dev, "baud");
> +	if (IS_ERR(clk_baud)) {
> +		dev_err(port->dev, "Failed to get the 'baud' clock\n");
> +		return PTR_ERR(clk_baud);
>   	}
>   
> -	devm_add_action_or_reset(dev,
> -			(void(*)(void *))clk_disable_unprepare,
> -			clk);
> -
> -	return clk;
> -}
> -
> -static int meson_uart_probe_clocks(struct platform_device *pdev,
> -				   struct uart_port *port)
> -{
> -	struct clk *clk_xtal = NULL;
> -	struct clk *clk_pclk = NULL;
> -	struct clk *clk_baud = NULL;
> -
> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
> -	if (IS_ERR(clk_pclk))
> -		return PTR_ERR(clk_pclk);
> -
> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>   	if (IS_ERR(clk_xtal))
> -		return PTR_ERR(clk_xtal);
> -
> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
> -	if (IS_ERR(clk_baud))
> -		return PTR_ERR(clk_baud);
> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
> +				     "Failed to get the 'xtal' clock\n");
> +
> +	if (private_data->use_xtal_clk) {
> +		hw = devm_clk_hw_register_divider_table(port->dev,
> +							CLK_NAME(xtal_div),
> +							__clk_get_name(clk_baud),
> +							CLK_SET_RATE_NO_REPARENT,
> +							port->membase + AML_UART_REG5,
> +							26, 2,
> +							CLK_DIVIDER_READ_ONLY,
> +							xtal_div_table, NULL);
> +		if (IS_ERR(hw))
> +			return PTR_ERR(hw);
> +
> +		use_xtal_mux_parents[1].hw = hw;
> +	} else {
> +		hw = devm_clk_hw_register_fixed_factor(port->dev,
> +						       CLK_NAME(clk81_div4),
> +						       __clk_get_name(clk_baud),
> +						       CLK_SET_RATE_NO_REPARENT,
> +						       1, 4);
> +		if (IS_ERR(hw))
> +			return PTR_ERR(hw);
> +
> +		use_xtal_mux_parents[0].hw = hw;
> +	}
>   
> -	port->uartclk = clk_get_rate(clk_baud);
> +	hw = __devm_clk_hw_register_mux(port->dev, NULL,
> +					CLK_NAME(use_xtal),
> +					ARRAY_SIZE(use_xtal_mux_parents),
> +					NULL, NULL,
> +					use_xtal_mux_parents,
> +					CLK_SET_RATE_PARENT,
> +					port->membase + AML_UART_REG5,
> +					24, 0x1,
> +					CLK_MUX_READ_ONLY,
> +					NULL, NULL);
> +	if (IS_ERR(hw))
> +		return PTR_ERR(hw);
> +
> +	port->uartclk = clk_hw_get_rate(hw);
> +
> +	hw = devm_clk_hw_register_divider(port->dev,
> +					  CLK_NAME(baud_div),
> +					  clk_hw_get_name(hw),
> +					  CLK_SET_RATE_PARENT,
> +					  port->membase + AML_UART_REG5,
> +					  0, 23,
> +					  CLK_DIVIDER_ROUND_CLOSEST,
> +					  NULL);
> +	if (IS_ERR(hw))
> +		return PTR_ERR(hw);
> +
> +	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
>   
>   	return 0;
>   }
>   
>   static int meson_uart_probe(struct platform_device *pdev)
>   {
> +	struct meson_uart_data *private_data;
>   	struct resource *res_mem;
>   	struct uart_port *port;
>   	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
> @@ -716,18 +783,20 @@ static int meson_uart_probe(struct platform_device *pdev)
>   		return -EBUSY;
>   	}
>   
> -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
> -	if (!port)
> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
> +				    GFP_KERNEL);
> +	if (!private_data)
>   		return -ENOMEM;
>   
> +	if (device_get_match_data(&pdev->dev))
> +		private_data->use_xtal_clk = true;
> +
> +	port = &private_data->port;
> +
>   	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>   	if (IS_ERR(port->membase))
>   		return PTR_ERR(port->membase);
>   
> -	ret = meson_uart_probe_clocks(pdev, port);
> -	if (ret)
> -		return ret;
> -
>   	port->iotype = UPIO_MEM;
>   	port->mapbase = res_mem->start;
>   	port->mapsize = resource_size(res_mem);
> @@ -740,7 +809,11 @@ static int meson_uart_probe(struct platform_device *pdev)
>   	port->x_char = 0;
>   	port->ops = &meson_uart_ops;
>   	port->fifosize = fifosize;
> +	port->private_data = private_data;
>   
> +	ret = meson_uart_probe_clocks(port);
> +	if (ret)
> +		return ret;
>   	meson_ports[pdev->id] = port;
>   	platform_set_drvdata(pdev, port);
>   
> @@ -766,10 +839,39 @@ static int meson_uart_remove(struct platform_device *pdev)
>   }
>   
>   static const struct of_device_id meson_uart_dt_match[] = {
> -	{ .compatible = "amlogic,meson6-uart" },
> -	{ .compatible = "amlogic,meson8-uart" },
> -	{ .compatible = "amlogic,meson8b-uart" },
> -	{ .compatible = "amlogic,meson-gx-uart" },
> +	{
> +		.compatible = "amlogic,meson6-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson8-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson8b-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson-gxbb-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson-gxl-uart",
> +		.data = (void *)true,
> +	},
> +	{
> +		.compatible = "amlogic,meson-g12a-uart",
> +		.data = (void *)true,
> +	},
> +	/*
> +	 * deprecated, don't use anymore because it doesn't differentiate
> +	 * between GXBB, GXL and G12A which have different revisions
> +	 * of the UART IP.
> +	 */
> +	{
> +		.compatible = "amlogic,meson-gx-uart",
> +		.data = (void *)false,
> +	},
>   	{ /* sentinel */ },
>   };
>   MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
> 
> base-commit: 93a770b7e16772530196674ffc79bb13fa927dc6
> prerequisite-patch-id: 95191c926509964c8e9bf4128b8bbad8a277b84a
> prerequisite-patch-id: a2e4756ff85f0df0efe111d7e2cb51b8e26e226f


From yu.tu at amlogic.com  Mon Jan 10 00:55:59 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:55:59 +0800
Subject: [PATCH V4 0/5] the UART driver compatible with
Message-ID: <20220110085604.18042-1-yu.tu@amlogic.com>

Using the common Clock code to describe the UART baud rate
clock makes it easier for the UART driver to be compatible
with the baud rate requirements of the UART IP on different
meson chips. Add Meson S4 SoC compatible.

Yu Tu (5):
  dt-bindings: serial: meson: Drop compatible = amlogic,meson-gx-uart.
  tty: serial: meson: Request the register region in meson_uart_probe()
  tty: serial: meson: The UART baud rate calculation is described using
    the common clock code.
  tty: serial: meson: Make the bit24 and bit [26,27] of the UART_REG5
    register writable
  tty: serial: meson: Added S4 SOC compatibility.

V1 -> V2: Use CCF to describe the UART baud rate clock.Make some changes as
discussed in the email
V2 -> V3: add compatible = "amlogic,meson-gx-uart". Because it must change
the DTS before it can be deleted
V3 -> V4: Change CCF to describe the UART baud rate clock as discussed
in the email.

Link:https://lore.kernel.org/linux-amlogic/20211230102110.3861-4-yu.tu at amlogic.com/

 .../bindings/serial/amlogic,meson-uart.yaml   |  10 +-
 drivers/tty/serial/meson_uart.c               | 244 ++++++++++++------
 2 files changed, 177 insertions(+), 77 deletions(-)

-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:56:00 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:56:00 +0800
Subject: [PATCH V4 1/5] dt-bindings: serial: meson: Drop
In-Reply-To: <20220110085604.18042-1-yu.tu@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
Message-ID: <20220110085604.18042-2-yu.tu@amlogic.com>

Deprecated, don't use anymore because compatible =
amlogic,meson-gx-uart. Don't differentiate between GXBB, GXL
and G12A which have different revisions of the UART IP.
So it's split into GXBB, GXL and G12A.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 .../devicetree/bindings/serial/amlogic,meson-uart.yaml | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
index 72e8868db3e0..ad9f1f4537a0 100644
--- a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
+++ b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
@@ -28,7 +28,10 @@ properties:
               - amlogic,meson6-uart
               - amlogic,meson8-uart
               - amlogic,meson8b-uart
-              - amlogic,meson-gx-uart
+              - amlogic,meson-gx-uart # deprecated, use revision specific property below
+              - amlogic,meson-gxbb-uart
+              - amlogic,meson-gxl-uart
+              - amlogic,meson-g12a-uart
               - amlogic,meson-s4-uart
           - const: amlogic,meson-ao-uart
       - description: Everything-Else power domain UART controller
@@ -36,7 +39,10 @@ properties:
           - amlogic,meson6-uart
           - amlogic,meson8-uart
           - amlogic,meson8b-uart
-          - amlogic,meson-gx-uart
+          - amlogic,meson-gx-uart # deprecated, use revision specific property below
+          - amlogic,meson-gxbb-uart
+          - amlogic,meson-gxl-uart
+          - amlogic,meson-g12a-uart
           - amlogic,meson-s4-uart
 
   reg:
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:56:01 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:56:01 +0800
Subject: [PATCH V4 2/5] tty: serial: meson: Request the register
In-Reply-To: <20220110085604.18042-1-yu.tu@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
Message-ID: <20220110085604.18042-3-yu.tu@amlogic.com>

This simplifies resetting the UART controller during probe and
will make it easier to integrate the common clock code which
will require the registers at probe time as well.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 24 ++++++------------------
 1 file changed, 6 insertions(+), 18 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 45e00d928253..7570958d010c 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -395,24 +395,11 @@ static int meson_uart_verify_port(struct uart_port *port,
 
 static void meson_uart_release_port(struct uart_port *port)
 {
-	devm_iounmap(port->dev, port->membase);
-	port->membase = NULL;
-	devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
+	/* nothing to do */
 }
 
 static int meson_uart_request_port(struct uart_port *port)
 {
-	if (!devm_request_mem_region(port->dev, port->mapbase, port->mapsize,
-				     dev_name(port->dev))) {
-		dev_err(port->dev, "Memory region busy\n");
-		return -EBUSY;
-	}
-
-	port->membase = devm_ioremap(port->dev, port->mapbase,
-					     port->mapsize);
-	if (!port->membase)
-		return -ENOMEM;
-
 	return 0;
 }
 
@@ -733,6 +720,10 @@ static int meson_uart_probe(struct platform_device *pdev)
 	if (!port)
 		return -ENOMEM;
 
+	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
+	if (IS_ERR(port->membase))
+		return PTR_ERR(port->membase);
+
 	ret = meson_uart_probe_clocks(pdev, port);
 	if (ret)
 		return ret;
@@ -754,10 +745,7 @@ static int meson_uart_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, port);
 
 	/* reset port before registering (and possibly registering console) */
-	if (meson_uart_request_port(port) >= 0) {
-		meson_uart_reset(port);
-		meson_uart_release_port(port);
-	}
+	meson_uart_reset(port);
 
 	ret = uart_add_one_port(&meson_uart_driver, port);
 	if (ret)
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:56:02 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:56:02 +0800
Subject: [PATCH V4 3/5] tty: serial: meson: The UART baud rate
In-Reply-To: <20220110085604.18042-1-yu.tu@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
Message-ID: <20220110085604.18042-4-yu.tu@amlogic.com>

Using the common Clock code to describe the UART baud rate clock
makes it easier for the UART driver to be compatible with the
baud rate requirements of the UART IP on different meson chips.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
 1 file changed, 163 insertions(+), 61 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 7570958d010c..1004fd0b0c9e 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -65,9 +66,7 @@
 #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
 
 /* AML_UART_REG5 bits */
-#define AML_UART_BAUD_MASK		0x7fffff
 #define AML_UART_BAUD_USE		BIT(23)
-#define AML_UART_BAUD_XTAL		BIT(24)
 
 #define AML_UART_PORT_NUM		12
 #define AML_UART_PORT_OFFSET		6
@@ -76,6 +75,13 @@
 #define AML_UART_POLL_USEC		5
 #define AML_UART_TIMEOUT_USEC		10000
 
+struct meson_uart_data {
+	struct uart_port	port;
+	struct clk		*pclk;
+	struct clk		*baud_clk;
+	bool			use_xtal_clk;
+};
+
 static struct uart_driver meson_uart_driver;
 
 static struct uart_port *meson_ports[AML_UART_PORT_NUM];
@@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
 static int meson_uart_startup(struct uart_port *port)
 {
 	u32 val;
-	int ret = 0;
+	int ret;
 
-	val = readl(port->membase + AML_UART_CONTROL);
-	val |= AML_UART_CLEAR_ERR;
-	writel(val, port->membase + AML_UART_CONTROL);
-	val &= ~AML_UART_CLEAR_ERR;
-	writel(val, port->membase + AML_UART_CONTROL);
+	meson_uart_reset(port);
 
+	val = readl(port->membase + AML_UART_CONTROL);
 	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
 	writel(val, port->membase + AML_UART_CONTROL);
 
@@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port *port)
 
 static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
 {
+	struct meson_uart_data *private_data = port->private_data;
 	u32 val;
 
 	while (!meson_uart_tx_empty(port))
 		cpu_relax();
 
-	if (port->uartclk == 24000000) {
-		val = ((port->uartclk / 3) / baud) - 1;
-		val |= AML_UART_BAUD_XTAL;
-	} else {
-		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
-	}
+	val = readl(port->membase + AML_UART_REG5);
 	val |= AML_UART_BAUD_USE;
 	writel(val, port->membase + AML_UART_REG5);
+
+	clk_set_rate(private_data->baud_clk, baud);
 }
 
 static void meson_uart_set_termios(struct uart_port *port,
@@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
 
 static void meson_uart_release_port(struct uart_port *port)
 {
-	/* nothing to do */
+	struct meson_uart_data *private_data = port->private_data;
+
+	clk_disable_unprepare(private_data->baud_clk);
+	clk_disable_unprepare(private_data->pclk);
 }
 
 static int meson_uart_request_port(struct uart_port *port)
 {
+	struct meson_uart_data *private_data = port->private_data;
+	int ret;
+
+	ret = clk_prepare_enable(private_data->pclk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(private_data->baud_clk);
+	if (ret) {
+		clk_disable_unprepare(private_data->pclk);
+		return ret;
+	}
+
 	return 0;
 }
 
@@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
 	.cons		= MESON_SERIAL_CONSOLE,
 };
 
-static inline struct clk *meson_uart_probe_clock(struct device *dev,
-						 const char *id)
+#define CLK_NAME(name) \
+({\
+	char clk_name[32];\
+	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
+	clk_name;\
+})
+
+static struct clk_div_table xtal_div_table[] = {
+	{ 0, 3  },
+	{ 1, 1  },
+	{ 2, 2  },
+	{ 3, 2  },
+};
+
+static int meson_uart_probe_clocks(struct uart_port *port)
 {
-	struct clk *clk = NULL;
-	int ret;
+	struct meson_uart_data *private_data = port->private_data;
+	struct clk *clk_baud, *clk_xtal;
+	struct clk_hw *hw;
+	struct clk_parent_data use_xtal_mux_parents[2] = {
+		{ .index = -1, },
+		{ .index = -1, },
+	};
 
-	clk = devm_clk_get(dev, id);
-	if (IS_ERR(clk))
-		return clk;
+	private_data->pclk = devm_clk_get(port->dev, "pclk");
+	if (IS_ERR(private_data->pclk))
+		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
+				     "Failed to get the 'pclk' clock\n");
 
-	ret = clk_prepare_enable(clk);
-	if (ret) {
-		dev_err(dev, "couldn't enable clk\n");
-		return ERR_PTR(ret);
+	clk_baud = devm_clk_get(port->dev, "baud");
+	if (IS_ERR(clk_baud)) {
+		dev_err(port->dev, "Failed to get the 'baud' clock\n");
+		return PTR_ERR(clk_baud);
 	}
 
-	devm_add_action_or_reset(dev,
-			(void(*)(void *))clk_disable_unprepare,
-			clk);
-
-	return clk;
-}
-
-static int meson_uart_probe_clocks(struct platform_device *pdev,
-				   struct uart_port *port)
-{
-	struct clk *clk_xtal = NULL;
-	struct clk *clk_pclk = NULL;
-	struct clk *clk_baud = NULL;
-
-	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
-	if (IS_ERR(clk_pclk))
-		return PTR_ERR(clk_pclk);
-
-	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
+	clk_xtal = devm_clk_get(port->dev, "xtal");
 	if (IS_ERR(clk_xtal))
-		return PTR_ERR(clk_xtal);
-
-	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
-	if (IS_ERR(clk_baud))
-		return PTR_ERR(clk_baud);
+		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
+				     "Failed to get the 'xtal' clock\n");
+
+	if (private_data->use_xtal_clk) {
+		hw = devm_clk_hw_register_divider_table(port->dev,
+							CLK_NAME(xtal_div),
+							__clk_get_name(clk_baud),
+							CLK_SET_RATE_NO_REPARENT,
+							port->membase + AML_UART_REG5,
+							26, 2,
+							CLK_DIVIDER_READ_ONLY,
+							xtal_div_table, NULL);
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		use_xtal_mux_parents[1].hw = hw;
+	} else {
+		hw = devm_clk_hw_register_fixed_factor(port->dev,
+						       CLK_NAME(clk81_div4),
+						       __clk_get_name(clk_baud),
+						       CLK_SET_RATE_NO_REPARENT,
+						       1, 4);
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		use_xtal_mux_parents[0].hw = hw;
+	}
 
-	port->uartclk = clk_get_rate(clk_baud);
+	hw = __devm_clk_hw_register_mux(port->dev, NULL,
+					CLK_NAME(use_xtal),
+					ARRAY_SIZE(use_xtal_mux_parents),
+					NULL, NULL,
+					use_xtal_mux_parents,
+					CLK_SET_RATE_PARENT,
+					port->membase + AML_UART_REG5,
+					24, 0x1,
+					CLK_MUX_READ_ONLY,
+					NULL, NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	port->uartclk = clk_hw_get_rate(hw);
+
+	hw = devm_clk_hw_register_divider(port->dev,
+					  CLK_NAME(baud_div),
+					  clk_hw_get_name(hw),
+					  CLK_SET_RATE_PARENT,
+					  port->membase + AML_UART_REG5,
+					  0, 23,
+					  CLK_DIVIDER_ROUND_CLOSEST,
+					  NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
 
 	return 0;
 }
 
 static int meson_uart_probe(struct platform_device *pdev)
 {
+	struct meson_uart_data *private_data;
 	struct resource *res_mem;
 	struct uart_port *port;
 	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
@@ -716,18 +783,20 @@ static int meson_uart_probe(struct platform_device *pdev)
 		return -EBUSY;
 	}
 
-	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
-	if (!port)
+	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
+				    GFP_KERNEL);
+	if (!private_data)
 		return -ENOMEM;
 
+	if (device_get_match_data(&pdev->dev))
+		private_data->use_xtal_clk = true;
+
+	port = &private_data->port;
+
 	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
 	if (IS_ERR(port->membase))
 		return PTR_ERR(port->membase);
 
-	ret = meson_uart_probe_clocks(pdev, port);
-	if (ret)
-		return ret;
-
 	port->iotype = UPIO_MEM;
 	port->mapbase = res_mem->start;
 	port->mapsize = resource_size(res_mem);
@@ -740,7 +809,11 @@ static int meson_uart_probe(struct platform_device *pdev)
 	port->x_char = 0;
 	port->ops = &meson_uart_ops;
 	port->fifosize = fifosize;
+	port->private_data = private_data;
 
+	ret = meson_uart_probe_clocks(port);
+	if (ret)
+		return ret;
 	meson_ports[pdev->id] = port;
 	platform_set_drvdata(pdev, port);
 
@@ -766,10 +839,39 @@ static int meson_uart_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id meson_uart_dt_match[] = {
-	{ .compatible = "amlogic,meson6-uart" },
-	{ .compatible = "amlogic,meson8-uart" },
-	{ .compatible = "amlogic,meson8b-uart" },
-	{ .compatible = "amlogic,meson-gx-uart" },
+	{
+		.compatible = "amlogic,meson6-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson8-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson8b-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson-gxbb-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson-gxl-uart",
+		.data = (void *)true,
+	},
+	{
+		.compatible = "amlogic,meson-g12a-uart",
+		.data = (void *)true,
+	},
+	/*
+	 * deprecated, don't use anymore because it doesn't differentiate
+	 * between GXBB, GXL and G12A which have different revisions
+	 * of the UART IP.
+	 */
+	{
+		.compatible = "amlogic,meson-gx-uart",
+		.data = (void *)false,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:56:03 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:56:03 +0800
Subject: [PATCH V4 4/5] tty: serial: meson: Make the bit24 and
In-Reply-To: <20220110085604.18042-1-yu.tu@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
Message-ID: <20220110085604.18042-5-yu.tu@amlogic.com>

The UART_REG5 register defaults to 0. The console port is set in
ROMCODE. But other UART ports default to 0, so make bit24 and
bit[26,27] writable so that the UART can choose a more
appropriate clock.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 1004fd0b0c9e..fd128878e91a 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -693,7 +693,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
 							CLK_SET_RATE_NO_REPARENT,
 							port->membase + AML_UART_REG5,
 							26, 2,
-							CLK_DIVIDER_READ_ONLY,
+							CLK_DIVIDER_ROUND_CLOSEST,
 							xtal_div_table, NULL);
 		if (IS_ERR(hw))
 			return PTR_ERR(hw);
@@ -719,7 +719,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
 					CLK_SET_RATE_PARENT,
 					port->membase + AML_UART_REG5,
 					24, 0x1,
-					CLK_MUX_READ_ONLY,
+					CLK_MUX_ROUND_CLOSEST,
 					NULL, NULL);
 	if (IS_ERR(hw))
 		return PTR_ERR(hw);
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:56:04 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:56:04 +0800
Subject: [PATCH V4 5/5] tty: serial: meson: Added S4 SOC compatibility.
In-Reply-To: <20220110085604.18042-1-yu.tu@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
Message-ID: <20220110085604.18042-6-yu.tu@amlogic.com>

Make UART driver compatible with S4 SOC UART.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index fd128878e91a..d6aa04cc31ba 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -863,6 +863,10 @@ static const struct of_device_id meson_uart_dt_match[] = {
 		.compatible = "amlogic,meson-g12a-uart",
 		.data = (void *)true,
 	},
+	{
+		.compatible = "amlogic,meson-s4-uart",
+		.data = (void *)true,
+	},
 	/*
 	 * deprecated, don't use anymore because it doesn't differentiate
 	 * between GXBB, GXL and G12A which have different revisions
-- 
2.33.1



From narmstrong at baylibre.com  Mon Jan 10 01:23:50 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 10:23:50 +0100
Subject: [GIT PULL] amlogic fixes for v5.17-rc
In-Reply-To: <YdoBffKeAvtOeRSe@lx2k>
References: <7e40328b-6645-4343-3050-73dcfb2cefcb@baylibre.com>
 <YdoBffKeAvtOeRSe@lx2k>
Message-ID: <df36156e-eb2e-21e0-e5f2-28666409547a@baylibre.com>

Hi,

On 08/01/2022 22:26, Olof Johansson wrote:
> On Mon, Jan 03, 2022 at 04:13:44PM +0100, Neil Armstrong wrote:
>> Hi,
>>
>> Here's a couple of DT fixes for v5.17-rc1, they fix the UART compatibles of
>> the ARMv7 Amlogic SoCs and by the way keep earlycon working after [1] has been
>> applied by greg in the tty branch for 5.17.
>>
>> I know it's early for 5.17-rc1, but at least it's in the pipe.
>>
>> I based the changes on your dt-5.17 tag pushed to linus for 5.17-rc1,
>> if necessary I can rebase on v5.16-rcX.
> 
> Hi Neil,
> 
> It looks like this branch is based on our arm/dt branch? Please don't base your
> topics on our branches, it'll be awkward if we ever need to rebuild them (it's
> happened a few times, but we try very hard to avoid it).


Sure, no worries, I tried but I was wrong

> 
> In this case, you should have based your contents on top of your latest dt
> branch (if it would have had conflicts), not ours.

Noted for next time

> 
> Mind rebuilding and send a new pull request?

Sure, rebasing right now on proper 5.17-rc DT tag

> 
> Thanks,
> 
> 
> -Olof
> 

Thanks,
Neil


From narmstrong at baylibre.com  Mon Jan 10 01:25:00 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 10:25:00 +0100
Subject: [PATCH v3 1/2] dt-bindings: phy: add Amlogic G12A Analog MIPI
 D-PHY bindings
In-Reply-To: <CAFBinCDRx6VaaAubr6VRLnX=G4Ez8cGg-=6e-9GWrH8FwwBs-g@mail.gmail.com>
References: <20220107150512.614423-1-narmstrong@baylibre.com>
 <20220107150512.614423-2-narmstrong@baylibre.com>
 <CAFBinCDRx6VaaAubr6VRLnX=G4Ez8cGg-=6e-9GWrH8FwwBs-g@mail.gmail.com>
Message-ID: <fad140b9-2940-a24a-ba70-9849bacf617d@baylibre.com>

On 07/01/2022 23:13, Martin Blumenstingl wrote:
> Hi Neil,
> 
> On Fri, Jan 7, 2022 at 4:05 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
> [...]
>> +required:
>> +  - compatible
>> +  - reg
>> +  - "#phy-cells"
> I also found a "MIPI DSI PHY clock" and "MIPI DSI PHY interrupt" in
> the datasheet.
> I'm no expert on this and I'm just asking in case you have missed one of these:
> Can you confirm that these belong to some other IP?

Indeed the name is misleading, both go to the DSI Transceiver IP (dw-mipi-dsi)

Neil

> 
> 
> Best regards,
> Martin
> 



From narmstrong at baylibre.com  Mon Jan 10 01:27:56 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 10:27:56 +0100
Subject: [PATCH V4 0/5] the UART driver compatible with
In-Reply-To: <20220110085604.18042-1-yu.tu@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
Message-ID: <1f4b9288-c7ff-c895-425c-187d058642b9@baylibre.com>

Hi,

On 10/01/2022 09:55, Yu Tu wrote:
> Using the common Clock code to describe the UART baud rate
> clock makes it easier for the UART driver to be compatible
> with the baud rate requirements of the UART IP on different
> meson chips. Add Meson S4 SoC compatible.
> 
> Yu Tu (5):
>   dt-bindings: serial: meson: Drop compatible = amlogic,meson-gx-uart.
>   tty: serial: meson: Request the register region in meson_uart_probe()
>   tty: serial: meson: The UART baud rate calculation is described using
>     the common clock code.
>   tty: serial: meson: Make the bit24 and bit [26,27] of the UART_REG5
>     register writable
>   tty: serial: meson: Added S4 SOC compatibility.

Weird, the subjects are fine in the cover letter but are all truncated in the email thread:
[PATCH V4 0/5] the UART driver compatible with
[PATCH V4 1/5] dt-bindings: serial: meson: Drop
[PATCH V4 2/5] tty: serial: meson: Request the register
...
Only the last one is OK.


> 
> V1 -> V2: Use CCF to describe the UART baud rate clock.Make some changes as
> discussed in the email
> V2 -> V3: add compatible = "amlogic,meson-gx-uart". Because it must change
> the DTS before it can be deleted
> V3 -> V4: Change CCF to describe the UART baud rate clock as discussed
> in the email.
> 
> Link:https://lore.kernel.org/linux-amlogic/20211230102110.3861-4-yu.tu at amlogic.com/
> 
>  .../bindings/serial/amlogic,meson-uart.yaml   |  10 +-
>  drivers/tty/serial/meson_uart.c               | 244 ++++++++++++------
>  2 files changed, 177 insertions(+), 77 deletions(-)
> 



From yu.tu at amlogic.com  Mon Jan 10 01:35:51 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 17:35:51 +0800
Subject: [PATCH V4 0/5] the UART driver compatible with
In-Reply-To: <1f4b9288-c7ff-c895-425c-187d058642b9@baylibre.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
 <1f4b9288-c7ff-c895-425c-187d058642b9@baylibre.com>
Message-ID: <a19771e6-d1d4-d1ef-9819-21e2147aad16@amlogic.com>

Hi Neil,
	Thank you very much for your reply.

On 2022/1/10 17:27, Neil Armstrong wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi,
> 
> On 10/01/2022 09:55, Yu Tu wrote:
>> Using the common Clock code to describe the UART baud rate
>> clock makes it easier for the UART driver to be compatible
>> with the baud rate requirements of the UART IP on different
>> meson chips. Add Meson S4 SoC compatible.
>>
>> Yu Tu (5):
>>    dt-bindings: serial: meson: Drop compatible = amlogic,meson-gx-uart.
>>    tty: serial: meson: Request the register region in meson_uart_probe()
>>    tty: serial: meson: The UART baud rate calculation is described using
>>      the common clock code.
>>    tty: serial: meson: Make the bit24 and bit [26,27] of the UART_REG5
>>      register writable
>>    tty: serial: meson: Added S4 SOC compatibility.
> 
> Weird, the subjects are fine in the cover letter but are all truncated in the email thread:
> [PATCH V4 0/5] the UART driver compatible with
> [PATCH V4 1/5] dt-bindings: serial: meson: Drop
> [PATCH V4 2/5] tty: serial: meson: Request the register
> ...
> Only the last one is OK.
> 
I saw the subject was a little long, I changed it manually, do I need to 
regenerate and send?
> 
>>
>> V1 -> V2: Use CCF to describe the UART baud rate clock.Make some changes as
>> discussed in the email
>> V2 -> V3: add compatible = "amlogic,meson-gx-uart". Because it must change
>> the DTS before it can be deleted
>> V3 -> V4: Change CCF to describe the UART baud rate clock as discussed
>> in the email.
>>
>> Link:https://lore.kernel.org/linux-amlogic/20211230102110.3861-4-yu.tu at amlogic.com/
>>
>>   .../bindings/serial/amlogic,meson-uart.yaml   |  10 +-
>>   drivers/tty/serial/meson_uart.c               | 244 ++++++++++++------
>>   2 files changed, 177 insertions(+), 77 deletions(-)
>>
> 


From narmstrong at baylibre.com  Mon Jan 10 01:38:49 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 10:38:49 +0100
Subject: [GIT PULL] amlogic fixes for v5.17-rc v2
Message-ID: <746a7f25-1c96-9d27-3a08-e86b2af608ef@baylibre.com>

Hi,

Here's a couple of DT fixes for v5.17-rc1, they fix the UART compatibles of
the ARMv7 Amlogic SoCs and by the way keep earlycon working after [1] has been
applied by greg in the tty branch for 5.17.

Now based on my previous arm DT tag touching these files, sorry for v1.

Neil

[1] https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/commit/?h=tty-next&id=ad234e2bac274a43c9fa540bde8cd9f0c627b71f

The following changes since commit 72ccc373b064ae3ac0c5b5f2306069b60ca118df:

  ARM: dts: meson8b: ec100: Fix the pwm regulator supply properties (2021-07-26 10:05:36 +0200)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git tags/amlogic-fixes-v5.17-rc-v2

for you to fetch changes up to 3375aa77135f6aeb1107ed839a2050a4118444bc:

  ARM: dts: meson8b: Fix the UART device-tree schema validation (2022-01-10 10:32:51 +0100)

----------------------------------------------------------------
Amlogic fixes for v5.17-rc
- meson6/meson8/meson8b UART compatible fixup to notably fix earlycon

----------------------------------------------------------------
Martin Blumenstingl (3):
      ARM: dts: meson: Fix the UART compatible strings
      ARM: dts: meson8: Fix the UART device-tree schema validation
      ARM: dts: meson8b: Fix the UART device-tree schema validation

 arch/arm/boot/dts/meson.dtsi   |  8 ++++----
 arch/arm/boot/dts/meson8.dtsi  | 24 ++++++++++++------------
 arch/arm/boot/dts/meson8b.dtsi | 24 ++++++++++++------------
 3 files changed, 28 insertions(+), 28 deletions(-)


From narmstrong at baylibre.com  Mon Jan 10 01:43:02 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 10:43:02 +0100
Subject: [PATCH V4 0/5] the UART driver compatible with
In-Reply-To: <a19771e6-d1d4-d1ef-9819-21e2147aad16@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
 <1f4b9288-c7ff-c895-425c-187d058642b9@baylibre.com>
 <a19771e6-d1d4-d1ef-9819-21e2147aad16@amlogic.com>
Message-ID: <d14fdcd5-99c2-6aa0-085e-5355ecc0febf@baylibre.com>

On 10/01/2022 10:35, Yu Tu wrote:
> Hi Neil,
> ????Thank you very much for your reply.
> 
> On 2022/1/10 17:27, Neil Armstrong wrote:
>> [ EXTERNAL EMAIL ]
>>
>> Hi,
>>
>> On 10/01/2022 09:55, Yu Tu wrote:
>>> Using the common Clock code to describe the UART baud rate
>>> clock makes it easier for the UART driver to be compatible
>>> with the baud rate requirements of the UART IP on different
>>> meson chips. Add Meson S4 SoC compatible.
>>>
>>> Yu Tu (5):
>>> ?? dt-bindings: serial: meson: Drop compatible = amlogic,meson-gx-uart.
>>> ?? tty: serial: meson: Request the register region in meson_uart_probe()
>>> ?? tty: serial: meson: The UART baud rate calculation is described using
>>> ???? the common clock code.
>>> ?? tty: serial: meson: Make the bit24 and bit [26,27] of the UART_REG5
>>> ???? register writable
>>> ?? tty: serial: meson: Added S4 SOC compatibility.
>>
>> Weird, the subjects are fine in the cover letter but are all truncated in the email thread:
>> [PATCH V4 0/5] the UART driver compatible with
>> [PATCH V4 1/5] dt-bindings: serial: meson: Drop
>> [PATCH V4 2/5] tty: serial: meson: Request the register
>> ...
>> Only the last one is OK.
>>
> I saw the subject was a little long, I changed it manually, do I need to regenerate and send?

yes please, the mail subject will be the commit title so it must be short but descriptive enough.

"dt-bindings: serial: meson: Drop" is too short.

"dt-bindings: serial: meson: Drop compatible = amlogic,meson-gx-uart" is ok but formulation is wrong,
and remove special characters like "=", "[", "]"...

The best title could be :
"dt-bindings: serial: meson: Drop legacy amlogic,meson-gx-uart compatible"

If the subject it too long, reduce it and enhance the commit message with the details.

Neil

>>
>>>
>>> V1 -> V2: Use CCF to describe the UART baud rate clock.Make some changes as
>>> discussed in the email
>>> V2 -> V3: add compatible = "amlogic,meson-gx-uart". Because it must change
>>> the DTS before it can be deleted
>>> V3 -> V4: Change CCF to describe the UART baud rate clock as discussed
>>> in the email.
>>>
>>> Link:https://lore.kernel.org/linux-amlogic/20211230102110.3861-4-yu.tu at amlogic.com/
>>>
>>> ? .../bindings/serial/amlogic,meson-uart.yaml?? |? 10 +-
>>> ? drivers/tty/serial/meson_uart.c?????????????? | 244 ++++++++++++------
>>> ? 2 files changed, 177 insertions(+), 77 deletions(-)
>>>
>>



From narmstrong at baylibre.com  Mon Jan 10 01:45:58 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 10:45:58 +0100
Subject: [PATCH 3/6] drm/meson: venc: add ENCL encoder setup for MIPI-DSI
 output
In-Reply-To: <CAFBinCA-df8Sedqh8Arh_BsMCHYv6-Kb3owrkFBd=W_EY2qxSA@mail.gmail.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-4-narmstrong@baylibre.com>
 <CAFBinCA-df8Sedqh8Arh_BsMCHYv6-Kb3owrkFBd=W_EY2qxSA@mail.gmail.com>
Message-ID: <6f62eeaa-1feb-274a-e1e8-377c582c428f@baylibre.com>

On 07/01/2022 23:33, Martin Blumenstingl wrote:
>  Hi Neil,
> 
> On Fri, Jan 7, 2022 at 3:57 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>>
>> This adds supports for the ENCL encoder connected to a MIPI-DSI transceiver on the
>> Amlogic AXG SoCs> Should this be "AXG and newer SoCs" or is this really AXG specific?

Yup should be, thanks for noting

> 
> [...]
>> +#define GAMMA_VCOM_POL    7     /* RW */
>> +#define GAMMA_RVS_OUT     6     /* RW */
>> +#define ADR_RDY           5     /* Read Only */
>> +#define WR_RDY            4     /* Read Only */
>> +#define RD_RDY            3     /* Read Only */
>> +#define GAMMA_TR          2     /* RW */
>> +#define GAMMA_SET         1     /* RW */
>> +#define GAMMA_EN          0     /* RW */
>> +
>> +#define H_RD              12
>> +#define H_AUTO_INC        11
>> +#define H_SEL_R           10
>> +#define H_SEL_G           9
>> +#define H_SEL_B           8
> I think all values above can be wrapped in the BIT() macro, then you
> don't need that below.

yep

> 
>> +#define HADR_MSB          7            /* 7:0 */
>> +#define HADR              0            /* 7:0 */
> Here GENMASK(7, 0) can be used for HADR
> 
> Also I think prefixing all macros above with their register name
> (L_GAMMA_CNTL_PORT_ or L_GAMMA_ADDR_PORT_) will make the code easier
> to read.
> 
> [...]
>> +       writel_relaxed(0x8000, priv->io_base + _REG(ENCL_VIDEO_MODE));
> The public S905 datasheet calls 0x8000 ENCL_PX_LN_CNT_SHADOW_EN

Thanks for searching !

> 
>> +       writel_relaxed(0x0418, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
> According to the public S905 datasheet this is:
> - BIT(3): ENCL_VIDEO_MODE_ADV_VFIFO_EN
> - BIT(4): ENCL_VIDEO_MODE_ADV_GAIN_HDTV
> - BIT(10): ENCL_SEL_GAMMA_RGB_IN
> 
>> +       writel_relaxed(0x1000, priv->io_base + _REG(ENCL_VIDEO_FILT_CTRL));
> I don't know the exact name but the 32-bit vendor kernel sources have
> a comment [0] saying that 0x1000 is "bypass filter"
> But maybe we can simply call it ENCL_VIDEO_FILT_CTRL_BYPASS_FILTER

Yep

> 
> [...]
>> +       writel_relaxed(3, priv->io_base + _REG(ENCL_VIDEO_RGBIN_CTRL));
> The public S905 datasheet says:
> - BIT(0): USE RGB data from VIU, furthermore a comment in the 3.10
> kernel sources make this more clear: bit[0] 1:RGB, 0:YUV
> - BIT(1): CFG_VIDEO_RGBIN_ZBLK
> 
>> +       /* default black pattern */
>> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_MDSEL));
>> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_Y));
>> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CB));
>> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CR));
>> +       writel_relaxed(1, priv->io_base + _REG(ENCL_TST_EN));
>> +       writel_bits_relaxed(BIT(3), 0, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
> same as above: ENCL_VIDEO_MODE_ADV_VFIFO_EN
> 
>> +
>> +       writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
>> +
>> +       writel_relaxed(0, priv->io_base + _REG(L_RGB_BASE_ADDR));
>> +       writel_relaxed(0x400, priv->io_base + _REG(L_RGB_COEFF_ADDR));
> note to self: L_RGB_COEFF_ADDR seems to contain some "magic" value,
> there's no further info in the 3.10 kernel sources or datasheet
> 
>> +       writel_relaxed(0x400, priv->io_base + _REG(L_DITH_CNTL_ADDR));
> According to the public S905 datasheet BIT(10) is DITH10_EN (10-bits
> Dithering to 8 Bits Enable).
> I am not sure if this would belong to the selected video mode/bit depth.
> I'll let other reviewers decide if this is relevant or not because I don't know.


it would probably for pre-GXL when the pipeline was 8bit, would probably need to add
a comment if someone wants to us DPI/LVDS on pre-GXL.

> 
> [...]
>> +       writel_relaxed(0, priv->io_base + _REG(L_INV_CNT_ADDR));
>> +       writel_relaxed(BIT(4) | BIT(5),
>> +                      priv->io_base + _REG(L_TCON_MISC_SEL_ADDR));
> the public S905 datasheet states:
> - BIT(4): STV1_SEL (STV1 is frame Signal)
> - BIT(5): STV2_SEL (STV2 is frame Signal)
> This doesn't seem helpful to me though, but maybe you can still create
> preprocessor macros for this (for consistency)?

yep

> 
> [...]
>> +       switch (priv->venc.current_mode) {
>> +       case MESON_VENC_MODE_MIPI_DSI:
>> +               writel_relaxed(0x200,
>> +                              priv->io_base + _REG(VENC_INTCTRL));
> the public S905 datasheet documents this as:
> - BIT(9): ENCP_LNRST_INT_EN (Progressive encoder filed change interrupt enable)
> Please add a preprocessor macro to make it consistent with
> VENC_INTCTRL_ENCI_LNRST_INT_EN which already exists and is used below.

Yep

Thanks for the review :-)

Neil

> 
> 
> Best regards,
> Martin
> 



From narmstrong at baylibre.com  Mon Jan 10 01:46:16 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 10:46:16 +0100
Subject: [PATCH 5/6] drm/meson: add DSI encoder
In-Reply-To: <CAFBinCCR4zftkvJWgX4T068BRsjVp9YhRbzgdBOR+tuMcGSZ3w@mail.gmail.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-6-narmstrong@baylibre.com>
 <CAFBinCCR4zftkvJWgX4T068BRsjVp9YhRbzgdBOR+tuMcGSZ3w@mail.gmail.com>
Message-ID: <b0200846-0346-a65b-ed98-c0c778040cd9@baylibre.com>

On 07/01/2022 23:35, Martin Blumenstingl wrote:
> Hi Neil,
> 
> On Fri, Jan 7, 2022 at 3:57 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
> 
> [...]
>> +       writel_bits_relaxed(BIT(3), BIT(3), priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
> see my comment on patch #3 from this series for BIT(3)
> 

Yep, thanks,

Neil

> 
> Best regards,
> Martin
> 



From narmstrong at baylibre.com  Mon Jan 10 01:51:49 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 10:51:49 +0100
Subject: [PATCH 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <CAFBinCB3+dSjQFRp5CBpGk5Qi8zoxRDRaobuCtXzU6VtM8+ryQ@mail.gmail.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-7-narmstrong@baylibre.com>
 <CAFBinCB3+dSjQFRp5CBpGk5Qi8zoxRDRaobuCtXzU6VtM8+ryQ@mail.gmail.com>
Message-ID: <508ea2d7-aee3-9409-023c-638b09d733b0@baylibre.com>

On 07/01/2022 23:49, Martin Blumenstingl wrote:
> Hi Neil,
> 
> some high-level comments from me below.
> 
> On Fri, Jan 7, 2022 at 3:58 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
> [...]
>> +/*  MIPI DSI Relative REGISTERs Definitions */
>> +/* For MIPI_DSI_TOP_CNTL */
>> +#define BIT_DPI_COLOR_MODE        20
>> +#define BIT_IN_COLOR_MODE         16
>> +#define BIT_CHROMA_SUBSAMPLE      14
>> +#define BIT_COMP2_SEL             12
>> +#define BIT_COMP1_SEL             10
>> +#define BIT_COMP0_SEL              8
>> +#define BIT_DE_POL                 6
>> +#define BIT_HSYNC_POL              5
>> +#define BIT_VSYNC_POL              4
>> +#define BIT_DPICOLORM              3
>> +#define BIT_DPISHUTDN              2
>> +#define BIT_EDPITE_INTR_PULSE      1
>> +#define BIT_ERR_INTR_PULSE         0
> Why not use BIT() and GENMASK() for these and prefixing them with
> MIPI_DSI_TOP_CNTL_?
> That would make them consistent with other parts of the meson sub-driver.

Yeah it was a lousy copy-paste from vendor driver, and I was lazy, but I'll fix this.

> 
> [...]
>> +static void meson_dw_mipi_dsi_hw_init(struct meson_dw_mipi_dsi *mipi_dsi)
>> +{
>> +       writel_relaxed((1 << 4) | (1 << 5) | (0 << 6),
>> +                      mipi_dsi->base + MIPI_DSI_TOP_CNTL);
> please use the macros from above
> 
>> +       writel_bits_relaxed(0xf, 0xf, mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);
>> +       writel_bits_relaxed(0xf, 0, mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);
> 
> [...]
>> +       phy_power_on(mipi_dsi->phy);
> Please propagate the error code here.
> Also shouldn't this go to a new dw_mipi_dsi_phy_power_on() as the PHY
> driver uses the updated settings from phy_configure only in it's
> .power_on callback?

Good point, let me check that.

> 
> [...]
>> +       phy_configure(mipi_dsi->phy, &mipi_dsi->phy_opts);
> please propagate the error code here as the PHY driver has some
> explicit code to return an error in it's .phy_configure callback
> 
> [...]
>> +       phy_init(mipi_dsi->phy);
> please propagate the error code here
> 
> [...]
>> +       phy_exit(mipi_dsi->phy);
> please propagate the error code here

ok for the 3

> 
> [...]
>> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +       mipi_dsi->base = devm_ioremap_resource(&pdev->dev, res);
> other parts of the meson DRM driver have been converted to use
> devm_platform_ioremap_resource()
> I suggest updating this as well to simplify the code here

Yep, again lazyness

> 
> [...]
>> +       mipi_dsi->phy = devm_phy_get(&pdev->dev, "dphy");
>> +       if (IS_ERR(mipi_dsi->phy)) {
>> +               ret = PTR_ERR(mipi_dsi->phy);
>> +               dev_err(&pdev->dev, "failed to get mipi dphy: %d\n", ret);
>> +               return ret;
> you can simplify this with:
>   return dev_err_probe(&pdev->dev, PTR_ERR(mipi_dsi->phy, "failed to
> get mipi dphy\n");
> 
> [...]
>> +       mipi_dsi->px_clk = devm_clk_get(&pdev->dev, "px_clk");
>> +       if (IS_ERR(mipi_dsi->px_clk)) {
>> +               dev_err(&pdev->dev, "Unable to get PLL clk\n");
>> +               return PTR_ERR(mipi_dsi->px_clk);
> you can simplify this with:
>   return dev_err_probe(&pdev->dev, PTR_ERR(mipi_dsi->px_clk, "Unable
> to get PLL clk\n");
> Also should it say s/PLL clk/px clock/?
> 
> [...]
>> +       top_rst = devm_reset_control_get_exclusive(&pdev->dev, "top");
>> +       if (IS_ERR(top_rst)) {
>> +               ret = PTR_ERR(top_rst);
>> +
>> +               if (ret != -EPROBE_DEFER)
>> +                       dev_err(&pdev->dev, "Unable to get reset control: %d\n", ret);
>> +
>> +               return ret;
> you can simplify this with:
>   return dev_err_probe(&pdev->dev, PTR_ERR(top_rst, "Unable to get
> reset control\n");
> 
> [...]
>> +       mipi_dsi->dmd = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata);
>> +       if (IS_ERR(mipi_dsi->dmd)) {
>> +               ret = PTR_ERR(mipi_dsi->dmd);
>> +               if (ret != -EPROBE_DEFER)
>> +                       dev_err(&pdev->dev,
>> +                               "Failed to probe dw_mipi_dsi: %d\n", ret);
> you can simplify this with:
>   dev_err_probe(&pdev->dev, ret, "Failed to probe dw_mipi_dsi\n");
>

Again 4 lazyness effects, will fix !

Thanks,
Neil


> 
> Best regards,
> Martin
> 



From yu.tu at amlogic.com  Mon Jan 10 02:42:09 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 18:42:09 +0800
Subject: [PATCH V5 0/5] The UART driver compatible with
Message-ID: <20220110104214.25321-1-yu.tu@amlogic.com>

Using the common Clock code to describe the UART baud rate
clock makes it easier for the UART driver to be compatible
with the baud rate requirements of the UART IP on different
meson chips. Add Meson S4 SoC compatible.

Yu Tu (5):
  dt-bindings: serial: meson: Drop legacy compatible.
  tty: serial: meson: Move request the register region.
  tty: serial: meson: Using the common clock code describe.
  tty: serial: meson: Make some bit of the REG5 register writable.
  tty: serial: meson: Added S4 SOC compatibility.

V4 -> V5: Change error format.
V3 -> V4: Change CCF to describe the UART baud rate clock as discussed
in the email.
V2 -> V3: add compatible = "amlogic,meson-gx-uart". Because it must change
the DTS before it can be deleted
V1 -> V2: Use CCF to describe the UART baud rate clock.Make some changes as
discussed in the email

Link:https://lore.kernel.org/linux-amlogic/20220110085604.18042-1-yu.tu at amlogic.com/

 .../bindings/serial/amlogic,meson-uart.yaml   |  10 +-
 drivers/tty/serial/meson_uart.c               | 244 ++++++++++++------
 2 files changed, 177 insertions(+), 77 deletions(-)

-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 02:42:10 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 18:42:10 +0800
Subject: [PATCH V5 1/5] dt-bindings: serial: meson: Drop legacy compatible.
In-Reply-To: <20220110104214.25321-1-yu.tu@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
Message-ID: <20220110104214.25321-2-yu.tu@amlogic.com>

Deprecated, don't use anymore because legacy amlogic,meson-gx-uart
compatible. Don't differentiate between GXBB, GXL and G12A which
have different revisions of the UART IP. So it's split into
GXBB,GXL and G12A.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 .../devicetree/bindings/serial/amlogic,meson-uart.yaml | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
index 72e8868db3e0..ad9f1f4537a0 100644
--- a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
+++ b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
@@ -28,7 +28,10 @@ properties:
               - amlogic,meson6-uart
               - amlogic,meson8-uart
               - amlogic,meson8b-uart
-              - amlogic,meson-gx-uart
+              - amlogic,meson-gx-uart # deprecated, use revision specific property below
+              - amlogic,meson-gxbb-uart
+              - amlogic,meson-gxl-uart
+              - amlogic,meson-g12a-uart
               - amlogic,meson-s4-uart
           - const: amlogic,meson-ao-uart
       - description: Everything-Else power domain UART controller
@@ -36,7 +39,10 @@ properties:
           - amlogic,meson6-uart
           - amlogic,meson8-uart
           - amlogic,meson8b-uart
-          - amlogic,meson-gx-uart
+          - amlogic,meson-gx-uart # deprecated, use revision specific property below
+          - amlogic,meson-gxbb-uart
+          - amlogic,meson-gxl-uart
+          - amlogic,meson-g12a-uart
           - amlogic,meson-s4-uart
 
   reg:
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 02:42:11 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 18:42:11 +0800
Subject: [PATCH V5 2/5] tty: serial: meson: Move request the register region.
In-Reply-To: <20220110104214.25321-1-yu.tu@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
Message-ID: <20220110104214.25321-3-yu.tu@amlogic.com>

This simplifies resetting the UART controller during probe
and will make it easier to integrate the common clock code
which will require the registers at probe time as well.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 24 ++++++------------------
 1 file changed, 6 insertions(+), 18 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 45e00d928253..7570958d010c 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -395,24 +395,11 @@ static int meson_uart_verify_port(struct uart_port *port,
 
 static void meson_uart_release_port(struct uart_port *port)
 {
-	devm_iounmap(port->dev, port->membase);
-	port->membase = NULL;
-	devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
+	/* nothing to do */
 }
 
 static int meson_uart_request_port(struct uart_port *port)
 {
-	if (!devm_request_mem_region(port->dev, port->mapbase, port->mapsize,
-				     dev_name(port->dev))) {
-		dev_err(port->dev, "Memory region busy\n");
-		return -EBUSY;
-	}
-
-	port->membase = devm_ioremap(port->dev, port->mapbase,
-					     port->mapsize);
-	if (!port->membase)
-		return -ENOMEM;
-
 	return 0;
 }
 
@@ -733,6 +720,10 @@ static int meson_uart_probe(struct platform_device *pdev)
 	if (!port)
 		return -ENOMEM;
 
+	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
+	if (IS_ERR(port->membase))
+		return PTR_ERR(port->membase);
+
 	ret = meson_uart_probe_clocks(pdev, port);
 	if (ret)
 		return ret;
@@ -754,10 +745,7 @@ static int meson_uart_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, port);
 
 	/* reset port before registering (and possibly registering console) */
-	if (meson_uart_request_port(port) >= 0) {
-		meson_uart_reset(port);
-		meson_uart_release_port(port);
-	}
+	meson_uart_reset(port);
 
 	ret = uart_add_one_port(&meson_uart_driver, port);
 	if (ret)
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 02:42:12 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 18:42:12 +0800
Subject: [PATCH V5 3/5] tty: serial: meson: Using the common clock code
 describe.
In-Reply-To: <20220110104214.25321-1-yu.tu@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
Message-ID: <20220110104214.25321-4-yu.tu@amlogic.com>

Using the common Clock code to describe the UART baud rate clock
makes it easier for the UART driver to be compatible with the
baud rate requirements of the UART IP on different meson chips.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
 1 file changed, 163 insertions(+), 61 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 7570958d010c..1004fd0b0c9e 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -65,9 +66,7 @@
 #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
 
 /* AML_UART_REG5 bits */
-#define AML_UART_BAUD_MASK		0x7fffff
 #define AML_UART_BAUD_USE		BIT(23)
-#define AML_UART_BAUD_XTAL		BIT(24)
 
 #define AML_UART_PORT_NUM		12
 #define AML_UART_PORT_OFFSET		6
@@ -76,6 +75,13 @@
 #define AML_UART_POLL_USEC		5
 #define AML_UART_TIMEOUT_USEC		10000
 
+struct meson_uart_data {
+	struct uart_port	port;
+	struct clk		*pclk;
+	struct clk		*baud_clk;
+	bool			use_xtal_clk;
+};
+
 static struct uart_driver meson_uart_driver;
 
 static struct uart_port *meson_ports[AML_UART_PORT_NUM];
@@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
 static int meson_uart_startup(struct uart_port *port)
 {
 	u32 val;
-	int ret = 0;
+	int ret;
 
-	val = readl(port->membase + AML_UART_CONTROL);
-	val |= AML_UART_CLEAR_ERR;
-	writel(val, port->membase + AML_UART_CONTROL);
-	val &= ~AML_UART_CLEAR_ERR;
-	writel(val, port->membase + AML_UART_CONTROL);
+	meson_uart_reset(port);
 
+	val = readl(port->membase + AML_UART_CONTROL);
 	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
 	writel(val, port->membase + AML_UART_CONTROL);
 
@@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port *port)
 
 static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
 {
+	struct meson_uart_data *private_data = port->private_data;
 	u32 val;
 
 	while (!meson_uart_tx_empty(port))
 		cpu_relax();
 
-	if (port->uartclk == 24000000) {
-		val = ((port->uartclk / 3) / baud) - 1;
-		val |= AML_UART_BAUD_XTAL;
-	} else {
-		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
-	}
+	val = readl(port->membase + AML_UART_REG5);
 	val |= AML_UART_BAUD_USE;
 	writel(val, port->membase + AML_UART_REG5);
+
+	clk_set_rate(private_data->baud_clk, baud);
 }
 
 static void meson_uart_set_termios(struct uart_port *port,
@@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
 
 static void meson_uart_release_port(struct uart_port *port)
 {
-	/* nothing to do */
+	struct meson_uart_data *private_data = port->private_data;
+
+	clk_disable_unprepare(private_data->baud_clk);
+	clk_disable_unprepare(private_data->pclk);
 }
 
 static int meson_uart_request_port(struct uart_port *port)
 {
+	struct meson_uart_data *private_data = port->private_data;
+	int ret;
+
+	ret = clk_prepare_enable(private_data->pclk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(private_data->baud_clk);
+	if (ret) {
+		clk_disable_unprepare(private_data->pclk);
+		return ret;
+	}
+
 	return 0;
 }
 
@@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
 	.cons		= MESON_SERIAL_CONSOLE,
 };
 
-static inline struct clk *meson_uart_probe_clock(struct device *dev,
-						 const char *id)
+#define CLK_NAME(name) \
+({\
+	char clk_name[32];\
+	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
+	clk_name;\
+})
+
+static struct clk_div_table xtal_div_table[] = {
+	{ 0, 3  },
+	{ 1, 1  },
+	{ 2, 2  },
+	{ 3, 2  },
+};
+
+static int meson_uart_probe_clocks(struct uart_port *port)
 {
-	struct clk *clk = NULL;
-	int ret;
+	struct meson_uart_data *private_data = port->private_data;
+	struct clk *clk_baud, *clk_xtal;
+	struct clk_hw *hw;
+	struct clk_parent_data use_xtal_mux_parents[2] = {
+		{ .index = -1, },
+		{ .index = -1, },
+	};
 
-	clk = devm_clk_get(dev, id);
-	if (IS_ERR(clk))
-		return clk;
+	private_data->pclk = devm_clk_get(port->dev, "pclk");
+	if (IS_ERR(private_data->pclk))
+		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
+				     "Failed to get the 'pclk' clock\n");
 
-	ret = clk_prepare_enable(clk);
-	if (ret) {
-		dev_err(dev, "couldn't enable clk\n");
-		return ERR_PTR(ret);
+	clk_baud = devm_clk_get(port->dev, "baud");
+	if (IS_ERR(clk_baud)) {
+		dev_err(port->dev, "Failed to get the 'baud' clock\n");
+		return PTR_ERR(clk_baud);
 	}
 
-	devm_add_action_or_reset(dev,
-			(void(*)(void *))clk_disable_unprepare,
-			clk);
-
-	return clk;
-}
-
-static int meson_uart_probe_clocks(struct platform_device *pdev,
-				   struct uart_port *port)
-{
-	struct clk *clk_xtal = NULL;
-	struct clk *clk_pclk = NULL;
-	struct clk *clk_baud = NULL;
-
-	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
-	if (IS_ERR(clk_pclk))
-		return PTR_ERR(clk_pclk);
-
-	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
+	clk_xtal = devm_clk_get(port->dev, "xtal");
 	if (IS_ERR(clk_xtal))
-		return PTR_ERR(clk_xtal);
-
-	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
-	if (IS_ERR(clk_baud))
-		return PTR_ERR(clk_baud);
+		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
+				     "Failed to get the 'xtal' clock\n");
+
+	if (private_data->use_xtal_clk) {
+		hw = devm_clk_hw_register_divider_table(port->dev,
+							CLK_NAME(xtal_div),
+							__clk_get_name(clk_baud),
+							CLK_SET_RATE_NO_REPARENT,
+							port->membase + AML_UART_REG5,
+							26, 2,
+							CLK_DIVIDER_READ_ONLY,
+							xtal_div_table, NULL);
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		use_xtal_mux_parents[1].hw = hw;
+	} else {
+		hw = devm_clk_hw_register_fixed_factor(port->dev,
+						       CLK_NAME(clk81_div4),
+						       __clk_get_name(clk_baud),
+						       CLK_SET_RATE_NO_REPARENT,
+						       1, 4);
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		use_xtal_mux_parents[0].hw = hw;
+	}
 
-	port->uartclk = clk_get_rate(clk_baud);
+	hw = __devm_clk_hw_register_mux(port->dev, NULL,
+					CLK_NAME(use_xtal),
+					ARRAY_SIZE(use_xtal_mux_parents),
+					NULL, NULL,
+					use_xtal_mux_parents,
+					CLK_SET_RATE_PARENT,
+					port->membase + AML_UART_REG5,
+					24, 0x1,
+					CLK_MUX_READ_ONLY,
+					NULL, NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	port->uartclk = clk_hw_get_rate(hw);
+
+	hw = devm_clk_hw_register_divider(port->dev,
+					  CLK_NAME(baud_div),
+					  clk_hw_get_name(hw),
+					  CLK_SET_RATE_PARENT,
+					  port->membase + AML_UART_REG5,
+					  0, 23,
+					  CLK_DIVIDER_ROUND_CLOSEST,
+					  NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
 
 	return 0;
 }
 
 static int meson_uart_probe(struct platform_device *pdev)
 {
+	struct meson_uart_data *private_data;
 	struct resource *res_mem;
 	struct uart_port *port;
 	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
@@ -716,18 +783,20 @@ static int meson_uart_probe(struct platform_device *pdev)
 		return -EBUSY;
 	}
 
-	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
-	if (!port)
+	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
+				    GFP_KERNEL);
+	if (!private_data)
 		return -ENOMEM;
 
+	if (device_get_match_data(&pdev->dev))
+		private_data->use_xtal_clk = true;
+
+	port = &private_data->port;
+
 	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
 	if (IS_ERR(port->membase))
 		return PTR_ERR(port->membase);
 
-	ret = meson_uart_probe_clocks(pdev, port);
-	if (ret)
-		return ret;
-
 	port->iotype = UPIO_MEM;
 	port->mapbase = res_mem->start;
 	port->mapsize = resource_size(res_mem);
@@ -740,7 +809,11 @@ static int meson_uart_probe(struct platform_device *pdev)
 	port->x_char = 0;
 	port->ops = &meson_uart_ops;
 	port->fifosize = fifosize;
+	port->private_data = private_data;
 
+	ret = meson_uart_probe_clocks(port);
+	if (ret)
+		return ret;
 	meson_ports[pdev->id] = port;
 	platform_set_drvdata(pdev, port);
 
@@ -766,10 +839,39 @@ static int meson_uart_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id meson_uart_dt_match[] = {
-	{ .compatible = "amlogic,meson6-uart" },
-	{ .compatible = "amlogic,meson8-uart" },
-	{ .compatible = "amlogic,meson8b-uart" },
-	{ .compatible = "amlogic,meson-gx-uart" },
+	{
+		.compatible = "amlogic,meson6-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson8-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson8b-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson-gxbb-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson-gxl-uart",
+		.data = (void *)true,
+	},
+	{
+		.compatible = "amlogic,meson-g12a-uart",
+		.data = (void *)true,
+	},
+	/*
+	 * deprecated, don't use anymore because it doesn't differentiate
+	 * between GXBB, GXL and G12A which have different revisions
+	 * of the UART IP.
+	 */
+	{
+		.compatible = "amlogic,meson-gx-uart",
+		.data = (void *)false,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 02:42:13 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 18:42:13 +0800
Subject: [PATCH V5 4/5] tty: serial: meson: Make some bit of the REG5 register
 writable.
In-Reply-To: <20220110104214.25321-1-yu.tu@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
Message-ID: <20220110104214.25321-5-yu.tu@amlogic.com>

The UART_REG5 register defaults to 0. The console port is set in
ROMCODE. But other UART ports default to 0, so make bit24 and
bit[26,27] writable so that the UART can choose a more
appropriate clock.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 1004fd0b0c9e..fd128878e91a 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -693,7 +693,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
 							CLK_SET_RATE_NO_REPARENT,
 							port->membase + AML_UART_REG5,
 							26, 2,
-							CLK_DIVIDER_READ_ONLY,
+							CLK_DIVIDER_ROUND_CLOSEST,
 							xtal_div_table, NULL);
 		if (IS_ERR(hw))
 			return PTR_ERR(hw);
@@ -719,7 +719,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
 					CLK_SET_RATE_PARENT,
 					port->membase + AML_UART_REG5,
 					24, 0x1,
-					CLK_MUX_READ_ONLY,
+					CLK_MUX_ROUND_CLOSEST,
 					NULL, NULL);
 	if (IS_ERR(hw))
 		return PTR_ERR(hw);
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 02:42:14 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 18:42:14 +0800
Subject: [PATCH V5 5/5] tty: serial: meson: Added S4 SOC compatibility.
In-Reply-To: <20220110104214.25321-1-yu.tu@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
Message-ID: <20220110104214.25321-6-yu.tu@amlogic.com>

Make UART driver compatible with S4 SOC UART.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index fd128878e91a..d6aa04cc31ba 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -863,6 +863,10 @@ static const struct of_device_id meson_uart_dt_match[] = {
 		.compatible = "amlogic,meson-g12a-uart",
 		.data = (void *)true,
 	},
+	{
+		.compatible = "amlogic,meson-s4-uart",
+		.data = (void *)true,
+	},
 	/*
 	 * deprecated, don't use anymore because it doesn't differentiate
 	 * between GXBB, GXL and G12A which have different revisions
-- 
2.33.1



From jirislaby at kernel.org  Mon Jan 10 03:58:19 2022
From: jirislaby at kernel.org (Jiri Slaby)
Date: Mon, 10 Jan 2022 12:58:19 +0100
Subject: [PATCH V5 2/5] tty: serial: meson: Move request the register
 region.
In-Reply-To: <20220110104214.25321-3-yu.tu@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
 <20220110104214.25321-3-yu.tu@amlogic.com>
Message-ID: <01066e66-5d97-ab40-b4a6-99e962b47073@kernel.org>

Hi,

On 10. 01. 22, 11:42, Yu Tu wrote:
> This simplifies resetting the UART controller during probe
> and will make it easier to integrate the common clock code
> which will require the registers at probe time as well.

And you are *also* switching devm_request_mem_region+devm_ioremap into 
devm_ioremap_resource without even noting it here. It should've been 
done in a separate patch.

And no, do not resend a new version in the next few days. Having v5 in 
20 days is a bit too much. Give maintainers and reviewers some more 
space to express themselves.
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>   drivers/tty/serial/meson_uart.c | 24 ++++++------------------
>   1 file changed, 6 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 45e00d928253..7570958d010c 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -395,24 +395,11 @@ static int meson_uart_verify_port(struct uart_port *port,
>   
>   static void meson_uart_release_port(struct uart_port *port)
>   {
> -	devm_iounmap(port->dev, port->membase);
> -	port->membase = NULL;
> -	devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
> +	/* nothing to do */
>   }
>   
>   static int meson_uart_request_port(struct uart_port *port)
>   {
> -	if (!devm_request_mem_region(port->dev, port->mapbase, port->mapsize,
> -				     dev_name(port->dev))) {
> -		dev_err(port->dev, "Memory region busy\n");
> -		return -EBUSY;
> -	}
> -
> -	port->membase = devm_ioremap(port->dev, port->mapbase,
> -					     port->mapsize);
> -	if (!port->membase)
> -		return -ENOMEM;
> -
>   	return 0;
>   }
>   
> @@ -733,6 +720,10 @@ static int meson_uart_probe(struct platform_device *pdev)
>   	if (!port)
>   		return -ENOMEM;
>   
> +	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
> +	if (IS_ERR(port->membase))
> +		return PTR_ERR(port->membase);
> +
>   	ret = meson_uart_probe_clocks(pdev, port);
>   	if (ret)
>   		return ret;
> @@ -754,10 +745,7 @@ static int meson_uart_probe(struct platform_device *pdev)
>   	platform_set_drvdata(pdev, port);
>   
>   	/* reset port before registering (and possibly registering console) */
> -	if (meson_uart_request_port(port) >= 0) {
> -		meson_uart_reset(port);
> -		meson_uart_release_port(port);
> -	}
> +	meson_uart_reset(port);
>   
>   	ret = uart_add_one_port(&meson_uart_driver, port);
>   	if (ret)

thanks,
-- 
js
suse labs


From jirislaby at kernel.org  Mon Jan 10 04:11:50 2022
From: jirislaby at kernel.org (Jiri Slaby)
Date: Mon, 10 Jan 2022 13:11:50 +0100
Subject: [PATCH V5 3/5] tty: serial: meson: Using the common clock code
 describe.
In-Reply-To: <20220110104214.25321-4-yu.tu@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
 <20220110104214.25321-4-yu.tu@amlogic.com>
Message-ID: <327f985f-bbf1-00ba-d203-cc9d5bbd955c@kernel.org>

Hi,

"Subject: Using the common clock code describe."

Please reformulate that ^^^ -- I cannot make any sense of it. And avoid 
adding a period to the subject. PLease see others' commit logs.

On 10. 01. 22, 11:42, Yu Tu wrote:
> Using the common Clock code to describe the UART baud rate clock
> makes it easier for the UART driver to be compatible with the
> baud rate requirements of the UART IP on different meson chips.



> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>   drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
>   1 file changed, 163 insertions(+), 61 deletions(-)
> 
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 7570958d010c..1004fd0b0c9e 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -6,6 +6,7 @@
>    */
>   
>   #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>   #include <linux/console.h>
>   #include <linux/delay.h>
>   #include <linux/init.h>
> @@ -65,9 +66,7 @@
>   #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>   
>   /* AML_UART_REG5 bits */
> -#define AML_UART_BAUD_MASK		0x7fffff
>   #define AML_UART_BAUD_USE		BIT(23)
> -#define AML_UART_BAUD_XTAL		BIT(24)
>   
>   #define AML_UART_PORT_NUM		12
>   #define AML_UART_PORT_OFFSET		6
> @@ -76,6 +75,13 @@
>   #define AML_UART_POLL_USEC		5
>   #define AML_UART_TIMEOUT_USEC		10000
>   
> +struct meson_uart_data {
> +	struct uart_port	port;
> +	struct clk		*pclk;
> +	struct clk		*baud_clk;
> +	bool			use_xtal_clk;
> +};
> +
>   static struct uart_driver meson_uart_driver;
>   
>   static struct uart_port *meson_ports[AML_UART_PORT_NUM];
> @@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
>   static int meson_uart_startup(struct uart_port *port)
>   {
>   	u32 val;
> -	int ret = 0;
> +	int ret;
>   
> -	val = readl(port->membase + AML_UART_CONTROL);
> -	val |= AML_UART_CLEAR_ERR;
> -	writel(val, port->membase + AML_UART_CONTROL);
> -	val &= ~AML_UART_CLEAR_ERR;
> -	writel(val, port->membase + AML_UART_CONTROL);
> +	meson_uart_reset(port);

Why is this OK? We didn't use to reset it.

And why is this not done in a separate patch?


> +	val = readl(port->membase + AML_UART_CONTROL);
>   	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>   	writel(val, port->membase + AML_UART_CONTROL);
>   
> @@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port *port)
>   
>   static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
>   {
> +	struct meson_uart_data *private_data = port->private_data;
>   	u32 val;
>   
>   	while (!meson_uart_tx_empty(port))
>   		cpu_relax();
>   
> -	if (port->uartclk == 24000000) {
> -		val = ((port->uartclk / 3) / baud) - 1;
> -		val |= AML_UART_BAUD_XTAL;
> -	} else {
> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
> -	}
> +	val = readl(port->membase + AML_UART_REG5);
>   	val |= AML_UART_BAUD_USE;
>   	writel(val, port->membase + AML_UART_REG5);
> +
> +	clk_set_rate(private_data->baud_clk, baud);
>   }
>   
>   static void meson_uart_set_termios(struct uart_port *port,
> @@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>   
>   static void meson_uart_release_port(struct uart_port *port)
>   {
> -	/* nothing to do */
> +	struct meson_uart_data *private_data = port->private_data;
> +
> +	clk_disable_unprepare(private_data->baud_clk);
> +	clk_disable_unprepare(private_data->pclk);
>   }
>   
>   static int meson_uart_request_port(struct uart_port *port)
>   {
> +	struct meson_uart_data *private_data = port->private_data;
> +	int ret;
> +
> +	ret = clk_prepare_enable(private_data->pclk);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_prepare_enable(private_data->baud_clk);
> +	if (ret) {
> +		clk_disable_unprepare(private_data->pclk);
> +		return ret;
> +	}
> +
>   	return 0;
>   }
>   
> @@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
>   	.cons		= MESON_SERIAL_CONSOLE,
>   };
>   
> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
> -						 const char *id)
> +#define CLK_NAME(name) \
> +({\
> +	char clk_name[32];\
> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
> +	clk_name;\
> +})

This is cryptic and duplicates the variable on the stack. Why not expand 
the macro and delete it then?

> +
> +static struct clk_div_table xtal_div_table[] = {
> +	{ 0, 3  },

An extra space here and there:

> +	{ 1, 1  },
> +	{ 2, 2  },
> +	{ 3, 2  },
> +};
> +
> +static int meson_uart_probe_clocks(struct uart_port *port)
>   {
> -	struct clk *clk = NULL;
> -	int ret;
> +	struct meson_uart_data *private_data = port->private_data;
> +	struct clk *clk_baud, *clk_xtal;
> +	struct clk_hw *hw;
> +	struct clk_parent_data use_xtal_mux_parents[2] = {
> +		{ .index = -1, },
> +		{ .index = -1, },
> +	};
>   
> -	clk = devm_clk_get(dev, id);
> -	if (IS_ERR(clk))
> -		return clk;
> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
> +	if (IS_ERR(private_data->pclk))
> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
> +				     "Failed to get the 'pclk' clock\n");
>   
> -	ret = clk_prepare_enable(clk);
> -	if (ret) {
> -		dev_err(dev, "couldn't enable clk\n");
> -		return ERR_PTR(ret);
> +	clk_baud = devm_clk_get(port->dev, "baud");
> +	if (IS_ERR(clk_baud)) {
> +		dev_err(port->dev, "Failed to get the 'baud' clock\n");
> +		return PTR_ERR(clk_baud);
>   	}
>   
> -	devm_add_action_or_reset(dev,
> -			(void(*)(void *))clk_disable_unprepare,
> -			clk);
> -
> -	return clk;
> -}
> -
> -static int meson_uart_probe_clocks(struct platform_device *pdev,
> -				   struct uart_port *port)
> -{
> -	struct clk *clk_xtal = NULL;
> -	struct clk *clk_pclk = NULL;
> -	struct clk *clk_baud = NULL;
> -
> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
> -	if (IS_ERR(clk_pclk))
> -		return PTR_ERR(clk_pclk);
> -
> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>   	if (IS_ERR(clk_xtal))
> -		return PTR_ERR(clk_xtal);
> -
> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
> -	if (IS_ERR(clk_baud))
> -		return PTR_ERR(clk_baud);
> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
> +				     "Failed to get the 'xtal' clock\n");
> +
> +	if (private_data->use_xtal_clk) {
> +		hw = devm_clk_hw_register_divider_table(port->dev,
> +							CLK_NAME(xtal_div),
> +							__clk_get_name(clk_baud),
> +							CLK_SET_RATE_NO_REPARENT,
> +							port->membase + AML_UART_REG5,
> +							26, 2,
> +							CLK_DIVIDER_READ_ONLY,
> +							xtal_div_table, NULL);
> +		if (IS_ERR(hw))
> +			return PTR_ERR(hw);
> +
> +		use_xtal_mux_parents[1].hw = hw;
> +	} else {
> +		hw = devm_clk_hw_register_fixed_factor(port->dev,
> +						       CLK_NAME(clk81_div4),
> +						       __clk_get_name(clk_baud),
> +						       CLK_SET_RATE_NO_REPARENT,
> +						       1, 4);
> +		if (IS_ERR(hw))
> +			return PTR_ERR(hw);
> +
> +		use_xtal_mux_parents[0].hw = hw;
> +	}
>   
> -	port->uartclk = clk_get_rate(clk_baud);
> +	hw = __devm_clk_hw_register_mux(port->dev, NULL,
> +					CLK_NAME(use_xtal),
> +					ARRAY_SIZE(use_xtal_mux_parents),
> +					NULL, NULL,
> +					use_xtal_mux_parents,
> +					CLK_SET_RATE_PARENT,
> +					port->membase + AML_UART_REG5,
> +					24, 0x1,
> +					CLK_MUX_READ_ONLY,
> +					NULL, NULL);
> +	if (IS_ERR(hw))
> +		return PTR_ERR(hw);
> +
> +	port->uartclk = clk_hw_get_rate(hw);
> +
> +	hw = devm_clk_hw_register_divider(port->dev,
> +					  CLK_NAME(baud_div),
> +					  clk_hw_get_name(hw),
> +					  CLK_SET_RATE_PARENT,
> +					  port->membase + AML_UART_REG5,
> +					  0, 23,
> +					  CLK_DIVIDER_ROUND_CLOSEST,
> +					  NULL);
> +	if (IS_ERR(hw))
> +		return PTR_ERR(hw);
> +
> +	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
>   
>   	return 0;
>   }



-- 
js
suse labs


From Qianggui.Song at amlogic.com  Mon Jan 10 04:27:03 2022
From: Qianggui.Song at amlogic.com (qianggui.song)
Date: Mon, 10 Jan 2022 20:27:03 +0800
Subject: [PATCH 2/4] irqchip/meson-gpio: support more than 8 channels gpio
 irq line
In-Reply-To: <87tueetsvz.wl-maz@kernel.org>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-3-qianggui.song@amlogic.com>
 <87tueetsvz.wl-maz@kernel.org>
Message-ID: <3235dfc6-413c-7582-8204-2ac8ad0952d4@amlogic.com>



On 1/8/22 6:37 PM, Marc Zyngier wrote:
> 
> On Sat, 08 Jan 2022 08:42:16 +0000,
> Qianggui Song <qianggui.song at amlogic.com> wrote:
>>
>> Current meson gpio irqchip driver only support 8 channels for gpio irq
>> line, later chips may have more then 8 channels, so need to modify code
>> to support more.
>>
>> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
>> ---
>>   drivers/irqchip/irq-meson-gpio.c | 33 +++++++++++++++++++++++---------
>>   1 file changed, 24 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
>> index d90ff0b92480..6a7b4fb13452 100644
>> --- a/drivers/irqchip/irq-meson-gpio.c
>> +++ b/drivers/irqchip/irq-meson-gpio.c
>> @@ -16,7 +16,6 @@
>>   #include <linux/of.h>
>>   #include <linux/of_address.h>
>>   
>> -#define NUM_CHANNEL 8
>>   #define MAX_INPUT_MUX 256
>>   
>>   #define REG_EDGE_POL	0x00
>> @@ -60,6 +59,7 @@ struct irq_ctl_ops {
>>   
>>   struct meson_gpio_irq_params {
>>   	unsigned int nr_hwirq;
>> +	unsigned int channel_num;
> 
> For consistency, please name this nr_channels.
Okay
> 
>>   	bool support_edge_both;
>>   	unsigned int edge_both_offset;
>>   	unsigned int edge_single_offset;
>> @@ -81,6 +81,7 @@ struct meson_gpio_irq_params {
>>   	.edge_single_offset = 0,				\
>>   	.pol_low_offset = 16,					\
>>   	.pin_sel_mask = 0xff,					\
>> +	.channel_num = 8,					\
>>   
>>   #define INIT_MESON_A1_COMMON_DATA(irqs)				\
>>   	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
>> @@ -90,6 +91,7 @@ struct meson_gpio_irq_params {
>>   	.edge_single_offset = 8,				\
>>   	.pol_low_offset = 0,					\
>>   	.pin_sel_mask = 0x7f,					\
>> +	.channel_num = 8,					\
>>   
>>   static const struct meson_gpio_irq_params meson8_params = {
>>   	INIT_MESON8_COMMON_DATA(134)
>> @@ -136,8 +138,9 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
>>   struct meson_gpio_irq_controller {
>>   	const struct meson_gpio_irq_params *params;
>>   	void __iomem *base;
>> -	u32 channel_irqs[NUM_CHANNEL];
>> -	DECLARE_BITMAP(channel_map, NUM_CHANNEL);
>> +	u32 *channel_irqs;
>> +	unsigned long *channel_map;
>> +	u8 channel_num;
> 
> Same thing. Though this is completely superfluous, see below.
I will remove this variable
> 
>>   	spinlock_t lock;
>>   };
>>   
>> @@ -207,8 +210,8 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
>>   	spin_lock_irqsave(&ctl->lock, flags);
>>   
>>   	/* Find a free channel */
>> -	idx = find_first_zero_bit(ctl->channel_map, NUM_CHANNEL);
>> -	if (idx >= NUM_CHANNEL) {
>> +	idx = find_first_zero_bit(ctl->channel_map, ctl->channel_num);
>> +	if (idx >= ctl->channel_num) {
>>   		spin_unlock_irqrestore(&ctl->lock, flags);
>>   		pr_err("No channel available\n");
>>   		return -ENOSPC;
>> @@ -447,13 +450,25 @@ static int meson_gpio_irq_parse_dt(struct device_node *node, struct meson_gpio_i
>>   
>>   	ctl->params = match->data;
>>   
>> +	ctl->channel_num = ctl->params->channel_num;
> 
> Since you already have a pointer to params, why do you need to
> duplicate this information?
will remove it next patch
> 
>> +	ctl->channel_irqs = kcalloc(ctl->channel_num,
>> +				    sizeof(*ctl->channel_irqs), GFP_KERNEL);
>> +	if (!ctl->channel_irqs)
>> +		return -ENOMEM;
>> +
>> +	ctl->channel_map = bitmap_zalloc(ctl->params->channel_num, GFP_KERNEL);
>> +	if (!ctl->channel_map) {
>> +		kfree(ctl->channel_irqs);
>> +		return -ENOMEM;
>> +	}
>> +
>>   	ret = of_property_read_variable_u32_array(node,
>>   						  "amlogic,channel-interrupts",
>>   						  ctl->channel_irqs,
>> -						  NUM_CHANNEL,
>> -						  NUM_CHANNEL);
>> +						  ctl->channel_num,
>> +						  ctl->channel_num);
>>   	if (ret < 0) {
>> -		pr_err("can't get %d channel interrupts\n", NUM_CHANNEL);
>> +		pr_err("can't get %d channel interrupts\n", ctl->channel_num);
>>   		return ret;
> 
> You are now leaking the bitmap and channel_map allocations.
will fix it next patch
> 
> 	M.
> 


From Qianggui.Song at amlogic.com  Mon Jan 10 04:28:00 2022
From: Qianggui.Song at amlogic.com (qianggui.song)
Date: Mon, 10 Jan 2022 20:28:00 +0800
Subject: [PATCH 3/4] irqchip/meson-gpio: add select trigger type callback
In-Reply-To: <87sftytsk4.wl-maz@kernel.org>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-4-qianggui.song@amlogic.com>
 <87sftytsk4.wl-maz@kernel.org>
Message-ID: <0525de06-03b0-2321-5131-eb2710e5935c@amlogic.com>



On 1/8/22 6:44 PM, Marc Zyngier wrote:
> 
> On Sat, 08 Jan 2022 08:42:17 +0000,
> Qianggui Song <qianggui.song at amlogic.com> wrote:
>>
>> Due to some chips may use different registers and offset, provide
>> a set trigger type call back.
>>
>> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
>> ---
>>   drivers/irqchip/irq-meson-gpio.c | 13 ++++++++++---
>>   1 file changed, 10 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
>> index 6a7b4fb13452..98419428fcbd 100644
>> --- a/drivers/irqchip/irq-meson-gpio.c
>> +++ b/drivers/irqchip/irq-meson-gpio.c
>> @@ -55,6 +55,8 @@ struct irq_ctl_ops {
>>   	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
>>   				 unsigned int channel, unsigned long hwirq);
>>   	void (*gpio_irq_init)(struct meson_gpio_irq_controller *ctl);
>> +	unsigned int (*gpio_irq_sel_type)(struct meson_gpio_irq_controller *ctl,
>> +					  unsigned int idx, u32 val);
>>   };
>>   
>>   struct meson_gpio_irq_params {
>> @@ -68,16 +70,17 @@ struct meson_gpio_irq_params {
>>   	struct irq_ctl_ops ops;
>>   };
>>   
>> -#define INIT_MESON_COMMON(irqs, init, sel)			\
>> +#define INIT_MESON_COMMON(irqs, init, sel, type)		\
>>   	.nr_hwirq = irqs,					\
>>   	.ops = {						\
>>   		.gpio_irq_init = init,				\
>>   		.gpio_irq_sel_pin = sel,			\
>> +		.gpio_irq_sel_type = type,			\
>>   	},
>>   
>>   #define INIT_MESON8_COMMON_DATA(irqs)				\
>>   	INIT_MESON_COMMON(irqs, meson_gpio_irq_init_dummy,	\
>> -			  meson8_gpio_irq_sel_pin)		\
>> +			  meson8_gpio_irq_sel_pin, NULL)	\
>>   	.edge_single_offset = 0,				\
>>   	.pol_low_offset = 16,					\
>>   	.pin_sel_mask = 0xff,					\
>> @@ -85,7 +88,7 @@ struct meson_gpio_irq_params {
>>   
>>   #define INIT_MESON_A1_COMMON_DATA(irqs)				\
>>   	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
>> -			  meson_a1_gpio_irq_sel_pin)		\
>> +			  meson_a1_gpio_irq_sel_pin, NULL)	\
>>   	.support_edge_both = true,				\
>>   	.edge_both_offset = 16,					\
>>   	.edge_single_offset = 8,				\
>> @@ -279,6 +282,10 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
>>   	 */
>>   	type &= IRQ_TYPE_SENSE_MASK;
>>   
>> +	/* Some controllers may have different calculation method*/
>> +	if (params->ops.gpio_irq_sel_type)
>> +		return params->ops.gpio_irq_sel_type(ctl, idx, type);
>> +
> 
> No. If you are going to indirect these things, indirect them for all
> implementations and keep the code clean.
Okay, I' ll try to implement a new macro
> 
> 	M.
> 


From Qianggui.Song at amlogic.com  Mon Jan 10 04:32:23 2022
From: Qianggui.Song at amlogic.com (qianggui.song)
Date: Mon, 10 Jan 2022 20:32:23 +0800
Subject: [PATCH 4/4] irqchip/meson-gpio: Add support for meson s4 SoCs
In-Reply-To: <87r19itrjx.wl-maz@kernel.org>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-5-qianggui.song@amlogic.com>
 <87r19itrjx.wl-maz@kernel.org>
Message-ID: <835a3f28-ec6a-9cd2-d574-5ef87b630fb3@amlogic.com>



On 1/8/22 7:06 PM, Marc Zyngier wrote:
> 
> On Sat, 08 Jan 2022 08:42:18 +0000,
> Qianggui Song <qianggui.song at amlogic.com> wrote:
>>
>> The meson s4 SoCs support 12 gpio irq lines compared with previous
>> serial chips and have something different, details are as below.
>>
>> IRQ Number:
>> - 80:68 13 pins on bank Z
>> - 67:48 20 pins on bank X
>> - 47:36 12 pins on bank H
>> - 35:24 12 pins on bank D
>> - 23:22 2  pins on bank E
>> - 21:14 8  pins on bank C
>> - 13:0  13 pins on bank B
>>
>> - PADCTRL_GPIO_IRQ_CTRL0
>>    bit[31]:    enable/disable the whole irq lines
> 
> s/the whole/all the/
Okay
> 
>>    bit[12-23]: single edge trigger
>>    bit[0-11]:  poll trigger
>>
>> - PADCTRL_GPIO_IRQ_CTRL[X]
>> - bit[0-16]: 7 bits to chooge gpio source for irq line 2*[X] - 2
> 
> choose?
yes it is choose
> 
>> - bit[16-22]:7 bits to chooge gpio source for irq line 2*[X] - 1
>>    where X = 1-6
>>
>> - PADCTRL_GPIO_IRQ_CTRL[7]
>>    bit[0-11]: both edge trigger
> 
> This information would fit better in the code than in the commit
> message.
> 
will copy this to code.
>>
>> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
>> ---
>>   drivers/irqchip/irq-meson-gpio.c | 51 ++++++++++++++++++++++++++++++++
>>   1 file changed, 51 insertions(+)
>>
>> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
>> index 98419428fcbd..c5d20a866c37 100644
>> --- a/drivers/irqchip/irq-meson-gpio.c
>> +++ b/drivers/irqchip/irq-meson-gpio.c
>> @@ -42,6 +42,11 @@
>>   #define REG_PIN_SEL_SHIFT(x)	(((x) % 4) * 8)
>>   #define REG_FILTER_SEL_SHIFT(x)	((x) * 4)
>>   
>> +/* use for s4 chips */
> 
> s/use/Used/
okay
> 
>> +#define REG_EDGE_POL_S4	0x1c
>> +#define REG_EDGE_POL_MASK_S4(x)				\
>> +	({typeof(x) _x = (x); BIT(_x) | BIT(12 + (_x)); })
> 
> Why on Earth should this macro handle multiple types?
If I use  #define REG_EDGE_POL_MASK_S4(x) (BIT(x) | BIT(12 + (x)), when
run git format-patch -1 --stdout | ./script/checkpath.pl --strict -,
will get a message
CHECK: Macro argument reuse 'x' - possible side-effects?

> 
>> +
>>   struct meson_gpio_irq_controller;
>>   static void meson8_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
>>   				    unsigned int channel, unsigned long hwirq);
>> @@ -50,6 +55,9 @@ static void meson_a1_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
>>   				      unsigned int channel,
>>   				      unsigned long hwirq);
>>   static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl);
>> +static unsigned int
>> +meson_s4_gpio_irq_sel_type(struct meson_gpio_irq_controller *ctl,
>> +			   unsigned int idx, u32 val);
>>   
>>   struct irq_ctl_ops {
>>   	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
>> @@ -96,6 +104,17 @@ struct meson_gpio_irq_params {
>>   	.pin_sel_mask = 0x7f,					\
>>   	.channel_num = 8,					\
>>   
>> +#define INIT_MESON_S4_COMMON_DATA(irqs)                         \
>> +	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,         \
>> +			  meson_a1_gpio_irq_sel_pin,            \
>> +			  meson_s4_gpio_irq_sel_type)           \
>> +	.support_edge_both = true,				\
>> +	.edge_both_offset = 0,					\
>> +	.edge_single_offset = 12,				\
>> +	.pol_low_offset = 0,					\
>> +	.pin_sel_mask = 0xff,					\
>> +	.channel_num = 12,					\
>> +
>>   static const struct meson_gpio_irq_params meson8_params = {
>>   	INIT_MESON8_COMMON_DATA(134)
>>   };
>> @@ -126,6 +145,10 @@ static const struct meson_gpio_irq_params a1_params = {
>>   	INIT_MESON_A1_COMMON_DATA(62)
>>   };
>>   
>> +static const struct meson_gpio_irq_params s4_params = {
>> +	INIT_MESON_S4_COMMON_DATA(82)
>> +};
>> +
>>   static const struct of_device_id meson_irq_gpio_matches[] = {
>>   	{ .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params },
>>   	{ .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params },
>> @@ -135,6 +158,7 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
>>   	{ .compatible = "amlogic,meson-g12a-gpio-intc", .data = &axg_params },
>>   	{ .compatible = "amlogic,meson-sm1-gpio-intc", .data = &sm1_params },
>>   	{ .compatible = "amlogic,meson-a1-gpio-intc", .data = &a1_params },
>> +	{ .compatible = "amlogic,meson-s4-gpio-intc", .data = &s4_params },
>>   	{ }
>>   };
>>   
>> @@ -202,6 +226,33 @@ static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl)
>>   	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL, BIT(31), BIT(31));
>>   }
>>   
>> +static unsigned int
>> +meson_s4_gpio_irq_sel_type(struct meson_gpio_irq_controller *ctl,
>> +			   unsigned int idx, unsigned int type)
> 
> An 'unsigned int' return type, directly returned by a caller that
> has 'int' as its return type. What could possibly go wrong?

will modify this next patch
> 
>> +{
>> +	unsigned int val = 0;
>> +
>> +	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4, BIT(0 + (idx)), 0);
> 
> Drop the 0 + as well as the useless bracketing all over this function.
> 
Okay
>> +
>> +	if (type == IRQ_TYPE_EDGE_BOTH) {
>> +		val |= BIT(ctl->params->edge_both_offset + (idx));
>> +		meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4,
>> +					   BIT(ctl->params->edge_both_offset + (idx)), val);
>> +		return 0;
>> +	}
>> +
>> +	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
>> +		val |= BIT(ctl->params->pol_low_offset + (idx));
>> +
>> +	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
>> +		val |= BIT(ctl->params->edge_single_offset  + (idx));
>> +
>> +	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
>> +				   REG_EDGE_POL_MASK_S4(idx), val);
>> +
>> +	return 0;
>> +};
>> +
>>   static int
>>   meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
>>   			       unsigned long  hwirq,
> 
> 	M.
> 


From Qianggui.Song at amlogic.com  Mon Jan 10 04:33:01 2022
From: Qianggui.Song at amlogic.com (qianggui.song)
Date: Mon, 10 Jan 2022 20:33:01 +0800
Subject: [PATCH 1/4] dt-bindings: interrupt-controller: New binding for
 Meson-S4 SoCs
In-Reply-To: <A4441A27-7B49-4A9A-83FD-05144A63E705@gmail.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-2-qianggui.song@amlogic.com>
 <A4441A27-7B49-4A9A-83FD-05144A63E705@gmail.com>
Message-ID: <50bc5a03-5c1f-10dc-b3c3-bdf78e435577@amlogic.com>



On 1/9/22 11:27 PM, Christian Hewitt wrote:
> 
> 
>> On 8 Jan 2022, at 12:42 pm, Qianggui Song <qianggui.song at amlogic.com> wrote:
>>
>> Update dt-binding document for GPIO interrupt controller of Meson-S4 SoCs
>>
>> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
>> ---
>> .../bindings/interrupt-controller/amlogic,meson-gpio-intc.txt    | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
>> index 23b18b92c558..9300736bf1ed 100644
>> --- a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
>> +++ b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
>> @@ -18,6 +18,7 @@ Required properties:
>>      "amlogic,meson-g12a-gpio-intc" for G12A SoCs (S905D2, S905X2, S905Y2)
>>      "amlogic,meson-sm1-gpio-intc" for SM1 SoCs (S905D3, S905X3, S905Y3)
>>      "amlogic,meson-a1-gpio-intc" for A1 SoCs (A113L)
>> +    "amlogic,meson-a1-gpio-intc" for S4 SoCs (S802X2, S905Y4, S805X2G, S905W2)
> 
> ^ should be "amlogic,meson-s4-gpio-intc? ?
Yes, thanks for pointing out
> 
> Christian
> 
>> - reg : Specifies base physical address and size of the registers.
>> - interrupt-controller : Identifies the node as an interrupt controller.
>> - #interrupt-cells : Specifies the number of cells needed to encode an
>> -- 
>> 2.34.1
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
> 
> .
> 


From narmstrong at baylibre.com  Mon Jan 10 05:01:30 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 14:01:30 +0100
Subject: [PATCH v3 2/2] phy: amlogic: Add G12A Analog MIPI D-PHY driver
In-Reply-To: <CAFBinCC9J_w9JM-TmrXp7SXT27V7Ze37wrxHZZQ1==N4y2-0dg@mail.gmail.com>
References: <20220107150512.614423-1-narmstrong@baylibre.com>
 <20220107150512.614423-3-narmstrong@baylibre.com>
 <CAFBinCC9J_w9JM-TmrXp7SXT27V7Ze37wrxHZZQ1==N4y2-0dg@mail.gmail.com>
Message-ID: <3f7f1c95-8a16-cb74-3a99-3f67404424db@baylibre.com>

Hi,

On 07/01/2022 23:09, Martin Blumenstingl wrote:
> Hi Neil,
> 
> On Fri, Jan 7, 2022 at 4:06 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
> [...]
>> +#define HHI_MIPI_CNTL2 0x08
>> +#define                HHI_MIPI_CNTL2_DIF_TX_CTL1      GENMASK(31, 16)
>> +#define                HHI_MIPI_CNTL2_CH_EN            GENMASK(15, 11)
>> +#define                HHI_MIPI_CNTL2_DIF_TX_CTL0      GENMASK(10, 0)
>> +
>> +#define DSI_LANE_0                             BIT(4)
>> +#define DSI_LANE_1                             BIT(3)
>> +#define DSI_LANE_CLK                           BIT(2)
>> +#define DSI_LANE_2                             BIT(1)
>> +#define DSI_LANE_3                             BIT(0)
> At first I thought that these should be named
> HHI_MIPI_CNTL2_DSI_LANE_0 (and similar).
> But then I understood that they aren't bits directly in HHI_MIPI_CNTL2
> but they belong to HHI_MIPI_CNTL2_CH_EN.
> Have you considered naming them for example
> HHI_MIPI_CNTL2_CH_EN_DSI_LANE_0 to make this more clear?
> 
> [...]
>> +       if (IS_ERR(map)) {
>> +               dev_err(dev,
>> +                       "failed to get HHI regmap\n");
>> +               return PTR_ERR(map);
> I suggest using:
>   return dev_err_probe(dev, PTR_ERR(map), "failed to get HHI regmap\n");
> to simplify the code
> 
> [...]
>> +       if (IS_ERR(priv->phy)) {
>> +               ret = PTR_ERR(priv->phy);
>> +               if (ret != -EPROBE_DEFER)
>> +                       dev_err(dev, "failed to create PHY\n");
>> +               return ret;
> and similar here:
>   return dev_err_probe(dev, PTR_ERR(priv->phy), "failed to create PHY\n");
> 
> [...]
>> +static const struct of_device_id phy_g12a_mipi_dphy_analog_of_match[] = {
>> +       {
>> +               .compatible = "amlogic,g12a-mipi-dphy-analog",
>> +       },
>> +       { },
> In the past I was suggested to use:
>   { /* sentinel */ }
> meaning: no trailing comma here so nobody can add entries after the
> sentinel by accident.
> I suggest doing the same here if you re-spin this series.

Yep, will do the changes,

Thanks,
Neil

> 
> 
> Thank you!
> Martin
> 



From jbrunet at baylibre.com  Mon Jan 10 06:29:45 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 10 Jan 2022 15:29:45 +0100
Subject: [PATCH V4 3/5] tty: serial: meson: The UART baud rate
In-Reply-To: <20220110085604.18042-4-yu.tu@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
 <20220110085604.18042-4-yu.tu@amlogic.com>
Message-ID: <1j8rvnps11.fsf@starbuckisacylon.baylibre.com>


On Mon 10 Jan 2022 at 16:56, Yu Tu <yu.tu at amlogic.com> wrote:

Title is bad (like several other patches in this series) - Please fix it

> Using the common Clock code to describe the UART baud rate clock
> makes it easier for the UART driver to be compatible with the
> baud rate requirements of the UART IP on different meson chips.
>
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>  drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
>  1 file changed, 163 insertions(+), 61 deletions(-)
>
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 7570958d010c..1004fd0b0c9e 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -6,6 +6,7 @@
>   */
>  
>  #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>  #include <linux/console.h>
>  #include <linux/delay.h>
>  #include <linux/init.h>
> @@ -65,9 +66,7 @@
>  #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>  
>  /* AML_UART_REG5 bits */
> -#define AML_UART_BAUD_MASK		0x7fffff
>  #define AML_UART_BAUD_USE		BIT(23)
> -#define AML_UART_BAUD_XTAL		BIT(24)
>  
>  #define AML_UART_PORT_NUM		12
>  #define AML_UART_PORT_OFFSET		6
> @@ -76,6 +75,13 @@
>  #define AML_UART_POLL_USEC		5
>  #define AML_UART_TIMEOUT_USEC		10000
>  
> +struct meson_uart_data {
> +	struct uart_port	port;
> +	struct clk		*pclk;
> +	struct clk		*baud_clk;
> +	bool			use_xtal_clk;
> +};
> +
>  static struct uart_driver meson_uart_driver;
>  
>  static struct uart_port *meson_ports[AML_UART_PORT_NUM];
> @@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
>  static int meson_uart_startup(struct uart_port *port)
>  {
>  	u32 val;
> -	int ret = 0;
> +	int ret;
>  
> -	val = readl(port->membase + AML_UART_CONTROL);
> -	val |= AML_UART_CLEAR_ERR;
> -	writel(val, port->membase + AML_UART_CONTROL);
> -	val &= ~AML_UART_CLEAR_ERR;
> -	writel(val, port->membase + AML_UART_CONTROL);
> +	meson_uart_reset(port);
>  
> +	val = readl(port->membase + AML_UART_CONTROL);
>  	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>  	writel(val, port->membase + AML_UART_CONTROL);
>  
> @@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port *port)
>  
>  static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
>  {
> +	struct meson_uart_data *private_data = port->private_data;
>  	u32 val;
>  
>  	while (!meson_uart_tx_empty(port))
>  		cpu_relax();
>  
> -	if (port->uartclk == 24000000) {
> -		val = ((port->uartclk / 3) / baud) - 1;
> -		val |= AML_UART_BAUD_XTAL;
> -	} else {
> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
> -	}
> +	val = readl(port->membase + AML_UART_REG5);
>  	val |= AML_UART_BAUD_USE;
>  	writel(val, port->membase + AML_UART_REG5);
> +
> +	clk_set_rate(private_data->baud_clk, baud);
>  }
>  
>  static void meson_uart_set_termios(struct uart_port *port,
> @@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>  
>  static void meson_uart_release_port(struct uart_port *port)
>  {
> -	/* nothing to do */
> +	struct meson_uart_data *private_data = port->private_data;
> +
> +	clk_disable_unprepare(private_data->baud_clk);
> +	clk_disable_unprepare(private_data->pclk);
>  }
>  
>  static int meson_uart_request_port(struct uart_port *port)
>  {
> +	struct meson_uart_data *private_data = port->private_data;
> +	int ret;
> +
> +	ret = clk_prepare_enable(private_data->pclk);
> +	if (ret)
> +		return ret;

In the previous version of the series, you already been asked to the
enable of pclk in the probe. Optimization should not be mixed with this
series

Please make sure all comments are addressed before re-posting

> +
> +	ret = clk_prepare_enable(private_data->baud_clk);
> +	if (ret) {
> +		clk_disable_unprepare(private_data->pclk);
> +		return ret;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
>  	.cons		= MESON_SERIAL_CONSOLE,
>  };
>  
> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
> -						 const char *id)
> +#define CLK_NAME(name) \
> +({\
> +	char clk_name[32];\
> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
> +	clk_name;\
> +})

1) This result in some ugly code being inlined
2) You return a pointer a local variable which is not gurantee to exist
anymore  outside of this ...

Please do this simply in the related function.

> +
> +static struct clk_div_table xtal_div_table[] = {
> +	{ 0, 3  },
> +	{ 1, 1  },
> +	{ 2, 2  },
> +	{ 3, 2  },
> +};
> +
> +static int meson_uart_probe_clocks(struct uart_port *port)
>  {
> -	struct clk *clk = NULL;
> -	int ret;
> +	struct meson_uart_data *private_data = port->private_data;
> +	struct clk *clk_baud, *clk_xtal;
> +	struct clk_hw *hw;
> +	struct clk_parent_data use_xtal_mux_parents[2] = {
> +		{ .index = -1, },
> +		{ .index = -1, },
> +	};
>  
> -	clk = devm_clk_get(dev, id);
> -	if (IS_ERR(clk))
> -		return clk;
> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
> +	if (IS_ERR(private_data->pclk))
> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
> +				     "Failed to get the 'pclk' clock\n");
>  
> -	ret = clk_prepare_enable(clk);
> -	if (ret) {
> -		dev_err(dev, "couldn't enable clk\n");
> -		return ERR_PTR(ret);
> +	clk_baud = devm_clk_get(port->dev, "baud");
> +	if (IS_ERR(clk_baud)) {
> +		dev_err(port->dev, "Failed to get the 'baud' clock\n");
> +		return PTR_ERR(clk_baud);
>  	}
>  
> -	devm_add_action_or_reset(dev,
> -			(void(*)(void *))clk_disable_unprepare,
> -			clk);
> -
> -	return clk;
> -}
> -
> -static int meson_uart_probe_clocks(struct platform_device *pdev,
> -				   struct uart_port *port)
> -{
> -	struct clk *clk_xtal = NULL;
> -	struct clk *clk_pclk = NULL;
> -	struct clk *clk_baud = NULL;
> -
> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
> -	if (IS_ERR(clk_pclk))
> -		return PTR_ERR(clk_pclk);
> -
> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>  	if (IS_ERR(clk_xtal))
> -		return PTR_ERR(clk_xtal);
> -
> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
> -	if (IS_ERR(clk_baud))
> -		return PTR_ERR(clk_baud);
> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
> +				     "Failed to get the 'xtal' clock\n");
> +
> +	if (private_data->use_xtal_clk) {
> +		hw = devm_clk_hw_register_divider_table(port->dev,
> +							CLK_NAME(xtal_div),
> +							__clk_get_name(clk_baud),
> +							CLK_SET_RATE_NO_REPARENT,
> +							port->membase + AML_UART_REG5,
> +							26, 2,
> +							CLK_DIVIDER_READ_ONLY,
> +							xtal_div_table, NULL);
> +		if (IS_ERR(hw))
> +			return PTR_ERR(hw);
> +
> +		use_xtal_mux_parents[1].hw = hw;
> +	} else {
> +		hw = devm_clk_hw_register_fixed_factor(port->dev,
> +						       CLK_NAME(clk81_div4),
> +						       __clk_get_name(clk_baud),
> +						       CLK_SET_RATE_NO_REPARENT,
> +						       1, 4);
> +		if (IS_ERR(hw))
> +			return PTR_ERR(hw);
> +
> +		use_xtal_mux_parents[0].hw = hw;
> +	}

Contradiction with previous series.
In the previous series we could clearly see that gxbb did not have the
/4 divider. It did not have bits 26 and 27 either.

Now gxbb get the /4 divider. It operated correctly without it so far, so
this is rather suspicious. Could you please comment on this ?

>  
> -	port->uartclk = clk_get_rate(clk_baud);
> +	hw = __devm_clk_hw_register_mux(port->dev, NULL,
> +					CLK_NAME(use_xtal),
> +					ARRAY_SIZE(use_xtal_mux_parents),
> +					NULL, NULL,
> +					use_xtal_mux_parents,
> +					CLK_SET_RATE_PARENT,
> +					port->membase + AML_UART_REG5,
> +					24, 0x1,
> +					CLK_MUX_READ_ONLY,
> +					NULL, NULL);
> +	if (IS_ERR(hw))
> +		return PTR_ERR(hw);
> +
> +	port->uartclk = clk_hw_get_rate(hw);
> +
> +	hw = devm_clk_hw_register_divider(port->dev,
> +					  CLK_NAME(baud_div),
> +					  clk_hw_get_name(hw),
> +					  CLK_SET_RATE_PARENT,
> +					  port->membase + AML_UART_REG5,
> +					  0, 23,
> +					  CLK_DIVIDER_ROUND_CLOSEST,
> +					  NULL);
> +	if (IS_ERR(hw))
> +		return PTR_ERR(hw);
> +
> +	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");

I have already commented on the use of this function in the previous
version.

Please make sure all comments are addressed before re-posting

>  
>  	return 0;
>  }
>  
>  static int meson_uart_probe(struct platform_device *pdev)
>  {
> +	struct meson_uart_data *private_data;
>  	struct resource *res_mem;
>  	struct uart_port *port;
>  	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
> @@ -716,18 +783,20 @@ static int meson_uart_probe(struct platform_device *pdev)
>  		return -EBUSY;
>  	}
>  
> -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
> -	if (!port)
> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
> +				    GFP_KERNEL);
> +	if (!private_data)
>  		return -ENOMEM;
>  
> +	if (device_get_match_data(&pdev->dev))
> +		private_data->use_xtal_clk = true;
> +
> +	port = &private_data->port;
> +
>  	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>  	if (IS_ERR(port->membase))
>  		return PTR_ERR(port->membase);
>  
> -	ret = meson_uart_probe_clocks(pdev, port);
> -	if (ret)
> -		return ret;
> -
>  	port->iotype = UPIO_MEM;
>  	port->mapbase = res_mem->start;
>  	port->mapsize = resource_size(res_mem);
> @@ -740,7 +809,11 @@ static int meson_uart_probe(struct platform_device *pdev)
>  	port->x_char = 0;
>  	port->ops = &meson_uart_ops;
>  	port->fifosize = fifosize;
> +	port->private_data = private_data;

port has private_data
private_data has port

Is it really necessary to have both ... looks to me that port in
private_data is overkill

>  
> +	ret = meson_uart_probe_clocks(port);
> +	if (ret)
> +		return ret;
>  	meson_ports[pdev->id] = port;
>  	platform_set_drvdata(pdev, port);
>  
> @@ -766,10 +839,39 @@ static int meson_uart_remove(struct platform_device *pdev)
>  }
>  
>  static const struct of_device_id meson_uart_dt_match[] = {
> -	{ .compatible = "amlogic,meson6-uart" },
> -	{ .compatible = "amlogic,meson8-uart" },
> -	{ .compatible = "amlogic,meson8b-uart" },
> -	{ .compatible = "amlogic,meson-gx-uart" },
> +	{
> +		.compatible = "amlogic,meson6-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson8-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson8b-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson-gxbb-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson-gxl-uart",
> +		.data = (void *)true,
> +	},
> +	{
> +		.compatible = "amlogic,meson-g12a-uart",
> +		.data = (void *)true,
> +	},
> +	/*
> +	 * deprecated, don't use anymore because it doesn't differentiate
> +	 * between GXBB, GXL and G12A which have different revisions
> +	 * of the UART IP.
> +	 */
> +	{
> +		.compatible = "amlogic,meson-gx-uart",
> +		.data = (void *)false,
> +	},
>  	{ /* sentinel */ },
>  };
>  MODULE_DEVICE_TABLE(of, meson_uart_dt_match);



From maz at kernel.org  Mon Jan 10 06:54:36 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 10 Jan 2022 14:54:36 +0000
Subject: [PATCH 4/4] irqchip/meson-gpio: Add support for meson s4 SoCs
In-Reply-To: <835a3f28-ec6a-9cd2-d574-5ef87b630fb3@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-5-qianggui.song@amlogic.com>
 <87r19itrjx.wl-maz@kernel.org>
 <835a3f28-ec6a-9cd2-d574-5ef87b630fb3@amlogic.com>
Message-ID: <87lezntzdf.wl-maz@kernel.org>

On Mon, 10 Jan 2022 12:32:23 +0000,
qianggui.song <Qianggui.Song at amlogic.com> wrote:
> 
> 
> 
> On 1/8/22 7:06 PM, Marc Zyngier wrote:
> > 
> > On Sat, 08 Jan 2022 08:42:18 +0000,
> > Qianggui Song <qianggui.song at amlogic.com> wrote:
> >> 
> >> The meson s4 SoCs support 12 gpio irq lines compared with previous
> >> serial chips and have something different, details are as below.
> >> 
> >> IRQ Number:
> >> - 80:68 13 pins on bank Z
> >> - 67:48 20 pins on bank X
> >> - 47:36 12 pins on bank H
> >> - 35:24 12 pins on bank D
> >> - 23:22 2  pins on bank E
> >> - 21:14 8  pins on bank C
> >> - 13:0  13 pins on bank B
> >> 
> >> - PADCTRL_GPIO_IRQ_CTRL0
> >>    bit[31]:    enable/disable the whole irq lines
> > 
> > s/the whole/all the/
> Okay
> > 
> >>    bit[12-23]: single edge trigger
> >>    bit[0-11]:  poll trigger
> >> 
> >> - PADCTRL_GPIO_IRQ_CTRL[X]
> >> - bit[0-16]: 7 bits to chooge gpio source for irq line 2*[X] - 2
> > 
> > choose?
> yes it is choose
> > 
> >> - bit[16-22]:7 bits to chooge gpio source for irq line 2*[X] - 1
> >>    where X = 1-6
> >> 
> >> - PADCTRL_GPIO_IRQ_CTRL[7]
> >>    bit[0-11]: both edge trigger
> > 
> > This information would fit better in the code than in the commit
> > message.
> > 
> will copy this to code.
> >> 
> >> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
> >> ---
> >>   drivers/irqchip/irq-meson-gpio.c | 51 ++++++++++++++++++++++++++++++++
> >>   1 file changed, 51 insertions(+)
> >> 
> >> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
> >> index 98419428fcbd..c5d20a866c37 100644
> >> --- a/drivers/irqchip/irq-meson-gpio.c
> >> +++ b/drivers/irqchip/irq-meson-gpio.c
> >> @@ -42,6 +42,11 @@
> >>   #define REG_PIN_SEL_SHIFT(x)	(((x) % 4) * 8)
> >>   #define REG_FILTER_SEL_SHIFT(x)	((x) * 4)
> >>   +/* use for s4 chips */
> > 
> > s/use/Used/
> okay
> > 
> >> +#define REG_EDGE_POL_S4	0x1c
> >> +#define REG_EDGE_POL_MASK_S4(x)				\
> >> +	({typeof(x) _x = (x); BIT(_x) | BIT(12 + (_x)); })
> > 
> > Why on Earth should this macro handle multiple types?
> If I use  #define REG_EDGE_POL_MASK_S4(x) (BIT(x) | BIT(12 + (x)), when
> run git format-patch -1 --stdout | ./script/checkpath.pl --strict -,
> will get a message
> CHECK: Macro argument reuse 'x' - possible side-effects?

Well, either expand the macro directly in the code (after all, there
is only one use for it) or make this a C function instead of a macro.

	M.

-- 
Without deviation from the norm, progress is not possible.


From robh+dt at kernel.org  Mon Jan 10 08:18:02 2022
From: robh+dt at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 10:18:02 -0600
Subject: [PATCH V5 1/5] dt-bindings: serial: meson: Drop legacy compatible.
In-Reply-To: <20220110104214.25321-2-yu.tu@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
 <20220110104214.25321-2-yu.tu@amlogic.com>
Message-ID: <CAL_JsqKFLnfc5eaUHeo6EkbS0kkpA94rh=Zuda9V9aCragdVxw@mail.gmail.com>

On Mon, Jan 10, 2022 at 4:42 AM Yu Tu <yu.tu at amlogic.com> wrote:
>
> Deprecated, don't use anymore because legacy amlogic,meson-gx-uart
> compatible. Don't differentiate between GXBB, GXL and G12A which
> have different revisions of the UART IP. So it's split into
> GXBB,GXL and G12A.

You are breaking compatibility. If your dts is updated to use the new
compatible, then a kernel without the change will not work anymore. It
worked before without understanding the changes you are making. It
should continue to. A compatible value like this would accomplish what
you want:

"amlogic,meson-gxbb-uart", "amlogic,meson-gx-uart", "amlogic,meson-ao-uart"

A new kernel will match on "amlogic,meson-gxbb-uart" or
"amlogic,meson-gx-uart" depending if the dtb is updated or not. An old
kernel will continue to match on "amlogic,meson-gx-uart".

If you are going to go breaking things, the power domain distinction
in the compatible is odd...


Rob


From robh at kernel.org  Mon Jan 10 09:36:02 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 11:36:02 -0600
Subject: [PATCH 2/3] dt-bindings: reset: add bindings for the Meson-S4
 SoC Reset Controller
In-Reply-To: <20220107023931.13251-3-zelong.dong@amlogic.com>
References: <20220107023931.13251-1-zelong.dong@amlogic.com>
 <20220107023931.13251-3-zelong.dong@amlogic.com>
Message-ID: <YdxugtL5PsrwsT6D@robh.at.kernel.org>

On Fri, 07 Jan 2022 10:39:30 +0800, Zelong Dong wrote:
> Add DT bindings for the Meson-S4 SoC Reset Controller include file.
> 
> Signed-off-by: Zelong Dong <zelong.dong at amlogic.com>
> ---
>  .../reset/amlogic,meson-s4-reset.h            | 125 ++++++++++++++++++
>  1 file changed, 125 insertions(+)
>  create mode 100644 include/dt-bindings/reset/amlogic,meson-s4-reset.h
> 


Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.

If a tag was not added on purpose, please state why and what changed.



From martin.blumenstingl at googlemail.com  Mon Jan 10 14:05:05 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Mon, 10 Jan 2022 23:05:05 +0100
Subject: ODROID-C1/-C2 USB Detection only triggered by some devices dwc2
In-Reply-To: <CAFBinCAvFbLXoobcTWiOoUrRSFnNzhOdn-=dkxvJOMkeOC+EAg@mail.gmail.com>
References: <822c3852-1d15-2976-8672-e49ae34c328f@synopsys.com>
 <CAFBinCC_0RpCMsj3AUt9fZrjHi6_qFirQtRR1g5VJcn45GpWAw@mail.gmail.com>
 <ad475275-eb2c-6309-fc59-494f94bf0605@synopsys.com>
 <CAFBinCCXioWL+ZGwvC8Ltrmx4y2XpGK03JAm8X=wDB4_dQ+pFA@mail.gmail.com>
 <20210715014451.GA397753@rowland.harvard.edu>
 <CAFBinCD0GKcc8veWAkWG=NCban4k8n5E-QdhNfccuH8OXvtA6g@mail.gmail.com>
 <20210719145322.GA565905@rowland.harvard.edu>
 <CAFBinCDAXzDugaCcf52ubE+a==7CtDkmHpX2hAeO+DkJWQCNSg@mail.gmail.com>
 <20210721155817.GC633399@rowland.harvard.edu>
 <CAFBinCBkUsTsPiMQ2iN5U63NczxXFHv818O-G01WzJXZ36ybeA@mail.gmail.com>
 <20210803213216.GA376608@rowland.harvard.edu>
 <CAFBinCAvFbLXoobcTWiOoUrRSFnNzhOdn-=dkxvJOMkeOC+EAg@mail.gmail.com>
Message-ID: <CAFBinCAMJXtK4VOknGmfPB0GwHnJNtQ8gSMwQR-8a-gJP6jL6g@mail.gmail.com>

Hi Minas,

On Sun, Dec 12, 2021 at 5:08 PM Martin Blumenstingl
<martin.blumenstingl at googlemail.com> wrote:
[...]
> On Tue, Aug 3, 2021 at 11:32 PM Alan Stern <stern at rowland.harvard.edu> wrote:
> >
> > Minas, you should look at analysis of the usbmon information below.
> Minas, it would be great if you could take the time to go through
> Alan's findings.
> Since it's been a while I am trying to summarize the current state of
> the findings here.
Since I sent my last email you were probably on vacation. I hope you
had a good time!

> In [0] Alan mentioned:
> > Minas, some of the things noted below may require your attention. In
> > particular, the usbmon traces don't show the root hub doing what it should,
> > which leads me to wonder whether the Genesys Logic hub attached to port 1
> > really is getting suspended and resumed properly.
>
> Then in [1] Alan goes through the usbmon traces from my Meson8b
> Odroid-C1+ and comes to the following conclusion:
> > [...] the trace shows that the GL hub was never fully suspended!
> >
> > So the question is: Why doesn't the port status on the DWC2 root hub
> > show the suspend feature set, and why doesn't the root hub port get
> > suspended?  This looks like a bug in the dwc2 driver. [...]
>
> Linux 5.16-rc4 is still affected by this issue, meaning that it hasn't
> been fixed in the meantime.
>
> I am happy about any feedback which can help resolve this issue. That
> means: even if you have an idea (like: flipping bit X in register Y
> could help) which you are unable to test yourself then please let me
> know - I can take care of the testing part (and share debug
> logs/usbmon traces if needed).
Could you please take out some time to go through Alan's findings and
let me know if/what you need from my end so we can resolve this issue?


Thank you!
Best regards,
Martin


From martin.blumenstingl at googlemail.com  Mon Jan 10 14:18:33 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Mon, 10 Jan 2022 23:18:33 +0100
Subject: [PATCH v3 1/2] dt-bindings: phy: add Amlogic G12A Analog MIPI
 D-PHY bindings
In-Reply-To: <fad140b9-2940-a24a-ba70-9849bacf617d@baylibre.com>
References: <20220107150512.614423-1-narmstrong@baylibre.com>
 <20220107150512.614423-2-narmstrong@baylibre.com>
 <CAFBinCDRx6VaaAubr6VRLnX=G4Ez8cGg-=6e-9GWrH8FwwBs-g@mail.gmail.com>
 <fad140b9-2940-a24a-ba70-9849bacf617d@baylibre.com>
Message-ID: <CAFBinCC7wfPjLGVe87E0H7WYXwrFw0e0k_2epF1dDaWKkSvRyQ@mail.gmail.com>

Hi Neil,

On Mon, Jan 10, 2022 at 10:25 AM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> On 07/01/2022 23:13, Martin Blumenstingl wrote:
> > Hi Neil,
> >
> > On Fri, Jan 7, 2022 at 4:05 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
> > [...]
> >> +required:
> >> +  - compatible
> >> +  - reg
> >> +  - "#phy-cells"
> > I also found a "MIPI DSI PHY clock" and "MIPI DSI PHY interrupt" in
> > the datasheet.
> > I'm no expert on this and I'm just asking in case you have missed one of these:
> > Can you confirm that these belong to some other IP?
>
> Indeed the name is misleading, both go to the DSI Transceiver IP (dw-mipi-dsi)
Thank you for clarifying this!

I just found an old comment from Rob on v2 of this series: [0]
He mentions:
"If this is a child of something else, then put a $ref to this schema
and the example in the parent schema."

To be honest: I completely forgot about that comment until now.
If I had remembered it (and assuming that his comment is still valid)
then I would have had to NACK my own
Documentation/devicetree/bindings/phy/amlogic,meson8-hdmi-tx-phy.yaml
For today it's already late so I'll look into this more tomorrow.


Best regards,
Martin


[0] https://lore.kernel.org/all/20210210165118.GA2311581 at robh.at.kernel.org/


From yu.tu at amlogic.com  Mon Jan 10 18:48:41 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 11 Jan 2022 10:48:41 +0800
Subject: [PATCH V5 2/5] tty: serial: meson: Move request the register
 region.
In-Reply-To: <01066e66-5d97-ab40-b4a6-99e962b47073@kernel.org>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
 <20220110104214.25321-3-yu.tu@amlogic.com>
 <01066e66-5d97-ab40-b4a6-99e962b47073@kernel.org>
Message-ID: <cad33ab0-26d3-5b78-3bcf-62217aa70871@amlogic.com>

Hi Jiri ,
	Thank you very much for your reply.

On 2022/1/10 19:58, Jiri Slaby wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi,
> 
> On 10. 01. 22, 11:42, Yu Tu wrote:
>> This simplifies resetting the UART controller during probe
>> and will make it easier to integrate the common clock code
>> which will require the registers at probe time as well.
> 
> And you are *also* switching devm_request_mem_region+devm_ioremap into 
> devm_ioremap_resource without even noting it here. It should've been 
> done in a separate patch.
> 
I can change it as you suggest?
The switching devm_request_mem_region+devm_ioremap into
devm_ioremap_resource in a separate patch.

> And no, do not resend a new version in the next few days. Having v5 in 
> 20 days is a bit too much. Give maintainers and reviewers some more 
> space to express themselves.
I am so sorry if PATCH is sent too frequently, which has disturbed you.
How often should I send it? Or under what circumstances can I send the 
next version?

>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>> ---
>> ? drivers/tty/serial/meson_uart.c | 24 ++++++------------------
>> ? 1 file changed, 6 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/tty/serial/meson_uart.c 
>> b/drivers/tty/serial/meson_uart.c
>> index 45e00d928253..7570958d010c 100644
>> --- a/drivers/tty/serial/meson_uart.c
>> +++ b/drivers/tty/serial/meson_uart.c
>> @@ -395,24 +395,11 @@ static int meson_uart_verify_port(struct 
>> uart_port *port,
>> ? static void meson_uart_release_port(struct uart_port *port)
>> ? {
>> -??? devm_iounmap(port->dev, port->membase);
>> -??? port->membase = NULL;
>> -??? devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
>> +??? /* nothing to do */
>> ? }
>> ? static int meson_uart_request_port(struct uart_port *port)
>> ? {
>> -??? if (!devm_request_mem_region(port->dev, port->mapbase, 
>> port->mapsize,
>> -???????????????????? dev_name(port->dev))) {
>> -??????? dev_err(port->dev, "Memory region busy\n");
>> -??????? return -EBUSY;
>> -??? }
>> -
>> -??? port->membase = devm_ioremap(port->dev, port->mapbase,
>> -???????????????????????? port->mapsize);
>> -??? if (!port->membase)
>> -??????? return -ENOMEM;
>> -
>> ????? return 0;
>> ? }
>> @@ -733,6 +720,10 @@ static int meson_uart_probe(struct 
>> platform_device *pdev)
>> ????? if (!port)
>> ????????? return -ENOMEM;
>> +??? port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>> +??? if (IS_ERR(port->membase))
>> +??????? return PTR_ERR(port->membase);
>> +
>> ????? ret = meson_uart_probe_clocks(pdev, port);
>> ????? if (ret)
>> ????????? return ret;
>> @@ -754,10 +745,7 @@ static int meson_uart_probe(struct 
>> platform_device *pdev)
>> ????? platform_set_drvdata(pdev, port);
>> ????? /* reset port before registering (and possibly registering 
>> console) */
>> -??? if (meson_uart_request_port(port) >= 0) {
>> -??????? meson_uart_reset(port);
>> -??????? meson_uart_release_port(port);
>> -??? }
>> +??? meson_uart_reset(port);
>> ????? ret = uart_add_one_port(&meson_uart_driver, port);
>> ????? if (ret)
> 
> thanks,


From yu.tu at amlogic.com  Mon Jan 10 19:13:52 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 11 Jan 2022 11:13:52 +0800
Subject: [PATCH V5 3/5] tty: serial: meson: Using the common clock code
 describe.
In-Reply-To: <327f985f-bbf1-00ba-d203-cc9d5bbd955c@kernel.org>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
 <20220110104214.25321-4-yu.tu@amlogic.com>
 <327f985f-bbf1-00ba-d203-cc9d5bbd955c@kernel.org>
Message-ID: <2710be28-3e01-081d-a726-b37b7c053f96@amlogic.com>

Hi Jiri,
	Thank you very much for your reply.

On 2022/1/10 20:11, Jiri Slaby wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi,
> 
> "Subject: Using the common clock code describe."
> 
> Please reformulate that ^^^ -- I cannot make any sense of it. And avoid 
> adding a period to the subject. PLease see others' commit logs.
> 
I will correct this in the next version.

> On 10. 01. 22, 11:42, Yu Tu wrote:
>> Using the common Clock code to describe the UART baud rate clock
>> makes it easier for the UART driver to be compatible with the
>> baud rate requirements of the UART IP on different meson chips.
> 
> 
> 
>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>> ---
>> ? drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
>> ? 1 file changed, 163 insertions(+), 61 deletions(-)
>>
>> diff --git a/drivers/tty/serial/meson_uart.c 
>> b/drivers/tty/serial/meson_uart.c
>> index 7570958d010c..1004fd0b0c9e 100644
>> --- a/drivers/tty/serial/meson_uart.c
>> +++ b/drivers/tty/serial/meson_uart.c
>> @@ -6,6 +6,7 @@
>> ?? */
>> ? #include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>> ? #include <linux/console.h>
>> ? #include <linux/delay.h>
>> ? #include <linux/init.h>
>> @@ -65,9 +66,7 @@
>> ? #define AML_UART_RECV_IRQ(c)??????? ((c) & 0xff)
>> ? /* AML_UART_REG5 bits */
>> -#define AML_UART_BAUD_MASK??????? 0x7fffff
>> ? #define AML_UART_BAUD_USE??????? BIT(23)
>> -#define AML_UART_BAUD_XTAL??????? BIT(24)
>> ? #define AML_UART_PORT_NUM??????? 12
>> ? #define AML_UART_PORT_OFFSET??????? 6
>> @@ -76,6 +75,13 @@
>> ? #define AML_UART_POLL_USEC??????? 5
>> ? #define AML_UART_TIMEOUT_USEC??????? 10000
>> +struct meson_uart_data {
>> +??? struct uart_port??? port;
>> +??? struct clk??????? *pclk;
>> +??? struct clk??????? *baud_clk;
>> +??? bool??????????? use_xtal_clk;
>> +};
>> +
>> ? static struct uart_driver meson_uart_driver;
>> ? static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>> @@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port 
>> *port)
>> ? static int meson_uart_startup(struct uart_port *port)
>> ? {
>> ????? u32 val;
>> -??? int ret = 0;
>> +??? int ret;
>> -??? val = readl(port->membase + AML_UART_CONTROL);
>> -??? val |= AML_UART_CLEAR_ERR;
>> -??? writel(val, port->membase + AML_UART_CONTROL);
>> -??? val &= ~AML_UART_CLEAR_ERR;
>> -??? writel(val, port->membase + AML_UART_CONTROL);
>> +??? meson_uart_reset(port);
> 
> Why is this OK? We didn't use to reset it.
This change simply optimizes the code. Because the meson_uart_reset 
function has implemented the control logic.
> 
> And why is this not done in a separate patch?
I will consider merging with the previous patch as a patch.
> 
> 
>> +??? val = readl(port->membase + AML_UART_CONTROL);
>> ????? val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>> ????? writel(val, port->membase + AML_UART_CONTROL);
>> @@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port 
>> *port)
>> ? static void meson_uart_change_speed(struct uart_port *port, unsigned 
>> long baud)
>> ? {
>> +??? struct meson_uart_data *private_data = port->private_data;
>> ????? u32 val;
>> ????? while (!meson_uart_tx_empty(port))
>> ????????? cpu_relax();
>> -??? if (port->uartclk == 24000000) {
>> -??????? val = ((port->uartclk / 3) / baud) - 1;
>> -??????? val |= AML_UART_BAUD_XTAL;
>> -??? } else {
>> -??????? val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>> -??? }
>> +??? val = readl(port->membase + AML_UART_REG5);
>> ????? val |= AML_UART_BAUD_USE;
>> ????? writel(val, port->membase + AML_UART_REG5);
>> +
>> +??? clk_set_rate(private_data->baud_clk, baud);
>> ? }
>> ? static void meson_uart_set_termios(struct uart_port *port,
>> @@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct 
>> uart_port *port,
>> ? static void meson_uart_release_port(struct uart_port *port)
>> ? {
>> -??? /* nothing to do */
>> +??? struct meson_uart_data *private_data = port->private_data;
>> +
>> +??? clk_disable_unprepare(private_data->baud_clk);
>> +??? clk_disable_unprepare(private_data->pclk);
>> ? }
>> ? static int meson_uart_request_port(struct uart_port *port)
>> ? {
>> +??? struct meson_uart_data *private_data = port->private_data;
>> +??? int ret;
>> +
>> +??? ret = clk_prepare_enable(private_data->pclk);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? ret = clk_prepare_enable(private_data->baud_clk);
>> +??? if (ret) {
>> +??????? clk_disable_unprepare(private_data->pclk);
>> +??????? return ret;
>> +??? }
>> +
>> ????? return 0;
>> ? }
>> @@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
>> ????? .cons??????? = MESON_SERIAL_CONSOLE,
>> ? };
>> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>> -???????????????????????? const char *id)
>> +#define CLK_NAME(name) \
>> +({\
>> +??? char clk_name[32];\
>> +??? snprintf(clk_name, sizeof(clk_name), "%s#%s", 
>> dev_name(port->dev), #name);\
>> +??? clk_name;\
>> +})
> 
> This is cryptic and duplicates the variable on the stack. Why not expand 
> the macro and delete it then?
> 
I've overdone it. I'll move it to the meson_uart_probe_clocks function 
as you suggested and delete it.
>> +
>> +static struct clk_div_table xtal_div_table[] = {
>> +??? { 0, 3? },
> 
> An extra space here and there:
> 
>> +??? { 1, 1? },
>> +??? { 2, 2? },
>> +??? { 3, 2? },
>> +};
>> +
Sorry, stupid mistake. I will correct.

>> +static int meson_uart_probe_clocks(struct uart_port *port)
>> ? {
>> -??? struct clk *clk = NULL;
>> -??? int ret;
>> +??? struct meson_uart_data *private_data = port->private_data;
>> +??? struct clk *clk_baud, *clk_xtal;
>> +??? struct clk_hw *hw;
>> +??? struct clk_parent_data use_xtal_mux_parents[2] = {
>> +??????? { .index = -1, },
>> +??????? { .index = -1, },
>> +??? };
>> -??? clk = devm_clk_get(dev, id);
>> -??? if (IS_ERR(clk))
>> -??????? return clk;
>> +??? private_data->pclk = devm_clk_get(port->dev, "pclk");
>> +??? if (IS_ERR(private_data->pclk))
>> +??????? return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
>> +???????????????????? "Failed to get the 'pclk' clock\n");
>> -??? ret = clk_prepare_enable(clk);
>> -??? if (ret) {
>> -??????? dev_err(dev, "couldn't enable clk\n");
>> -??????? return ERR_PTR(ret);
>> +??? clk_baud = devm_clk_get(port->dev, "baud");
>> +??? if (IS_ERR(clk_baud)) {
>> +??????? dev_err(port->dev, "Failed to get the 'baud' clock\n");
>> +??????? return PTR_ERR(clk_baud);
>> ????? }
>> -??? devm_add_action_or_reset(dev,
>> -??????????? (void(*)(void *))clk_disable_unprepare,
>> -??????????? clk);
>> -
>> -??? return clk;
>> -}
>> -
>> -static int meson_uart_probe_clocks(struct platform_device *pdev,
>> -?????????????????? struct uart_port *port)
>> -{
>> -??? struct clk *clk_xtal = NULL;
>> -??? struct clk *clk_pclk = NULL;
>> -??? struct clk *clk_baud = NULL;
>> -
>> -??? clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>> -??? if (IS_ERR(clk_pclk))
>> -??????? return PTR_ERR(clk_pclk);
>> -
>> -??? clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>> +??? clk_xtal = devm_clk_get(port->dev, "xtal");
>> ????? if (IS_ERR(clk_xtal))
>> -??????? return PTR_ERR(clk_xtal);
>> -
>> -??? clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>> -??? if (IS_ERR(clk_baud))
>> -??????? return PTR_ERR(clk_baud);
>> +??????? return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>> +???????????????????? "Failed to get the 'xtal' clock\n");
>> +
>> +??? if (private_data->use_xtal_clk) {
>> +??????? hw = devm_clk_hw_register_divider_table(port->dev,
>> +??????????????????????????? CLK_NAME(xtal_div),
>> +??????????????????????????? __clk_get_name(clk_baud),
>> +??????????????????????????? CLK_SET_RATE_NO_REPARENT,
>> +??????????????????????????? port->membase + AML_UART_REG5,
>> +??????????????????????????? 26, 2,
>> +??????????????????????????? CLK_DIVIDER_READ_ONLY,
>> +??????????????????????????? xtal_div_table, NULL);
>> +??????? if (IS_ERR(hw))
>> +??????????? return PTR_ERR(hw);
>> +
>> +??????? use_xtal_mux_parents[1].hw = hw;
>> +??? } else {
>> +??????? hw = devm_clk_hw_register_fixed_factor(port->dev,
>> +?????????????????????????????? CLK_NAME(clk81_div4),
>> +?????????????????????????????? __clk_get_name(clk_baud),
>> +?????????????????????????????? CLK_SET_RATE_NO_REPARENT,
>> +?????????????????????????????? 1, 4);
>> +??????? if (IS_ERR(hw))
>> +??????????? return PTR_ERR(hw);
>> +
>> +??????? use_xtal_mux_parents[0].hw = hw;
>> +??? }
>> -??? port->uartclk = clk_get_rate(clk_baud);
>> +??? hw = __devm_clk_hw_register_mux(port->dev, NULL,
>> +??????????????????? CLK_NAME(use_xtal),
>> +??????????????????? ARRAY_SIZE(use_xtal_mux_parents),
>> +??????????????????? NULL, NULL,
>> +??????????????????? use_xtal_mux_parents,
>> +??????????????????? CLK_SET_RATE_PARENT,
>> +??????????????????? port->membase + AML_UART_REG5,
>> +??????????????????? 24, 0x1,
>> +??????????????????? CLK_MUX_READ_ONLY,
>> +??????????????????? NULL, NULL);
>> +??? if (IS_ERR(hw))
>> +??????? return PTR_ERR(hw);
>> +
>> +??? port->uartclk = clk_hw_get_rate(hw);
>> +
>> +??? hw = devm_clk_hw_register_divider(port->dev,
>> +????????????????????? CLK_NAME(baud_div),
>> +????????????????????? clk_hw_get_name(hw),
>> +????????????????????? CLK_SET_RATE_PARENT,
>> +????????????????????? port->membase + AML_UART_REG5,
>> +????????????????????? 0, 23,
>> +????????????????????? CLK_DIVIDER_ROUND_CLOSEST,
>> +????????????????????? NULL);
>> +??? if (IS_ERR(hw))
>> +??????? return PTR_ERR(hw);
>> +
>> +??? private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
>> ????? return 0;
>> ? }
> 
> 
> 


From yu.tu at amlogic.com  Mon Jan 10 23:04:14 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 11 Jan 2022 15:04:14 +0800
Subject: [PATCH V4 3/5] tty: serial: meson: The UART baud rate
In-Reply-To: <1j8rvnps11.fsf@starbuckisacylon.baylibre.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
 <20220110085604.18042-4-yu.tu@amlogic.com>
 <1j8rvnps11.fsf@starbuckisacylon.baylibre.com>
Message-ID: <c9bb2f8f-6169-b4ab-5637-56c185dbf254@amlogic.com>

Hi Jerome,
	Thank you very much for your reply.

On 2022/1/10 22:29, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> 
> On Mon 10 Jan 2022 at 16:56, Yu Tu <yu.tu at amlogic.com> wrote:
> 
> Title is bad (like several other patches in this series) - Please fix it
> Ok.
>> Using the common Clock code to describe the UART baud rate clock
>> makes it easier for the UART driver to be compatible with the
>> baud rate requirements of the UART IP on different meson chips.
>>
>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>> ---
>>   drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
>>   1 file changed, 163 insertions(+), 61 deletions(-)
>>
>> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
>> index 7570958d010c..1004fd0b0c9e 100644
>> --- a/drivers/tty/serial/meson_uart.c
>> +++ b/drivers/tty/serial/meson_uart.c
>> @@ -6,6 +6,7 @@
>>    */
>>   
>>   #include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>>   #include <linux/console.h>
>>   #include <linux/delay.h>
>>   #include <linux/init.h>
>> @@ -65,9 +66,7 @@
>>   #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>>   
>>   /* AML_UART_REG5 bits */
>> -#define AML_UART_BAUD_MASK		0x7fffff
>>   #define AML_UART_BAUD_USE		BIT(23)
>> -#define AML_UART_BAUD_XTAL		BIT(24)
>>   
>>   #define AML_UART_PORT_NUM		12
>>   #define AML_UART_PORT_OFFSET		6
>> @@ -76,6 +75,13 @@
>>   #define AML_UART_POLL_USEC		5
>>   #define AML_UART_TIMEOUT_USEC		10000
>>   
>> +struct meson_uart_data {
>> +	struct uart_port	port;
>> +	struct clk		*pclk;
>> +	struct clk		*baud_clk;
>> +	bool			use_xtal_clk;
>> +};
>> +
>>   static struct uart_driver meson_uart_driver;
>>   
>>   static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>> @@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
>>   static int meson_uart_startup(struct uart_port *port)
>>   {
>>   	u32 val;
>> -	int ret = 0;
>> +	int ret;
>>   
>> -	val = readl(port->membase + AML_UART_CONTROL);
>> -	val |= AML_UART_CLEAR_ERR;
>> -	writel(val, port->membase + AML_UART_CONTROL);
>> -	val &= ~AML_UART_CLEAR_ERR;
>> -	writel(val, port->membase + AML_UART_CONTROL);
>> +	meson_uart_reset(port);
>>   
>> +	val = readl(port->membase + AML_UART_CONTROL);
>>   	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>>   	writel(val, port->membase + AML_UART_CONTROL);
>>   
>> @@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port *port)
>>   
>>   static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
>>   {
>> +	struct meson_uart_data *private_data = port->private_data;
>>   	u32 val;
>>   
>>   	while (!meson_uart_tx_empty(port))
>>   		cpu_relax();
>>   
>> -	if (port->uartclk == 24000000) {
>> -		val = ((port->uartclk / 3) / baud) - 1;
>> -		val |= AML_UART_BAUD_XTAL;
>> -	} else {
>> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>> -	}
>> +	val = readl(port->membase + AML_UART_REG5);
>>   	val |= AML_UART_BAUD_USE;
>>   	writel(val, port->membase + AML_UART_REG5);
>> +
>> +	clk_set_rate(private_data->baud_clk, baud);
>>   }
>>   
>>   static void meson_uart_set_termios(struct uart_port *port,
>> @@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>>   
>>   static void meson_uart_release_port(struct uart_port *port)
>>   {
>> -	/* nothing to do */
>> +	struct meson_uart_data *private_data = port->private_data;
>> +
>> +	clk_disable_unprepare(private_data->baud_clk);
>> +	clk_disable_unprepare(private_data->pclk);
>>   }
>>   
>>   static int meson_uart_request_port(struct uart_port *port)
>>   {
>> +	struct meson_uart_data *private_data = port->private_data;
>> +	int ret;
>> +
>> +	ret = clk_prepare_enable(private_data->pclk);
>> +	if (ret)
>> +		return ret;
> 
> In the previous version of the series, you already been asked to the
> enable of pclk in the probe. Optimization should not be mixed with this
> series
> 
> Please make sure all comments are addressed before re-posting
> 
I'm sorry. I misunderstood you earlier. I'm going to move into the probe 
function.
>> +
>> +	ret = clk_prepare_enable(private_data->baud_clk);
>> +	if (ret) {
>> +		clk_disable_unprepare(private_data->pclk);
>> +		return ret;
>> +	}
>> +
>>   	return 0;
>>   }
>>   
>> @@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
>>   	.cons		= MESON_SERIAL_CONSOLE,
>>   };
>>   
>> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>> -						 const char *id)
>> +#define CLK_NAME(name) \
>> +({\
>> +	char clk_name[32];\
>> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
>> +	clk_name;\
>> +})
> 
> 1) This result in some ugly code being inlined
> 2) You return a pointer a local variable which is not gurantee to exist
> anymore  outside of this ...
> 
> Please do this simply in the related function.
I've overdone it. I'll move it to the meson_uart_probe_clocks function 
as you suggested.
> 
>> +
>> +static struct clk_div_table xtal_div_table[] = {
>> +	{ 0, 3  },
>> +	{ 1, 1  },
>> +	{ 2, 2  },
>> +	{ 3, 2  },
>> +};
>> +
>> +static int meson_uart_probe_clocks(struct uart_port *port)
>>   {
>> -	struct clk *clk = NULL;
>> -	int ret;
>> +	struct meson_uart_data *private_data = port->private_data;
>> +	struct clk *clk_baud, *clk_xtal;
>> +	struct clk_hw *hw;
>> +	struct clk_parent_data use_xtal_mux_parents[2] = {
>> +		{ .index = -1, },
>> +		{ .index = -1, },
>> +	};
>>   
>> -	clk = devm_clk_get(dev, id);
>> -	if (IS_ERR(clk))
>> -		return clk;
>> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
>> +	if (IS_ERR(private_data->pclk))
>> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
>> +				     "Failed to get the 'pclk' clock\n");
>>   
>> -	ret = clk_prepare_enable(clk);
>> -	if (ret) {
>> -		dev_err(dev, "couldn't enable clk\n");
>> -		return ERR_PTR(ret);
>> +	clk_baud = devm_clk_get(port->dev, "baud");
>> +	if (IS_ERR(clk_baud)) {
>> +		dev_err(port->dev, "Failed to get the 'baud' clock\n");
>> +		return PTR_ERR(clk_baud);
>>   	}
>>   
>> -	devm_add_action_or_reset(dev,
>> -			(void(*)(void *))clk_disable_unprepare,
>> -			clk);
>> -
>> -	return clk;
>> -}
>> -
>> -static int meson_uart_probe_clocks(struct platform_device *pdev,
>> -				   struct uart_port *port)
>> -{
>> -	struct clk *clk_xtal = NULL;
>> -	struct clk *clk_pclk = NULL;
>> -	struct clk *clk_baud = NULL;
>> -
>> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>> -	if (IS_ERR(clk_pclk))
>> -		return PTR_ERR(clk_pclk);
>> -
>> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>>   	if (IS_ERR(clk_xtal))
>> -		return PTR_ERR(clk_xtal);
>> -
>> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>> -	if (IS_ERR(clk_baud))
>> -		return PTR_ERR(clk_baud);
>> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>> +				     "Failed to get the 'xtal' clock\n");
>> +
>> +	if (private_data->use_xtal_clk) {
>> +		hw = devm_clk_hw_register_divider_table(port->dev,
>> +							CLK_NAME(xtal_div),
>> +							__clk_get_name(clk_baud),
>> +							CLK_SET_RATE_NO_REPARENT,
>> +							port->membase + AML_UART_REG5,
>> +							26, 2,
>> +							CLK_DIVIDER_READ_ONLY,
>> +							xtal_div_table, NULL);
>> +		if (IS_ERR(hw))
>> +			return PTR_ERR(hw);
>> +
>> +		use_xtal_mux_parents[1].hw = hw;
>> +	} else {
>> +		hw = devm_clk_hw_register_fixed_factor(port->dev,
>> +						       CLK_NAME(clk81_div4),
>> +						       __clk_get_name(clk_baud),
>> +						       CLK_SET_RATE_NO_REPARENT,
>> +						       1, 4);
>> +		if (IS_ERR(hw))
>> +			return PTR_ERR(hw);
>> +
>> +		use_xtal_mux_parents[0].hw = hw;
>> +	}
> 
> Contradiction with previous series.
> In the previous series we could clearly see that gxbb did not have the
> /4 divider. It did not have bits 26 and 27 either.
> 
> Now gxbb get the /4 divider. It operated correctly without it so far, so
> this is rather suspicious. Could you please comment on this ?
> 
As Martin and I discussed earlier.
meson6 and meson8b SoC.There are not have bits 26 and 27 either.
CLK81 is recommended for this part of SOC.

GXL,GXM,GXBB and AXG SOC.The UART_EE_A_REG5[26] is added.
UART_EE_A_REG5[26]:
- 0x0: divide the input clock by 3 (meaning: this internally works
with an 8MHz clock)
- 0x1: use the input clock directly without further division (meaning:
this internally work with an 24MHz clock)
8MHz is recommended for this part of SOC. Their UART IP configuration is 
the same.

G12A/B,,SM1,A1 and S4 SOC.The UART_EE_A_REG5[27] is added.
UART_EE_A_REG5[27]:
- 0x0: use the clock as configured in UART_EE_A_REG5[26]
- 0x1: divide the input clock by 2 (meaning: this internally works
with an 12MHz clock)
12MHz is recommended for this part of SOC.

NOTE:
1. clk81 /4 divider.
There is a 4 divider inside, this is what the internal SOC designer told 
me. But they forgot to document it. So it makes people feel suspicious.

2.The UART_EE_A_REG5 default value is 0,except for the console port(set 
in romcode).All the baud rate clocks supported by UART can work, but 
different chip usage scenarios suggest using that clock to reduce jitter.

In summary, I would like to know your suggestions, including how to 
change compatible.
Thank you so much!

  >>
>> -	port->uartclk = clk_get_rate(clk_baud);
>> +	hw = __devm_clk_hw_register_mux(port->dev, NULL,
>> +					CLK_NAME(use_xtal),
>> +					ARRAY_SIZE(use_xtal_mux_parents),
>> +					NULL, NULL,
>> +					use_xtal_mux_parents,
>> +					CLK_SET_RATE_PARENT,
>> +					port->membase + AML_UART_REG5,
>> +					24, 0x1,
>> +					CLK_MUX_READ_ONLY,
>> +					NULL, NULL);
>> +	if (IS_ERR(hw))
>> +		return PTR_ERR(hw);
>> +
>> +	port->uartclk = clk_hw_get_rate(hw);
>> +
>> +	hw = devm_clk_hw_register_divider(port->dev,
>> +					  CLK_NAME(baud_div),
>> +					  clk_hw_get_name(hw),
>> +					  CLK_SET_RATE_PARENT,
>> +					  port->membase + AML_UART_REG5,
>> +					  0, 23,
>> +					  CLK_DIVIDER_ROUND_CLOSEST,
>> +					  NULL);
>> +	if (IS_ERR(hw))
>> +		return PTR_ERR(hw);
>> +
>> +	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
> 
> I have already commented on the use of this function in the previous
> version.
> 
> Please make sure all comments are addressed before re-posting
> 
I'm sorry. I misunderstood you earlier. I will be changed to
"private_data->baud_clk = hw->clk;".What do you think?
>>   
>>   	return 0;
>>   }
>>   
>>   static int meson_uart_probe(struct platform_device *pdev)
>>   {
>> +	struct meson_uart_data *private_data;
>>   	struct resource *res_mem;
>>   	struct uart_port *port;
>>   	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
>> @@ -716,18 +783,20 @@ static int meson_uart_probe(struct platform_device *pdev)
>>   		return -EBUSY;
>>   	}
>>   
>> -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
>> -	if (!port)
>> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
>> +				    GFP_KERNEL);
>> +	if (!private_data)
>>   		return -ENOMEM;
>>   
>> +	if (device_get_match_data(&pdev->dev))
>> +		private_data->use_xtal_clk = true;
>> +
>> +	port = &private_data->port;
>> +
>>   	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>>   	if (IS_ERR(port->membase))
>>   		return PTR_ERR(port->membase);
>>   
>> -	ret = meson_uart_probe_clocks(pdev, port);
>> -	if (ret)
>> -		return ret;
>> -
>>   	port->iotype = UPIO_MEM;
>>   	port->mapbase = res_mem->start;
>>   	port->mapsize = resource_size(res_mem);
>> @@ -740,7 +809,11 @@ static int meson_uart_probe(struct platform_device *pdev)
>>   	port->x_char = 0;
>>   	port->ops = &meson_uart_ops;
>>   	port->fifosize = fifosize;
>> +	port->private_data = private_data;
> 
> port has private_data
> private_data has port
> 
> Is it really necessary to have both ... looks to me that port in
> private_data is overkill
> 
It's very thoughtful of you. I'll delete it as you suggested.
>>   
>> +	ret = meson_uart_probe_clocks(port);
>> +	if (ret)
>> +		return ret;
>>   	meson_ports[pdev->id] = port;
>>   	platform_set_drvdata(pdev, port);
>>   
>> @@ -766,10 +839,39 @@ static int meson_uart_remove(struct platform_device *pdev)
>>   }
>>   
>>   static const struct of_device_id meson_uart_dt_match[] = {
>> -	{ .compatible = "amlogic,meson6-uart" },
>> -	{ .compatible = "amlogic,meson8-uart" },
>> -	{ .compatible = "amlogic,meson8b-uart" },
>> -	{ .compatible = "amlogic,meson-gx-uart" },
>> +	{
>> +		.compatible = "amlogic,meson6-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson8-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson8b-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-gxbb-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-gxl-uart",
>> +		.data = (void *)true,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-g12a-uart",
>> +		.data = (void *)true,
>> +	},
>> +	/*
>> +	 * deprecated, don't use anymore because it doesn't differentiate
>> +	 * between GXBB, GXL and G12A which have different revisions
>> +	 * of the UART IP.
>> +	 */
>> +	{
>> +		.compatible = "amlogic,meson-gx-uart",
>> +		.data = (void *)false,
>> +	},
>>   	{ /* sentinel */ },
>>   };
>>   MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
> 


From yu.tu at amlogic.com  Mon Jan 10 23:18:13 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 11 Jan 2022 15:18:13 +0800
Subject: [PATCH V5 1/5] dt-bindings: serial: meson: Drop legacy compatible.
In-Reply-To: <CAL_JsqKFLnfc5eaUHeo6EkbS0kkpA94rh=Zuda9V9aCragdVxw@mail.gmail.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
 <20220110104214.25321-2-yu.tu@amlogic.com>
 <CAL_JsqKFLnfc5eaUHeo6EkbS0kkpA94rh=Zuda9V9aCragdVxw@mail.gmail.com>
Message-ID: <fbca8027-f7f0-7822-5252-0be586a66496@amlogic.com>

Hi Rob,
	Thank you very much for your reply.

On 2022/1/11 0:18, Rob Herring wrote:
> [ EXTERNAL EMAIL ]
> 
> On Mon, Jan 10, 2022 at 4:42 AM Yu Tu <yu.tu at amlogic.com> wrote:
>>
>> Deprecated, don't use anymore because legacy amlogic,meson-gx-uart
>> compatible. Don't differentiate between GXBB, GXL and G12A which
>> have different revisions of the UART IP. So it's split into
>> GXBB,GXL and G12A.
> 
> You are breaking compatibility. If your dts is updated to use the new
> compatible, then a kernel without the change will not work anymore. It
> worked before without understanding the changes you are making. It
> should continue to. A compatible value like this would accomplish what
> you want:
> 
> "amlogic,meson-gxbb-uart", "amlogic,meson-gx-uart", "amlogic,meson-ao-uart"
> 
> A new kernel will match on "amlogic,meson-gxbb-uart" or
> "amlogic,meson-gx-uart" depending if the dtb is updated or not. An old
> kernel will continue to match on "amlogic,meson-gx-uart".
> 
> If you are going to go breaking things, the power domain distinction
> in the compatible is odd...
> 
I will not blindly delete this "amlogic, meson-gx-uart" compatible as 
you suggest, just make a comment until all DTS changes are finished.
> 
> Rob
> 


From hverkuil-cisco at xs4all.nl  Tue Jan 11 01:16:37 2022
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Tue, 11 Jan 2022 10:16:37 +0100
Subject: [PATCH v3] media: meson: vdec: Fix a NULL pointer dereference in
 amvdec_add_ts()
In-Reply-To: <20211215033535.40422-1-zhou1615@umn.edu>
References: <20211214144613.35fec82a@coco.lan>
 <20211215033535.40422-1-zhou1615@umn.edu>
Message-ID: <368bc1b7-ff86-beaa-6749-afbe5960eaeb@xs4all.nl>

Zhou Qingyang, this is exactly the patch Neil wrote, except you just stuck your
name on it. Not nice.

Neil, can you post your patch with your own Signed-off-by, then I'll take that one.

Regards,

	Hans

On 15/12/2021 04:35, Zhou Qingyang wrote:
> In amvdec_add_ts(), there is a dereference of kzalloc(), which could lead
> to a NULL pointer dereference on failure of kzalloc().
> 
> Fix this bug by adding a NULL check of new_ts.
> 
> This bug was found by a static analyzer[1].
> 
> Builds with CONFIG_VIDEO_MESON_VDEC=m show no new warnings,
> and our static analyzer no longer warns about this code.
> 
> Fixes: 876f123b8956 ("media: meson: vdec: bring up to compliance")
> Signed-off-by: Zhou Qingyang <zhou1615 at umn.edu>
> ---
> 
> [1] The analysis employs differential checking to identify inconsistent
> security operations (e.g., checks or kfrees) between two code paths and
> confirms that the inconsistent operations are not recovered in the 
> current function or the callers, so they constitute bugs.
> 
> Note that, as a bug found by static analysis, it can be a false
> positive or hard to trigger. Multiple researchers have cross-reviewed
> the bug.
> 
> Changes in v3:
>   -  Change the description of patch
>   -  Turn the return type from 'void' to 'int'
>   -  Check the return value in the caller 'esparser_queue()'
> 
> Changes in v2:
>   -  Delete dev_err() message
> 
>  drivers/staging/media/meson/vdec/esparser.c     | 7 ++++++-
>  drivers/staging/media/meson/vdec/vdec_helpers.c | 8 ++++++--
>  drivers/staging/media/meson/vdec/vdec_helpers.h | 4 ++--
>  3 files changed, 14 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
> index db7022707ff8..095100a50da8 100644
> --- a/drivers/staging/media/meson/vdec/esparser.c
> +++ b/drivers/staging/media/meson/vdec/esparser.c
> @@ -328,7 +328,12 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
>  
>  	offset = esparser_get_offset(sess);
>  
> -	amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
> +	ret = amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
> +	if (!ret) {
> +		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
> +		return ret;
> +	}
> +
>  	dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X flags = %08X\n",
>  		vb->timestamp, payload_size, offset, vbuf->flags);
>  
> diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c
> index b9125c295d1d..06fd66539797 100644
> --- a/drivers/staging/media/meson/vdec/vdec_helpers.c
> +++ b/drivers/staging/media/meson/vdec/vdec_helpers.c
> @@ -227,13 +227,16 @@ int amvdec_set_canvases(struct amvdec_session *sess,
>  }
>  EXPORT_SYMBOL_GPL(amvdec_set_canvases);
>  
> -void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> -		   struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
> +int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> +		  struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
>  {
>  	struct amvdec_timestamp *new_ts;
>  	unsigned long flags;
>  
>  	new_ts = kzalloc(sizeof(*new_ts), GFP_KERNEL);
> +	if (!new_ts)
> +		return -ENOMEM;
> +
>  	new_ts->ts = ts;
>  	new_ts->tc = tc;
>  	new_ts->offset = offset;
> @@ -242,6 +245,7 @@ void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
>  	spin_lock_irqsave(&sess->ts_spinlock, flags);
>  	list_add_tail(&new_ts->list, &sess->timestamps);
>  	spin_unlock_irqrestore(&sess->ts_spinlock, flags);
> +	return 0;
>  }
>  EXPORT_SYMBOL_GPL(amvdec_add_ts);
>  
> diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.h b/drivers/staging/media/meson/vdec/vdec_helpers.h
> index 88137d15aa3a..4bf3e61d081b 100644
> --- a/drivers/staging/media/meson/vdec/vdec_helpers.h
> +++ b/drivers/staging/media/meson/vdec/vdec_helpers.h
> @@ -56,8 +56,8 @@ void amvdec_dst_buf_done_offset(struct amvdec_session *sess,
>   * @offset: offset in the VIFIFO where the associated packet was written
>   * @flags: the vb2_v4l2_buffer flags
>   */
> -void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> -		   struct v4l2_timecode tc, u32 offset, u32 flags);
> +int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> +		  struct v4l2_timecode tc, u32 offset, u32 flags);
>  void amvdec_remove_ts(struct amvdec_session *sess, u64 ts);
>  
>  /**



From hverkuil at xs4all.nl  Tue Jan 11 01:21:59 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Tue, 11 Jan 2022 10:21:59 +0100
Subject: [PATCH v2] media: meson: vdec: potential dereference of null
 pointer
In-Reply-To: <20211210015620.2143555-1-jiasheng@iscas.ac.cn>
References: <20211210015620.2143555-1-jiasheng@iscas.ac.cn>
Message-ID: <03dbdbe8-ea08-ef62-c09d-67b3baab6401@xs4all.nl>

On 10/12/2021 02:56, Jiasheng Jiang wrote:
> The return value of kzalloc() needs to be checked.
> To avoid use of null pointer in case of the failure of alloc.

Same issue as with Zhou's patch: this is almost identical to Neil's patch,
but without any mention of his name.

I very much prefer it if Neil just posts his patch so I can pick that up.

Regards,

	Hans

> 
> Fixes: 876f123b8956 ("media: meson: vdec: bring up to compliance")
> Signed-off-by: Jiasheng Jiang <jiasheng at iscas.ac.cn>
> ---
> Changelog:
> 
> v1 -> v2
> 
> *Change 1. Change the return type of amvdec_add_ts from void to int.
> *Change 2. Return -ENOMEN if alloc fail and return 0 if not.
> *Change 3. Modify the caller to deal with the error.
> ---
>  drivers/staging/media/meson/vdec/esparser.c     | 6 +++++-
>  drivers/staging/media/meson/vdec/vdec_helpers.c | 5 ++++-
>  drivers/staging/media/meson/vdec/vdec_helpers.h | 2 +-
>  3 files changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
> index db7022707ff8..7e78288cc551 100644
> --- a/drivers/staging/media/meson/vdec/esparser.c
> +++ b/drivers/staging/media/meson/vdec/esparser.c
> @@ -328,9 +328,13 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
>  
>  	offset = esparser_get_offset(sess);
>  
> -	amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
> +	ret = amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
>  	dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X flags = %08X\n",
>  		vb->timestamp, payload_size, offset, vbuf->flags);
> +	if (ret) {
> +		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
> +		return ret;
> +	}
>  
>  	vbuf->flags = 0;
>  	vbuf->field = V4L2_FIELD_NONE;
> diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c
> index 7f07a9175815..972a1d1a12a5 100644
> --- a/drivers/staging/media/meson/vdec/vdec_helpers.c
> +++ b/drivers/staging/media/meson/vdec/vdec_helpers.c
> @@ -227,13 +227,15 @@ int amvdec_set_canvases(struct amvdec_session *sess,
>  }
>  EXPORT_SYMBOL_GPL(amvdec_set_canvases);
>  
> -void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> +int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> +		  struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
>  {
>  	struct amvdec_timestamp *new_ts;
>  	unsigned long flags;
>  
>  	new_ts = kzalloc(sizeof(*new_ts), GFP_KERNEL);
> +	if (!new_ts)
> +		return -ENOMEM;
>  	new_ts->ts = ts;
>  	new_ts->tc = tc;
>  	new_ts->offset = offset;
> @@ -242,6 +244,7 @@ void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
>  	spin_lock_irqsave(&sess->ts_spinlock, flags);
>  	list_add_tail(&new_ts->list, &sess->timestamps);
>  	spin_unlock_irqrestore(&sess->ts_spinlock, flags);
> +	return 0;
>  }
>  EXPORT_SYMBOL_GPL(amvdec_add_ts);
>  
> diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.h b/drivers/staging/media/meson/vdec/vdec_helpers.h
> index cfaed52ab526..1bcb697290de 100644
> --- a/drivers/staging/media/meson/vdec/vdec_helpers.h
> +++ b/drivers/staging/media/meson/vdec/vdec_helpers.h
> @@ -55,7 +55,7 @@ void amvdec_dst_buf_done_offset(struct amvdec_session *sess,
>   * @offset: offset in the VIFIFO where the associated packet was written
>   * @flags the vb2_v4l2_buffer flags
>   */
> -void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> +int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> +		  struct v4l2_timecode tc, u32 offset, u32 flags);
>  void amvdec_remove_ts(struct amvdec_session *sess, u64 ts);
>  



From aouledameur at baylibre.com  Tue Jan 11 01:52:52 2022
From: aouledameur at baylibre.com (Amjad Ouled-Ameur)
Date: Tue, 11 Jan 2022 10:52:52 +0100
Subject: [PATCH v6 0/3] phy: amlogic: fix shared reset control use
Message-ID: <20220111095255.176141-1-aouledameur@baylibre.com>

This patchset fixes a usb suspend warning seen on the libretech-cc by
using reset_control_rearm() call of the reset framework API. 
This call allows a reset consummer to release the reset line even when 
just triggered so that it may be triggered again by other reset
consummers.

reset_control_(de)assert() calls are called, in some meson usb drivers, 
on a shared reset line when reset_control_reset has been used. This is not
allowed by the reset framework.

Finally the meson usb drivers are updated to use this new call, which
solves the suspend issue addressed by the previous reverted 
commit 7a410953d1fb ("usb: dwc3: meson-g12a: fix shared reset control
use").

changes since v5:
- No changes.

Amjad Ouled-Ameur (3):
  phy: amlogic: phy-meson-gxl-usb2: fix shared reset controller use
  phy: amlogic: meson8b-usb2: Use dev_err_probe()
  phy: amlogic: meson8b-usb2: fix shared reset control use

 drivers/phy/amlogic/phy-meson-gxl-usb2.c | 5 ++++-
 drivers/phy/amlogic/phy-meson8b-usb2.c   | 9 +++++++--
 2 files changed, 11 insertions(+), 3 deletions(-)

-- 
2.25.1



From aouledameur at baylibre.com  Tue Jan 11 01:52:53 2022
From: aouledameur at baylibre.com (Amjad Ouled-Ameur)
Date: Tue, 11 Jan 2022 10:52:53 +0100
Subject: [PATCH v6 1/3] phy: amlogic: phy-meson-gxl-usb2: fix shared reset
 controller use
In-Reply-To: <20220111095255.176141-1-aouledameur@baylibre.com>
References: <20220111095255.176141-1-aouledameur@baylibre.com>
Message-ID: <20220111095255.176141-2-aouledameur@baylibre.com>

Use reset_control_rearm() call if an error occurs in case
phy_meson_gxl_usb2_init() fails after reset() has been called ; or in case
phy_meson_gxl_usb2_exit() is called i.e the resource is no longer used
and the reset line may be triggered again by other devices.

reset_control_rearm() keeps use of triggered_count sane in the reset
framework. Therefore, use of reset_control_reset() on shared reset line
should be balanced with reset_control_rearm().

Signed-off-by: Amjad Ouled-Ameur <aouledameur at baylibre.com>
Reported-by: Jerome Brunet <jbrunet at baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Reviewed-by: Philipp Zabel <p.zabel at pengutronix.de>
Acked-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/phy/amlogic/phy-meson-gxl-usb2.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/amlogic/phy-meson-gxl-usb2.c b/drivers/phy/amlogic/phy-meson-gxl-usb2.c
index 2b3c0d730f20..db17c3448bfe 100644
--- a/drivers/phy/amlogic/phy-meson-gxl-usb2.c
+++ b/drivers/phy/amlogic/phy-meson-gxl-usb2.c
@@ -114,8 +114,10 @@ static int phy_meson_gxl_usb2_init(struct phy *phy)
 		return ret;
 
 	ret = clk_prepare_enable(priv->clk);
-	if (ret)
+	if (ret) {
+		reset_control_rearm(priv->reset);
 		return ret;
+	}
 
 	return 0;
 }
@@ -125,6 +127,7 @@ static int phy_meson_gxl_usb2_exit(struct phy *phy)
 	struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
 
 	clk_disable_unprepare(priv->clk);
+	reset_control_rearm(priv->reset);
 
 	return 0;
 }
-- 
2.25.1



From aouledameur at baylibre.com  Tue Jan 11 01:52:54 2022
From: aouledameur at baylibre.com (Amjad Ouled-Ameur)
Date: Tue, 11 Jan 2022 10:52:54 +0100
Subject: [PATCH v6 2/3] phy: amlogic: meson8b-usb2: Use dev_err_probe()
In-Reply-To: <20220111095255.176141-1-aouledameur@baylibre.com>
References: <20220111095255.176141-1-aouledameur@baylibre.com>
Message-ID: <20220111095255.176141-3-aouledameur@baylibre.com>

Use the existing dev_err_probe() helper instead of open-coding the same
operation.

Signed-off-by: Amjad Ouled-Ameur <aouledameur at baylibre.com>
Reported-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Acked-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/phy/amlogic/phy-meson8b-usb2.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/amlogic/phy-meson8b-usb2.c b/drivers/phy/amlogic/phy-meson8b-usb2.c
index cf10bed40528..77e7e9b1428c 100644
--- a/drivers/phy/amlogic/phy-meson8b-usb2.c
+++ b/drivers/phy/amlogic/phy-meson8b-usb2.c
@@ -265,8 +265,9 @@ static int phy_meson8b_usb2_probe(struct platform_device *pdev)
 		return PTR_ERR(priv->clk_usb);
 
 	priv->reset = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
-	if (PTR_ERR(priv->reset) == -EPROBE_DEFER)
-		return PTR_ERR(priv->reset);
+	if (IS_ERR(priv->reset))
+		return dev_err_probe(&pdev->dev, PTR_ERR(priv->reset),
+				     "Failed to get the reset line");
 
 	priv->dr_mode = of_usb_get_dr_mode_by_phy(pdev->dev.of_node, -1);
 	if (priv->dr_mode == USB_DR_MODE_UNKNOWN) {
-- 
2.25.1



From aouledameur at baylibre.com  Tue Jan 11 01:52:55 2022
From: aouledameur at baylibre.com (Amjad Ouled-Ameur)
Date: Tue, 11 Jan 2022 10:52:55 +0100
Subject: [PATCH v6 3/3] phy: amlogic: meson8b-usb2: fix shared reset control
 use
In-Reply-To: <20220111095255.176141-1-aouledameur@baylibre.com>
References: <20220111095255.176141-1-aouledameur@baylibre.com>
Message-ID: <20220111095255.176141-4-aouledameur@baylibre.com>

Use reset_control_rearm() call if an error occurs in case
phy_meson8b_usb2_power_on() fails after reset() has been called, or in
case phy_meson8b_usb2_power_off() is called i.e the resource is no longer
used and the reset line may be triggered again by other devices.

reset_control_rearm() keeps use of triggered_count sane in the reset
framework, use of reset_control_reset() on shared reset line should
be balanced with reset_control_rearm().

Signed-off-by: Amjad Ouled-Ameur <aouledameur at baylibre.com>
Reported-by: Jerome Brunet <jbrunet at baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Acked-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/phy/amlogic/phy-meson8b-usb2.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/phy/amlogic/phy-meson8b-usb2.c b/drivers/phy/amlogic/phy-meson8b-usb2.c
index 77e7e9b1428c..dd96763911b8 100644
--- a/drivers/phy/amlogic/phy-meson8b-usb2.c
+++ b/drivers/phy/amlogic/phy-meson8b-usb2.c
@@ -154,6 +154,7 @@ static int phy_meson8b_usb2_power_on(struct phy *phy)
 	ret = clk_prepare_enable(priv->clk_usb_general);
 	if (ret) {
 		dev_err(&phy->dev, "Failed to enable USB general clock\n");
+		reset_control_rearm(priv->reset);
 		return ret;
 	}
 
@@ -161,6 +162,7 @@ static int phy_meson8b_usb2_power_on(struct phy *phy)
 	if (ret) {
 		dev_err(&phy->dev, "Failed to enable USB DDR clock\n");
 		clk_disable_unprepare(priv->clk_usb_general);
+		reset_control_rearm(priv->reset);
 		return ret;
 	}
 
@@ -199,6 +201,7 @@ static int phy_meson8b_usb2_power_on(struct phy *phy)
 				dev_warn(&phy->dev, "USB ID detect failed!\n");
 				clk_disable_unprepare(priv->clk_usb);
 				clk_disable_unprepare(priv->clk_usb_general);
+				reset_control_rearm(priv->reset);
 				return -EINVAL;
 			}
 		}
@@ -218,6 +221,7 @@ static int phy_meson8b_usb2_power_off(struct phy *phy)
 
 	clk_disable_unprepare(priv->clk_usb);
 	clk_disable_unprepare(priv->clk_usb_general);
+	reset_control_rearm(priv->reset);
 
 	/* power off the PHY by putting it into reset mode */
 	regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET,
-- 
2.25.1



From noralf at tronnes.org  Tue Jan 11 04:02:50 2022
From: noralf at tronnes.org (=?UTF-8?Q?Noralf_Tr=c3=b8nnes?=)
Date: Tue, 11 Jan 2022 13:02:50 +0100
Subject: [PATCH v2 1/2] drm/mipi-dbi: Remove dependency on GEM CMA helper
 library
In-Reply-To: <20211106193509.17472-2-tzimmermann@suse.de>
References: <20211106193509.17472-2-tzimmermann@suse.de>
Message-ID: <a9e2d66e-1a85-b61f-ee3b-ca7032e0516f@tronnes.org>

> The MIPI DBI helpers access struct drm_gem_cma_object.vaddr in a
> few places. Replace all instances with the correct generic GEM
> functions. Use drm_gem_fb_vmap() for mapping a framebuffer's GEM
> objects and drm_gem_fb_vunmap() for unmapping them. This removes
> the dependency on CMA helpers within MIPI DBI.
>
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
> Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
> ---
>  drivers/gpu/drm/drm_mipi_dbi.c | 34 +++++++++++++++++++++++++---------
>  1 file changed, 25 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_mipi_dbi.c
b/drivers/gpu/drm/drm_mipi_dbi.c
> index 71b646c4131f..f80fd6c0ccf8 100644
> --- a/drivers/gpu/drm/drm_mipi_dbi.c
> +++ b/drivers/gpu/drm/drm_mipi_dbi.c
> @@ -15,9 +15,10 @@
>  #include <drm/drm_connector.h>
>  #include <drm/drm_damage_helper.h>
>  #include <drm/drm_drv.h>
> -#include <drm/drm_gem_cma_helper.h>
> +#include <drm/drm_file.h>
>  #include <drm/drm_format_helper.h>
>  #include <drm/drm_fourcc.h>
> +#include <drm/drm_gem.h>
>  #include <drm/drm_gem_framebuffer_helper.h>
>  #include <drm/drm_mipi_dbi.h>
>  #include <drm/drm_modes.h>
> @@ -200,13 +201,19 @@ int mipi_dbi_buf_copy(void *dst, struct
drm_framebuffer *fb,
>  		      struct drm_rect *clip, bool swap)
>  {
>  	struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0);
> -	struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(gem);
> -	void *src = cma_obj->vaddr;
> +	struct dma_buf_map map[DRM_FORMAT_MAX_PLANES];
> +	struct dma_buf_map data[DRM_FORMAT_MAX_PLANES];
> +	void *src;
>  	int ret;
>
>  	ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
>  	if (ret)
>  		return ret;
> +	src = data[0].vaddr; /* TODO: Use mapping abstraction properly */

This assignment should be after the _vmap() call. The MIPI DBI drivers
are currently broken because of this.

Noralf.

> +
> +	ret = drm_gem_fb_vmap(fb, map, data);
> +	if (ret)
> +		goto out_drm_gem_fb_end_cpu_access;
>
>  	switch (fb->format->format) {
>  	case DRM_FORMAT_RGB565:
> @@ -221,9 +228,11 @@ int mipi_dbi_buf_copy(void *dst, struct
drm_framebuffer *fb,
>  	default:
>  		drm_err_once(fb->dev, "Format is not supported: %p4cc\n",
>  			     &fb->format->format);
> -		return -EINVAL;
> +		ret = -EINVAL;
>  	}
>
> +	drm_gem_fb_vunmap(fb, map);
> +out_drm_gem_fb_end_cpu_access:
>  	drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
>
>  	return ret;
>


From robh at kernel.org  Tue Jan 11 14:54:50 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 16:54:50 -0600
Subject: [PATCH v2 2/9] dt-bindings: arm: amlogic: add X96-AIR bindings
In-Reply-To: <20220103163956.6581-3-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
 <20220103163956.6581-3-christianshewitt@gmail.com>
Message-ID: <Yd4KulrOCjS4PdWG@robh.at.kernel.org>

On Mon, 03 Jan 2022 16:39:49 +0000, Christian Hewitt wrote:
> Add board bindings for the Amediatech X96-AIR STB which ships with
> model variants distiguished by Ethernet configuration: models using
> an external Gigabit PHY have a -gbit suffix, while models using an
> internal 10/100 PHY have no suffix.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  Documentation/devicetree/bindings/arm/amlogic.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 14:55:40 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 16:55:40 -0600
Subject: [PATCH v2 5/9] dt-bindings: arm: amlogic: add A95XF3-AIR bindings
In-Reply-To: <20220103163956.6581-6-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
 <20220103163956.6581-6-christianshewitt@gmail.com>
Message-ID: <Yd4K7PqBM/qNLDkI@robh.at.kernel.org>

On Mon, Jan 03, 2022 at 04:39:52PM +0000, Christian Hewitt wrote:
> Add board bindings for the CYX A95XF3-AIR set-top box which ships
> with model variants distiguished by Ethernet configuration: models

typo: distinguished

> using external Gigabit PHY have a -gbit suffix, while models using
> an internal 10/100 PHY have no suffix.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  Documentation/devicetree/bindings/arm/amlogic.yaml | 2 ++
>  1 file changed, 2 insertions(+)

Otherwise,

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 17:48:10 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:48:10 -0600
Subject: [PATCH 1/3] dt-bindings: reset: Add compatible for Meson-S4
 Reset Controller
In-Reply-To: <20220107023931.13251-2-zelong.dong@amlogic.com>
References: <20220107023931.13251-1-zelong.dong@amlogic.com>
 <20220107023931.13251-2-zelong.dong@amlogic.com>
Message-ID: <Yd4zWnQxB1ZK8IPo@robh.at.kernel.org>

On Fri, 07 Jan 2022 10:39:29 +0800, Zelong Dong wrote:
> Add new compatible for Amlogic's Meson-S4 Reset Controller
> 
> Signed-off-by: Zelong Dong <zelong.dong at amlogic.com>
> ---
>  Documentation/devicetree/bindings/reset/amlogic,meson-reset.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 17:54:24 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:54:24 -0600
Subject: [PATCH 1/6] dt-bindings: display: add Amlogic MIPI DSI Host
 Controller bindings
In-Reply-To: <20220107145515.613009-2-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-2-narmstrong@baylibre.com>
Message-ID: <Yd400IApAqHeSW4B@robh.at.kernel.org>

On Fri, Jan 07, 2022 at 03:55:10PM +0100, Neil Armstrong wrote:
> The Amlogic G12A, G12B & SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
> with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI Glue
> on the same Amlogic SoCs.
> 
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> ---
>  .../display/amlogic,meson-dw-mipi-dsi.yaml    | 118 ++++++++++++++++++
>  1 file changed, 118 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
> 
> diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
> new file mode 100644
> index 000000000000..f3070783d606
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
> @@ -0,0 +1,118 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright 2020 BayLibre, SAS
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/display/amlogic,meson-dw-mipi-dsi.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Amlogic specific extensions to the Synopsys Designware MIPI DSI Host Controller
> +
> +maintainers:
> +  - Neil Armstrong <narmstrong at baylibre.com>
> +
> +description: |
> +  The Amlogic Meson Synopsys Designware Integration is composed of
> +  - A Synopsys DesignWare MIPI DSI Host Controller IP
> +  - A TOP control block controlling the Clocks & Resets of the IP
> +
> +allOf:
> +  - $ref: dsi-controller.yaml#
> +
> +properties:
> +  compatible:
> +    enum:
> +      - amlogic,meson-g12a-dw-mipi-dsi
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    minItems: 2
> +
> +  clock-names:
> +    minItems: 2
> +    items:
> +      - const: pclk
> +      - const: px_clk
> +      - const: meas_clk
> +
> +  resets:
> +    minItems: 1
> +
> +  reset-names:
> +    items:
> +      - const: top
> +
> +  phys:
> +    minItems: 1
> +
> +  phy-names:
> +    items:
> +      - const: dphy
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port at 0:
> +        $ref: /schemas/graph.yaml#/$defs/port-base

/schemas/graph.yaml#/properties/port

> +        unevaluatedProperties: false

And this can be dropped.

> +        description: Input node to receive pixel data.
> +
> +      port at 1:
> +        $ref: /schemas/graph.yaml#/$defs/port-base
> +        unevaluatedProperties: false

Same here.

With that,

Reviewed-by: Rob Herring <robh at kernel.org>

> +        description: DSI output node to panel.
> +
> +    required:
> +      - port at 0
> +      - port at 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - resets
> +  - reset-names
> +  - phys
> +  - phy-names
> +  - ports
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    dsi at 7000 {
> +          compatible = "amlogic,meson-g12a-dw-mipi-dsi";
> +          reg = <0x6000 0x400>;
> +          resets = <&reset_top>;
> +          reset-names = "top";
> +          clocks = <&clk_pclk>, <&clk_px>;
> +          clock-names = "pclk", "px_clk";
> +          phys = <&mipi_dphy>;
> +          phy-names = "dphy";
> +
> +          ports {
> +              #address-cells = <1>;
> +              #size-cells = <0>;
> +
> +              /* VPU VENC Input */
> +              mipi_dsi_venc_port: port at 0 {
> +                  reg = <0>;
> +
> +                  mipi_dsi_in: endpoint {
> +                       remote-endpoint = <&dpi_out>;
> +                  };
> +              };
> +
> +              /* DSI Output */
> +              mipi_dsi_panel_port: port at 1 {
> +                  reg = <1>;
> +
> +                  mipi_out_panel: endpoint {
> +                      remote-endpoint = <&mipi_in_panel>;
> +                  };
> +              };
> +          };
> +    };
> -- 
> 2.25.1
> 
> 


From robh at kernel.org  Tue Jan 11 17:54:46 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:54:46 -0600
Subject: [PATCH 2/6] dt-bindings: display: meson-vpu: add third DPI
 output port
In-Reply-To: <20220107145515.613009-3-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-3-narmstrong@baylibre.com>
Message-ID: <Yd405jhJtNSiOgzm@robh.at.kernel.org>

On Fri, 07 Jan 2022 15:55:11 +0100, Neil Armstrong wrote:
> Add third port corresponding to the ENCL DPI encoder used to connect
> to DSI or LVDS transceivers.
> 
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> ---
>  .../devicetree/bindings/display/amlogic,meson-vpu.yaml       | 5 +++++
>  1 file changed, 5 insertions(+)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From christianshewitt at gmail.com  Tue Jan 11 18:27:04 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:04 +0000
Subject: [PATCH v3 0/9] arm64: dts: meson: add support for ac2xx devices
Message-ID: <20220112022713.25962-1-christianshewitt@gmail.com>

This series adds support for several popular Amlogic S905X3 (SM1) Android
Set-Top Box devices. Like most Android box devices, they ship in variants
with multiple RAM, eMMC, WiFi and BT configurations. RAM and eMMC are not
something we need to consider to get a working boot, but we do need to get
the correct connectivity spec. Broadly speaking we see boxes with Higher
and Lower spec connectivity; High spec is Gigabit Ethernet and Faster dual
antennna WiFi, and Lower spec is Megabit Ethernet and a single antenna. In
some low-end boxes BT is omitted.

As initial distro setup is frequently performed over SSH or an HDMI GUI
app it is important for users to pick a device-tree with the correct
Ethernet PHY spec else connectivity is impossible. To aid this we append
a -gbit suffix to X96-AIR and A95XF3-AIR models using an external Gigabit
PHY, while 10/00 models with internal PHY have no suffix.

NB: At the current time the Realtek 8822CS and MT7668 WiFi/BT modules we
have seen on 'AIR' devices are not supported in the kernel so these are
deliberately omitted. The H96-Max uses a conventional Broadcom module
so has more complete support. For now the boxes have simple HDMI audio
support; wiring up the Headphone socket will be done at a later date.

Changes since v2 series:
- Add Robs binding acks (patches 2/5)
- Add Martin/Piotir's Tested-By's (patches 1/3)
- Reorder Tested-By on patch 9
- Correct 'distinguished' typo in patch 5
- Correct typo in series name/subject

Changes since RFC(v1) series:
- Add Robs binding acks on patches 4/7/8 (patches 2/5 still need acks)
- Rename and rework patches around -gbit (as requested by Neil)
- Correct 'manufacturer' typo on patch 8
- Rebase against v5.18/dt64 branch

Christian Hewitt (9):
  arm64: dts: meson: add common SM1 ac2xx dtsi
  dt-bindings: arm: amlogic: add X96-AIR bindings
  arm64: dts: meson: add initial device-trees for X96-AIR
  dt-bindings: vendor-prefixes: add cyx prefix
  dt-bindings: arm: amlogic: add A95XF3-AIR bindings
  arm64: dts: meson: add initial device-trees for A95XF3-AIR
  dt-bindings: vendor-prefixes: add haochuangyi prefix
  dt-bindings: arm: amlogic: add H96-Max bindings
  arm64: dts: meson: add initial device-tree for H96-Max

 .../devicetree/bindings/arm/amlogic.yaml      |   5 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   4 +
 arch/arm64/boot/dts/amlogic/Makefile          |   5 +
 .../dts/amlogic/meson-sm1-a95xf3-air-gbit.dts | 129 ++++++++
 .../boot/dts/amlogic/meson-sm1-a95xf3-air.dts | 108 +++++++
 .../boot/dts/amlogic/meson-sm1-ac2xx.dtsi     | 300 ++++++++++++++++++
 .../boot/dts/amlogic/meson-sm1-h96-max.dts    | 145 +++++++++
 .../dts/amlogic/meson-sm1-x96-air-gbit.dts    | 133 ++++++++
 .../boot/dts/amlogic/meson-sm1-x96-air.dts    | 112 +++++++
 9 files changed, 941 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts

-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:05 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:05 +0000
Subject: [PATCH v3 1/9] arm64: dts: meson: add common SM1 ac2xx dtsi
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-2-christianshewitt@gmail.com>

Add a common dtsi for Android STB devices based on the Amlogic S905X3
(AC213/AC214) and S905D3 (AC201/AC202) reference designs. The dtsi is
loosely based on the existing SEI610 device-tree.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com> # X96-Air with Gbit PHY
---
 .../boot/dts/amlogic/meson-sm1-ac2xx.dtsi     | 300 ++++++++++++++++++
 1 file changed, 300 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
new file mode 100644
index 000000000000..46a34731f7e2
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ *
+ * AC200/AC202 = S905D3
+ * AC213/AC214 = S905X3
+ *
+ */
+
+#include "meson-sm1.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		serial0 = &uart_AO;
+		ethernet0 = &ethmac;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	emmc_pwrseq: emmc-pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
+	};
+
+	cvbs-connector {
+		compatible = "composite-video-connector";
+
+		port {
+			cvbs_connector_in: endpoint {
+				remote-endpoint = <&cvbs_vdac_out>;
+			};
+		};
+	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&hdmi_tx_tmds_out>;
+			};
+		};
+	};
+
+	memory at 0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x40000000>;
+	};
+
+	ao_5v: regulator-ao_5v {
+		compatible = "regulator-fixed";
+		regulator-name = "AO_5V";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_in>;
+		regulator-always-on;
+	};
+
+	dc_in: regulator-dc_in {
+		compatible = "regulator-fixed";
+		regulator-name = "DC_IN";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	emmc_1v8: regulator-emmc_1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "EMMC_1V8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vddao_3v3>;
+		regulator-always-on;
+	};
+
+	vddao_3v3: regulator-vddao_3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDAO_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&dc_in>;
+		regulator-always-on;
+	};
+
+	vddcpu: regulator-vddcpu {
+		compatible = "pwm-regulator";
+
+		regulator-name = "VDDCPU";
+		regulator-min-microvolt = <690000>;
+		regulator-max-microvolt = <1050000>;
+
+		vin-supply = <&dc_in>;
+
+		pwms = <&pwm_AO_cd 1 1500 0>;
+		pwm-dutycycle-range = <100 0>;
+
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	vddio_ao1v8: regulator-vddio_ao1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDIO_AO1V8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vddao_3v3>;
+		regulator-always-on;
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+		clocks = <&wifi32k>;
+		clock-names = "ext_clock";
+	};
+
+	wifi32k: wifi32k {
+		compatible = "pwm-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+	};
+};
+
+&cec_AO {
+	pinctrl-0 = <&cec_ao_a_h_pins>;
+	pinctrl-names = "default";
+	status = "disabled";
+	hdmi-phandle = <&hdmi_tx>;
+};
+
+&cecb_AO {
+	pinctrl-0 = <&cec_ao_b_h_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+	hdmi-phandle = <&hdmi_tx>;
+};
+
+&cpu0 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu1 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU1_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu2 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU2_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu3 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU3_CLK>;
+	clock-latency = <50000>;
+};
+
+&cvbs_vdac_port {
+	cvbs_vdac_out: endpoint {
+		remote-endpoint = <&cvbs_connector_in>;
+	};
+};
+
+&hdmi_tx {
+	status = "okay";
+	pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
+	pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+	hdmi_tx_tmds_out: endpoint {
+		remote-endpoint = <&hdmi_connector_in>;
+	};
+};
+
+&ir {
+	status = "okay";
+	pinctrl-0 = <&remote_input_ao_pins>;
+	pinctrl-names = "default";
+};
+
+&pwm_AO_ab {
+	status = "okay";
+	pinctrl-0 = <&pwm_ao_a_pins>;
+	pinctrl-names = "default";
+	clocks = <&xtal>;
+	clock-names = "clkin0";
+};
+
+&pwm_AO_cd {
+	pinctrl-0 = <&pwm_ao_d_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&xtal>;
+	clock-names = "clkin1";
+	status = "okay";
+};
+
+&pwm_ef {
+	status = "okay";
+	pinctrl-0 = <&pwm_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&xtal>;
+	clock-names = "clkin0";
+};
+
+&saradc {
+	status = "okay";
+	vref-supply = <&vddio_ao1v8>;
+};
+
+/* SDIO */
+&sd_emmc_a {
+	status = "okay";
+	pinctrl-0 = <&sdio_pins>;
+	pinctrl-1 = <&sdio_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	sd-uhs-sdr104;
+	max-frequency = <200000000>;
+
+	non-removable;
+	disable-wp;
+
+	/* WiFi firmware requires power to be kept while in suspend */
+	keep-power-in-suspend;
+
+	mmc-pwrseq = <&sdio_pwrseq>;
+
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddio_ao1v8>;
+};
+
+/* SD Card */
+&sd_emmc_b {
+	status = "okay";
+	pinctrl-0 = <&sdcard_c_pins>;
+	pinctrl-1 = <&sdcard_clk_gate_c_pins>;
+	pinctrl-names = "default", "clk-gate";
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	/* CRC errors are observed at 50MHz */
+	max-frequency = <35000000>;
+	disable-wp;
+
+	cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddao_3v3>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+	status = "okay";
+	pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
+	pinctrl-1 = <&emmc_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	max-frequency = <200000000>;
+	non-removable;
+	disable-wp;
+
+	mmc-pwrseq = <&emmc_pwrseq>;
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&emmc_1v8>;
+};
+
+&uart_AO {
+	status = "okay";
+	pinctrl-0 = <&uart_ao_a_pins>;
+	pinctrl-names = "default";
+};
+
+&usb {
+	status = "okay";
+	dr_mode = "otg";
+};
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:06 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:06 +0000
Subject: [PATCH v3 2/9] dt-bindings: arm: amlogic: add X96-AIR bindings
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-3-christianshewitt@gmail.com>

Add board bindings for the Amediatech X96-AIR STB which ships with
model variants distiguished by Ethernet configuration: models using
an external Gigabit PHY have a -gbit suffix, while models using an
internal 10/100 PHY have no suffix.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/arm/amlogic.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 31df120d73b0..b5b995941d3b 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -170,6 +170,8 @@ properties:
       - description: Boards with the Amlogic Meson SM1 S905X3/D3/Y3 SoC
         items:
           - enum:
+              - amediatech,x96-air
+              - amediatech,x96-air-gbit
               - bananapi,bpi-m5
               - hardkernel,odroid-c4
               - hardkernel,odroid-hc4
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:07 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:07 +0000
Subject: [PATCH v3 3/9] arm64: dts: meson: add initial device-trees for X96-AIR
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-4-christianshewitt@gmail.com>

The Amediatek X96-AIR is based on Amlogic S905X3 reference board
designs and ships in multiple configurations:

? 4GB DDR3 + 64GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
? 4GB DDR3 + 32GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
? 4GB DDR3 + 32GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
? 2GB DDR3 + 16GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
...
- HDMI 2.1 video
- S/PDIF optical output
- AV output
- 2x USB 2.0 inc. OTG port
- 1x USB 3.0 port
- IR receiver
- 1x micro SD card slot (internal)
- 1x Reset/Update button (in AV jack)
- 7-segment VFD

The device-tree with -gbit suffix supports models with Gigabit
Ethernet, and the device-tree with no suffix supports models
with 10/100 Ethernet.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com> # X96-Air with Gbit PHY
Tested-by: Piotr Oniszczuk <piotr.oniszczuk at gmail.com> # X96-Air with 10/100 Eth
---
 arch/arm64/boot/dts/amlogic/Makefile          |   2 +
 .../dts/amlogic/meson-sm1-x96-air-gbit.dts    | 133 ++++++++++++++++++
 .../boot/dts/amlogic/meson-sm1-x96-air.dts    | 112 +++++++++++++++
 3 files changed, 247 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 5148cd9e5146..1c0e554f54fc 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -56,4 +56,6 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air-gbit.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
new file mode 100644
index 000000000000..7e1a74046ba5
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "amediatech,x96-air-gbit", "amlogic,sm1";
+	model = "Shenzhen Amediatech Technology Co., Ltd X96 Air";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "X96-AIR";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+
+	pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+	pinctrl-names = "default";
+	phy-mode = "rgmii-txid";
+	phy-handle = <&external_phy>;
+
+	rx-internal-delay-ps = <800>;
+};
+
+&ext_mdio {
+	external_phy: ethernet-phy at 0 {
+		/* Realtek RTL8211F (0x001cc916) */
+		reg = <0>;
+		max-speed = <1000>;
+
+		reset-assert-us = <10000>;
+		reset-deassert-us = <80000>;
+		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+		interrupt-parent = <&gpio_intc>;
+		/* MAC_INTR on GPIOZ_14 */
+		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&ir {
+	linux,rc-map-name = "rc-x96max";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts
new file mode 100644
index 000000000000..cd93d798f2a3
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "amediatech,x96-air", "amlogic,sm1";
+	model = "Shenzhen Amediatech Technology Co., Ltd X96 Air";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "X96-AIR";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+	phy-handle = <&internal_ephy>;
+	phy-mode = "rmii";
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&ir {
+	linux,rc-map-name = "rc-beelink-gs1";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:08 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:08 +0000
Subject: [PATCH v3 4/9] dt-bindings: vendor-prefixes: add cyx prefix
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-5-christianshewitt@gmail.com>

Shenzhen CYX Industrial Co., Ltd are a manufacturer of Android
Set-Top Box devices.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index eb8ab0d82198..c9202a101d71 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -281,6 +281,8 @@ patternProperties:
     description: CUI Devices
   "^cypress,.*":
     description: Cypress Semiconductor Corporation
+  "^cyx,.*":
+    description: Shenzhen CYX Industrial Co., Ltd
   "^cznic,.*":
     description: CZ.NIC, z.s.p.o.
   "^dallas,.*":
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:09 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:09 +0000
Subject: [PATCH v3 5/9] dt-bindings: arm: amlogic: add A95XF3-AIR bindings
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-6-christianshewitt@gmail.com>

Add board bindings for the CYX A95XF3-AIR set-top box which ships
with model variants distinguished by Ethernet configuration: models
using external Gigabit PHY have a -gbit suffix, while models using
an internal 10/100 PHY have no suffix.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/arm/amlogic.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index b5b995941d3b..2027ce81a834 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -173,6 +173,8 @@ properties:
               - amediatech,x96-air
               - amediatech,x96-air-gbit
               - bananapi,bpi-m5
+              - cyx,a95xf3-air
+              - cyx,a95xf3-air-gbit
               - hardkernel,odroid-c4
               - hardkernel,odroid-hc4
               - khadas,vim3l
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:10 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:10 +0000
Subject: [PATCH v3 6/9] arm64: dts: meson: add initial device-trees for
 A95XF3-AIR
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-7-christianshewitt@gmail.com>

The CYX A95XF3-AIR is based on Amlogic S905X3 reference board
designs and ships in multiple configurations:

? 4GB DDR3 + 64GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
? 4GB DDR3 + 32GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
? 2GB DDR3 + 16GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
...
- HDMI 2.1 video
- S/PDIF optical output
- AV output
- 1x USB 2.0 OTG port
- 1x USB 3.0 port
- IR receiver
- 1x micro SD card slot (internal)
- 1x Reset/Update button (in AV jack)
- 7-segment VFD
- Multicolour case LED 'arc'

The device-tree with -gbit suffix supports models with Gigabit
Ethernet, and the device-tree with no suffix supports models
with 10/100 Ethernet.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/Makefile          |   2 +
 .../dts/amlogic/meson-sm1-a95xf3-air-gbit.dts | 129 ++++++++++++++++++
 .../boot/dts/amlogic/meson-sm1-a95xf3-air.dts | 108 +++++++++++++++
 3 files changed, 239 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 1c0e554f54fc..e87adc6593df 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -51,6 +51,8 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-rbox-pro.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-s912-libretech-pc.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-vega-s96.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-wetek-core2.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air-gbit.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-bananapi-m5.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
new file mode 100644
index 000000000000..d1debccdc1c2
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "cyx,a95xf3-air-gbit", "amlogic,sm1";
+	model = "Shenzhen CYX Industrial Co., Ltd A95XF3-AIR";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "A95XF3-AIR";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+
+	pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+	pinctrl-names = "default";
+	phy-mode = "rgmii-txid";
+	phy-handle = <&external_phy>;
+
+	rx-internal-delay-ps = <800>;
+};
+
+&ext_mdio {
+	external_phy: ethernet-phy at 0 {
+		/* Realtek RTL8211F (0x001cc916) */
+		reg = <0>;
+		max-speed = <1000>;
+
+		reset-assert-us = <10000>;
+		reset-deassert-us = <80000>;
+		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+		interrupt-parent = <&gpio_intc>;
+		/* MAC_INTR on GPIOZ_14 */
+		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts
new file mode 100644
index 000000000000..c94f2870b78b
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "cyx,a95xf3-air", "amlogic,sm1";
+	model = "Shenzhen CYX Industrial Co., Ltd A95XF3-AIR";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "A95XF3-AIR";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+	phy-handle = <&internal_ephy>;
+	phy-mode = "rmii";
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:11 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:11 +0000
Subject: [PATCH v3 7/9] dt-bindings: vendor-prefixes: add haochuangyi prefix
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-8-christianshewitt@gmail.com>

Shenzhen Haochuangyi Technology Co.,Ltd are a manufacturer of Android
Set-Top Box devices.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index c9202a101d71..f4160ee3b5df 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -485,6 +485,8 @@ patternProperties:
     deprecated: true
   "^hannstar,.*":
     description: HannStar Display Corporation
+  "^haochuangyi,.*":
+    description: Shenzhen Haochuangyi Technology Co.,Ltd
   "^haoyu,.*":
     description: Haoyu Microelectronic Co. Ltd.
   "^hardkernel,.*":
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:12 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:12 +0000
Subject: [PATCH v3 8/9] dt-bindings: arm: amlogic: add H96-Max bindings
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-9-christianshewitt@gmail.com>

Add the board binding for the Haochuangyi H96-Max STB device.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 2027ce81a834..a073a959232c 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -177,6 +177,7 @@ properties:
               - cyx,a95xf3-air-gbit
               - hardkernel,odroid-c4
               - hardkernel,odroid-hc4
+              - haochuangyi,h96-max
               - khadas,vim3l
               - seirobotics,sei610
           - const: amlogic,sm1
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:13 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:13 +0000
Subject: [PATCH v3 9/9] arm64: dts: meson: add initial device-tree for H96-Max
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-10-christianshewitt@gmail.com>

The Haochuangyi H96-Max is based on the Amlogic S905X3 reference
design with the following specs:

- 4GB DDR4 RAM
- 32/64/128GB eMMC
- HDMI 2.1 video
- S/PDIF optical output
- AV output
- 10/100/1000 Base-T Ethernet
- AP6356S Wireless (802.11 a/b/g/n/ac, BT 4.1)
- 1x USB 2.0 OTG port
- 1x USB 3.0 port
- IR receiver
- 1x micro SD card slot (internal)
- 1x Reset/Update button (in AV jack)
- 7-segment VFD

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Benoit Masson <yahoo at perenite.com>
---
 arch/arm64/boot/dts/amlogic/Makefile          |   1 +
 .../boot/dts/amlogic/meson-sm1-h96-max.dts    | 145 ++++++++++++++++++
 2 files changed, 146 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index e87adc6593df..868d74044072 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -54,6 +54,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-wetek-core2.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air-gbit.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-bananapi-m5.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-h96-max.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts
new file mode 100644
index 000000000000..0f6660e68e72
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "haochuangyi,h96-max", "amlogic,sm1";
+	model = "Shenzhen Haochuangyi Technology Co., Ltd H96 Max";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "H96-MAX";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+
+	pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+	pinctrl-names = "default";
+	phy-mode = "rgmii-txid";
+	phy-handle = <&external_phy>;
+
+	rx-internal-delay-ps = <800>;
+};
+
+&ext_mdio {
+	external_phy: ethernet-phy at 0 {
+		/* Realtek RTL8211F (0x001cc916) */
+		reg = <0>;
+		max-speed = <1000>;
+
+		reset-assert-us = <10000>;
+		reset-deassert-us = <80000>;
+		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+		interrupt-parent = <&gpio_intc>;
+		/* MAC_INTR on GPIOZ_14 */
+		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
+
+&uart_A {
+	status = "okay";
+
+	pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+	pinctrl-names = "default";
+	uart-has-rtscts;
+
+	bluetooth {
+		compatible = "brcm,bcm43438-bt";
+		shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+		max-speed = <2000000>;
+		clocks = <&wifi32k>;
+		clock-names = "lpo";
+	};
+};
-- 
2.17.1



From jagan at amarulasolutions.com  Tue Jan 11 23:24:38 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Wed, 12 Jan 2022 12:54:38 +0530
Subject: [PATCH 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <20200907081825.1654-7-narmstrong@baylibre.com>
References: <20200907081825.1654-1-narmstrong@baylibre.com>
 <20200907081825.1654-7-narmstrong@baylibre.com>
Message-ID: <CAMty3ZBEmafG8LS_yv4eektvUoHwYFoV=-8wohUXgsvpRbZqtA@mail.gmail.com>

Hi Neil,

On Mon, Sep 7, 2020 at 1:48 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> The Amlogic AXg SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a), with a custom
> glue managing the IP resets, clock and data input similar to the DW-HDMI Glue on other
> Amlogic SoCs.
>
> This adds support for the Glue managing the transceiver, mimicing the init flow provided
> by Amlogic to setup the ENCl encoder, the glue, the transceiver, the digital D-PHY and the
> Analog PHY in the proper way.
>
> The DW-MIPI-DSI transceiver + D-PHY are directly clocked by the VCLK2 clock, which pixel clock
> is derived and feeds the ENCL encoder and the VIU pixel reader.
>
> An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
> DW-MIPI-DSI transceiver.
>
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> ---
>  drivers/gpu/drm/meson/Kconfig             |   7 +
>  drivers/gpu/drm/meson/Makefile            |   1 +
>  drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 562 ++++++++++++++++++++++
>  3 files changed, 570 insertions(+)
>  create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
>
> diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
> index 9f9281dd49f8..385f6f23839b 100644
> --- a/drivers/gpu/drm/meson/Kconfig
> +++ b/drivers/gpu/drm/meson/Kconfig
> @@ -16,3 +16,10 @@ config DRM_MESON_DW_HDMI
>         default y if DRM_MESON
>         select DRM_DW_HDMI
>         imply DRM_DW_HDMI_I2S_AUDIO
> +
> +config DRM_MESON_DW_MIPI_DSI
> +       tristate "MIPI DSI Synopsys Controller support for Amlogic Meson Display"
> +       depends on DRM_MESON
> +       default y if DRM_MESON
> +       select DRM_DW_MIPI_DSI
> +       select GENERIC_PHY_MIPI_DPHY
> diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
> index 28a519cdf66b..2cc870e91182 100644
> --- a/drivers/gpu/drm/meson/Makefile
> +++ b/drivers/gpu/drm/meson/Makefile
> @@ -5,3 +5,4 @@ meson-drm-y += meson_rdma.o meson_osd_afbcd.o
>
>  obj-$(CONFIG_DRM_MESON) += meson-drm.o
>  obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
> +obj-$(CONFIG_DRM_MESON_DW_MIPI_DSI) += meson_dw_mipi_dsi.o
> diff --git a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
> new file mode 100644
> index 000000000000..bbe1294fce7c
> --- /dev/null
> +++ b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
> @@ -0,0 +1,562 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2016 BayLibre, SAS
> + * Author: Neil Armstrong <narmstrong at baylibre.com>
> + * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/component.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/of_graph.h>
> +#include <linux/reset.h>
> +#include <linux/phy/phy.h>
> +
> +#include <video/mipi_display.h>
> +
> +#include <drm/bridge/dw_mipi_dsi.h>
> +#include <drm/drm_mipi_dsi.h>
> +
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_device.h>
> +#include <drm/drm_probe_helper.h>
> +#include <drm/drm_print.h>
> +
> +#include "meson_drv.h"
> +#include "meson_dw_mipi_dsi.h"
> +#include "meson_registers.h"
> +#include "meson_venc.h"
> +
> +#define DRIVER_NAME "meson-dw-mipi-dsi"
> +#define DRIVER_DESC "Amlogic Meson MIPI-DSI DRM driver"
> +
> +/*  MIPI DSI/VENC Color Format Definitions */
> +#define MIPI_DSI_VENC_COLOR_30B   0x0
> +#define MIPI_DSI_VENC_COLOR_24B   0x1
> +#define MIPI_DSI_VENC_COLOR_18B   0x2
> +#define MIPI_DSI_VENC_COLOR_16B   0x3
> +
> +#define COLOR_16BIT_CFG_1         0x0
> +#define COLOR_16BIT_CFG_2         0x1
> +#define COLOR_16BIT_CFG_3         0x2
> +#define COLOR_18BIT_CFG_1         0x3
> +#define COLOR_18BIT_CFG_2         0x4
> +#define COLOR_24BIT               0x5
> +#define COLOR_20BIT_LOOSE         0x6
> +#define COLOR_24_BIT_YCBCR        0x7
> +#define COLOR_16BIT_YCBCR         0x8
> +#define COLOR_30BIT               0x9
> +#define COLOR_36BIT               0xa
> +#define COLOR_12BIT               0xb
> +#define COLOR_RGB_111             0xc
> +#define COLOR_RGB_332             0xd
> +#define COLOR_RGB_444             0xe
> +
> +/*  MIPI DSI Relative REGISTERs Definitions */
> +/* For MIPI_DSI_TOP_CNTL */
> +#define BIT_DPI_COLOR_MODE        20
> +#define BIT_IN_COLOR_MODE         16
> +#define BIT_CHROMA_SUBSAMPLE      14
> +#define BIT_COMP2_SEL             12
> +#define BIT_COMP1_SEL             10
> +#define BIT_COMP0_SEL              8
> +#define BIT_DE_POL                 6
> +#define BIT_HSYNC_POL              5
> +#define BIT_VSYNC_POL              4
> +#define BIT_DPICOLORM              3
> +#define BIT_DPISHUTDN              2
> +#define BIT_EDPITE_INTR_PULSE      1
> +#define BIT_ERR_INTR_PULSE         0
> +
> +/* HHI Registers */
> +#define HHI_VIID_CLK_DIV       0x128 /* 0x4a offset in data sheet */
> +#define VCLK2_DIV_MASK         0xff
> +#define VCLK2_DIV_EN           BIT(16)
> +#define VCLK2_DIV_RESET                BIT(17)
> +#define CTS_ENCL_SEL_MASK      (0xf << 12)
> +#define CTS_ENCL_SEL_SHIFT     12
> +#define HHI_VIID_CLK_CNTL      0x12c /* 0x4b offset in data sheet */
> +#define VCLK2_EN               BIT(19)
> +#define VCLK2_SEL_MASK         (0x7 << 16)
> +#define VCLK2_SEL_SHIFT                16
> +#define VCLK2_SOFT_RESET       BIT(15)
> +#define VCLK2_DIV1_EN          BIT(0)
> +#define HHI_VID_CLK_CNTL2      0x194 /* 0x65 offset in data sheet */
> +#define CTS_ENCL_EN            BIT(3)
> +
> +/**
> + * DOC: MIPI DSI
> + *
> + */
> +
> +struct meson_dw_mipi_dsi {
> +       struct drm_encoder encoder;
> +       struct meson_drm *priv;
> +       struct device *dev;
> +       void __iomem *base;
> +       struct phy *phy;
> +       union phy_configure_opts phy_opts;
> +       struct dw_mipi_dsi *dmd;
> +       struct dw_mipi_dsi_plat_data pdata;
> +       struct mipi_dsi_device *dsi_device;
> +       unsigned long mode_flags;
> +       struct clk *px_clk;
> +};
> +#define encoder_to_meson_dw_mipi_dsi(x) \
> +       container_of(x, struct meson_dw_mipi_dsi, encoder)
> +
> +static void dw_mipi_dsi_set_vclk(struct meson_dw_mipi_dsi *mipi_dsi,
> +                                struct drm_display_mode *mode)
> +{
> +       struct meson_drm *priv = mipi_dsi->priv;
> +       unsigned int vclk2_div;
> +       unsigned int pll_rate;
> +       int ret;
> +
> +       pll_rate = mipi_dsi->phy_opts.mipi_dphy.hs_clk_rate;
> +       vclk2_div = pll_rate / (mode->clock * 1000);
> +
> +       ret = clk_set_rate(mipi_dsi->px_clk, pll_rate);
> +       if (ret) {
> +               pr_err("Failed to set DSI PLL rate %lu\n",
> +                      mipi_dsi->phy_opts.mipi_dphy.hs_clk_rate);
> +
> +               return;
> +       }
> +
> +       /* Disable VCLK2 */
> +       regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, 0);
> +
> +       /* Setup the VCLK2 divider value */
> +       regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
> +                               VCLK2_DIV_MASK, (vclk2_div - 1));
> +
> +       /* select gp0 for vclk2 */
> +       regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
> +                               VCLK2_SEL_MASK, (0 << VCLK2_SEL_SHIFT));
> +
> +       /* enable vclk2 gate */
> +       regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN);
> +
> +       /* select vclk2_div1 for encl */
> +       regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
> +                               CTS_ENCL_SEL_MASK, (8 << CTS_ENCL_SEL_SHIFT));
> +
> +       /* release vclk2_div_reset and enable vclk2_div */
> +       regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
> +                               VCLK2_DIV_EN | VCLK2_DIV_RESET, VCLK2_DIV_EN);
> +
> +       /* enable vclk2_div1 gate */
> +       regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
> +                               VCLK2_DIV1_EN, VCLK2_DIV1_EN);
> +
> +       /* reset vclk2 */
> +       regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
> +                               VCLK2_SOFT_RESET, VCLK2_SOFT_RESET);
> +       regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
> +                               VCLK2_SOFT_RESET, 0);
> +
> +       /* enable encl_clk */
> +       regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
> +                               CTS_ENCL_EN, CTS_ENCL_EN);
> +
> +       usleep_range(10000, 11000);
> +}
> +
> +static int dw_mipi_dsi_phy_init(void *priv_data)
> +{
> +       struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
> +       struct meson_drm *priv = mipi_dsi->priv;
> +
> +
> +       phy_power_on(mipi_dsi->phy);
> +
> +       writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
> +
> +       return 0;
> +}
> +
> +static void dw_mipi_dsi_phy_power_off(void *priv_data)
> +{
> +       struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
> +
> +       phy_power_off(mipi_dsi->phy);
> +}
> +
> +static int
> +dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
> +                         unsigned long mode_flags, u32 lanes, u32 format,
> +                         unsigned int *lane_mbps)
> +{
> +       struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
> +
> +       *lane_mbps = mipi_dsi->phy_opts.mipi_dphy.hs_clk_rate / 1000000;
> +
> +       return 0;
> +}
> +
> +static int
> +dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
> +                          struct dw_mipi_dsi_dphy_timing *timing)
> +{
> +       /* TOFIX handle other cases */
> +
> +       timing->clk_lp2hs = 37;
> +       timing->clk_hs2lp = 135;
> +       timing->data_lp2hs = 50;
> +       timing->data_hs2lp = 3;
> +
> +       return 0;
> +}
> +
> +static int
> +dw_mipi_dsi_get_esc_clk_rate(void *priv_data, unsigned int *esc_clk_rate)
> +{
> +       *esc_clk_rate = 4; /* Mhz */
> +
> +       return 0;
> +}
> +
> +static const struct dw_mipi_dsi_phy_ops meson_dw_mipi_dsi_phy_ops = {
> +       .init = dw_mipi_dsi_phy_init,
> +       .power_off = dw_mipi_dsi_phy_power_off,
> +       .get_lane_mbps = dw_mipi_dsi_get_lane_mbps,
> +       .get_timing = dw_mipi_dsi_phy_get_timing,
> +       .get_esc_clk_rate = dw_mipi_dsi_get_esc_clk_rate,
> +};
> +
> +/* Encoder */
> +
> +static void meson_mipi_dsi_encoder_destroy(struct drm_encoder *encoder)
> +{
> +       drm_encoder_cleanup(encoder);
> +}
> +
> +static const struct drm_encoder_funcs meson_mipi_dsi_encoder_funcs = {
> +       .destroy        = meson_mipi_dsi_encoder_destroy,
> +};
> +
> +static int meson_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
> +                                       struct drm_crtc_state *crtc_state,
> +                                       struct drm_connector_state *conn_state)
> +{
> +       struct meson_dw_mipi_dsi *mipi_dsi =
> +                       encoder_to_meson_dw_mipi_dsi(encoder);
> +
> +       switch (mipi_dsi->dsi_device->format) {
> +       case MIPI_DSI_FMT_RGB888:
> +               break;
> +       case MIPI_DSI_FMT_RGB666:
> +               break;
> +       case MIPI_DSI_FMT_RGB666_PACKED:
> +       case MIPI_DSI_FMT_RGB565:
> +       default:
> +               DRM_DEV_ERROR(mipi_dsi->dev,
> +                               "invalid pixel format %d\n",
> +                               mipi_dsi->dsi_device->format);
> +               return -EINVAL;
> +       };
> +
> +       return 0;
> +}
> +
> +static void meson_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
> +{
> +       struct meson_dw_mipi_dsi *mipi_dsi =
> +                       encoder_to_meson_dw_mipi_dsi(encoder);
> +       struct meson_drm *priv = mipi_dsi->priv;
> +
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
> +}
> +
> +static void meson_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
> +{
> +       struct meson_dw_mipi_dsi *mipi_dsi =
> +                       encoder_to_meson_dw_mipi_dsi(encoder);
> +       struct meson_drm *priv = mipi_dsi->priv;
> +
> +       writel_bits_relaxed(BIT(3), BIT(3),
> +                       priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_EN));
> +}
> +
> +static void meson_dw_mipi_dsi_init(struct meson_dw_mipi_dsi *mipi_dsi)
> +{
> +       writel_relaxed((1 << 4) | (1 << 5) | (0 << 6),
> +                       mipi_dsi->base + MIPI_DSI_TOP_CNTL);
> +
> +       writel_bits_relaxed(0xf, 0xf,
> +                           mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);
> +       writel_bits_relaxed(0xf, 0,
> +                           mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);
> +
> +       writel_bits_relaxed(0x3, 0x3,
> +                           mipi_dsi->base + MIPI_DSI_TOP_CLK_CNTL);
> +
> +       writel_relaxed(0, mipi_dsi->base + MIPI_DSI_TOP_MEM_PD);
> +}
> +
> +static void meson_mipi_dsi_encoder_mode_set(struct drm_encoder *encoder,
> +                                  struct drm_display_mode *mode,
> +                                  struct drm_display_mode *adjusted_mode)
> +{
> +       struct meson_dw_mipi_dsi *mipi_dsi = encoder_to_meson_dw_mipi_dsi(encoder);
> +       unsigned int dpi_data_format, venc_data_width;
> +       struct meson_drm *priv = mipi_dsi->priv;
> +       int bpp;
> +       u32 reg;
> +
> +       mipi_dsi->mode_flags = mode->flags;
> +
> +       bpp = mipi_dsi_pixel_format_to_bpp(mipi_dsi->dsi_device->format);
> +
> +       phy_mipi_dphy_get_default_config(mode->clock * 1000,
> +                                        bpp, mipi_dsi->dsi_device->lanes,
> +                                        &mipi_dsi->phy_opts.mipi_dphy);
> +
> +       phy_configure(mipi_dsi->phy, &mipi_dsi->phy_opts);
> +
> +       switch (mipi_dsi->dsi_device->format) {
> +       case MIPI_DSI_FMT_RGB888:
> +               dpi_data_format = COLOR_24BIT;
> +               venc_data_width = MIPI_DSI_VENC_COLOR_24B;
> +               break;
> +       case MIPI_DSI_FMT_RGB666:
> +               dpi_data_format = COLOR_18BIT_CFG_2;
> +               venc_data_width = MIPI_DSI_VENC_COLOR_18B;
> +               break;
> +       case MIPI_DSI_FMT_RGB666_PACKED:
> +       case MIPI_DSI_FMT_RGB565:
> +               /* invalid */
> +               break;
> +       };
> +
> +       dw_mipi_dsi_set_vclk(mipi_dsi, mode);
> +       meson_venc_mipi_dsi_mode_set(priv, mode);
> +
> +       meson_encl_load_gamma(priv);
> +
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
> +
> +       meson_dw_mipi_dsi_init(mipi_dsi);
> +
> +       /* Configure Set color format for DPI register */
> +       reg = readl_relaxed(mipi_dsi->base + MIPI_DSI_TOP_CNTL) &
> +               ~(0xf<<BIT_DPI_COLOR_MODE) &
> +               ~(0x7<<BIT_IN_COLOR_MODE) &
> +               ~(0x3<<BIT_CHROMA_SUBSAMPLE);
> +
> +       writel_relaxed(reg |
> +               (dpi_data_format  << BIT_DPI_COLOR_MODE)  |
> +               (venc_data_width  << BIT_IN_COLOR_MODE) |
> +               0 << BIT_COMP0_SEL |
> +               1 << BIT_COMP1_SEL |
> +               2 << BIT_COMP2_SEL |
> +               (mipi_dsi->mode_flags & DRM_MODE_FLAG_NHSYNC ? 0 : BIT(BIT_HSYNC_POL)) |
> +               (mipi_dsi->mode_flags & DRM_MODE_FLAG_NVSYNC ? 0 : BIT(BIT_VSYNC_POL)),
> +               mipi_dsi->base + MIPI_DSI_TOP_CNTL);
> +}
> +
> +static const struct drm_encoder_helper_funcs
> +                               meson_mipi_dsi_encoder_helper_funcs = {
> +       .atomic_check   = meson_mipi_dsi_encoder_atomic_check,
> +       .disable        = meson_mipi_dsi_encoder_disable,
> +       .enable         = meson_mipi_dsi_encoder_enable,
> +       .mode_set       = meson_mipi_dsi_encoder_mode_set,
> +};
> +
> +static int meson_dw_mipi_dsi_bind(struct device *dev, struct device *master,
> +                               void *data)
> +{
> +       struct meson_dw_mipi_dsi *mipi_dsi = dev_get_drvdata(dev);
> +       struct drm_device *drm = data;
> +       struct meson_drm *priv = drm->dev_private;
> +       struct drm_encoder *encoder;
> +       int ret;
> +
> +       /* Check before if we are supposed to have a sub-device... */
> +       if (!mipi_dsi->dsi_device)
> +               return -EPROBE_DEFER;
> +
> +       encoder = &mipi_dsi->encoder;
> +       mipi_dsi->priv = priv;
> +
> +       /* Encoder */
> +       ret = drm_encoder_init(drm, encoder, &meson_mipi_dsi_encoder_funcs,
> +                              DRM_MODE_ENCODER_DSI, "meson_mipi_dsi");
> +       if (ret) {
> +               dev_err(priv->dev, "Failed to init DSI encoder\n");
> +               return ret;
> +       }
> +
> +       drm_encoder_helper_add(encoder, &meson_mipi_dsi_encoder_helper_funcs);
> +
> +       encoder->possible_crtcs = BIT(0);
> +
> +       ret = dw_mipi_dsi_bind(mipi_dsi->dmd, encoder);
> +       if (ret) {
> +               DRM_DEV_ERROR(dev, "Failed to bind: %d\n", ret);
> +               return ret;
> +       }
> +
> +       phy_init(mipi_dsi->phy);
> +
> +       return 0;
> +}
> +
> +static void meson_dw_mipi_dsi_unbind(struct device *dev, struct device *master,
> +                                  void *data)
> +{
> +       struct meson_dw_mipi_dsi *mipi_dsi = dev_get_drvdata(dev);
> +
> +       dw_mipi_dsi_remove(mipi_dsi->dmd);
> +
> +       phy_exit(mipi_dsi->phy);
> +}
> +
> +static const struct component_ops meson_dw_mipi_dsi_ops = {
> +       .bind   = meson_dw_mipi_dsi_bind,
> +       .unbind = meson_dw_mipi_dsi_unbind,
> +};

Do you thought of non-component based meson DSI like STM DSI? It
require changes from meson drm but just to understand if you have any
such plan.

Thanks,
Jagan.


From narmstrong at baylibre.com  Wed Jan 12 00:19:35 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:19:35 +0100
Subject: [PATCH 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <CAMty3ZBEmafG8LS_yv4eektvUoHwYFoV=-8wohUXgsvpRbZqtA@mail.gmail.com>
References: <20200907081825.1654-1-narmstrong@baylibre.com>
 <20200907081825.1654-7-narmstrong@baylibre.com>
 <CAMty3ZBEmafG8LS_yv4eektvUoHwYFoV=-8wohUXgsvpRbZqtA@mail.gmail.com>
Message-ID: <70d1af3f-bc00-4afd-1157-1cf70d3b2c88@baylibre.com>

Hi,

On 12/01/2022 08:24, Jagan Teki wrote:
> Hi Neil,
> 
> On Mon, Sep 7, 2020 at 1:48 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>>
>> The Amlogic AXg SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a), with a custom
>> glue managing the IP resets, clock and data input similar to the DW-HDMI Glue on other
>> Amlogic SoCs.
>>
>> This adds support for the Glue managing the transceiver, mimicing the init flow provided
>> by Amlogic to setup the ENCl encoder, the glue, the transceiver, the digital D-PHY and the
>> Analog PHY in the proper way.
>>
>> The DW-MIPI-DSI transceiver + D-PHY are directly clocked by the VCLK2 clock, which pixel clock
>> is derived and feeds the ENCL encoder and the VIU pixel reader.
>>
>> An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
>> DW-MIPI-DSI transceiver.
>>
>> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
>> ---

[..]

>> +
>> +static const struct component_ops meson_dw_mipi_dsi_ops = {
>> +       .bind   = meson_dw_mipi_dsi_bind,
>> +       .unbind = meson_dw_mipi_dsi_unbind,
>> +};
> 
> Do you thought of non-component based meson DSI like STM DSI? It
> require changes from meson drm but just to understand if you have any
> such plan.

I have no such plans for now, note this serie has been rewritten at [1] but still
with based with components.

If worth it, the plan is to get it with components and than yes if it's simpler
drop components completely.

I'll have a look at how ST does

Neil

[1] https://lore.kernel.org/r/20220107145515.613009-1-narmstrong at baylibre.com

> 
> Thanks,
> Jagan.
> 



From narmstrong at baylibre.com  Wed Jan 12 00:28:23 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:28:23 +0100
Subject: [PATCH] arm64: dts: meson-sm1: add spdifin spdifout nodes
In-Reply-To: <20211215030236.340841-1-art@khadas.com>
References: <20211215030236.340841-1-art@khadas.com>
Message-ID: <164197609473.825600.7789792176979118539.b4-ty@baylibre.com>

Hi,

On Wed, 15 Dec 2021 11:02:36 +0800, Artem Lapkin wrote:
> Add spdifin spdifout nodes for Amlogic SM1 SoCs.
> 
> 

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v5.18/dt64)

[1/1] arm64: dts: meson-sm1: add spdifin spdifout nodes
      https://git.kernel.org/amlogic/c/86f2159468d55aca1793c1f0f3d95213501b32f3

-- 
Neil


From narmstrong at baylibre.com  Wed Jan 12 00:28:22 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:28:22 +0100
Subject: [PATCH v3 0/9] arm64: dts: meson: add support for ac2xx devices
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <164197609474.825600.7106897196640617717.b4-ty@baylibre.com>

Hi,

On Wed, 12 Jan 2022 02:27:04 +0000, Christian Hewitt wrote:
> This series adds support for several popular Amlogic S905X3 (SM1) Android
> Set-Top Box devices. Like most Android box devices, they ship in variants
> with multiple RAM, eMMC, WiFi and BT configurations. RAM and eMMC are not
> something we need to consider to get a working boot, but we do need to get
> the correct connectivity spec. Broadly speaking we see boxes with Higher
> and Lower spec connectivity; High spec is Gigabit Ethernet and Faster dual
> antennna WiFi, and Lower spec is Megabit Ethernet and a single antenna. In
> some low-end boxes BT is omitted.
> 
> [...]

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v5.18/dt64)

[1/9] arm64: dts: meson: add common SM1 ac2xx dtsi
      https://git.kernel.org/amlogic/c/b5a03ecec30c1a71d51de3e73a2e7ab23c3ddeb6
[2/9] dt-bindings: arm: amlogic: add X96-AIR bindings
      https://git.kernel.org/amlogic/c/d2ecf5ae59c8eef9fe2ad20d83977c2889646d4c
[3/9] arm64: dts: meson: add initial device-trees for X96-AIR
      https://git.kernel.org/amlogic/c/37875d9dcb42d489ba28518b50fed0b2ba768b03
[4/9] dt-bindings: vendor-prefixes: add cyx prefix
      https://git.kernel.org/amlogic/c/3dbabb9ac746ab01c71aa019c58a2e0cc6eafe1c
[5/9] dt-bindings: arm: amlogic: add A95XF3-AIR bindings
      https://git.kernel.org/amlogic/c/bc7811bd4e884bbc21cc7b7031cb7c297662db9c
[6/9] arm64: dts: meson: add initial device-trees for A95XF3-AIR
      https://git.kernel.org/amlogic/c/8b749a0205bd41cafae37e878fd4a1b57b7b24f3
[7/9] dt-bindings: vendor-prefixes: add haochuangyi prefix
      https://git.kernel.org/amlogic/c/bf510ace20ac153946d6d0ab6305dd8aa52eec6c
[8/9] dt-bindings: arm: amlogic: add H96-Max bindings
      https://git.kernel.org/amlogic/c/2ca889b1201625d36efcd51d25371d937a6a0b8f
[9/9] arm64: dts: meson: add initial device-tree for H96-Max
      https://git.kernel.org/amlogic/c/ac7b4433714a37e2c4b61acc6ce9b4538175e836

-- 
Neil


From narmstrong at baylibre.com  Wed Jan 12 00:28:24 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:28:24 +0100
Subject: [PATCH V3] dt-bindings: arm: amlogic: add S4 based AQ222 bindings
In-Reply-To: <20211221030014.434-1-xianwei.zhao@amlogic.com>
References: <20211221030014.434-1-xianwei.zhao@amlogic.com>
Message-ID: <164197609473.825600.4070247492095618792.b4-ty@baylibre.com>

Hi,

On Tue, 21 Dec 2021 11:00:14 +0800, Xianwei Zhao wrote:
> Add bindings for the new Amlogic S4 SoC family,
> and add binds the compatible for the Amlogic S4 Based AQ222 board.
> 
> S4 is an application processor designed for hybrid OTT/IP Set To
> Box(STB) and high-end media box applications, with quad core Cortex-A35.
> 
> 
> [...]

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v5.18/dt64)

[1/1] dt-bindings: arm: amlogic: add S4 based AQ222 bindings
      https://git.kernel.org/amlogic/c/fc32ca1ea6f74c1be7abf9d21b0bac8bce11bec3

-- 
Neil


From narmstrong at baylibre.com  Wed Jan 12 00:30:37 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:30:37 +0100
Subject: [PATCH 1/3] pinctrl: meson-g12a: add more pwm_f options
In-Reply-To: <20220103154616.308376-2-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220103154616.308376-2-gary.bisson@boundarydevices.com>
Message-ID: <cd92df54-caa1-deed-3a93-929ba43adba8@baylibre.com>

On 03/01/2022 16:46, Gary Bisson wrote:
> Add missing PWM_F pin muxing for GPIOA_11 and GPIOZ_12.
> 
> Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
> ---
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: linux-gpio at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> ---
>  drivers/pinctrl/meson/pinctrl-meson-g12a.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pinctrl/meson/pinctrl-meson-g12a.c b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
> index cd9656b13836..d182a575981e 100644
> --- a/drivers/pinctrl/meson/pinctrl-meson-g12a.c
> +++ b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
> @@ -283,6 +283,8 @@ static const unsigned int pwm_d_x6_pins[]		= { GPIOX_6 };
>  static const unsigned int pwm_e_pins[]			= { GPIOX_16 };
>  
>  /* pwm_f */
> +static const unsigned int pwm_f_z_pins[]		= { GPIOZ_12 };
> +static const unsigned int pwm_f_a_pins[]		= { GPIOA_11 };
>  static const unsigned int pwm_f_x_pins[]		= { GPIOX_7 };
>  static const unsigned int pwm_f_h_pins[]		= { GPIOH_5 };
>  
> @@ -618,6 +620,7 @@ static struct meson_pmx_group meson_g12a_periphs_groups[] = {
>  	GROUP(tdm_c_dout2_z,		4),
>  	GROUP(tdm_c_dout3_z,		4),
>  	GROUP(mclk1_z,			4),
> +	GROUP(pwm_f_z,			5),
>  
>  	/* bank GPIOX */
>  	GROUP(sdio_d0,			1),
> @@ -768,6 +771,7 @@ static struct meson_pmx_group meson_g12a_periphs_groups[] = {
>  	GROUP(tdm_c_dout3_a,		2),
>  	GROUP(mclk0_a,			1),
>  	GROUP(mclk1_a,			2),
> +	GROUP(pwm_f_a,			3),
>  };
>  
>  /* uart_ao_a */
> @@ -1069,7 +1073,7 @@ static const char * const pwm_e_groups[] = {
>  };
>  
>  static const char * const pwm_f_groups[] = {
> -	"pwm_f_x", "pwm_f_h",
> +	"pwm_f_z", "pwm_f_a", "pwm_f_x", "pwm_f_h",
>  };
>  
>  static const char * const cec_ao_a_h_groups[] = {
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From narmstrong at baylibre.com  Wed Jan 12 00:30:54 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:30:54 +0100
Subject: [PATCH 2/3] arm64: dts: meson-g12-common: add more pwm_f options
In-Reply-To: <20220103154616.308376-3-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220103154616.308376-3-gary.bisson@boundarydevices.com>
Message-ID: <a4282cb9-3ebd-0c95-7a47-522eb1bbb770@baylibre.com>

On 03/01/2022 16:46, Gary Bisson wrote:
> Add missing PWM_F pin muxing for GPIOA_11 and GPIOZ_12.
> 
> Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
> ---
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: devicetree at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> ---
>  .../arm64/boot/dts/amlogic/meson-g12-common.dtsi | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> index 00c6f53290d4..af1357c48bee 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> @@ -894,6 +894,22 @@ mux {
>  						};
>  					};
>  
> +					pwm_f_z_pins: pwm-f-z {
> +						mux {
> +							groups = "pwm_f_z";
> +							function = "pwm_f";
> +							bias-disable;
> +						};
> +					};
> +
> +					pwm_f_a_pins: pwm-f-a {
> +						mux {
> +							groups = "pwm_f_a";
> +							function = "pwm_f";
> +							bias-disable;
> +						};
> +					};
> +
>  					pwm_f_x_pins: pwm-f-x {
>  						mux {
>  							groups = "pwm_f_x";
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From narmstrong at baylibre.com  Wed Jan 12 00:33:42 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:33:42 +0100
Subject: [PATCH 3/3] arm64: dts: meson-g12-common: add uart_ao_b pins
 muxing
In-Reply-To: <20220103154616.308376-4-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220103154616.308376-4-gary.bisson@boundarydevices.com>
Message-ID: <fe58c139-f127-d102-a6a6-b8c2151aac20@baylibre.com>

Hi,

On 03/01/2022 16:46, Gary Bisson wrote:
> - RX/TX signals can be mapped on 2 different pairs of pins so supporting
>   both options
> - RTS/CTS signals however only have 1 option available
> 
> Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
> ---
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: devicetree at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> ---
>  .../boot/dts/amlogic/meson-g12-common.dtsi    | 27 +++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> index af1357c48bee..3a7773ffbd08 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> @@ -1952,6 +1952,33 @@ mux {
>  						};
>  					};
>  
> +					uart_ao_b_1_pins: uart-ao-b-1 {
> +						mux {
> +							groups = "uart_ao_b_tx_2",
> +								 "uart_ao_b_rx_3";
> +							function = "uart_ao_b";
> +							bias-disable;
> +						};
> +					};
> +
> +					uart_ao_b_2_pins: uart-ao-b-2 {
> +						mux {
> +							groups = "uart_ao_b_tx_8",
> +								 "uart_ao_b_rx_9";
> +							function = "uart_ao_b";
> +							bias-disable;
> +						};
> +					};

I'm not fan of these nodes namings.

Perhaps :
- uart-ao-b-2-3
- uart-ao-b-8-9

so the actual pins numbers used are more clear ?

> +
> +					uart_ao_b_cts_rts_pins: uart-ao-b-cts-rts {
> +						mux {
> +							groups = "uart_ao_b_cts",
> +								 "uart_ao_b_rts";
> +							function = "uart_ao_b";
> +							bias-disable;
> +						};
> +					};
> +
>  					pwm_a_e_pins: pwm-a-e {
>  						mux {
>  							groups = "pwm_a_e";
> 



From narmstrong at baylibre.com  Wed Jan 12 00:36:23 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:36:23 +0100
Subject: [PATCH V2 2/2] soc: s4: Add support for power domains controller
In-Reply-To: <CAFBinCALAOJz16=u7r8tLM6ditriq=-NOACS2HRLrWs5B_FkVA@mail.gmail.com>
References: <20211230094434.3053195-1-shunzhou.jiang@amlogic.com>
 <20211230094434.3053195-3-shunzhou.jiang@amlogic.com>
 <CAFBinCALAOJz16=u7r8tLM6ditriq=-NOACS2HRLrWs5B_FkVA@mail.gmail.com>
Message-ID: <b2a9b8f0-2b12-c49f-9609-21999b1fffc8@baylibre.com>

Hi Shunzhou,

On 30/12/2021 23:15, Martin Blumenstingl wrote:
> On Thu, Dec 30, 2021 at 10:44 AM Shunzhou.Jiang
> <shunzhou.jiang at amlogic.com> wrote:
>>
>> From: Shunzhou Jiang <shunzhou.jiang at amlogic.com>
>>
>> Add support s4 Power controller. In s4, power control
>> registers are in secure domain, and should be accessed by smc.
>>
>> Signed-off-by: Shunzhou Jiang <shunzhou.jiang at amlogic.com>
> Also here I don't have any datasheet to compare this with, so this gets my:
> Acked-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> 
> [...]
>> +       SEC_PD(S4_VPU_HDMI,     GENPD_FLAG_ALWAYS_ON),
>> +       SEC_PD(S4_USB_COMB,     GENPD_FLAG_ALWAYS_ON),
>> +       SEC_PD(S4_GE2D,         0),
>> +       SEC_PD(S4_ETH,          GENPD_FLAG_ALWAYS_ON),
> For the A1 SoC's UART entry we have the following comment which
> explains why we want to to be "always on":
>   UART should keep working in ATF after suspend and before resume
> 
> If for some reason you need to re-send this series then it would be
> great if you could add a comment above each entry with
> GENPD_FLAG_ALWAYS_ON.
> It will help others (like me) understand these SoCs better.

Can you resend with those comments added so I can apply the patches ?

Thanks,
Neil

> 
> 
> Best regards,
> Martin
> 



From narmstrong at baylibre.com  Wed Jan 12 00:39:35 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:39:35 +0100
Subject: [PATCH V4] arm64: dts: add support for S4 based Amlogic AQ222
In-Reply-To: <20220106112214.6987-1-xianwei.zhao@amlogic.com>
References: <20220106112214.6987-1-xianwei.zhao@amlogic.com>
Message-ID: <164197677138.826461.16430612345551126459.b4-ty@baylibre.com>

Hi,

On Thu, 6 Jan 2022 19:22:14 +0800, Xianwei Zhao wrote:
> Add basic support for the Amlogic S4 based Amlogic AQ222 board:
> which describe components as follows: CPU, GIC, IRQ, Timer, UART.
> It's capable of booting up into the serial console.
> 
> 

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v5.18/dt64)

[1/1] arm64: dts: add support for S4 based Amlogic AQ222
      https://git.kernel.org/amlogic/c/1c1475389af077a9636c22dcb8c9ef498b48fcfc

-- 
Neil


From narmstrong at baylibre.com  Wed Jan 12 00:57:10 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:57:10 +0100
Subject: [PATCH v3] media: meson: vdec: Fix a NULL pointer dereference in
 amvdec_add_ts()
In-Reply-To: <CA+Cm_xSOv5NnW5GXcKKGi8bQSvT45iH6=65YJk3EG6uW0c5_Vw@mail.gmail.com>
References: <20211214144613.35fec82a@coco.lan>
 <20211215033535.40422-1-zhou1615@umn.edu>
 <368bc1b7-ff86-beaa-6749-afbe5960eaeb@xs4all.nl>
 <CA+Cm_xSOv5NnW5GXcKKGi8bQSvT45iH6=65YJk3EG6uW0c5_Vw@mail.gmail.com>
Message-ID: <7e9f1b17-7087-3513-84b9-f5dd25211b87@baylibre.com>

Hi,

On 11/01/2022 14:03, Qingyang Zhou wrote:
> Hi Hans:
> 
> Here I certify that this is an origin patch I wrote. I did not copy Neil's patch, and I did not know his patch.
> 
> Neil, please post your original patch here, so everyone can see both patches.
> 
> Yours?
> Zhou Qingyang.
> 
> On Tue, Jan 11, 2022 at 5:16 PM Hans Verkuil <hverkuil-cisco at xs4all.nl <mailto:hverkuil-cisco at xs4all.nl>> wrote:
> 
>     Zhou Qingyang, this is exactly the patch Neil wrote, except you just stuck your
>     name on it. Not nice.
> 
>     Neil, can you post your patch with your own Signed-off-by, then I'll take that one.
> 
>     Regards,
> 
>     ? ? ? ? Hans
> 
>     On 15/12/2021 04:35, Zhou Qingyang wrote:
>     > In amvdec_add_ts(), there is a dereference of kzalloc(), which could lead
>     > to a NULL pointer dereference on failure of kzalloc().
>     >
>     > Fix this bug by adding a NULL check of new_ts.
>     >
>     > This bug was found by a static analyzer[1].
>     >
>     > Builds with CONFIG_VIDEO_MESON_VDEC=m show no new warnings,
>     > and our static analyzer no longer warns about this code.
>     >
>     > Fixes: 876f123b8956 ("media: meson: vdec: bring up to compliance")
>     > Signed-off-by: Zhou Qingyang <zhou1615 at umn.edu <mailto:zhou1615 at umn.edu>>
>     > ---
>     >
>     > [1] The analysis employs differential checking to identify inconsistent
>     > security operations (e.g., checks or kfrees) between two code paths and
>     > confirms that the inconsistent operations are not recovered in the
>     > current function or the callers, so they constitute bugs.
>     >
>     > Note that, as a bug found by static analysis, it can be a false
>     > positive or hard to trigger. Multiple researchers have cross-reviewed
>     > the bug.
>     >
>     > Changes in v3:
>     >? ?-? Change the description of patch
>     >? ?-? Turn the return type from 'void' to 'int'
>     >? ?-? Check the return value in the caller 'esparser_queue()'
>     >
>     > Changes in v2:
>     >? ?-? Delete dev_err() message
>     >
>     >? drivers/staging/media/meson/vdec/esparser.c? ? ?| 7 ++++++-
>     >? drivers/staging/media/meson/vdec/vdec_helpers.c | 8 ++++++--
>     >? drivers/staging/media/meson/vdec/vdec_helpers.h | 4 ++--
>     >? 3 files changed, 14 insertions(+), 5 deletions(-)
>     >
>     > diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
>     > index db7022707ff8..095100a50da8 100644
>     > --- a/drivers/staging/media/meson/vdec/esparser.c
>     > +++ b/drivers/staging/media/meson/vdec/esparser.c
>     > @@ -328,7 +328,12 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
>     >?
>     >? ? ? ?offset = esparser_get_offset(sess);
>     >?
>     > -? ? ?amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
>     > +? ? ?ret = amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
>     > +? ? ?if (!ret) {
>     > +? ? ? ? ? ? ?v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
>     > +? ? ? ? ? ? ?return ret;
>     > +? ? ?}
>     > +
>     >? ? ? ?dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X flags = %08X\n",
>     >? ? ? ? ? ? ? ?vb->timestamp, payload_size, offset, vbuf->flags);
>     >?
>     > diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c
>     > index b9125c295d1d..06fd66539797 100644
>     > --- a/drivers/staging/media/meson/vdec/vdec_helpers.c
>     > +++ b/drivers/staging/media/meson/vdec/vdec_helpers.c
>     > @@ -227,13 +227,16 @@ int amvdec_set_canvases(struct amvdec_session *sess,
>     >? }
>     >? EXPORT_SYMBOL_GPL(amvdec_set_canvases);
>     >?
>     > -void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
>     > -? ? ? ? ? ? ? ? struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
>     > +int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
>     > +? ? ? ? ? ? ? ?struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
>     >? {
>     >? ? ? ?struct amvdec_timestamp *new_ts;
>     >? ? ? ?unsigned long flags;
>     >?
>     >? ? ? ?new_ts = kzalloc(sizeof(*new_ts), GFP_KERNEL);
>     > +? ? ?if (!new_ts)
>     > +? ? ? ? ? ? ?return -ENOMEM;
>     > +
>     >? ? ? ?new_ts->ts = ts;
>     >? ? ? ?new_ts->tc = tc;
>     >? ? ? ?new_ts->offset = offset;
>     > @@ -242,6 +245,7 @@ void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
>     >? ? ? ?spin_lock_irqsave(&sess->ts_spinlock, flags);
>     >? ? ? ?list_add_tail(&new_ts->list, &sess->timestamps);
>     >? ? ? ?spin_unlock_irqrestore(&sess->ts_spinlock, flags);
>     > +? ? ?return 0;
>     >? }
>     >? EXPORT_SYMBOL_GPL(amvdec_add_ts);
>     >?
>     > diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.h b/drivers/staging/media/meson/vdec/vdec_helpers.h
>     > index 88137d15aa3a..4bf3e61d081b 100644
>     > --- a/drivers/staging/media/meson/vdec/vdec_helpers.h
>     > +++ b/drivers/staging/media/meson/vdec/vdec_helpers.h
>     > @@ -56,8 +56,8 @@ void amvdec_dst_buf_done_offset(struct amvdec_session *sess,
>     >? ?* @offset: offset in the VIFIFO where the associated packet was written
>     >? ?* @flags: the vb2_v4l2_buffer flags
>     >? ?*/
>     > -void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
>     > -? ? ? ? ? ? ? ? struct v4l2_timecode tc, u32 offset, u32 flags);
>     > +int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
>     > +? ? ? ? ? ? ? ?struct v4l2_timecode tc, u32 offset, u32 flags);
>     >? void amvdec_remove_ts(struct amvdec_session *sess, u64 ts);
>     >?
>     >? /**
> 

Let's inspect:

I posted a probable solution the 09/12/2021 in a reply to 20211209085840.2081024-1-jiasheng at iscas.ac.cn :

===================><=============================
diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
index db7022707ff8..df733eff9ac7 100644
--- a/drivers/staging/media/meson/vdec/esparser.c
+++ b/drivers/staging/media/meson/vdec/esparser.c
@@ -328,7 +328,11 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)

        offset = esparser_get_offset(sess);

-       amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
+       ret = amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
+       if (ret) {
+               v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+               return ret;
+       }
        dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X flags = %08X\n",
                vb->timestamp, payload_size, offset, vbuf->flags);

diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c
index b9125c295d1d..593b2ccbece2 100644
--- a/drivers/staging/media/meson/vdec/vdec_helpers.c
+++ b/drivers/staging/media/meson/vdec/vdec_helpers.c
@@ -227,13 +227,15 @@ int amvdec_set_canvases(struct amvdec_session *sess,
 }
 EXPORT_SYMBOL_GPL(amvdec_set_canvases);

-void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
-                  struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
+int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
+                 struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
 {
        struct amvdec_timestamp *new_ts;
        unsigned long flags;

        new_ts = kzalloc(sizeof(*new_ts), GFP_KERNEL);
+       if (!new_ts)
+               return -ENOMEM;
        new_ts->ts = ts;
        new_ts->tc = tc;
        new_ts->offset = offset;
diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.h b/drivers/staging/media/meson/vdec/vdec_helpers.h
index 88137d15aa3a..4bf3e61d081b 100644
--- a/drivers/staging/media/meson/vdec/vdec_helpers.h
+++ b/drivers/staging/media/meson/vdec/vdec_helpers.h
@@ -56,8 +56,8 @@ void amvdec_dst_buf_done_offset(struct amvdec_session *sess,
  * @offset: offset in the VIFIFO where the associated packet was written
  * @flags: the vb2_v4l2_buffer flags
  */
-void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
-                  struct v4l2_timecode tc, u32 offset, u32 flags);
+int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
+                 struct v4l2_timecode tc, u32 offset, u32 flags);
 void amvdec_remove_ts(struct amvdec_session *sess, u64 ts);
===================><=============================


Then the patches were sent:
- 20211210015620.2143555-1-jiasheng at iscas.ac.cn on 10/12/2021
- 20211215033535.40422-1-zhou1615 at umn.edu on 15/12/2021

They are extremely close but not similar, mostly indenting differs.

Both patches have the missing final "return 0" in amvdec_add_ts which is missing in my proposal.

But only 20211210015620.2143555-1-jiasheng at iscas.ac.cn has the correct "if (ret)" in esparser_queue().
Patch 20211215033535.40422-1-zhou1615 at umn.ed has a wrong "if (!ret)".

But when comparing, 20211215033535.40422-1-zhou1615 at umn.edu is an almost exact copy of my proposal, minus the fixes and the bogus return check.

To be honest, there is a limited way to fix this, it's probable 20211215033535.40422-1-zhou1615 at umn.edu was written independently from
my proposal since there is a bug return check, and 20211210015620.2143555-1-jiasheng at iscas.ac.cn was rewritten from my proposal.

Since 20211215033535.40422-1-zhou1615 at umn.ed has a bogus return check, it should be naked.

I'll only ask 20211210015620.2143555-1-jiasheng at iscas.ac.cn to be resent with a "Suggested-by" and indentation fixed like my proposal.

Neil



From narmstrong at baylibre.com  Wed Jan 12 00:57:51 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:57:51 +0100
Subject: [PATCH] arm64: dts: meson-sm1: add spdifin spdifout nodes
In-Reply-To: <1jtuekrfsf.fsf@starbuckisacylon.baylibre.com>
References: <20211215030236.340841-1-art@khadas.com>
 <1jtuekrfsf.fsf@starbuckisacylon.baylibre.com>
Message-ID: <b4b62e3d-dc43-a56c-06c5-78e6ee7f6303@baylibre.com>

On 03/01/2022 16:35, Jerome Brunet wrote:
> 
> On Wed 15 Dec 2021 at 11:02, Artem Lapkin <email2tema at gmail.com> wrote:
> 
>> Add spdifin spdifout nodes for Amlogic SM1 SoCs.
>              ^ add (same in the title)
> 
>>
>> Signed-off-by: Artem Lapkin <art at khadas.com>
>> ---
>>
>> SPDIF IN and SPDIF OUT both tested and works fine for VIM3L (meson-sm1)
>> same as for VIM3 (meson-g12)
>>
>> SPDIF in and SPDIF OUT both pins available via GPIO header (SPDIF_OUT PIN
>> 13 spdif_ao_out_pins and SPDIF_IN PIN 35 - same PWM_F spdif_in_h_pins)
>>
>> https://lore.kernel.org/linux-arm-kernel/1jtuhwvqxa.fsf at starbuckisacylon.baylibre.com/t/
>>
>> ALSA spdifin test example
>> =========================
>>
>> # arecord -fS16_LE -r48000 -c2 -Dplug:spdifin
>>
>> # cat .asoundrc
>> pcm.spdifin {
>> type iec958
>> slave {
>> pcm "hw:0,1"
>> format IEC958_SUBFRAME_LE
>> }
>> }
>>
>> DT sound card configs for testing
>> =================================
>>
>> &spdifout {
>>     pinctrl-0 = <&spdif_ao_out_pins>;
>>     pinctrl-names = "default";
>>     status = "okay";
>> };
>>
>> &spdifin {
>>     pinctrl-0 = <&spdif_in_h_pins>;
>>     pinctrl-names = "default";
>>     status = "okay";
>> };
>>
>> ...
>>     spdif_dit: audio-codec-1 {
>> 	#sound-dai-cells = <0>;
>> 	compatible = "linux,spdif-dit";
>> 	status = "okay";
>> 	sound-name-prefix = "DIT";
>>     };
>>
>>     spdif_dir: audio-codec-2 {
>> 	#sound-dai-cells = <0>;
>> 	compatible = "linux,spdif-dir";
>> 	status = "okay";
>> 	sound-name-prefix = "DIR";
>>     };
>> ...
>> 	audio-routing = ...
>> 		"TODDR_B IN 3", "SPDIFIN Capture",
>> 		"SPDIFOUT IN 0", "FRDDR_A OUT 3";
>>
>> ...
>> 	dai-link-10 {
>> 	    sound-dai = <&spdifout>;
>>
>> 	    codec-0 {
>> 		sound-dai = <&spdif_dit>;
>> 	    };
>> 	};
>>
>> 	/* spdif or toslink interface */
>> 	dai-link-11 {
>> 	    sound-dai = <&spdifin>;
>>
>> 	    codec-0 {
>> 		sound-dai = <&spdif_dir>;
>> 	    };
>> 	};
>> ...
>>
>> ---
>>  arch/arm64/boot/dts/amlogic/meson-sm1.dtsi | 27 ++++++++++++++++++++++
>>  1 file changed, 27 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
>> index 3d8b1f4f2001..1e0adf259d61 100644
>> --- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
>> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
>> @@ -356,6 +356,33 @@ tdmin_lb: audio-controller at 3c0 {
>>  			status = "disabled";
>>  		};
>>  
>> +		spdifin: audio-controller at 400 {
>> +			compatible = "amlogic,g12a-spdifin",
>> +			"amlogic,axg-spdifin";
>> +			reg = <0x0 0x400 0x0 0x30>;
>> +			#sound-dai-cells = <0>;
>> +			sound-name-prefix = "SPDIFIN";
>> +			interrupts = <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
>> +			clocks = <&clkc_audio AUD_CLKID_SPDIFIN>,
>> +			<&clkc_audio AUD_CLKID_SPDIFIN_CLK>;
>> +			clock-names = "pclk", "refclk";
>> +			resets = <&clkc_audio AUD_RESET_SPDIFIN>;
>> +			status = "disabled";
>> +		};
>> +
>> +		spdifout: audio-controller at 480 {
> 
> Node should still be named spdifout_a, even if the spdifout_b is not added yet
> 
>> +			compatible = "amlogic,g12a-spdifout",
>> +			"amlogic,axg-spdifout";
>> +			reg = <0x0 0x480 0x0 0x50>;
>> +			#sound-dai-cells = <0>;
>> +			sound-name-prefix = "SPDIFOUT";
> 
> Same here
> 
>> +			clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
>> +			<&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
>> +			clock-names = "pclk", "mclk";
>> +			resets = <&clkc_audio AUD_RESET_SPDIFOUT>;
>> +			status = "disabled";
>> +		};
>> +
>>  		tdmout_a: audio-controller at 500 {
>>  			compatible = "amlogic,sm1-tdmout";
>>  			reg = <0x0 0x500 0x0 0x40>;
> 

All these fixed while applying, no need to send a new version.

Neil


From gary.bisson at boundarydevices.com  Wed Jan 12 05:01:15 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Wed, 12 Jan 2022 14:01:15 +0100
Subject: [PATCH 3/3] arm64: dts: meson-g12-common: add uart_ao_b pins
 muxing
In-Reply-To: <fe58c139-f127-d102-a6a6-b8c2151aac20@baylibre.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220103154616.308376-4-gary.bisson@boundarydevices.com>
 <fe58c139-f127-d102-a6a6-b8c2151aac20@baylibre.com>
Message-ID: <Yd7RG80hhjZilGs7@p1g2>

Hi,

On Wed, Jan 12, 2022 at 09:33:42AM +0100, Neil Armstrong wrote:
> Hi,
> 
> On 03/01/2022 16:46, Gary Bisson wrote:
> > - RX/TX signals can be mapped on 2 different pairs of pins so supporting
> >   both options
> > - RTS/CTS signals however only have 1 option available
> > 
> > Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
> > ---
> > Cc: Rob Herring <robh+dt at kernel.org>
> > Cc: Neil Armstrong <narmstrong at baylibre.com>
> > Cc: Kevin Hilman <khilman at baylibre.com>
> > Cc: Jerome Brunet <jbrunet at baylibre.com>
> > Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> > Cc: devicetree at vger.kernel.org
> > Cc: linux-arm-kernel at lists.infradead.org
> > Cc: linux-kernel at vger.kernel.org
> > ---
> >  .../boot/dts/amlogic/meson-g12-common.dtsi    | 27 +++++++++++++++++++
> >  1 file changed, 27 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> > index af1357c48bee..3a7773ffbd08 100644
> > --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> > +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> > @@ -1952,6 +1952,33 @@ mux {
> >  						};
> >  					};
> >  
> > +					uart_ao_b_1_pins: uart-ao-b-1 {
> > +						mux {
> > +							groups = "uart_ao_b_tx_2",
> > +								 "uart_ao_b_rx_3";
> > +							function = "uart_ao_b";
> > +							bias-disable;
> > +						};
> > +					};
> > +
> > +					uart_ao_b_2_pins: uart-ao-b-2 {
> > +						mux {
> > +							groups = "uart_ao_b_tx_8",
> > +								 "uart_ao_b_rx_9";
> > +							function = "uart_ao_b";
> > +							bias-disable;
> > +						};
> > +					};
> 
> I'm not fan of these nodes namings.
> 
> Perhaps :
> - uart-ao-b-2-3
> - uart-ao-b-8-9
> 
> so the actual pins numbers used are more clear ?

Sure, I wasn't convinced by that naming either. I although thought
about:
- uart-ao-b
- uart-ao-b-alt

Let me know which one you prefer and I'll respin the patch.
Also let me know if I should re-send the entire series or just this
patch.

Regards,
Gary


From narmstrong at baylibre.com  Wed Jan 12 06:34:02 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 15:34:02 +0100
Subject: [PATCH 3/3] arm64: dts: meson-g12-common: add uart_ao_b pins
 muxing
In-Reply-To: <Yd7RG80hhjZilGs7@p1g2>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220103154616.308376-4-gary.bisson@boundarydevices.com>
 <fe58c139-f127-d102-a6a6-b8c2151aac20@baylibre.com> <Yd7RG80hhjZilGs7@p1g2>
Message-ID: <10696e08-80ca-7dcf-9766-60d0a2475c6e@baylibre.com>

On 12/01/2022 14:01, Gary Bisson wrote:
> Hi,
> 
> On Wed, Jan 12, 2022 at 09:33:42AM +0100, Neil Armstrong wrote:
>> Hi,
>>
>> On 03/01/2022 16:46, Gary Bisson wrote:
>>> - RX/TX signals can be mapped on 2 different pairs of pins so supporting
>>>   both options
>>> - RTS/CTS signals however only have 1 option available
>>>
>>> Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
>>> ---
>>> Cc: Rob Herring <robh+dt at kernel.org>
>>> Cc: Neil Armstrong <narmstrong at baylibre.com>
>>> Cc: Kevin Hilman <khilman at baylibre.com>
>>> Cc: Jerome Brunet <jbrunet at baylibre.com>
>>> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
>>> Cc: devicetree at vger.kernel.org
>>> Cc: linux-arm-kernel at lists.infradead.org
>>> Cc: linux-kernel at vger.kernel.org
>>> ---
>>>  .../boot/dts/amlogic/meson-g12-common.dtsi    | 27 +++++++++++++++++++
>>>  1 file changed, 27 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
>>> index af1357c48bee..3a7773ffbd08 100644
>>> --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
>>> +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
>>> @@ -1952,6 +1952,33 @@ mux {
>>>  						};
>>>  					};
>>>  
>>> +					uart_ao_b_1_pins: uart-ao-b-1 {
>>> +						mux {
>>> +							groups = "uart_ao_b_tx_2",
>>> +								 "uart_ao_b_rx_3";
>>> +							function = "uart_ao_b";
>>> +							bias-disable;
>>> +						};
>>> +					};
>>> +
>>> +					uart_ao_b_2_pins: uart-ao-b-2 {
>>> +						mux {
>>> +							groups = "uart_ao_b_tx_8",
>>> +								 "uart_ao_b_rx_9";
>>> +							function = "uart_ao_b";
>>> +							bias-disable;
>>> +						};
>>> +					};
>>
>> I'm not fan of these nodes namings.
>>
>> Perhaps :
>> - uart-ao-b-2-3
>> - uart-ao-b-8-9
>>
>> so the actual pins numbers used are more clear ?
> 
> Sure, I wasn't convinced by that naming either. I although thought
> about:
> - uart-ao-b
> - uart-ao-b-alt

Not sure about these because it means one is the default and the second
is an alternate one, and I'm not sure about that. If it's the case, then
this naming is ok.

> 
> Let me know which one you prefer and I'll respin the patch.
> Also let me know if I should re-send the entire series or just this
> patch.

I'm lazy, so the entire patchset please :-)

Thanks,
Neil

> 
> Regards,
> Gary
> 



From lkp at intel.com  Wed Jan 12 08:08:44 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 13 Jan 2022 00:08:44 +0800
Subject: [PATCH V4 3/5] tty: serial: meson: The UART baud rate
In-Reply-To: <20220110085604.18042-4-yu.tu@amlogic.com>
References: <20220110085604.18042-4-yu.tu@amlogic.com>
Message-ID: <202201130013.KVlPG5Gj-lkp@intel.com>

Hi Yu,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on tty/tty-testing]
[also build test ERROR on next-20220112]
[cannot apply to robh/for-next soc/for-next clk/clk-next v5.16]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Yu-Tu/the-UART-driver-compatible-with/20220110-170020
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
config: m68k-randconfig-m031-20220112 (https://download.01.org/0day-ci/archive/20220113/202201130013.KVlPG5Gj-lkp at intel.com/config)
compiler: m68k-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/6d55159e6626326d9001d4c8f20b914a69c2c40b
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Yu-Tu/the-UART-driver-compatible-with/20220110-170020
        git checkout 6d55159e6626326d9001d4c8f20b914a69c2c40b
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=m68k SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   m68k-linux-ld: arch/m68k/kernel/machine_kexec.o: in function `machine_kexec':
   machine_kexec.c:(.text+0x6a): undefined reference to `m68k_mmutype'
   m68k-linux-ld: machine_kexec.c:(.text+0x72): undefined reference to `m68k_cputype'
   m68k-linux-ld: arch/m68k/kernel/relocate_kernel.o:(.m68k_fixup+0x0): undefined reference to `M68K_FIXUP_MEMOFFSET'
   m68k-linux-ld: arch/m68k/kernel/relocate_kernel.o:(.m68k_fixup+0x8): undefined reference to `M68K_FIXUP_MEMOFFSET'
   m68k-linux-ld: arch/m68k/kernel/uboot.o: in function `process_uboot_commandline':
   uboot.c:(.init.text+0x32): undefined reference to `_init_sp'
   m68k-linux-ld: drivers/tty/serial/meson_uart.o: in function `meson_uart_probe_clocks':
   meson_uart.c:(.text+0x4de): undefined reference to `__clk_get_name'
>> m68k-linux-ld: meson_uart.c:(.text+0x53c): undefined reference to `__devm_clk_hw_register_divider'
>> m68k-linux-ld: meson_uart.c:(.text+0x5a8): undefined reference to `__devm_clk_hw_register_mux'
>> m68k-linux-ld: meson_uart.c:(.text+0x5c0): undefined reference to `clk_hw_get_rate'
>> m68k-linux-ld: meson_uart.c:(.text+0x5d2): undefined reference to `clk_hw_get_name'
   m68k-linux-ld: meson_uart.c:(.text+0x622): undefined reference to `__devm_clk_hw_register_divider'
>> m68k-linux-ld: meson_uart.c:(.text+0x63c): undefined reference to `clk_hw_get_clk'
>> m68k-linux-ld: meson_uart.c:(.text+0x666): undefined reference to `__clk_get_name'
>> m68k-linux-ld: meson_uart.c:(.text+0x6ae): undefined reference to `devm_clk_hw_register_fixed_factor'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Jan 12 12:05:24 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 13 Jan 2022 04:05:24 +0800
Subject: [PATCH V4 3/5] tty: serial: meson: The UART baud rate
In-Reply-To: <20220110085604.18042-4-yu.tu@amlogic.com>
References: <20220110085604.18042-4-yu.tu@amlogic.com>
Message-ID: <202201130331.dzluDr3h-lkp@intel.com>

Hi Yu,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on tty/tty-testing]
[also build test ERROR on next-20220112]
[cannot apply to robh/for-next soc/for-next clk/clk-next v5.16]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Yu-Tu/the-UART-driver-compatible-with/20220110-170020
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
config: powerpc-randconfig-s031-20220112 (https://download.01.org/0day-ci/archive/20220113/202201130331.dzluDr3h-lkp at intel.com/config)
compiler: powerpc-linux-gcc (GCC) 11.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-dirty
        # https://github.com/0day-ci/linux/commit/6d55159e6626326d9001d4c8f20b914a69c2c40b
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Yu-Tu/the-UART-driver-compatible-with/20220110-170020
        git checkout 6d55159e6626326d9001d4c8f20b914a69c2c40b
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=powerpc SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   powerpc-linux-ld: drivers/tty/serial/meson_uart.o: in function `meson_uart_probe_clocks':
   meson_uart.c:(.text+0x464): undefined reference to `__clk_get_name'
>> powerpc-linux-ld: meson_uart.c:(.text+0x4bc): undefined reference to `__devm_clk_hw_register_divider'
>> powerpc-linux-ld: meson_uart.c:(.text+0x4fc): undefined reference to `__clk_get_name'
>> powerpc-linux-ld: meson_uart.c:(.text+0x518): undefined reference to `devm_clk_hw_register_fixed_factor'
>> powerpc-linux-ld: meson_uart.c:(.text+0x5a8): undefined reference to `__devm_clk_hw_register_mux'
>> powerpc-linux-ld: meson_uart.c:(.text+0x5c0): undefined reference to `clk_hw_get_rate'
>> powerpc-linux-ld: meson_uart.c:(.text+0x5f8): undefined reference to `clk_hw_get_name'
   powerpc-linux-ld: meson_uart.c:(.text+0x640): undefined reference to `__devm_clk_hw_register_divider'
>> powerpc-linux-ld: meson_uart.c:(.text+0x65c): undefined reference to `clk_hw_get_clk'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From gary.bisson at boundarydevices.com  Wed Jan 12 13:16:39 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Wed, 12 Jan 2022 22:16:39 +0100
Subject: [PATCH v2 0/3] meson-g12: add pwm and uart pin muxing options
In-Reply-To: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
Message-ID: <20220112211642.2248901-1-gary.bisson@boundarydevices.com>

This series adds a few pin muxing options needed for our HW platform (to
be submitted soon).

1- pwm_f: adding missing both GPIOZ_12 & GPIOA_11 options
  -> tested GPIOA_11 as mipi display backlight
  -> order for this patch is not alphabetical but follows doc order (to
match current order)
2- uart_ao_b: adding both options for ao_b uart + its rts/cts pins
  -> tested on custom hw too

Changes v1->v2:
- rename uart_ao_b signals as suggested by Neil

Let me know if you have any questions.

Regards,
Gary

Gary Bisson (3):
  pinctrl: meson-g12a: add more pwm_f options
  arm64: dts: meson-g12-common: add more pwm_f options
  arm64: dts: meson-g12-common: add uart_ao_b pins muxing

 .../boot/dts/amlogic/meson-g12-common.dtsi    | 43 +++++++++++++++++++
 drivers/pinctrl/meson/pinctrl-meson-g12a.c    |  6 ++-
 2 files changed, 48 insertions(+), 1 deletion(-)

-- 
2.34.1



From gary.bisson at boundarydevices.com  Wed Jan 12 13:16:40 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Wed, 12 Jan 2022 22:16:40 +0100
Subject: [PATCH v2 1/3] pinctrl: meson-g12a: add more pwm_f options
In-Reply-To: <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
Message-ID: <20220112211642.2248901-2-gary.bisson@boundarydevices.com>

Add missing PWM_F pin muxing for GPIOA_11 and GPIOZ_12.

Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>
---
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: linux-gpio at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 drivers/pinctrl/meson/pinctrl-meson-g12a.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/meson/pinctrl-meson-g12a.c b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
index cd9656b13836..d182a575981e 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-g12a.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
@@ -283,6 +283,8 @@ static const unsigned int pwm_d_x6_pins[]		= { GPIOX_6 };
 static const unsigned int pwm_e_pins[]			= { GPIOX_16 };
 
 /* pwm_f */
+static const unsigned int pwm_f_z_pins[]		= { GPIOZ_12 };
+static const unsigned int pwm_f_a_pins[]		= { GPIOA_11 };
 static const unsigned int pwm_f_x_pins[]		= { GPIOX_7 };
 static const unsigned int pwm_f_h_pins[]		= { GPIOH_5 };
 
@@ -618,6 +620,7 @@ static struct meson_pmx_group meson_g12a_periphs_groups[] = {
 	GROUP(tdm_c_dout2_z,		4),
 	GROUP(tdm_c_dout3_z,		4),
 	GROUP(mclk1_z,			4),
+	GROUP(pwm_f_z,			5),
 
 	/* bank GPIOX */
 	GROUP(sdio_d0,			1),
@@ -768,6 +771,7 @@ static struct meson_pmx_group meson_g12a_periphs_groups[] = {
 	GROUP(tdm_c_dout3_a,		2),
 	GROUP(mclk0_a,			1),
 	GROUP(mclk1_a,			2),
+	GROUP(pwm_f_a,			3),
 };
 
 /* uart_ao_a */
@@ -1069,7 +1073,7 @@ static const char * const pwm_e_groups[] = {
 };
 
 static const char * const pwm_f_groups[] = {
-	"pwm_f_x", "pwm_f_h",
+	"pwm_f_z", "pwm_f_a", "pwm_f_x", "pwm_f_h",
 };
 
 static const char * const cec_ao_a_h_groups[] = {
-- 
2.34.1



From gary.bisson at boundarydevices.com  Wed Jan 12 13:16:41 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Wed, 12 Jan 2022 22:16:41 +0100
Subject: [PATCH v2 2/3] arm64: dts: meson-g12-common: add more pwm_f options
In-Reply-To: <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
Message-ID: <20220112211642.2248901-3-gary.bisson@boundarydevices.com>

Add missing PWM_F pin muxing for GPIOA_11 and GPIOZ_12.

Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>
---
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: devicetree at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 .../arm64/boot/dts/amlogic/meson-g12-common.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index 00c6f53290d4..af1357c48bee 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -894,6 +894,22 @@ mux {
 						};
 					};
 
+					pwm_f_z_pins: pwm-f-z {
+						mux {
+							groups = "pwm_f_z";
+							function = "pwm_f";
+							bias-disable;
+						};
+					};
+
+					pwm_f_a_pins: pwm-f-a {
+						mux {
+							groups = "pwm_f_a";
+							function = "pwm_f";
+							bias-disable;
+						};
+					};
+
 					pwm_f_x_pins: pwm-f-x {
 						mux {
 							groups = "pwm_f_x";
-- 
2.34.1



From gary.bisson at boundarydevices.com  Wed Jan 12 13:16:42 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Wed, 12 Jan 2022 22:16:42 +0100
Subject: [PATCH v2 3/3] arm64: dts: meson-g12-common: add uart_ao_b pins muxing
In-Reply-To: <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
Message-ID: <20220112211642.2248901-4-gary.bisson@boundarydevices.com>

- RX/TX signals can be mapped on 2 different pairs of pins so supporting
  both options
- RTS/CTS signals however only have 1 option available

Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
---
Changes v1->v2:
- renamed nodes as suggested by Neil

Cc: Rob Herring <robh+dt at kernel.org>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: devicetree at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 .../boot/dts/amlogic/meson-g12-common.dtsi    | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index af1357c48bee..62350c408e16 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -1952,6 +1952,33 @@ mux {
 						};
 					};
 
+					uart_ao_b_2_3_pins: uart-ao-b-2-3 {
+						mux {
+							groups = "uart_ao_b_tx_2",
+								 "uart_ao_b_rx_3";
+							function = "uart_ao_b";
+							bias-disable;
+						};
+					};
+
+					uart_ao_b_8_9_pins: uart-ao-b-8-9 {
+						mux {
+							groups = "uart_ao_b_tx_8",
+								 "uart_ao_b_rx_9";
+							function = "uart_ao_b";
+							bias-disable;
+						};
+					};
+
+					uart_ao_b_cts_rts_pins: uart-ao-b-cts-rts {
+						mux {
+							groups = "uart_ao_b_cts",
+								 "uart_ao_b_rts";
+							function = "uart_ao_b";
+							bias-disable;
+						};
+					};
+
 					pwm_a_e_pins: pwm-a-e {
 						mux {
 							groups = "pwm_a_e";
-- 
2.34.1



From qianggui.song at amlogic.com  Wed Jan 12 19:10:40 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Thu, 13 Jan 2022 11:10:40 +0800
Subject: [PATCH v4 0/3] pinctrl: meson-s4: add pinctrl driver
Message-ID: <20220113031044.2665-1-qianggui.song@amlogic.com>

This patchset adds Pin controller driver support for Meson-S4 SoC
which shares the same register layout with previous Meson-A1

Changes since v3 at [2]:
- collect Martin's Acked-by and Reviewed-by
- remove useless empty line

Changes since v2 at [1]:
- add dt-bindings header file patch back with Rob's Acked-by

Changes since v1 at [0]:
- fix typos in commit message
- fix coding style problem in pinctrl-meson-s4.c
- change tdm groups makeup and split mclk groups

[0] https://lore.kernel.org/linux-amlogic/20211214022100.14841-1-qianggui.song at amlogic.com/
[1] https://lore.kernel.org/linux-amlogic/20211227080649.32275-1-qianggui.song at amlogic.com/
[2] https://lore.kernel.org/linux-amlogic/20211229121605.10513-1-qianggui.song at amlogic.com

Qianggui Song (3):
  dt-bindings: pinctrl: meson: Add compatible for S4
  dt-bindings: gpio: Add a header file for Amlogic Meson S4
  pinctrl: meson: add pinctrl driver support for Meson-S4 Soc

 .../bindings/pinctrl/meson,pinctrl.txt        |    1 +
 drivers/pinctrl/meson/Kconfig                 |    6 +
 drivers/pinctrl/meson/Makefile                |    1 +
 drivers/pinctrl/meson/pinctrl-meson-s4.c      | 1232 +++++++++++++++++
 include/dt-bindings/gpio/meson-s4-gpio.h      |   99 ++
 5 files changed, 1339 insertions(+)
 create mode 100644 drivers/pinctrl/meson/pinctrl-meson-s4.c
 create mode 100644 include/dt-bindings/gpio/meson-s4-gpio.h

-- 
2.34.1



From qianggui.song at amlogic.com  Wed Jan 12 19:10:41 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Thu, 13 Jan 2022 11:10:41 +0800
Subject: [PATCH v4 1/3] dt-bindings: pinctrl: meson: Add compatible for S4
In-Reply-To: <20220113031044.2665-1-qianggui.song@amlogic.com>
References: <20220113031044.2665-1-qianggui.song@amlogic.com>
Message-ID: <20220113031044.2665-2-qianggui.song@amlogic.com>

Add new compatible for Amlogic's Meson-S4 pin controller

Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
index 0aff1f28495c..8146193bd8ac 100644
--- a/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
@@ -16,6 +16,7 @@ Required properties for the root node:
 		      "amlogic,meson-g12a-periphs-pinctrl"
 		      "amlogic,meson-g12a-aobus-pinctrl"
 		      "amlogic,meson-a1-periphs-pinctrl"
+		      "amlogic,meson-s4-periphs-pinctrl"
  - reg: address and size of registers controlling irq functionality
 
 === GPIO sub-nodes ===
-- 
2.34.1



From qianggui.song at amlogic.com  Wed Jan 12 19:10:42 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Thu, 13 Jan 2022 11:10:42 +0800
Subject: [PATCH v4 2/3] dt-bindings: gpio: Add a header file for Amlogic Meson
 S4
In-Reply-To: <20220113031044.2665-1-qianggui.song@amlogic.com>
References: <20220113031044.2665-1-qianggui.song@amlogic.com>
Message-ID: <20220113031044.2665-3-qianggui.song@amlogic.com>

Add a new dt-binding header file which documents the detail pin names.

Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Acked-by: Rob Herring <robh at kernel.org>
Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 include/dt-bindings/gpio/meson-s4-gpio.h | 99 ++++++++++++++++++++++++
 1 file changed, 99 insertions(+)
 create mode 100644 include/dt-bindings/gpio/meson-s4-gpio.h

diff --git a/include/dt-bindings/gpio/meson-s4-gpio.h b/include/dt-bindings/gpio/meson-s4-gpio.h
new file mode 100644
index 000000000000..35aee21b94f1
--- /dev/null
+++ b/include/dt-bindings/gpio/meson-s4-gpio.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
+ * Author: Qianggui Song <qianggui.song at amlogic.com>
+ */
+
+#ifndef _DT_BINDINGS_MESON_S4_GPIO_H
+#define _DT_BINDINGS_MESON_S4_GPIO_H
+
+#define	GPIOB_0		0
+#define	GPIOB_1		1
+#define	GPIOB_2		2
+#define	GPIOB_3		3
+#define	GPIOB_4		4
+#define	GPIOB_5		5
+#define	GPIOB_6		6
+#define	GPIOB_7		7
+#define	GPIOB_8		8
+#define	GPIOB_9		9
+#define	GPIOB_10	10
+#define	GPIOB_11	11
+#define	GPIOB_12	12
+#define	GPIOB_13	13
+
+#define	GPIOC_0		14
+#define	GPIOC_1		15
+#define	GPIOC_2		16
+#define	GPIOC_3		17
+#define	GPIOC_4		18
+#define	GPIOC_5		19
+#define	GPIOC_6		20
+#define	GPIOC_7		21
+
+#define	GPIOE_0		22
+#define	GPIOE_1		23
+
+#define	GPIOD_0		24
+#define	GPIOD_1		25
+#define	GPIOD_2		26
+#define	GPIOD_3		27
+#define	GPIOD_4		28
+#define	GPIOD_5		29
+#define	GPIOD_6		30
+#define	GPIOD_7		31
+#define	GPIOD_8		32
+#define	GPIOD_9		33
+#define	GPIOD_10	34
+#define	GPIOD_11	35
+
+#define	GPIOH_0		36
+#define	GPIOH_1		37
+#define	GPIOH_2		38
+#define	GPIOH_3		39
+#define	GPIOH_4		40
+#define	GPIOH_5		41
+#define	GPIOH_6		42
+#define	GPIOH_7		43
+#define	GPIOH_8		44
+#define	GPIOH_9		45
+#define	GPIOH_10	46
+#define	GPIOH_11	47
+
+#define	GPIOX_0		48
+#define	GPIOX_1		49
+#define	GPIOX_2		50
+#define	GPIOX_3		51
+#define	GPIOX_4		52
+#define	GPIOX_5		53
+#define	GPIOX_6		54
+#define	GPIOX_7		55
+#define	GPIOX_8		56
+#define	GPIOX_9		57
+#define	GPIOX_10	58
+#define	GPIOX_11	59
+#define	GPIOX_12	60
+#define	GPIOX_13	61
+#define	GPIOX_14	62
+#define	GPIOX_15	63
+#define	GPIOX_16	64
+#define	GPIOX_17	65
+#define	GPIOX_18	66
+#define	GPIOX_19	67
+
+#define	GPIOZ_0		68
+#define	GPIOZ_1		69
+#define	GPIOZ_2		70
+#define	GPIOZ_3		71
+#define	GPIOZ_4		72
+#define	GPIOZ_5		73
+#define	GPIOZ_6		74
+#define	GPIOZ_7		75
+#define	GPIOZ_8		76
+#define	GPIOZ_9		77
+#define	GPIOZ_10	78
+#define	GPIOZ_11	79
+#define	GPIOZ_12	80
+
+#define	GPIO_TEST_N	81
+#endif /* _DT_BINDINGS_MESON_S4_GPIO_H */
-- 
2.34.1



From qianggui.song at amlogic.com  Wed Jan 12 19:10:43 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Thu, 13 Jan 2022 11:10:43 +0800
Subject: [PATCH v4 3/3] pinctrl: meson: add pinctrl driver support for
 Meson-S4 Soc
In-Reply-To: <20220113031044.2665-1-qianggui.song@amlogic.com>
References: <20220113031044.2665-1-qianggui.song@amlogic.com>
Message-ID: <20220113031044.2665-4-qianggui.song@amlogic.com>

Add new pinctrl driver for Amlogic's Meson-S4 SoC which share the
same register layout as the previous Meson-A1.

Acked-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 drivers/pinctrl/meson/Kconfig            |    6 +
 drivers/pinctrl/meson/Makefile           |    1 +
 drivers/pinctrl/meson/pinctrl-meson-s4.c | 1232 ++++++++++++++++++++++
 3 files changed, 1239 insertions(+)
 create mode 100644 drivers/pinctrl/meson/pinctrl-meson-s4.c

diff --git a/drivers/pinctrl/meson/Kconfig b/drivers/pinctrl/meson/Kconfig
index b2855e341a75..d1955c65b4b6 100644
--- a/drivers/pinctrl/meson/Kconfig
+++ b/drivers/pinctrl/meson/Kconfig
@@ -61,4 +61,10 @@ config PINCTRL_MESON_A1
 	select PINCTRL_MESON_AXG_PMX
 	default y
 
+config PINCTRL_MESON_S4
+	tristate "Meson s4 Soc pinctrl driver"
+	depends on ARM64
+	select PINCTRL_MESON_AXG_PMX
+	default y
+
 endif
diff --git a/drivers/pinctrl/meson/Makefile b/drivers/pinctrl/meson/Makefile
index 1a5bffe953f9..694f0596bfbc 100644
--- a/drivers/pinctrl/meson/Makefile
+++ b/drivers/pinctrl/meson/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_PINCTRL_MESON_AXG_PMX) += pinctrl-meson-axg-pmx.o
 obj-$(CONFIG_PINCTRL_MESON_AXG) += pinctrl-meson-axg.o
 obj-$(CONFIG_PINCTRL_MESON_G12A) += pinctrl-meson-g12a.o
 obj-$(CONFIG_PINCTRL_MESON_A1) += pinctrl-meson-a1.o
+obj-$(CONFIG_PINCTRL_MESON_S4) += pinctrl-meson-s4.o
diff --git a/drivers/pinctrl/meson/pinctrl-meson-s4.c b/drivers/pinctrl/meson/pinctrl-meson-s4.c
new file mode 100644
index 000000000000..3c7358f53302
--- /dev/null
+++ b/drivers/pinctrl/meson/pinctrl-meson-s4.c
@@ -0,0 +1,1232 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Pin controller and GPIO driver for Amlogic Meson S4 SoC.
+ *
+ * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
+ * Author: Qianggui Song <qianggui.song at amlogic.com>
+ */
+
+#include <dt-bindings/gpio/meson-s4-gpio.h>
+#include "pinctrl-meson.h"
+#include "pinctrl-meson-axg-pmx.h"
+
+static const struct pinctrl_pin_desc meson_s4_periphs_pins[] = {
+	MESON_PIN(GPIOE_0),
+	MESON_PIN(GPIOE_1),
+
+	MESON_PIN(GPIOB_0),
+	MESON_PIN(GPIOB_1),
+	MESON_PIN(GPIOB_2),
+	MESON_PIN(GPIOB_3),
+	MESON_PIN(GPIOB_4),
+	MESON_PIN(GPIOB_5),
+	MESON_PIN(GPIOB_6),
+	MESON_PIN(GPIOB_7),
+	MESON_PIN(GPIOB_8),
+	MESON_PIN(GPIOB_9),
+	MESON_PIN(GPIOB_10),
+	MESON_PIN(GPIOB_11),
+	MESON_PIN(GPIOB_12),
+	MESON_PIN(GPIOB_13),
+
+	MESON_PIN(GPIOC_0),
+	MESON_PIN(GPIOC_1),
+	MESON_PIN(GPIOC_2),
+	MESON_PIN(GPIOC_3),
+	MESON_PIN(GPIOC_4),
+	MESON_PIN(GPIOC_5),
+	MESON_PIN(GPIOC_6),
+	MESON_PIN(GPIOC_7),
+
+	MESON_PIN(GPIOD_0),
+	MESON_PIN(GPIOD_1),
+	MESON_PIN(GPIOD_2),
+	MESON_PIN(GPIOD_3),
+	MESON_PIN(GPIOD_4),
+	MESON_PIN(GPIOD_5),
+	MESON_PIN(GPIOD_6),
+	MESON_PIN(GPIOD_7),
+	MESON_PIN(GPIOD_8),
+	MESON_PIN(GPIOD_9),
+	MESON_PIN(GPIOD_10),
+	MESON_PIN(GPIOD_11),
+
+	MESON_PIN(GPIOH_0),
+	MESON_PIN(GPIOH_1),
+	MESON_PIN(GPIOH_2),
+	MESON_PIN(GPIOH_3),
+	MESON_PIN(GPIOH_4),
+	MESON_PIN(GPIOH_5),
+	MESON_PIN(GPIOH_6),
+	MESON_PIN(GPIOH_7),
+	MESON_PIN(GPIOH_8),
+	MESON_PIN(GPIOH_9),
+	MESON_PIN(GPIOH_10),
+	MESON_PIN(GPIOH_11),
+
+	MESON_PIN(GPIOX_0),
+	MESON_PIN(GPIOX_1),
+	MESON_PIN(GPIOX_2),
+	MESON_PIN(GPIOX_3),
+	MESON_PIN(GPIOX_4),
+	MESON_PIN(GPIOX_5),
+	MESON_PIN(GPIOX_6),
+	MESON_PIN(GPIOX_7),
+	MESON_PIN(GPIOX_8),
+	MESON_PIN(GPIOX_9),
+	MESON_PIN(GPIOX_10),
+	MESON_PIN(GPIOX_11),
+	MESON_PIN(GPIOX_12),
+	MESON_PIN(GPIOX_13),
+	MESON_PIN(GPIOX_14),
+	MESON_PIN(GPIOX_15),
+	MESON_PIN(GPIOX_16),
+	MESON_PIN(GPIOX_17),
+	MESON_PIN(GPIOX_18),
+	MESON_PIN(GPIOX_19),
+
+	MESON_PIN(GPIOZ_0),
+	MESON_PIN(GPIOZ_1),
+	MESON_PIN(GPIOZ_2),
+	MESON_PIN(GPIOZ_3),
+	MESON_PIN(GPIOZ_4),
+	MESON_PIN(GPIOZ_5),
+	MESON_PIN(GPIOZ_6),
+	MESON_PIN(GPIOZ_7),
+	MESON_PIN(GPIOZ_8),
+	MESON_PIN(GPIOZ_9),
+	MESON_PIN(GPIOZ_10),
+	MESON_PIN(GPIOZ_11),
+	MESON_PIN(GPIOZ_12),
+
+	MESON_PIN(GPIO_TEST_N),
+};
+
+/* BANK E func1 */
+static const unsigned int i2c0_sda_pins[]		= { GPIOE_0 };
+static const unsigned int i2c0_scl_pins[]		= { GPIOE_1 };
+
+/* BANK E func2 */
+static const unsigned int uart_b_tx_e_pins[]		= { GPIOE_0 };
+static const unsigned int uart_b_rx_e_pins[]		= { GPIOE_1 };
+
+/* BANK E func3 */
+static const unsigned int pwm_h_pins[]			= { GPIOE_0 };
+static const unsigned int pwm_j_pins[]			= { GPIOE_1 };
+
+/* BANK B func1 */
+static const unsigned int emmc_nand_d0_pins[]		= { GPIOB_0 };
+static const unsigned int emmc_nand_d1_pins[]		= { GPIOB_1 };
+static const unsigned int emmc_nand_d2_pins[]		= { GPIOB_2 };
+static const unsigned int emmc_nand_d3_pins[]		= { GPIOB_3 };
+static const unsigned int emmc_nand_d4_pins[]		= { GPIOB_4 };
+static const unsigned int emmc_nand_d5_pins[]		= { GPIOB_5 };
+static const unsigned int emmc_nand_d6_pins[]		= { GPIOB_6 };
+static const unsigned int emmc_nand_d7_pins[]		= { GPIOB_7 };
+static const unsigned int emmc_clk_pins[]		= { GPIOB_8 };
+static const unsigned int emmc_rst_pins[]		= { GPIOB_9 };
+static const unsigned int emmc_cmd_pins[]		= { GPIOB_10 };
+static const unsigned int emmc_nand_ds_pins[]		= { GPIOB_11 };
+
+/* Bank B func2 */
+static const unsigned int nand_wen_clk_pins[]		= { GPIOB_8 };
+static const unsigned int nand_ale_pins[]		= { GPIOB_9 };
+static const unsigned int nand_ren_wr_pins[]		= { GPIOB_10 };
+static const unsigned int nand_cle_pins[]		= { GPIOB_11 };
+static const unsigned int nand_ce0_pins[]		= { GPIOB_12 };
+
+/* Bank B func3 */
+static const unsigned int spif_hold_pins[]		= { GPIOB_3 };
+static const unsigned int spif_mo_pins[]		= { GPIOB_4 };
+static const unsigned int spif_mi_pins[]		= { GPIOB_5 };
+static const unsigned int spif_clk_pins[]		= { GPIOB_6 };
+static const unsigned int spif_wp_pins[]		= { GPIOB_7 };
+static const unsigned int spif_cs_pins[]		= { GPIOB_13 };
+
+/* Bank C func1 */
+static const unsigned int sdcard_d0_c_pins[]		= { GPIOC_0 };
+static const unsigned int sdcard_d1_c_pins[]		= { GPIOC_1 };
+static const unsigned int sdcard_d2_c_pins[]		= { GPIOC_2 };
+static const unsigned int sdcard_d3_c_pins[]		= { GPIOC_3 };
+static const unsigned int sdcard_clk_c_pins[]		= { GPIOC_4 };
+static const unsigned int sdcard_cmd_c_pins[]		= { GPIOC_5 };
+static const unsigned int sdcard_cd_pins[]		= { GPIOC_6 };
+
+/* Bank C func2 */
+static const unsigned int jtag_2_tdo_pins[]		= { GPIOC_0 };
+static const unsigned int jtag_2_tdi_pins[]		= { GPIOC_1 };
+static const unsigned int uart_b_rx_c_pins[]		= { GPIOC_2 };
+static const unsigned int uart_b_tx_c_pins[]		= { GPIOC_3 };
+static const unsigned int jtag_2_clk_pins[]		= { GPIOC_4 };
+static const unsigned int jtag_2_tms_pins[]		= { GPIOC_5 };
+static const unsigned int i2c1_sda_c_pins[]		= { GPIOC_6 };
+static const unsigned int i2c1_scl_c_pins[]		= { GPIOC_7 };
+
+/* Bank C func3 */
+static const unsigned int pdm_din1_c_pins[]		= { GPIOC_0 };
+static const unsigned int pdm_din0_c_pins[]		= { GPIOC_1 };
+static const unsigned int i2c4_sda_c_pins[]		= { GPIOC_2 };
+static const unsigned int i2c4_scl_c_pins[]		= { GPIOC_3 };
+static const unsigned int pdm_dclk_c_pins[]		= { GPIOC_4 };
+static const unsigned int iso7816_clk_c_pins[]		= { GPIOC_5 };
+static const unsigned int iso7816_data_c_pins[]		= { GPIOC_6 };
+
+/* Bank C func4 */
+static const unsigned int tdm_d2_c_pins[]		= { GPIOC_0 };
+static const unsigned int tdm_d3_c_pins[]		= { GPIOC_1 };
+static const unsigned int tdm_fs1_c_pins[]		= { GPIOC_2 };
+static const unsigned int tdm_sclk1_c_pins[]		= { GPIOC_3 };
+static const unsigned int mclk_1_c_pins[]		= { GPIOC_4 };
+static const unsigned int tdm_d4_c_pins[]		= { GPIOC_5 };
+static const unsigned int tdm_d5_c_pins[]		= { GPIOC_6 };
+
+/* Bank D func1 */
+static const unsigned int uart_b_tx_d_pins[]		= { GPIOD_0 };
+static const unsigned int uart_b_rx_d_pins[]		= { GPIOD_1 };
+static const unsigned int uart_b_cts_d_pins[]		= { GPIOD_2 };
+static const unsigned int uart_b_rts_d_pins[]		= { GPIOD_3 };
+static const unsigned int remote_out_pins[]		= { GPIOD_4 };
+static const unsigned int remote_in_pins[]		= { GPIOD_5 };
+static const unsigned int jtag_1_clk_pins[]		= { GPIOD_6 };
+static const unsigned int jtag_1_tms_pins[]		= { GPIOD_7 };
+static const unsigned int jtag_1_tdi_pins[]		= { GPIOD_8 };
+static const unsigned int jtag_1_tdo_pins[]		= { GPIOD_9 };
+static const unsigned int clk12_24_pins[]		= { GPIOD_10 };
+static const unsigned int pwm_g_hiz_pins[]		= { GPIOD_11 };
+
+/* Bank D func2 */
+static const unsigned int i2c4_sda_d_pins[]		= { GPIOD_2 };
+static const unsigned int i2c4_scl_d_pins[]		= { GPIOD_3 };
+static const unsigned int mclk_1_d_pins[]		= { GPIOD_4 };
+static const unsigned int tdm_sclk1_d_pins[]		= { GPIOD_6 };
+static const unsigned int tdm_fs1_d_pins[]		= { GPIOD_7 };
+static const unsigned int tdm_d4_d_pins[]		= { GPIOD_8 };
+static const unsigned int tdm_d3_d_pins[]		= { GPIOD_9 };
+static const unsigned int tdm_d2_d_pins[]		= { GPIOD_10 };
+static const unsigned int pwm_g_d_pins[]		= { GPIOD_11 };
+
+/* Bank D func3 */
+static const unsigned int uart_c_tx_pins[]		= { GPIOD_2 };
+static const unsigned int uart_c_rx_pins[]		= { GPIOD_3 };
+static const unsigned int pwm_b_d_pins[]		= { GPIOD_4 };
+static const unsigned int pwm_a_d_pins[]		= { GPIOD_6 };
+static const unsigned int pwm_c_d_pins[]		= { GPIOD_7 };
+static const unsigned int pwm_d_d_pins[]		= { GPIOD_8 };
+static const unsigned int pwm_i_d_pins[]		= { GPIOD_9 };
+
+/* Bank D func4 */
+static const unsigned int clk_32k_in_pins[]		= { GPIOD_2 };
+static const unsigned int pwm_b_hiz_pins[]		= { GPIOD_4 };
+static const unsigned int pwm_a_hiz_pins[]		= { GPIOD_6 };
+static const unsigned int pwm_c_hiz_pins[]		= { GPIOD_7 };
+static const unsigned int pdm_dclk_d_pins[]		= { GPIOD_8 };
+static const unsigned int pdm_din0_d_pins[]		= { GPIOD_9 };
+static const unsigned int pdm_din1_d_pins[]		= { GPIOD_10 };
+
+/* Bank D func5 */
+static const unsigned int mic_mute_en_pins[]		= { GPIOD_2 };
+static const unsigned int mic_mute_key_pins[]		= { GPIOD_3 };
+static const unsigned int i2c1_sda_d_pins[]		= { GPIOD_6 };
+static const unsigned int i2c1_scl_d_pins[]		= { GPIOD_7 };
+static const unsigned int i2c2_sda_d_pins[]		= { GPIOD_10 };
+static const unsigned int i2c2_scl_d_pins[]		= { GPIOD_11 };
+
+/* Bank D func6 */
+static const unsigned int gen_clk_d_pins[]		= { GPIOD_10 };
+static const unsigned int tsin_b_clk_c_pins[]		= { GPIOD_6 };
+static const unsigned int tsin_b_sop_c_pins[]		= { GPIOD_7 };
+static const unsigned int tsin_b_valid_c_pins[]		= { GPIOD_8 };
+static const unsigned int tsin_b_d0_c_pins[]		= { GPIOD_9 };
+
+/* Bank H func1 */
+static const unsigned int hdmitx_sda_pins[]		= { GPIOH_0 };
+static const unsigned int hdmitx_sck_pins[]		= { GPIOH_1 };
+static const unsigned int hdmitx_hpd_in_pins[]		= { GPIOH_2 };
+static const unsigned int ao_cec_a_pins[]		= { GPIOH_3 };
+static const unsigned int spdif_out_h_pins[]		= { GPIOH_4 };
+static const unsigned int spdif_in_pins[]		= { GPIOH_5 };
+static const unsigned int i2c1_sda_h_pins[]		= { GPIOH_6 };
+static const unsigned int i2c1_scl_h_pins[]		= { GPIOH_7 };
+static const unsigned int i2c2_sda_h8_pins[]		= { GPIOH_8 };
+static const unsigned int i2c2_scl_h9_pins[]		= { GPIOH_9 };
+static const unsigned int eth_link_led_pins[]		= { GPIOH_10 };
+static const unsigned int eth_act_led_pins[]		= { GPIOH_11 };
+
+/* Bank H func2 */
+static const unsigned int i2c2_sda_h0_pins[]		= { GPIOH_0 };
+static const unsigned int i2c2_scl_h1_pins[]		= { GPIOH_1 };
+static const unsigned int ao_cec_b_pins[]		= { GPIOH_3 };
+static const unsigned int uart_d_tx_h_pins[]		= { GPIOH_4 };
+static const unsigned int uart_d_rx_h_pins[]		= { GPIOH_5 };
+static const unsigned int uart_d_cts_h_pins[]		= { GPIOH_6 };
+static const unsigned int uart_d_rts_h_pins[]		= { GPIOH_7 };
+static const unsigned int iso7816_clk_h_pins[]		= { GPIOH_8 };
+static const unsigned int iso7816_data_h_pins[]		= { GPIOH_9 };
+static const unsigned int uart_e_tx_h_pins[]		= { GPIOH_10 };
+static const unsigned int uart_e_rx_h_pins[]		= { GPIOH_11 };
+
+/* Bank H func3 */
+static const unsigned int pwm_d_h_pins[]		= { GPIOH_6 };
+static const unsigned int pwm_i_h_pins[]		= { GPIOH_7 };
+static const unsigned int pdm_dclk_h_pins[]		= { GPIOH_8 };
+static const unsigned int pdm_din0_h_pins[]		= { GPIOH_9 };
+static const unsigned int pdm_din1_h_pins[]		= { GPIOH_10 };
+
+/* Bank H func4 */
+static const unsigned int mclk_1_h_pins[]		= { GPIOH_4 };
+static const unsigned int tdm_sclk1_h_pins[]		= { GPIOH_5 };
+static const unsigned int tdm_fs1_h_pins[]		= { GPIOH_6 };
+static const unsigned int tdm_d2_h_pins[]		= { GPIOH_7 };
+static const unsigned int tdm_d3_h_pins[]		= { GPIOH_8 };
+static const unsigned int tdm_d4_h_pins[]		= { GPIOH_9 };
+
+/* Bank H func5 */
+static const unsigned int spi_a_miso_h_pins[]		= { GPIOH_4 };
+static const unsigned int spi_a_mosi_h_pins[]		= { GPIOH_5 };
+static const unsigned int spi_a_clk_h_pins[]		= { GPIOH_6 };
+static const unsigned int spi_a_ss0_h_pins[]		= { GPIOH_7 };
+
+/* Bank H func6 */
+static const unsigned int gen_clk_h_pins[]		= { GPIOH_11 };
+static const unsigned int tsin_b1_clk_pins[]		= { GPIOH_4 };
+static const unsigned int tsin_b1_sop_pins[]		= { GPIOH_5 };
+static const unsigned int tsin_b1_valid_pins[]		= { GPIOH_6 };
+static const unsigned int tsin_b1_d0_pins[]		= { GPIOH_7 };
+
+/* Bank X func1 */
+static const unsigned int sdio_d0_pins[]		= { GPIOX_0 };
+static const unsigned int sdio_d1_pins[]		= { GPIOX_1 };
+static const unsigned int sdio_d2_pins[]		= { GPIOX_2 };
+static const unsigned int sdio_d3_pins[]		= { GPIOX_3 };
+static const unsigned int sdio_clk_pins[]		= { GPIOX_4 };
+static const unsigned int sdio_cmd_pins[]		= { GPIOX_5 };
+static const unsigned int pwm_a_x_pins[]		= { GPIOX_6 };
+static const unsigned int pwm_f_x_pins[]		= { GPIOX_7 };
+static const unsigned int tdm_d1_pins[]			= { GPIOX_8 };
+static const unsigned int tdm_d0_pins[]			= { GPIOX_9 };
+static const unsigned int tdm_fs0_pins[]		= { GPIOX_10 };
+static const unsigned int tdm_sclk0_pins[]		= { GPIOX_11 };
+static const unsigned int uart_a_tx_pins[]		= { GPIOX_12 };
+static const unsigned int uart_a_rx_pins[]		= { GPIOX_13 };
+static const unsigned int uart_a_cts_pins[]		= { GPIOX_14 };
+static const unsigned int uart_a_rts_pins[]		= { GPIOX_15 };
+static const unsigned int pwm_e_x_pins[]		= { GPIOX_16 };
+static const unsigned int i2c1_sda_x_pins[]		= { GPIOX_17 };
+static const unsigned int i2c1_scl_x_pins[]		= { GPIOX_18 };
+static const unsigned int pwm_b_x_pins[]		= { GPIOX_19 };
+
+/* Bank X func2 */
+static const unsigned int pdm_din0_x_pins[]		= { GPIOX_8 };
+static const unsigned int pdm_din1_x_pins[]		= { GPIOX_9 };
+static const unsigned int pdm_dclk_x_pins[]		= { GPIOX_11 };
+
+/* Bank X func3 */
+static const unsigned int spi_a_mosi_x_pins[]		= { GPIOX_8 };
+static const unsigned int spi_a_miso_x_pins[]		= { GPIOX_9 };
+static const unsigned int spi_a_ss0_x_pins[]		= { GPIOX_10 };
+static const unsigned int spi_a_clk_x_pins[]		= { GPIOX_11 };
+
+/* Bank X func4 */
+static const unsigned int pwm_c_x_pins[]		= { GPIOX_8 };
+static const unsigned int i2c_slave_scl_pins[]		= { GPIOX_10 };
+static const unsigned int i2c_slave_sda_pins[]		= { GPIOX_11 };
+
+/* Bank X func5 */
+static const unsigned int i2c3_sda_x_pins[]		= { GPIOX_10 };
+static const unsigned int i2c3_scl_x_pins[]		= { GPIOX_11 };
+
+/* Bank Z func1 */
+static const unsigned int tdm_fs2_pins[]		= { GPIOZ_0 };
+static const unsigned int tdm_sclk2_pins[]		= { GPIOZ_1 };
+static const unsigned int tdm_d4_z_pins[]		= { GPIOZ_2 };
+static const unsigned int tdm_d5_z_pins[]		= { GPIOZ_3 };
+static const unsigned int tdm_d6_pins[]			= { GPIOZ_4 };
+static const unsigned int tdm_d7_pins[]			= { GPIOZ_5 };
+static const unsigned int mclk_2_pins[]			= { GPIOZ_6 };
+static const unsigned int spdif_out_z_pins[]		= { GPIOZ_9 };
+static const unsigned int dtv_a_if_agc_z10_pins[]	= { GPIOZ_10 };
+static const unsigned int uart_e_tx_z11_pins[]		= { GPIOZ_11 };
+static const unsigned int uart_e_rx_z12_pins[]		= { GPIOZ_12 };
+
+/* Bank Z func2 */
+static const unsigned int tsin_a_clk_pins[]		= { GPIOZ_0 };
+static const unsigned int tsin_a_sop_pins[]		= { GPIOZ_1 };
+static const unsigned int tsin_a_valid_pins[]		= { GPIOZ_2 };
+static const unsigned int tsin_a_din0_pins[]		= { GPIOZ_3 };
+static const unsigned int dtv_a_if_agc_z6_pins[]	= { GPIOZ_6 };
+static const unsigned int dtv_b_if_agc_pins[]		= { GPIOZ_7 };
+static const unsigned int i2c3_sda_z_pins[]		= { GPIOZ_8 };
+static const unsigned int i2c3_scl_z_pins[]		= { GPIOZ_9 };
+static const unsigned int dtv_a_rf_agc_pins[]		= { GPIOZ_10 };
+static const unsigned int dtv_b_rf_agc_pins[]		= { GPIOZ_11 };
+
+/* Bank Z func3 */
+static const unsigned int sdcard_d0_z_pins[]		= { GPIOZ_0 };
+static const unsigned int sdcard_d1_z_pins[]		= { GPIOZ_1 };
+static const unsigned int sdcard_d2_z_pins[]		= { GPIOZ_2 };
+static const unsigned int sdcard_d3_z_pins[]		= { GPIOZ_3 };
+static const unsigned int sdcard_clk_z_pins[]		= { GPIOZ_4 };
+static const unsigned int sdcard_cmd_z_pins[]		= { GPIOZ_5 };
+static const unsigned int uart_e_tx_z8_pins[]		= { GPIOZ_8 };
+static const unsigned int uart_e_rx_z9_pins[]		= { GPIOZ_9 };
+static const unsigned int pdm_din1_z_pins[]		= { GPIOZ_10 };
+static const unsigned int pdm_din0_z_pins[]		= { GPIOZ_11 };
+static const unsigned int pdm_dclk_z_pins[]		= { GPIOZ_12 };
+
+/* Bank Z func4 */
+static const unsigned int spi_a_miso_z_pins[]		= { GPIOZ_0 };
+static const unsigned int spi_a_mosi_z_pins[]		= { GPIOZ_1 };
+static const unsigned int spi_a_clk_z_pins[]		= { GPIOZ_2 };
+static const unsigned int spi_a_ss0_z_pins[]		= { GPIOZ_3 };
+static const unsigned int spi_a_ss1_z_pins[]		= { GPIOZ_4 };
+static const unsigned int spi_a_ss2_z_pins[]		= { GPIOZ_5 };
+static const unsigned int i2c4_scl_z_pins[]		= { GPIOZ_11 };
+static const unsigned int i2c4_sda_z_pins[]		= { GPIOZ_12 };
+
+/* Bank Z func5 */
+static const unsigned int uart_d_tx_z_pins[]		= { GPIOZ_0 };
+static const unsigned int uart_d_rx_z_pins[]		= { GPIOZ_1 };
+static const unsigned int uart_d_cts_z_pins[]		= { GPIOZ_2 };
+static const unsigned int uart_d_rts_z_pins[]		= { GPIOZ_3 };
+static const unsigned int pwm_g_z_pins[]		= { GPIOZ_4 };
+static const unsigned int pwm_f_z_pins[]		= { GPIOZ_5 };
+static const unsigned int pwm_e_z_pins[]		= { GPIOZ_6 };
+static const unsigned int tsin_b_clk_z_pins[]		= { GPIOZ_7 };
+static const unsigned int tsin_b_sop_z_pins[]		= { GPIOZ_10 };
+static const unsigned int tsin_b_valid_z_pins[]		= { GPIOZ_11 };
+static const unsigned int tsin_b_d0_z_pins[]		= { GPIOZ_12 };
+
+/* Bank Z func6 */
+static const unsigned int s2_demod_gpio7_pins[]		= { GPIOZ_0 };
+static const unsigned int s2_demod_gpio6_pins[]		= { GPIOZ_1 };
+static const unsigned int s2_demod_gpio5_pins[]		= { GPIOZ_2 };
+static const unsigned int s2_demod_gpio4_pins[]		= { GPIOZ_3 };
+static const unsigned int s2_demod_gpio3_pins[]		= { GPIOZ_4 };
+static const unsigned int s2_demod_gpio2_pins[]		= { GPIOZ_5 };
+static const unsigned int diseqc_out_pins[]		= { GPIOZ_7 };
+static const unsigned int s2_demod_gpio1_pins[]		= { GPIOZ_8 };
+static const unsigned int s2_demod_gpio0_pins[]		= { GPIOZ_12 };
+
+/* Bank Z func7 */
+static const unsigned int gen_clk_z9_pins[]		= { GPIOZ_9 };
+static const unsigned int gen_clk_z12_pins[]		= { GPIOZ_12 };
+
+static struct meson_pmx_group meson_s4_periphs_groups[] = {
+	GPIO_GROUP(GPIOE_0),
+	GPIO_GROUP(GPIOE_1),
+
+	GPIO_GROUP(GPIOB_0),
+	GPIO_GROUP(GPIOB_1),
+	GPIO_GROUP(GPIOB_2),
+	GPIO_GROUP(GPIOB_3),
+	GPIO_GROUP(GPIOB_4),
+	GPIO_GROUP(GPIOB_5),
+	GPIO_GROUP(GPIOB_6),
+	GPIO_GROUP(GPIOB_7),
+	GPIO_GROUP(GPIOB_8),
+	GPIO_GROUP(GPIOB_9),
+	GPIO_GROUP(GPIOB_10),
+	GPIO_GROUP(GPIOB_11),
+	GPIO_GROUP(GPIOB_12),
+	GPIO_GROUP(GPIOB_13),
+
+	GPIO_GROUP(GPIOC_0),
+	GPIO_GROUP(GPIOC_1),
+	GPIO_GROUP(GPIOC_2),
+	GPIO_GROUP(GPIOC_3),
+	GPIO_GROUP(GPIOC_4),
+	GPIO_GROUP(GPIOC_5),
+	GPIO_GROUP(GPIOC_6),
+	GPIO_GROUP(GPIOC_7),
+
+	GPIO_GROUP(GPIOD_0),
+	GPIO_GROUP(GPIOD_1),
+	GPIO_GROUP(GPIOD_2),
+	GPIO_GROUP(GPIOD_3),
+	GPIO_GROUP(GPIOD_4),
+	GPIO_GROUP(GPIOD_5),
+	GPIO_GROUP(GPIOD_6),
+	GPIO_GROUP(GPIOD_7),
+	GPIO_GROUP(GPIOD_8),
+	GPIO_GROUP(GPIOD_9),
+	GPIO_GROUP(GPIOD_10),
+	GPIO_GROUP(GPIOD_11),
+
+	GPIO_GROUP(GPIOH_0),
+	GPIO_GROUP(GPIOH_1),
+	GPIO_GROUP(GPIOH_2),
+	GPIO_GROUP(GPIOH_3),
+	GPIO_GROUP(GPIOH_4),
+	GPIO_GROUP(GPIOH_5),
+	GPIO_GROUP(GPIOH_6),
+	GPIO_GROUP(GPIOH_7),
+	GPIO_GROUP(GPIOH_8),
+	GPIO_GROUP(GPIOH_9),
+	GPIO_GROUP(GPIOH_10),
+	GPIO_GROUP(GPIOH_11),
+
+	GPIO_GROUP(GPIOX_0),
+	GPIO_GROUP(GPIOX_1),
+	GPIO_GROUP(GPIOX_2),
+	GPIO_GROUP(GPIOX_3),
+	GPIO_GROUP(GPIOX_4),
+	GPIO_GROUP(GPIOX_5),
+	GPIO_GROUP(GPIOX_6),
+	GPIO_GROUP(GPIOX_7),
+	GPIO_GROUP(GPIOX_8),
+	GPIO_GROUP(GPIOX_9),
+	GPIO_GROUP(GPIOX_10),
+	GPIO_GROUP(GPIOX_11),
+	GPIO_GROUP(GPIOX_12),
+	GPIO_GROUP(GPIOX_13),
+	GPIO_GROUP(GPIOX_14),
+	GPIO_GROUP(GPIOX_15),
+	GPIO_GROUP(GPIOX_16),
+	GPIO_GROUP(GPIOX_17),
+	GPIO_GROUP(GPIOX_18),
+	GPIO_GROUP(GPIOX_19),
+
+	GPIO_GROUP(GPIOZ_0),
+	GPIO_GROUP(GPIOZ_1),
+	GPIO_GROUP(GPIOZ_2),
+	GPIO_GROUP(GPIOZ_3),
+	GPIO_GROUP(GPIOZ_4),
+	GPIO_GROUP(GPIOZ_5),
+	GPIO_GROUP(GPIOZ_6),
+	GPIO_GROUP(GPIOZ_7),
+	GPIO_GROUP(GPIOZ_8),
+	GPIO_GROUP(GPIOZ_9),
+	GPIO_GROUP(GPIOZ_10),
+	GPIO_GROUP(GPIOZ_11),
+	GPIO_GROUP(GPIOZ_12),
+
+	GPIO_GROUP(GPIO_TEST_N),
+
+	/* BANK E func1 */
+	GROUP(i2c0_sda,			1),
+	GROUP(i2c0_scl,			1),
+
+	/* BANK E func2 */
+	GROUP(uart_b_tx_e,		2),
+	GROUP(uart_b_rx_e,		2),
+
+	/* BANK E func3 */
+	GROUP(pwm_h,			3),
+	GROUP(pwm_j,			3),
+
+	/* BANK B func1 */
+	GROUP(emmc_nand_d0,		1),
+	GROUP(emmc_nand_d1,		1),
+	GROUP(emmc_nand_d2,		1),
+	GROUP(emmc_nand_d3,		1),
+	GROUP(emmc_nand_d4,		1),
+	GROUP(emmc_nand_d5,		1),
+	GROUP(emmc_nand_d6,		1),
+	GROUP(emmc_nand_d7,		1),
+	GROUP(emmc_clk,			1),
+	GROUP(emmc_rst,			1),
+	GROUP(emmc_cmd,			1),
+	GROUP(emmc_nand_ds,		1),
+
+	/* Bank B func2 */
+	GROUP(nand_wen_clk,		2),
+	GROUP(nand_ale,			2),
+	GROUP(nand_ren_wr,		2),
+	GROUP(nand_cle,			2),
+	GROUP(nand_ce0,			2),
+
+	/* Bank B func3 */
+	GROUP(spif_hold,		3),
+	GROUP(spif_mo,			3),
+	GROUP(spif_mi,			3),
+	GROUP(spif_clk,			3),
+	GROUP(spif_wp,			3),
+	GROUP(spif_cs,			3),
+
+	/* Bank C func1 */
+	GROUP(sdcard_d0_c,		1),
+	GROUP(sdcard_d1_c,		1),
+	GROUP(sdcard_d2_c,		1),
+	GROUP(sdcard_d3_c,		1),
+	GROUP(sdcard_clk_c,		1),
+	GROUP(sdcard_cmd_c,		1),
+	GROUP(sdcard_cd,		1),
+
+	/* Bank C func2 */
+	GROUP(jtag_2_tdo,		2),
+	GROUP(jtag_2_tdi,		2),
+	GROUP(uart_b_rx_c,		2),
+	GROUP(uart_b_tx_c,		2),
+	GROUP(jtag_2_clk,		2),
+	GROUP(jtag_2_tms,		2),
+	GROUP(i2c1_sda_c,		2),
+	GROUP(i2c1_scl_c,		2),
+
+	/* Bank C func3 */
+	GROUP(pdm_din1_c,		3),
+	GROUP(pdm_din0_c,		3),
+	GROUP(i2c4_sda_c,		3),
+	GROUP(i2c4_scl_c,		3),
+	GROUP(pdm_dclk_c,		3),
+	GROUP(iso7816_clk_c,		3),
+	GROUP(iso7816_data_c,		3),
+
+	/* Bank C func4 */
+	GROUP(tdm_d2_c,			4),
+	GROUP(tdm_d3_c,			4),
+	GROUP(tdm_fs1_c,		4),
+	GROUP(mclk_1_c,			4),
+	GROUP(tdm_d4_c,			4),
+	GROUP(tdm_d5_c,			4),
+
+	/* Bank D func1 */
+	GROUP(uart_b_tx_d,		1),
+	GROUP(uart_b_rx_d,		1),
+	GROUP(uart_b_cts_d,		1),
+	GROUP(uart_b_rts_d,		1),
+	GROUP(remote_out,		1),
+	GROUP(remote_in,		1),
+	GROUP(jtag_1_clk,		1),
+	GROUP(jtag_1_tms,		1),
+	GROUP(jtag_1_tdi,		1),
+	GROUP(jtag_1_tdo,		1),
+	GROUP(clk12_24,			1),
+	GROUP(pwm_g_hiz,		1),
+
+	/* Bank D func2 */
+	GROUP(i2c4_sda_d,		2),
+	GROUP(i2c4_scl_d,		2),
+	GROUP(mclk_1_d,			2),
+	GROUP(tdm_sclk1_d,		2),
+	GROUP(tdm_fs1_d,		2),
+	GROUP(tdm_d4_d,			2),
+	GROUP(tdm_d3_d,			2),
+	GROUP(tdm_d2_d,			2),
+	GROUP(pwm_g_d,			2),
+
+	/* Bank D func3 */
+	GROUP(uart_c_tx,		3),
+	GROUP(uart_c_rx,		3),
+	GROUP(pwm_b_d,			3),
+	GROUP(pwm_a_d,			3),
+	GROUP(pwm_c_d,			3),
+	GROUP(pwm_d_d,			3),
+	GROUP(pwm_i_d,			3),
+
+	/* Bank D func4 */
+	GROUP(clk_32k_in,		4),
+	GROUP(pwm_b_hiz,		4),
+	GROUP(pwm_a_hiz,		4),
+	GROUP(pwm_c_hiz,		4),
+	GROUP(pdm_dclk_d,		4),
+	GROUP(pdm_din0_d,		4),
+	GROUP(pdm_din1_d,		4),
+
+	/* Bank D func5 */
+	GROUP(mic_mute_en,		5),
+	GROUP(mic_mute_key,		5),
+	GROUP(i2c1_sda_d,		5),
+	GROUP(i2c1_scl_d,		5),
+	GROUP(i2c2_sda_d,		5),
+	GROUP(i2c2_scl_d,		5),
+
+	/* Bank D func6 */
+	GROUP(gen_clk_d,		6),
+	GROUP(tsin_b_clk_c,		6),
+	GROUP(tsin_b_sop_c,		6),
+	GROUP(tsin_b_valid_c,		6),
+	GROUP(tsin_b_d0_c,		6),
+
+	/* Bank H func1 */
+	GROUP(hdmitx_sda,		1),
+	GROUP(hdmitx_sck,		1),
+	GROUP(hdmitx_hpd_in,		1),
+	GROUP(ao_cec_a,			1),
+	GROUP(spdif_out_h,		1),
+	GROUP(spdif_in,			1),
+	GROUP(i2c1_sda_h,		1),
+	GROUP(i2c1_scl_h,		1),
+	GROUP(i2c2_sda_h8,		1),
+	GROUP(i2c2_scl_h9,		1),
+	GROUP(eth_link_led,		1),
+	GROUP(eth_act_led,		1),
+
+	/* Bank H func2 */
+	GROUP(i2c2_sda_h0,		2),
+	GROUP(i2c2_scl_h1,		2),
+	GROUP(ao_cec_b,			2),
+	GROUP(uart_d_tx_h,		2),
+	GROUP(uart_d_rx_h,		2),
+	GROUP(uart_d_cts_h,		2),
+	GROUP(uart_d_rts_h,		2),
+	GROUP(iso7816_clk_h,		2),
+	GROUP(iso7816_data_h,		2),
+	GROUP(uart_e_tx_h,		2),
+	GROUP(uart_e_rx_h,		2),
+
+	/* Bank H func3 */
+	GROUP(pwm_d_h,			3),
+	GROUP(pwm_i_h,			3),
+	GROUP(pdm_dclk_h,		3),
+	GROUP(pdm_din0_h,		3),
+	GROUP(pdm_din1_h,		3),
+
+	/* Bank H func4 */
+	GROUP(mclk_1_h,			4),
+	GROUP(tdm_sclk1_h,		4),
+	GROUP(tdm_fs1_h,		4),
+	GROUP(tdm_d2_h,			4),
+	GROUP(tdm_d3_h,			4),
+	GROUP(tdm_d4_h,			4),
+
+	/* Bank H func5 */
+	GROUP(spi_a_miso_h,		5),
+	GROUP(spi_a_mosi_h,		5),
+	GROUP(spi_a_clk_h,		5),
+	GROUP(spi_a_ss0_h,		5),
+
+	/* Bank H func6 */
+	GROUP(gen_clk_h,		6),
+	GROUP(tsin_b1_clk,		6),
+	GROUP(tsin_b1_sop,		6),
+	GROUP(tsin_b1_valid,		6),
+	GROUP(tsin_b1_d0,		6),
+
+	/* Bank X func1 */
+	GROUP(sdio_d0,			1),
+	GROUP(sdio_d1,			1),
+	GROUP(sdio_d2,			1),
+	GROUP(sdio_d3,			1),
+	GROUP(sdio_clk,			1),
+	GROUP(sdio_cmd,			1),
+	GROUP(pwm_a_x,			1),
+	GROUP(pwm_f_x,			1),
+	GROUP(tdm_d1,			1),
+	GROUP(tdm_d0,			1),
+	GROUP(tdm_fs0,			1),
+	GROUP(tdm_sclk0,		1),
+	GROUP(uart_a_tx,		1),
+	GROUP(uart_a_rx,		1),
+	GROUP(uart_a_cts,		1),
+	GROUP(uart_a_rts,		1),
+	GROUP(pwm_e_x,			1),
+	GROUP(i2c1_sda_x,		1),
+	GROUP(i2c1_scl_x,		1),
+	GROUP(pwm_b_x,			1),
+
+	/* Bank X func2 */
+	GROUP(pdm_din0_x,		2),
+	GROUP(pdm_din1_x,		2),
+	GROUP(pdm_dclk_x,		2),
+
+	/* Bank X func3 */
+	GROUP(spi_a_mosi_x,		3),
+	GROUP(spi_a_miso_x,		3),
+	GROUP(spi_a_ss0_x,		3),
+	GROUP(spi_a_clk_x,		3),
+
+	/* Bank X func4 */
+	GROUP(pwm_c_x,			4),
+	GROUP(i2c_slave_scl,		4),
+	GROUP(i2c_slave_sda,		4),
+
+	/* Bank X func5 */
+	GROUP(i2c3_sda_x,		5),
+	GROUP(i2c3_scl_x,		5),
+
+	/* Bank Z func1 */
+	GROUP(tdm_fs2,			1),
+	GROUP(tdm_sclk2,		1),
+	GROUP(tdm_d4_z,			1),
+	GROUP(tdm_d5_z,			1),
+	GROUP(tdm_d6,			1),
+	GROUP(tdm_d7,			1),
+	GROUP(mclk_2,			1),
+	GROUP(spdif_out_z,		1),
+	GROUP(dtv_a_if_agc_z10,		1),
+	GROUP(uart_e_tx_z11,		1),
+	GROUP(uart_e_rx_z12,		1),
+
+	/* Bank Z func2 */
+	GROUP(tsin_a_clk,		2),
+	GROUP(tsin_a_sop,		2),
+	GROUP(tsin_a_valid,		2),
+	GROUP(tsin_a_din0,		2),
+	GROUP(dtv_a_if_agc_z6,		2),
+	GROUP(dtv_b_if_agc,		2),
+	GROUP(i2c3_sda_z,		2),
+	GROUP(i2c3_scl_z,		2),
+	GROUP(dtv_a_rf_agc,		2),
+	GROUP(dtv_b_rf_agc,		2),
+
+	/* Bank Z func3 */
+	GROUP(sdcard_d0_z,		3),
+	GROUP(sdcard_d1_z,		3),
+	GROUP(sdcard_d2_z,		3),
+	GROUP(sdcard_d3_z,		3),
+	GROUP(sdcard_clk_z,		3),
+	GROUP(sdcard_cmd_z,		3),
+	GROUP(uart_e_tx_z8,		3),
+	GROUP(uart_e_rx_z9,		3),
+	GROUP(pdm_din1_z,		3),
+	GROUP(pdm_din0_z,		3),
+	GROUP(pdm_dclk_z,		3),
+
+	/* Bank Z func4 */
+	GROUP(spi_a_miso_z,		4),
+	GROUP(spi_a_mosi_z,		4),
+	GROUP(spi_a_clk_z,		4),
+	GROUP(spi_a_ss0_z,		4),
+	GROUP(spi_a_ss1_z,		4),
+	GROUP(spi_a_ss2_z,		4),
+	GROUP(i2c4_scl_z,		4),
+	GROUP(i2c4_sda_z,		4),
+
+	/* Bank Z func5 */
+	GROUP(uart_d_tx_z,		5),
+	GROUP(uart_d_rx_z,		5),
+	GROUP(uart_d_cts_z,		5),
+	GROUP(uart_d_rts_z,		5),
+	GROUP(pwm_g_z,			5),
+	GROUP(pwm_f_z,			5),
+	GROUP(pwm_e_z,			5),
+	GROUP(tsin_b_clk_z,		5),
+	GROUP(tsin_b_sop_z,		5),
+	GROUP(tsin_b_valid_z,		5),
+	GROUP(tsin_b_d0_z,		5),
+
+	/* Bank Z func6 */
+	GROUP(s2_demod_gpio7,		6),
+	GROUP(s2_demod_gpio6,		6),
+	GROUP(s2_demod_gpio5,		6),
+	GROUP(s2_demod_gpio4,		6),
+	GROUP(s2_demod_gpio3,		6),
+	GROUP(s2_demod_gpio2,		6),
+	GROUP(diseqc_out,		6),
+	GROUP(s2_demod_gpio1,		6),
+	GROUP(s2_demod_gpio0,		6),
+
+	/* Bank Z func7 */
+	GROUP(gen_clk_z9,		7),
+	GROUP(gen_clk_z12,		7),
+};
+
+static const char * const gpio_periphs_groups[] = {
+	"GPIOE_0", "GPIOE_1",
+
+	"GPIOB_0", "GPIOB_1", "GPIOB_2", "GPIOB_3", "GPIOB_4", "GPIOB_5",
+	"GPIOB_6", "GPIOB_7", "GPIOB_8", "GPIOB_9", "GPIOB_10", "GPIOB_11",
+	"GPIOB_12", "GPIOB_13",
+
+	"GPIOC_0", "GPIOC_1", "GPIOC_2", "GPIOC_3", "GPIOC_4", "GPIOC_5",
+	"GPIOC_6", "GPIOC_7",
+
+	"GPIOD_0", "GPIOD_1", "GPIOD_2", "GPIOD_3", "GPIOD_4", "GPIOD_5",
+	"GPIOD_6", "GPIOD_7", "GPIOD_8", "GPIOD_9", "GPIOD_10", "GPIOD_11",
+
+	"GPIOH_0", "GPIOH_1", "GPIOH_2", "GPIOH_3", "GPIOH_4", "GPIOH_5",
+	"GPIOH_6", "GPIOH_7", "GPIOH_8", "GPIOH_9", "GPIOH_10", "GPIOH_11",
+
+	"GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", "GPIOX_4", "GPIOX_5",
+	"GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9", "GPIOX_10", "GPIOX_11",
+	"GPIOX_12", "GPIOX_13", "GPIOX_14", "GPIOX_15", "GPIOX_16", "GPIOX_17",
+	"GPIOX_18", "GPIOX_19",
+
+	"GPIOZ_0", "GPIOZ_1", "GPIOZ_2", "GPIOZ_3", "GPIOZ_4", "GPIOZ_5",
+	"GPIOZ_6", "GPIOZ_7", "GPIOZ_8", "GPIOZ_9", "GPIOZ_10",
+	"GPIOZ_11", "GPIOZ_12",
+
+	"GPIO_TEST_N",
+};
+
+static const char * const i2c0_groups[] = {
+	"i2c0_sda", "i2c0_scl",
+};
+
+static const char * const i2c1_groups[] = {
+	"i2c1_sda_c", "i2c1_scl_c",
+	"i2c1_sda_d", "i2c1_scl_d",
+	"i2c1_sda_h", "i2c1_scl_h",
+	"i2c1_sda_x", "i2c1_scl_x",
+};
+
+static const char * const i2c2_groups[] = {
+	"i2c2_sda_d", "i2c2_scl_d",
+	"i2c2_sda_h8", "i2c2_scl_h9",
+	"i2c2_sda_h0", "i2c2_scl_h1l,"
+};
+
+static const char * const i2c3_groups[] = {
+	"i2c3_sda_x", "i2c3_scl_x",
+	"i2c3_sda_z", "i2c3_scl_z",
+};
+
+static const char * const i2c4_groups[] = {
+	"i2c4_sda_c", "i2c4_scl_c",
+	"i2c4_sda_d", "i2c4_scl_d",
+	"i2c4_scl_z", "i2c4_sda_z",
+};
+
+static const char * const uart_a_groups[] = {
+	"uart_a_tx", "uart_a_rx", "uart_a_cts", "uart_a_rts",
+};
+
+static const char * const uart_b_groups[] = {
+	"uart_b_tx_e", "uart_b_rx_e", "uart_b_rx_c", "uart_b_tx_c",
+	"uart_b_tx_d", "uart_b_rx_d", "uart_b_cts_d", "uart_b_rts_d",
+};
+
+static const char * const uart_c_groups[] = {
+	"uart_c_tx", "uart_c_rx",
+};
+
+static const char * const uart_d_groups[] = {
+	"uart_d_tx_h", "uart_d_rx_h", "uart_d_cts_h", "uart_d_rts_h",
+	"uart_d_tx_z", "uart_d_rx_z", "uart_d_cts_z", "uart_d_rts_z",
+};
+
+static const char * const uart_e_groups[] = {
+	"uart_e_tx_h", "uart_e_rx_h", "uart_e_tx_z11", "uart_e_rx_z12",
+	"uart_e_tx_z8", "uart_e_rx_z9",
+};
+
+static const char * const emmc_groups[] = {
+	"emmc_nand_d0", "emmc_nand_d1", "emmc_nand_d2", "emmc_nand_d3",
+	"emmc_nand_d4", "emmc_nand_d5", "emmc_nand_d6", "emmc_nand_d7",
+	"emmc_clk", "emmc_rst", "emmc_cmd", "emmc_nand_ds",
+};
+
+static const char * const nand_groups[] = {
+	"emmc_nand_d0", "emmc_nand_d1", "emmc_nand_d2", "emmc_nand_d3",
+	"emmc_nand_d4", "emmc_nand_d5", "emmc_nand_d6", "emmc_nand_d7",
+	"nand_wen_clk", "nand_ale", "nand_ren_wr", "nand_cle", "nand_ce0",
+};
+
+static const char * const spif_groups[] = {
+	"spif_hold", "spif_mo", "spif_mi", "spif_clk", "spif_wp",
+	"spif_cs",
+};
+
+static const char * const sdcard_groups[] = {
+	"sdcard_d0_c", "sdcard_d1_c", "sdcard_d2_c", "sdcard_d3_c",
+	"sdcard_clk_c", "sdcard_cmd_c", "sdcard_cd",
+	"sdcard_d0_z", "sdcard_d1_z", "sdcard_d2_z", "sdcard_d3_z",
+	"sdcard_clk_z", "sdcard_cmd_z",
+};
+
+static const char * const jtag_1_groups[] = {
+	"jtag_1_clk", "jtag_1_tms", "jtag_1_tdi", "jtag_1_tdo",
+};
+
+static const char * const jtag_2_groups[] = {
+	"jtag_2_tdo", "jtag_2_tdi", "jtag_2_clk", "jtag_2_tms",
+};
+
+static const char * const pdm_groups[] = {
+	"pdm_din1_c", "pdm_din0_c", "pdm_dclk_c",
+	"pdm_dclk_d", "pdm_din0_d", "pdm_din1_d",
+	"pdm_dclk_h", "pdm_din0_h", "pdm_din1_h",
+	"pdm_din0_x", "pdm_din1_x", "pdm_dclk_x",
+	"pdm_din1_z", "pdm_din0_z", "pdm_dclk_z",
+};
+
+static const char * const iso7816_groups[] = {
+	"iso7816_clk_c", "iso7816_data_c",
+	"iso7816_clk_h", "iso7816_data_h",
+};
+
+static const char * const tdm_groups[] = {
+	"tdm_d2_c", "tdm_d3_c", "tdm_fs1_c", "tdm_d4_c", "tdm_d5_c",
+	"tdm_fs1_d", "tdm_d4_d", "tdm_d3_d", "tdm_d2_d", "tdm_sclk1_d",
+	"tdm_sclk1_h", "tdm_fs1_h", "tdm_d2_h", "tdm_d3_h", "tdm_d4_h",
+	"tdm_d1", "tdm_d0", "tdm_fs0", "tdm_sclk0", "tdm_fs2", "tdm_sclk2",
+	"tdm_d4_z", "tdm_d5_z", "tdm_d6", "tdm_d7",
+};
+
+static const char * const mclk_1_groups[] = {
+	"mclk_1_c", "mclk_1_d", "mclk_1_h", "mclk_2",
+};
+
+static const char * const mclk_2_groups[] = {
+	"mclk_2",
+};
+
+static const char * const remote_out_groups[] = {
+	"remote_out",
+};
+
+static const char * const remote_in_groups[] = {
+	"remote_in",
+};
+
+static const char * const clk12_24_groups[] = {
+	"clk12_24",
+};
+
+static const char * const clk_32k_in_groups[] = {
+	"clk_32k_in",
+};
+
+static const char * const pwm_a_hiz_groups[] = {
+	"pwm_a_hiz",
+};
+
+static const char * const pwm_b_hiz_groups[] = {
+	"pwm_b_hiz",
+};
+
+static const char * const pwm_c_hiz_groups[] = {
+	"pwm_c_hiz",
+};
+
+static const char * const pwm_g_hiz_groups[] = {
+	"pwm_g_hiz",
+};
+
+static const char * const pwm_a_groups[] = {
+	"pwm_a_d",
+};
+
+static const char * const pwm_b_groups[] = {
+	"pwm_b_d", "pwm_b_x",
+};
+
+static const char * const pwm_c_groups[] = {
+	"pwm_c_d", "pwm_c_x",
+};
+
+static const char * const pwm_d_groups[] = {
+	"pwm_d_d", "pwm_d_h",
+};
+
+static const char * const pwm_e_groups[] = {
+	"pwm_e_x", "pwm_e_z",
+};
+
+static const char * const pwm_f_groups[] = {
+	"pwm_f_x", "pwm_f_z",
+};
+
+static const char * const pwm_g_groups[] = {
+	"pwm_g_d", "pwm_g_z",
+};
+
+static const char * const pwm_h_groups[] = {
+	"pwm_h",
+};
+
+static const char * const pwm_i_groups[] = {
+	"pwm_i_d", "pwm_i_h"
+};
+
+static const char * const pwm_j_groups[] = {
+	"pwm_j",
+};
+
+static const char * const mic_mute_groups[] = {
+	"mic_mute_en", "mic_mute_key",
+};
+
+static const char * const hdmitx_groups[] = {
+	"hdmitx_sda", "hdmitx_sck", "hdmitx_hpd_in",
+};
+
+static const char * const ao_cec_a_groups[] = {
+	"ao_cec_a",
+};
+
+static const char * const ao_cec_b_groups[] = {
+	"ao_cec_b",
+};
+
+static const char * const spdif_out_groups[] = {
+	"spdif_out_h", "spdif_out_z",
+};
+
+static const char * const spdif_in_groups[] = {
+	"spdif_in",
+};
+
+static const char * const eth_groups[] = {
+	"eth_link_led", "eth_act_led",
+};
+
+static const char * const spi_a_groups[] = {
+	"spi_a_miso_h", "spi_a_mosi_h", "spi_a_clk_h", "spi_a_ss0_h",
+
+	"spi_a_mosi_x", "spi_a_miso_x", "spi_a_ss0_x", "spi_a_clk_x",
+
+	"spi_a_miso_z", "spi_a_mosi_z", "spi_a_clk_z", "spi_a_ss0_z",
+	"spi_a_ss1_z", "spi_a_ss2_z",
+};
+
+static const char * const gen_clk_groups[] = {
+	"gen_clk_h", "gen_clk_z9", "gen_clk_z12",
+};
+
+static const char * const sdio_groups[] = {
+	"sdio_d0", "sdio_d1", "sdio_d2", "sdio_d3", "sdio_clk", "sdio_cmd",
+};
+
+static const char * const i2c_slave_groups[] = {
+	"i2c_slave_scl", "i2c_slave_sda",
+};
+
+static const char * const dtv_groups[] = {
+	"dtv_a_if_agc_z10", "dtv_a_if_agc_z6", "dtv_b_if_agc",
+	"dtv_a_rf_agc", "dtv_b_rf_agc",
+};
+
+static const char * const tsin_a_groups[] = {
+	"tsin_a_clk", "tsin_a_sop", "tsin_a_valid", "tsin_a_din0",
+};
+
+static const char * const tsin_b_groups[] = {
+	"tsin_b_clk_c", "tsin_b_sop_c", "tsin_b_valid_c", "tsin_b_d0_c",
+	"tsin_b_clk_z", "tsin_b_sop_z", "tsin_b_valid_z", "tsin_b_d0_z",
+};
+
+static const char * const tsin_b1_groups[] = {
+	"tsin_b1_clk", "tsin_b1_sop", "tsin_b1_valid", "tsin_b1_d0",
+};
+
+static const char * const diseqc_out_groups[] = {
+	"diseqc_out",
+};
+
+static const char * const s2_demod_groups[] = {
+	"s2_demod_gpio7", "s2_demod_gpio6", "s2_demod_gpio5", "s2_demod_gpio4",
+	"s2_demod_gpio3", "s2_demod_gpio2", "s2_demod_gpio1", "s2_demod_gpio0",
+};
+
+static struct meson_pmx_func meson_s4_periphs_functions[] = {
+	FUNCTION(gpio_periphs),
+	FUNCTION(i2c0),
+	FUNCTION(i2c1),
+	FUNCTION(i2c2),
+	FUNCTION(i2c3),
+	FUNCTION(i2c4),
+	FUNCTION(uart_a),
+	FUNCTION(uart_b),
+	FUNCTION(uart_c),
+	FUNCTION(uart_d),
+	FUNCTION(uart_e),
+	FUNCTION(emmc),
+	FUNCTION(nand),
+	FUNCTION(spif),
+	FUNCTION(sdcard),
+	FUNCTION(jtag_1),
+	FUNCTION(jtag_2),
+	FUNCTION(pdm),
+	FUNCTION(iso7816),
+	FUNCTION(tdm),
+	FUNCTION(mclk_1),
+	FUNCTION(mclk_2),
+	FUNCTION(remote_out),
+	FUNCTION(remote_in),
+	FUNCTION(clk12_24),
+	FUNCTION(clk_32k_in),
+	FUNCTION(pwm_a_hiz),
+	FUNCTION(pwm_b_hiz),
+	FUNCTION(pwm_c_hiz),
+	FUNCTION(pwm_g_hiz),
+	FUNCTION(pwm_a),
+	FUNCTION(pwm_b),
+	FUNCTION(pwm_c),
+	FUNCTION(pwm_d),
+	FUNCTION(pwm_e),
+	FUNCTION(pwm_f),
+	FUNCTION(pwm_g),
+	FUNCTION(pwm_h),
+	FUNCTION(pwm_i),
+	FUNCTION(pwm_j),
+	FUNCTION(mic_mute),
+	FUNCTION(hdmitx),
+	FUNCTION(ao_cec_a),
+	FUNCTION(ao_cec_b),
+	FUNCTION(spdif_out),
+	FUNCTION(spdif_in),
+	FUNCTION(eth),
+	FUNCTION(spi_a),
+	FUNCTION(gen_clk),
+	FUNCTION(sdio),
+	FUNCTION(i2c_slave),
+	FUNCTION(dtv),
+	FUNCTION(tsin_a),
+	FUNCTION(tsin_b),
+	FUNCTION(tsin_b1),
+	FUNCTION(diseqc_out),
+	FUNCTION(s2_demod),
+};
+
+static struct meson_bank meson_s4_periphs_banks[] = {
+	/* name  first  last  irq  pullen  pull  dir  out  in */
+	BANK_DS("B", GPIOB_0,    GPIOB_13,  0, 13,
+		0x63,  0,  0x64,  0,  0x62, 0,  0x61, 0,  0x60, 0, 0x67, 0),
+	BANK_DS("C", GPIOC_0,    GPIOC_7,   14, 21,
+		0x53,  0,  0x54,  0,  0x52, 0,  0x51, 0,  0x50, 0, 0x57, 0),
+	BANK_DS("E", GPIOE_0,    GPIOE_1,   22, 23,
+		0x43,  0,  0x44,  0,  0x42, 0,  0x41, 0,  0x40, 0, 0x47, 0),
+	BANK_DS("D", GPIOD_0,    GPIOD_11,  24, 35,
+		0x33,  0,  0x34,  0,  0x32, 0,  0x31, 0,  0x30, 0, 0x37, 0),
+	BANK_DS("H", GPIOH_0,    GPIOH_11,  36, 47,
+		0x23,  0,  0x24,  0,  0x22, 0,  0x21, 0,  0x20, 0, 0x27, 0),
+	BANK_DS("X", GPIOX_0,    GPIOX_19,   48, 67,
+		0x13,  0,  0x14,  0,  0x12, 0,  0x11, 0,  0x10, 0, 0x17, 0),
+	BANK_DS("Z", GPIOZ_0,    GPIOZ_12,  68, 80,
+		0x03,  0,  0x04,  0,  0x02, 0,  0x01, 0,  0x00, 0, 0x07, 0),
+	BANK_DS("TEST_N", GPIO_TEST_N,    GPIO_TEST_N,   -1, -1,
+		0x83,  0,  0x84,  0,  0x82, 0,  0x81,  0, 0x80, 0, 0x87, 0),
+};
+
+static struct meson_pmx_bank meson_s4_periphs_pmx_banks[] = {
+	/*name	            first	 lask        reg offset*/
+	BANK_PMX("B",      GPIOB_0,     GPIOB_13,    0x00, 0),
+	BANK_PMX("C",      GPIOC_0,     GPIOC_7,     0x9,  0),
+	BANK_PMX("E",      GPIOE_0,     GPIOE_1,     0x12, 0),
+	BANK_PMX("D",      GPIOD_0,     GPIOD_11,    0x10, 0),
+	BANK_PMX("H",      GPIOH_0,     GPIOH_11,    0xb,  0),
+	BANK_PMX("X",      GPIOX_0,     GPIOX_19,    0x3,  0),
+	BANK_PMX("Z",      GPIOZ_0,     GPIOZ_12,    0x6,  0),
+	BANK_PMX("TEST_N", GPIO_TEST_N, GPIO_TEST_N, 0xf,  0)
+};
+
+static struct meson_axg_pmx_data meson_s4_periphs_pmx_banks_data = {
+	.pmx_banks	= meson_s4_periphs_pmx_banks,
+	.num_pmx_banks	= ARRAY_SIZE(meson_s4_periphs_pmx_banks),
+};
+
+static struct meson_pinctrl_data meson_s4_periphs_pinctrl_data = {
+	.name		= "periphs-banks",
+	.pins		= meson_s4_periphs_pins,
+	.groups		= meson_s4_periphs_groups,
+	.funcs		= meson_s4_periphs_functions,
+	.banks		= meson_s4_periphs_banks,
+	.num_pins	= ARRAY_SIZE(meson_s4_periphs_pins),
+	.num_groups	= ARRAY_SIZE(meson_s4_periphs_groups),
+	.num_funcs	= ARRAY_SIZE(meson_s4_periphs_functions),
+	.num_banks	= ARRAY_SIZE(meson_s4_periphs_banks),
+	.pmx_ops	= &meson_axg_pmx_ops,
+	.pmx_data	= &meson_s4_periphs_pmx_banks_data,
+	.parse_dt	= &meson_a1_parse_dt_extra,
+};
+
+static const struct of_device_id meson_s4_pinctrl_dt_match[] = {
+	{
+		.compatible = "amlogic,meson-s4-periphs-pinctrl",
+		.data = &meson_s4_periphs_pinctrl_data,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, meson_s4_pinctrl_dt_match);
+
+static struct platform_driver meson_s4_pinctrl_driver = {
+	.probe  = meson_pinctrl_probe,
+	.driver = {
+		.name	= "meson-s4-pinctrl",
+		.of_match_table = meson_s4_pinctrl_dt_match,
+	},
+};
+module_platform_driver(meson_s4_pinctrl_driver);
+
+MODULE_LICENSE("Dual BSD/GPL");
-- 
2.34.1



From christianshewitt at gmail.com  Wed Jan 12 20:17:43 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Thu, 13 Jan 2022 04:17:43 +0000
Subject: [PATCH 0/3] arm64: dts: meson: minor P212/VIM1 fixups
Message-ID: <20220113041746.16040-1-christianshewitt@gmail.com>

The P212 (S905X reference board) dts is used with a number of no-name
Android boxes that follow the reference design, and users had noticed
that BT worked but WiFi did not. While investigating and adding the
missing WiFi bits to the dtsi for testing I spotted that VIM1 inherits
from the p212 dtsi and has the BT node duplicated, so we can clean that
up too. And since we're tidying things, the pwm_ef node can be moved
to maintain normal alpha sorting.

Christian Hewitt (3):
  arm64: dts: meson: add Broadcom WiFi to P212 dtsi
  arm64: dts: meson: move pwm_ef node in P212 dtsi
  arm64: dts: meson: remove Broadcom WiFi/BT nodes from Khadas VIM1

 .../amlogic/meson-gxl-s905x-khadas-vim.dts    | 19 ---------------
 .../dts/amlogic/meson-gxl-s905x-p212.dtsi     | 23 +++++++++++--------
 2 files changed, 14 insertions(+), 28 deletions(-)

-- 
2.17.1



From christianshewitt at gmail.com  Wed Jan 12 20:17:44 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Thu, 13 Jan 2022 04:17:44 +0000
Subject: [PATCH 1/3] arm64: dts: meson: add Broadcom WiFi to P212 dtsi
In-Reply-To: <20220113041746.16040-1-christianshewitt@gmail.com>
References: <20220113041746.16040-1-christianshewitt@gmail.com>
Message-ID: <20220113041746.16040-2-christianshewitt@gmail.com>

The P212 has a combined WiFi/BT module. The BT side is already enabled
in the dtsi but the WiFi side is not. Let's tweak SDIO speed (in-line
with other GXL/GXM devices) and enable the WiFi module.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
index 05cb2f5e5c36..c635e5858929 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
@@ -113,7 +113,7 @@
 
 	bus-width = <4>;
 	cap-sd-highspeed;
-	max-frequency = <50000000>;
+	max-frequency = <100000000>;
 
 	non-removable;
 	disable-wp;
@@ -125,6 +125,11 @@
 
 	vmmc-supply = <&vddao_3v3>;
 	vqmmc-supply = <&vddio_boot>;
+
+	brcmf: wifi at 1 {
+		reg = <1>;
+		compatible = "brcm,bcm4329-fmac";
+	};
 };
 
 /* SD card */
-- 
2.17.1



From christianshewitt at gmail.com  Wed Jan 12 20:17:45 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Thu, 13 Jan 2022 04:17:45 +0000
Subject: [PATCH 2/3] arm64: dts: meson: move pwm_ef node in P212 dtsi
In-Reply-To: <20220113041746.16040-1-christianshewitt@gmail.com>
References: <20220113041746.16040-1-christianshewitt@gmail.com>
Message-ID: <20220113041746.16040-3-christianshewitt@gmail.com>

Cosmetic-only change to move/alpha-sort the node.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 .../boot/dts/amlogic/meson-gxl-s905x-p212.dtsi   | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
index c635e5858929..b3d7b8613d6d 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
@@ -97,6 +97,14 @@
 	pinctrl-names = "default";
 };
 
+&pwm_ef {
+	status = "okay";
+	pinctrl-0 = <&pwm_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&clkc CLKID_FCLK_DIV4>;
+	clock-names = "clkin0";
+};
+
 &saradc {
 	status = "okay";
 	vref-supply = <&vddio_ao18>;
@@ -170,14 +178,6 @@
 	vqmmc-supply = <&vddio_boot>;
 };
 
-&pwm_ef {
-	status = "okay";
-	pinctrl-0 = <&pwm_e_pins>;
-	pinctrl-names = "default";
-	clocks = <&clkc CLKID_FCLK_DIV4>;
-	clock-names = "clkin0";
-};
-
 /* This is connected to the Bluetooth module: */
 &uart_A {
 	status = "okay";
-- 
2.17.1



From christianshewitt at gmail.com  Wed Jan 12 20:17:46 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Thu, 13 Jan 2022 04:17:46 +0000
Subject: [PATCH 3/3] arm64: dts: meson: remove Broadcom WiFi/BT nodes from
 Khadas VIM1
In-Reply-To: <20220113041746.16040-1-christianshewitt@gmail.com>
References: <20220113041746.16040-1-christianshewitt@gmail.com>
Message-ID: <20220113041746.16040-4-christianshewitt@gmail.com>

The Broadcom WiFi/BT SDIO nodes are now inherited from the P212 common dtsi
so we can remove them from the VIM1 board dts.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 .../amlogic/meson-gxl-s905x-khadas-vim.dts    | 19 -------------------
 1 file changed, 19 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
index 6ab1cc125b96..108232a5aa2e 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
@@ -217,25 +217,6 @@
 	pinctrl-0 = <&pwm_e_pins>, <&pwm_f_clk_pins>;
 };
 
-&sd_emmc_a {
-	max-frequency = <100000000>;
-
-	brcmf: wifi at 1 {
-		reg = <1>;
-		compatible = "brcm,bcm4329-fmac";
-	};
-};
-
-&uart_A {
-	bluetooth {
-		compatible = "brcm,bcm43438-bt";
-		shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
-		max-speed = <2000000>;
-		clocks = <&wifi32k>;
-		clock-names = "lpo";
-	};
-};
-
 /* This is brought out on the Linux_RX (18) and Linux_TX (19) pins: */
 &uart_AO {
 	status = "okay";
-- 
2.17.1



From christianshewitt at gmail.com  Wed Jan 12 20:45:46 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Thu, 13 Jan 2022 04:45:46 +0000
Subject: [PATCH] arm64: dts: meson: add audio playback to P212
Message-ID: <20220113044546.16856-1-christianshewitt@gmail.com>

Add initial audio support limited to HDMI i2s.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
The P212 dts is widely used with Android box devices that follow the
reference design. The real P212 development board probably has many
more audio capabilities, but as a minimum we can enable HDMI output
and help box users too.

 .../boot/dts/amlogic/meson-gxl-s905x-p212.dts | 40 +++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
index 2602940c2077..a39830379c74 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "meson-gxl-s905x-p212.dtsi"
+#include <dt-bindings/sound/meson-aiu.h>
 
 / {
 	compatible = "amlogic,p212", "amlogic,s905x", "amlogic,meson-gxl";
@@ -32,6 +33,45 @@
 			};
 		};
 	};
+
+	sound {
+		compatible = "amlogic,gx-sound-card";
+		model = "S905X-P212";
+		assigned-clocks = <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>,
+				  <&clkc CLKID_MPLL2>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
+			dai-format = "i2s";
+			mclk-fs = <256>;
+
+			codec-0 {
+				sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
+			};
+		};
+
+		dai-link-2 {
+			sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
+
+			codec-0 {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&aiu {
+	status = "okay";
 };
 
 &cec_AO {
-- 
2.17.1



From jiasheng at iscas.ac.cn  Wed Jan 12 22:56:36 2022
From: jiasheng at iscas.ac.cn (Jiasheng Jiang)
Date: Thu, 13 Jan 2022 14:56:36 +0800
Subject: [PATCH] media: meson: vdec: potential dereference of null pointer
Message-ID: <20220113065636.1198072-1-jiasheng@iscas.ac.cn>

As the possible failure of the kzalloc(), the 'new_ts' could be NULL
pointer.
Therefore, it should be better to check it in order to avoid the
dereference of the NULL pointer.
Also, the caller esparser_queue() needs to deal with the return value of
the amvdec_add_ts().

Fixes: 876f123b8956 ("media: meson: vdec: bring up to compliance")
Signed-off-by: Jiasheng Jiang <jiasheng at iscas.ac.cn>
---
 drivers/staging/media/meson/vdec/esparser.c     | 7 ++++++-
 drivers/staging/media/meson/vdec/vdec_helpers.c | 8 ++++++--
 drivers/staging/media/meson/vdec/vdec_helpers.h | 4 ++--
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
index db7022707ff8..86ccc8937afc 100644
--- a/drivers/staging/media/meson/vdec/esparser.c
+++ b/drivers/staging/media/meson/vdec/esparser.c
@@ -328,7 +328,12 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
 
 	offset = esparser_get_offset(sess);
 
-	amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
+	ret = amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
+	if (ret) {
+		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+		return ret;
+	}
+
 	dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X flags = %08X\n",
 		vb->timestamp, payload_size, offset, vbuf->flags);
 
diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c
index 203d7afa085d..7d2a75653250 100644
--- a/drivers/staging/media/meson/vdec/vdec_helpers.c
+++ b/drivers/staging/media/meson/vdec/vdec_helpers.c
@@ -227,13 +227,16 @@ int amvdec_set_canvases(struct amvdec_session *sess,
 }
 EXPORT_SYMBOL_GPL(amvdec_set_canvases);
 
-void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
-		   struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
+int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
+		  struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
 {
 	struct amvdec_timestamp *new_ts;
 	unsigned long flags;
 
 	new_ts = kzalloc(sizeof(*new_ts), GFP_KERNEL);
+	if (!new_ts)
+		return -ENOMEM;
+
 	new_ts->ts = ts;
 	new_ts->tc = tc;
 	new_ts->offset = offset;
@@ -242,6 +245,7 @@ void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
 	spin_lock_irqsave(&sess->ts_spinlock, flags);
 	list_add_tail(&new_ts->list, &sess->timestamps);
 	spin_unlock_irqrestore(&sess->ts_spinlock, flags);
+	return 0;
 }
 EXPORT_SYMBOL_GPL(amvdec_add_ts);
 
diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.h b/drivers/staging/media/meson/vdec/vdec_helpers.h
index 88137d15aa3a..4bf3e61d081b 100644
--- a/drivers/staging/media/meson/vdec/vdec_helpers.h
+++ b/drivers/staging/media/meson/vdec/vdec_helpers.h
@@ -56,8 +56,8 @@ void amvdec_dst_buf_done_offset(struct amvdec_session *sess,
  * @offset: offset in the VIFIFO where the associated packet was written
  * @flags: the vb2_v4l2_buffer flags
  */
-void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
-		   struct v4l2_timecode tc, u32 offset, u32 flags);
+int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
+		  struct v4l2_timecode tc, u32 offset, u32 flags);
 void amvdec_remove_ts(struct amvdec_session *sess, u64 ts);
 
 /**
-- 
2.25.1



From jiasheng at iscas.ac.cn  Wed Jan 12 22:59:28 2022
From: jiasheng at iscas.ac.cn (Jiasheng Jiang)
Date: Thu, 13 Jan 2022 14:59:28 +0800
Subject: [PATCH v3] media: meson: vdec: potential dereference of null pointer
Message-ID: <20220113065928.1198125-1-jiasheng@iscas.ac.cn>

As the possible failure of the kzalloc(), the 'new_ts' could be NULL
pointer.
Therefore, it should be better to check it in order to avoid the
dereference of the NULL pointer.
Also, the caller esparser_queue() needs to deal with the return value of
the amvdec_add_ts().

Fixes: 876f123b8956 ("media: meson: vdec: bring up to compliance")
Signed-off-by: Jiasheng Jiang <jiasheng at iscas.ac.cn>
---
Changelog

v1 -> v2

* Change 1. Change the return type of amvdec_add_ts from void to int.
* Change 2. Return -ENOMEN if alloc fail and return 0 if not.
* Change 3. Modify the caller to deal with the error.

v2 -> v3

* Change 1. Fix the indentation and refine the commit message.
---
 drivers/staging/media/meson/vdec/esparser.c     | 7 ++++++-
 drivers/staging/media/meson/vdec/vdec_helpers.c | 8 ++++++--
 drivers/staging/media/meson/vdec/vdec_helpers.h | 4 ++--
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
index db7022707ff8..86ccc8937afc 100644
--- a/drivers/staging/media/meson/vdec/esparser.c
+++ b/drivers/staging/media/meson/vdec/esparser.c
@@ -328,7 +328,12 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
 
 	offset = esparser_get_offset(sess);
 
-	amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
+	ret = amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
+	if (ret) {
+		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+		return ret;
+	}
+
 	dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X flags = %08X\n",
 		vb->timestamp, payload_size, offset, vbuf->flags);
 
diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c
index 203d7afa085d..7d2a75653250 100644
--- a/drivers/staging/media/meson/vdec/vdec_helpers.c
+++ b/drivers/staging/media/meson/vdec/vdec_helpers.c
@@ -227,13 +227,16 @@ int amvdec_set_canvases(struct amvdec_session *sess,
 }
 EXPORT_SYMBOL_GPL(amvdec_set_canvases);
 
-void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
-		   struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
+int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
+		  struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
 {
 	struct amvdec_timestamp *new_ts;
 	unsigned long flags;
 
 	new_ts = kzalloc(sizeof(*new_ts), GFP_KERNEL);
+	if (!new_ts)
+		return -ENOMEM;
+
 	new_ts->ts = ts;
 	new_ts->tc = tc;
 	new_ts->offset = offset;
@@ -242,6 +245,7 @@ void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
 	spin_lock_irqsave(&sess->ts_spinlock, flags);
 	list_add_tail(&new_ts->list, &sess->timestamps);
 	spin_unlock_irqrestore(&sess->ts_spinlock, flags);
+	return 0;
 }
 EXPORT_SYMBOL_GPL(amvdec_add_ts);
 
diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.h b/drivers/staging/media/meson/vdec/vdec_helpers.h
index 88137d15aa3a..4bf3e61d081b 100644
--- a/drivers/staging/media/meson/vdec/vdec_helpers.h
+++ b/drivers/staging/media/meson/vdec/vdec_helpers.h
@@ -56,8 +56,8 @@ void amvdec_dst_buf_done_offset(struct amvdec_session *sess,
  * @offset: offset in the VIFIFO where the associated packet was written
  * @flags: the vb2_v4l2_buffer flags
  */
-void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
-		   struct v4l2_timecode tc, u32 offset, u32 flags);
+int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
+		  struct v4l2_timecode tc, u32 offset, u32 flags);
 void amvdec_remove_ts(struct amvdec_session *sess, u64 ts);
 
 /**
-- 
2.25.1



From jirislaby at kernel.org  Wed Jan 12 23:25:49 2022
From: jirislaby at kernel.org (Jiri Slaby)
Date: Thu, 13 Jan 2022 08:25:49 +0100
Subject: [PATCH V5 2/5] tty: serial: meson: Move request the register
 region.
In-Reply-To: <cad33ab0-26d3-5b78-3bcf-62217aa70871@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
 <20220110104214.25321-3-yu.tu@amlogic.com>
 <01066e66-5d97-ab40-b4a6-99e962b47073@kernel.org>
 <cad33ab0-26d3-5b78-3bcf-62217aa70871@amlogic.com>
Message-ID: <efce614d-c8e6-bb06-e3c1-cb67b26bbc6a@kernel.org>

On 11. 01. 22, 3:48, Yu Tu wrote:
>> And no, do not resend a new version in the next few days. Having v5 in 
>> 20 days is a bit too much. Give maintainers and reviewers some more 
>> space to express themselves.
> I am so sorry if PATCH is sent too frequently, which has disturbed you.
> How often should I send it? Or under what circumstances can I send the 
> next version?

~ one week after the last reply to your previous patchset is about fine. 
You could see that people were still responding to v4 while v5 was 
already on the list.

thanks,
-- 
js


From narmstrong at baylibre.com  Thu Jan 13 00:56:08 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 13 Jan 2022 09:56:08 +0100
Subject: [PATCH v3] media: meson: vdec: potential dereference of null
 pointer
In-Reply-To: <20220113065928.1198125-1-jiasheng@iscas.ac.cn>
References: <20220113065928.1198125-1-jiasheng@iscas.ac.cn>
Message-ID: <9790448d-53bb-cc61-655e-dda70ae97fa3@baylibre.com>

On 13/01/2022 07:59, Jiasheng Jiang wrote:
> As the possible failure of the kzalloc(), the 'new_ts' could be NULL
> pointer.
> Therefore, it should be better to check it in order to avoid the
> dereference of the NULL pointer.
> Also, the caller esparser_queue() needs to deal with the return value of
> the amvdec_add_ts().
> 
> Fixes: 876f123b8956 ("media: meson: vdec: bring up to compliance")
> Signed-off-by: Jiasheng Jiang <jiasheng at iscas.ac.cn>
> ---
> Changelog
> 
> v1 -> v2
> 
> * Change 1. Change the return type of amvdec_add_ts from void to int.
> * Change 2. Return -ENOMEN if alloc fail and return 0 if not.
> * Change 3. Modify the caller to deal with the error.
> 
> v2 -> v3
> 
> * Change 1. Fix the indentation and refine the commit message.
> ---
>  drivers/staging/media/meson/vdec/esparser.c     | 7 ++++++-
>  drivers/staging/media/meson/vdec/vdec_helpers.c | 8 ++++++--
>  drivers/staging/media/meson/vdec/vdec_helpers.h | 4 ++--
>  3 files changed, 14 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
> index db7022707ff8..86ccc8937afc 100644
> --- a/drivers/staging/media/meson/vdec/esparser.c
> +++ b/drivers/staging/media/meson/vdec/esparser.c
> @@ -328,7 +328,12 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
>  
>  	offset = esparser_get_offset(sess);
>  
> -	amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
> +	ret = amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
> +	if (ret) {
> +		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
> +		return ret;
> +	}
> +
>  	dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X flags = %08X\n",
>  		vb->timestamp, payload_size, offset, vbuf->flags);
>  
> diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c
> index 203d7afa085d..7d2a75653250 100644
> --- a/drivers/staging/media/meson/vdec/vdec_helpers.c
> +++ b/drivers/staging/media/meson/vdec/vdec_helpers.c
> @@ -227,13 +227,16 @@ int amvdec_set_canvases(struct amvdec_session *sess,
>  }
>  EXPORT_SYMBOL_GPL(amvdec_set_canvases);
>  
> -void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> -		   struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
> +int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> +		  struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
>  {
>  	struct amvdec_timestamp *new_ts;
>  	unsigned long flags;
>  
>  	new_ts = kzalloc(sizeof(*new_ts), GFP_KERNEL);
> +	if (!new_ts)
> +		return -ENOMEM;
> +
>  	new_ts->ts = ts;
>  	new_ts->tc = tc;
>  	new_ts->offset = offset;
> @@ -242,6 +245,7 @@ void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
>  	spin_lock_irqsave(&sess->ts_spinlock, flags);
>  	list_add_tail(&new_ts->list, &sess->timestamps);
>  	spin_unlock_irqrestore(&sess->ts_spinlock, flags);
> +	return 0;
>  }
>  EXPORT_SYMBOL_GPL(amvdec_add_ts);
>  
> diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.h b/drivers/staging/media/meson/vdec/vdec_helpers.h
> index 88137d15aa3a..4bf3e61d081b 100644
> --- a/drivers/staging/media/meson/vdec/vdec_helpers.h
> +++ b/drivers/staging/media/meson/vdec/vdec_helpers.h
> @@ -56,8 +56,8 @@ void amvdec_dst_buf_done_offset(struct amvdec_session *sess,
>   * @offset: offset in the VIFIFO where the associated packet was written
>   * @flags: the vb2_v4l2_buffer flags
>   */
> -void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> -		   struct v4l2_timecode tc, u32 offset, u32 flags);
> +int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> +		  struct v4l2_timecode tc, u32 offset, u32 flags);
>  void amvdec_remove_ts(struct amvdec_session *sess, u64 ts);
>  
>  /**
> 

Suggested-by: Neil Armstrong <narmstrong at baylibre.com>
Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>

Neil


From narmstrong at baylibre.com  Thu Jan 13 00:57:47 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 13 Jan 2022 09:57:47 +0100
Subject: [PATCH v2 3/3] arm64: dts: meson-g12-common: add uart_ao_b pins
 muxing
In-Reply-To: <20220112211642.2248901-4-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
 <20220112211642.2248901-4-gary.bisson@boundarydevices.com>
Message-ID: <78e5049b-5e39-ff70-7c77-9f233c7b2fd2@baylibre.com>

On 12/01/2022 22:16, Gary Bisson wrote:
> - RX/TX signals can be mapped on 2 different pairs of pins so supporting
>   both options
> - RTS/CTS signals however only have 1 option available
> 
> Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
> ---
> Changes v1->v2:
> - renamed nodes as suggested by Neil
> 
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: devicetree at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> ---
>  .../boot/dts/amlogic/meson-g12-common.dtsi    | 27 +++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> index af1357c48bee..62350c408e16 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> @@ -1952,6 +1952,33 @@ mux {
>  						};
>  					};
>  
> +					uart_ao_b_2_3_pins: uart-ao-b-2-3 {
> +						mux {
> +							groups = "uart_ao_b_tx_2",
> +								 "uart_ao_b_rx_3";
> +							function = "uart_ao_b";
> +							bias-disable;
> +						};
> +					};
> +
> +					uart_ao_b_8_9_pins: uart-ao-b-8-9 {
> +						mux {
> +							groups = "uart_ao_b_tx_8",
> +								 "uart_ao_b_rx_9";
> +							function = "uart_ao_b";
> +							bias-disable;
> +						};
> +					};
> +
> +					uart_ao_b_cts_rts_pins: uart-ao-b-cts-rts {
> +						mux {
> +							groups = "uart_ao_b_cts",
> +								 "uart_ao_b_rts";
> +							function = "uart_ao_b";
> +							bias-disable;
> +						};
> +					};
> +
>  					pwm_a_e_pins: pwm-a-e {
>  						mux {
>  							groups = "pwm_a_e";
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>

Thanks !
Neil


From narmstrong at baylibre.com  Thu Jan 13 01:02:01 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 13 Jan 2022 10:02:01 +0100
Subject: [PATCH v2 0/3] meson-g12: add pwm and uart pin muxing options
In-Reply-To: <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
Message-ID: <20d3b8da-2a59-a95b-aced-b341093ea5dd@baylibre.com>

Hi,

On 12/01/2022 22:16, Gary Bisson wrote:
> This series adds a few pin muxing options needed for our HW platform (to
> be submitted soon).
> 
> 1- pwm_f: adding missing both GPIOZ_12 & GPIOA_11 options
>   -> tested GPIOA_11 as mipi display backlight
>   -> order for this patch is not alphabetical but follows doc order (to
> match current order)
> 2- uart_ao_b: adding both options for ao_b uart + its rts/cts pins
>   -> tested on custom hw too
> 
> Changes v1->v2:
> - rename uart_ao_b signals as suggested by Neil
> 
> Let me know if you have any questions.

Thanks, I'm waiting for Linus to pick the pinctrl patch and I'll apply the DT patches.

Thanks,
Neil

> 
> Regards,
> Gary
> 
> Gary Bisson (3):
>   pinctrl: meson-g12a: add more pwm_f options
>   arm64: dts: meson-g12-common: add more pwm_f options
>   arm64: dts: meson-g12-common: add uart_ao_b pins muxing
> 
>  .../boot/dts/amlogic/meson-g12-common.dtsi    | 43 +++++++++++++++++++
>  drivers/pinctrl/meson/pinctrl-meson-g12a.c    |  6 ++-
>  2 files changed, 48 insertions(+), 1 deletion(-)
> 



From anders.roxell at linaro.org  Thu Jan 13 02:27:46 2022
From: anders.roxell at linaro.org (Anders Roxell)
Date: Thu, 13 Jan 2022 11:27:46 +0100
Subject: [PATCH] arm64: dts: amlogic: meson-s4-aq222: fix waring for leading 0s
Message-ID: <20220113102746.598763-1-anders.roxell@linaro.org>

When building allmodconfig the following waring shows up:

arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts:21.18-24.4: Warning (unit_address_format): /memory at 00000000: unit name should not have leading 0s

Fixing the waring by dropping all the '0' except one.

Fixes: 1c1475389af0 ("arm64: dts: add support for S4 based Amlogic AQ222")
Signed-off-by: Anders Roxell <anders.roxell at linaro.org>
---
 arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
index a942d7e06d6e..8ffbcb2b1ac5 100644
--- a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
@@ -18,7 +18,7 @@ aliases {
 		serial0 = &uart_B;
 	};
 
-	memory at 00000000 {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x0 0x0 0x0 0x40000000>;
 	};
-- 
2.34.1



From narmstrong at baylibre.com  Thu Jan 13 02:39:47 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 13 Jan 2022 11:39:47 +0100
Subject: [PATCH] arm64: dts: amlogic: meson-s4-aq222: fix waring for
 leading 0s
In-Reply-To: <20220113102746.598763-1-anders.roxell@linaro.org>
References: <20220113102746.598763-1-anders.roxell@linaro.org>
Message-ID: <e0a8be1b-025f-a599-0298-3521066860b0@baylibre.com>

Hi,


On 13/01/2022 11:27, Anders Roxell wrote:
> When building allmodconfig the following waring shows up:
> 
> arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts:21.18-24.4: Warning (unit_address_format): /memory at 00000000: unit name should not have leading 0s
> 
> Fixing the waring by dropping all the '0' except one.
> 
> Fixes: 1c1475389af0 ("arm64: dts: add support for S4 based Amlogic AQ222")
> Signed-off-by: Anders Roxell <anders.roxell at linaro.org>
> ---
>  arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
> index a942d7e06d6e..8ffbcb2b1ac5 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
> @@ -18,7 +18,7 @@ aliases {
>  		serial0 = &uart_B;
>  	};
>  
> -	memory at 00000000 {
> +	memory at 0 {
>  		device_type = "memory";
>  		reg = <0x0 0x0 0x0 0x40000000>;
>  	};
> 


Thanks, I also noticed and fixed in the commit directly, it should be fixed on next -next

Neil


From liang.yang at amlogic.com  Thu Jan 13 03:57:41 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Thu, 13 Jan 2022 19:57:41 +0800
Subject: [PATCH v9 0/4] clk: meson: add a sub EMMC clock controller support
Message-ID: <20220113115745.45826-1-liang.yang@amlogic.com>

Changes since v8 [9]
 - use MESON_SCLK_ONE_BASED instead of CLK_DIVIDER_ONE_BASED
 - use struct_size to caculate onecell_data
 - add clk-phase-delay.h
 - define CLK_DELAY_STEP_PS_GX and CLK_DELAY_STEP_PS_AXG

Changes since v7 [8]
 - move meson_clk_get_phase_delay_data() from header to driver
 - CONFIG sclk-div with COMMON_CLK_AMLOGIC instead of COMMON_CLK_AMLOGIC_AUDIO
 - remove onecell date and ID for internal MUX clk
 - use helper for functions for ONE_BASED in sclk-div
 - add ONE_BASED support for duty cycle

Changes since v6 [7]:
 - add one based support for sclk divier
 - alloc sclk in probe for multiple instance
 - fix coding styles

Changes since v5 [6]:
 - remove divider ops with .init and use sclk_div instead
 - drop CLK_DIVIDER_ROUND_CLOSEST in mux and div
 - drop the useless type cast 

Changes since v4 [5]:
 - use struct parm in phase delay driver
 - remove 0 delay releted part in phase delay driver
 - don't rebuild the parent name once again
 - add divider ops with .init

Changes since v3 [4]:
 - separate clk-phase-delay driver
 - replace clk_get_rate() with clk_hw_get_rate()
 - collect Rob's R-Y
 - drop 'meson-' prefix from compatible string

 Changes since v2 [3]:
 - squash dt-binding clock-id patch
 - update license
 - fix alignment
 - construct a clk register helper() function

Changes since v1 [2]:
 - implement phase clock
 - update compatible name
 - adjust file name
 - divider probe() into small functions, and re-use them

[1] https://lkml.kernel.org/r/20180628090034.0637a062 at xps13
[2] https://lkml.kernel.org/r/20180703145716.31860-1-yixun.lan at amlogic.com
[3] https://lkml.kernel.org/r/20180710163658.6175-1-yixun.lan at amlogic.com
[4] https://lkml.kernel.org/r/20180712211244.11428-1-yixun.lan at amlogic.com
[5] https://lkml.kernel.org/r/20180809070724.11935-4-yixun.lan at amlogic.com
[6] https://lkml.kernel.org/r/1539839245-13793-1-git-send-email-jianxin.pan at amlogic.com
[7] https://lkml.kernel.org/r/1541089855-19356-1-git-send-email-jianxin.pan at amlogic.com
[8] https://lkml.kernel.org/r/1544457877-51301-1-git-send-email-jianxin.pan at amlogic.com
[9] https://lkml.kernel.org/r/1545063850-21504-1-git-send-email-jianxin.pan at amlogic.com
Liang Yang (4):
  clk: meson: add one based divider support for sclk
  clk: meson: add emmc sub clock phase delay driver
  clk: meson: add DT documentation for emmc clock controller
  clk: meson: add sub MMC clock controller driver

 .../bindings/clock/amlogic,mmc-clkc.yaml      |  64 ++++
 drivers/clk/meson/Kconfig                     |  18 ++
 drivers/clk/meson/Makefile                    |   2 +
 drivers/clk/meson/clk-phase-delay.c           |  69 ++++
 drivers/clk/meson/clk-phase-delay.h           |  20 ++
 drivers/clk/meson/mmc-clkc.c                  | 300 ++++++++++++++++++
 drivers/clk/meson/sclk-div.c                  |  61 ++--
 drivers/clk/meson/sclk-div.h                  |   3 +
 include/dt-bindings/clock/amlogic,mmc-clkc.h  |  14 +
 9 files changed, 529 insertions(+), 22 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
 create mode 100644 drivers/clk/meson/clk-phase-delay.c
 create mode 100644 drivers/clk/meson/clk-phase-delay.h
 create mode 100644 drivers/clk/meson/mmc-clkc.c
 create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h

-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan 13 03:57:42 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Thu, 13 Jan 2022 19:57:42 +0800
Subject: [PATCH v9 1/4] clk: meson: add one based divider support for sclk
In-Reply-To: <20220113115745.45826-1-liang.yang@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
Message-ID: <20220113115745.45826-2-liang.yang@amlogic.com>

When MESON_SCLK_ONE_BASED flag is set, the sclk divider will be:
one based divider (div = val), and zero value gates the clock

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 drivers/clk/meson/sclk-div.c | 61 +++++++++++++++++++++++-------------
 drivers/clk/meson/sclk-div.h |  3 ++
 2 files changed, 42 insertions(+), 22 deletions(-)

diff --git a/drivers/clk/meson/sclk-div.c b/drivers/clk/meson/sclk-div.c
index 76d31c0a3342..79c9efd28115 100644
--- a/drivers/clk/meson/sclk-div.c
+++ b/drivers/clk/meson/sclk-div.c
@@ -4,16 +4,17 @@
  * Author: Jerome Brunet <jbrunet at baylibre.com>
  *
  * Sample clock generator divider:
- * This HW divider gates with value 0 but is otherwise a zero based divider:
+ * This HW divider gates with value 0:
  *
  * val >= 1
- * divider = val + 1
+ * divider = val + 1 if ONE_BASED is not set, otherwise divider = val.
  *
  * The duty cycle may also be set for the LR clock variant. The duty cycle
  * ratio is:
  *
  * hi = [0 - val]
- * duty_cycle = (1 + hi) / (1 + val)
+ * duty_cycle = (1 + hi) / (1 + val) if ONE_BASED is not set, otherwise:
+ * duty_cycle = hi / (1 + val)
  */
 
 #include <linux/clk-provider.h>
@@ -28,22 +29,39 @@ meson_sclk_div_data(struct clk_regmap *clk)
 	return (struct meson_sclk_div_data *)clk->data;
 }
 
-static int sclk_div_maxval(struct meson_sclk_div_data *sclk)
+static inline int sclk_get_reg(int val, unsigned char flag)
 {
-	return (1 << sclk->div.width) - 1;
+	if ((flag & MESON_SCLK_ONE_BASED) || !val)
+		return val;
+	else
+		return val - 1;
+}
+
+static inline int sclk_get_divider(int reg, unsigned char flag)
+{
+	if (flag & MESON_SCLK_ONE_BASED)
+		return reg;
+	else
+		return reg + 1;
 }
 
 static int sclk_div_maxdiv(struct meson_sclk_div_data *sclk)
 {
-	return sclk_div_maxval(sclk) + 1;
+	unsigned int reg = (1 << sclk->div.width) - 1;
+
+	return sclk_get_divider(reg, sclk->flags);
 }
 
 static int sclk_div_getdiv(struct clk_hw *hw, unsigned long rate,
-			   unsigned long prate, int maxdiv)
+			   unsigned long prate)
 {
 	int div = DIV_ROUND_CLOSEST_ULL((u64)prate, rate);
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk);
+	int mindiv = sclk_get_divider(1, sclk->flags);
+	int maxdiv = sclk_div_maxdiv(sclk);
 
-	return clamp(div, 2, maxdiv);
+	return clamp(div, mindiv, maxdiv);
 }
 
 static int sclk_div_bestdiv(struct clk_hw *hw, unsigned long rate,
@@ -51,25 +69,25 @@ static int sclk_div_bestdiv(struct clk_hw *hw, unsigned long rate,
 			    struct meson_sclk_div_data *sclk)
 {
 	struct clk_hw *parent = clk_hw_get_parent(hw);
-	int bestdiv = 0, i;
+	int bestdiv = 0, i, mindiv;
 	unsigned long maxdiv, now, parent_now;
 	unsigned long best = 0, best_parent = 0;
 
 	if (!rate)
 		rate = 1;
 
-	maxdiv = sclk_div_maxdiv(sclk);
-
 	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT))
-		return sclk_div_getdiv(hw, rate, *prate, maxdiv);
+		return sclk_div_getdiv(hw, rate, *prate);
 
 	/*
 	 * The maximum divider we can use without overflowing
 	 * unsigned long in rate * i below
 	 */
+	maxdiv = sclk_div_maxdiv(sclk);
 	maxdiv = min(ULONG_MAX / rate, maxdiv);
+	mindiv = sclk_get_divider(1, sclk->flags);
 
-	for (i = 2; i <= maxdiv; i++) {
+	for (i = mindiv; i <= maxdiv; i++) {
 		/*
 		 * It's the most ideal case if the requested rate can be
 		 * divided from parent clock without needing to change
@@ -115,10 +133,7 @@ static void sclk_apply_ratio(struct clk_regmap *clk,
 					    sclk->cached_duty.num,
 					    sclk->cached_duty.den);
 
-	if (hi)
-		hi -= 1;
-
-	meson_parm_write(clk->map, &sclk->hi, hi);
+	meson_parm_write(clk->map, &sclk->hi, sclk_get_reg(hi, sclk->flags));
 }
 
 static int sclk_div_set_duty_cycle(struct clk_hw *hw,
@@ -149,7 +164,7 @@ static int sclk_div_get_duty_cycle(struct clk_hw *hw,
 	}
 
 	hi = meson_parm_read(clk->map, &sclk->hi);
-	duty->num = hi + 1;
+	duty->num = sclk_get_divider(hi, sclk->flags);
 	duty->den = sclk->cached_div;
 	return 0;
 }
@@ -157,10 +172,13 @@ static int sclk_div_get_duty_cycle(struct clk_hw *hw,
 static void sclk_apply_divider(struct clk_regmap *clk,
 			       struct meson_sclk_div_data *sclk)
 {
+	unsigned int div;
+
 	if (MESON_PARM_APPLICABLE(&sclk->hi))
 		sclk_apply_ratio(clk, sclk);
 
-	meson_parm_write(clk->map, &sclk->div, sclk->cached_div - 1);
+	div = sclk_get_reg(sclk->cached_div, sclk->flags);
+	meson_parm_write(clk->map, &sclk->div, div);
 }
 
 static int sclk_div_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -168,9 +186,8 @@ static int sclk_div_set_rate(struct clk_hw *hw, unsigned long rate,
 {
 	struct clk_regmap *clk = to_clk_regmap(hw);
 	struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk);
-	unsigned long maxdiv = sclk_div_maxdiv(sclk);
 
-	sclk->cached_div = sclk_div_getdiv(hw, rate, prate, maxdiv);
+	sclk->cached_div = sclk_div_getdiv(hw, rate, prate);
 
 	if (clk_hw_is_enabled(hw))
 		sclk_apply_divider(clk, sclk);
@@ -228,7 +245,7 @@ static int sclk_div_init(struct clk_hw *hw)
 	if (!val)
 		sclk->cached_div = sclk_div_maxdiv(sclk);
 	else
-		sclk->cached_div = val + 1;
+		sclk->cached_div = sclk_get_divider(val, sclk->flags);
 
 	sclk_div_get_duty_cycle(hw, &sclk->cached_duty);
 
diff --git a/drivers/clk/meson/sclk-div.h b/drivers/clk/meson/sclk-div.h
index b64b2a32005f..944dab5ec0cf 100644
--- a/drivers/clk/meson/sclk-div.h
+++ b/drivers/clk/meson/sclk-div.h
@@ -10,11 +10,14 @@
 #include <linux/clk-provider.h>
 #include "parm.h"
 
+#define MESON_SCLK_ONE_BASED	BIT(0)
+
 struct meson_sclk_div_data {
 	struct parm div;
 	struct parm hi;
 	unsigned int cached_div;
 	struct clk_duty cached_duty;
+	u8 flags;
 };
 
 extern const struct clk_ops meson_sclk_div_ops;
-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan 13 03:57:43 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Thu, 13 Jan 2022 19:57:43 +0800
Subject: [PATCH v9 2/4] clk: meson: add emmc sub clock phase delay driver
In-Reply-To: <20220113115745.45826-1-liang.yang@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
Message-ID: <20220113115745.45826-3-liang.yang@amlogic.com>

Export the emmc sub clock phase delay ops which will be used
by the emmc sub clock driver itself.

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 drivers/clk/meson/Kconfig           |  4 ++
 drivers/clk/meson/Makefile          |  1 +
 drivers/clk/meson/clk-phase-delay.c | 69 +++++++++++++++++++++++++++++
 drivers/clk/meson/clk-phase-delay.h | 20 +++++++++
 4 files changed, 94 insertions(+)
 create mode 100644 drivers/clk/meson/clk-phase-delay.c
 create mode 100644 drivers/clk/meson/clk-phase-delay.h

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 3014e2f1fbb4..bb0f59eea366 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -18,6 +18,10 @@ config COMMON_CLK_MESON_PHASE
 	tristate
 	select COMMON_CLK_MESON_REGMAP
 
+config COMMON_CLK_MESON_PHASE_DELAY
+	tristate
+	select COMMON_CLK_MESON_REGMAP
+
 config COMMON_CLK_MESON_PLL
 	tristate
 	select COMMON_CLK_MESON_REGMAP
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index b3ef5f67820f..c450f38d3801 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o
 obj-$(CONFIG_COMMON_CLK_MESON_REGMAP) += clk-regmap.o
 obj-$(CONFIG_COMMON_CLK_MESON_SCLK_DIV) += sclk-div.o
 obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
+obj-$(CONFIG_COMMON_CLK_MESON_PHASE_DELAY) += clk-phase-delay.o
 
 # Amlogic Clock controllers
 
diff --git a/drivers/clk/meson/clk-phase-delay.c b/drivers/clk/meson/clk-phase-delay.c
new file mode 100644
index 000000000000..3c1ae0ee2a24
--- /dev/null
+++ b/drivers/clk/meson/clk-phase-delay.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+
+#include "clk-regmap.h"
+#include "clk-phase-delay.h"
+
+static inline struct meson_clk_phase_delay_data *
+meson_clk_get_phase_delay_data(struct clk_regmap *clk)
+{
+	return clk->data;
+}
+
+static int meson_clk_phase_delay_get_phase(struct clk_hw *hw)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_clk_phase_delay_data *ph;
+	unsigned long period_ps, p, d;
+	int degrees;
+
+	ph = meson_clk_get_phase_delay_data(clk);
+	p = meson_parm_read(clk->map, &ph->phase);
+	degrees = p * 360 / (1 << (ph->phase.width));
+
+	period_ps = DIV_ROUND_UP_ULL(NSEC_PER_SEC * 1000ull,
+				     clk_hw_get_rate(hw));
+
+	d = meson_parm_read(clk->map, &ph->delay);
+	degrees += d * ph->delay_step_ps * 360 / period_ps;
+	degrees %= 360;
+
+	return degrees;
+}
+
+static int meson_clk_phase_delay_set_phase(struct clk_hw *hw, int degrees)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_clk_phase_delay_data *ph;
+	unsigned long period_ps, d = 0;
+	unsigned int p;
+
+	ph = meson_clk_get_phase_delay_data(clk);
+	period_ps = DIV_ROUND_UP_ULL(NSEC_PER_SEC * 1000ull,
+				     clk_hw_get_rate(hw));
+
+	/*
+	 * First compute the phase index (p), the remainder (r) is the
+	 * part we'll try to acheive using the delays (d).
+	 */
+	p = 360 / 1 << (ph->phase.width);
+	degrees = degrees / p;
+	d = DIV_ROUND_CLOSEST((degrees % p) * period_ps,
+			      360 * ph->delay_step_ps);
+	d = min(d, PMASK(ph->delay.width));
+
+	meson_parm_write(clk->map, &ph->phase, degrees);
+	meson_parm_write(clk->map, &ph->delay, d);
+	return 0;
+}
+
+const struct clk_ops meson_clk_phase_delay_ops = {
+	.get_phase = meson_clk_phase_delay_get_phase,
+	.set_phase = meson_clk_phase_delay_set_phase,
+};
+EXPORT_SYMBOL_GPL(meson_clk_phase_delay_ops);
diff --git a/drivers/clk/meson/clk-phase-delay.h b/drivers/clk/meson/clk-phase-delay.h
new file mode 100644
index 000000000000..b4f211d02c84
--- /dev/null
+++ b/drivers/clk/meson/clk-phase-delay.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __MESON_CLK_PHASE_DELAY_H
+#define __MESON_CLK_PHASE_DELAY_H
+
+#include <linux/clk-provider.h>
+#include "parm.h"
+
+struct meson_clk_phase_delay_data {
+	struct parm     phase;
+	struct parm     delay;
+	unsigned int    delay_step_ps;
+};
+
+extern const struct clk_ops meson_clk_phase_delay_ops;
+
+#endif /* __MESON_CLK_PHASE_DELAY_H */
-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan 13 03:57:44 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Thu, 13 Jan 2022 19:57:44 +0800
Subject: [PATCH v9 3/4] clk: meson: add DT documentation for emmc clock
 controller
In-Reply-To: <20220113115745.45826-1-liang.yang@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
Message-ID: <20220113115745.45826-4-liang.yang@amlogic.com>

Document the MMC sub clock controller driver, the potential consumer
of this driver is MMC or NAND. Also add four clock bindings IDs which
provided by this driver.

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 .../bindings/clock/amlogic,mmc-clkc.yaml      | 64 +++++++++++++++++++
 include/dt-bindings/clock/amlogic,mmc-clkc.h  | 14 ++++
 2 files changed, 78 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
 create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h

diff --git a/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
new file mode 100644
index 000000000000..a274c3d5fc2e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,mmc-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic MMC Sub Clock Controller Driver Device Tree Bindings
+
+maintainers:
+  - jianxin.pan at amlogic.com
+  - liang.yang at amlogic.com
+
+properties:
+  compatible:
+    enum:
+      - "amlogic,axg-mmc-clkc", "syscon"
+      - "amlogic,gx-mmc-clkc", "syscon"
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: "clkin0", "clkin1"
+
+  "#clock-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    sd_mmc_c_clkc: clock-controller at 7000 {
+	compatible = "amlogic,axg-mmc-clkc", "syscon";
+	reg = <0x0 0x7000 0x0 0x4>;
+	#clock-cells = <1>;
+
+	clock-names = "clkin0", "clkin1";
+	clocks = <&clkc CLKID_SD_MMC_C_CLK0>,
+		 <&clkc CLKID_FCLK_DIV2>;
+     };
+
+  - |
+    sd_emmc_b_clkc: clock-controller at 5000 {
+	compatible = "amlogic,axg-mmc-clkc", "syscon";
+	reg = <0x0 0x5000 0x0 0x4>;
+
+	#clock-cells = <1>;
+	clock-names = "clkin0", "clkin1";
+	clocks = <&clkc CLKID_SD_EMMC_B_CLK0>,
+		 <&clkc CLKID_FCLK_DIV2>;
+    };
+
+...
\ No newline at end of file
diff --git a/include/dt-bindings/clock/amlogic,mmc-clkc.h b/include/dt-bindings/clock/amlogic,mmc-clkc.h
new file mode 100644
index 000000000000..71301517b183
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,mmc-clkc.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __MMC_CLKC_H
+#define __MMC_CLKC_H
+
+#define CLKID_MMC_DIV		0
+#define CLKID_MMC_PHASE_CORE	1
+#define CLKID_MMC_PHASE_TX	2
+#define CLKID_MMC_PHASE_RX	3
+
+#endif
-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan 13 03:57:45 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Thu, 13 Jan 2022 19:57:45 +0800
Subject: [PATCH v9 4/4] clk: meson: add sub MMC clock controller driver
In-Reply-To: <20220113115745.45826-1-liang.yang@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
Message-ID: <20220113115745.45826-5-liang.yang@amlogic.com>

The patch will add a MMC clock controller driver which used by MMC or NAND,
It provide a mux and divider clock, and three phase clocks - core, tx, tx.

Two clocks are provided as the parent of MMC clock controller from
upper layer clock controller - eg "amlogic,axg-clkc" in AXG platform.

To specify which clock the MMC or NAND driver may consume,
the preprocessor macros in the dt-bindings/clock/amlogic,mmc-clkc.h header
can be used in the device tree sources.

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 drivers/clk/meson/Kconfig    |  14 ++
 drivers/clk/meson/Makefile   |   1 +
 drivers/clk/meson/mmc-clkc.c | 300 +++++++++++++++++++++++++++++++++++
 3 files changed, 315 insertions(+)
 create mode 100644 drivers/clk/meson/mmc-clkc.c

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index bb0f59eea366..3de6f3b24461 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -39,6 +39,20 @@ config COMMON_CLK_MESON_AO_CLKC
 	select COMMON_CLK_MESON_REGMAP
 	select RESET_CONTROLLER
 
+config COMMON_CLK_MMC_MESON
+	tristate "Meson MMC Sub Clock Controller Driver"
+	depends on ARCH_MESON || COMPILE_TEST
+	select MFD_SYSCON
+	select COMMON_CLK_AMLOGIC
+	select COMMON_CLK_MESON_PHASE
+	select COMMON_CLK_MESON_PHASE_DELAY
+	select COMMON_CLK_MESON_SCLK_DIV
+	help
+	  Support for the MMC sub clock controller on
+	  Amlogic Meson Platform, which includes S905 (GXBB, GXL),
+	  A113D/X (AXG) devices . Say Y if you want this
+	  clock enabled.
+
 config COMMON_CLK_MESON_EE_CLKC
 	tristate
 	select COMMON_CLK_MESON_REGMAP
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index c450f38d3801..f7a94a33e789 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_PHASE_DELAY) += clk-phase-delay.o
 
 obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
 obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
+obj-$(CONFIG_COMMON_CLK_MMC_MESON) += mmc-clkc.o
 obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
 obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
 obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c
new file mode 100644
index 000000000000..f53977f61390
--- /dev/null
+++ b/drivers/clk/meson/mmc-clkc.c
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/of_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/amlogic,mmc-clkc.h>
+
+#include "sclk-div.h"
+#include "clk-phase-delay.h"
+#include "clk-regmap.h"
+#include "clk-phase.h"
+
+/* clock ID used by internal driver */
+
+#define SD_EMMC_CLOCK		0
+#define CLK_DELAY_STEP_PS_GX	200
+#define CLK_DELAY_STEP_PS_AXG	78
+#define MUX_CLK_NUM_PARENTS	2
+#define MMC_MAX_CLKS		4
+
+struct mmc_clkc_data {
+	struct meson_clk_phase_delay_data tx;
+	struct meson_clk_phase_delay_data rx;
+};
+
+static struct clk_regmap_mux_data mmc_clkc_mux_data = {
+	.offset = SD_EMMC_CLOCK,
+	.mask   = 0x3,
+	.shift  = 6,
+};
+
+static const struct meson_sclk_div_data mmc_clkc_div_data = {
+	.div = {
+		.reg_off = SD_EMMC_CLOCK,
+		.width   = 6,
+	},
+	.flags = MESON_SCLK_ONE_BASED,
+};
+
+static struct meson_clk_phase_data mmc_clkc_core_phase = {
+	.ph = {
+		.reg_off = SD_EMMC_CLOCK,
+		.shift   = 8,
+		.width   = 2,
+	}
+};
+
+static const struct mmc_clkc_data mmc_clkc_gx_data = {
+	.tx = {
+		.phase = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 10,
+			.width   = 2,
+		},
+		.delay = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 16,
+			.width   = 4,
+		},
+		.delay_step_ps = CLK_DELAY_STEP_PS_GX,
+	},
+	.rx = {
+		.phase = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 12,
+			.width   = 2,
+		},
+		.delay = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 20,
+			.width   = 4,
+		},
+		.delay_step_ps   = CLK_DELAY_STEP_PS_GX,
+	},
+};
+
+static const struct mmc_clkc_data mmc_clkc_axg_data = {
+	.tx = {
+		.phase = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 10,
+			.width   = 2,
+		},
+		.delay = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 16,
+			.width   = 6,
+		},
+		.delay_step_ps   = CLK_DELAY_STEP_PS_AXG,
+	},
+	.rx = {
+		.phase = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 12,
+			.width   = 2,
+		},
+		.delay = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 22,
+			.width   = 6,
+		},
+		.delay_step_ps   = CLK_DELAY_STEP_PS_AXG,
+	},
+};
+
+static const struct of_device_id mmc_clkc_match_table[] = {
+	{
+		.compatible	= "amlogic,gx-mmc-clkc",
+		.data		= &mmc_clkc_gx_data
+	},
+	{
+		.compatible	= "amlogic,axg-mmc-clkc",
+		.data		= &mmc_clkc_axg_data
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, mmc_clkc_match_table);
+
+static struct clk_regmap *
+mmc_clkc_register_clk(struct device *dev, struct regmap *map,
+		      struct clk_init_data *init,
+		      const char *suffix, void *data)
+{
+	struct clk_regmap *clk;
+	char *name;
+	int ret;
+
+	clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
+	if (!clk)
+		return ERR_PTR(-ENOMEM);
+
+	name = kasprintf(GFP_KERNEL, "%s#%s", dev_name(dev), suffix);
+	if (!name)
+		return ERR_PTR(-ENOMEM);
+
+	init->name = name;
+	clk->map = map;
+	clk->data = data;
+	clk->hw.init = init;
+	ret = devm_clk_hw_register(dev, &clk->hw);
+	if (ret)
+		clk = ERR_PTR(ret);
+
+	kfree(name);
+	return clk;
+}
+
+static struct clk_regmap *mmc_clkc_register_mux(struct device *dev,
+						struct regmap *map)
+{
+	const char *parent_names[MUX_CLK_NUM_PARENTS];
+	struct clk_init_data init;
+	struct clk_regmap *mux;
+	struct clk *clk;
+	int i;
+
+	for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
+		char name[8];
+
+		snprintf(name, sizeof(name), "clkin%d", i);
+		clk = devm_clk_get(dev, name);
+		if (IS_ERR(clk)) {
+			if (clk != ERR_PTR(-EPROBE_DEFER))
+				dev_err(dev, "Missing clock %s\n", name);
+			return ERR_CAST(clk);
+		}
+
+		parent_names[i] = __clk_get_name(clk);
+	}
+
+	init.ops = &clk_regmap_mux_ops;
+	init.flags = CLK_SET_RATE_PARENT;
+	init.parent_names = parent_names;
+	init.num_parents = MUX_CLK_NUM_PARENTS;
+
+	mux = mmc_clkc_register_clk(dev, map, &init, "mux", &mmc_clkc_mux_data);
+	if (IS_ERR(mux))
+		dev_err(dev, "Mux clock registration failed\n");
+
+	return mux;
+}
+
+static struct clk_regmap *
+mmc_clkc_register_clk_with_parent(struct device *dev, struct regmap *map,
+				  char *suffix, const struct clk_hw *hw,
+				  unsigned long flags,
+				  const struct clk_ops *ops, void *data)
+{
+	struct clk_init_data init;
+	struct clk_regmap *clk;
+	const char *parent_name = clk_hw_get_name(hw);
+
+	init.ops = ops;
+	init.flags = flags;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	clk = mmc_clkc_register_clk(dev, map, &init, suffix, data);
+	if (IS_ERR(clk))
+		dev_err(dev, "%s clock registration failed\n", suffix);
+
+	return clk;
+}
+
+static int mmc_clkc_probe(struct platform_device *pdev)
+{
+	struct clk_hw_onecell_data *onecell_data;
+	struct device *dev = &pdev->dev;
+	struct mmc_clkc_data *data;
+	struct regmap *map;
+	struct clk_regmap *clk, *core;
+	struct meson_sclk_div_data *div_data;
+
+	/*cast to drop the const in match->data*/
+	data = (struct mmc_clkc_data *)of_device_get_match_data(dev);
+	if (!data)
+		return -ENODEV;
+
+	map = syscon_node_to_regmap(dev->of_node);
+	if (IS_ERR(map)) {
+		dev_err(dev, "could not find mmc clock controller\n");
+		return PTR_ERR(map);
+	}
+
+	onecell_data = devm_kzalloc(dev,
+				    struct_size(onecell_data, hws,
+						MMC_MAX_CLKS),
+				    GFP_KERNEL);
+	if (!onecell_data)
+		return -ENOMEM;
+
+	clk = mmc_clkc_register_mux(dev, map);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	div_data = devm_kzalloc(dev, sizeof(*div_data), GFP_KERNEL);
+	if (!div_data)
+		return -ENOMEM;
+
+	memcpy(div_data, &mmc_clkc_div_data, sizeof(*div_data));
+	clk = mmc_clkc_register_clk_with_parent(dev, map, "div",
+						&clk->hw,
+						CLK_SET_RATE_PARENT,
+						&meson_sclk_div_ops,
+						div_data);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	onecell_data->hws[CLKID_MMC_DIV] = &clk->hw;
+	core = mmc_clkc_register_clk_with_parent(dev, map, "core",
+						 &clk->hw,
+						 CLK_SET_RATE_PARENT,
+						 &meson_clk_phase_ops,
+						 &mmc_clkc_core_phase);
+	if (IS_ERR(core))
+		return PTR_ERR(core);
+
+	onecell_data->hws[CLKID_MMC_PHASE_CORE] = &core->hw;
+	clk = mmc_clkc_register_clk_with_parent(dev, map, "rx",
+						&core->hw,  0,
+						&meson_clk_phase_delay_ops,
+						&data->rx);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	onecell_data->hws[CLKID_MMC_PHASE_RX] = &clk->hw;
+	clk = mmc_clkc_register_clk_with_parent(dev, map, "tx",
+						&core->hw,  0,
+						&meson_clk_phase_delay_ops,
+						&data->tx);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	onecell_data->hws[CLKID_MMC_PHASE_TX] = &clk->hw;
+	onecell_data->num = MMC_MAX_CLKS;
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   onecell_data);
+}
+
+static struct platform_driver mmc_clkc_driver = {
+	.probe		= mmc_clkc_probe,
+	.driver		= {
+		.name	= "meson-mmc-clkc",
+		.of_match_table = of_match_ptr(mmc_clkc_match_table),
+	},
+};
+
+module_platform_driver(mmc_clkc_driver);
+
+MODULE_DESCRIPTION("Amlogic AXG MMC clock driver");
+MODULE_AUTHOR("Jianxin Pan <jianxin.pan at amlogic.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.34.1



From stefan at agner.ch  Thu Jan 13 06:36:38 2022
From: stefan at agner.ch (Stefan Agner)
Date: Thu, 13 Jan 2022 15:36:38 +0100
Subject: HDMI CEC on ODROID-N2+
Message-ID: <d2ef8936c54567c9c2652b3c53a82f68@agner.ch>

Hi Neil,

I am trying to use HDMI CEC on ODROID-N2+ using Linux 5.10.91. However,
I was unsuccessful: As far as I can tell cec-client uses the right
device (I disabled CONFIG_DRM_DW_HDMI_CEC since my kernel is still
missing your patch "drm/meson: dw-hdmi: disable DW-HDMI CEC
sub-driver"). But communication won't work, and dmesg prints timeout
messages:

[   68.831253] cec-meson_g12a_ao_cec: message ff 84 20 00 06 timed out
[   71.134987] cec-meson_g12a_ao_cec: message ff 87 00 15 82 timed out
[   73.438826] cec-meson_g12a_ao_cec: message f0 timed out
[   75.742677] cec-meson_g12a_ao_cec: message f0 timed out
[   78.046555] cec-meson_g12a_ao_cec: message f0 timed out
[   80.350446] cec-meson_g12a_ao_cec: message f0 timed out
[   82.654358] cec-meson_g12a_ao_cec: message 11 timed out
[   84.958285] cec-meson_g12a_ao_cec: message 11 timed out
[   87.262194] cec-meson_g12a_ao_cec: message 11 timed out
[   89.566130] cec-meson_g12a_ao_cec: message 11 timed out

I did a quick test with CoreELEC which uses the 4.9 downstream kernel,
CEC seems to work there. So it does not seem to be my hardware setup.

A quick test with the latest Linux 5.16 shows the same errors.

Do you happen to have an idea? Do you know if HDMI CEC using upstream
kernels worked at one point on that particular platform?

--
Stefan


From narmstrong at baylibre.com  Thu Jan 13 07:52:22 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 13 Jan 2022 16:52:22 +0100
Subject: HDMI CEC on ODROID-N2+
In-Reply-To: <d2ef8936c54567c9c2652b3c53a82f68@agner.ch>
References: <d2ef8936c54567c9c2652b3c53a82f68@agner.ch>
Message-ID: <a072cbe4-f922-a98f-14d9-270fc4c72d8e@baylibre.com>

Hi,


On 13/01/2022 15:36, Stefan Agner wrote:
> Hi Neil,
> 
> I am trying to use HDMI CEC on ODROID-N2+ using Linux 5.10.91. However,
> I was unsuccessful: As far as I can tell cec-client uses the right
> device (I disabled CONFIG_DRM_DW_HDMI_CEC since my kernel is still
> missing your patch "drm/meson: dw-hdmi: disable DW-HDMI CEC
> sub-driver"). But communication won't work, and dmesg prints timeout
> messages:
> 
> [   68.831253] cec-meson_g12a_ao_cec: message ff 84 20 00 06 timed out
> [   71.134987] cec-meson_g12a_ao_cec: message ff 87 00 15 82 timed out
> [   73.438826] cec-meson_g12a_ao_cec: message f0 timed out
> [   75.742677] cec-meson_g12a_ao_cec: message f0 timed out
> [   78.046555] cec-meson_g12a_ao_cec: message f0 timed out
> [   80.350446] cec-meson_g12a_ao_cec: message f0 timed out
> [   82.654358] cec-meson_g12a_ao_cec: message 11 timed out
> [   84.958285] cec-meson_g12a_ao_cec: message 11 timed out
> [   87.262194] cec-meson_g12a_ao_cec: message 11 timed out
> [   89.566130] cec-meson_g12a_ao_cec: message 11 timed out
> 
> I did a quick test with CoreELEC which uses the 4.9 downstream kernel,
> CEC seems to work there. So it does not seem to be my hardware setup.
> 
> A quick test with the latest Linux 5.16 shows the same errors.
> 
> Do you happen to have an idea? Do you know if HDMI CEC using upstream
> kernels worked at one point on that particular platform?

I was reported it works on Yukawa 5.10 kernel, I'll have a check it still works.

Neil

> 
> --
> Stefan
> 



From jiasheng at iscas.ac.cn  Wed Jan 12 23:06:37 2022
From: jiasheng at iscas.ac.cn (Jiasheng Jiang)
Date: Thu, 13 Jan 2022 15:06:37 +0800
Subject: [PATCH v3] media: meson: vdec: Fix a NULL pointer dereference
 in amvdec_add_ts()
Message-ID: <20220113070637.1198179-1-jiasheng@iscas.ac.cn>

On Wed, Jan 12, 2022 at 05:04:41PM +0800, Hans Verkuil wrote:
> I changed the status of this patch to 'Changes Requested'. Jiasheng,
> can you post a v3 with
> the requested changes?

Thanks, I have sent the v3 with the correct indentation.
And I am sorry that I sent two patches, and the first one is
lack of 'v3' tag.
So please ignore it.
And the later one is right.

Sincerely thanks,
Jiang



From biju.das.jz at bp.renesas.com  Thu Jan 13 09:45:05 2022
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Thu, 13 Jan 2022 17:45:05 +0000
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
Message-ID: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>

Hi All,

RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour) till the commit
7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts callbacks").

After this patch, the screen becomes greenish(may be it is setting it into YUV format??).

By checking the code, previously it used to call get_input_fmt callback and set colour as RGB24.

After this commit, it calls get_output_fmt_callbck and returns 3 outputformats(YUV16, YUV24 and RGB24)
And get_input_fmt callback, I see the outputformat as YUV16 instead of RGB24.

Not sure, I am the only one seeing this issue with dw_HDMI driver.

Regards,
Biju


From festevam at gmail.com  Thu Jan 13 12:01:34 2022
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 13 Jan 2022 17:01:34 -0300
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge:
 display-connector: implement bus fmts callbacks")
In-Reply-To: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
Message-ID: <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>

Hi Biju,

On Thu, Jan 13, 2022 at 2:45 PM Biju Das <biju.das.jz at bp.renesas.com> wrote:
>
> Hi All,
>
> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour) till the commit
> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts callbacks").
>
> After this patch, the screen becomes greenish(may be it is setting it into YUV format??).
>
> By checking the code, previously it used to call get_input_fmt callback and set colour as RGB24.
>
> After this commit, it calls get_output_fmt_callbck and returns 3 outputformats(YUV16, YUV24 and RGB24)
> And get_input_fmt callback, I see the outputformat as YUV16 instead of RGB24.
>
> Not sure, I am the only one seeing this issue with dw_HDMI driver.

I have tested linux-next 20220112 on a imx6q-sabresd board, which shows:

dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with HDCP
(DWC HDMI 3D TX PHY)

The colors are shown correctly here.


From sboyd at kernel.org  Thu Jan 13 13:28:00 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 13 Jan 2022 13:28:00 -0800
Subject: [PATCH v9 1/4] clk: meson: add one based divider support for sclk
In-Reply-To: <20220113115745.45826-2-liang.yang@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-2-liang.yang@amlogic.com>
Message-ID: <20220113212801.E88BFC36AE3@smtp.kernel.org>

Quoting Liang Yang (2022-01-13 03:57:42)
> diff --git a/drivers/clk/meson/sclk-div.c b/drivers/clk/meson/sclk-div.c
> index 76d31c0a3342..79c9efd28115 100644
> --- a/drivers/clk/meson/sclk-div.c
> +++ b/drivers/clk/meson/sclk-div.c
> @@ -28,22 +29,39 @@ meson_sclk_div_data(struct clk_regmap *clk)
>         return (struct meson_sclk_div_data *)clk->data;
>  }
>  
> -static int sclk_div_maxval(struct meson_sclk_div_data *sclk)
> +static inline int sclk_get_reg(int val, unsigned char flag)
>  {
> -       return (1 << sclk->div.width) - 1;
> +       if ((flag & MESON_SCLK_ONE_BASED) || !val)
> +               return val;
> +       else
> +               return val - 1;

Please drop the else

> +}
> +
> +static inline int sclk_get_divider(int reg, unsigned char flag)
> +{
> +       if (flag & MESON_SCLK_ONE_BASED)
> +               return reg;
> +       else

Please drop the else

> +               return reg + 1;
>  }
>  
>  static int sclk_div_maxdiv(struct meson_sclk_div_data *sclk)
>  {
> -       return sclk_div_maxval(sclk) + 1;


From sboyd at kernel.org  Thu Jan 13 13:29:26 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 13 Jan 2022 13:29:26 -0800
Subject: [PATCH v9 2/4] clk: meson: add emmc sub clock phase delay driver
In-Reply-To: <20220113115745.45826-3-liang.yang@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-3-liang.yang@amlogic.com>
Message-ID: <20220113212928.28C10C36AE3@smtp.kernel.org>

Quoting Liang Yang (2022-01-13 03:57:43)
> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
> index b3ef5f67820f..c450f38d3801 100644
> --- a/drivers/clk/meson/Makefile
> +++ b/drivers/clk/meson/Makefile
> @@ -11,6 +11,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o
>  obj-$(CONFIG_COMMON_CLK_MESON_REGMAP) += clk-regmap.o
>  obj-$(CONFIG_COMMON_CLK_MESON_SCLK_DIV) += sclk-div.o
>  obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
> +obj-$(CONFIG_COMMON_CLK_MESON_PHASE_DELAY) += clk-phase-delay.o

Sort by Kconfig symbol?

>  
>  # Amlogic Clock controllers
>


From sboyd at kernel.org  Thu Jan 13 13:29:56 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 13 Jan 2022 13:29:56 -0800
Subject: [PATCH v9 3/4] clk: meson: add DT documentation for emmc clock
 controller
In-Reply-To: <20220113115745.45826-4-liang.yang@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-4-liang.yang@amlogic.com>
Message-ID: <20220113212957.768FFC36AE3@smtp.kernel.org>

Quoting Liang Yang (2022-01-13 03:57:44)
> Document the MMC sub clock controller driver, the potential consumer
> of this driver is MMC or NAND. Also add four clock bindings IDs which
> provided by this driver.
> 
> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
> ---
>  .../bindings/clock/amlogic,mmc-clkc.yaml      | 64 +++++++++++++++++++
>  include/dt-bindings/clock/amlogic,mmc-clkc.h  | 14 ++++
>  2 files changed, 78 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>  create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
> 
> diff --git a/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
> new file mode 100644
> index 000000000000..a274c3d5fc2e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
> @@ -0,0 +1,64 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/amlogic,mmc-clkc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Amlogic MMC Sub Clock Controller Driver Device Tree Bindings
> +
> +maintainers:
> +  - jianxin.pan at amlogic.com
> +  - liang.yang at amlogic.com
> +
> +properties:
> +  compatible:
> +    enum:
> +      - "amlogic,axg-mmc-clkc", "syscon"

Why is it a syscon?


From sboyd at kernel.org  Thu Jan 13 13:35:12 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 13 Jan 2022 13:35:12 -0800
Subject: [PATCH v9 4/4] clk: meson: add sub MMC clock controller driver
In-Reply-To: <20220113115745.45826-5-liang.yang@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-5-liang.yang@amlogic.com>
Message-ID: <20220113213513.9819AC36AEA@smtp.kernel.org>

Quoting Liang Yang (2022-01-13 03:57:45)
> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> index bb0f59eea366..3de6f3b24461 100644
> --- a/drivers/clk/meson/Kconfig
> +++ b/drivers/clk/meson/Kconfig
> @@ -39,6 +39,20 @@ config COMMON_CLK_MESON_AO_CLKC
>         select COMMON_CLK_MESON_REGMAP
>         select RESET_CONTROLLER
>  
> +config COMMON_CLK_MMC_MESON
> +       tristate "Meson MMC Sub Clock Controller Driver"
> +       depends on ARCH_MESON || COMPILE_TEST
> +       select MFD_SYSCON
> +       select COMMON_CLK_AMLOGIC
> +       select COMMON_CLK_MESON_PHASE
> +       select COMMON_CLK_MESON_PHASE_DELAY
> +       select COMMON_CLK_MESON_SCLK_DIV
> +       help
> +         Support for the MMC sub clock controller on
> +         Amlogic Meson Platform, which includes S905 (GXBB, GXL),
> +         A113D/X (AXG) devices . Say Y if you want this

s/devices /devices/

> +         clock enabled.
> +
>  config COMMON_CLK_MESON_EE_CLKC
>         tristate
>         select COMMON_CLK_MESON_REGMAP
> diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c
> new file mode 100644
> index 000000000000..f53977f61390
> --- /dev/null
> +++ b/drivers/clk/meson/mmc-clkc.c
> @@ -0,0 +1,300 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/of_device.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/platform_device.h>
> +#include <dt-bindings/clock/amlogic,mmc-clkc.h>
> +
> +#include "sclk-div.h"
> +#include "clk-phase-delay.h"
> +#include "clk-regmap.h"
> +#include "clk-phase.h"
> +
> +/* clock ID used by internal driver */
> +
> +#define SD_EMMC_CLOCK          0
> +#define CLK_DELAY_STEP_PS_GX   200
> +#define CLK_DELAY_STEP_PS_AXG  78
> +#define MUX_CLK_NUM_PARENTS    2
> +#define MMC_MAX_CLKS           4
> +
> +struct mmc_clkc_data {
> +       struct meson_clk_phase_delay_data tx;
> +       struct meson_clk_phase_delay_data rx;
> +};
> +
> +static struct clk_regmap_mux_data mmc_clkc_mux_data = {
> +       .offset = SD_EMMC_CLOCK,
> +       .mask   = 0x3,
> +       .shift  = 6,
> +};
> +
> +static const struct meson_sclk_div_data mmc_clkc_div_data = {
> +       .div = {
> +               .reg_off = SD_EMMC_CLOCK,
> +               .width   = 6,
> +       },
> +       .flags = MESON_SCLK_ONE_BASED,
> +};
> +
> +static struct meson_clk_phase_data mmc_clkc_core_phase = {
> +       .ph = {
> +               .reg_off = SD_EMMC_CLOCK,
> +               .shift   = 8,
> +               .width   = 2,
> +       }
> +};
> +
> +static const struct mmc_clkc_data mmc_clkc_gx_data = {
> +       .tx = {
> +               .phase = {
> +                       .reg_off = SD_EMMC_CLOCK,
> +                       .shift   = 10,
> +                       .width   = 2,
> +               },
> +               .delay = {
> +                       .reg_off = SD_EMMC_CLOCK,
> +                       .shift   = 16,
> +                       .width   = 4,
> +               },
> +               .delay_step_ps = CLK_DELAY_STEP_PS_GX,
> +       },
> +       .rx = {
> +               .phase = {
> +                       .reg_off = SD_EMMC_CLOCK,
> +                       .shift   = 12,
> +                       .width   = 2,
> +               },
> +               .delay = {
> +                       .reg_off = SD_EMMC_CLOCK,
> +                       .shift   = 20,
> +                       .width   = 4,
> +               },
> +               .delay_step_ps   = CLK_DELAY_STEP_PS_GX,
> +       },
> +};
> +
> +static const struct mmc_clkc_data mmc_clkc_axg_data = {
> +       .tx = {
> +               .phase = {
> +                       .reg_off = SD_EMMC_CLOCK,
> +                       .shift   = 10,
> +                       .width   = 2,
> +               },
> +               .delay = {
> +                       .reg_off = SD_EMMC_CLOCK,
> +                       .shift   = 16,
> +                       .width   = 6,
> +               },
> +               .delay_step_ps   = CLK_DELAY_STEP_PS_AXG,
> +       },
> +       .rx = {
> +               .phase = {
> +                       .reg_off = SD_EMMC_CLOCK,
> +                       .shift   = 12,
> +                       .width   = 2,
> +               },
> +               .delay = {
> +                       .reg_off = SD_EMMC_CLOCK,
> +                       .shift   = 22,
> +                       .width   = 6,
> +               },
> +               .delay_step_ps   = CLK_DELAY_STEP_PS_AXG,
> +       },
> +};
> +
> +static const struct of_device_id mmc_clkc_match_table[] = {
> +       {
> +               .compatible     = "amlogic,gx-mmc-clkc",
> +               .data           = &mmc_clkc_gx_data
> +       },
> +       {
> +               .compatible     = "amlogic,axg-mmc-clkc",
> +               .data           = &mmc_clkc_axg_data
> +       },
> +       {}
> +};
> +MODULE_DEVICE_TABLE(of, mmc_clkc_match_table);
> +
> +static struct clk_regmap *
> +mmc_clkc_register_clk(struct device *dev, struct regmap *map,
> +                     struct clk_init_data *init,
> +                     const char *suffix, void *data)
> +{
> +       struct clk_regmap *clk;
> +       char *name;
> +       int ret;
> +
> +       clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
> +       if (!clk)
> +               return ERR_PTR(-ENOMEM);
> +
> +       name = kasprintf(GFP_KERNEL, "%s#%s", dev_name(dev), suffix);
> +       if (!name)
> +               return ERR_PTR(-ENOMEM);
> +
> +       init->name = name;
> +       clk->map = map;
> +       clk->data = data;
> +       clk->hw.init = init;
> +       ret = devm_clk_hw_register(dev, &clk->hw);
> +       if (ret)
> +               clk = ERR_PTR(ret);
> +
> +       kfree(name);
> +       return clk;
> +}
> +
> +static struct clk_regmap *mmc_clkc_register_mux(struct device *dev,
> +                                               struct regmap *map)
> +{
> +       const char *parent_names[MUX_CLK_NUM_PARENTS];
> +       struct clk_init_data init;
> +       struct clk_regmap *mux;
> +       struct clk *clk;
> +       int i;
> +
> +       for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
> +               char name[8];
> +
> +               snprintf(name, sizeof(name), "clkin%d", i);
> +               clk = devm_clk_get(dev, name);
> +               if (IS_ERR(clk)) {
> +                       if (clk != ERR_PTR(-EPROBE_DEFER))
> +                               dev_err(dev, "Missing clock %s\n", name);

Use dev_err_probe()?

> +                       return ERR_CAST(clk);
> +               }
> +
> +               parent_names[i] = __clk_get_name(clk);

Why can't we use clk_parent_data?

> +       }
> +
> +       init.ops = &clk_regmap_mux_ops;
> +       init.flags = CLK_SET_RATE_PARENT;
> +       init.parent_names = parent_names;
> +       init.num_parents = MUX_CLK_NUM_PARENTS;
> +
> +       mux = mmc_clkc_register_clk(dev, map, &init, "mux", &mmc_clkc_mux_data);
> +       if (IS_ERR(mux))
> +               dev_err(dev, "Mux clock registration failed\n");
> +
> +       return mux;
> +}
> +
> +static struct clk_regmap *
> +mmc_clkc_register_clk_with_parent(struct device *dev, struct regmap *map,
> +                                 char *suffix, const struct clk_hw *hw,
> +                                 unsigned long flags,
> +                                 const struct clk_ops *ops, void *data)
> +{
> +       struct clk_init_data init;
> +       struct clk_regmap *clk;
> +       const char *parent_name = clk_hw_get_name(hw);
> +
> +       init.ops = ops;
> +       init.flags = flags;
> +       init.parent_names = &parent_name;
> +       init.num_parents = 1;
> +
> +       clk = mmc_clkc_register_clk(dev, map, &init, suffix, data);
> +       if (IS_ERR(clk))
> +               dev_err(dev, "%s clock registration failed\n", suffix);
> +
> +       return clk;
> +}
> +
> +static int mmc_clkc_probe(struct platform_device *pdev)
> +{
> +       struct clk_hw_onecell_data *onecell_data;
> +       struct device *dev = &pdev->dev;
> +       struct mmc_clkc_data *data;
> +       struct regmap *map;
> +       struct clk_regmap *clk, *core;
> +       struct meson_sclk_div_data *div_data;
> +
> +       /*cast to drop the const in match->data*/

Space after *, also why do we need to cast away const? The user of this
pointer passes it all the way down to mmc_clkc_register_clk() which
could take the data as const void pointer and decide to cast away const
there.

> +       data = (struct mmc_clkc_data *)of_device_get_match_data(dev);
> +       if (!data)
> +               return -ENODEV;
> +
> +       map = syscon_node_to_regmap(dev->of_node);
> +       if (IS_ERR(map)) {
> +               dev_err(dev, "could not find mmc clock controller\n");
> +               return PTR_ERR(map);
> +       }
> +
> +       onecell_data = devm_kzalloc(dev,
> +                                   struct_size(onecell_data, hws,
> +                                               MMC_MAX_CLKS),
> +                                   GFP_KERNEL);
> +       if (!onecell_data)
> +               return -ENOMEM;
> +
> +       clk = mmc_clkc_register_mux(dev, map);
> +       if (IS_ERR(clk))
> +               return PTR_ERR(clk);
> +
> +       div_data = devm_kzalloc(dev, sizeof(*div_data), GFP_KERNEL);
> +       if (!div_data)
> +               return -ENOMEM;
> +
> +       memcpy(div_data, &mmc_clkc_div_data, sizeof(*div_data));
> +       clk = mmc_clkc_register_clk_with_parent(dev, map, "div",
> +                                               &clk->hw,
> +                                               CLK_SET_RATE_PARENT,
> +                                               &meson_sclk_div_ops,
> +                                               div_data);
> +       if (IS_ERR(clk))
> +               return PTR_ERR(clk);
> +
> +       onecell_data->hws[CLKID_MMC_DIV] = &clk->hw;
> +       core = mmc_clkc_register_clk_with_parent(dev, map, "core",
> +                                                &clk->hw,
> +                                                CLK_SET_RATE_PARENT,
> +                                                &meson_clk_phase_ops,
> +                                                &mmc_clkc_core_phase);
> +       if (IS_ERR(core))
> +               return PTR_ERR(core);
> +
> +       onecell_data->hws[CLKID_MMC_PHASE_CORE] = &core->hw;
> +       clk = mmc_clkc_register_clk_with_parent(dev, map, "rx",
> +                                               &core->hw,  0,
> +                                               &meson_clk_phase_delay_ops,
> +                                               &data->rx);
> +       if (IS_ERR(clk))
> +               return PTR_ERR(clk);
> +
> +       onecell_data->hws[CLKID_MMC_PHASE_RX] = &clk->hw;
> +       clk = mmc_clkc_register_clk_with_parent(dev, map, "tx",
> +                                               &core->hw,  0,
> +                                               &meson_clk_phase_delay_ops,
> +                                               &data->tx);
> +       if (IS_ERR(clk))
> +               return PTR_ERR(clk);
> +
> +       onecell_data->hws[CLKID_MMC_PHASE_TX] = &clk->hw;
> +       onecell_data->num = MMC_MAX_CLKS;
> +       return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
> +                                          onecell_data);
> +}
> +
> +static struct platform_driver mmc_clkc_driver = {
> +       .probe          = mmc_clkc_probe,
> +       .driver         = {
> +               .name   = "meson-mmc-clkc",
> +               .of_match_table = of_match_ptr(mmc_clkc_match_table),
> +       },
> +};
> +
> +module_platform_driver(mmc_clkc_driver);
> +
> +MODULE_DESCRIPTION("Amlogic AXG MMC clock driver");
> +MODULE_AUTHOR("Jianxin Pan <jianxin.pan at amlogic.com>");
> +MODULE_LICENSE("GPL v2");


From liang.yang at amlogic.com  Thu Jan 13 19:06:07 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 14 Jan 2022 11:06:07 +0800
Subject: [PATCH v9 3/4] clk: meson: add DT documentation for emmc clock
 controller
In-Reply-To: <20220113212957.768FFC36AE3@smtp.kernel.org>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-4-liang.yang@amlogic.com>
 <20220113212957.768FFC36AE3@smtp.kernel.org>
Message-ID: <5d99ac02-a246-5bcc-2ecb-371b0d193537@amlogic.com>

Hi Stephen,

Thanks for your quick response.

On 2022/1/14 5:29, Stephen Boyd wrote:
> [ EXTERNAL EMAIL ]
> 
> Quoting Liang Yang (2022-01-13 03:57:44)
>> Document the MMC sub clock controller driver, the potential consumer
>> of this driver is MMC or NAND. Also add four clock bindings IDs which
>> provided by this driver.
>>
>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>> ---
>>   .../bindings/clock/amlogic,mmc-clkc.yaml      | 64 +++++++++++++++++++
>>   include/dt-bindings/clock/amlogic,mmc-clkc.h  | 14 ++++
>>   2 files changed, 78 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>>   create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
>>
>> diff --git a/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>> new file mode 100644
>> index 000000000000..a274c3d5fc2e
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>> @@ -0,0 +1,64 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/clock/amlogic,mmc-clkc.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Amlogic MMC Sub Clock Controller Driver Device Tree Bindings
>> +
>> +maintainers:
>> +  - jianxin.pan at amlogic.com
>> +  - liang.yang at amlogic.com
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - "amlogic,axg-mmc-clkc", "syscon"
> 
> Why is it a syscon?

The register documented by reg is shared with SD/eMMC controller port C, 
and it need to be ops on NFC driver.

> 
> .


From liang.yang at amlogic.com  Thu Jan 13 19:07:17 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 14 Jan 2022 11:07:17 +0800
Subject: [PATCH v9 1/4] clk: meson: add one based divider support for sclk
In-Reply-To: <20220113212801.E88BFC36AE3@smtp.kernel.org>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-2-liang.yang@amlogic.com>
 <20220113212801.E88BFC36AE3@smtp.kernel.org>
Message-ID: <98619eef-8b51-c138-e98d-39fdbe4c9ebb@amlogic.com>

Hi Stephen,

On 2022/1/14 5:28, Stephen Boyd wrote:
> [ EXTERNAL EMAIL ]
> 
> Quoting Liang Yang (2022-01-13 03:57:42)
>> diff --git a/drivers/clk/meson/sclk-div.c b/drivers/clk/meson/sclk-div.c
>> index 76d31c0a3342..79c9efd28115 100644
>> --- a/drivers/clk/meson/sclk-div.c
>> +++ b/drivers/clk/meson/sclk-div.c
>> @@ -28,22 +29,39 @@ meson_sclk_div_data(struct clk_regmap *clk)
>>          return (struct meson_sclk_div_data *)clk->data;
>>   }
>>   
>> -static int sclk_div_maxval(struct meson_sclk_div_data *sclk)
>> +static inline int sclk_get_reg(int val, unsigned char flag)
>>   {
>> -       return (1 << sclk->div.width) - 1;
>> +       if ((flag & MESON_SCLK_ONE_BASED) || !val)
>> +               return val;
>> +       else
>> +               return val - 1;
> 
> Please drop the else
ok
> 
>> +}
>> +
>> +static inline int sclk_get_divider(int reg, unsigned char flag)
>> +{
>> +       if (flag & MESON_SCLK_ONE_BASED)
>> +               return reg;
>> +       else
> 
> Please drop the else
ok
> 
>> +               return reg + 1;
>>   }
>>   
>>   static int sclk_div_maxdiv(struct meson_sclk_div_data *sclk)
>>   {
>> -       return sclk_div_maxval(sclk) + 1;
> 
> .


From liang.yang at amlogic.com  Thu Jan 13 19:08:05 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 14 Jan 2022 11:08:05 +0800
Subject: [PATCH v9 2/4] clk: meson: add emmc sub clock phase delay driver
In-Reply-To: <20220113212928.28C10C36AE3@smtp.kernel.org>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-3-liang.yang@amlogic.com>
 <20220113212928.28C10C36AE3@smtp.kernel.org>
Message-ID: <34b86361-a823-4de0-0426-0e0fbc79e550@amlogic.com>



On 2022/1/14 5:29, Stephen Boyd wrote:
> [ EXTERNAL EMAIL ]
> 
> Quoting Liang Yang (2022-01-13 03:57:43)
>> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
>> index b3ef5f67820f..c450f38d3801 100644
>> --- a/drivers/clk/meson/Makefile
>> +++ b/drivers/clk/meson/Makefile
>> @@ -11,6 +11,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o
>>   obj-$(CONFIG_COMMON_CLK_MESON_REGMAP) += clk-regmap.o
>>   obj-$(CONFIG_COMMON_CLK_MESON_SCLK_DIV) += sclk-div.o
>>   obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
>> +obj-$(CONFIG_COMMON_CLK_MESON_PHASE_DELAY) += clk-phase-delay.o
> 
> Sort by Kconfig symbol?
ok, it will fix it.
> 
>>   
>>   # Amlogic Clock controllers
>>
> 
> .


From liang.yang at amlogic.com  Thu Jan 13 21:14:46 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 14 Jan 2022 13:14:46 +0800
Subject: [PATCH v9 4/4] clk: meson: add sub MMC clock controller driver
In-Reply-To: <20220113213513.9819AC36AEA@smtp.kernel.org>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-5-liang.yang@amlogic.com>
 <20220113213513.9819AC36AEA@smtp.kernel.org>
Message-ID: <09ff9044-9abc-d1ad-26c1-5e6ece56d30c@amlogic.com>

Hi Stephen,

On 2022/1/14 5:35, Stephen Boyd wrote:
> [ EXTERNAL EMAIL ]
> 
> Quoting Liang Yang (2022-01-13 03:57:45)
>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>> index bb0f59eea366..3de6f3b24461 100644
>> --- a/drivers/clk/meson/Kconfig
>> +++ b/drivers/clk/meson/Kconfig
>> @@ -39,6 +39,20 @@ config COMMON_CLK_MESON_AO_CLKC
>>          select COMMON_CLK_MESON_REGMAP
>>          select RESET_CONTROLLER
>>   
>> +config COMMON_CLK_MMC_MESON
>> +       tristate "Meson MMC Sub Clock Controller Driver"
>> +       depends on ARCH_MESON || COMPILE_TEST
>> +       select MFD_SYSCON
>> +       select COMMON_CLK_AMLOGIC
>> +       select COMMON_CLK_MESON_PHASE
>> +       select COMMON_CLK_MESON_PHASE_DELAY
>> +       select COMMON_CLK_MESON_SCLK_DIV
>> +       help
>> +         Support for the MMC sub clock controller on
>> +         Amlogic Meson Platform, which includes S905 (GXBB, GXL),
>> +         A113D/X (AXG) devices . Say Y if you want this
> 
> s/devices /devices/
ok, i will fix it
> 
>> +         clock enabled.
>> +
>>   config COMMON_CLK_MESON_EE_CLKC
>>          tristate
>>          select COMMON_CLK_MESON_REGMAP
>> diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c
>> new file mode 100644
>> index 000000000000..f53977f61390
>> --- /dev/null
>> +++ b/drivers/clk/meson/mmc-clkc.c
>> @@ -0,0 +1,300 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>> +/*
>> + * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/module.h>
>> +#include <linux/regmap.h>
>> +#include <linux/slab.h>
>> +#include <linux/of_device.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/platform_device.h>
>> +#include <dt-bindings/clock/amlogic,mmc-clkc.h>
>> +
>> +#include "sclk-div.h"
>> +#include "clk-phase-delay.h"
>> +#include "clk-regmap.h"
>> +#include "clk-phase.h"
>> +
>> +/* clock ID used by internal driver */
>> +
>> +#define SD_EMMC_CLOCK          0
>> +#define CLK_DELAY_STEP_PS_GX   200
>> +#define CLK_DELAY_STEP_PS_AXG  78
>> +#define MUX_CLK_NUM_PARENTS    2
>> +#define MMC_MAX_CLKS           4
>> +
>> +struct mmc_clkc_data {
>> +       struct meson_clk_phase_delay_data tx;
>> +       struct meson_clk_phase_delay_data rx;
>> +};
>> +
>> +static struct clk_regmap_mux_data mmc_clkc_mux_data = {
>> +       .offset = SD_EMMC_CLOCK,
>> +       .mask   = 0x3,
>> +       .shift  = 6,
>> +};
>> +
>> +static const struct meson_sclk_div_data mmc_clkc_div_data = {
>> +       .div = {
>> +               .reg_off = SD_EMMC_CLOCK,
>> +               .width   = 6,
>> +       },
>> +       .flags = MESON_SCLK_ONE_BASED,
>> +};
>> +
>> +static struct meson_clk_phase_data mmc_clkc_core_phase = {
>> +       .ph = {
>> +               .reg_off = SD_EMMC_CLOCK,
>> +               .shift   = 8,
>> +               .width   = 2,
>> +       }
>> +};
>> +
>> +static const struct mmc_clkc_data mmc_clkc_gx_data = {
>> +       .tx = {
>> +               .phase = {
>> +                       .reg_off = SD_EMMC_CLOCK,
>> +                       .shift   = 10,
>> +                       .width   = 2,
>> +               },
>> +               .delay = {
>> +                       .reg_off = SD_EMMC_CLOCK,
>> +                       .shift   = 16,
>> +                       .width   = 4,
>> +               },
>> +               .delay_step_ps = CLK_DELAY_STEP_PS_GX,
>> +       },
>> +       .rx = {
>> +               .phase = {
>> +                       .reg_off = SD_EMMC_CLOCK,
>> +                       .shift   = 12,
>> +                       .width   = 2,
>> +               },
>> +               .delay = {
>> +                       .reg_off = SD_EMMC_CLOCK,
>> +                       .shift   = 20,
>> +                       .width   = 4,
>> +               },
>> +               .delay_step_ps   = CLK_DELAY_STEP_PS_GX,
>> +       },
>> +};
>> +
>> +static const struct mmc_clkc_data mmc_clkc_axg_data = {
>> +       .tx = {
>> +               .phase = {
>> +                       .reg_off = SD_EMMC_CLOCK,
>> +                       .shift   = 10,
>> +                       .width   = 2,
>> +               },
>> +               .delay = {
>> +                       .reg_off = SD_EMMC_CLOCK,
>> +                       .shift   = 16,
>> +                       .width   = 6,
>> +               },
>> +               .delay_step_ps   = CLK_DELAY_STEP_PS_AXG,
>> +       },
>> +       .rx = {
>> +               .phase = {
>> +                       .reg_off = SD_EMMC_CLOCK,
>> +                       .shift   = 12,
>> +                       .width   = 2,
>> +               },
>> +               .delay = {
>> +                       .reg_off = SD_EMMC_CLOCK,
>> +                       .shift   = 22,
>> +                       .width   = 6,
>> +               },
>> +               .delay_step_ps   = CLK_DELAY_STEP_PS_AXG,
>> +       },
>> +};
>> +
>> +static const struct of_device_id mmc_clkc_match_table[] = {
>> +       {
>> +               .compatible     = "amlogic,gx-mmc-clkc",
>> +               .data           = &mmc_clkc_gx_data
>> +       },
>> +       {
>> +               .compatible     = "amlogic,axg-mmc-clkc",
>> +               .data           = &mmc_clkc_axg_data
>> +       },
>> +       {}
>> +};
>> +MODULE_DEVICE_TABLE(of, mmc_clkc_match_table);
>> +
>> +static struct clk_regmap *
>> +mmc_clkc_register_clk(struct device *dev, struct regmap *map,
>> +                     struct clk_init_data *init,
>> +                     const char *suffix, void *data)
>> +{
>> +       struct clk_regmap *clk;
>> +       char *name;
>> +       int ret;
>> +
>> +       clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
>> +       if (!clk)
>> +               return ERR_PTR(-ENOMEM);
>> +
>> +       name = kasprintf(GFP_KERNEL, "%s#%s", dev_name(dev), suffix);
>> +       if (!name)
>> +               return ERR_PTR(-ENOMEM);
>> +
>> +       init->name = name;
>> +       clk->map = map;
>> +       clk->data = data;
>> +       clk->hw.init = init;
>> +       ret = devm_clk_hw_register(dev, &clk->hw);
>> +       if (ret)
>> +               clk = ERR_PTR(ret);
>> +
>> +       kfree(name);
>> +       return clk;
>> +}
>> +
>> +static struct clk_regmap *mmc_clkc_register_mux(struct device *dev,
>> +                                               struct regmap *map)
>> +{
>> +       const char *parent_names[MUX_CLK_NUM_PARENTS];
>> +       struct clk_init_data init;
>> +       struct clk_regmap *mux;
>> +       struct clk *clk;
>> +       int i;
>> +
>> +       for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
>> +               char name[8];
>> +
>> +               snprintf(name, sizeof(name), "clkin%d", i);
>> +               clk = devm_clk_get(dev, name);
>> +               if (IS_ERR(clk)) {
>> +                       if (clk != ERR_PTR(-EPROBE_DEFER))
>> +                               dev_err(dev, "Missing clock %s\n", name);
> 
> Use dev_err_probe()?
ok
> 
>> +                       return ERR_CAST(clk);
>> +               }
>> +
>> +               parent_names[i] = __clk_get_name(clk);
> 
> Why can't we use clk_parent_data?

ok, i will try clk_parent_data.

> 
>> +       }
>> +
>> +       init.ops = &clk_regmap_mux_ops;
>> +       init.flags = CLK_SET_RATE_PARENT;
>> +       init.parent_names = parent_names;
>> +       init.num_parents = MUX_CLK_NUM_PARENTS;
>> +
>> +       mux = mmc_clkc_register_clk(dev, map, &init, "mux", &mmc_clkc_mux_data);
>> +       if (IS_ERR(mux))
>> +               dev_err(dev, "Mux clock registration failed\n");
>> +
>> +       return mux;
>> +}
>> +
>> +static struct clk_regmap *
>> +mmc_clkc_register_clk_with_parent(struct device *dev, struct regmap *map,
>> +                                 char *suffix, const struct clk_hw *hw,
>> +                                 unsigned long flags,
>> +                                 const struct clk_ops *ops, void *data)
>> +{
>> +       struct clk_init_data init;
>> +       struct clk_regmap *clk;
>> +       const char *parent_name = clk_hw_get_name(hw);
>> +
>> +       init.ops = ops;
>> +       init.flags = flags;
>> +       init.parent_names = &parent_name;
>> +       init.num_parents = 1;
>> +
>> +       clk = mmc_clkc_register_clk(dev, map, &init, suffix, data);
>> +       if (IS_ERR(clk))
>> +               dev_err(dev, "%s clock registration failed\n", suffix);
>> +
>> +       return clk;
>> +}
>> +
>> +static int mmc_clkc_probe(struct platform_device *pdev)
>> +{
>> +       struct clk_hw_onecell_data *onecell_data;
>> +       struct device *dev = &pdev->dev;
>> +       struct mmc_clkc_data *data;
>> +       struct regmap *map;
>> +       struct clk_regmap *clk, *core;
>> +       struct meson_sclk_div_data *div_data;
>> +
>> +       /*cast to drop the const in match->data*/
> 
> Space after *, also why do we need to cast away const? The user of this
> pointer passes it all the way down to mmc_clkc_register_clk() which
> could take the data as const void pointer and decide to cast away const
> there.

if use 'const' here, it will report a warning:
drivers/clk/meson/mmc-clkc.c:224:7: error: assignment discards ?const? 
qualifier from pointer targe
t type [-Werror=discarded-qualifiers] 

   data = (const struct mmc_clkc_data *)of_device_get_match_data(dev);

> 
>> +       data = (struct mmc_clkc_data *)of_device_get_match_data(dev);
>> +       if (!data)
>> +               return -ENODEV;
>> +
>> +       map = syscon_node_to_regmap(dev->of_node);
>> +       if (IS_ERR(map)) {
>> +               dev_err(dev, "could not find mmc clock controller\n");
>> +               return PTR_ERR(map);
>> +       }
>> +
>> +       onecell_data = devm_kzalloc(dev,
>> +                                   struct_size(onecell_data, hws,
>> +                                               MMC_MAX_CLKS),
>> +                                   GFP_KERNEL);
>> +       if (!onecell_data)
>> +               return -ENOMEM;
>> +
>> +       clk = mmc_clkc_register_mux(dev, map);
>> +       if (IS_ERR(clk))
>> +               return PTR_ERR(clk);
>> +
>> +       div_data = devm_kzalloc(dev, sizeof(*div_data), GFP_KERNEL);
>> +       if (!div_data)
>> +               return -ENOMEM;
>> +
>> +       memcpy(div_data, &mmc_clkc_div_data, sizeof(*div_data));
>> +       clk = mmc_clkc_register_clk_with_parent(dev, map, "div",
>> +                                               &clk->hw,
>> +                                               CLK_SET_RATE_PARENT,
>> +                                               &meson_sclk_div_ops,
>> +                                               div_data);
>> +       if (IS_ERR(clk))
>> +               return PTR_ERR(clk);
>> +
>> +       onecell_data->hws[CLKID_MMC_DIV] = &clk->hw;
>> +       core = mmc_clkc_register_clk_with_parent(dev, map, "core",
>> +                                                &clk->hw,
>> +                                                CLK_SET_RATE_PARENT,
>> +                                                &meson_clk_phase_ops,
>> +                                                &mmc_clkc_core_phase);
>> +       if (IS_ERR(core))
>> +               return PTR_ERR(core);
>> +
>> +       onecell_data->hws[CLKID_MMC_PHASE_CORE] = &core->hw;
>> +       clk = mmc_clkc_register_clk_with_parent(dev, map, "rx",
>> +                                               &core->hw,  0,
>> +                                               &meson_clk_phase_delay_ops,
>> +                                               &data->rx);
>> +       if (IS_ERR(clk))
>> +               return PTR_ERR(clk);
>> +
>> +       onecell_data->hws[CLKID_MMC_PHASE_RX] = &clk->hw;
>> +       clk = mmc_clkc_register_clk_with_parent(dev, map, "tx",
>> +                                               &core->hw,  0,
>> +                                               &meson_clk_phase_delay_ops,
>> +                                               &data->tx);
>> +       if (IS_ERR(clk))
>> +               return PTR_ERR(clk);
>> +
>> +       onecell_data->hws[CLKID_MMC_PHASE_TX] = &clk->hw;
>> +       onecell_data->num = MMC_MAX_CLKS;
>> +       return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
>> +                                          onecell_data);
>> +}
>> +
>> +static struct platform_driver mmc_clkc_driver = {
>> +       .probe          = mmc_clkc_probe,
>> +       .driver         = {
>> +               .name   = "meson-mmc-clkc",
>> +               .of_match_table = of_match_ptr(mmc_clkc_match_table),
>> +       },
>> +};
>> +
>> +module_platform_driver(mmc_clkc_driver);
>> +
>> +MODULE_DESCRIPTION("Amlogic AXG MMC clock driver");
>> +MODULE_AUTHOR("Jianxin Pan <jianxin.pan at amlogic.com>");
>> +MODULE_LICENSE("GPL v2");
> 
> .


From Jiayi.Zhou at amlogic.com  Thu Jan 13 21:28:46 2022
From: Jiayi.Zhou at amlogic.com (Jiayi Zhou)
Date: Fri, 14 Jan 2022 13:28:46 +0800
Subject: [PATCH] pwm: meson: external clock configuration for s4
In-Reply-To: <ee1b72e6-f18a-2dcc-cba9-6816e6fadc33@amlogic.com>
References: <20211223055833.23466-1-Jiayi.Zhou@amlogic.com>
 <CAFBinCCscyxiTq3-9n8Eq-m+avo19+14DiRke+wGKcRmSmyi4g@mail.gmail.com>
 <ee1b72e6-f18a-2dcc-cba9-6816e6fadc33@amlogic.com>
Message-ID: <29172360-024b-c4d4-e330-b89edfa698e2@amlogic.com>


? 2022/1/13 20:24, Jiayi Zhou ??:
>
>
> ? 2021/12/25 2:24, Martin Blumenstingl ??:
>> Hello,
>>
>> I am adding my thoughts in this email which are in addition to Uwe's comments.
>>
>> Please always Cc the linux-amlogic mailing list when you are sending patches.
>> Currently this patch cannot be found in the mailing list archives,
>> patchwork, ...
> ??? OK, I'll cc the linux-amlogic mailing list when I send the v2 release.
>> On Thu, Dec 23, 2021 at 6:58 AM Jiayi Zhou<Jiayi.Zhou at amlogic.com>  wrote:
>>> From: "jiayi.zhou"<jiayi.zhou at amlogic.com>
>>>
>>> For PWM controller in the Meson-S4 SoC,
>>> PWM needs to obtain an external clock source.
>>> This patch tries to describe them in the DT compatible data.
>> I think this patch does more than what is described here.
>> It adds support for the constant high/low output, which is a feature
>> which I think has been introduced on the G12A SoC. I suggest having a
>> separate patch for this and also enabling it on supported SoCs (not
>> just the S4).
> ??? The relevant code has been removed in the v2 version.
>> [...]
>>> +#define PWM_DISABLE            0
>> I don't see this being used anywhere so I think it can be dropped
> ??? code has been removed in v2 verison.
>> [...]
>>> +       /*
>>> +        * duty_cycle equal 0% and 100%,constant should be enabled,
>>> +        * high and low count will not incease one;
>> typo: incease -> increase
> ??? It has been modified in v2 version.
>> [...]
>>> +       if (meson->data->extern_clk) {
>>> +               set_clk = clk_get_rate(channel->clk);
>>> +               if (set_clk == 0)
>>> +                       dev_err(meson->chip.dev, "invalid source clock frequency\n");
>>> +               set_clk /= (channel->pre_div + 1);
>>> +               err = clk_set_rate(channel->clk, set_clk);
>>> +               if (err)
>>> +                       dev_err(meson->chip.dev, "%s: error in setting pwm rate!\n", __func__);
>>> +       }
>>> +
>>>          value = readl(meson->base + REG_MISC_AB);
>>>          value &= ~(MISC_CLK_DIV_MASK << channel_data->clk_div_shift);
>>>          value |= channel->pre_div << channel_data->clk_div_shift;
>> Why does this new controller version require clk_set_rate with a rate
>> that's calculated based on the pre-divider and then also configuring
>> the pre-divider in the MISC_AB register?
>> This seems odd, can't we use only one of them (either clk_set_rate or
>> setting MISC_AB)?
>>
>> Also if clk_set_rate is the way to go here I suggest refactoring the
>> existing code so the pre-divider is a clock as well so we can use
>> clk_set_rate for both, the "old" and "new" IP version.
>
> ?This part of the code was refactored in the v2 version, using 
> clk_set_rate to
>
> ?differentiate the "old" and "new" IP versions.
>
>> [...]
>>> +static const struct meson_pwm_data pwm_meson_data = {
>>> +       .extern_clk = true,
>>>   };
>> [...]
>>> +static int meson_pwm_v2_init_channels(struct meson_pwm *meson)
>>> +{
>>> +       struct meson_pwm_channel *channels = meson->channels;
>>> +       struct device *dev = meson->chip.dev;
>>> +       unsigned int i;
>>> +       char name[255];
>>> +
>>> +       for (i = 0; i < (meson->chip.npwm / 2); i++) {
>>> +               snprintf(name, sizeof(name), "clkin%u", i);
>>> +               (channels + i)->clk = devm_clk_get(dev, name);
>>> +               if (IS_ERR((channels + i)->clk)) {
>>> +                       dev_err(meson->chip.dev, "can't get device clock\n");
>>> +                       return PTR_ERR((channels + i)->clk);
>>> +               }
>>> +               (channels + i + 2)->clk = (channels + i)->clk;
>>> +       }
>> I think this is whole function is broken.
>> The vendor driver uses four channels per PWM controller on newer SoCs.
>> In the mainline driver we only support two PWM channels per controller.
>>
>> Now the whole loop starts with npwm / 2 which is always 1 in the
>> mainline driver.
>> This is the first problem: this would never initialize the second PWM.
>> The second problem is that "channels + i + 2" would access channels[0
>> + 2] which is out of bounds for this array (that array only holds two
>> values so only index 0 and 1 are valid)..
>
> ?This part of the code has been fixed in the v2 version.
>
>> Best regards,
>> Martin
>>
>> .


From narmstrong at baylibre.com  Fri Jan 14 00:23:51 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri, 14 Jan 2022 09:23:51 +0100
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
Message-ID: <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>

Hi,

On 13/01/2022 21:01, Fabio Estevam wrote:
> Hi Biju,
> 
> On Thu, Jan 13, 2022 at 2:45 PM Biju Das <biju.das.jz at bp.renesas.com> wrote:
>>
>> Hi All,
>>
>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour) till the commit
>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts callbacks").
>>
>> After this patch, the screen becomes greenish(may be it is setting it into YUV format??).
>>
>> By checking the code, previously it used to call get_input_fmt callback and set colour as RGB24.
>>
>> After this commit, it calls get_output_fmt_callbck and returns 3 outputformats(YUV16, YUV24 and RGB24)
>> And get_input_fmt callback, I see the outputformat as YUV16 instead of RGB24.
>>
>> Not sure, I am the only one seeing this issue with dw_HDMI driver.

This patch was introduced to maintain the bridge color format negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR,
but it seems it behaves incorrectly if the first bridge doesn't implement the negotiation callbacks.

Let me check the code to see how to fix that.

> 
> I have tested linux-next 20220112 on a imx6q-sabresd board, which shows:
> 
> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with HDCP
> (DWC HDMI 3D TX PHY)
> 
> The colors are shown correctly here.
> 

The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the negotiation fails and use the RGB fallback input & output format.

Anyway thanks for testing

Neil


From biju.das.jz at bp.renesas.com  Fri Jan 14 00:29:28 2022
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Fri, 14 Jan 2022 08:29:28 +0000
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
Message-ID: <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>

Hi Neil,
 
+ renesas-soc

> Subject: Re: dw_hdmi is showing wrong colour after commit
> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> callbacks")
> 
> Hi,
> 
> On 13/01/2022 21:01, Fabio Estevam wrote:
> > Hi Biju,
> >
> > On Thu, Jan 13, 2022 at 2:45 PM Biju Das <biju.das.jz at bp.renesas.com>
> wrote:
> >>
> >> Hi All,
> >>
> >> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour) till
> >> the commit
> >> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> callbacks").
> >>
> >> After this patch, the screen becomes greenish(may be it is setting it
> into YUV format??).
> >>
> >> By checking the code, previously it used to call get_input_fmt callback
> and set colour as RGB24.
> >>
> >> After this commit, it calls get_output_fmt_callbck and returns 3
> >> outputformats(YUV16, YUV24 and RGB24) And get_input_fmt callback, I see
> the outputformat as YUV16 instead of RGB24.
> >>
> >> Not sure, I am the only one seeing this issue with dw_HDMI driver.
> 
> This patch was introduced to maintain the bridge color format negotiation
> after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it seems it behaves
> incorrectly if the first bridge doesn't implement the negotiation
> callbacks.
> 
> Let me check the code to see how to fix that.

Thanks for the information, I am happy to test the patch/fix.

Cheers,
Biju

> 
> >
> > I have tested linux-next 20220112 on a imx6q-sabresd board, which shows:
> >
> > dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with HDCP
> > (DWC HDMI 3D TX PHY)
> >
> > The colors are shown correctly here.
> >
> 
> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the negotiation
> fails and use the RGB fallback input & output format.
> 
> Anyway thanks for testing
> 
> Neil

From jiayi.zhou at amlogic.com  Fri Jan 14 00:39:29 2022
From: jiayi.zhou at amlogic.com (jiayi.zhou at amlogic.com)
Date: Fri, 14 Jan 2022 16:39:29 +0800
Subject: [PATCH v2] dt-bindings: pwm: Update bindings for the Meson-S4
Message-ID: <20220114083929.2910-1-jiayi.zhou@amlogic.com>

From: "Jiayi.zhou" <jiayi.zhou at amlogic.com>

Update the doc to explicitly support Meson-S4

Signed-off-by: Jiayi.zhou <jiayi.zhou at amlogic.com>
---
 Documentation/devicetree/bindings/pwm/pwm-meson.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pwm/pwm-meson.txt b/Documentation/devicetree/bindings/pwm/pwm-meson.txt
index bd02b0a1496f..0fbedf20074f 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-meson.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-meson.txt
@@ -10,6 +10,7 @@ Required properties:
                          or "amlogic,meson-g12a-ee-pwm"
                          or "amlogic,meson-g12a-ao-pwm-ab"
                          or "amlogic,meson-g12a-ao-pwm-cd"
+                         or "amlogic,meson-s4-pwm"
 - #pwm-cells: Should be 3. See pwm.yaml in this directory for a description of
   the cells format.
 
-- 
2.34.1



From Jiayi.Zhou at amlogic.com  Fri Jan 14 01:07:53 2022
From: Jiayi.Zhou at amlogic.com (Jiayi.Zhou at amlogic.com)
Date: Fri, 14 Jan 2022 17:07:53 +0800
Subject: [PATCH v2] pwm: meson: external clock configuration for s4
Message-ID: <20220114090753.34873-1-Jiayi.Zhou@amlogic.com>

From: "Jiayi.zhou" <jiayi.zhou at amlogic.com>

For PWM controller in the Meson-S4 SoC,
PWM needs to obtain an external clock source.
This patch tries to describe them in the DT compatible data.

Signed-off-by: Jiayi.zhou <jiayi.zhou at amlogic.com>
---
 drivers/pwm/pwm-meson.c | 145 ++++++++++++++++++++++++++++++----------
 1 file changed, 110 insertions(+), 35 deletions(-)

diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
index 3cf3bcf5ddfc..54db56c95be2 100644
--- a/drivers/pwm/pwm-meson.c
+++ b/drivers/pwm/pwm-meson.c
@@ -51,6 +51,7 @@
 #define REG_MISC_AB		0x8
 #define MISC_B_CLK_EN		BIT(23)
 #define MISC_A_CLK_EN		BIT(15)
+
 #define MISC_CLK_DIV_MASK	0x7f
 #define MISC_B_CLK_DIV_SHIFT	16
 #define MISC_A_CLK_DIV_SHIFT	8
@@ -93,11 +94,13 @@ struct meson_pwm_channel {
 	struct clk *clk_parent;
 	struct clk_mux mux;
 	struct clk *clk;
+	struct clk *clk_mux;
 };
 
 struct meson_pwm_data {
 	const char * const *parent_names;
 	unsigned int num_parents;
+	unsigned int extern_clk;
 };
 
 struct meson_pwm {
@@ -105,6 +108,7 @@ struct meson_pwm {
 	const struct meson_pwm_data *data;
 	struct meson_pwm_channel channels[MESON_NUM_PWMS];
 	void __iomem *base;
+
 	/*
 	 * Protects register (write) access to the REG_MISC_AB register
 	 * that is shared between the two PWMs.
@@ -130,13 +134,15 @@ static int meson_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
 
 	channel = &meson->channels[pwm->hwpwm];
 
-	if (channel->clk_parent) {
-		err = clk_set_parent(channel->clk, channel->clk_parent);
-		if (err < 0) {
-			dev_err(dev, "failed to set parent %s for %s: %d\n",
-				__clk_get_name(channel->clk_parent),
-				__clk_get_name(channel->clk), err);
-			return err;
+	if (!meson->data->extern_clk) {
+		if (channel->clk_parent) {
+			err = clk_set_parent(channel->clk, channel->clk_parent);
+			if (err < 0) {
+				dev_err(dev, "failed to set parent %s for %s: %d\n",
+					__clk_get_name(channel->clk_parent),
+					__clk_get_name(channel->clk), err);
+					return err;
+			}
 		}
 	}
 
@@ -171,7 +177,11 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
 	if (state->polarity == PWM_POLARITY_INVERSED)
 		duty = period - duty;
 
-	fin_freq = clk_get_rate(channel->clk);
+	if (meson->data->extern_clk) {
+		fin_freq = clk_get_rate(channel->clk_mux);
+	} else {
+		fin_freq = clk_get_rate(channel->clk);
+	}
 	if (fin_freq == 0) {
 		dev_err(meson->chip.dev, "invalid source clock frequency\n");
 		return -EINVAL;
@@ -228,17 +238,32 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
 	struct meson_pwm_channel_data *channel_data;
 	unsigned long flags;
 	u32 value;
+	unsigned long set_clk;
+	u32 err;
 
 	channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];
 
-	spin_lock_irqsave(&meson->lock, flags);
-
 	value = readl(meson->base + REG_MISC_AB);
-	value &= ~(MISC_CLK_DIV_MASK << channel_data->clk_div_shift);
-	value |= channel->pre_div << channel_data->clk_div_shift;
-	value |= channel_data->clk_en_mask;
-	writel(value, meson->base + REG_MISC_AB);
+	if (meson->data->extern_clk) {
+		set_clk = clk_get_rate(channel->clk_mux);
+
+		if (set_clk == 0)
+			dev_err(meson->chip.dev, "invalid source clock frequency\n");
+		set_clk /= channel->pre_div + 1;
+		err = clk_set_rate(channel->clk, set_clk);
+		if (err)
+			dev_err(meson->chip.dev, "%s: error in setting pwm rate!\n", __func__);
+	} else {
+		spin_lock_irqsave(&meson->lock, flags);
+
+		value &= ~(MISC_CLK_DIV_MASK << channel_data->clk_div_shift);
+		value |= channel->pre_div << channel_data->clk_div_shift;
+		value |= channel_data->clk_en_mask;
+		writel(value, meson->base + REG_MISC_AB);
 
+		spin_unlock_irqrestore(&meson->lock, flags);
+	}
+	spin_lock_irqsave(&meson->lock, flags);
 	value = FIELD_PREP(PWM_HIGH_MASK, channel->hi) |
 		FIELD_PREP(PWM_LOW_MASK, channel->lo);
 	writel(value, meson->base + channel_data->reg_offset);
@@ -246,7 +271,6 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
 	value = readl(meson->base + REG_MISC_AB);
 	value |= channel_data->pwm_en_mask;
 	writel(value, meson->base + REG_MISC_AB);
-
 	spin_unlock_irqrestore(&meson->lock, flags);
 }
 
@@ -333,7 +357,8 @@ static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
 	struct meson_pwm *meson = to_meson_pwm(chip);
 	struct meson_pwm_channel_data *channel_data;
 	struct meson_pwm_channel *channel;
-	u32 value, tmp;
+	u32 value_pwm, value, tmp;
+	unsigned long gate_clk, fre;
 
 	if (!state)
 		return;
@@ -341,30 +366,42 @@ static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
 	channel = &meson->channels[pwm->hwpwm];
 	channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];
 
-	value = readl(meson->base + REG_MISC_AB);
-
-	tmp = channel_data->pwm_en_mask | channel_data->clk_en_mask;
-	state->enabled = (value & tmp) == tmp;
-
-	tmp = value >> channel_data->clk_div_shift;
-	channel->pre_div = FIELD_GET(MISC_CLK_DIV_MASK, tmp);
-
+	value_pwm = readl(meson->base + REG_MISC_AB);
 	value = readl(meson->base + channel_data->reg_offset);
 
 	channel->lo = FIELD_GET(PWM_LOW_MASK, value);
 	channel->hi = FIELD_GET(PWM_HIGH_MASK, value);
 
-	if (channel->lo == 0) {
-		state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->hi);
-		state->duty_cycle = state->period;
-	} else if (channel->lo >= channel->hi) {
-		state->period = meson_pwm_cnt_to_ns(chip, pwm,
-						    channel->lo + channel->hi);
-		state->duty_cycle = meson_pwm_cnt_to_ns(chip, pwm,
-							channel->hi);
+	if (meson->data->extern_clk) {
+		gate_clk = clk_get_rate(channel->clk);
+		fre = gate_clk / (channel->lo + channel->hi);
+		state->period = div_u64(NSEC_PER_SEC, fre);
+		state->duty_cycle = div_u64(state->period * channel->hi, channel->lo + channel->hi);
+		tmp = channel_data->pwm_en_mask;
+
+		if (((value_pwm & tmp) == tmp) && __clk_is_enabled(channel->clk))
+			state->enabled = true;
+		else
+			state->enabled = false;
 	} else {
-		state->period = 0;
-		state->duty_cycle = 0;
+		tmp = channel_data->pwm_en_mask | channel_data->clk_en_mask;
+
+		state->enabled = (value_pwm & tmp) == tmp;
+
+		tmp = value_pwm >> channel_data->clk_div_shift;
+		channel->pre_div = FIELD_GET(MISC_CLK_DIV_MASK, tmp);
+
+		if (channel->lo == 0) {
+			state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->hi);
+			state->duty_cycle = state->period;
+		} else if (channel->lo >= channel->hi) {
+			state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->lo
+							    + channel->hi);
+			state->duty_cycle = meson_pwm_cnt_to_ns(chip, pwm, channel->hi);
+		} else {
+			state->period = 0;
+			state->duty_cycle = 0;
+		}
 	}
 }
 
@@ -452,6 +489,10 @@ static const struct meson_pwm_data pwm_g12a_ee_data = {
 	.num_parents = ARRAY_SIZE(pwm_g12a_ee_parent_names),
 };
 
+static const struct meson_pwm_data pwm_meson_data = {
+	.extern_clk = true,
+};
+
 static const struct of_device_id meson_pwm_matches[] = {
 	{
 		.compatible = "amlogic,meson8b-pwm",
@@ -485,6 +526,10 @@ static const struct of_device_id meson_pwm_matches[] = {
 		.compatible = "amlogic,meson-g12a-ao-pwm-cd",
 		.data = &pwm_g12a_ao_cd_data
 	},
+	{
+		.compatible = "amlogic,meson-s4-pwm",
+		.data = &pwm_meson_data
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, meson_pwm_matches);
@@ -534,6 +579,33 @@ static int meson_pwm_init_channels(struct meson_pwm *meson)
 	return 0;
 }
 
+static int meson_pwm_extern_init_channels(struct meson_pwm *meson)
+{
+	struct meson_pwm_channel *channels = meson->channels;
+	struct device *dev = meson->chip.dev;
+	unsigned int i;
+	char name[255];
+
+	for (i = 0; i < meson->chip.npwm; i++) {
+		snprintf(name, sizeof(name), "clkin%u", i);
+		(channels + i)->clk = devm_clk_get(dev, name);
+		if (IS_ERR((channels + i)->clk)) {
+			dev_err_probe(meson->chip.dev, PTR_ERR((channels + i)->clk),
+				      "can't get device clock\n");
+			return PTR_ERR((channels + i)->clk);
+		}
+		snprintf(name, sizeof(name), "mux%u", i);
+		(channels + i)->clk_mux = devm_clk_get(dev, name);
+		if (IS_ERR((channels + i)->clk_mux)) {
+			dev_err_probe(meson->chip.dev, PTR_ERR((channels + i)->clk_mux),
+				      "can't get device clock\n");
+			return PTR_ERR((channels + i)->clk_mux);
+		}
+	}
+
+	return 0;
+}
+
 static int meson_pwm_probe(struct platform_device *pdev)
 {
 	struct meson_pwm *meson;
@@ -553,8 +625,11 @@ static int meson_pwm_probe(struct platform_device *pdev)
 	meson->chip.npwm = MESON_NUM_PWMS;
 
 	meson->data = of_device_get_match_data(&pdev->dev);
+	if (meson->data->extern_clk)
+		err = meson_pwm_extern_init_channels(meson);
+	else
+		err = meson_pwm_init_channels(meson);
 
-	err = meson_pwm_init_channels(meson);
 	if (err < 0)
 		return err;
 
-- 
2.34.1



From narmstrong at baylibre.com  Fri Jan 14 02:16:04 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri, 14 Jan 2022 11:16:04 +0100
Subject: [PATCH v2] pwm: meson: external clock configuration for s4
In-Reply-To: <20220114090753.34873-1-Jiayi.Zhou@amlogic.com>
References: <20220114090753.34873-1-Jiayi.Zhou@amlogic.com>
Message-ID: <07581fb8-0cd9-5b76-6fa3-1d1a7353d944@baylibre.com>

Hi,

On 14/01/2022 10:07, Jiayi.Zhou at amlogic.com wrote:
> From: "Jiayi.zhou" <jiayi.zhou at amlogic.com>
> 
> For PWM controller in the Meson-S4 SoC,
> PWM needs to obtain an external clock source.
> This patch tries to describe them in the DT compatible data.

Can you be more explicit here ? On which SoC ? Why ?

As I understand while reading the S805X2 datasheet, now the PWM clock input is
done in independent CLKCTRL registers and no more in the PWM registers, right ?

So with S4, instead of passing the mux input clock of clkin0 & clkin1, now you pass
the PWM mux output clock.

> 
> Signed-off-by: Jiayi.zhou <jiayi.zhou at amlogic.com>
> ---
>  drivers/pwm/pwm-meson.c | 145 ++++++++++++++++++++++++++++++----------
>  1 file changed, 110 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
> index 3cf3bcf5ddfc..54db56c95be2 100644
> --- a/drivers/pwm/pwm-meson.c
> +++ b/drivers/pwm/pwm-meson.c
> @@ -51,6 +51,7 @@
>  #define REG_MISC_AB		0x8
>  #define MISC_B_CLK_EN		BIT(23)
>  #define MISC_A_CLK_EN		BIT(15)
> +
>  #define MISC_CLK_DIV_MASK	0x7f
>  #define MISC_B_CLK_DIV_SHIFT	16
>  #define MISC_A_CLK_DIV_SHIFT	8
> @@ -93,11 +94,13 @@ struct meson_pwm_channel {
>  	struct clk *clk_parent;
>  	struct clk_mux mux;
>  	struct clk *clk;
> +	struct clk *clk_mux;

Why do you add a mux ?

>  };
>  
>  struct meson_pwm_data {
>  	const char * const *parent_names;
>  	unsigned int num_parents;
> +	unsigned int extern_clk;
>  };
>  
>  struct meson_pwm {
> @@ -105,6 +108,7 @@ struct meson_pwm {
>  	const struct meson_pwm_data *data;
>  	struct meson_pwm_channel channels[MESON_NUM_PWMS];
>  	void __iomem *base;
> +
>  	/*
>  	 * Protects register (write) access to the REG_MISC_AB register
>  	 * that is shared between the two PWMs.
> @@ -130,13 +134,15 @@ static int meson_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
>  
>  	channel = &meson->channels[pwm->hwpwm];
>  
> -	if (channel->clk_parent) {
> -		err = clk_set_parent(channel->clk, channel->clk_parent);
> -		if (err < 0) {
> -			dev_err(dev, "failed to set parent %s for %s: %d\n",
> -				__clk_get_name(channel->clk_parent),
> -				__clk_get_name(channel->clk), err);
> -			return err;
> +	if (!meson->data->extern_clk) {
> +		if (channel->clk_parent) {
> +			err = clk_set_parent(channel->clk, channel->clk_parent);
> +			if (err < 0) {
> +				dev_err(dev, "failed to set parent %s for %s: %d\n",
> +					__clk_get_name(channel->clk_parent),
> +					__clk_get_name(channel->clk), err);
> +					return err;
> +			}
>  		}
>  	}
>  
> @@ -171,7 +177,11 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
>  	if (state->polarity == PWM_POLARITY_INVERSED)
>  		duty = period - duty;
>  
> -	fin_freq = clk_get_rate(channel->clk);
> +	if (meson->data->extern_clk) {
> +		fin_freq = clk_get_rate(channel->clk_mux);> +	} else {
> +		fin_freq = clk_get_rate(channel->clk);
> +	}
>  	if (fin_freq == 0) {
>  		dev_err(meson->chip.dev, "invalid source clock frequency\n");
>  		return -EINVAL;
> @@ -228,17 +238,32 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
>  	struct meson_pwm_channel_data *channel_data;
>  	unsigned long flags;
>  	u32 value;
> +	unsigned long set_clk;
> +	u32 err;
>  
>  	channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];
>  
> -	spin_lock_irqsave(&meson->lock, flags);
> -
>  	value = readl(meson->base + REG_MISC_AB);
> -	value &= ~(MISC_CLK_DIV_MASK << channel_data->clk_div_shift);
> -	value |= channel->pre_div << channel_data->clk_div_shift;
> -	value |= channel_data->clk_en_mask;
> -	writel(value, meson->base + REG_MISC_AB);
> +	if (meson->data->extern_clk) {
> +		set_clk = clk_get_rate(channel->clk_mux);
> +
> +		if (set_clk == 0)
> +			dev_err(meson->chip.dev, "invalid source clock frequency\n");
> +		set_clk /= channel->pre_div + 1;
> +		err = clk_set_rate(channel->clk, set_clk);
> +		if (err)
> +			dev_err(meson->chip.dev, "%s: error in setting pwm rate!\n", __func__);
> +	} else {
> +		spin_lock_irqsave(&meson->lock, flags);
> +
> +		value &= ~(MISC_CLK_DIV_MASK << channel_data->clk_div_shift);
> +		value |= channel->pre_div << channel_data->clk_div_shift;
> +		value |= channel_data->clk_en_mask;
> +		writel(value, meson->base + REG_MISC_AB);
>  
> +		spin_unlock_irqrestore(&meson->lock, flags);
> +	}
> +	spin_lock_irqsave(&meson->lock, flags);
>  	value = FIELD_PREP(PWM_HIGH_MASK, channel->hi) |
>  		FIELD_PREP(PWM_LOW_MASK, channel->lo);
>  	writel(value, meson->base + channel_data->reg_offset);
> @@ -246,7 +271,6 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
>  	value = readl(meson->base + REG_MISC_AB);
>  	value |= channel_data->pwm_en_mask;
>  	writel(value, meson->base + REG_MISC_AB);
> -
>  	spin_unlock_irqrestore(&meson->lock, flags);
>  }
>  
> @@ -333,7 +357,8 @@ static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
>  	struct meson_pwm *meson = to_meson_pwm(chip);
>  	struct meson_pwm_channel_data *channel_data;
>  	struct meson_pwm_channel *channel;
> -	u32 value, tmp;
> +	u32 value_pwm, value, tmp;
> +	unsigned long gate_clk, fre;
>  
>  	if (!state)
>  		return;
> @@ -341,30 +366,42 @@ static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
>  	channel = &meson->channels[pwm->hwpwm];
>  	channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];
>  
> -	value = readl(meson->base + REG_MISC_AB);
> -
> -	tmp = channel_data->pwm_en_mask | channel_data->clk_en_mask;
> -	state->enabled = (value & tmp) == tmp;
> -
> -	tmp = value >> channel_data->clk_div_shift;
> -	channel->pre_div = FIELD_GET(MISC_CLK_DIV_MASK, tmp);
> -
> +	value_pwm = readl(meson->base + REG_MISC_AB);
>  	value = readl(meson->base + channel_data->reg_offset);
>  
>  	channel->lo = FIELD_GET(PWM_LOW_MASK, value);
>  	channel->hi = FIELD_GET(PWM_HIGH_MASK, value);
>  
> -	if (channel->lo == 0) {
> -		state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->hi);
> -		state->duty_cycle = state->period;
> -	} else if (channel->lo >= channel->hi) {
> -		state->period = meson_pwm_cnt_to_ns(chip, pwm,
> -						    channel->lo + channel->hi);
> -		state->duty_cycle = meson_pwm_cnt_to_ns(chip, pwm,
> -							channel->hi);
> +	if (meson->data->extern_clk) {
> +		gate_clk = clk_get_rate(channel->clk);
> +		fre = gate_clk / (channel->lo + channel->hi);
> +		state->period = div_u64(NSEC_PER_SEC, fre);
> +		state->duty_cycle = div_u64(state->period * channel->hi, channel->lo + channel->hi);
> +		tmp = channel_data->pwm_en_mask;
> +
> +		if (((value_pwm & tmp) == tmp) && __clk_is_enabled(channel->clk))
> +			state->enabled = true;
> +		else
> +			state->enabled = false;
>  	} else {
> -		state->period = 0;
> -		state->duty_cycle = 0;
> +		tmp = channel_data->pwm_en_mask | channel_data->clk_en_mask;
> +
> +		state->enabled = (value_pwm & tmp) == tmp;
> +
> +		tmp = value_pwm >> channel_data->clk_div_shift;
> +		channel->pre_div = FIELD_GET(MISC_CLK_DIV_MASK, tmp);
> +
> +		if (channel->lo == 0) {
> +			state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->hi);
> +			state->duty_cycle = state->period;
> +		} else if (channel->lo >= channel->hi) {
> +			state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->lo
> +							    + channel->hi);
> +			state->duty_cycle = meson_pwm_cnt_to_ns(chip, pwm, channel->hi);
> +		} else {
> +			state->period = 0;
> +			state->duty_cycle = 0;
> +		}
>  	}
>  }

You need to rewrite the clock calculation entirely, instead of relying on a fin_freq, you need
to set_rate() the needed rate to the input clock, then calculate the periods on the rate
set by CCF.

One way is to forget trying to set a rate of the input clock, simply get_rate() of the input clock
and try to calculate periods on it.

Instead rely on assignes-clock-parent & assigned-clock-rate in DT to set the right parent of the mux
and rate of the mux post divider to feed to correct rate to the PWM controller.

>  
> @@ -452,6 +489,10 @@ static const struct meson_pwm_data pwm_g12a_ee_data = {
>  	.num_parents = ARRAY_SIZE(pwm_g12a_ee_parent_names),
>  };
>  
> +static const struct meson_pwm_data pwm_meson_data = {
> +	.extern_clk = true,
> +};
> +
>  static const struct of_device_id meson_pwm_matches[] = {
>  	{
>  		.compatible = "amlogic,meson8b-pwm",
> @@ -485,6 +526,10 @@ static const struct of_device_id meson_pwm_matches[] = {
>  		.compatible = "amlogic,meson-g12a-ao-pwm-cd",
>  		.data = &pwm_g12a_ao_cd_data
>  	},
> +	{
> +		.compatible = "amlogic,meson-s4-pwm",
> +		.data = &pwm_meson_data
> +	},
>  	{},
>  };
>  MODULE_DEVICE_TABLE(of, meson_pwm_matches);
> @@ -534,6 +579,33 @@ static int meson_pwm_init_channels(struct meson_pwm *meson)
>  	return 0;
>  }
>  
> +static int meson_pwm_extern_init_channels(struct meson_pwm *meson)
> +{
> +	struct meson_pwm_channel *channels = meson->channels;
> +	struct device *dev = meson->chip.dev;
> +	unsigned int i;
> +	char name[255];
> +
> +	for (i = 0; i < meson->chip.npwm; i++) {
> +		snprintf(name, sizeof(name), "clkin%u", i);
> +		(channels + i)->clk = devm_clk_get(dev, name);
> +		if (IS_ERR((channels + i)->clk)) {
> +			dev_err_probe(meson->chip.dev, PTR_ERR((channels + i)->clk),
> +				      "can't get device clock\n");
> +			return PTR_ERR((channels + i)->clk);
> +		}
> +		snprintf(name, sizeof(name), "mux%u", i);
> +		(channels + i)->clk_mux = devm_clk_get(dev, name);
> +		if (IS_ERR((channels + i)->clk_mux)) {
> +			dev_err_probe(meson->chip.dev, PTR_ERR((channels + i)->clk_mux),
> +				      "can't get device clock\n");
> +			return PTR_ERR((channels + i)->clk_mux);

If you add mux you'll need to changes the bindings.

> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  static int meson_pwm_probe(struct platform_device *pdev)
>  {
>  	struct meson_pwm *meson;
> @@ -553,8 +625,11 @@ static int meson_pwm_probe(struct platform_device *pdev)
>  	meson->chip.npwm = MESON_NUM_PWMS;
>  
>  	meson->data = of_device_get_match_data(&pdev->dev);
> +	if (meson->data->extern_clk)
> +		err = meson_pwm_extern_init_channels(meson);
> +	else
> +		err = meson_pwm_init_channels(meson);
>  
> -	err = meson_pwm_init_channels(meson);
>  	if (err < 0)
>  		return err;
>  
> 



From narmstrong at baylibre.com  Fri Jan 14 02:42:35 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri, 14 Jan 2022 11:42:35 +0100
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
Message-ID: <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>

On 14/01/2022 09:29, Biju Das wrote:
> Hi Neil,
>  
> + renesas-soc
> 
>> Subject: Re: dw_hdmi is showing wrong colour after commit
>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>> callbacks")
>>
>> Hi,
>>
>> On 13/01/2022 21:01, Fabio Estevam wrote:
>>> Hi Biju,
>>>
>>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das <biju.das.jz at bp.renesas.com>
>> wrote:
>>>>
>>>> Hi All,
>>>>
>>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour) till
>>>> the commit
>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>> callbacks").
>>>>
>>>> After this patch, the screen becomes greenish(may be it is setting it
>> into YUV format??).
>>>>
>>>> By checking the code, previously it used to call get_input_fmt callback
>> and set colour as RGB24.
>>>>
>>>> After this commit, it calls get_output_fmt_callbck and returns 3
>>>> outputformats(YUV16, YUV24 and RGB24) And get_input_fmt callback, I see
>> the outputformat as YUV16 instead of RGB24.
>>>>
>>>> Not sure, I am the only one seeing this issue with dw_HDMI driver.
>>
>> This patch was introduced to maintain the bridge color format negotiation
>> after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it seems it behaves
>> incorrectly if the first bridge doesn't implement the negotiation
>> callbacks.
>>
>> Let me check the code to see how to fix that.
> 
> Thanks for the information, I am happy to test the patch/fix.
> 
> Cheers,
> Biju
> 
>>
>>>
>>> I have tested linux-next 20220112 on a imx6q-sabresd board, which shows:
>>>
>>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with HDCP
>>> (DWC HDMI 3D TX PHY)
>>>
>>> The colors are shown correctly here.
>>>
>>
>> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the negotiation
>> fails and use the RGB fallback input & output format.
>>
>> Anyway thanks for testing
>>
>> Neil

Can you test :

==><===============================
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index c96847fc0ebc..7019acd37716 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -955,7 +955,14 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
        last_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state,
                                                            last_bridge);

-       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
+       /*
+        * Only negociate with real values if both end of the bridge chain
+        * support negociation callbacks, otherwise you can end in a situation
+        * where the selected output format doesn't match with the first bridge
+        * output format.
+        */
+       if (bridge->funcs->atomic_get_input_bus_fmts &&
+           last_bridge->funcs->atomic_get_output_bus_fmts) {
                const struct drm_bridge_funcs *funcs = last_bridge->funcs;

                /*
@@ -980,7 +987,12 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
                if (!out_bus_fmts)
                        return -ENOMEM;

-               if (conn->display_info.num_bus_formats &&
+               /*
+                * If first bridge doesn't support negociation, use MEDIA_BUS_FMT_FIXED
+                * as a safe value for the whole bridge chain
+                */
+               if (bridge->funcs->atomic_get_input_bus_fmts &&
+                   conn->display_info.num_bus_formats &&
                    conn->display_info.bus_formats)
                        out_bus_fmts[0] = conn->display_info.bus_formats[0];
                else
==><===============================

This should exclude your situation where the first bridge doesn't support negociation.

Neil


From biju.das.jz at bp.renesas.com  Fri Jan 14 03:08:45 2022
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Fri, 14 Jan 2022 11:08:45 +0000
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
Message-ID: <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>

Hi Neil,

> Subject: Re: dw_hdmi is showing wrong colour after commit
> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> callbacks")
> 
> On 14/01/2022 09:29, Biju Das wrote:
> > Hi Neil,
> >
> > + renesas-soc
> >
> >> Subject: Re: dw_hdmi is showing wrong colour after commit
> >> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> >> callbacks")
> >>
> >> Hi,
> >>
> >> On 13/01/2022 21:01, Fabio Estevam wrote:
> >>> Hi Biju,
> >>>
> >>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das
> >>> <biju.das.jz at bp.renesas.com>
> >> wrote:
> >>>>
> >>>> Hi All,
> >>>>
> >>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour)
> >>>> till the commit
> >>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> >> callbacks").
> >>>>
> >>>> After this patch, the screen becomes greenish(may be it is setting
> >>>> it
> >> into YUV format??).
> >>>>
> >>>> By checking the code, previously it used to call get_input_fmt
> >>>> callback
> >> and set colour as RGB24.
> >>>>
> >>>> After this commit, it calls get_output_fmt_callbck and returns 3
> >>>> outputformats(YUV16, YUV24 and RGB24) And get_input_fmt callback, I
> >>>> see
> >> the outputformat as YUV16 instead of RGB24.
> >>>>
> >>>> Not sure, I am the only one seeing this issue with dw_HDMI driver.
> >>
> >> This patch was introduced to maintain the bridge color format
> >> negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it seems
> >> it behaves incorrectly if the first bridge doesn't implement the
> >> negotiation callbacks.
> >>
> >> Let me check the code to see how to fix that.
> >
> > Thanks for the information, I am happy to test the patch/fix.
> >
> > Cheers,
> > Biju
> >
> >>
> >>>
> >>> I have tested linux-next 20220112 on a imx6q-sabresd board, which
> shows:
> >>>
> >>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with HDCP
> >>> (DWC HDMI 3D TX PHY)
> >>>
> >>> The colors are shown correctly here.
> >>>
> >>
> >> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the negotiation
> >> fails and use the RGB fallback input & output format.
> >>
> >> Anyway thanks for testing
> >>
> >> Neil
> 
> Can you test :
> 
> ==><===============================
> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> index c96847fc0ebc..7019acd37716 100644
> --- a/drivers/gpu/drm/drm_bridge.c
> +++ b/drivers/gpu/drm/drm_bridge.c
> @@ -955,7 +955,14 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
> drm_bridge *bridge,
>         last_bridge_state = drm_atomic_get_new_bridge_state(crtc_state-
> >state,
>                                                             last_bridge);
> 
> -       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
> +       /*
> +        * Only negociate with real values if both end of the bridge chain
> +        * support negociation callbacks, otherwise you can end in a
> situation
> +        * where the selected output format doesn't match with the first
> bridge
> +        * output format.
> +        */
> +       if (bridge->funcs->atomic_get_input_bus_fmts &&
> +           last_bridge->funcs->atomic_get_output_bus_fmts) {
>                 const struct drm_bridge_funcs *funcs = last_bridge->funcs;
> 
>                 /*
> @@ -980,7 +987,12 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
> drm_bridge *bridge,
>                 if (!out_bus_fmts)
>                         return -ENOMEM;
> 
> -               if (conn->display_info.num_bus_formats &&
> +               /*
> +                * If first bridge doesn't support negociation, use
> MEDIA_BUS_FMT_FIXED
> +                * as a safe value for the whole bridge chain
> +                */
> +               if (bridge->funcs->atomic_get_input_bus_fmts &&
> +                   conn->display_info.num_bus_formats &&
>                     conn->display_info.bus_formats)
>                         out_bus_fmts[0] = conn-
> >display_info.bus_formats[0];
>                 else
> ==><===============================
> 
> This should exclude your situation where the first bridge doesn't support
> negociation.

I have tested this fix with Linux next-20220114. Still I see colour issue.

It is still negotiating and it is calling get_output_fmt_callbck

[    3.460155] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_UYVY8_1X16=0#########
[    3.460180] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_YUV8_1X24=1#########
[    3.460202] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_RGB888_1X24=2#########

And In get_input_fmt callback, I See the outputformat as YUV16 instead of RGB24.

[    3.460319] ########dw_hdmi_bridge_atomic_get_input_bus_fmts MEDIA_BUS_FMT_UYVY8_1X16#########
[    3.473644] ########hdmi_video_sample MEDIA_BUS_FMT_UYVY8_1X16#########

Regards,
Biju

From narmstrong at baylibre.com  Fri Jan 14 05:56:29 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri, 14 Jan 2022 14:56:29 +0100
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
 <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
Message-ID: <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>

Hi,

On 14/01/2022 12:08, Biju Das wrote:
> Hi Neil,
> 
>> Subject: Re: dw_hdmi is showing wrong colour after commit
>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>> callbacks")
>>
>> On 14/01/2022 09:29, Biju Das wrote:
>>> Hi Neil,
>>>
>>> + renesas-soc
>>>
>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>> callbacks")
>>>>
>>>> Hi,
>>>>
>>>> On 13/01/2022 21:01, Fabio Estevam wrote:
>>>>> Hi Biju,
>>>>>
>>>>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das
>>>>> <biju.das.jz at bp.renesas.com>
>>>> wrote:
>>>>>>
>>>>>> Hi All,
>>>>>>
>>>>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour)
>>>>>> till the commit
>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>> callbacks").
>>>>>>
>>>>>> After this patch, the screen becomes greenish(may be it is setting
>>>>>> it
>>>> into YUV format??).
>>>>>>
>>>>>> By checking the code, previously it used to call get_input_fmt
>>>>>> callback
>>>> and set colour as RGB24.
>>>>>>
>>>>>> After this commit, it calls get_output_fmt_callbck and returns 3
>>>>>> outputformats(YUV16, YUV24 and RGB24) And get_input_fmt callback, I
>>>>>> see
>>>> the outputformat as YUV16 instead of RGB24.
>>>>>>
>>>>>> Not sure, I am the only one seeing this issue with dw_HDMI driver.
>>>>
>>>> This patch was introduced to maintain the bridge color format
>>>> negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it seems
>>>> it behaves incorrectly if the first bridge doesn't implement the
>>>> negotiation callbacks.
>>>>
>>>> Let me check the code to see how to fix that.
>>>
>>> Thanks for the information, I am happy to test the patch/fix.
>>>
>>> Cheers,
>>> Biju
>>>
>>>>
>>>>>
>>>>> I have tested linux-next 20220112 on a imx6q-sabresd board, which
>> shows:
>>>>>
>>>>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with HDCP
>>>>> (DWC HDMI 3D TX PHY)
>>>>>
>>>>> The colors are shown correctly here.
>>>>>
>>>>
>>>> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the negotiation
>>>> fails and use the RGB fallback input & output format.
>>>>
>>>> Anyway thanks for testing
>>>>
>>>> Neil
>>
>> Can you test :
>>
>> ==><===============================
>> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
>> index c96847fc0ebc..7019acd37716 100644
>> --- a/drivers/gpu/drm/drm_bridge.c
>> +++ b/drivers/gpu/drm/drm_bridge.c
>> @@ -955,7 +955,14 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
>> drm_bridge *bridge,
>>         last_bridge_state = drm_atomic_get_new_bridge_state(crtc_state-
>>> state,
>>                                                             last_bridge);
>>
>> -       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
>> +       /*
>> +        * Only negociate with real values if both end of the bridge chain
>> +        * support negociation callbacks, otherwise you can end in a
>> situation
>> +        * where the selected output format doesn't match with the first
>> bridge
>> +        * output format.
>> +        */
>> +       if (bridge->funcs->atomic_get_input_bus_fmts &&
>> +           last_bridge->funcs->atomic_get_output_bus_fmts) {
>>                 const struct drm_bridge_funcs *funcs = last_bridge->funcs;
>>
>>                 /*
>> @@ -980,7 +987,12 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
>> drm_bridge *bridge,
>>                 if (!out_bus_fmts)
>>                         return -ENOMEM;
>>
>> -               if (conn->display_info.num_bus_formats &&
>> +               /*
>> +                * If first bridge doesn't support negociation, use
>> MEDIA_BUS_FMT_FIXED
>> +                * as a safe value for the whole bridge chain
>> +                */
>> +               if (bridge->funcs->atomic_get_input_bus_fmts &&
>> +                   conn->display_info.num_bus_formats &&
>>                     conn->display_info.bus_formats)
>>                         out_bus_fmts[0] = conn-
>>> display_info.bus_formats[0];
>>                 else
>> ==><===============================
>>
>> This should exclude your situation where the first bridge doesn't support
>> negociation.
> 
> I have tested this fix with Linux next-20220114. Still I see colour issue.
> 
> It is still negotiating and it is calling get_output_fmt_callbck
> 
> [    3.460155] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_UYVY8_1X16=0#########
> [    3.460180] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_YUV8_1X24=1#########
> [    3.460202] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_RGB888_1X24=2#########
> 
> And In get_input_fmt callback, I See the outputformat as YUV16 instead of RGB24.
> 
> [    3.460319] ########dw_hdmi_bridge_atomic_get_input_bus_fmts MEDIA_BUS_FMT_UYVY8_1X16#########
> [    3.473644] ########hdmi_video_sample MEDIA_BUS_FMT_UYVY8_1X16#########

OK, looking at rcar-du, the dw-hdmi bridge is directly connected to the encoder.

Let me figure that out, no sure I can find a clean solution except putting back RGB24 before YUV.

Anyway please test that:

==><===============================
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 54d8fdad395f..68f79094f648 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2589,45 +2589,44 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
 	}

 	/*
-	 * Order bus formats from 16bit to 8bit and from YUV422 to RGB
+	 * Order bus formats from 16bit to 8bit and from RGB to YUV422
 	 * if supported. In any case the default RGB888 format is added
 	 */

 	if (max_bpc >= 16 && info->bpc == 16) {
+		output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
+
 		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
 			output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48;
-
-		output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
 	}

 	if (max_bpc >= 12 && info->bpc >= 12) {
-		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
-			output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
+		output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;

 		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
 			output_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36;

-		output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
+		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
+			output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
 	}

 	if (max_bpc >= 10 && info->bpc >= 10) {
-		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
-			output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
+		output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;

 		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
 			output_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30;

-		output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
+		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
+			output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
 	}

-	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
-		output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
+	output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;

 	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
 		output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;

-	/* Default 8bit RGB fallback */
-	output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
+	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
+		output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;

 	*num_output_fmts = i;

==><===============================

Neil

> 
> Regards,
> Biju
> 



From biju.das.jz at bp.renesas.com  Fri Jan 14 06:23:52 2022
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Fri, 14 Jan 2022 14:23:52 +0000
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
 <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>
Message-ID: <OS0PR01MB5922BC31FBCF85F99F17737B86549@OS0PR01MB5922.jpnprd01.prod.outlook.com>



> -----Original Message-----
> From: Neil Armstrong <narmstrong at baylibre.com>
> Sent: 14 January 2022 13:56
> To: Biju Das <biju.das.jz at bp.renesas.com>; Fabio Estevam
> <festevam at gmail.com>
> Cc: daniel at ffwll.ch; Laurent.pinchart at ideasonboard.com;
> robert.foss at linaro.org; jonas at kwiboo.se; jernej.skrabec at gmail.com;
> martin.blumenstingl at googlemail.com; linux-amlogic at lists.infradead.org;
> linux-arm-kernel at lists.infradead.org; dri-devel at lists.freedesktop.org;
> linux-kernel at vger.kernel.org; linux-renesas-soc at vger.kernel.org
> Subject: Re: dw_hdmi is showing wrong colour after commit
> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> callbacks")
> 
> Hi,
> 
> On 14/01/2022 12:08, Biju Das wrote:
> > Hi Neil,
> >
> >> Subject: Re: dw_hdmi is showing wrong colour after commit
> >> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> >> callbacks")
> >>
> >> On 14/01/2022 09:29, Biju Das wrote:
> >>> Hi Neil,
> >>>
> >>> + renesas-soc
> >>>
> >>>> Subject: Re: dw_hdmi is showing wrong colour after commit
> >>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> >>>> callbacks")
> >>>>
> >>>> Hi,
> >>>>
> >>>> On 13/01/2022 21:01, Fabio Estevam wrote:
> >>>>> Hi Biju,
> >>>>>
> >>>>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das
> >>>>> <biju.das.jz at bp.renesas.com>
> >>>> wrote:
> >>>>>>
> >>>>>> Hi All,
> >>>>>>
> >>>>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour)
> >>>>>> till the commit
> >>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
> >>>>>> fmts
> >>>> callbacks").
> >>>>>>
> >>>>>> After this patch, the screen becomes greenish(may be it is
> >>>>>> setting it
> >>>> into YUV format??).
> >>>>>>
> >>>>>> By checking the code, previously it used to call get_input_fmt
> >>>>>> callback
> >>>> and set colour as RGB24.
> >>>>>>
> >>>>>> After this commit, it calls get_output_fmt_callbck and returns 3
> >>>>>> outputformats(YUV16, YUV24 and RGB24) And get_input_fmt callback,
> >>>>>> I see
> >>>> the outputformat as YUV16 instead of RGB24.
> >>>>>>
> >>>>>> Not sure, I am the only one seeing this issue with dw_HDMI driver.
> >>>>
> >>>> This patch was introduced to maintain the bridge color format
> >>>> negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it
> >>>> seems it behaves incorrectly if the first bridge doesn't implement
> >>>> the negotiation callbacks.
> >>>>
> >>>> Let me check the code to see how to fix that.
> >>>
> >>> Thanks for the information, I am happy to test the patch/fix.
> >>>
> >>> Cheers,
> >>> Biju
> >>>
> >>>>
> >>>>>
> >>>>> I have tested linux-next 20220112 on a imx6q-sabresd board, which
> >> shows:
> >>>>>
> >>>>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with
> >>>>> HDCP (DWC HDMI 3D TX PHY)
> >>>>>
> >>>>> The colors are shown correctly here.
> >>>>>
> >>>>
> >>>> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the
> >>>> negotiation fails and use the RGB fallback input & output format.
> >>>>
> >>>> Anyway thanks for testing
> >>>>
> >>>> Neil
> >>
> >> Can you test :
> >>
> >> ==><===============================
> >> diff --git a/drivers/gpu/drm/drm_bridge.c
> >> b/drivers/gpu/drm/drm_bridge.c index c96847fc0ebc..7019acd37716
> >> 100644
> >> --- a/drivers/gpu/drm/drm_bridge.c
> >> +++ b/drivers/gpu/drm/drm_bridge.c
> >> @@ -955,7 +955,14 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
> >> drm_bridge *bridge,
> >>         last_bridge_state =
> >> drm_atomic_get_new_bridge_state(crtc_state-
> >>> state,
> >>
> >> last_bridge);
> >>
> >> -       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
> >> +       /*
> >> +        * Only negociate with real values if both end of the bridge
> chain
> >> +        * support negociation callbacks, otherwise you can end in a
> >> situation
> >> +        * where the selected output format doesn't match with the
> >> + first
> >> bridge
> >> +        * output format.
> >> +        */
> >> +       if (bridge->funcs->atomic_get_input_bus_fmts &&
> >> +           last_bridge->funcs->atomic_get_output_bus_fmts) {
> >>                 const struct drm_bridge_funcs *funcs =
> >> last_bridge->funcs;
> >>
> >>                 /*
> >> @@ -980,7 +987,12 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
> >> drm_bridge *bridge,
> >>                 if (!out_bus_fmts)
> >>                         return -ENOMEM;
> >>
> >> -               if (conn->display_info.num_bus_formats &&
> >> +               /*
> >> +                * If first bridge doesn't support negociation, use
> >> MEDIA_BUS_FMT_FIXED
> >> +                * as a safe value for the whole bridge chain
> >> +                */
> >> +               if (bridge->funcs->atomic_get_input_bus_fmts &&
> >> +                   conn->display_info.num_bus_formats &&
> >>                     conn->display_info.bus_formats)
> >>                         out_bus_fmts[0] = conn-
> >>> display_info.bus_formats[0];
> >>                 else
> >> ==><===============================
> >>
> >> This should exclude your situation where the first bridge doesn't
> >> support negociation.
> >
> > I have tested this fix with Linux next-20220114. Still I see colour
> issue.
> >
> > It is still negotiating and it is calling get_output_fmt_callbck
> >
> > [    3.460155] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> MEDIA_BUS_FMT_UYVY8_1X16=0#########
> > [    3.460180] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> MEDIA_BUS_FMT_YUV8_1X24=1#########
> > [    3.460202] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> MEDIA_BUS_FMT_RGB888_1X24=2#########
> >
> > And In get_input_fmt callback, I See the outputformat as YUV16 instead
> of RGB24.
> >
> > [    3.460319] ########dw_hdmi_bridge_atomic_get_input_bus_fmts
> MEDIA_BUS_FMT_UYVY8_1X16#########
> > [    3.473644] ########hdmi_video_sample
> MEDIA_BUS_FMT_UYVY8_1X16#########
> 
> OK, looking at rcar-du, the dw-hdmi bridge is directly connected to the
> encoder.

Yep.

> 
> Let me figure that out, no sure I can find a clean solution except putting
> back RGB24 before YUV.
> 
> Anyway please test that:

It works now after reordering.

[    3.493302] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_RGB888_1X24=0#########
[    3.493326] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_YUV8_1X24=1#########
[    3.493348] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_UYVY8_1X16=2#########

[    3.493463] ########dw_hdmi_bridge_atomic_get_input_bus_fmts MEDIA_BUS_FMT_RGB888_1X24#########
[    3.506797] ########hdmi_video_sample MEDIA_BUS_FMT_RGB888_1X24#########

Is it acceptable solution to the users of dw_hdmi driver? May be it is worth to post a patch.
at least it is fixing the colour issue??

Regards,
Biju

> 
> ==><===============================
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 54d8fdad395f..68f79094f648 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2589,45 +2589,44 @@ static u32
> *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
>  	}
> 
>  	/*
> -	 * Order bus formats from 16bit to 8bit and from YUV422 to RGB
> +	 * Order bus formats from 16bit to 8bit and from RGB to YUV422
>  	 * if supported. In any case the default RGB888 format is added
>  	 */
> 
>  	if (max_bpc >= 16 && info->bpc == 16) {
> +		output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
> +
>  		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
>  			output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48;
> -
> -		output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
>  	}
> 
>  	if (max_bpc >= 12 && info->bpc >= 12) {
> -		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
> -			output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
> +		output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
> 
>  		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
>  			output_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36;
> 
> -		output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
> +		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
> +			output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
>  	}
> 
>  	if (max_bpc >= 10 && info->bpc >= 10) {
> -		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
> -			output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
> +		output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
> 
>  		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
>  			output_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30;
> 
> -		output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
> +		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
> +			output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
>  	}
> 
> -	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
> -		output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
> +	output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
> 
>  	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
>  		output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;
> 
> -	/* Default 8bit RGB fallback */
> -	output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
> +	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
> +		output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
> 
>  	*num_output_fmts = i;
> 
> ==><===============================
> 
> Neil
> 
> >
> > Regards,
> > Biju
> >


From narmstrong at baylibre.com  Fri Jan 14 06:40:50 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri, 14 Jan 2022 15:40:50 +0100
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <OS0PR01MB5922BC31FBCF85F99F17737B86549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
 <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>
 <OS0PR01MB5922BC31FBCF85F99F17737B86549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
Message-ID: <ebaff694-a2d7-7eb8-5850-980e9d4e1e68@baylibre.com>

Hi,

On 14/01/2022 15:23, Biju Das wrote:
> 
> 
>> -----Original Message-----
>> From: Neil Armstrong <narmstrong at baylibre.com>
>> Sent: 14 January 2022 13:56
>> To: Biju Das <biju.das.jz at bp.renesas.com>; Fabio Estevam
>> <festevam at gmail.com>
>> Cc: daniel at ffwll.ch; Laurent.pinchart at ideasonboard.com;
>> robert.foss at linaro.org; jonas at kwiboo.se; jernej.skrabec at gmail.com;
>> martin.blumenstingl at googlemail.com; linux-amlogic at lists.infradead.org;
>> linux-arm-kernel at lists.infradead.org; dri-devel at lists.freedesktop.org;
>> linux-kernel at vger.kernel.org; linux-renesas-soc at vger.kernel.org
>> Subject: Re: dw_hdmi is showing wrong colour after commit
>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>> callbacks")
>>
>> Hi,
>>
>> On 14/01/2022 12:08, Biju Das wrote:
>>> Hi Neil,
>>>
>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>> callbacks")
>>>>
>>>> On 14/01/2022 09:29, Biju Das wrote:
>>>>> Hi Neil,
>>>>>
>>>>> + renesas-soc
>>>>>
>>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>>>> callbacks")
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> On 13/01/2022 21:01, Fabio Estevam wrote:
>>>>>>> Hi Biju,
>>>>>>>
>>>>>>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das
>>>>>>> <biju.das.jz at bp.renesas.com>
>>>>>> wrote:
>>>>>>>>
>>>>>>>> Hi All,
>>>>>>>>
>>>>>>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour)
>>>>>>>> till the commit
>>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
>>>>>>>> fmts
>>>>>> callbacks").
>>>>>>>>
>>>>>>>> After this patch, the screen becomes greenish(may be it is
>>>>>>>> setting it
>>>>>> into YUV format??).
>>>>>>>>
>>>>>>>> By checking the code, previously it used to call get_input_fmt
>>>>>>>> callback
>>>>>> and set colour as RGB24.
>>>>>>>>
>>>>>>>> After this commit, it calls get_output_fmt_callbck and returns 3
>>>>>>>> outputformats(YUV16, YUV24 and RGB24) And get_input_fmt callback,
>>>>>>>> I see
>>>>>> the outputformat as YUV16 instead of RGB24.
>>>>>>>>
>>>>>>>> Not sure, I am the only one seeing this issue with dw_HDMI driver.
>>>>>>
>>>>>> This patch was introduced to maintain the bridge color format
>>>>>> negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it
>>>>>> seems it behaves incorrectly if the first bridge doesn't implement
>>>>>> the negotiation callbacks.
>>>>>>
>>>>>> Let me check the code to see how to fix that.
>>>>>
>>>>> Thanks for the information, I am happy to test the patch/fix.
>>>>>
>>>>> Cheers,
>>>>> Biju
>>>>>
>>>>>>
>>>>>>>
>>>>>>> I have tested linux-next 20220112 on a imx6q-sabresd board, which
>>>> shows:
>>>>>>>
>>>>>>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with
>>>>>>> HDCP (DWC HDMI 3D TX PHY)
>>>>>>>
>>>>>>> The colors are shown correctly here.
>>>>>>>
>>>>>>
>>>>>> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the
>>>>>> negotiation fails and use the RGB fallback input & output format.
>>>>>>
>>>>>> Anyway thanks for testing
>>>>>>
>>>>>> Neil
>>>>
>>>> Can you test :
>>>>
>>>> ==><===============================
>>>> diff --git a/drivers/gpu/drm/drm_bridge.c
>>>> b/drivers/gpu/drm/drm_bridge.c index c96847fc0ebc..7019acd37716
>>>> 100644
>>>> --- a/drivers/gpu/drm/drm_bridge.c
>>>> +++ b/drivers/gpu/drm/drm_bridge.c
>>>> @@ -955,7 +955,14 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
>>>> drm_bridge *bridge,
>>>>         last_bridge_state =
>>>> drm_atomic_get_new_bridge_state(crtc_state-
>>>>> state,
>>>>
>>>> last_bridge);
>>>>
>>>> -       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
>>>> +       /*
>>>> +        * Only negociate with real values if both end of the bridge
>> chain
>>>> +        * support negociation callbacks, otherwise you can end in a
>>>> situation
>>>> +        * where the selected output format doesn't match with the
>>>> + first
>>>> bridge
>>>> +        * output format.
>>>> +        */
>>>> +       if (bridge->funcs->atomic_get_input_bus_fmts &&
>>>> +           last_bridge->funcs->atomic_get_output_bus_fmts) {
>>>>                 const struct drm_bridge_funcs *funcs =
>>>> last_bridge->funcs;
>>>>
>>>>                 /*
>>>> @@ -980,7 +987,12 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
>>>> drm_bridge *bridge,
>>>>                 if (!out_bus_fmts)
>>>>                         return -ENOMEM;
>>>>
>>>> -               if (conn->display_info.num_bus_formats &&
>>>> +               /*
>>>> +                * If first bridge doesn't support negociation, use
>>>> MEDIA_BUS_FMT_FIXED
>>>> +                * as a safe value for the whole bridge chain
>>>> +                */
>>>> +               if (bridge->funcs->atomic_get_input_bus_fmts &&
>>>> +                   conn->display_info.num_bus_formats &&
>>>>                     conn->display_info.bus_formats)
>>>>                         out_bus_fmts[0] = conn-
>>>>> display_info.bus_formats[0];
>>>>                 else
>>>> ==><===============================
>>>>
>>>> This should exclude your situation where the first bridge doesn't
>>>> support negociation.
>>>
>>> I have tested this fix with Linux next-20220114. Still I see colour
>> issue.
>>>
>>> It is still negotiating and it is calling get_output_fmt_callbck
>>>
>>> [    3.460155] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>> MEDIA_BUS_FMT_UYVY8_1X16=0#########
>>> [    3.460180] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>> MEDIA_BUS_FMT_YUV8_1X24=1#########
>>> [    3.460202] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>> MEDIA_BUS_FMT_RGB888_1X24=2#########
>>>
>>> And In get_input_fmt callback, I See the outputformat as YUV16 instead
>> of RGB24.
>>>
>>> [    3.460319] ########dw_hdmi_bridge_atomic_get_input_bus_fmts
>> MEDIA_BUS_FMT_UYVY8_1X16#########
>>> [    3.473644] ########hdmi_video_sample
>> MEDIA_BUS_FMT_UYVY8_1X16#########
>>
>> OK, looking at rcar-du, the dw-hdmi bridge is directly connected to the
>> encoder.
> 
> Yep.
> 
>>
>> Let me figure that out, no sure I can find a clean solution except putting
>> back RGB24 before YUV.
>>
>> Anyway please test that:
> 
> It works now after reordering.
> 
> [    3.493302] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_RGB888_1X24=0#########
> [    3.493326] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_YUV8_1X24=1#########
> [    3.493348] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_UYVY8_1X16=2#########
> 
> [    3.493463] ########dw_hdmi_bridge_atomic_get_input_bus_fmts MEDIA_BUS_FMT_RGB888_1X24#########
> [    3.506797] ########hdmi_video_sample MEDIA_BUS_FMT_RGB888_1X24#########
> 
> Is it acceptable solution to the users of dw_hdmi driver? May be it is worth to post a patch.
> at least it is fixing the colour issue??

Yes, it gets back to default behavior before negociation, nevertheless we need to think
how to handle your use-case correctly at some point.

I'll post this as a patch ASAP so it gets applied before landing in linus master.

Neil

> 
> Regards,
> Biju
> 
>>
>> ==><===============================
>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> index 54d8fdad395f..68f79094f648 100644
>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> @@ -2589,45 +2589,44 @@ static u32
>> *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
>>  	}
>>
>>  	/*
>> -	 * Order bus formats from 16bit to 8bit and from YUV422 to RGB
>> +	 * Order bus formats from 16bit to 8bit and from RGB to YUV422
>>  	 * if supported. In any case the default RGB888 format is added
>>  	 */
>>
>>  	if (max_bpc >= 16 && info->bpc == 16) {
>> +		output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
>> +
>>  		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
>>  			output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48;
>> -
>> -		output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
>>  	}
>>
>>  	if (max_bpc >= 12 && info->bpc >= 12) {
>> -		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
>> -			output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
>> +		output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
>>
>>  		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
>>  			output_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36;
>>
>> -		output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
>> +		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
>> +			output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
>>  	}
>>
>>  	if (max_bpc >= 10 && info->bpc >= 10) {
>> -		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
>> -			output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
>> +		output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
>>
>>  		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
>>  			output_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30;
>>
>> -		output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
>> +		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
>> +			output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
>>  	}
>>
>> -	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
>> -		output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
>> +	output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
>>
>>  	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
>>  		output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;
>>
>> -	/* Default 8bit RGB fallback */
>> -	output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
>> +	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
>> +		output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
>>
>>  	*num_output_fmts = i;
>>
>> ==><===============================
>>
>> Neil
>>
>>>
>>> Regards,
>>> Biju
>>>
> 



From jbrunet at baylibre.com  Fri Jan 14 06:53:58 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Fri, 14 Jan 2022 15:53:58 +0100
Subject: [PATCH v2] pwm: meson: external clock configuration for s4
In-Reply-To: <20220114090753.34873-1-Jiayi.Zhou@amlogic.com>
References: <20220114090753.34873-1-Jiayi.Zhou@amlogic.com>
Message-ID: <1jmtjybc05.fsf@starbuckisacylon.baylibre.com>


On Fri 14 Jan 2022 at 17:07, <Jiayi.Zhou at amlogic.com> wrote:

> From: "Jiayi.zhou" <jiayi.zhou at amlogic.com>
>
> For PWM controller in the Meson-S4 SoC,
> PWM needs to obtain an external clock source.
> This patch tries to describe them in the DT compatible data.
>

I'm sorry but I have already commented on v1 that all the mess in here
don't seem necessary. For Reference:

"""
 You trying to bypass the input selection mux. There is no reason to do
 so.

 Your input clocks should be
 * OSC
 * vid_pll
 * fdiv3
 * fdiv4

 While the pwm driver could welcome a rework around how it deal with DT
 and the clocks, this S4 chip does not warrant any change compared to
 previous generation (AFAICT)

 All the stuff around "extern_clk" should go away IMO.
"""

Unless you can *really* justify why this approach is required, it is
firm Nack.


From sboyd at kernel.org  Fri Jan 14 14:59:55 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 14 Jan 2022 14:59:55 -0800
Subject: [PATCH v9 3/4] clk: meson: add DT documentation for emmc clock
 controller
In-Reply-To: <5d99ac02-a246-5bcc-2ecb-371b0d193537@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-4-liang.yang@amlogic.com>
 <20220113212957.768FFC36AE3@smtp.kernel.org>
 <5d99ac02-a246-5bcc-2ecb-371b0d193537@amlogic.com>
Message-ID: <20220114225957.285ADC36AE7@smtp.kernel.org>

Quoting Liang Yang (2022-01-13 19:06:07)
> Hi Stephen,
> 
> Thanks for your quick response.
> 
> On 2022/1/14 5:29, Stephen Boyd wrote:
> > [ EXTERNAL EMAIL ]
> > 
> > Quoting Liang Yang (2022-01-13 03:57:44)
> >> Document the MMC sub clock controller driver, the potential consumer
> >> of this driver is MMC or NAND. Also add four clock bindings IDs which
> >> provided by this driver.
> >>
> >> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
> >> ---
> >>   .../bindings/clock/amlogic,mmc-clkc.yaml      | 64 +++++++++++++++++++
> >>   include/dt-bindings/clock/amlogic,mmc-clkc.h  | 14 ++++
> >>   2 files changed, 78 insertions(+)
> >>   create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
> >>   create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
> >>
> >> diff --git a/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
> >> new file mode 100644
> >> index 000000000000..a274c3d5fc2e
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
> >> @@ -0,0 +1,64 @@
> >> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> >> +%YAML 1.2
> >> +---
> >> +$id: http://devicetree.org/schemas/clock/amlogic,mmc-clkc.yaml#
> >> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >> +
> >> +title: Amlogic MMC Sub Clock Controller Driver Device Tree Bindings
> >> +
> >> +maintainers:
> >> +  - jianxin.pan at amlogic.com
> >> +  - liang.yang at amlogic.com
> >> +
> >> +properties:
> >> +  compatible:
> >> +    enum:
> >> +      - "amlogic,axg-mmc-clkc", "syscon"
> > 
> > Why is it a syscon?
> 
> The register documented by reg is shared with SD/eMMC controller port C, 
> and it need to be ops on NFC driver.
> 

Is this the case where the clk is inside the SD/eMMC controller? Can the
mmc driver register the clk controller from there and pass it an iomem
pointer to poke clks?


From sboyd at kernel.org  Fri Jan 14 15:01:28 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 14 Jan 2022 15:01:28 -0800
Subject: [PATCH v9 4/4] clk: meson: add sub MMC clock controller driver
In-Reply-To: <09ff9044-9abc-d1ad-26c1-5e6ece56d30c@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-5-liang.yang@amlogic.com>
 <20220113213513.9819AC36AEA@smtp.kernel.org>
 <09ff9044-9abc-d1ad-26c1-5e6ece56d30c@amlogic.com>
Message-ID: <20220114230130.35EAAC36AE7@smtp.kernel.org>

Quoting Liang Yang (2022-01-13 21:14:46)
> On 2022/1/14 5:35, Stephen Boyd wrote:
> > Quoting Liang Yang (2022-01-13 03:57:45)
> >> diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c
> >> new file mode 100644
> >> index 000000000000..f53977f61390
> >> --- /dev/null
> >> +++ b/drivers/clk/meson/mmc-clkc.c
> >> @@ -0,0 +1,300 @@
[..]
> >> +
> >> +static int mmc_clkc_probe(struct platform_device *pdev)
> >> +{
> >> +       struct clk_hw_onecell_data *onecell_data;
> >> +       struct device *dev = &pdev->dev;
> >> +       struct mmc_clkc_data *data;
> >> +       struct regmap *map;
> >> +       struct clk_regmap *clk, *core;
> >> +       struct meson_sclk_div_data *div_data;
> >> +
> >> +       /*cast to drop the const in match->data*/
> > 
> > Space after *, also why do we need to cast away const? The user of this
> > pointer passes it all the way down to mmc_clkc_register_clk() which
> > could take the data as const void pointer and decide to cast away const
> > there.
> 
> if use 'const' here, it will report a warning:
> drivers/clk/meson/mmc-clkc.c:224:7: error: assignment discards ?const? 
> qualifier from pointer targe
> t type [-Werror=discarded-qualifiers] 
> 
>    data = (const struct mmc_clkc_data *)of_device_get_match_data(dev);

Of course. The type declaration up above needs const added to it.


From martin.blumenstingl at googlemail.com  Fri Jan 14 16:09:11 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sat, 15 Jan 2022 01:09:11 +0100
Subject: [PATCH v9 3/4] clk: meson: add DT documentation for emmc clock
 controller
In-Reply-To: <5d99ac02-a246-5bcc-2ecb-371b0d193537@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-4-liang.yang@amlogic.com>
 <20220113212957.768FFC36AE3@smtp.kernel.org>
 <5d99ac02-a246-5bcc-2ecb-371b0d193537@amlogic.com>
Message-ID: <CAFBinCDkNk+Ba340vshhL2rE76U9qb_dZ5ZsgWnMgFYpL6i1jA@mail.gmail.com>

Hi Liang,

On Fri, Jan 14, 2022 at 4:06 AM Liang Yang <liang.yang at amlogic.com> wrote:
[...]
> >> +properties:
> >> +  compatible:
> >> +    enum:
> >> +      - "amlogic,axg-mmc-clkc", "syscon"
> >
> > Why is it a syscon?
>
> The register documented by reg is shared with SD/eMMC controller port C,
> and it need to be ops on NFC driver.
Can you please share an example how the .dts would look like in the
end for two example cases:
1) using the sd_emmc_c MMC interface
2) not using the MMC interface of sd_emmc_c but only using it's clocks
for the NFC

Initially I wanted to suggest the usage of a sub-node with compatible
= "mmc-slot" (see
Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.txt for an
example) to decide whether the MMC controller is registered or whether
just the clock controller is registered.
However, the mmc-slot compatible string is not documented in
Documentation/devicetree/bindings/mmc/mmc-controller.yaml currently.
Maybe the MMC maintainers have any suggestions if other IPs have
similar requirements (for IPs with shared parts).


Best regards,
Martin


From alexander.stein at mailbox.org  Sat Jan 15 01:35:56 2022
From: alexander.stein at mailbox.org (Alexander Stein)
Date: Sat, 15 Jan 2022 10:35:56 +0100
Subject: [PATCH 1/2] arm64: dts: meson-axg: add missing reset-names property
Message-ID: <20220115093557.30498-1-alexander.stein@mailbox.org>

Bindings amlogic,axg-fifo.txt mandates that reset-names is a required
property. Add it.

Signed-off-by: Alexander Stein <alexander.stein at mailbox.org>
---
This is essentially a preparation for YAML conversion to fix the
warnings.

 arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index 3f5254eeb47b..b14175e2f1d6 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -1333,6 +1333,7 @@ toddr_a: audio-controller at 100 {
 				interrupts = <GIC_SPI 84 IRQ_TYPE_EDGE_RISING>;
 				clocks = <&clkc_audio AUD_CLKID_TODDR_A>;
 				resets = <&arb AXG_ARB_TODDR_A>;
+				reset-names = "arb";
 				amlogic,fifo-depth = <512>;
 				status = "disabled";
 			};
@@ -1345,6 +1346,7 @@ toddr_b: audio-controller at 140 {
 				interrupts = <GIC_SPI 85 IRQ_TYPE_EDGE_RISING>;
 				clocks = <&clkc_audio AUD_CLKID_TODDR_B>;
 				resets = <&arb AXG_ARB_TODDR_B>;
+				reset-names = "arb";
 				amlogic,fifo-depth = <256>;
 				status = "disabled";
 			};
@@ -1357,6 +1359,7 @@ toddr_c: audio-controller at 180 {
 				interrupts = <GIC_SPI 86 IRQ_TYPE_EDGE_RISING>;
 				clocks = <&clkc_audio AUD_CLKID_TODDR_C>;
 				resets = <&arb AXG_ARB_TODDR_C>;
+				reset-names = "arb";
 				amlogic,fifo-depth = <256>;
 				status = "disabled";
 			};
@@ -1369,6 +1372,7 @@ frddr_a: audio-controller at 1c0 {
 				interrupts = <GIC_SPI 88 IRQ_TYPE_EDGE_RISING>;
 				clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
 				resets = <&arb AXG_ARB_FRDDR_A>;
+				reset-names = "arb";
 				amlogic,fifo-depth = <512>;
 				status = "disabled";
 			};
@@ -1381,6 +1385,7 @@ frddr_b: audio-controller at 200 {
 				interrupts = <GIC_SPI 89 IRQ_TYPE_EDGE_RISING>;
 				clocks = <&clkc_audio AUD_CLKID_FRDDR_B>;
 				resets = <&arb AXG_ARB_FRDDR_B>;
+				reset-names = "arb";
 				amlogic,fifo-depth = <256>;
 				status = "disabled";
 			};
@@ -1393,6 +1398,7 @@ frddr_c: audio-controller at 240 {
 				interrupts = <GIC_SPI 90 IRQ_TYPE_EDGE_RISING>;
 				clocks = <&clkc_audio AUD_CLKID_FRDDR_C>;
 				resets = <&arb AXG_ARB_FRDDR_C>;
+				reset-names = "arb";
 				amlogic,fifo-depth = <256>;
 				status = "disabled";
 			};
-- 
2.34.1



From alexander.stein at mailbox.org  Sat Jan 15 01:35:57 2022
From: alexander.stein at mailbox.org (Alexander Stein)
Date: Sat, 15 Jan 2022 10:35:57 +0100
Subject: [PATCH 2/2] ASoC: meson: axg-fifo: convert Amlogic FIFO controller to
 yaml
In-Reply-To: <20220115093557.30498-1-alexander.stein@mailbox.org>
References: <20220115093557.30498-1-alexander.stein@mailbox.org>
Message-ID: <20220115093557.30498-2-alexander.stein@mailbox.org>

Convert Amlogic FIFO controller documentation to yaml format.

Signed-off-by: Alexander Stein <alexander.stein at mailbox.org>
---
Things to note:
First of, Jerome, sorry for adding you as maintainer, but
1) it's mandatory
2) your are the (only) author of amlogic,axg-fifo.txt

Please add your Signed-off-by if that is okay with you.

License is mandated by checkpath, not my choice.

I'm not so sure about the compatible check. Essentially it is either
* 'amlogic,axg-frddr' OR
* 'amlogic,g12a-frddr' + 'amlogic,axg-frddr'
  (or 'sm1' instead of 'g12a')

Same goes for *-toddr. Is this schema correct in that regard? At least I
got no warnings on existing device trees.

 .../bindings/sound/amlogic,axg-fifo.txt       | 34 -------
 .../bindings/sound/amlogic,axg-fifo.yaml      | 97 +++++++++++++++++++
 2 files changed, 97 insertions(+), 34 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt
 create mode 100644 Documentation/devicetree/bindings/sound/amlogic,axg-fifo.yaml

diff --git a/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt b/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt
deleted file mode 100644
index fa4545ed81ca..000000000000
--- a/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-* Amlogic Audio FIFO controllers
-
-Required properties:
-- compatible: 'amlogic,axg-toddr' or
-	      'amlogic,axg-toddr' or
-	      'amlogic,g12a-frddr' or
-	      'amlogic,g12a-toddr' or
-	      'amlogic,sm1-frddr' or
-	      'amlogic,sm1-toddr'
-- reg: physical base address of the controller and length of memory
-       mapped region.
-- interrupts: interrupt specifier for the fifo.
-- clocks: phandle to the fifo peripheral clock provided by the audio
-	  clock controller.
-- resets: list of reset phandle, one for each entry reset-names.
-- reset-names: should contain the following:
-  * "arb" : memory ARB line (required)
-  * "rst" : dedicated device reset line (optional)
-- #sound-dai-cells: must be 0.
-- amlogic,fifo-depth: The size of the controller's fifo in bytes. This
-  		      is useful for determining certain configuration such
-		      as the flush threshold of the fifo
-
-Example of FRDDR A on the A113 SoC:
-
-frddr_a: audio-controller at 1c0 {
-	compatible = "amlogic,axg-frddr";
-	reg = <0x0 0x1c0 0x0 0x1c>;
-	#sound-dai-cells = <0>;
-	interrupts = <GIC_SPI 88 IRQ_TYPE_EDGE_RISING>;
-	clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
-	resets = <&arb AXG_ARB_FRDDR_A>;
-	fifo-depth = <512>;
-};
diff --git a/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.yaml b/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.yaml
new file mode 100644
index 000000000000..54bc073591f4
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.yaml
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/amlogic,axg-fifo.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic Audio FIFO controllers
+
+maintainers:
+  - Jerome Brunet <jbrunet at baylibre.com>
+
+allOf:
+  - $ref: name-prefix.yaml#
+
+properties:
+  $nodename:
+    pattern: "^audio-controller at .*"
+
+  "#sound-dai-cells":
+    const: 0
+
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - amlogic,g12a-frddr
+              - amlogic,sm1-frddr
+          - const: amlogic,axg-frddr
+      - const: amlogic,axg-frddr
+      - items:
+          - enum:
+              - amlogic,g12a-toddr
+              - amlogic,sm1-toddr
+          - const: amlogic,axg-toddr
+      - const: amlogic,axg-toddr
+
+  reg:
+    items:
+      - description: physical base address of the controller
+
+  interrupts:
+    items:
+      - description: FIFO interrupt
+
+  clocks:
+    items:
+      - description: FIFO peripheral clock provided by the audio clock controller
+
+  resets:
+    minItems: 1
+    items:
+      - description: memory ARB line
+      - description: optional device reset line
+
+  reset-names:
+    minItems: 1
+    items:
+      - const: arb
+      - const: rst
+
+  amlogic,fifo-depth:
+    description: >
+      The size of the controller's fifo in bytes. This
+      is useful for determining certain configuration such
+      as the flush threshold of the fifo
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  sound-name-prefix: true
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - resets
+  - reset-names
+  - '#sound-dai-cells'
+  - amlogic,fifo-depth
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/axg-audio-clkc.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/reset/amlogic,meson-axg-audio-arb.h>
+
+    frddr_a: audio-controller at 1c0 {
+        compatible = "amlogic,axg-frddr";
+        reg = <0x1c0 0x1c>;
+        #sound-dai-cells = <0>;
+        interrupts = <88 IRQ_TYPE_EDGE_RISING>;
+        clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
+        resets = <&arb AXG_ARB_FRDDR_A>;
+        reset-names = "arb";
+        amlogic,fifo-depth = <512>;
+    };
-- 
2.34.1



From alexander.stein at mailbox.org  Sat Jan 15 02:02:04 2022
From: alexander.stein at mailbox.org (Alexander Stein)
Date: Sat, 15 Jan 2022 11:02:04 +0100
Subject: (EXT) HDMI CEC on ODROID-N2+
In-Reply-To: <d2ef8936c54567c9c2652b3c53a82f68@agner.ch>
References: <d2ef8936c54567c9c2652b3c53a82f68@agner.ch>
Message-ID: <5560050.DvuYhMxLoT@kongar>

Hi Stefan,

Am Donnerstag, 13. Januar 2022, 15:36:38 CET schrieb Stefan Agner:
> Hi Neil,
> 
> I am trying to use HDMI CEC on ODROID-N2+ using Linux 5.10.91. However,
> I was unsuccessful: As far as I can tell cec-client uses the right
> device (I disabled CONFIG_DRM_DW_HDMI_CEC since my kernel is still
> missing your patch "drm/meson: dw-hdmi: disable DW-HDMI CEC
> sub-driver"). But communication won't work, and dmesg prints timeout
> messages:
> 
> [   68.831253] cec-meson_g12a_ao_cec: message ff 84 20 00 06 timed out
> [   71.134987] cec-meson_g12a_ao_cec: message ff 87 00 15 82 timed out
> [   73.438826] cec-meson_g12a_ao_cec: message f0 timed out
> [   75.742677] cec-meson_g12a_ao_cec: message f0 timed out
> [   78.046555] cec-meson_g12a_ao_cec: message f0 timed out
> [   80.350446] cec-meson_g12a_ao_cec: message f0 timed out
> [   82.654358] cec-meson_g12a_ao_cec: message 11 timed out
> [   84.958285] cec-meson_g12a_ao_cec: message 11 timed out
> [   87.262194] cec-meson_g12a_ao_cec: message 11 timed out
> [   89.566130] cec-meson_g12a_ao_cec: message 11 timed out
> 
> I did a quick test with CoreELEC which uses the 4.9 downstream kernel,
> CEC seems to work there. So it does not seem to be my hardware setup.
> 
> A quick test with the latest Linux 5.16 shows the same errors.
> 
> Do you happen to have an idea? Do you know if HDMI CEC using upstream
> kernels worked at one point on that particular platform?

I'm using Arch Linux on my ODROID-n2 (non-plus) and HDMI CEC works as 
expected.
Currently I'm running a 5.15.13-1-aarch64-ARCH kernel. AFAICS the mentioned 
patch is mainline since v5.14. I can see my TV without issues. I have to add 
that not every cable is suitable for HDMI CEC, I have one where CEC does not 
work (in general).

HTH
Alexander
------
$ cec-ctl --playback
$ cec-ctl -S
Driver Info:
        Driver Name                : meson-ao-cec-g12a
        Adapter Name               : meson_g12a_ao_cec
        Capabilities               : 0x0000011e
                Logical Addresses
                Transmit
                Passthrough
                Remote Control Support
                Connector Info
        Driver version             : 5.15.13
        Available Logical Addresses: 4
        DRM Connector Info         : card 1, connector 32
        Physical Address           : 1.0.0.0
        Logical Address Mask       : 0x0010
        CEC Version                : 2.0
        Vendor ID                  : 0x000c03 (HDMI)
        OSD Name                   : 'Playback'
        Logical Addresses          : 1 (Allow RC Passthrough)

          Logical Address          : 4 (Playback Device 1)
            Primary Device Type    : Playback
            Logical Address Type   : Playback
            All Device Types       : Playback
            RC TV Profile          : None
            Device Features        :
                None

        System Information for device 0 (TV) from device 4 (Playback Device 
1):
                CEC Version                : 1.4
                Physical Address           : 0.0.0.0
                Primary Device Type        : TV
                Vendor ID                  : 0x080046 (Sony)
                OSD Name                   : 'TV'
                Power Status               : Standby

        Topology:

            0.0.0.0: TV
                1.0.0.0: Playback Device 1





From stefan at agner.ch  Sat Jan 15 02:52:31 2022
From: stefan at agner.ch (Stefan Agner)
Date: Sat, 15 Jan 2022 11:52:31 +0100
Subject: (EXT) HDMI CEC on ODROID-N2+
In-Reply-To: <5560050.DvuYhMxLoT@kongar>
References: <d2ef8936c54567c9c2652b3c53a82f68@agner.ch>
 <5560050.DvuYhMxLoT@kongar>
Message-ID: <8112d37eaed169735ca8b46e5d587210@agner.ch>

Hi Alexander,

On 2022-01-15 11:02, Alexander Stein wrote:
> Hi Stefan,
> 
> Am Donnerstag, 13. Januar 2022, 15:36:38 CET schrieb Stefan Agner:
>> Hi Neil,
>>
>> I am trying to use HDMI CEC on ODROID-N2+ using Linux 5.10.91. However,
>> I was unsuccessful: As far as I can tell cec-client uses the right
>> device (I disabled CONFIG_DRM_DW_HDMI_CEC since my kernel is still
>> missing your patch "drm/meson: dw-hdmi: disable DW-HDMI CEC
>> sub-driver"). But communication won't work, and dmesg prints timeout
>> messages:
>>
>> [   68.831253] cec-meson_g12a_ao_cec: message ff 84 20 00 06 timed out
>> [   71.134987] cec-meson_g12a_ao_cec: message ff 87 00 15 82 timed out
>> [   73.438826] cec-meson_g12a_ao_cec: message f0 timed out
>> [   75.742677] cec-meson_g12a_ao_cec: message f0 timed out
>> [   78.046555] cec-meson_g12a_ao_cec: message f0 timed out
>> [   80.350446] cec-meson_g12a_ao_cec: message f0 timed out
>> [   82.654358] cec-meson_g12a_ao_cec: message 11 timed out
>> [   84.958285] cec-meson_g12a_ao_cec: message 11 timed out
>> [   87.262194] cec-meson_g12a_ao_cec: message 11 timed out
>> [   89.566130] cec-meson_g12a_ao_cec: message 11 timed out
>>
>> I did a quick test with CoreELEC which uses the 4.9 downstream kernel,
>> CEC seems to work there. So it does not seem to be my hardware setup.
>>
>> A quick test with the latest Linux 5.16 shows the same errors.
>>
>> Do you happen to have an idea? Do you know if HDMI CEC using upstream
>> kernels worked at one point on that particular platform?
> 
> I'm using Arch Linux on my ODROID-n2 (non-plus) and HDMI CEC works as 
> expected.
> Currently I'm running a 5.15.13-1-aarch64-ARCH kernel. AFAICS the mentioned 
> patch is mainline since v5.14. I can see my TV without issues. I have to add 
> that not every cable is suitable for HDMI CEC, I have one where CEC does not 
> work (in general).

Hm, interesting, thanks for the datapoint!

I tried to reproduce your findings, unfortunately I am not successful in
booting mainline using Arch Linux ARM so far. It seems it comes with
downstream 4.9 kernel by default (where CEC seems to work in this case
too). I then installed linux-aarch64 and adjusted the device tree, but
it seems that the downstream U-Boot 2015.01-10 has some hardcoded
"rsvmem" command which fails. How are you booting v5.14?

It is a bit surprising that 5.15.13 works for you but 5.16 didn't for
me. That makes me wonder, could it be bootloader dependent? Are you
using downstream U-Boot?

--
Stefan

> 
> HTH
> Alexander
> ------
> $ cec-ctl --playback
> $ cec-ctl -S
> Driver Info:
>         Driver Name                : meson-ao-cec-g12a
>         Adapter Name               : meson_g12a_ao_cec
>         Capabilities               : 0x0000011e
>                 Logical Addresses
>                 Transmit
>                 Passthrough
>                 Remote Control Support
>                 Connector Info
>         Driver version             : 5.15.13
>         Available Logical Addresses: 4
>         DRM Connector Info         : card 1, connector 32
>         Physical Address           : 1.0.0.0
>         Logical Address Mask       : 0x0010
>         CEC Version                : 2.0
>         Vendor ID                  : 0x000c03 (HDMI)
>         OSD Name                   : 'Playback'
>         Logical Addresses          : 1 (Allow RC Passthrough)
> 
>           Logical Address          : 4 (Playback Device 1)
>             Primary Device Type    : Playback
>             Logical Address Type   : Playback
>             All Device Types       : Playback
>             RC TV Profile          : None
>             Device Features        :
>                 None
> 
>         System Information for device 0 (TV) from device 4 (Playback Device 
> 1):
>                 CEC Version                : 1.4
>                 Physical Address           : 0.0.0.0
>                 Primary Device Type        : TV
>                 Vendor ID                  : 0x080046 (Sony)
>                 OSD Name                   : 'TV'
>                 Power Status               : Standby
> 
>         Topology:
> 
>             0.0.0.0: TV
>                 1.0.0.0: Playback Device 1


From stefan at agner.ch  Sat Jan 15 05:28:01 2022
From: stefan at agner.ch (Stefan Agner)
Date: Sat, 15 Jan 2022 14:28:01 +0100
Subject: (EXT) HDMI CEC on ODROID-N2+
In-Reply-To: <8112d37eaed169735ca8b46e5d587210@agner.ch>
References: <d2ef8936c54567c9c2652b3c53a82f68@agner.ch>
 <5560050.DvuYhMxLoT@kongar> <8112d37eaed169735ca8b46e5d587210@agner.ch>
Message-ID: <772e1613cd49ddac3941ae584e0e89c2@agner.ch>

Hi Alexander, Hi Neil,

On 2022-01-15 11:52, Stefan Agner wrote:
> Hi Alexander,
> 
> On 2022-01-15 11:02, Alexander Stein wrote:
>> Hi Stefan,
>>
>> Am Donnerstag, 13. Januar 2022, 15:36:38 CET schrieb Stefan Agner:
>>> Hi Neil,
>>>
>>> I am trying to use HDMI CEC on ODROID-N2+ using Linux 5.10.91. However,
>>> I was unsuccessful: As far as I can tell cec-client uses the right
>>> device (I disabled CONFIG_DRM_DW_HDMI_CEC since my kernel is still
>>> missing your patch "drm/meson: dw-hdmi: disable DW-HDMI CEC
>>> sub-driver"). But communication won't work, and dmesg prints timeout
>>> messages:
>>>
>>> [   68.831253] cec-meson_g12a_ao_cec: message ff 84 20 00 06 timed out
>>> [   71.134987] cec-meson_g12a_ao_cec: message ff 87 00 15 82 timed out
>>> [   73.438826] cec-meson_g12a_ao_cec: message f0 timed out
>>> [   75.742677] cec-meson_g12a_ao_cec: message f0 timed out
>>> [   78.046555] cec-meson_g12a_ao_cec: message f0 timed out
>>> [   80.350446] cec-meson_g12a_ao_cec: message f0 timed out
>>> [   82.654358] cec-meson_g12a_ao_cec: message 11 timed out
>>> [   84.958285] cec-meson_g12a_ao_cec: message 11 timed out
>>> [   87.262194] cec-meson_g12a_ao_cec: message 11 timed out
>>> [   89.566130] cec-meson_g12a_ao_cec: message 11 timed out
>>>
>>> I did a quick test with CoreELEC which uses the 4.9 downstream kernel,
>>> CEC seems to work there. So it does not seem to be my hardware setup.
>>>
>>> A quick test with the latest Linux 5.16 shows the same errors.
>>>
>>> Do you happen to have an idea? Do you know if HDMI CEC using upstream
>>> kernels worked at one point on that particular platform?
>>
>> I'm using Arch Linux on my ODROID-n2 (non-plus) and HDMI CEC works as
>> expected.
>> Currently I'm running a 5.15.13-1-aarch64-ARCH kernel. AFAICS the mentioned
>> patch is mainline since v5.14. I can see my TV without issues. I have to add
>> that not every cable is suitable for HDMI CEC, I have one where CEC does not
>> work (in general).
> 
> Hm, interesting, thanks for the datapoint!
> 
> I tried to reproduce your findings, unfortunately I am not successful in
> booting mainline using Arch Linux ARM so far. It seems it comes with
> downstream 4.9 kernel by default (where CEC seems to work in this case
> too). I then installed linux-aarch64 and adjusted the device tree, but
> it seems that the downstream U-Boot 2015.01-10 has some hardcoded
> "rsvmem" command which fails. How are you booting v5.14?

FWIW, adjusted U-Boot load addresses fixed that issue:
# Set load addresses
setenv dtb_loadaddr "0x20000000"
setenv loadaddr "0x1080000"
setenv initrd_loadaddr "0x4080000"

And I can confirm, HDMI CEC works with Arch Linux 5.15.13 kernel!

> 
> It is a bit surprising that 5.15.13 works for you but 5.16 didn't for
> me. That makes me wonder, could it be bootloader dependent? Are you
> using downstream U-Boot?

That assumption turned out to be wrong: I used our mainline based U-Boot
2021.10 instead of the Arch Linux ARM U-Boot, and HDMI CEC continued to
work.

I then moved to 5.15.13 as well to rule out any kernel changes. But
still, in our configuration HDMI CEC did not work. I ended up diffing
configuration, and noticed that we are using built-in CONFIG_CEC_CORE
whereas Arch Linux uses it as a module. To build CONFIG_CEC_CORE as a
module I had to change some other configuration from built-in to module,
namely:

- CONFIG_CEC_CORE=m
- CONFIG_DRM_DW_HDMI=m
- CONFIG_DRM_MESON=m
- CONFIG_DRM_MESON_DW_HDMI=m

With that change, HDMI CEC started to work in my builds too!

With that change, it also works on Linux 5.10.

I guess there is some ordering issue or something which makes it fail
when those drivers are built-in? Note that I did not change
CONFIG_CEC_MESON_G12A_AO, that driver was already a module before.

--
Stefan


From jbrunet at baylibre.com  Sat Jan 15 07:04:10 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Sat, 15 Jan 2022 16:04:10 +0100
Subject: [PATCH 1/2] arm64: dts: meson-axg: add missing reset-names
 property
In-Reply-To: <20220115093557.30498-1-alexander.stein@mailbox.org>
References: <20220115093557.30498-1-alexander.stein@mailbox.org>
Message-ID: <1jilulav4u.fsf@starbuckisacylon.baylibre.com>


On Sat 15 Jan 2022 at 10:35, Alexander Stein <alexander.stein at mailbox.org> wrote:

> Bindings amlogic,axg-fifo.txt mandates that reset-names is a required
> property. Add it.

Binginds *mandates* ?? the bindings you are adding mandates that, not the
previous doc, nor the driver.

Modifying drivers and DT to accomodate made-up bindings requirement is
disturbing.

The bindings should not require that because the driver does not, as it
stands. The driver requires the arb reset to be provided, not the name.
Please fix the bindings.

>
> Signed-off-by: Alexander Stein <alexander.stein at mailbox.org>
> ---
> This is essentially a preparation for YAML conversion to fix the
> warnings.
>
>  arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
> index 3f5254eeb47b..b14175e2f1d6 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
> @@ -1333,6 +1333,7 @@ toddr_a: audio-controller at 100 {
>  				interrupts = <GIC_SPI 84 IRQ_TYPE_EDGE_RISING>;
>  				clocks = <&clkc_audio AUD_CLKID_TODDR_A>;
>  				resets = <&arb AXG_ARB_TODDR_A>;
> +				reset-names = "arb";
>  				amlogic,fifo-depth = <512>;
>  				status = "disabled";
>  			};
> @@ -1345,6 +1346,7 @@ toddr_b: audio-controller at 140 {
>  				interrupts = <GIC_SPI 85 IRQ_TYPE_EDGE_RISING>;
>  				clocks = <&clkc_audio AUD_CLKID_TODDR_B>;
>  				resets = <&arb AXG_ARB_TODDR_B>;
> +				reset-names = "arb";
>  				amlogic,fifo-depth = <256>;
>  				status = "disabled";
>  			};
> @@ -1357,6 +1359,7 @@ toddr_c: audio-controller at 180 {
>  				interrupts = <GIC_SPI 86 IRQ_TYPE_EDGE_RISING>;
>  				clocks = <&clkc_audio AUD_CLKID_TODDR_C>;
>  				resets = <&arb AXG_ARB_TODDR_C>;
> +				reset-names = "arb";
>  				amlogic,fifo-depth = <256>;
>  				status = "disabled";
>  			};
> @@ -1369,6 +1372,7 @@ frddr_a: audio-controller at 1c0 {
>  				interrupts = <GIC_SPI 88 IRQ_TYPE_EDGE_RISING>;
>  				clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
>  				resets = <&arb AXG_ARB_FRDDR_A>;
> +				reset-names = "arb";
>  				amlogic,fifo-depth = <512>;
>  				status = "disabled";
>  			};
> @@ -1381,6 +1385,7 @@ frddr_b: audio-controller at 200 {
>  				interrupts = <GIC_SPI 89 IRQ_TYPE_EDGE_RISING>;
>  				clocks = <&clkc_audio AUD_CLKID_FRDDR_B>;
>  				resets = <&arb AXG_ARB_FRDDR_B>;
> +				reset-names = "arb";
>  				amlogic,fifo-depth = <256>;
>  				status = "disabled";
>  			};
> @@ -1393,6 +1398,7 @@ frddr_c: audio-controller at 240 {
>  				interrupts = <GIC_SPI 90 IRQ_TYPE_EDGE_RISING>;
>  				clocks = <&clkc_audio AUD_CLKID_FRDDR_C>;
>  				resets = <&arb AXG_ARB_FRDDR_C>;
> +				reset-names = "arb";
>  				amlogic,fifo-depth = <256>;
>  				status = "disabled";
>  			};



From jbrunet at baylibre.com  Sat Jan 15 07:16:41 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Sat, 15 Jan 2022 16:16:41 +0100
Subject: [PATCH 2/2] ASoC: meson: axg-fifo: convert Amlogic FIFO
 controller to yaml
In-Reply-To: <20220115093557.30498-2-alexander.stein@mailbox.org>
References: <20220115093557.30498-1-alexander.stein@mailbox.org>
 <20220115093557.30498-2-alexander.stein@mailbox.org>
Message-ID: <1jee59auok.fsf@starbuckisacylon.baylibre.com>


On Sat 15 Jan 2022 at 10:35, Alexander Stein <alexander.stein at mailbox.org> wrote:

> Convert Amlogic FIFO controller documentation to yaml format.
>
> Signed-off-by: Alexander Stein <alexander.stein at mailbox.org>
> ---
> Things to note:
> First of, Jerome, sorry for adding you as maintainer, but
> 1) it's mandatory
> 2) your are the (only) author of amlogic,axg-fifo.txt
>
> Please add your Signed-off-by if that is okay with you.
>
> License is mandated by checkpath, not my choice.
>
> I'm not so sure about the compatible check. Essentially it is either
> * 'amlogic,axg-frddr' OR
> * 'amlogic,g12a-frddr' + 'amlogic,axg-frddr'
>   (or 'sm1' instead of 'g12a')
>
> Same goes for *-toddr. Is this schema correct in that regard? At least I
> got no warnings on existing device trees.
>

There has already been a submission of this.
It should answer your questions. You've also missed some
constraints regarding resets. Please check:

https://patchwork.kernel.org/project/linux-amlogic/list/?series=246453&state=%2A&archive=both


>  .../bindings/sound/amlogic,axg-fifo.txt       | 34 -------
>  .../bindings/sound/amlogic,axg-fifo.yaml      | 97 +++++++++++++++++++
>  2 files changed, 97 insertions(+), 34 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt
>  create mode 100644 Documentation/devicetree/bindings/sound/amlogic,axg-fifo.yaml
>
> diff --git a/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt b/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt
> deleted file mode 100644
> index fa4545ed81ca..000000000000
> --- a/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt
> +++ /dev/null
> @@ -1,34 +0,0 @@
> -* Amlogic Audio FIFO controllers
> -
> -Required properties:
> -- compatible: 'amlogic,axg-toddr' or
> -	      'amlogic,axg-toddr' or
> -	      'amlogic,g12a-frddr' or
> -	      'amlogic,g12a-toddr' or
> -	      'amlogic,sm1-frddr' or
> -	      'amlogic,sm1-toddr'
> -- reg: physical base address of the controller and length of memory
> -       mapped region.
> -- interrupts: interrupt specifier for the fifo.
> -- clocks: phandle to the fifo peripheral clock provided by the audio
> -	  clock controller.
> -- resets: list of reset phandle, one for each entry reset-names.
> -- reset-names: should contain the following:
> -  * "arb" : memory ARB line (required)
> -  * "rst" : dedicated device reset line (optional)
> -- #sound-dai-cells: must be 0.
> -- amlogic,fifo-depth: The size of the controller's fifo in bytes. This
> -  		      is useful for determining certain configuration such
> -		      as the flush threshold of the fifo
> -
> -Example of FRDDR A on the A113 SoC:
> -
> -frddr_a: audio-controller at 1c0 {
> -	compatible = "amlogic,axg-frddr";
> -	reg = <0x0 0x1c0 0x0 0x1c>;
> -	#sound-dai-cells = <0>;
> -	interrupts = <GIC_SPI 88 IRQ_TYPE_EDGE_RISING>;
> -	clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
> -	resets = <&arb AXG_ARB_FRDDR_A>;
> -	fifo-depth = <512>;
> -};
> diff --git a/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.yaml b/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.yaml
> new file mode 100644
> index 000000000000..54bc073591f4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.yaml
> @@ -0,0 +1,97 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/amlogic,axg-fifo.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Amlogic Audio FIFO controllers
> +
> +maintainers:
> +  - Jerome Brunet <jbrunet at baylibre.com>
> +
> +allOf:
> +  - $ref: name-prefix.yaml#
> +
> +properties:
> +  $nodename:
> +    pattern: "^audio-controller at .*"
> +
> +  "#sound-dai-cells":
> +    const: 0
> +
> +  compatible:
> +    oneOf:
> +      - items:
> +          - enum:
> +              - amlogic,g12a-frddr
> +              - amlogic,sm1-frddr
> +          - const: amlogic,axg-frddr
> +      - const: amlogic,axg-frddr
> +      - items:
> +          - enum:
> +              - amlogic,g12a-toddr
> +              - amlogic,sm1-toddr
> +          - const: amlogic,axg-toddr
> +      - const: amlogic,axg-toddr
> +
> +  reg:
> +    items:
> +      - description: physical base address of the controller
> +
> +  interrupts:
> +    items:
> +      - description: FIFO interrupt
> +
> +  clocks:
> +    items:
> +      - description: FIFO peripheral clock provided by the audio clock controller
> +
> +  resets:
> +    minItems: 1
> +    items:
> +      - description: memory ARB line
> +      - description: optional device reset line
> +
> +  reset-names:
> +    minItems: 1
> +    items:
> +      - const: arb
> +      - const: rst
> +
> +  amlogic,fifo-depth:
> +    description: >
> +      The size of the controller's fifo in bytes. This
> +      is useful for determining certain configuration such
> +      as the flush threshold of the fifo
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +
> +  sound-name-prefix: true
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - resets
> +  - reset-names
> +  - '#sound-dai-cells'
> +  - amlogic,fifo-depth
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/axg-audio-clkc.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/reset/amlogic,meson-axg-audio-arb.h>
> +
> +    frddr_a: audio-controller at 1c0 {
> +        compatible = "amlogic,axg-frddr";
> +        reg = <0x1c0 0x1c>;
> +        #sound-dai-cells = <0>;
> +        interrupts = <88 IRQ_TYPE_EDGE_RISING>;
> +        clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
> +        resets = <&arb AXG_ARB_FRDDR_A>;
> +        reset-names = "arb";
> +        amlogic,fifo-depth = <512>;
> +    };



From robh at kernel.org  Sat Jan 15 09:22:30 2022
From: robh at kernel.org (Rob Herring)
Date: Sat, 15 Jan 2022 11:22:30 -0600
Subject: [PATCH 2/2] ASoC: meson: axg-fifo: convert Amlogic FIFO
 controller to yaml
In-Reply-To: <20220115093557.30498-2-alexander.stein@mailbox.org>
References: <20220115093557.30498-1-alexander.stein@mailbox.org>
 <20220115093557.30498-2-alexander.stein@mailbox.org>
Message-ID: <1642267350.954937.119895.nullmailer@robh.at.kernel.org>

On Sat, 15 Jan 2022 10:35:57 +0100, Alexander Stein wrote:
> Convert Amlogic FIFO controller documentation to yaml format.
> 
> Signed-off-by: Alexander Stein <alexander.stein at mailbox.org>
> ---
> Things to note:
> First of, Jerome, sorry for adding you as maintainer, but
> 1) it's mandatory
> 2) your are the (only) author of amlogic,axg-fifo.txt
> 
> Please add your Signed-off-by if that is okay with you.
> 
> License is mandated by checkpath, not my choice.
> 
> I'm not so sure about the compatible check. Essentially it is either
> * 'amlogic,axg-frddr' OR
> * 'amlogic,g12a-frddr' + 'amlogic,axg-frddr'
>   (or 'sm1' instead of 'g12a')
> 
> Same goes for *-toddr. Is this schema correct in that regard? At least I
> got no warnings on existing device trees.
> 
>  .../bindings/sound/amlogic,axg-fifo.txt       | 34 -------
>  .../bindings/sound/amlogic,axg-fifo.yaml      | 97 +++++++++++++++++++
>  2 files changed, 97 insertions(+), 34 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt
>  create mode 100644 Documentation/devicetree/bindings/sound/amlogic,axg-fifo.yaml
> 

Running 'make dtbs_check' with the schema in this patch gives the
following warnings. Consider if they are expected or the schema is
incorrect. These may not be new warnings.

Note that it is not yet a requirement to have 0 warnings for dtbs_check.
This will change in the future.

Full log is available here: https://patchwork.ozlabs.org/patch/1580333


audio-controller at 100: 'reset-names' is a required property
	arch/arm64/boot/dts/amlogic/meson-axg-s400.dt.yaml

audio-controller at 140: 'reset-names' is a required property
	arch/arm64/boot/dts/amlogic/meson-axg-s400.dt.yaml

audio-controller at 180: 'reset-names' is a required property
	arch/arm64/boot/dts/amlogic/meson-axg-s400.dt.yaml

audio-controller at 1c0: 'reset-names' is a required property
	arch/arm64/boot/dts/amlogic/meson-axg-s400.dt.yaml

audio-controller at 200: 'reset-names' is a required property
	arch/arm64/boot/dts/amlogic/meson-axg-s400.dt.yaml

audio-controller at 240: 'reset-names' is a required property
	arch/arm64/boot/dts/amlogic/meson-axg-s400.dt.yaml



From robh+dt at kernel.org  Sat Jan 15 09:29:10 2022
From: robh+dt at kernel.org (Rob Herring)
Date: Sat, 15 Jan 2022 11:29:10 -0600
Subject: [PATCH 2/2] ASoC: meson: axg-fifo: convert Amlogic FIFO
 controller to yaml
In-Reply-To: <20220115093557.30498-2-alexander.stein@mailbox.org>
References: <20220115093557.30498-1-alexander.stein@mailbox.org>
 <20220115093557.30498-2-alexander.stein@mailbox.org>
Message-ID: <CAL_JsqKfSLb2EB4AJObPqHN7iKm555xHuiNAdmd4mu4jgW0H1g@mail.gmail.com>

On Sat, Jan 15, 2022 at 3:36 AM Alexander Stein
<alexander.stein at mailbox.org> wrote:
>
> Convert Amlogic FIFO controller documentation to yaml format.
>
> Signed-off-by: Alexander Stein <alexander.stein at mailbox.org>
> ---
> Things to note:
> First of, Jerome, sorry for adding you as maintainer, but
> 1) it's mandatory
> 2) your are the (only) author of amlogic,axg-fifo.txt
>
> Please add your Signed-off-by if that is okay with you.

That's not how Signed-off-by works. 'Acked-by' would be correct. But
as the only author, I don't think that's required here.
>
> License is mandated by checkpath, not my choice.

checkpatch doesn't mandate anything. It is guidance. If you copy the
existing binding, then you inherit the default license (GPL-2.0). But
if Jerome is okay with relicensing, that would be nice.

Rob


From linus.walleij at linaro.org  Sat Jan 15 17:03:18 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 16 Jan 2022 02:03:18 +0100
Subject: [PATCH 1/3] pinctrl: meson-g12a: add more pwm_f options
In-Reply-To: <20220103154616.308376-2-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220103154616.308376-2-gary.bisson@boundarydevices.com>
Message-ID: <CACRpkdZRL8VuY5K_d69VHE6eXCmUb18ZRs5v9shExe4ipmw90Q@mail.gmail.com>

On Mon, Jan 3, 2022 at 4:46 PM Gary Bisson
<gary.bisson at boundarydevices.com> wrote:

> Add missing PWM_F pin muxing for GPIOA_11 and GPIOZ_12.
>
> Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>

This patch 1/3 applied for v5.18.

Yours,
Linus Walleij


From xkernel.wang at foxmail.com  Sat Jan 15 21:34:50 2022
From: xkernel.wang at foxmail.com (xkernel.wang at foxmail.com)
Date: Sun, 16 Jan 2022 13:34:50 +0800
Subject: [PATCH] nvmem: meson-mx-efuse: check the return value of
 devm_kstrdup()
Message-ID: <tencent_0F8E090AA07050A5857F1E9067E6B9DC0C07@qq.com>

From: Xiaoke Wang <xkernel.wang at foxmail.com>

devm_kstrdup() returns pointer to allocated string on success,
NULL on failure. So it is better to check the return value of it.

Signed-off-by: Xiaoke Wang <xkernel.wang at foxmail.com>
---
 drivers/nvmem/meson-mx-efuse.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/nvmem/meson-mx-efuse.c b/drivers/nvmem/meson-mx-efuse.c
index 07c9f38..38e6a5f 100644
--- a/drivers/nvmem/meson-mx-efuse.c
+++ b/drivers/nvmem/meson-mx-efuse.c
@@ -211,6 +211,9 @@ static int meson_mx_efuse_probe(struct platform_device *pdev)
 
 	efuse->config.name = devm_kstrdup(&pdev->dev, drvdata->name,
 					  GFP_KERNEL);
+	if (!efuse->config.name)
+		return -ENOMEM;
+
 	efuse->config.owner = THIS_MODULE;
 	efuse->config.dev = &pdev->dev;
 	efuse->config.priv = efuse;
-- 


From alexander.stein at mailbox.org  Sun Jan 16 01:49:45 2022
From: alexander.stein at mailbox.org (Alexander Stein)
Date: Sun, 16 Jan 2022 10:49:45 +0100
Subject: [PATCH 1/2] arm64: dts: meson-axg: add missing reset-names
 property
In-Reply-To: <1jilulav4u.fsf@starbuckisacylon.baylibre.com>
References: <20220115093557.30498-1-alexander.stein@mailbox.org>
 <1jilulav4u.fsf@starbuckisacylon.baylibre.com>
Message-ID: <4732096.GXAFRqVoOG@kongar>

Am Samstag, 15. Januar 2022, 16:04:10 CET schrieb Jerome Brunet:
> 
> On Sat 15 Jan 2022 at 10:35, Alexander Stein <alexander.stein at mailbox.org> 
wrote:
> 
> > Bindings amlogic,axg-fifo.txt mandates that reset-names is a required
> > property. Add it.
> 
> Binginds *mandates* ?? the bindings you are adding mandates that, not the
> previous doc, nor the driver.

Well, under required properties 'reset-names' is listed as well as 'arb' is 
required, only 'rst' is optional.
So when creating the .yaml accordingly this leads to warnings this patch is 
about to fix.

> Modifying drivers and DT to accomodate made-up bindings requirement is
> disturbing.
> 
> The bindings should not require that because the driver does not, as it
> stands. The driver requires the arb reset to be provided, not the name.
> Please fix the bindings.

Nothing is made up. When creating the .yaml file I took the .txt documentation 
for granted. How should I know the bindings documentation is apparently wrong?

When using your older bindings conversion [1] I'm fine with dropping this one.

Best regards,
Alexander

[1] https://patchwork.kernel.org/project/linux-amlogic/list/?
series=246453&state=%2A&archive=both




From alexander.stein at mailbox.org  Sun Jan 16 02:14:14 2022
From: alexander.stein at mailbox.org (Alexander Stein)
Date: Sun, 16 Jan 2022 11:14:14 +0100
Subject: (EXT) HDMI CEC on ODROID-N2+
In-Reply-To: <772e1613cd49ddac3941ae584e0e89c2@agner.ch>
References: <d2ef8936c54567c9c2652b3c53a82f68@agner.ch>
 <8112d37eaed169735ca8b46e5d587210@agner.ch>
 <772e1613cd49ddac3941ae584e0e89c2@agner.ch>
Message-ID: <2219762.iZASKD2KPV@kongar>

Hi Stefan,

Am Samstag, 15. Januar 2022, 14:28:01 CET schrieb Stefan Agner:
> > I tried to reproduce your findings, unfortunately I am not successful in
> > booting mainline using Arch Linux ARM so far. It seems it comes with
> > downstream 4.9 kernel by default (where CEC seems to work in this case
> > too). I then installed linux-aarch64 and adjusted the device tree, but
> > it seems that the downstream U-Boot 2015.01-10 has some hardcoded
> > "rsvmem" command which fails. How are you booting v5.14?
> 
> FWIW, adjusted U-Boot load addresses fixed that issue:
> # Set load addresses
> setenv dtb_loadaddr "0x20000000"
> setenv loadaddr "0x1080000"
> setenv initrd_loadaddr "0x4080000"
> 
> And I can confirm, HDMI CEC works with Arch Linux 5.15.13 kernel!

Yes, you need to modify the loading addresses as with newer kernels the size 
increased. With the load addresses you will hit a memory hole which aborts the 
boot process.
I'm on downstream u-boot BTW.

> That assumption turned out to be wrong: I used our mainline based U-Boot
> 2021.10 instead of the Arch Linux ARM U-Boot, and HDMI CEC continued to
> work.

Does the mainstream U-Boot work out of the box? Or does it require some 
additional configuration?

> I then moved to 5.15.13 as well to rule out any kernel changes. But
> still, in our configuration HDMI CEC did not work. I ended up diffing
> configuration, and noticed that we are using built-in CONFIG_CEC_CORE
> whereas Arch Linux uses it as a module. To build CONFIG_CEC_CORE as a
> module I had to change some other configuration from built-in to module,
> namely:
> 
> - CONFIG_CEC_CORE=m
> - CONFIG_DRM_DW_HDMI=m
> - CONFIG_DRM_MESON=m
> - CONFIG_DRM_MESON_DW_HDMI=m
> 
> With that change, HDMI CEC started to work in my builds too!
> 
> With that change, it also works on Linux 5.10.
> 
> I guess there is some ordering issue or something which makes it fail
> when those drivers are built-in? Note that I did not change
> CONFIG_CEC_MESON_G12A_AO, that driver was already a module before.

You need all 4 options above to be modules? Or is it maybe enough to set 
CONFIG_DRM_DW_HDMI_CEC=m? This should make CONFIG_CEC_CORE=m as well, while 
the other modules are built-in.
I suspect at some point a -EPROBE_DEFER is missing.

Just FYI: Arch Linux aarch64 kernel config currently lacks some drivers for 
HDMI audio. See [1].

Best regards,
Alexander

[1] https://github.com/archlinuxarm/PKGBUILDs/pull/1864





From stefan at agner.ch  Sun Jan 16 02:50:14 2022
From: stefan at agner.ch (Stefan Agner)
Date: Sun, 16 Jan 2022 11:50:14 +0100
Subject: (EXT) HDMI CEC on ODROID-N2+
In-Reply-To: <2219762.iZASKD2KPV@kongar>
References: <d2ef8936c54567c9c2652b3c53a82f68@agner.ch>
 <8112d37eaed169735ca8b46e5d587210@agner.ch>
 <772e1613cd49ddac3941ae584e0e89c2@agner.ch> <2219762.iZASKD2KPV@kongar>
Message-ID: <3ed4754d39454354c6ac79ea2256c969@agner.ch>

Hi Alexander,

On 2022-01-16 11:14, Alexander Stein wrote:
> Hi Stefan,
> 
> Am Samstag, 15. Januar 2022, 14:28:01 CET schrieb Stefan Agner:
>> That assumption turned out to be wrong: I used our mainline based U-Boot
>> 2021.10 instead of the Arch Linux ARM U-Boot, and HDMI CEC continued to
>> work.
> 
> Does the mainstream U-Boot work out of the box? Or does it require some 
> additional configuration?
> 

Yes mainline U-Boot works out of the box. Building it is somewhat
involved since it requires extra firmwares (there are build instructions
in the source tree in board/amlogic/w400/README.odroid-n2).

You need to add a boot script to your boot partition. I used the script
part of the uboot-odroid-n2-mainline package as inspiration [1]. It
needs some adjustments as it seems to try to boot from the root file
system directly (and my setup used the FAT/ext4 setup still).

We carry a single patch which improved reliability booting from eMMC,
see [2].


>> I then moved to 5.15.13 as well to rule out any kernel changes. But
>> still, in our configuration HDMI CEC did not work. I ended up diffing
>> configuration, and noticed that we are using built-in CONFIG_CEC_CORE
>> whereas Arch Linux uses it as a module. To build CONFIG_CEC_CORE as a
>> module I had to change some other configuration from built-in to module,
>> namely:
>>
>> - CONFIG_CEC_CORE=m
>> - CONFIG_DRM_DW_HDMI=m
>> - CONFIG_DRM_MESON=m
>> - CONFIG_DRM_MESON_DW_HDMI=m
>>
>> With that change, HDMI CEC started to work in my builds too!
>>
>> With that change, it also works on Linux 5.10.
>>
>> I guess there is some ordering issue or something which makes it fail
>> when those drivers are built-in? Note that I did not change
>> CONFIG_CEC_MESON_G12A_AO, that driver was already a module before.
> 
> You need all 4 options above to be modules? Or is it maybe enough to set 
> CONFIG_DRM_DW_HDMI_CEC=m? This should make CONFIG_CEC_CORE=m as well, while 
> the other modules are built-in.

In our builds I disabled CONFIG_DRM_DW_HDMI_CEC entirely actually.

It seems that CONFIG_DRM_DW_HDMI is tied to CEC_CORE through this
dependency:

config DRM_DW_HDMI
...
        select CEC_CORE if CEC_NOTIFIER

> I suspect at some point a -EPROBE_DEFER is missing.
> 
> Just FYI: Arch Linux aarch64 kernel config currently lacks some drivers for 
> HDMI audio. See [1].

Thanks for the link, just checked, it seems our kernel configuration
covers those.

--
Stefan

> 
> Best regards,
> Alexander
> 
> [1] https://github.com/archlinuxarm/PKGBUILDs/pull/1864

[1]
https://github.com/archlinuxarm/PKGBUILDs/blob/master/alarm/uboot-odroid-c2-mainline/boot.txt
[2]
https://github.com/home-assistant/operating-system/blob/rel-7/buildroot-external/board/hardkernel/patches/uboot/0001-HACK-mmc-meson-gx-limit-to-24MHz.patch


From jbrunet at baylibre.com  Sun Jan 16 09:30:32 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Sun, 16 Jan 2022 18:30:32 +0100
Subject: [PATCH 1/2] arm64: dts: meson-axg: add missing reset-names
 property
In-Reply-To: <4732096.GXAFRqVoOG@kongar>
References: <20220115093557.30498-1-alexander.stein@mailbox.org>
 <1jilulav4u.fsf@starbuckisacylon.baylibre.com> <4732096.GXAFRqVoOG@kongar>
Message-ID: <1jfspnpoxh.fsf@starbuckisacylon.baylibre.com>


On Sun 16 Jan 2022 at 10:49, Alexander Stein <alexander.stein at mailbox.org> wrote:

> Am Samstag, 15. Januar 2022, 16:04:10 CET schrieb Jerome Brunet:
>> 
>> On Sat 15 Jan 2022 at 10:35, Alexander Stein <alexander.stein at mailbox.org> 
> wrote:
>> 
>> > Bindings amlogic,axg-fifo.txt mandates that reset-names is a required
>> > property. Add it.
>> 
>> Binginds *mandates* ?? the bindings you are adding mandates that, not the
>> previous doc, nor the driver.
>
> Well, under required properties 'reset-names' is listed as well as 'arb' is 
> required, only 'rst' is optional.

I think there is a misunderstanding then.
The arb reset is required, the "reset-names" is not - as long as there
is single reset.

> So when creating the .yaml accordingly this leads to warnings this patch is 
> about to fix.
>
>> Modifying drivers and DT to accomodate made-up bindings requirement is
>> disturbing.
>> 
>> The bindings should not require that because the driver does not, as it
>> stands. The driver requires the arb reset to be provided, not the name.
>> Please fix the bindings.
>
> Nothing is made up. When creating the .yaml file I took the .txt documentation 
> for granted. How should I know the bindings documentation is apparently wrong?
>
> When using your older bindings conversion [1] I'm fine with dropping this one.
>
> Best regards,
> Alexander
>
> [1] https://patchwork.kernel.org/project/linux-amlogic/list/?
> series=246453&state=%2A&archive=both



From martin.blumenstingl at googlemail.com  Sun Jan 16 15:01:27 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Mon, 17 Jan 2022 00:01:27 +0100
Subject: [PATCH] nvmem: meson-mx-efuse: check the return value of
 devm_kstrdup()
In-Reply-To: <tencent_0F8E090AA07050A5857F1E9067E6B9DC0C07@qq.com>
References: <tencent_0F8E090AA07050A5857F1E9067E6B9DC0C07@qq.com>
Message-ID: <CAFBinCDigiSYT+AkRmCgEB6u_v2uJLg49aNrt8ddxq97FkEMxw@mail.gmail.com>

Hello,

First of all: thank you for this patch!

On Sun, Jan 16, 2022 at 6:37 AM <xkernel.wang at foxmail.com> wrote:
[...]
> @@ -211,6 +211,9 @@ static int meson_mx_efuse_probe(struct platform_device *pdev)
>
>         efuse->config.name = devm_kstrdup(&pdev->dev, drvdata->name,
>                                           GFP_KERNEL);
> +       if (!efuse->config.name)
> +               return -ENOMEM;
Looking at other drivers and also at drivers/nvmem/core.c I believe
that the whole devm_kstrdup is unnecessary.
Instead I think the code can be simplified as:
    efuse->config.name = drvdata->name;

What do you think?


Best regards,
Martin


From liang.yang at amlogic.com  Sun Jan 16 18:43:01 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Mon, 17 Jan 2022 10:43:01 +0800
Subject: [PATCH v9 3/4] clk: meson: add DT documentation for emmc clock
 controller
In-Reply-To: <20220114225957.285ADC36AE7@smtp.kernel.org>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-4-liang.yang@amlogic.com>
 <20220113212957.768FFC36AE3@smtp.kernel.org>
 <5d99ac02-a246-5bcc-2ecb-371b0d193537@amlogic.com>
 <20220114225957.285ADC36AE7@smtp.kernel.org>
Message-ID: <d6933fd7-ec4c-aee1-5cf4-9cbcf881a33d@amlogic.com>



On 2022/1/15 6:59, Stephen Boyd wrote:
> [ EXTERNAL EMAIL ]
> 
> Quoting Liang Yang (2022-01-13 19:06:07)
>> Hi Stephen,
>>
>> Thanks for your quick response.
>>
>> On 2022/1/14 5:29, Stephen Boyd wrote:
>>> [ EXTERNAL EMAIL ]
>>>
>>> Quoting Liang Yang (2022-01-13 03:57:44)
>>>> Document the MMC sub clock controller driver, the potential consumer
>>>> of this driver is MMC or NAND. Also add four clock bindings IDs which
>>>> provided by this driver.
>>>>
>>>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>>>> ---
>>>>    .../bindings/clock/amlogic,mmc-clkc.yaml      | 64 +++++++++++++++++++
>>>>    include/dt-bindings/clock/amlogic,mmc-clkc.h  | 14 ++++
>>>>    2 files changed, 78 insertions(+)
>>>>    create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>>>>    create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>>>> new file mode 100644
>>>> index 000000000000..a274c3d5fc2e
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>>>> @@ -0,0 +1,64 @@
>>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>>> +%YAML 1.2
>>>> +---
>>>> +$id: http://devicetree.org/schemas/clock/amlogic,mmc-clkc.yaml#
>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>> +
>>>> +title: Amlogic MMC Sub Clock Controller Driver Device Tree Bindings
>>>> +
>>>> +maintainers:
>>>> +  - jianxin.pan at amlogic.com
>>>> +  - liang.yang at amlogic.com
>>>> +
>>>> +properties:
>>>> +  compatible:
>>>> +    enum:
>>>> +      - "amlogic,axg-mmc-clkc", "syscon"
>>>
>>> Why is it a syscon?
>>
>> The register documented by reg is shared with SD/eMMC controller port C,
>> and it need to be ops on NFC driver.
>>
> 
> Is this the case where the clk is inside the SD/eMMC controller? Can the
yes.
> mmc driver register the clk controller from there and pass it an iomem
> pointer to poke clks?
we can't do that since EMMC and NAND is mutually exclusivem. both of 
them share the same data pins.
> 
> .


From xkernel.wang at foxmail.com  Sun Jan 16 18:56:21 2022
From: xkernel.wang at foxmail.com (xkernel.wang at foxmail.com)
Date: Mon, 17 Jan 2022 10:56:21 +0800
Subject: [PATCH v2] nvmem: meson-mx-efuse: replace unnecessary devm_kstrdup()
Message-ID: <tencent_0589E3FF08A4905922F78BC38602361C5505@qq.com>

From: Xiaoke Wang <xkernel.wang at foxmail.com>

Replace unnecessary devm_kstrdup() so to avoid redundant memory allocation.

Suggested-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Xiaoke Wang <xkernel.wang at foxmail.com>
---
Changelogs:
Simplify the patch to replace unnecessary devm_kstrdup().
 drivers/nvmem/meson-mx-efuse.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/nvmem/meson-mx-efuse.c b/drivers/nvmem/meson-mx-efuse.c
index 07c9f38..13eb143 100644
--- a/drivers/nvmem/meson-mx-efuse.c
+++ b/drivers/nvmem/meson-mx-efuse.c
@@ -209,8 +209,7 @@ static int meson_mx_efuse_probe(struct platform_device *pdev)
 	if (IS_ERR(efuse->base))
 		return PTR_ERR(efuse->base);
 
-	efuse->config.name = devm_kstrdup(&pdev->dev, drvdata->name,
-					  GFP_KERNEL);
+	efuse->config.name = drvdata->name;
 	efuse->config.owner = THIS_MODULE;
 	efuse->config.dev = &pdev->dev;
 	efuse->config.priv = efuse;
-- 


From liang.yang at amlogic.com  Sun Jan 16 22:24:28 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Mon, 17 Jan 2022 14:24:28 +0800
Subject: [PATCH v9 4/4] clk: meson: add sub MMC clock controller driver
In-Reply-To: <20220114230130.35EAAC36AE7@smtp.kernel.org>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-5-liang.yang@amlogic.com>
 <20220113213513.9819AC36AEA@smtp.kernel.org>
 <09ff9044-9abc-d1ad-26c1-5e6ece56d30c@amlogic.com>
 <20220114230130.35EAAC36AE7@smtp.kernel.org>
Message-ID: <fe77fd6b-788f-1694-f260-f95e54cf4ef3@amlogic.com>



On 2022/1/15 7:01, Stephen Boyd wrote:
> [ EXTERNAL EMAIL ]
> 
> Quoting Liang Yang (2022-01-13 21:14:46)
>> On 2022/1/14 5:35, Stephen Boyd wrote:
>>> Quoting Liang Yang (2022-01-13 03:57:45)
>>>> diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c
>>>> new file mode 100644
>>>> index 000000000000..f53977f61390
>>>> --- /dev/null
>>>> +++ b/drivers/clk/meson/mmc-clkc.c
>>>> @@ -0,0 +1,300 @@
> [..]
>>>> +
>>>> +static int mmc_clkc_probe(struct platform_device *pdev)
>>>> +{
>>>> +       struct clk_hw_onecell_data *onecell_data;
>>>> +       struct device *dev = &pdev->dev;
>>>> +       struct mmc_clkc_data *data;
>>>> +       struct regmap *map;
>>>> +       struct clk_regmap *clk, *core;
>>>> +       struct meson_sclk_div_data *div_data;
>>>> +
>>>> +       /*cast to drop the const in match->data*/
>>>
>>> Space after *, also why do we need to cast away const? The user of this
>>> pointer passes it all the way down to mmc_clkc_register_clk() which
>>> could take the data as const void pointer and decide to cast away const
>>> there.
>>
>> if use 'const' here, it  will report a warning:
>> drivers/clk/meson/mmc-clkc.c:224:7: error: assignment discards ?const?
>> qualifier from pointer targe
>> t type [-Werror=discarded-qualifiers]
>>
>>     data = (const struct mmc_clkc_data *)of_device_get_match_data(dev);
> 
> Of course. The type declaration up above needs const added to it.The parm of mmc_clkc_register_clk_with_parent(...., void *data) does not 
have 'const', so make the type declaration cause a further 'const' cast 
warning. Could i copy these infos just like below:

struct mmc_clkc_data *data_clkc;
......
data = of_device_get_match_data(dev);
data_clkc = devm_kmalloc(dev, sizeof(*data_clkc), GFP_KERNEL);
memcpy(data_clkc, data, sizeof(*data_clkc));
......
clk = mmc_clkc_register_clk_with_parent(...., &data_clkc->rx);

> 
> .


From liang.yang at amlogic.com  Sun Jan 16 23:03:47 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Mon, 17 Jan 2022 15:03:47 +0800
Subject: [PATCH v9 3/4] clk: meson: add DT documentation for emmc clock
 controller
In-Reply-To: <CAFBinCDkNk+Ba340vshhL2rE76U9qb_dZ5ZsgWnMgFYpL6i1jA@mail.gmail.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-4-liang.yang@amlogic.com>
 <20220113212957.768FFC36AE3@smtp.kernel.org>
 <5d99ac02-a246-5bcc-2ecb-371b0d193537@amlogic.com>
 <CAFBinCDkNk+Ba340vshhL2rE76U9qb_dZ5ZsgWnMgFYpL6i1jA@mail.gmail.com>
Message-ID: <8783eb66-16ee-3b8b-5d55-73b49deab3a2@amlogic.com>

Hi Martin,

On 2022/1/15 8:09, Martin Blumenstingl wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi Liang,
> 
> On Fri, Jan 14, 2022 at 4:06 AM Liang Yang <liang.yang at amlogic.com> wrote:
> [...]
>>>> +properties:
>>>> +  compatible:
>>>> +    enum:
>>>> +      - "amlogic,axg-mmc-clkc", "syscon"
>>>
>>> Why is it a syscon?
>>
>> The register documented by reg is shared with SD/eMMC controller port C,
>> and it need to be ops on NFC driver.
> Can you please share an example how the .dts would look like in the
> end for two example cases:
> 1) using the sd_emmc_c MMC interface > 2) not using the MMC interface of sd_emmc_c but only using it's clocks
> for the NFC
I think both EMMC(although it is not implemented by 'axg-mmc-clkc'  yet) 
and NAND clock have the same way in dts:
		......
		clocks = <&clkc CLKID_SD_EMMC_C>,
			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
		clock-names = "core", "device", "rx", "tx";
		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
		......

> 
> Initially I wanted to suggest the usage of a sub-node with compatible
> = "mmc-slot" (see
> Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.txt for an
> example) to decide whether the MMC controller is registered or whether
> just the clock controller is registered.
> However, the mmc-slot compatible string is not documented in
> Documentation/devicetree/bindings/mmc/mmc-controller.yaml currently.
> Maybe the MMC maintainers have any suggestions if other IPs have
> similar requirements (for IPs with shared parts).
> 
> 
> Best regards,
> Martin
> 
> .


From jbrunet at baylibre.com  Mon Jan 17 00:26:40 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 17 Jan 2022 09:26:40 +0100
Subject: [PATCH V4 3/5] tty: serial: meson: The UART baud rate
In-Reply-To: <c9bb2f8f-6169-b4ab-5637-56c185dbf254@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
 <20220110085604.18042-4-yu.tu@amlogic.com>
 <1j8rvnps11.fsf@starbuckisacylon.baylibre.com>
 <c9bb2f8f-6169-b4ab-5637-56c185dbf254@amlogic.com>
Message-ID: <1j7dayn4vh.fsf@starbuckisacylon.baylibre.com>


On Tue 11 Jan 2022 at 15:04, Yu Tu <yu.tu at amlogic.com> wrote:

> Hi Jerome,
> 	Thank you very much for your reply.
>
> On 2022/1/10 22:29, Jerome Brunet wrote:
>> [ EXTERNAL EMAIL ]
>> 
>> On Mon 10 Jan 2022 at 16:56, Yu Tu <yu.tu at amlogic.com> wrote:
>> Title is bad (like several other patches in this series) - Please fix it
>> Ok.
>>> Using the common Clock code to describe the UART baud rate clock
>>> makes it easier for the UART driver to be compatible with the
>>> baud rate requirements of the UART IP on different meson chips.
>>>
>>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>>> ---
>>>   drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
>>>   1 file changed, 163 insertions(+), 61 deletions(-)
>>>
>>> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
>>> index 7570958d010c..1004fd0b0c9e 100644
>>> --- a/drivers/tty/serial/meson_uart.c
>>> +++ b/drivers/tty/serial/meson_uart.c
>>> @@ -6,6 +6,7 @@
>>>    */
>>>     #include <linux/clk.h>
>>> +#include <linux/clk-provider.h>
>>>   #include <linux/console.h>
>>>   #include <linux/delay.h>
>>>   #include <linux/init.h>
>>> @@ -65,9 +66,7 @@
>>>   #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>>>     /* AML_UART_REG5 bits */
>>> -#define AML_UART_BAUD_MASK		0x7fffff
>>>   #define AML_UART_BAUD_USE		BIT(23)
>>> -#define AML_UART_BAUD_XTAL		BIT(24)
>>>     #define AML_UART_PORT_NUM		12
>>>   #define AML_UART_PORT_OFFSET		6
>>> @@ -76,6 +75,13 @@
>>>   #define AML_UART_POLL_USEC		5
>>>   #define AML_UART_TIMEOUT_USEC		10000
>>>   +struct meson_uart_data {
>>> +	struct uart_port	port;
>>> +	struct clk		*pclk;
>>> +	struct clk		*baud_clk;
>>> +	bool			use_xtal_clk;
>>> +};
>>> +
>>>   static struct uart_driver meson_uart_driver;
>>>     static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>>> @@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
>>>   static int meson_uart_startup(struct uart_port *port)
>>>   {
>>>   	u32 val;
>>> -	int ret = 0;
>>> +	int ret;
>>>   -	val = readl(port->membase + AML_UART_CONTROL);
>>> -	val |= AML_UART_CLEAR_ERR;
>>> -	writel(val, port->membase + AML_UART_CONTROL);
>>> -	val &= ~AML_UART_CLEAR_ERR;
>>> -	writel(val, port->membase + AML_UART_CONTROL);
>>> +	meson_uart_reset(port);
>>>   +	val = readl(port->membase + AML_UART_CONTROL);
>>>   	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>>>   	writel(val, port->membase + AML_UART_CONTROL);
>>>   @@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port
>>> *port)
>>>     static void meson_uart_change_speed(struct uart_port *port, unsigned
>>> long baud)
>>>   {
>>> +	struct meson_uart_data *private_data = port->private_data;
>>>   	u32 val;
>>>     	while (!meson_uart_tx_empty(port))
>>>   		cpu_relax();
>>>   -	if (port->uartclk == 24000000) {
>>> -		val = ((port->uartclk / 3) / baud) - 1;
>>> -		val |= AML_UART_BAUD_XTAL;
>>> -	} else {
>>> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>>> -	}
>>> +	val = readl(port->membase + AML_UART_REG5);
>>>   	val |= AML_UART_BAUD_USE;
>>>   	writel(val, port->membase + AML_UART_REG5);
>>> +
>>> +	clk_set_rate(private_data->baud_clk, baud);
>>>   }
>>>     static void meson_uart_set_termios(struct uart_port *port,
>>> @@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>>>     static void meson_uart_release_port(struct uart_port *port)
>>>   {
>>> -	/* nothing to do */
>>> +	struct meson_uart_data *private_data = port->private_data;
>>> +
>>> +	clk_disable_unprepare(private_data->baud_clk);
>>> +	clk_disable_unprepare(private_data->pclk);
>>>   }
>>>     static int meson_uart_request_port(struct uart_port *port)
>>>   {
>>> +	struct meson_uart_data *private_data = port->private_data;
>>> +	int ret;
>>> +
>>> +	ret = clk_prepare_enable(private_data->pclk);
>>> +	if (ret)
>>> +		return ret;
>> In the previous version of the series, you already been asked to the
>> enable of pclk in the probe. Optimization should not be mixed with this
>> series
>> Please make sure all comments are addressed before re-posting
>> 
> I'm sorry. I misunderstood you earlier. I'm going to move into the probe
> function.
>>> +
>>> +	ret = clk_prepare_enable(private_data->baud_clk);
>>> +	if (ret) {
>>> +		clk_disable_unprepare(private_data->pclk);
>>> +		return ret;
>>> +	}
>>> +
>>>   	return 0;
>>>   }
>>>   @@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
>>>   	.cons		= MESON_SERIAL_CONSOLE,
>>>   };
>>>   -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>>> -						 const char *id)
>>> +#define CLK_NAME(name) \
>>> +({\
>>> +	char clk_name[32];\
>>> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
>>> +	clk_name;\
>>> +})
>> 1) This result in some ugly code being inlined
>> 2) You return a pointer a local variable which is not gurantee to exist
>> anymore  outside of this ...
>> Please do this simply in the related function.
> I've overdone it. I'll move it to the meson_uart_probe_clocks function as
> you suggested.
>> 
>>> +
>>> +static struct clk_div_table xtal_div_table[] = {
>>> +	{ 0, 3  },
>>> +	{ 1, 1  },
>>> +	{ 2, 2  },
>>> +	{ 3, 2  },
>>> +};
>>> +
>>> +static int meson_uart_probe_clocks(struct uart_port *port)
>>>   {
>>> -	struct clk *clk = NULL;
>>> -	int ret;
>>> +	struct meson_uart_data *private_data = port->private_data;
>>> +	struct clk *clk_baud, *clk_xtal;
>>> +	struct clk_hw *hw;
>>> +	struct clk_parent_data use_xtal_mux_parents[2] = {
>>> +		{ .index = -1, },
>>> +		{ .index = -1, },
>>> +	};
>>>   -	clk = devm_clk_get(dev, id);
>>> -	if (IS_ERR(clk))
>>> -		return clk;
>>> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
>>> +	if (IS_ERR(private_data->pclk))
>>> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
>>> +				     "Failed to get the 'pclk' clock\n");
>>>   -	ret = clk_prepare_enable(clk);
>>> -	if (ret) {
>>> -		dev_err(dev, "couldn't enable clk\n");
>>> -		return ERR_PTR(ret);
>>> +	clk_baud = devm_clk_get(port->dev, "baud");
>>> +	if (IS_ERR(clk_baud)) {
>>> +		dev_err(port->dev, "Failed to get the 'baud' clock\n");
>>> +		return PTR_ERR(clk_baud);
>>>   	}
>>>   -	devm_add_action_or_reset(dev,
>>> -			(void(*)(void *))clk_disable_unprepare,
>>> -			clk);
>>> -
>>> -	return clk;
>>> -}
>>> -
>>> -static int meson_uart_probe_clocks(struct platform_device *pdev,
>>> -				   struct uart_port *port)
>>> -{
>>> -	struct clk *clk_xtal = NULL;
>>> -	struct clk *clk_pclk = NULL;
>>> -	struct clk *clk_baud = NULL;
>>> -
>>> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>>> -	if (IS_ERR(clk_pclk))
>>> -		return PTR_ERR(clk_pclk);
>>> -
>>> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>>> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>>>   	if (IS_ERR(clk_xtal))
>>> -		return PTR_ERR(clk_xtal);
>>> -
>>> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>>> -	if (IS_ERR(clk_baud))
>>> -		return PTR_ERR(clk_baud);
>>> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>>> +				     "Failed to get the 'xtal' clock\n");
>>> +
>>> +	if (private_data->use_xtal_clk) {
>>> +		hw = devm_clk_hw_register_divider_table(port->dev,
>>> +							CLK_NAME(xtal_div),
>>> +							__clk_get_name(clk_baud),
>>> +							CLK_SET_RATE_NO_REPARENT,
>>> +							port->membase + AML_UART_REG5,
>>> +							26, 2,
>>> +							CLK_DIVIDER_READ_ONLY,
>>> +							xtal_div_table, NULL);
>>> +		if (IS_ERR(hw))
>>> +			return PTR_ERR(hw);
>>> +
>>> +		use_xtal_mux_parents[1].hw = hw;
>>> +	} else {
>>> +		hw = devm_clk_hw_register_fixed_factor(port->dev,
>>> +						       CLK_NAME(clk81_div4),
>>> +						       __clk_get_name(clk_baud),
>>> +						       CLK_SET_RATE_NO_REPARENT,
>>> +						       1, 4);
>>> +		if (IS_ERR(hw))
>>> +			return PTR_ERR(hw);
>>> +
>>> +		use_xtal_mux_parents[0].hw = hw;
>>> +	}
>> Contradiction with previous series.
>> In the previous series we could clearly see that gxbb did not have the
>> /4 divider. It did not have bits 26 and 27 either.
>> Now gxbb get the /4 divider. It operated correctly without it so far, so
>> this is rather suspicious. Could you please comment on this ?
>> 
> As Martin and I discussed earlier.
> meson6 and meson8b SoC.There are not have bits 26 and 27 either.
> CLK81 is recommended for this part of SOC.
>
> GXL,GXM,GXBB and AXG SOC.The UART_EE_A_REG5[26] is added.
> UART_EE_A_REG5[26]:
> - 0x0: divide the input clock by 3 (meaning: this internally works
> with an 8MHz clock)
> - 0x1: use the input clock directly without further division (meaning:
> this internally work with an 24MHz clock)
> 8MHz is recommended for this part of SOC. Their UART IP configuration is
> the same.
>
> G12A/B,,SM1,A1 and S4 SOC.The UART_EE_A_REG5[27] is added.
> UART_EE_A_REG5[27]:
> - 0x0: use the clock as configured in UART_EE_A_REG5[26]
> - 0x1: divide the input clock by 2 (meaning: this internally works
> with an 12MHz clock)
> 12MHz is recommended for this part of SOC.
>
> NOTE:
> 1. clk81 /4 divider.
> There is a 4 divider inside, this is what the internal SOC designer told
> me. But they forgot to document it. So it makes people feel suspicious.
>
> 2.The UART_EE_A_REG5 default value is 0,except for the console port(set in
> romcode).All the baud rate clocks supported by UART can work, but different
> chip usage scenarios suggest using that clock to reduce jitter.
>
> In summary, I would like to know your suggestions, including how to change
> compatible.
> Thank you so much!

>From your comment, gxbb should have "true" instead of false, isn't it ?

>
>  >>
>>> -	port->uartclk = clk_get_rate(clk_baud);
>>> +	hw = __devm_clk_hw_register_mux(port->dev, NULL,
>>> +					CLK_NAME(use_xtal),
>>> +					ARRAY_SIZE(use_xtal_mux_parents),
>>> +					NULL, NULL,
>>> +					use_xtal_mux_parents,
>>> +					CLK_SET_RATE_PARENT,
>>> +					port->membase + AML_UART_REG5,
>>> +					24, 0x1,
>>> +					CLK_MUX_READ_ONLY,
>>> +					NULL, NULL);
>>> +	if (IS_ERR(hw))
>>> +		return PTR_ERR(hw);
>>> +
>>> +	port->uartclk = clk_hw_get_rate(hw);
>>> +
>>> +	hw = devm_clk_hw_register_divider(port->dev,
>>> +					  CLK_NAME(baud_div),
>>> +					  clk_hw_get_name(hw),
>>> +					  CLK_SET_RATE_PARENT,
>>> +					  port->membase + AML_UART_REG5,
>>> +					  0, 23,
>>> +					  CLK_DIVIDER_ROUND_CLOSEST,
>>> +					  NULL);
>>> +	if (IS_ERR(hw))
>>> +		return PTR_ERR(hw);
>>> +
>>> +	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
>> I have already commented on the use of this function in the previous
>> version.
>> Please make sure all comments are addressed before re-posting
>> 
> I'm sorry. I misunderstood you earlier. I will be changed to
> "private_data->baud_clk = hw->clk;".What do you think?

yes

>>>     	return 0;
>>>   }
>>>     static int meson_uart_probe(struct platform_device *pdev)
>>>   {
>>> +	struct meson_uart_data *private_data;
>>>   	struct resource *res_mem;
>>>   	struct uart_port *port;
>>>   	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
>>> @@ -716,18 +783,20 @@ static int meson_uart_probe(struct platform_device *pdev)
>>>   		return -EBUSY;
>>>   	}
>>>   -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port),
>>> GFP_KERNEL);
>>> -	if (!port)
>>> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
>>> +				    GFP_KERNEL);
>>> +	if (!private_data)
>>>   		return -ENOMEM;
>>>   +	if (device_get_match_data(&pdev->dev))
>>> +		private_data->use_xtal_clk = true;
>>> +
>>> +	port = &private_data->port;
>>> +
>>>   	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>>>   	if (IS_ERR(port->membase))
>>>   		return PTR_ERR(port->membase);
>>>   -	ret = meson_uart_probe_clocks(pdev, port);
>>> -	if (ret)
>>> -		return ret;
>>> -
>>>   	port->iotype = UPIO_MEM;
>>>   	port->mapbase = res_mem->start;
>>>   	port->mapsize = resource_size(res_mem);
>>> @@ -740,7 +809,11 @@ static int meson_uart_probe(struct platform_device *pdev)
>>>   	port->x_char = 0;
>>>   	port->ops = &meson_uart_ops;
>>>   	port->fifosize = fifosize;
>>> +	port->private_data = private_data;
>> port has private_data
>> private_data has port
>> Is it really necessary to have both ... looks to me that port in
>> private_data is overkill
>> 
> It's very thoughtful of you. I'll delete it as you suggested.
>>>   +	ret = meson_uart_probe_clocks(port);
>>> +	if (ret)
>>> +		return ret;
>>>   	meson_ports[pdev->id] = port;
>>>   	platform_set_drvdata(pdev, port);
>>>   @@ -766,10 +839,39 @@ static int meson_uart_remove(struct
>>> platform_device *pdev)
>>>   }
>>>     static const struct of_device_id meson_uart_dt_match[] = {
>>> -	{ .compatible = "amlogic,meson6-uart" },
>>> -	{ .compatible = "amlogic,meson8-uart" },
>>> -	{ .compatible = "amlogic,meson8b-uart" },
>>> -	{ .compatible = "amlogic,meson-gx-uart" },
>>> +	{
>>> +		.compatible = "amlogic,meson6-uart",
>>> +		.data = (void *)false,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson8-uart",
>>> +		.data = (void *)false,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson8b-uart",
>>> +		.data = (void *)false,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson-gxbb-uart",
>>> +		.data = (void *)false,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson-gxl-uart",
>>> +		.data = (void *)true,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson-g12a-uart",
>>> +		.data = (void *)true,
>>> +	},
>>> +	/*
>>> +	 * deprecated, don't use anymore because it doesn't differentiate
>>> +	 * between GXBB, GXL and G12A which have different revisions
>>> +	 * of the UART IP.
>>> +	 */
>>> +	{
>>> +		.compatible = "amlogic,meson-gx-uart",
>>> +		.data = (void *)false,
>>> +	},
>>>   	{ /* sentinel */ },
>>>   };
>>>   MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
>> 
>
> _______________________________________________
> linux-amlogic mailing list
> linux-amlogic at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-amlogic



From yu.tu at amlogic.com  Mon Jan 17 01:03:31 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 17 Jan 2022 17:03:31 +0800
Subject: [PATCH V4 3/5] tty: serial: meson: The UART baud rate
In-Reply-To: <1j7dayn4vh.fsf@starbuckisacylon.baylibre.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
 <20220110085604.18042-4-yu.tu@amlogic.com>
 <1j8rvnps11.fsf@starbuckisacylon.baylibre.com>
 <c9bb2f8f-6169-b4ab-5637-56c185dbf254@amlogic.com>
 <1j7dayn4vh.fsf@starbuckisacylon.baylibre.com>
Message-ID: <70307ecc-b251-6adc-66c2-f7600d237f08@amlogic.com>

  Hi Jerome,
	Thank you very much for your reply.

On 2022/1/17 16:26, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> 
> On Tue 11 Jan 2022 at 15:04, Yu Tu <yu.tu at amlogic.com> wrote:
> 
>> Hi Jerome,
>> 	Thank you very much for your reply.
>>
>> On 2022/1/10 22:29, Jerome Brunet wrote:
>>> [ EXTERNAL EMAIL ]
>>>
>>> On Mon 10 Jan 2022 at 16:56, Yu Tu <yu.tu at amlogic.com> wrote:
>>> Title is bad (like several other patches in this series) - Please fix it
>>> Ok.
>>>> Using the common Clock code to describe the UART baud rate clock
>>>> makes it easier for the UART driver to be compatible with the
>>>> baud rate requirements of the UART IP on different meson chips.
>>>>
>>>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>>>> ---
>>>>    drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
>>>>    1 file changed, 163 insertions(+), 61 deletions(-)
>>>>
>>>> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
>>>> index 7570958d010c..1004fd0b0c9e 100644
>>>> --- a/drivers/tty/serial/meson_uart.c
>>>> +++ b/drivers/tty/serial/meson_uart.c
>>>> @@ -6,6 +6,7 @@
>>>>     */
>>>>      #include <linux/clk.h>
>>>> +#include <linux/clk-provider.h>
>>>>    #include <linux/console.h>
>>>>    #include <linux/delay.h>
>>>>    #include <linux/init.h>
>>>> @@ -65,9 +66,7 @@
>>>>    #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>>>>      /* AML_UART_REG5 bits */
>>>> -#define AML_UART_BAUD_MASK		0x7fffff
>>>>    #define AML_UART_BAUD_USE		BIT(23)
>>>> -#define AML_UART_BAUD_XTAL		BIT(24)
>>>>      #define AML_UART_PORT_NUM		12
>>>>    #define AML_UART_PORT_OFFSET		6
>>>> @@ -76,6 +75,13 @@
>>>>    #define AML_UART_POLL_USEC		5
>>>>    #define AML_UART_TIMEOUT_USEC		10000
>>>>    +struct meson_uart_data {
>>>> +	struct uart_port	port;
>>>> +	struct clk		*pclk;
>>>> +	struct clk		*baud_clk;
>>>> +	bool			use_xtal_clk;
>>>> +};
>>>> +
>>>>    static struct uart_driver meson_uart_driver;
>>>>      static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>>>> @@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
>>>>    static int meson_uart_startup(struct uart_port *port)
>>>>    {
>>>>    	u32 val;
>>>> -	int ret = 0;
>>>> +	int ret;
>>>>    -	val = readl(port->membase + AML_UART_CONTROL);
>>>> -	val |= AML_UART_CLEAR_ERR;
>>>> -	writel(val, port->membase + AML_UART_CONTROL);
>>>> -	val &= ~AML_UART_CLEAR_ERR;
>>>> -	writel(val, port->membase + AML_UART_CONTROL);
>>>> +	meson_uart_reset(port);
>>>>    +	val = readl(port->membase + AML_UART_CONTROL);
>>>>    	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>>>>    	writel(val, port->membase + AML_UART_CONTROL);
>>>>    @@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port
>>>> *port)
>>>>      static void meson_uart_change_speed(struct uart_port *port, unsigned
>>>> long baud)
>>>>    {
>>>> +	struct meson_uart_data *private_data = port->private_data;
>>>>    	u32 val;
>>>>      	while (!meson_uart_tx_empty(port))
>>>>    		cpu_relax();
>>>>    -	if (port->uartclk == 24000000) {
>>>> -		val = ((port->uartclk / 3) / baud) - 1;
>>>> -		val |= AML_UART_BAUD_XTAL;
>>>> -	} else {
>>>> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>>>> -	}
>>>> +	val = readl(port->membase + AML_UART_REG5);
>>>>    	val |= AML_UART_BAUD_USE;
>>>>    	writel(val, port->membase + AML_UART_REG5);
>>>> +
>>>> +	clk_set_rate(private_data->baud_clk, baud);
>>>>    }
>>>>      static void meson_uart_set_termios(struct uart_port *port,
>>>> @@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>>>>      static void meson_uart_release_port(struct uart_port *port)
>>>>    {
>>>> -	/* nothing to do */
>>>> +	struct meson_uart_data *private_data = port->private_data;
>>>> +
>>>> +	clk_disable_unprepare(private_data->baud_clk);
>>>> +	clk_disable_unprepare(private_data->pclk);
>>>>    }
>>>>      static int meson_uart_request_port(struct uart_port *port)
>>>>    {
>>>> +	struct meson_uart_data *private_data = port->private_data;
>>>> +	int ret;
>>>> +
>>>> +	ret = clk_prepare_enable(private_data->pclk);
>>>> +	if (ret)
>>>> +		return ret;
>>> In the previous version of the series, you already been asked to the
>>> enable of pclk in the probe. Optimization should not be mixed with this
>>> series
>>> Please make sure all comments are addressed before re-posting
>>>
>> I'm sorry. I misunderstood you earlier. I'm going to move into the probe
>> function.
>>>> +
>>>> +	ret = clk_prepare_enable(private_data->baud_clk);
>>>> +	if (ret) {
>>>> +		clk_disable_unprepare(private_data->pclk);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>>    	return 0;
>>>>    }
>>>>    @@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
>>>>    	.cons		= MESON_SERIAL_CONSOLE,
>>>>    };
>>>>    -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>>>> -						 const char *id)
>>>> +#define CLK_NAME(name) \
>>>> +({\
>>>> +	char clk_name[32];\
>>>> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
>>>> +	clk_name;\
>>>> +})
>>> 1) This result in some ugly code being inlined
>>> 2) You return a pointer a local variable which is not gurantee to exist
>>> anymore  outside of this ...
>>> Please do this simply in the related function.
>> I've overdone it. I'll move it to the meson_uart_probe_clocks function as
>> you suggested.
>>>
>>>> +
>>>> +static struct clk_div_table xtal_div_table[] = {
>>>> +	{ 0, 3  },
>>>> +	{ 1, 1  },
>>>> +	{ 2, 2  },
>>>> +	{ 3, 2  },
>>>> +};
>>>> +
>>>> +static int meson_uart_probe_clocks(struct uart_port *port)
>>>>    {
>>>> -	struct clk *clk = NULL;
>>>> -	int ret;
>>>> +	struct meson_uart_data *private_data = port->private_data;
>>>> +	struct clk *clk_baud, *clk_xtal;
>>>> +	struct clk_hw *hw;
>>>> +	struct clk_parent_data use_xtal_mux_parents[2] = {
>>>> +		{ .index = -1, },
>>>> +		{ .index = -1, },
>>>> +	};
>>>>    -	clk = devm_clk_get(dev, id);
>>>> -	if (IS_ERR(clk))
>>>> -		return clk;
>>>> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
>>>> +	if (IS_ERR(private_data->pclk))
>>>> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
>>>> +				     "Failed to get the 'pclk' clock\n");
>>>>    -	ret = clk_prepare_enable(clk);
>>>> -	if (ret) {
>>>> -		dev_err(dev, "couldn't enable clk\n");
>>>> -		return ERR_PTR(ret);
>>>> +	clk_baud = devm_clk_get(port->dev, "baud");
>>>> +	if (IS_ERR(clk_baud)) {
>>>> +		dev_err(port->dev, "Failed to get the 'baud' clock\n");
>>>> +		return PTR_ERR(clk_baud);
>>>>    	}
>>>>    -	devm_add_action_or_reset(dev,
>>>> -			(void(*)(void *))clk_disable_unprepare,
>>>> -			clk);
>>>> -
>>>> -	return clk;
>>>> -}
>>>> -
>>>> -static int meson_uart_probe_clocks(struct platform_device *pdev,
>>>> -				   struct uart_port *port)
>>>> -{
>>>> -	struct clk *clk_xtal = NULL;
>>>> -	struct clk *clk_pclk = NULL;
>>>> -	struct clk *clk_baud = NULL;
>>>> -
>>>> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>>>> -	if (IS_ERR(clk_pclk))
>>>> -		return PTR_ERR(clk_pclk);
>>>> -
>>>> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>>>> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>>>>    	if (IS_ERR(clk_xtal))
>>>> -		return PTR_ERR(clk_xtal);
>>>> -
>>>> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>>>> -	if (IS_ERR(clk_baud))
>>>> -		return PTR_ERR(clk_baud);
>>>> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>>>> +				     "Failed to get the 'xtal' clock\n");
>>>> +
>>>> +	if (private_data->use_xtal_clk) {
>>>> +		hw = devm_clk_hw_register_divider_table(port->dev,
>>>> +							CLK_NAME(xtal_div),
>>>> +							__clk_get_name(clk_baud),
>>>> +							CLK_SET_RATE_NO_REPARENT,
>>>> +							port->membase + AML_UART_REG5,
>>>> +							26, 2,
>>>> +							CLK_DIVIDER_READ_ONLY,
>>>> +							xtal_div_table, NULL);
>>>> +		if (IS_ERR(hw))
>>>> +			return PTR_ERR(hw);
>>>> +
>>>> +		use_xtal_mux_parents[1].hw = hw;
>>>> +	} else {
>>>> +		hw = devm_clk_hw_register_fixed_factor(port->dev,
>>>> +						       CLK_NAME(clk81_div4),
>>>> +						       __clk_get_name(clk_baud),
>>>> +						       CLK_SET_RATE_NO_REPARENT,
>>>> +						       1, 4);
>>>> +		if (IS_ERR(hw))
>>>> +			return PTR_ERR(hw);
>>>> +
>>>> +		use_xtal_mux_parents[0].hw = hw;
>>>> +	}
>>> Contradiction with previous series.
>>> In the previous series we could clearly see that gxbb did not have the
>>> /4 divider. It did not have bits 26 and 27 either.
>>> Now gxbb get the /4 divider. It operated correctly without it so far, so
>>> this is rather suspicious. Could you please comment on this ?
>>>
>> As Martin and I discussed earlier.
>> meson6 and meson8b SoC.There are not have bits 26 and 27 either.
>> CLK81 is recommended for this part of SOC.
>>
>> GXL,GXM,GXBB and AXG SOC.The UART_EE_A_REG5[26] is added.
>> UART_EE_A_REG5[26]:
>> - 0x0: divide the input clock by 3 (meaning: this internally works
>> with an 8MHz clock)
>> - 0x1: use the input clock directly without further division (meaning:
>> this internally work with an 24MHz clock)
>> 8MHz is recommended for this part of SOC. Their UART IP configuration is
>> the same.
>>
>> G12A/B,,SM1,A1 and S4 SOC.The UART_EE_A_REG5[27] is added.
>> UART_EE_A_REG5[27]:
>> - 0x0: use the clock as configured in UART_EE_A_REG5[26]
>> - 0x1: divide the input clock by 2 (meaning: this internally works
>> with an 12MHz clock)
>> 12MHz is recommended for this part of SOC.
>>
>> NOTE:
>> 1. clk81 /4 divider.
>> There is a 4 divider inside, this is what the internal SOC designer told
>> me. But they forgot to document it. So it makes people feel suspicious.
>>
>> 2.The UART_EE_A_REG5 default value is 0,except for the console port(set in
>> romcode).All the baud rate clocks supported by UART can work, but different
>> chip usage scenarios suggest using that clock to reduce jitter.
>>
>> In summary, I would like to know your suggestions, including how to change
>> compatible.
>> Thank you so much!
> 
>  From your comment, gxbb should have "true" instead of false, isn't it ?
> 
Yes, You are right.
I don't see the need to split "amlogic, meson-gx-uart" compatible right 
now. I think the following change
{
.compatible = "amlogic,meson-gx-uart",
.data = (void *)true,
},
can satisfy all UART IP using XTAL. Because CCF automatically selects an 
appropriate clock source when setting baud rate.

I wonder if you agree with that. Or maybe you have a better idea. I'd 
like to know your opinion
>>
>>   >>
>>>> -	port->uartclk = clk_get_rate(clk_baud);
>>>> +	hw = __devm_clk_hw_register_mux(port->dev, NULL,
>>>> +					CLK_NAME(use_xtal),
>>>> +					ARRAY_SIZE(use_xtal_mux_parents),
>>>> +					NULL, NULL,
>>>> +					use_xtal_mux_parents,
>>>> +					CLK_SET_RATE_PARENT,
>>>> +					port->membase + AML_UART_REG5,
>>>> +					24, 0x1,
>>>> +					CLK_MUX_READ_ONLY,
>>>> +					NULL, NULL);
>>>> +	if (IS_ERR(hw))
>>>> +		return PTR_ERR(hw);
>>>> +
>>>> +	port->uartclk = clk_hw_get_rate(hw);
>>>> +
>>>> +	hw = devm_clk_hw_register_divider(port->dev,
>>>> +					  CLK_NAME(baud_div),
>>>> +					  clk_hw_get_name(hw),
>>>> +					  CLK_SET_RATE_PARENT,
>>>> +					  port->membase + AML_UART_REG5,
>>>> +					  0, 23,
>>>> +					  CLK_DIVIDER_ROUND_CLOSEST,
>>>> +					  NULL);
>>>> +	if (IS_ERR(hw))
>>>> +		return PTR_ERR(hw);
>>>> +
>>>> +	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
>>> I have already commented on the use of this function in the previous
>>> version.
>>> Please make sure all comments are addressed before re-posting
>>>
>> I'm sorry. I misunderstood you earlier. I will be changed to
>> "private_data->baud_clk = hw->clk;".What do you think?
> 
> yes
> 
>>>>      	return 0;
>>>>    }
>>>>      static int meson_uart_probe(struct platform_device *pdev)
>>>>    {
>>>> +	struct meson_uart_data *private_data;
>>>>    	struct resource *res_mem;
>>>>    	struct uart_port *port;
>>>>    	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
>>>> @@ -716,18 +783,20 @@ static int meson_uart_probe(struct platform_device *pdev)
>>>>    		return -EBUSY;
>>>>    	}
>>>>    -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port),
>>>> GFP_KERNEL);
>>>> -	if (!port)
>>>> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
>>>> +				    GFP_KERNEL);
>>>> +	if (!private_data)
>>>>    		return -ENOMEM;
>>>>    +	if (device_get_match_data(&pdev->dev))
>>>> +		private_data->use_xtal_clk = true;
>>>> +
>>>> +	port = &private_data->port;
>>>> +
>>>>    	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>>>>    	if (IS_ERR(port->membase))
>>>>    		return PTR_ERR(port->membase);
>>>>    -	ret = meson_uart_probe_clocks(pdev, port);
>>>> -	if (ret)
>>>> -		return ret;
>>>> -
>>>>    	port->iotype = UPIO_MEM;
>>>>    	port->mapbase = res_mem->start;
>>>>    	port->mapsize = resource_size(res_mem);
>>>> @@ -740,7 +809,11 @@ static int meson_uart_probe(struct platform_device *pdev)
>>>>    	port->x_char = 0;
>>>>    	port->ops = &meson_uart_ops;
>>>>    	port->fifosize = fifosize;
>>>> +	port->private_data = private_data;
>>> port has private_data
>>> private_data has port
>>> Is it really necessary to have both ... looks to me that port in
>>> private_data is overkill
>>>
>> It's very thoughtful of you. I'll delete it as you suggested.
>>>>    +	ret = meson_uart_probe_clocks(port);
>>>> +	if (ret)
>>>> +		return ret;
>>>>    	meson_ports[pdev->id] = port;
>>>>    	platform_set_drvdata(pdev, port);
>>>>    @@ -766,10 +839,39 @@ static int meson_uart_remove(struct
>>>> platform_device *pdev)
>>>>    }
>>>>      static const struct of_device_id meson_uart_dt_match[] = {
>>>> -	{ .compatible = "amlogic,meson6-uart" },
>>>> -	{ .compatible = "amlogic,meson8-uart" },
>>>> -	{ .compatible = "amlogic,meson8b-uart" },
>>>> -	{ .compatible = "amlogic,meson-gx-uart" },
>>>> +	{
>>>> +		.compatible = "amlogic,meson6-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson8-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson8b-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson-gxbb-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson-gxl-uart",
>>>> +		.data = (void *)true,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson-g12a-uart",
>>>> +		.data = (void *)true,
>>>> +	},
>>>> +	/*
>>>> +	 * deprecated, don't use anymore because it doesn't differentiate
>>>> +	 * between GXBB, GXL and G12A which have different revisions
>>>> +	 * of the UART IP.
>>>> +	 */
>>>> +	{
>>>> +		.compatible = "amlogic,meson-gx-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>>    	{ /* sentinel */ },
>>>>    };
>>>>    MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
>>>
>>
>> _______________________________________________
>> linux-amlogic mailing list
>> linux-amlogic at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-amlogic
> 


From narmstrong at baylibre.com  Mon Jan 17 01:47:00 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 10:47:00 +0100
Subject: [PATCH v2 0/3] meson-g12: add pwm and uart pin muxing options
In-Reply-To: <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
Message-ID: <164241280577.1159604.15931539808955359814.b4-ty@baylibre.com>

Hi,

On Wed, 12 Jan 2022 22:16:39 +0100, Gary Bisson wrote:
> This series adds a few pin muxing options needed for our HW platform (to
> be submitted soon).
> 
> 1- pwm_f: adding missing both GPIOZ_12 & GPIOA_11 options
>   -> tested GPIOA_11 as mipi display backlight
>   -> order for this patch is not alphabetical but follows doc order (to
> match current order)
> 2- uart_ao_b: adding both options for ao_b uart + its rts/cts pins
>   -> tested on custom hw too
> 
> [...]

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v5.18/dt64)

[2/3] arm64: dts: meson-g12-common: add more pwm_f options
      https://git.kernel.org/amlogic/c/073983233302641d080b524640cc99be696e802a
[3/3] arm64: dts: meson-g12-common: add uart_ao_b pins muxing
      https://git.kernel.org/amlogic/c/2c420d79dae47f9fa3bb8ccb76eaba864c579721

-- 
Neil


From narmstrong at baylibre.com  Mon Jan 17 01:49:34 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 10:49:34 +0100
Subject: [PATCH 1/2] arm64: dts: meson-axg: add missing reset-names
 property
In-Reply-To: <1jfspnpoxh.fsf@starbuckisacylon.baylibre.com>
References: <20220115093557.30498-1-alexander.stein@mailbox.org>
 <1jilulav4u.fsf@starbuckisacylon.baylibre.com> <4732096.GXAFRqVoOG@kongar>
 <1jfspnpoxh.fsf@starbuckisacylon.baylibre.com>
Message-ID: <0a51873b-429f-5905-5bf2-9406f578223b@baylibre.com>

Hi,

On 16/01/2022 18:30, Jerome Brunet wrote:
> 
> On Sun 16 Jan 2022 at 10:49, Alexander Stein <alexander.stein at mailbox.org> wrote:
> 
>> Am Samstag, 15. Januar 2022, 16:04:10 CET schrieb Jerome Brunet:
>>>
>>> On Sat 15 Jan 2022 at 10:35, Alexander Stein <alexander.stein at mailbox.org> 
>> wrote:
>>>
>>>> Bindings amlogic,axg-fifo.txt mandates that reset-names is a required
>>>> property. Add it.
>>>
>>> Binginds *mandates* ?? the bindings you are adding mandates that, not the
>>> previous doc, nor the driver.
>>
>> Well, under required properties 'reset-names' is listed as well as 'arb' is 
>> required, only 'rst' is optional.
> 
> I think there is a misunderstanding then.
> The arb reset is required, the "reset-names" is not - as long as there
> is single reset.

To be fair, it's not explicit in the .txt bindings at all:

-- reset-names: should contain the following:
-  * "arb" : memory ARB line (required)
-  * "rst" : dedicated device reset line (optional)

Anyway, this should be solved, it's pretty common to have reset-names mandatory even
for a single reset if a second one is optional.

> 
>> So when creating the .yaml accordingly this leads to warnings this patch is 
>> about to fix.
>>
>>> Modifying drivers and DT to accomodate made-up bindings requirement is
>>> disturbing.
>>>
>>> The bindings should not require that because the driver does not, as it
>>> stands. The driver requires the arb reset to be provided, not the name.
>>> Please fix the bindings.
>>
>> Nothing is made up. When creating the .yaml file I took the .txt documentation 
>> for granted. How should I know the bindings documentation is apparently wrong?
>>
>> When using your older bindings conversion [1] I'm fine with dropping this one.
>>
>> Best regards,
>> Alexander
>>
>> [1] https://patchwork.kernel.org/project/linux-amlogic/list/?
>> series=246453&state=%2A&archive=both
> 



From narmstrong at baylibre.com  Mon Jan 17 02:08:38 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 11:08:38 +0100
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <ebaff694-a2d7-7eb8-5850-980e9d4e1e68@baylibre.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
 <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>
 <OS0PR01MB5922BC31FBCF85F99F17737B86549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <ebaff694-a2d7-7eb8-5850-980e9d4e1e68@baylibre.com>
Message-ID: <80fdc5a0-ddb8-5a0f-eb8c-ef7988ced638@baylibre.com>

Hi again,

On 14/01/2022 15:40, Neil Armstrong wrote:
> Hi,
> 
> On 14/01/2022 15:23, Biju Das wrote:
>>
>>
>>> -----Original Message-----
>>> From: Neil Armstrong <narmstrong at baylibre.com>
>>> Sent: 14 January 2022 13:56
>>> To: Biju Das <biju.das.jz at bp.renesas.com>; Fabio Estevam
>>> <festevam at gmail.com>
>>> Cc: daniel at ffwll.ch; Laurent.pinchart at ideasonboard.com;
>>> robert.foss at linaro.org; jonas at kwiboo.se; jernej.skrabec at gmail.com;
>>> martin.blumenstingl at googlemail.com; linux-amlogic at lists.infradead.org;
>>> linux-arm-kernel at lists.infradead.org; dri-devel at lists.freedesktop.org;
>>> linux-kernel at vger.kernel.org; linux-renesas-soc at vger.kernel.org
>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>> callbacks")
>>>
>>> Hi,
>>>
>>> On 14/01/2022 12:08, Biju Das wrote:
>>>> Hi Neil,
>>>>
>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>>> callbacks")
>>>>>
>>>>> On 14/01/2022 09:29, Biju Das wrote:
>>>>>> Hi Neil,
>>>>>>
>>>>>> + renesas-soc
>>>>>>
>>>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>>>>> callbacks")
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> On 13/01/2022 21:01, Fabio Estevam wrote:
>>>>>>>> Hi Biju,
>>>>>>>>
>>>>>>>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das
>>>>>>>> <biju.das.jz at bp.renesas.com>
>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>> Hi All,
>>>>>>>>>
>>>>>>>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour)
>>>>>>>>> till the commit
>>>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
>>>>>>>>> fmts
>>>>>>> callbacks").
>>>>>>>>>
>>>>>>>>> After this patch, the screen becomes greenish(may be it is
>>>>>>>>> setting it
>>>>>>> into YUV format??).
>>>>>>>>>
>>>>>>>>> By checking the code, previously it used to call get_input_fmt
>>>>>>>>> callback
>>>>>>> and set colour as RGB24.
>>>>>>>>>
>>>>>>>>> After this commit, it calls get_output_fmt_callbck and returns 3
>>>>>>>>> outputformats(YUV16, YUV24 and RGB24) And get_input_fmt callback,
>>>>>>>>> I see
>>>>>>> the outputformat as YUV16 instead of RGB24.
>>>>>>>>>
>>>>>>>>> Not sure, I am the only one seeing this issue with dw_HDMI driver.
>>>>>>>
>>>>>>> This patch was introduced to maintain the bridge color format
>>>>>>> negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it
>>>>>>> seems it behaves incorrectly if the first bridge doesn't implement
>>>>>>> the negotiation callbacks.
>>>>>>>
>>>>>>> Let me check the code to see how to fix that.
>>>>>>
>>>>>> Thanks for the information, I am happy to test the patch/fix.
>>>>>>
>>>>>> Cheers,
>>>>>> Biju
>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> I have tested linux-next 20220112 on a imx6q-sabresd board, which
>>>>> shows:
>>>>>>>>
>>>>>>>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with
>>>>>>>> HDCP (DWC HDMI 3D TX PHY)
>>>>>>>>
>>>>>>>> The colors are shown correctly here.
>>>>>>>>
>>>>>>>
>>>>>>> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the
>>>>>>> negotiation fails and use the RGB fallback input & output format.
>>>>>>>
>>>>>>> Anyway thanks for testing
>>>>>>>
>>>>>>> Neil
>>>>>
>>>>> Can you test :
>>>>>
>>>>> ==><===============================
>>>>> diff --git a/drivers/gpu/drm/drm_bridge.c
>>>>> b/drivers/gpu/drm/drm_bridge.c index c96847fc0ebc..7019acd37716
>>>>> 100644
>>>>> --- a/drivers/gpu/drm/drm_bridge.c
>>>>> +++ b/drivers/gpu/drm/drm_bridge.c
>>>>> @@ -955,7 +955,14 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
>>>>> drm_bridge *bridge,
>>>>>         last_bridge_state =
>>>>> drm_atomic_get_new_bridge_state(crtc_state-
>>>>>> state,
>>>>>
>>>>> last_bridge);
>>>>>
>>>>> -       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
>>>>> +       /*
>>>>> +        * Only negociate with real values if both end of the bridge
>>> chain
>>>>> +        * support negociation callbacks, otherwise you can end in a
>>>>> situation
>>>>> +        * where the selected output format doesn't match with the
>>>>> + first
>>>>> bridge
>>>>> +        * output format.
>>>>> +        */
>>>>> +       if (bridge->funcs->atomic_get_input_bus_fmts &&
>>>>> +           last_bridge->funcs->atomic_get_output_bus_fmts) {
>>>>>                 const struct drm_bridge_funcs *funcs =
>>>>> last_bridge->funcs;
>>>>>
>>>>>                 /*
>>>>> @@ -980,7 +987,12 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
>>>>> drm_bridge *bridge,
>>>>>                 if (!out_bus_fmts)
>>>>>                         return -ENOMEM;
>>>>>
>>>>> -               if (conn->display_info.num_bus_formats &&
>>>>> +               /*
>>>>> +                * If first bridge doesn't support negociation, use
>>>>> MEDIA_BUS_FMT_FIXED
>>>>> +                * as a safe value for the whole bridge chain
>>>>> +                */
>>>>> +               if (bridge->funcs->atomic_get_input_bus_fmts &&
>>>>> +                   conn->display_info.num_bus_formats &&
>>>>>                     conn->display_info.bus_formats)
>>>>>                         out_bus_fmts[0] = conn-
>>>>>> display_info.bus_formats[0];
>>>>>                 else
>>>>> ==><===============================
>>>>>
>>>>> This should exclude your situation where the first bridge doesn't
>>>>> support negociation.
>>>>
>>>> I have tested this fix with Linux next-20220114. Still I see colour
>>> issue.
>>>>
>>>> It is still negotiating and it is calling get_output_fmt_callbck
>>>>
>>>> [    3.460155] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>> MEDIA_BUS_FMT_UYVY8_1X16=0#########
>>>> [    3.460180] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>> MEDIA_BUS_FMT_YUV8_1X24=1#########
>>>> [    3.460202] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>> MEDIA_BUS_FMT_RGB888_1X24=2#########
>>>>
>>>> And In get_input_fmt callback, I See the outputformat as YUV16 instead
>>> of RGB24.
>>>>
>>>> [    3.460319] ########dw_hdmi_bridge_atomic_get_input_bus_fmts
>>> MEDIA_BUS_FMT_UYVY8_1X16#########
>>>> [    3.473644] ########hdmi_video_sample
>>> MEDIA_BUS_FMT_UYVY8_1X16#########
>>>
>>> OK, looking at rcar-du, the dw-hdmi bridge is directly connected to the
>>> encoder.
>>
>> Yep.
>>
>>>
>>> Let me figure that out, no sure I can find a clean solution except putting
>>> back RGB24 before YUV.
>>>
>>> Anyway please test that:
>>
>> It works now after reordering.
>>
>> [    3.493302] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_RGB888_1X24=0#########
>> [    3.493326] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_YUV8_1X24=1#########
>> [    3.493348] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_UYVY8_1X16=2#########
>>
>> [    3.493463] ########dw_hdmi_bridge_atomic_get_input_bus_fmts MEDIA_BUS_FMT_RGB888_1X24#########
>> [    3.506797] ########hdmi_video_sample MEDIA_BUS_FMT_RGB888_1X24#########
>>
>> Is it acceptable solution to the users of dw_hdmi driver? May be it is worth to post a patch.
>> at least it is fixing the colour issue??
> 
> Yes, it gets back to default behavior before negociation, nevertheless we need to think
> how to handle your use-case correctly at some point.
> 
> I'll post this as a patch ASAP so it gets applied before landing in linus master.
> 
> Neil
> 
>>
>> Regards,
>> Biju
>>
>>>
[...]

I'm not happy with this version since it's merely a hack which makes it work.

Can you test the following change instead, it's correctly handles your situation in a generic manner.

========================><=============================
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 54d8fdad395f..9f2e1cac0ae2 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2551,8 +2551,9 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
        if (!output_fmts)
                return NULL;

-       /* If dw-hdmi is the only bridge, avoid negociating with ourselves */
-       if (list_is_singular(&bridge->encoder->bridge_chain)) {
+       /* If dw-hdmi is the first or only bridge, avoid negociating with ourselves */
+       if (list_is_singular(&bridge->encoder->bridge_chain) ||
+           list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain)) {
                *num_output_fmts = 1;
                output_fmts[0] = MEDIA_BUS_FMT_FIXED;

@@ -2673,6 +2674,10 @@ static u32 *dw_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
        if (!input_fmts)
                return NULL;

+       /* If dw-hdmi is the first bridge fall-back to safe output format */
+       if (list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain))
+               output_fmt = MEDIA_BUS_FMT_FIXED;
+
        switch (output_fmt) {
        /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */
        case MEDIA_BUS_FMT_FIXED:
========================><=============================

Thanks,
Neil


>>>
>>> Neil
>>>
>>>>
>>>> Regards,
>>>> Biju
>>>>
>>
> 



From jbrunet at baylibre.com  Mon Jan 17 02:08:43 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 17 Jan 2022 11:08:43 +0100
Subject: [PATCH 1/2] arm64: dts: meson-axg: add missing reset-names
 property
In-Reply-To: <0a51873b-429f-5905-5bf2-9406f578223b@baylibre.com>
References: <20220115093557.30498-1-alexander.stein@mailbox.org>
 <1jilulav4u.fsf@starbuckisacylon.baylibre.com> <4732096.GXAFRqVoOG@kongar>
 <1jfspnpoxh.fsf@starbuckisacylon.baylibre.com>
 <0a51873b-429f-5905-5bf2-9406f578223b@baylibre.com>
Message-ID: <1j35lmmzap.fsf@starbuckisacylon.baylibre.com>


On Mon 17 Jan 2022 at 10:49, Neil Armstrong <narmstrong at baylibre.com> wrote:

> Hi,
>
> On 16/01/2022 18:30, Jerome Brunet wrote:
>> 
>> On Sun 16 Jan 2022 at 10:49, Alexander Stein <alexander.stein at mailbox.org> wrote:
>> 
>>> Am Samstag, 15. Januar 2022, 16:04:10 CET schrieb Jerome Brunet:
>>>>
>>>> On Sat 15 Jan 2022 at 10:35, Alexander Stein <alexander.stein at mailbox.org> 
>>> wrote:
>>>>
>>>>> Bindings amlogic,axg-fifo.txt mandates that reset-names is a required
>>>>> property. Add it.
>>>>
>>>> Binginds *mandates* ?? the bindings you are adding mandates that, not the
>>>> previous doc, nor the driver.
>>>
>>> Well, under required properties 'reset-names' is listed as well as 'arb' is 
>>> required, only 'rst' is optional.
>> 
>> I think there is a misunderstanding then.
>> The arb reset is required, the "reset-names" is not - as long as there
>> is single reset.
>
> To be fair, it's not explicit in the .txt bindings at all:
>
- resets: list of reset phandle, one for each entry reset-names.
> -- reset-names: should contain the following:
> -  * "arb" : memory ARB line (required)
> -  * "rst" : dedicated device reset line (optional)

That was fairly usual way to describe clocks and reset with txt files
but I agree it could have been interpreted the other way around

>
> Anyway, this should be solved, it's pretty common to have reset-names mandatory even
> for a single reset if a second one is optional.

Binding should not decribe what's common but how the binding is supposed to be
used. Fact is the usage was defined by the first and only user which is linux
driver.

This driver does not care if the arb name is present or not. Mandating
something which is unused makes no sense.

If we want to be precise, then it just cares it is the first reset is
the arb one (and yes, this constraint is not described either).

The reason for that is simple, there was no 'rst' line on
first version of the IP, and it was 'fairly usual' to not have
'reset-names' when there is a single reset.

If you think the 'arb' name should be made mandatory, that's fine by
me but one should be able to rely on the name so the driver should be
updated to use it.

>
>> 
>>> So when creating the .yaml accordingly this leads to warnings this patch is 
>>> about to fix.
>>>
>>>> Modifying drivers and DT to accomodate made-up bindings requirement is
>>>> disturbing.
>>>>
>>>> The bindings should not require that because the driver does not, as it
>>>> stands. The driver requires the arb reset to be provided, not the name.
>>>> Please fix the bindings.
>>>
>>> Nothing is made up. When creating the .yaml file I took the .txt documentation 
>>> for granted. How should I know the bindings documentation is apparently wrong?
>>>
>>> When using your older bindings conversion [1] I'm fine with dropping this one.
>>>
>>> Best regards,
>>> Alexander
>>>
>>> [1] https://patchwork.kernel.org/project/linux-amlogic/list/?
>>> series=246453&state=%2A&archive=both
>> 



From biju.das.jz at bp.renesas.com  Mon Jan 17 04:13:36 2022
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Mon, 17 Jan 2022 12:13:36 +0000
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <80fdc5a0-ddb8-5a0f-eb8c-ef7988ced638@baylibre.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
 <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>
 <OS0PR01MB5922BC31FBCF85F99F17737B86549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <ebaff694-a2d7-7eb8-5850-980e9d4e1e68@baylibre.com>
 <80fdc5a0-ddb8-5a0f-eb8c-ef7988ced638@baylibre.com>
Message-ID: <OS0PR01MB59224F0F892D6F86DBD5D36286579@OS0PR01MB5922.jpnprd01.prod.outlook.com>

Hi Neil,
> Subject: Re: dw_hdmi is showing wrong colour after commit
> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> callbacks")
> 
> Hi again,
> 
> On 14/01/2022 15:40, Neil Armstrong wrote:
> > Hi,
> >
> > On 14/01/2022 15:23, Biju Das wrote:
> >>
> >>
> >>> -----Original Message-----
> >>> From: Neil Armstrong <narmstrong at baylibre.com>
> >>> Sent: 14 January 2022 13:56
> >>> To: Biju Das <biju.das.jz at bp.renesas.com>; Fabio Estevam
> >>> <festevam at gmail.com>
> >>> Cc: daniel at ffwll.ch; Laurent.pinchart at ideasonboard.com;
> >>> robert.foss at linaro.org; jonas at kwiboo.se; jernej.skrabec at gmail.com;
> >>> martin.blumenstingl at googlemail.com;
> >>> linux-amlogic at lists.infradead.org;
> >>> linux-arm-kernel at lists.infradead.org;
> >>> dri-devel at lists.freedesktop.org; linux-kernel at vger.kernel.org;
> >>> linux-renesas-soc at vger.kernel.org
> >>> Subject: Re: dw_hdmi is showing wrong colour after commit
> >>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> >>> callbacks")
> >>>
> >>> Hi,
> >>>
> >>> On 14/01/2022 12:08, Biju Das wrote:
> >>>> Hi Neil,
> >>>>
> >>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
> >>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
> >>>>> fmts
> >>>>> callbacks")
> >>>>>
> >>>>> On 14/01/2022 09:29, Biju Das wrote:
> >>>>>> Hi Neil,
> >>>>>>
> >>>>>> + renesas-soc
> >>>>>>
> >>>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
> >>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
> >>>>>>> fmts
> >>>>>>> callbacks")
> >>>>>>>
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>> On 13/01/2022 21:01, Fabio Estevam wrote:
> >>>>>>>> Hi Biju,
> >>>>>>>>
> >>>>>>>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das
> >>>>>>>> <biju.das.jz at bp.renesas.com>
> >>>>>>> wrote:
> >>>>>>>>>
> >>>>>>>>> Hi All,
> >>>>>>>>>
> >>>>>>>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working
> >>>>>>>>> ok(colour) till the commit
> >>>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
> >>>>>>>>> fmts
> >>>>>>> callbacks").
> >>>>>>>>>
> >>>>>>>>> After this patch, the screen becomes greenish(may be it is
> >>>>>>>>> setting it
> >>>>>>> into YUV format??).
> >>>>>>>>>
> >>>>>>>>> By checking the code, previously it used to call get_input_fmt
> >>>>>>>>> callback
> >>>>>>> and set colour as RGB24.
> >>>>>>>>>
> >>>>>>>>> After this commit, it calls get_output_fmt_callbck and returns
> >>>>>>>>> 3 outputformats(YUV16, YUV24 and RGB24) And get_input_fmt
> >>>>>>>>> callback, I see
> >>>>>>> the outputformat as YUV16 instead of RGB24.
> >>>>>>>>>
> >>>>>>>>> Not sure, I am the only one seeing this issue with dw_HDMI
> driver.
> >>>>>>>
> >>>>>>> This patch was introduced to maintain the bridge color format
> >>>>>>> negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it
> >>>>>>> seems it behaves incorrectly if the first bridge doesn't
> >>>>>>> implement the negotiation callbacks.
> >>>>>>>
> >>>>>>> Let me check the code to see how to fix that.
> >>>>>>
> >>>>>> Thanks for the information, I am happy to test the patch/fix.
> >>>>>>
> >>>>>> Cheers,
> >>>>>> Biju
> >>>>>>
> >>>>>>>
> >>>>>>>>
> >>>>>>>> I have tested linux-next 20220112 on a imx6q-sabresd board,
> >>>>>>>> which
> >>>>> shows:
> >>>>>>>>
> >>>>>>>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with
> >>>>>>>> HDCP (DWC HDMI 3D TX PHY)
> >>>>>>>>
> >>>>>>>> The colors are shown correctly here.
> >>>>>>>>
> >>>>>>>
> >>>>>>> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the
> >>>>>>> negotiation fails and use the RGB fallback input & output format.
> >>>>>>>
> >>>>>>> Anyway thanks for testing
> >>>>>>>
> >>>>>>> Neil
> >>>>>
> >>>>> Can you test :
> >>>>>
> >>>>> ==><===============================
> >>>>> diff --git a/drivers/gpu/drm/drm_bridge.c
> >>>>> b/drivers/gpu/drm/drm_bridge.c index c96847fc0ebc..7019acd37716
> >>>>> 100644
> >>>>> --- a/drivers/gpu/drm/drm_bridge.c
> >>>>> +++ b/drivers/gpu/drm/drm_bridge.c
> >>>>> @@ -955,7 +955,14 @@
> >>>>> drm_atomic_bridge_chain_select_bus_fmts(struct
> >>>>> drm_bridge *bridge,
> >>>>>         last_bridge_state =
> >>>>> drm_atomic_get_new_bridge_state(crtc_state-
> >>>>>> state,
> >>>>>
> >>>>> last_bridge);
> >>>>>
> >>>>> -       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
> >>>>> +       /*
> >>>>> +        * Only negociate with real values if both end of the
> >>>>> + bridge
> >>> chain
> >>>>> +        * support negociation callbacks, otherwise you can end in
> >>>>> + a
> >>>>> situation
> >>>>> +        * where the selected output format doesn't match with the
> >>>>> + first
> >>>>> bridge
> >>>>> +        * output format.
> >>>>> +        */
> >>>>> +       if (bridge->funcs->atomic_get_input_bus_fmts &&
> >>>>> +           last_bridge->funcs->atomic_get_output_bus_fmts) {
> >>>>>                 const struct drm_bridge_funcs *funcs =
> >>>>> last_bridge->funcs;
> >>>>>
> >>>>>                 /*
> >>>>> @@ -980,7 +987,12 @@
> >>>>> drm_atomic_bridge_chain_select_bus_fmts(struct
> >>>>> drm_bridge *bridge,
> >>>>>                 if (!out_bus_fmts)
> >>>>>                         return -ENOMEM;
> >>>>>
> >>>>> -               if (conn->display_info.num_bus_formats &&
> >>>>> +               /*
> >>>>> +                * If first bridge doesn't support negociation,
> >>>>> + use
> >>>>> MEDIA_BUS_FMT_FIXED
> >>>>> +                * as a safe value for the whole bridge chain
> >>>>> +                */
> >>>>> +               if (bridge->funcs->atomic_get_input_bus_fmts &&
> >>>>> +                   conn->display_info.num_bus_formats &&
> >>>>>                     conn->display_info.bus_formats)
> >>>>>                         out_bus_fmts[0] = conn-
> >>>>>> display_info.bus_formats[0];
> >>>>>                 else
> >>>>> ==><===============================
> >>>>>
> >>>>> This should exclude your situation where the first bridge doesn't
> >>>>> support negociation.
> >>>>
> >>>> I have tested this fix with Linux next-20220114. Still I see colour
> >>> issue.
> >>>>
> >>>> It is still negotiating and it is calling get_output_fmt_callbck
> >>>>
> >>>> [    3.460155] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> >>> MEDIA_BUS_FMT_UYVY8_1X16=0#########
> >>>> [    3.460180] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> >>> MEDIA_BUS_FMT_YUV8_1X24=1#########
> >>>> [    3.460202] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> >>> MEDIA_BUS_FMT_RGB888_1X24=2#########
> >>>>
> >>>> And In get_input_fmt callback, I See the outputformat as YUV16
> >>>> instead
> >>> of RGB24.
> >>>>
> >>>> [    3.460319] ########dw_hdmi_bridge_atomic_get_input_bus_fmts
> >>> MEDIA_BUS_FMT_UYVY8_1X16#########
> >>>> [    3.473644] ########hdmi_video_sample
> >>> MEDIA_BUS_FMT_UYVY8_1X16#########
> >>>
> >>> OK, looking at rcar-du, the dw-hdmi bridge is directly connected to
> >>> the encoder.
> >>
> >> Yep.
> >>
> >>>
> >>> Let me figure that out, no sure I can find a clean solution except
> >>> putting back RGB24 before YUV.
> >>>
> >>> Anyway please test that:
> >>
> >> It works now after reordering.
> >>
> >> [    3.493302] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> MEDIA_BUS_FMT_RGB888_1X24=0#########
> >> [    3.493326] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> MEDIA_BUS_FMT_YUV8_1X24=1#########
> >> [    3.493348] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> MEDIA_BUS_FMT_UYVY8_1X16=2#########
> >>
> >> [    3.493463] ########dw_hdmi_bridge_atomic_get_input_bus_fmts
> MEDIA_BUS_FMT_RGB888_1X24#########
> >> [    3.506797] ########hdmi_video_sample
> MEDIA_BUS_FMT_RGB888_1X24#########
> >>
> >> Is it acceptable solution to the users of dw_hdmi driver? May be it is
> worth to post a patch.
> >> at least it is fixing the colour issue??
> >
> > Yes, it gets back to default behavior before negociation, nevertheless
> > we need to think how to handle your use-case correctly at some point.
> >
> > I'll post this as a patch ASAP so it gets applied before landing in
> linus master.
> >
> > Neil
> >
> >>
> >> Regards,
> >> Biju
> >>
> >>>
> [...]
> 
> I'm not happy with this version since it's merely a hack which makes it
> work.
> 
> Can you test the following change instead, it's correctly handles your
> situation in a generic manner.
> 
> ========================><=============================
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 54d8fdad395f..9f2e1cac0ae2 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2551,8 +2551,9 @@ static u32
> *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
>         if (!output_fmts)
>                 return NULL;
> 
> -       /* If dw-hdmi is the only bridge, avoid negociating with ourselves
> */
> -       if (list_is_singular(&bridge->encoder->bridge_chain)) {
> +       /* If dw-hdmi is the first or only bridge, avoid negociating with
> ourselves */
> +       if (list_is_singular(&bridge->encoder->bridge_chain) ||
> +           list_is_first(&bridge->chain_node,
> + &bridge->encoder->bridge_chain)) {
>                 *num_output_fmts = 1;
>                 output_fmts[0] = MEDIA_BUS_FMT_FIXED;
> 
> @@ -2673,6 +2674,10 @@ static u32
> *dw_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
>         if (!input_fmts)
>                 return NULL;
> 
> +       /* If dw-hdmi is the first bridge fall-back to safe output format
> */
> +       if (list_is_first(&bridge->chain_node, &bridge->encoder-
> >bridge_chain))
> +               output_fmt = MEDIA_BUS_FMT_FIXED;
> +
>         switch (output_fmt) {
>         /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */
>         case MEDIA_BUS_FMT_FIXED:
> ========================><=============================

This patch alone fixes the issue. I have tested with Linux-next.
Do we need below code, as it is already taken care in output_bus_fmt callback.

> +       if (list_is_first(&bridge->chain_node, &bridge->encoder-
> >bridge_chain))
> +               output_fmt = MEDIA_BUS_FMT_FIXED;

Cheers,
Biju

From narmstrong at baylibre.com  Mon Jan 17 05:52:34 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 14:52:34 +0100
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <OS0PR01MB59224F0F892D6F86DBD5D36286579@OS0PR01MB5922.jpnprd01.prod.outlook.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
 <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>
 <OS0PR01MB5922BC31FBCF85F99F17737B86549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <ebaff694-a2d7-7eb8-5850-980e9d4e1e68@baylibre.com>
 <80fdc5a0-ddb8-5a0f-eb8c-ef7988ced638@baylibre.com>
 <OS0PR01MB59224F0F892D6F86DBD5D36286579@OS0PR01MB5922.jpnprd01.prod.outlook.com>
Message-ID: <b52ae1a2-b211-2bca-8d62-482a840787ec@baylibre.com>

On 17/01/2022 13:13, Biju Das wrote:
> Hi Neil,
>> Subject: Re: dw_hdmi is showing wrong colour after commit
>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>> callbacks")
>>
>> Hi again,
>>
>> On 14/01/2022 15:40, Neil Armstrong wrote:
>>> Hi,
>>>
>>> On 14/01/2022 15:23, Biju Das wrote:
>>>>
>>>>
>>>>> -----Original Message-----
>>>>> From: Neil Armstrong <narmstrong at baylibre.com>
>>>>> Sent: 14 January 2022 13:56
>>>>> To: Biju Das <biju.das.jz at bp.renesas.com>; Fabio Estevam
>>>>> <festevam at gmail.com>
>>>>> Cc: daniel at ffwll.ch; Laurent.pinchart at ideasonboard.com;
>>>>> robert.foss at linaro.org; jonas at kwiboo.se; jernej.skrabec at gmail.com;
>>>>> martin.blumenstingl at googlemail.com;
>>>>> linux-amlogic at lists.infradead.org;
>>>>> linux-arm-kernel at lists.infradead.org;
>>>>> dri-devel at lists.freedesktop.org; linux-kernel at vger.kernel.org;
>>>>> linux-renesas-soc at vger.kernel.org
>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>>> callbacks")
>>>>>
>>>>> Hi,
>>>>>
>>>>> On 14/01/2022 12:08, Biju Das wrote:
>>>>>> Hi Neil,
>>>>>>
>>>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
>>>>>>> fmts
>>>>>>> callbacks")
>>>>>>>
>>>>>>> On 14/01/2022 09:29, Biju Das wrote:
>>>>>>>> Hi Neil,
>>>>>>>>
>>>>>>>> + renesas-soc
>>>>>>>>
>>>>>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
>>>>>>>>> fmts
>>>>>>>>> callbacks")
>>>>>>>>>
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> On 13/01/2022 21:01, Fabio Estevam wrote:
>>>>>>>>>> Hi Biju,
>>>>>>>>>>
>>>>>>>>>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das
>>>>>>>>>> <biju.das.jz at bp.renesas.com>
>>>>>>>>> wrote:
>>>>>>>>>>>
>>>>>>>>>>> Hi All,
>>>>>>>>>>>
>>>>>>>>>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working
>>>>>>>>>>> ok(colour) till the commit
>>>>>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
>>>>>>>>>>> fmts
>>>>>>>>> callbacks").
>>>>>>>>>>>
>>>>>>>>>>> After this patch, the screen becomes greenish(may be it is
>>>>>>>>>>> setting it
>>>>>>>>> into YUV format??).
>>>>>>>>>>>
>>>>>>>>>>> By checking the code, previously it used to call get_input_fmt
>>>>>>>>>>> callback
>>>>>>>>> and set colour as RGB24.
>>>>>>>>>>>
>>>>>>>>>>> After this commit, it calls get_output_fmt_callbck and returns
>>>>>>>>>>> 3 outputformats(YUV16, YUV24 and RGB24) And get_input_fmt
>>>>>>>>>>> callback, I see
>>>>>>>>> the outputformat as YUV16 instead of RGB24.
>>>>>>>>>>>
>>>>>>>>>>> Not sure, I am the only one seeing this issue with dw_HDMI
>> driver.
>>>>>>>>>
>>>>>>>>> This patch was introduced to maintain the bridge color format
>>>>>>>>> negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it
>>>>>>>>> seems it behaves incorrectly if the first bridge doesn't
>>>>>>>>> implement the negotiation callbacks.
>>>>>>>>>
>>>>>>>>> Let me check the code to see how to fix that.
>>>>>>>>
>>>>>>>> Thanks for the information, I am happy to test the patch/fix.
>>>>>>>>
>>>>>>>> Cheers,
>>>>>>>> Biju
>>>>>>>>
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> I have tested linux-next 20220112 on a imx6q-sabresd board,
>>>>>>>>>> which
>>>>>>> shows:
>>>>>>>>>>
>>>>>>>>>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with
>>>>>>>>>> HDCP (DWC HDMI 3D TX PHY)
>>>>>>>>>>
>>>>>>>>>> The colors are shown correctly here.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the
>>>>>>>>> negotiation fails and use the RGB fallback input & output format.
>>>>>>>>>
>>>>>>>>> Anyway thanks for testing
>>>>>>>>>
>>>>>>>>> Neil
>>>>>>>
>>>>>>> Can you test :
>>>>>>>
>>>>>>> ==><===============================
>>>>>>> diff --git a/drivers/gpu/drm/drm_bridge.c
>>>>>>> b/drivers/gpu/drm/drm_bridge.c index c96847fc0ebc..7019acd37716
>>>>>>> 100644
>>>>>>> --- a/drivers/gpu/drm/drm_bridge.c
>>>>>>> +++ b/drivers/gpu/drm/drm_bridge.c
>>>>>>> @@ -955,7 +955,14 @@
>>>>>>> drm_atomic_bridge_chain_select_bus_fmts(struct
>>>>>>> drm_bridge *bridge,
>>>>>>>         last_bridge_state =
>>>>>>> drm_atomic_get_new_bridge_state(crtc_state-
>>>>>>>> state,
>>>>>>>
>>>>>>> last_bridge);
>>>>>>>
>>>>>>> -       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
>>>>>>> +       /*
>>>>>>> +        * Only negociate with real values if both end of the
>>>>>>> + bridge
>>>>> chain
>>>>>>> +        * support negociation callbacks, otherwise you can end in
>>>>>>> + a
>>>>>>> situation
>>>>>>> +        * where the selected output format doesn't match with the
>>>>>>> + first
>>>>>>> bridge
>>>>>>> +        * output format.
>>>>>>> +        */
>>>>>>> +       if (bridge->funcs->atomic_get_input_bus_fmts &&
>>>>>>> +           last_bridge->funcs->atomic_get_output_bus_fmts) {
>>>>>>>                 const struct drm_bridge_funcs *funcs =
>>>>>>> last_bridge->funcs;
>>>>>>>
>>>>>>>                 /*
>>>>>>> @@ -980,7 +987,12 @@
>>>>>>> drm_atomic_bridge_chain_select_bus_fmts(struct
>>>>>>> drm_bridge *bridge,
>>>>>>>                 if (!out_bus_fmts)
>>>>>>>                         return -ENOMEM;
>>>>>>>
>>>>>>> -               if (conn->display_info.num_bus_formats &&
>>>>>>> +               /*
>>>>>>> +                * If first bridge doesn't support negociation,
>>>>>>> + use
>>>>>>> MEDIA_BUS_FMT_FIXED
>>>>>>> +                * as a safe value for the whole bridge chain
>>>>>>> +                */
>>>>>>> +               if (bridge->funcs->atomic_get_input_bus_fmts &&
>>>>>>> +                   conn->display_info.num_bus_formats &&
>>>>>>>                     conn->display_info.bus_formats)
>>>>>>>                         out_bus_fmts[0] = conn-
>>>>>>>> display_info.bus_formats[0];
>>>>>>>                 else
>>>>>>> ==><===============================
>>>>>>>
>>>>>>> This should exclude your situation where the first bridge doesn't
>>>>>>> support negociation.
>>>>>>
>>>>>> I have tested this fix with Linux next-20220114. Still I see colour
>>>>> issue.
>>>>>>
>>>>>> It is still negotiating and it is calling get_output_fmt_callbck
>>>>>>
>>>>>> [    3.460155] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>>>> MEDIA_BUS_FMT_UYVY8_1X16=0#########
>>>>>> [    3.460180] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>>>> MEDIA_BUS_FMT_YUV8_1X24=1#########
>>>>>> [    3.460202] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>>>> MEDIA_BUS_FMT_RGB888_1X24=2#########
>>>>>>
>>>>>> And In get_input_fmt callback, I See the outputformat as YUV16
>>>>>> instead
>>>>> of RGB24.
>>>>>>
>>>>>> [    3.460319] ########dw_hdmi_bridge_atomic_get_input_bus_fmts
>>>>> MEDIA_BUS_FMT_UYVY8_1X16#########
>>>>>> [    3.473644] ########hdmi_video_sample
>>>>> MEDIA_BUS_FMT_UYVY8_1X16#########
>>>>>
>>>>> OK, looking at rcar-du, the dw-hdmi bridge is directly connected to
>>>>> the encoder.
>>>>
>>>> Yep.
>>>>
>>>>>
>>>>> Let me figure that out, no sure I can find a clean solution except
>>>>> putting back RGB24 before YUV.
>>>>>
>>>>> Anyway please test that:
>>>>
>>>> It works now after reordering.
>>>>
>>>> [    3.493302] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>> MEDIA_BUS_FMT_RGB888_1X24=0#########
>>>> [    3.493326] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>> MEDIA_BUS_FMT_YUV8_1X24=1#########
>>>> [    3.493348] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>> MEDIA_BUS_FMT_UYVY8_1X16=2#########
>>>>
>>>> [    3.493463] ########dw_hdmi_bridge_atomic_get_input_bus_fmts
>> MEDIA_BUS_FMT_RGB888_1X24#########
>>>> [    3.506797] ########hdmi_video_sample
>> MEDIA_BUS_FMT_RGB888_1X24#########
>>>>
>>>> Is it acceptable solution to the users of dw_hdmi driver? May be it is
>> worth to post a patch.
>>>> at least it is fixing the colour issue??
>>>
>>> Yes, it gets back to default behavior before negociation, nevertheless
>>> we need to think how to handle your use-case correctly at some point.
>>>
>>> I'll post this as a patch ASAP so it gets applied before landing in
>> linus master.
>>>
>>> Neil
>>>
>>>>
>>>> Regards,
>>>> Biju
>>>>
>>>>>
>> [...]
>>
>> I'm not happy with this version since it's merely a hack which makes it
>> work.
>>
>> Can you test the following change instead, it's correctly handles your
>> situation in a generic manner.
>>
>> ========================><=============================
>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> index 54d8fdad395f..9f2e1cac0ae2 100644
>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> @@ -2551,8 +2551,9 @@ static u32
>> *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
>>         if (!output_fmts)
>>                 return NULL;
>>
>> -       /* If dw-hdmi is the only bridge, avoid negociating with ourselves
>> */
>> -       if (list_is_singular(&bridge->encoder->bridge_chain)) {
>> +       /* If dw-hdmi is the first or only bridge, avoid negociating with
>> ourselves */
>> +       if (list_is_singular(&bridge->encoder->bridge_chain) ||
>> +           list_is_first(&bridge->chain_node,
>> + &bridge->encoder->bridge_chain)) {
>>                 *num_output_fmts = 1;
>>                 output_fmts[0] = MEDIA_BUS_FMT_FIXED;
>>
>> @@ -2673,6 +2674,10 @@ static u32
>> *dw_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
>>         if (!input_fmts)
>>                 return NULL;
>>
>> +       /* If dw-hdmi is the first bridge fall-back to safe output format
>> */
>> +       if (list_is_first(&bridge->chain_node, &bridge->encoder-
>>> bridge_chain))
>> +               output_fmt = MEDIA_BUS_FMT_FIXED;
>> +
>>         switch (output_fmt) {
>>         /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */
>>         case MEDIA_BUS_FMT_FIXED:
>> ========================><=============================
> 
> This patch alone fixes the issue. I have tested with Linux-next.
> Do we need below code, as it is already taken care in output_bus_fmt callback.

You're right in your case the first part is enough.

> 
>> +       if (list_is_first(&bridge->chain_node, &bridge->encoder-
>>> bridge_chain))
>> +               output_fmt = MEDIA_BUS_FMT_FIXED;
> 
> Cheers,
> Biju
> 

Thanks for testing,
Neil


From narmstrong at baylibre.com  Mon Jan 17 05:53:47 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 14:53:47 +0100
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <164241711700.10801.9011781958267060147@Monstersaurus>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
 <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>
 <OS0PR01MB5922BC31FBCF85F99F17737B86549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <ebaff694-a2d7-7eb8-5850-980e9d4e1e68@baylibre.com>
 <80fdc5a0-ddb8-5a0f-eb8c-ef7988ced638@baylibre.com>
 <164241711700.10801.9011781958267060147@Monstersaurus>
Message-ID: <4f214ea2-5f9f-1217-6e65-f92e434ed826@baylibre.com>

On 17/01/2022 11:58, Kieran Bingham wrote:
> Hi Neil,
> 
> Quoting Neil Armstrong (2022-01-17 10:08:38)
>> Hi again,
>>
>> On 14/01/2022 15:40, Neil Armstrong wrote:
>>> Hi,
>>>
>>> On 14/01/2022 15:23, Biju Das wrote:
>>>>
>>>>
>>>>> -----Original Message-----
>>>>> From: Neil Armstrong <narmstrong at baylibre.com>
>>>>> Sent: 14 January 2022 13:56
>>>>> To: Biju Das <biju.das.jz at bp.renesas.com>; Fabio Estevam
>>>>> <festevam at gmail.com>
>>>>> Cc: daniel at ffwll.ch; Laurent.pinchart at ideasonboard.com;
>>>>> robert.foss at linaro.org; jonas at kwiboo.se; jernej.skrabec at gmail.com;
>>>>> martin.blumenstingl at googlemail.com; linux-amlogic at lists.infradead.org;
>>>>> linux-arm-kernel at lists.infradead.org; dri-devel at lists.freedesktop.org;
>>>>> linux-kernel at vger.kernel.org; linux-renesas-soc at vger.kernel.org
>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>>> callbacks")
>>>>>
>>>>> Hi,
>>>>>
>>>>> On 14/01/2022 12:08, Biju Das wrote:
>>>>>> Hi Neil,
>>>>>>
>>>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>>>>> callbacks")
>>>>>>>
>>>>>>> On 14/01/2022 09:29, Biju Das wrote:
>>>>>>>> Hi Neil,
>>>>>>>>
>>>>>>>> + renesas-soc
>>>>>>>>
>>>>>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>>>>>>> callbacks")
>>>>>>>>>
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> On 13/01/2022 21:01, Fabio Estevam wrote:
>>>>>>>>>> Hi Biju,
>>>>>>>>>>
>>>>>>>>>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das
>>>>>>>>>> <biju.das.jz at bp.renesas.com>
>>>>>>>>> wrote:
>>>>>>>>>>>
>>>>>>>>>>> Hi All,
>>>>>>>>>>>
>>>>>>>>>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour)
>>>>>>>>>>> till the commit
>>>>>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
>>>>>>>>>>> fmts
>>>>>>>>> callbacks").
>>>>>>>>>>>
>>>>>>>>>>> After this patch, the screen becomes greenish(may be it is
>>>>>>>>>>> setting it
>>>>>>>>> into YUV format??).
>>>>>>>>>>>
>>>>>>>>>>> By checking the code, previously it used to call get_input_fmt
>>>>>>>>>>> callback
>>>>>>>>> and set colour as RGB24.
>>>>>>>>>>>
>>>>>>>>>>> After this commit, it calls get_output_fmt_callbck and returns 3
>>>>>>>>>>> outputformats(YUV16, YUV24 and RGB24) And get_input_fmt callback,
>>>>>>>>>>> I see
>>>>>>>>> the outputformat as YUV16 instead of RGB24.
>>>>>>>>>>>
>>>>>>>>>>> Not sure, I am the only one seeing this issue with dw_HDMI driver.
>>>>>>>>>
>>>>>>>>> This patch was introduced to maintain the bridge color format
>>>>>>>>> negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it
>>>>>>>>> seems it behaves incorrectly if the first bridge doesn't implement
>>>>>>>>> the negotiation callbacks.
>>>>>>>>>
>>>>>>>>> Let me check the code to see how to fix that.
>>>>>>>>
>>>>>>>> Thanks for the information, I am happy to test the patch/fix.
>>>>>>>>
>>>>>>>> Cheers,
>>>>>>>> Biju
>>>>>>>>
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> I have tested linux-next 20220112 on a imx6q-sabresd board, which
>>>>>>> shows:
>>>>>>>>>>
>>>>>>>>>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with
>>>>>>>>>> HDCP (DWC HDMI 3D TX PHY)
>>>>>>>>>>
>>>>>>>>>> The colors are shown correctly here.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the
>>>>>>>>> negotiation fails and use the RGB fallback input & output format.
>>>>>>>>>
>>>>>>>>> Anyway thanks for testing
>>>>>>>>>
>>>>>>>>> Neil
>>>>>>>
>>>>>>> Can you test :
>>>>>>>
>>>>>>> ==><===============================
>>>>>>> diff --git a/drivers/gpu/drm/drm_bridge.c
>>>>>>> b/drivers/gpu/drm/drm_bridge.c index c96847fc0ebc..7019acd37716
>>>>>>> 100644
>>>>>>> --- a/drivers/gpu/drm/drm_bridge.c
>>>>>>> +++ b/drivers/gpu/drm/drm_bridge.c
>>>>>>> @@ -955,7 +955,14 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
>>>>>>> drm_bridge *bridge,
>>>>>>>         last_bridge_state =
>>>>>>> drm_atomic_get_new_bridge_state(crtc_state-
>>>>>>>> state,
>>>>>>>
>>>>>>> last_bridge);
>>>>>>>
>>>>>>> -       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
>>>>>>> +       /*
>>>>>>> +        * Only negociate with real values if both end of the bridge
>>>>> chain
>>>>>>> +        * support negociation callbacks, otherwise you can end in a
>>>>>>> situation
>>>>>>> +        * where the selected output format doesn't match with the
>>>>>>> + first
>>>>>>> bridge
>>>>>>> +        * output format.
>>>>>>> +        */
>>>>>>> +       if (bridge->funcs->atomic_get_input_bus_fmts &&
>>>>>>> +           last_bridge->funcs->atomic_get_output_bus_fmts) {
>>>>>>>                 const struct drm_bridge_funcs *funcs =
>>>>>>> last_bridge->funcs;
>>>>>>>
>>>>>>>                 /*
>>>>>>> @@ -980,7 +987,12 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
>>>>>>> drm_bridge *bridge,
>>>>>>>                 if (!out_bus_fmts)
>>>>>>>                         return -ENOMEM;
>>>>>>>
>>>>>>> -               if (conn->display_info.num_bus_formats &&
>>>>>>> +               /*
>>>>>>> +                * If first bridge doesn't support negociation, use
>>>>>>> MEDIA_BUS_FMT_FIXED
>>>>>>> +                * as a safe value for the whole bridge chain
>>>>>>> +                */
>>>>>>> +               if (bridge->funcs->atomic_get_input_bus_fmts &&
>>>>>>> +                   conn->display_info.num_bus_formats &&
>>>>>>>                     conn->display_info.bus_formats)
>>>>>>>                         out_bus_fmts[0] = conn-
>>>>>>>> display_info.bus_formats[0];
>>>>>>>                 else
>>>>>>> ==><===============================
>>>>>>>
>>>>>>> This should exclude your situation where the first bridge doesn't
>>>>>>> support negociation.
> 
> This fixes the issue for me here on an H3 Salvator-XS.
> 
> Could you add...
> 
> Bisected-by: Kieran Bingham <kieran.bingham+renesas at ideasonboard.com>
> Tested-by: Kieran Bingham <kieran.bingham+renesas at ideasonboard.com>
> 
> alongside Biju's Reported-by: tag when posting as a fix please?


Which patch did you test ?

Neil

> 
> 
>>>>>>
>>>>>> I have tested this fix with Linux next-20220114. Still I see colour
>>>>> issue.
>>>>>>
>>>>>> It is still negotiating and it is calling get_output_fmt_callbck
>>>>>>
>>>>>> [    3.460155] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>>>> MEDIA_BUS_FMT_UYVY8_1X16=0#########
>>>>>> [    3.460180] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>>>> MEDIA_BUS_FMT_YUV8_1X24=1#########
>>>>>> [    3.460202] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>>>> MEDIA_BUS_FMT_RGB888_1X24=2#########
>>>>>>
>>>>>> And In get_input_fmt callback, I See the outputformat as YUV16 instead
>>>>> of RGB24.
>>>>>>
>>>>>> [    3.460319] ########dw_hdmi_bridge_atomic_get_input_bus_fmts
>>>>> MEDIA_BUS_FMT_UYVY8_1X16#########
>>>>>> [    3.473644] ########hdmi_video_sample
>>>>> MEDIA_BUS_FMT_UYVY8_1X16#########
>>>>>
>>>>> OK, looking at rcar-du, the dw-hdmi bridge is directly connected to the
>>>>> encoder.
>>>>
>>>> Yep.
>>>>
>>>>>
>>>>> Let me figure that out, no sure I can find a clean solution except putting
>>>>> back RGB24 before YUV.
>>>>>
>>>>> Anyway please test that:
>>>>
>>>> It works now after reordering.
>>>>
>>>> [    3.493302] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_RGB888_1X24=0#########
>>>> [    3.493326] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_YUV8_1X24=1#########
>>>> [    3.493348] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_UYVY8_1X16=2#########
>>>>
>>>> [    3.493463] ########dw_hdmi_bridge_atomic_get_input_bus_fmts MEDIA_BUS_FMT_RGB888_1X24#########
>>>> [    3.506797] ########hdmi_video_sample MEDIA_BUS_FMT_RGB888_1X24#########
>>>>
>>>> Is it acceptable solution to the users of dw_hdmi driver? May be it is worth to post a patch.
>>>> at least it is fixing the colour issue??
>>>
>>> Yes, it gets back to default behavior before negociation, nevertheless we need to think
>>> how to handle your use-case correctly at some point.
>>>
>>> I'll post this as a patch ASAP so it gets applied before landing in linus master.
>>>
>>> Neil
>>>
>>>>
>>>> Regards,
>>>> Biju
>>>>
>>>>>
>> [...]
>>
>> I'm not happy with this version since it's merely a hack which makes it work.
>>
>> Can you test the following change instead, it's correctly handles your situation in a generic manner.
>>
>> ========================><=============================
>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> index 54d8fdad395f..9f2e1cac0ae2 100644
>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> @@ -2551,8 +2551,9 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
>>         if (!output_fmts)
>>                 return NULL;
>>
>> -       /* If dw-hdmi is the only bridge, avoid negociating with ourselves */
>> -       if (list_is_singular(&bridge->encoder->bridge_chain)) {
>> +       /* If dw-hdmi is the first or only bridge, avoid negociating with ourselves */
>> +       if (list_is_singular(&bridge->encoder->bridge_chain) ||
>> +           list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain)) {
>>                 *num_output_fmts = 1;
>>                 output_fmts[0] = MEDIA_BUS_FMT_FIXED;
>>
>> @@ -2673,6 +2674,10 @@ static u32 *dw_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
>>         if (!input_fmts)
>>                 return NULL;
>>
>> +       /* If dw-hdmi is the first bridge fall-back to safe output format */
>> +       if (list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain))
>> +               output_fmt = MEDIA_BUS_FMT_FIXED;
>> +
>>         switch (output_fmt) {
>>         /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */
>>         case MEDIA_BUS_FMT_FIXED:
>> ========================><=============================
>>
>> Thanks,
>> Neil
>>
>>
>>>>>
>>>>> Neil
>>>>>
>>>>>>
>>>>>> Regards,
>>>>>> Biju
>>>>>>
>>>>
>>>
>>



From narmstrong at baylibre.com  Mon Jan 17 06:07:45 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 15:07:45 +0100
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <164242831905.10801.10615379536917395435@Monstersaurus>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
 <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>
 <OS0PR01MB5922BC31FBCF85F99F17737B86549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <ebaff694-a2d7-7eb8-5850-980e9d4e1e68@baylibre.com>
 <80fdc5a0-ddb8-5a0f-eb8c-ef7988ced638@baylibre.com>
 <164241711700.10801.9011781958267060147@Monstersaurus>
 <4f214ea2-5f9f-1217-6e65-f92e434ed826@baylibre.com>
 <164242831905.10801.10615379536917395435@Monstersaurus>
Message-ID: <92f37b42-23db-4aab-5262-911d07b6301f@baylibre.com>

On 17/01/2022 15:05, Kieran Bingham wrote:
> Quoting Neil Armstrong (2022-01-17 13:53:47)
>> On 17/01/2022 11:58, Kieran Bingham wrote:
>>> Hi Neil,
> 
> <big snips to clear up contexts>
> 
>>> This fixes the issue for me here on an H3 Salvator-XS.
>>>
>>> Could you add...
>>>
>>> Bisected-by: Kieran Bingham <kieran.bingham+renesas at ideasonboard.com>
>>> Tested-by: Kieran Bingham <kieran.bingham+renesas at ideasonboard.com>
>>>
>>> alongside Biju's Reported-by: tag when posting as a fix please?
>>
>>
>> Which patch did you test ?
> 
> Ah, yes that's not clear is it - sorry! I replied in the wrong place on
> the thread when I went back to the mail ... see below...
> 
>>>> I'm not happy with this version since it's merely a hack which makes it work.
>>>>
>>>> Can you test the following change instead, it's correctly handles your situation in a generic manner.
>>>>
>>>> ========================><=============================
>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> index 54d8fdad395f..9f2e1cac0ae2 100644
>>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> @@ -2551,8 +2551,9 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
>>>>         if (!output_fmts)
>>>>                 return NULL;
>>>>
>>>> -       /* If dw-hdmi is the only bridge, avoid negociating with ourselves */
>>>> -       if (list_is_singular(&bridge->encoder->bridge_chain)) {
>>>> +       /* If dw-hdmi is the first or only bridge, avoid negociating with ourselves */
>>>> +       if (list_is_singular(&bridge->encoder->bridge_chain) ||
>>>> +           list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain)) {
>>>>                 *num_output_fmts = 1;
>>>>                 output_fmts[0] = MEDIA_BUS_FMT_FIXED;
>>>>
>>>> @@ -2673,6 +2674,10 @@ static u32 *dw_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
>>>>         if (!input_fmts)
>>>>                 return NULL;
>>>>
>>>> +       /* If dw-hdmi is the first bridge fall-back to safe output format */
>>>> +       if (list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain))
>>>> +               output_fmt = MEDIA_BUS_FMT_FIXED;
>>>> +
>>>>         switch (output_fmt) {
>>>>         /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */
>>>>         case MEDIA_BUS_FMT_FIXED:
>>>> ========================><=============================
> 
> Sorry, I replied in the wrong part of the thread.
> 
> Here's the direct diff on my local tree:
> 
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 54d8fdad395f..cac9a87949f1 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2551,8 +2551,10 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
>         if (!output_fmts)
>                 return NULL;
>  
> -       /* If dw-hdmi is the only bridge, avoid negociating with ourselves */
> -       if (list_is_singular(&bridge->encoder->bridge_chain)) {
> +       /* If dw-hdmi is the first or only bridge, avoid negociating with ourselves */
> +       if (list_is_singular(&bridge->encoder->bridge_chain) ||
> +           list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain)) {
> +
>                 *num_output_fmts = 1;
>                 output_fmts[0] = MEDIA_BUS_FMT_FIXED;
>  
> @@ -2673,6 +2675,10 @@ static u32 *dw_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
>         if (!input_fmts)
>                 return NULL;
>  
> +       /* If dw-hdmi is the first bridge fall-back to safe output format */
> +       if (list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain))
> +               output_fmt = MEDIA_BUS_FMT_FIXED;
> +
>         switch (output_fmt) {
>         /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */
>         case MEDIA_BUS_FMT_FIXED:
> 
> Which I believe matches the above.

Ok thanks of clarifying !

let me post it asap.

Neil

> 
> --
> Kieran
> 



From narmstrong at baylibre.com  Mon Jan 17 06:30:39 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 15:30:39 +0100
Subject: [PATCH 3/3] arm64: dts: meson: remove Broadcom WiFi/BT nodes from
 Khadas VIM1
In-Reply-To: <20220113041746.16040-4-christianshewitt@gmail.com>
References: <20220113041746.16040-1-christianshewitt@gmail.com>
 <20220113041746.16040-4-christianshewitt@gmail.com>
Message-ID: <2236d8a8-77e7-7dc9-fd32-b3ade335a128@baylibre.com>

Hi,

On 13/01/2022 05:17, Christian Hewitt wrote:
> The Broadcom WiFi/BT SDIO nodes are now inherited from the P212 common dtsi
> so we can remove them from the VIM1 board dts.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  .../amlogic/meson-gxl-s905x-khadas-vim.dts    | 19 -------------------
>  1 file changed, 19 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
> index 6ab1cc125b96..108232a5aa2e 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
> @@ -217,25 +217,6 @@
>  	pinctrl-0 = <&pwm_e_pins>, <&pwm_f_clk_pins>;
>  };
>  
> -&sd_emmc_a {
> -	max-frequency = <100000000>;

The SDIO freq is marked as 50000000 in the p212 DTSI and was explicitly changes
by Jerome in adc52bf7ef16 ("arm64: dts: meson: fix mmc v2 chips max frequencies")

The change is ok if you change the p212 DTSI to 100000000 aswell.

> -
> -	brcmf: wifi at 1 {
> -		reg = <1>;
> -		compatible = "brcm,bcm4329-fmac";
> -	};
> -};
> -
> -&uart_A {
> -	bluetooth {
> -		compatible = "brcm,bcm43438-bt";
> -		shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
> -		max-speed = <2000000>;
> -		clocks = <&wifi32k>;
> -		clock-names = "lpo";
> -	};
> -};
> -
>  /* This is brought out on the Linux_RX (18) and Linux_TX (19) pins: */
>  &uart_AO {
>  	status = "okay";
> 

With the change in p212 dtsi:

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>

Thanks,
Neil


From narmstrong at baylibre.com  Mon Jan 17 06:30:47 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 15:30:47 +0100
Subject: [PATCH 2/3] arm64: dts: meson: move pwm_ef node in P212 dtsi
In-Reply-To: <20220113041746.16040-3-christianshewitt@gmail.com>
References: <20220113041746.16040-1-christianshewitt@gmail.com>
 <20220113041746.16040-3-christianshewitt@gmail.com>
Message-ID: <d82549cf-01cc-68de-8af3-763b94ba6ef6@baylibre.com>

On 13/01/2022 05:17, Christian Hewitt wrote:
> Cosmetic-only change to move/alpha-sort the node.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  .../boot/dts/amlogic/meson-gxl-s905x-p212.dtsi   | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
> index c635e5858929..b3d7b8613d6d 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
> @@ -97,6 +97,14 @@
>  	pinctrl-names = "default";
>  };
>  
> +&pwm_ef {
> +	status = "okay";
> +	pinctrl-0 = <&pwm_e_pins>;
> +	pinctrl-names = "default";
> +	clocks = <&clkc CLKID_FCLK_DIV4>;
> +	clock-names = "clkin0";
> +};
> +
>  &saradc {
>  	status = "okay";
>  	vref-supply = <&vddio_ao18>;
> @@ -170,14 +178,6 @@
>  	vqmmc-supply = <&vddio_boot>;
>  };
>  
> -&pwm_ef {
> -	status = "okay";
> -	pinctrl-0 = <&pwm_e_pins>;
> -	pinctrl-names = "default";
> -	clocks = <&clkc CLKID_FCLK_DIV4>;
> -	clock-names = "clkin0";
> -};
> -
>  /* This is connected to the Bluetooth module: */
>  &uart_A {
>  	status = "okay";
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From narmstrong at baylibre.com  Mon Jan 17 06:32:04 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 15:32:04 +0100
Subject: [PATCH 1/3] arm64: dts: meson: add Broadcom WiFi to P212 dtsi
In-Reply-To: <20220113041746.16040-2-christianshewitt@gmail.com>
References: <20220113041746.16040-1-christianshewitt@gmail.com>
 <20220113041746.16040-2-christianshewitt@gmail.com>
Message-ID: <927257db-1338-af1c-3198-3153e122967b@baylibre.com>

On 13/01/2022 05:17, Christian Hewitt wrote:
> The P212 has a combined WiFi/BT module. The BT side is already enabled
> in the dtsi but the WiFi side is not. Let's tweak SDIO speed (in-line
> with other GXL/GXM devices) and enable the WiFi module.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
> index 05cb2f5e5c36..c635e5858929 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
> @@ -113,7 +113,7 @@
>  
>  	bus-width = <4>;
>  	cap-sd-highspeed;
> -	max-frequency = <50000000>;
> +	max-frequency = <100000000>;
>  
>  	non-removable;
>  	disable-wp;
> @@ -125,6 +125,11 @@
>  
>  	vmmc-supply = <&vddao_3v3>;
>  	vqmmc-supply = <&vddio_boot>;
> +
> +	brcmf: wifi at 1 {
> +		reg = <1>;
> +		compatible = "brcm,bcm4329-fmac";
> +	};
>  };
>  
>  /* SD card */
> 

As I commented in patch 3, the 2 changes should be split.

When you resend, you can put my:

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>

in both patches.

Neil


From narmstrong at baylibre.com  Mon Jan 17 06:37:56 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 15:37:56 +0100
Subject: [PATCH] arm64: dts: meson: add audio playback to P212
In-Reply-To: <20220113044546.16856-1-christianshewitt@gmail.com>
References: <20220113044546.16856-1-christianshewitt@gmail.com>
Message-ID: <aa02e3f7-3f77-4b9c-74a0-987045de0352@baylibre.com>

Hi,

On 13/01/2022 05:45, Christian Hewitt wrote:
> Add initial audio support limited to HDMI i2s.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
> The P212 dts is widely used with Android box devices that follow the
> reference design. The real P212 development board probably has many
> more audio capabilities, but as a minimum we can enable HDMI output
> and help box users too.
> 
>  .../boot/dts/amlogic/meson-gxl-s905x-p212.dts | 40 +++++++++++++++++++
>  1 file changed, 40 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
> index 2602940c2077..a39830379c74 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
> @@ -7,6 +7,7 @@
>  /dts-v1/;
>  
>  #include "meson-gxl-s905x-p212.dtsi"
> +#include <dt-bindings/sound/meson-aiu.h>
>  
>  / {
>  	compatible = "amlogic,p212", "amlogic,s905x", "amlogic,meson-gxl";
> @@ -32,6 +33,45 @@
>  			};
>  		};
>  	};
> +
> +	sound {
> +		compatible = "amlogic,gx-sound-card";
> +		model = "S905X-P212";
> +		assigned-clocks = <&clkc CLKID_MPLL0>,
> +				  <&clkc CLKID_MPLL1>,
> +				  <&clkc CLKID_MPLL2>;
> +		assigned-clock-parents = <0>, <0>, <0>;
> +		assigned-clock-rates = <294912000>,
> +				       <270950400>,
> +				       <393216000>;
> +		status = "okay";
> +
> +		dai-link-0 {
> +			sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
> +		};
> +
> +		dai-link-1 {
> +			sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
> +			dai-format = "i2s";
> +			mclk-fs = <256>;
> +
> +			codec-0 {
> +				sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
> +			};
> +		};
> +
> +		dai-link-2 {
> +			sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
> +
> +			codec-0 {
> +				sound-dai = <&hdmi_tx>;
> +			};
> +		};
> +	};
> +};
> +
> +&aiu {
> +	status = "okay";
>  };
>  
>  &cec_AO {
> 

The P212 ref board has an analog audio output with a DIO2133CT14 amplifier unmuted by default with the active high GPIOH_5 to mute.

It's very probable all the STB boxes uses the same scheme, so it'll be safe to add the analog audio output here exactly like libretech-cc.

Neil


From sashal at kernel.org  Mon Jan 17 08:58:13 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 11:58:13 -0500
Subject: [PATCH AUTOSEL 5.16 12/52] clk: meson: gxbb: Fix the SDM_EN bit for
 MPLL0 on GXBB
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
References: <20220117165853.1470420-1-sashal@kernel.org>
Message-ID: <20220117165853.1470420-12-sashal@kernel.org>

From: Martin Blumenstingl <martin.blumenstingl at googlemail.com>

[ Upstream commit ff54938dd190d85f740b9bf9dde59b550936b621 ]

There are reports that 48kHz audio does not work on the WeTek Play 2
(which uses a GXBB SoC), while 44.1kHz audio works fine on the same
board. There are also reports of 48kHz audio working fine on GXL and
GXM SoCs, which are using an (almost) identical AIU (audio controller).

Experimenting has shown that MPLL0 is causing this problem. In the .dts
we have by default:
	assigned-clocks = <&clkc CLKID_MPLL0>,
			  <&clkc CLKID_MPLL1>,
			  <&clkc CLKID_MPLL2>;
	assigned-clock-rates = <294912000>,
			       <270950400>,
			       <393216000>;
The MPLL0 rate is divisible by 48kHz without remainder and the MPLL1
rate is divisible by 44.1kHz without remainder. Swapping these two clock
rates "fixes" 48kHz audio but breaks 44.1kHz audio.

Everything looks normal when looking at the info provided by the common
clock framework while playing 48kHz audio (via I2S with mclk-fs = 256):
        mpll_prediv                 1        1        0  2000000000
           mpll0_div                1        1        0   294909641
              mpll0                 1        1        0   294909641
                 cts_amclk_sel       1        1        0   294909641
                    cts_amclk_div       1        1        0    12287902
                       cts_amclk       1        1        0    12287902

meson-clk-msr however shows that the actual MPLL0 clock is off by more
than 38MHz:
        mp0_out               333322917    +/-10416Hz

The rate seen by meson-clk-msr is very close to what we would get when
SDM (the fractional part) was ignored:
  (2000000000Hz * 16384) / ((16384 * 6) = 333.33MHz
If SDM was considered the we should get close to:
  (2000000000Hz * 16384) / ((16384 * 6) + 12808) = 294.9MHz

Further experimenting shows that HHI_MPLL_CNTL7[15] does not have any
effect on the rate of MPLL0 as seen my meson-clk-msr (regardless of
whether that bit is zero or one the rate is always the same according to
meson-clk-msr). Using HHI_MPLL_CNTL[25] on the other hand as SDM_EN
results in SDM being considered for the rate output by the hardware. The
rate - as seen by meson-clk-msr - matches with what we expect when
SDM_EN is enabled (fractional part is being considered, resulting in a
294.9MHz output) or disable (fractional part being ignored, resulting in
a 333.33MHz output).

Reported-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Christian Hewitt <christianshewitt at gmail.com>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
Link: https://lore.kernel.org/r/20211031135006.1508796-1-martin.blumenstingl at googlemail.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/clk/meson/gxbb.c | 44 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index d6eed760327d0..608e0e8ca49a8 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -713,6 +713,35 @@ static struct clk_regmap gxbb_mpll_prediv = {
 };
 
 static struct clk_regmap gxbb_mpll0_div = {
+	.data = &(struct meson_clk_mpll_data){
+		.sdm = {
+			.reg_off = HHI_MPLL_CNTL7,
+			.shift   = 0,
+			.width   = 14,
+		},
+		.sdm_en = {
+			.reg_off = HHI_MPLL_CNTL,
+			.shift   = 25,
+			.width	 = 1,
+		},
+		.n2 = {
+			.reg_off = HHI_MPLL_CNTL7,
+			.shift   = 16,
+			.width   = 9,
+		},
+		.lock = &meson_clk_lock,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mpll0_div",
+		.ops = &meson_clk_mpll_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&gxbb_mpll_prediv.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap gxl_mpll0_div = {
 	.data = &(struct meson_clk_mpll_data){
 		.sdm = {
 			.reg_off = HHI_MPLL_CNTL7,
@@ -749,7 +778,16 @@ static struct clk_regmap gxbb_mpll0 = {
 	.hw.init = &(struct clk_init_data){
 		.name = "mpll0",
 		.ops = &clk_regmap_gate_ops,
-		.parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw },
+		.parent_data = &(const struct clk_parent_data) {
+			/*
+			 * Note:
+			 * GXL and GXBB have different SDM_EN registers. We
+			 * fallback to the global naming string mechanism so
+			 * mpll0_div picks up the appropriate one.
+			 */
+			.name = "mpll0_div",
+			.index = -1,
+		},
 		.num_parents = 1,
 		.flags = CLK_SET_RATE_PARENT,
 	},
@@ -3044,7 +3082,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
 		[CLKID_VAPB_1]		    = &gxbb_vapb_1.hw,
 		[CLKID_VAPB_SEL]	    = &gxbb_vapb_sel.hw,
 		[CLKID_VAPB]		    = &gxbb_vapb.hw,
-		[CLKID_MPLL0_DIV]	    = &gxbb_mpll0_div.hw,
+		[CLKID_MPLL0_DIV]	    = &gxl_mpll0_div.hw,
 		[CLKID_MPLL1_DIV]	    = &gxbb_mpll1_div.hw,
 		[CLKID_MPLL2_DIV]	    = &gxbb_mpll2_div.hw,
 		[CLKID_MPLL_PREDIV]	    = &gxbb_mpll_prediv.hw,
@@ -3439,7 +3477,7 @@ static struct clk_regmap *const gxl_clk_regmaps[] = {
 	&gxbb_mpll0,
 	&gxbb_mpll1,
 	&gxbb_mpll2,
-	&gxbb_mpll0_div,
+	&gxl_mpll0_div,
 	&gxbb_mpll1_div,
 	&gxbb_mpll2_div,
 	&gxbb_cts_amclk_div,
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:00:54 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:00:54 -0500
Subject: [PATCH AUTOSEL 5.15 11/44] clk: meson: gxbb: Fix the SDM_EN bit for
 MPLL0 on GXBB
In-Reply-To: <20220117170127.1471115-1-sashal@kernel.org>
References: <20220117170127.1471115-1-sashal@kernel.org>
Message-ID: <20220117170127.1471115-11-sashal@kernel.org>

From: Martin Blumenstingl <martin.blumenstingl at googlemail.com>

[ Upstream commit ff54938dd190d85f740b9bf9dde59b550936b621 ]

There are reports that 48kHz audio does not work on the WeTek Play 2
(which uses a GXBB SoC), while 44.1kHz audio works fine on the same
board. There are also reports of 48kHz audio working fine on GXL and
GXM SoCs, which are using an (almost) identical AIU (audio controller).

Experimenting has shown that MPLL0 is causing this problem. In the .dts
we have by default:
	assigned-clocks = <&clkc CLKID_MPLL0>,
			  <&clkc CLKID_MPLL1>,
			  <&clkc CLKID_MPLL2>;
	assigned-clock-rates = <294912000>,
			       <270950400>,
			       <393216000>;
The MPLL0 rate is divisible by 48kHz without remainder and the MPLL1
rate is divisible by 44.1kHz without remainder. Swapping these two clock
rates "fixes" 48kHz audio but breaks 44.1kHz audio.

Everything looks normal when looking at the info provided by the common
clock framework while playing 48kHz audio (via I2S with mclk-fs = 256):
        mpll_prediv                 1        1        0  2000000000
           mpll0_div                1        1        0   294909641
              mpll0                 1        1        0   294909641
                 cts_amclk_sel       1        1        0   294909641
                    cts_amclk_div       1        1        0    12287902
                       cts_amclk       1        1        0    12287902

meson-clk-msr however shows that the actual MPLL0 clock is off by more
than 38MHz:
        mp0_out               333322917    +/-10416Hz

The rate seen by meson-clk-msr is very close to what we would get when
SDM (the fractional part) was ignored:
  (2000000000Hz * 16384) / ((16384 * 6) = 333.33MHz
If SDM was considered the we should get close to:
  (2000000000Hz * 16384) / ((16384 * 6) + 12808) = 294.9MHz

Further experimenting shows that HHI_MPLL_CNTL7[15] does not have any
effect on the rate of MPLL0 as seen my meson-clk-msr (regardless of
whether that bit is zero or one the rate is always the same according to
meson-clk-msr). Using HHI_MPLL_CNTL[25] on the other hand as SDM_EN
results in SDM being considered for the rate output by the hardware. The
rate - as seen by meson-clk-msr - matches with what we expect when
SDM_EN is enabled (fractional part is being considered, resulting in a
294.9MHz output) or disable (fractional part being ignored, resulting in
a 333.33MHz output).

Reported-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Christian Hewitt <christianshewitt at gmail.com>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
Link: https://lore.kernel.org/r/20211031135006.1508796-1-martin.blumenstingl at googlemail.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/clk/meson/gxbb.c | 44 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index d6eed760327d0..608e0e8ca49a8 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -713,6 +713,35 @@ static struct clk_regmap gxbb_mpll_prediv = {
 };
 
 static struct clk_regmap gxbb_mpll0_div = {
+	.data = &(struct meson_clk_mpll_data){
+		.sdm = {
+			.reg_off = HHI_MPLL_CNTL7,
+			.shift   = 0,
+			.width   = 14,
+		},
+		.sdm_en = {
+			.reg_off = HHI_MPLL_CNTL,
+			.shift   = 25,
+			.width	 = 1,
+		},
+		.n2 = {
+			.reg_off = HHI_MPLL_CNTL7,
+			.shift   = 16,
+			.width   = 9,
+		},
+		.lock = &meson_clk_lock,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mpll0_div",
+		.ops = &meson_clk_mpll_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&gxbb_mpll_prediv.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap gxl_mpll0_div = {
 	.data = &(struct meson_clk_mpll_data){
 		.sdm = {
 			.reg_off = HHI_MPLL_CNTL7,
@@ -749,7 +778,16 @@ static struct clk_regmap gxbb_mpll0 = {
 	.hw.init = &(struct clk_init_data){
 		.name = "mpll0",
 		.ops = &clk_regmap_gate_ops,
-		.parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw },
+		.parent_data = &(const struct clk_parent_data) {
+			/*
+			 * Note:
+			 * GXL and GXBB have different SDM_EN registers. We
+			 * fallback to the global naming string mechanism so
+			 * mpll0_div picks up the appropriate one.
+			 */
+			.name = "mpll0_div",
+			.index = -1,
+		},
 		.num_parents = 1,
 		.flags = CLK_SET_RATE_PARENT,
 	},
@@ -3044,7 +3082,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
 		[CLKID_VAPB_1]		    = &gxbb_vapb_1.hw,
 		[CLKID_VAPB_SEL]	    = &gxbb_vapb_sel.hw,
 		[CLKID_VAPB]		    = &gxbb_vapb.hw,
-		[CLKID_MPLL0_DIV]	    = &gxbb_mpll0_div.hw,
+		[CLKID_MPLL0_DIV]	    = &gxl_mpll0_div.hw,
 		[CLKID_MPLL1_DIV]	    = &gxbb_mpll1_div.hw,
 		[CLKID_MPLL2_DIV]	    = &gxbb_mpll2_div.hw,
 		[CLKID_MPLL_PREDIV]	    = &gxbb_mpll_prediv.hw,
@@ -3439,7 +3477,7 @@ static struct clk_regmap *const gxl_clk_regmaps[] = {
 	&gxbb_mpll0,
 	&gxbb_mpll1,
 	&gxbb_mpll2,
-	&gxbb_mpll0_div,
+	&gxl_mpll0_div,
 	&gxbb_mpll1_div,
 	&gxbb_mpll2_div,
 	&gxbb_cts_amclk_div,
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:03:01 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:03:01 -0500
Subject: [PATCH AUTOSEL 5.10 11/34] clk: meson: gxbb: Fix the SDM_EN bit for
 MPLL0 on GXBB
In-Reply-To: <20220117170326.1471712-1-sashal@kernel.org>
References: <20220117170326.1471712-1-sashal@kernel.org>
Message-ID: <20220117170326.1471712-11-sashal@kernel.org>

From: Martin Blumenstingl <martin.blumenstingl at googlemail.com>

[ Upstream commit ff54938dd190d85f740b9bf9dde59b550936b621 ]

There are reports that 48kHz audio does not work on the WeTek Play 2
(which uses a GXBB SoC), while 44.1kHz audio works fine on the same
board. There are also reports of 48kHz audio working fine on GXL and
GXM SoCs, which are using an (almost) identical AIU (audio controller).

Experimenting has shown that MPLL0 is causing this problem. In the .dts
we have by default:
	assigned-clocks = <&clkc CLKID_MPLL0>,
			  <&clkc CLKID_MPLL1>,
			  <&clkc CLKID_MPLL2>;
	assigned-clock-rates = <294912000>,
			       <270950400>,
			       <393216000>;
The MPLL0 rate is divisible by 48kHz without remainder and the MPLL1
rate is divisible by 44.1kHz without remainder. Swapping these two clock
rates "fixes" 48kHz audio but breaks 44.1kHz audio.

Everything looks normal when looking at the info provided by the common
clock framework while playing 48kHz audio (via I2S with mclk-fs = 256):
        mpll_prediv                 1        1        0  2000000000
           mpll0_div                1        1        0   294909641
              mpll0                 1        1        0   294909641
                 cts_amclk_sel       1        1        0   294909641
                    cts_amclk_div       1        1        0    12287902
                       cts_amclk       1        1        0    12287902

meson-clk-msr however shows that the actual MPLL0 clock is off by more
than 38MHz:
        mp0_out               333322917    +/-10416Hz

The rate seen by meson-clk-msr is very close to what we would get when
SDM (the fractional part) was ignored:
  (2000000000Hz * 16384) / ((16384 * 6) = 333.33MHz
If SDM was considered the we should get close to:
  (2000000000Hz * 16384) / ((16384 * 6) + 12808) = 294.9MHz

Further experimenting shows that HHI_MPLL_CNTL7[15] does not have any
effect on the rate of MPLL0 as seen my meson-clk-msr (regardless of
whether that bit is zero or one the rate is always the same according to
meson-clk-msr). Using HHI_MPLL_CNTL[25] on the other hand as SDM_EN
results in SDM being considered for the rate output by the hardware. The
rate - as seen by meson-clk-msr - matches with what we expect when
SDM_EN is enabled (fractional part is being considered, resulting in a
294.9MHz output) or disable (fractional part being ignored, resulting in
a 333.33MHz output).

Reported-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Christian Hewitt <christianshewitt at gmail.com>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
Link: https://lore.kernel.org/r/20211031135006.1508796-1-martin.blumenstingl at googlemail.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/clk/meson/gxbb.c | 44 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 0a68af6eec3dd..d42551a46ec91 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -712,6 +712,35 @@ static struct clk_regmap gxbb_mpll_prediv = {
 };
 
 static struct clk_regmap gxbb_mpll0_div = {
+	.data = &(struct meson_clk_mpll_data){
+		.sdm = {
+			.reg_off = HHI_MPLL_CNTL7,
+			.shift   = 0,
+			.width   = 14,
+		},
+		.sdm_en = {
+			.reg_off = HHI_MPLL_CNTL,
+			.shift   = 25,
+			.width	 = 1,
+		},
+		.n2 = {
+			.reg_off = HHI_MPLL_CNTL7,
+			.shift   = 16,
+			.width   = 9,
+		},
+		.lock = &meson_clk_lock,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mpll0_div",
+		.ops = &meson_clk_mpll_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&gxbb_mpll_prediv.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap gxl_mpll0_div = {
 	.data = &(struct meson_clk_mpll_data){
 		.sdm = {
 			.reg_off = HHI_MPLL_CNTL7,
@@ -748,7 +777,16 @@ static struct clk_regmap gxbb_mpll0 = {
 	.hw.init = &(struct clk_init_data){
 		.name = "mpll0",
 		.ops = &clk_regmap_gate_ops,
-		.parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw },
+		.parent_data = &(const struct clk_parent_data) {
+			/*
+			 * Note:
+			 * GXL and GXBB have different SDM_EN registers. We
+			 * fallback to the global naming string mechanism so
+			 * mpll0_div picks up the appropriate one.
+			 */
+			.name = "mpll0_div",
+			.index = -1,
+		},
 		.num_parents = 1,
 		.flags = CLK_SET_RATE_PARENT,
 	},
@@ -3043,7 +3081,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
 		[CLKID_VAPB_1]		    = &gxbb_vapb_1.hw,
 		[CLKID_VAPB_SEL]	    = &gxbb_vapb_sel.hw,
 		[CLKID_VAPB]		    = &gxbb_vapb.hw,
-		[CLKID_MPLL0_DIV]	    = &gxbb_mpll0_div.hw,
+		[CLKID_MPLL0_DIV]	    = &gxl_mpll0_div.hw,
 		[CLKID_MPLL1_DIV]	    = &gxbb_mpll1_div.hw,
 		[CLKID_MPLL2_DIV]	    = &gxbb_mpll2_div.hw,
 		[CLKID_MPLL_PREDIV]	    = &gxbb_mpll_prediv.hw,
@@ -3438,7 +3476,7 @@ static struct clk_regmap *const gxl_clk_regmaps[] = {
 	&gxbb_mpll0,
 	&gxbb_mpll1,
 	&gxbb_mpll2,
-	&gxbb_mpll0_div,
+	&gxl_mpll0_div,
 	&gxbb_mpll1_div,
 	&gxbb_mpll2_div,
 	&gxbb_cts_amclk_div,
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:04:42 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:04:42 -0500
Subject: [PATCH AUTOSEL 5.4 10/21] clk: meson: gxbb: Fix the SDM_EN bit for
 MPLL0 on GXBB
In-Reply-To: <20220117170454.1472347-1-sashal@kernel.org>
References: <20220117170454.1472347-1-sashal@kernel.org>
Message-ID: <20220117170454.1472347-10-sashal@kernel.org>

From: Martin Blumenstingl <martin.blumenstingl at googlemail.com>

[ Upstream commit ff54938dd190d85f740b9bf9dde59b550936b621 ]

There are reports that 48kHz audio does not work on the WeTek Play 2
(which uses a GXBB SoC), while 44.1kHz audio works fine on the same
board. There are also reports of 48kHz audio working fine on GXL and
GXM SoCs, which are using an (almost) identical AIU (audio controller).

Experimenting has shown that MPLL0 is causing this problem. In the .dts
we have by default:
	assigned-clocks = <&clkc CLKID_MPLL0>,
			  <&clkc CLKID_MPLL1>,
			  <&clkc CLKID_MPLL2>;
	assigned-clock-rates = <294912000>,
			       <270950400>,
			       <393216000>;
The MPLL0 rate is divisible by 48kHz without remainder and the MPLL1
rate is divisible by 44.1kHz without remainder. Swapping these two clock
rates "fixes" 48kHz audio but breaks 44.1kHz audio.

Everything looks normal when looking at the info provided by the common
clock framework while playing 48kHz audio (via I2S with mclk-fs = 256):
        mpll_prediv                 1        1        0  2000000000
           mpll0_div                1        1        0   294909641
              mpll0                 1        1        0   294909641
                 cts_amclk_sel       1        1        0   294909641
                    cts_amclk_div       1        1        0    12287902
                       cts_amclk       1        1        0    12287902

meson-clk-msr however shows that the actual MPLL0 clock is off by more
than 38MHz:
        mp0_out               333322917    +/-10416Hz

The rate seen by meson-clk-msr is very close to what we would get when
SDM (the fractional part) was ignored:
  (2000000000Hz * 16384) / ((16384 * 6) = 333.33MHz
If SDM was considered the we should get close to:
  (2000000000Hz * 16384) / ((16384 * 6) + 12808) = 294.9MHz

Further experimenting shows that HHI_MPLL_CNTL7[15] does not have any
effect on the rate of MPLL0 as seen my meson-clk-msr (regardless of
whether that bit is zero or one the rate is always the same according to
meson-clk-msr). Using HHI_MPLL_CNTL[25] on the other hand as SDM_EN
results in SDM being considered for the rate output by the hardware. The
rate - as seen by meson-clk-msr - matches with what we expect when
SDM_EN is enabled (fractional part is being considered, resulting in a
294.9MHz output) or disable (fractional part being ignored, resulting in
a 333.33MHz output).

Reported-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Christian Hewitt <christianshewitt at gmail.com>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
Link: https://lore.kernel.org/r/20211031135006.1508796-1-martin.blumenstingl at googlemail.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/clk/meson/gxbb.c | 44 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 1f9c056e684ce..e8e36ec70b27f 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -712,6 +712,35 @@ static struct clk_regmap gxbb_mpll_prediv = {
 };
 
 static struct clk_regmap gxbb_mpll0_div = {
+	.data = &(struct meson_clk_mpll_data){
+		.sdm = {
+			.reg_off = HHI_MPLL_CNTL7,
+			.shift   = 0,
+			.width   = 14,
+		},
+		.sdm_en = {
+			.reg_off = HHI_MPLL_CNTL,
+			.shift   = 25,
+			.width	 = 1,
+		},
+		.n2 = {
+			.reg_off = HHI_MPLL_CNTL7,
+			.shift   = 16,
+			.width   = 9,
+		},
+		.lock = &meson_clk_lock,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mpll0_div",
+		.ops = &meson_clk_mpll_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&gxbb_mpll_prediv.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap gxl_mpll0_div = {
 	.data = &(struct meson_clk_mpll_data){
 		.sdm = {
 			.reg_off = HHI_MPLL_CNTL7,
@@ -748,7 +777,16 @@ static struct clk_regmap gxbb_mpll0 = {
 	.hw.init = &(struct clk_init_data){
 		.name = "mpll0",
 		.ops = &clk_regmap_gate_ops,
-		.parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw },
+		.parent_data = &(const struct clk_parent_data) {
+			/*
+			 * Note:
+			 * GXL and GXBB have different SDM_EN registers. We
+			 * fallback to the global naming string mechanism so
+			 * mpll0_div picks up the appropriate one.
+			 */
+			.name = "mpll0_div",
+			.index = -1,
+		},
 		.num_parents = 1,
 		.flags = CLK_SET_RATE_PARENT,
 	},
@@ -3036,7 +3074,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
 		[CLKID_VAPB_1]		    = &gxbb_vapb_1.hw,
 		[CLKID_VAPB_SEL]	    = &gxbb_vapb_sel.hw,
 		[CLKID_VAPB]		    = &gxbb_vapb.hw,
-		[CLKID_MPLL0_DIV]	    = &gxbb_mpll0_div.hw,
+		[CLKID_MPLL0_DIV]	    = &gxl_mpll0_div.hw,
 		[CLKID_MPLL1_DIV]	    = &gxbb_mpll1_div.hw,
 		[CLKID_MPLL2_DIV]	    = &gxbb_mpll2_div.hw,
 		[CLKID_MPLL_PREDIV]	    = &gxbb_mpll_prediv.hw,
@@ -3430,7 +3468,7 @@ static struct clk_regmap *const gxl_clk_regmaps[] = {
 	&gxbb_mpll0,
 	&gxbb_mpll1,
 	&gxbb_mpll2,
-	&gxbb_mpll0_div,
+	&gxl_mpll0_div,
 	&gxbb_mpll1_div,
 	&gxbb_mpll2_div,
 	&gxbb_cts_amclk_div,
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:16:32 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:16:32 -0500
Subject: [PATCH AUTOSEL 5.16 029/217] usb: dwc3: meson-g12a: fix shared reset
 control use
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-29-sashal@kernel.org>

From: Amjad Ouled-Ameur <aouledameur at baylibre.com>

[ Upstream commit 4ce3b45704d5ef46fb4b28083c8aba6716fabf3b ]

reset_control_(de)assert() calls are called on a shared reset line when
reset_control_reset has been used. This is not allowed by the reset
framework.

Use reset_control_rearm() call in suspend() and remove() as a way to state
that the resource is no longer used, hence the shared reset line
may be triggered again by other devices. Use reset_control_rearm() also in
case probe fails after reset() has been called.

reset_control_rearm() keeps use of triggered_count sane in the reset
framework, use of reset_control_reset() on shared reset line should be
balanced with reset_control_rearm().

Signed-off-by: Amjad Ouled-Ameur <aouledameur at baylibre.com>
Reported-by: Jerome Brunet <jbrunet at baylibre.com>
Link: https://lore.kernel.org/r/20211112162827.128319-3-aouledameur at baylibre.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/usb/dwc3/dwc3-meson-g12a.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c
index d0f9b7c296b0d..bd814df3bf8b8 100644
--- a/drivers/usb/dwc3/dwc3-meson-g12a.c
+++ b/drivers/usb/dwc3/dwc3-meson-g12a.c
@@ -755,16 +755,16 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
 
 	ret = dwc3_meson_g12a_get_phys(priv);
 	if (ret)
-		goto err_disable_clks;
+		goto err_rearm;
 
 	ret = priv->drvdata->setup_regmaps(priv, base);
 	if (ret)
-		goto err_disable_clks;
+		goto err_rearm;
 
 	if (priv->vbus) {
 		ret = regulator_enable(priv->vbus);
 		if (ret)
-			goto err_disable_clks;
+			goto err_rearm;
 	}
 
 	/* Get dr_mode */
@@ -825,6 +825,9 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
 	if (priv->vbus)
 		regulator_disable(priv->vbus);
 
+err_rearm:
+	reset_control_rearm(priv->reset);
+
 err_disable_clks:
 	clk_bulk_disable_unprepare(priv->drvdata->num_clks,
 				   priv->drvdata->clks);
@@ -852,6 +855,8 @@ static int dwc3_meson_g12a_remove(struct platform_device *pdev)
 	pm_runtime_put_noidle(dev);
 	pm_runtime_set_suspended(dev);
 
+	reset_control_rearm(priv->reset);
+
 	clk_bulk_disable_unprepare(priv->drvdata->num_clks,
 				   priv->drvdata->clks);
 
@@ -892,7 +897,7 @@ static int __maybe_unused dwc3_meson_g12a_suspend(struct device *dev)
 		phy_exit(priv->phys[i]);
 	}
 
-	reset_control_assert(priv->reset);
+	reset_control_rearm(priv->reset);
 
 	return 0;
 }
@@ -902,7 +907,9 @@ static int __maybe_unused dwc3_meson_g12a_resume(struct device *dev)
 	struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
 	int i, ret;
 
-	reset_control_deassert(priv->reset);
+	ret = reset_control_reset(priv->reset);
+	if (ret)
+		return ret;
 
 	ret = priv->drvdata->usb_init(priv);
 	if (ret)
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:29:07 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:29:07 -0500
Subject: [PATCH AUTOSEL 5.15 023/188] usb: dwc3: meson-g12a: fix shared reset
 control use
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-23-sashal@kernel.org>

From: Amjad Ouled-Ameur <aouledameur at baylibre.com>

[ Upstream commit 4ce3b45704d5ef46fb4b28083c8aba6716fabf3b ]

reset_control_(de)assert() calls are called on a shared reset line when
reset_control_reset has been used. This is not allowed by the reset
framework.

Use reset_control_rearm() call in suspend() and remove() as a way to state
that the resource is no longer used, hence the shared reset line
may be triggered again by other devices. Use reset_control_rearm() also in
case probe fails after reset() has been called.

reset_control_rearm() keeps use of triggered_count sane in the reset
framework, use of reset_control_reset() on shared reset line should be
balanced with reset_control_rearm().

Signed-off-by: Amjad Ouled-Ameur <aouledameur at baylibre.com>
Reported-by: Jerome Brunet <jbrunet at baylibre.com>
Link: https://lore.kernel.org/r/20211112162827.128319-3-aouledameur at baylibre.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/usb/dwc3/dwc3-meson-g12a.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c
index d0f9b7c296b0d..bd814df3bf8b8 100644
--- a/drivers/usb/dwc3/dwc3-meson-g12a.c
+++ b/drivers/usb/dwc3/dwc3-meson-g12a.c
@@ -755,16 +755,16 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
 
 	ret = dwc3_meson_g12a_get_phys(priv);
 	if (ret)
-		goto err_disable_clks;
+		goto err_rearm;
 
 	ret = priv->drvdata->setup_regmaps(priv, base);
 	if (ret)
-		goto err_disable_clks;
+		goto err_rearm;
 
 	if (priv->vbus) {
 		ret = regulator_enable(priv->vbus);
 		if (ret)
-			goto err_disable_clks;
+			goto err_rearm;
 	}
 
 	/* Get dr_mode */
@@ -825,6 +825,9 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
 	if (priv->vbus)
 		regulator_disable(priv->vbus);
 
+err_rearm:
+	reset_control_rearm(priv->reset);
+
 err_disable_clks:
 	clk_bulk_disable_unprepare(priv->drvdata->num_clks,
 				   priv->drvdata->clks);
@@ -852,6 +855,8 @@ static int dwc3_meson_g12a_remove(struct platform_device *pdev)
 	pm_runtime_put_noidle(dev);
 	pm_runtime_set_suspended(dev);
 
+	reset_control_rearm(priv->reset);
+
 	clk_bulk_disable_unprepare(priv->drvdata->num_clks,
 				   priv->drvdata->clks);
 
@@ -892,7 +897,7 @@ static int __maybe_unused dwc3_meson_g12a_suspend(struct device *dev)
 		phy_exit(priv->phys[i]);
 	}
 
-	reset_control_assert(priv->reset);
+	reset_control_rearm(priv->reset);
 
 	return 0;
 }
@@ -902,7 +907,9 @@ static int __maybe_unused dwc3_meson_g12a_resume(struct device *dev)
 	struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
 	int i, ret;
 
-	reset_control_deassert(priv->reset);
+	ret = reset_control_reset(priv->reset);
+	if (ret)
+		return ret;
 
 	ret = priv->drvdata->usb_init(priv);
 	if (ret)
-- 
2.34.1



From victor.liu at nxp.com  Mon Jan 17 18:59:18 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Tue, 18 Jan 2022 10:59:18 +0800
Subject: [PATCH] phy: dphy: Correct clk_pre parameter
Message-ID: <20220118025918.1444288-1-victor.liu@nxp.com>

The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
mentions that it should be in UI.  However, the dphy core driver wrongly
sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
is '8 UI', instead of 8.

So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
value according to the D-PHY specification.

I'm assuming that all impacted custom drivers shall program values in
TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
specification mentions that the frequency of TxByteClkHS is exactly 1/8
the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
custom driver code is changed to program those values as
DIV_ROUND_UP(cfg->clk_pre, MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD), then.

Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
as I don't have the hardwares.

Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
Cc: Andrzej Hajda <andrzej.hajda at intel.com>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Robert Foss <robert.foss at linaro.org>
Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
Cc: Jonas Karlman <jonas at kwiboo.se>
Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
Cc: David Airlie <airlied at linux.ie>
Cc: Daniel Vetter <daniel at ffwll.ch>
Cc: Kishon Vijay Abraham I <kishon at ti.com>
Cc: Vinod Koul <vkoul at kernel.org>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: Heiko Stuebner <heiko at sntech.de>
Cc: Maxime Ripard <mripard at kernel.org>
Cc: Guido G?nther <agx at sigxcpu.org>
Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
 drivers/gpu/drm/bridge/nwl-dsi.c                 | 7 ++-----
 drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    | 3 ++-
 drivers/phy/phy-core-mipi-dphy.c                 | 4 ++--
 drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c | 3 ++-
 include/linux/phy/phy-mipi-dphy.h                | 4 +++-
 5 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index a7389a0facfb..f1fdcdf763ee 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -196,12 +196,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
 /*
  * ui2bc - UI time periods to byte clock cycles
  */
-static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
+static u32 ui2bc(struct nwl_dsi *dsi, unsigned int ui)
 {
-	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
-
-	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
-				  dsi->mode.clock * 1000 * bpp);
+	return DIV_ROUND_UP(ui, MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD);
 }
 
 /*
diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
index cd2332bf0e31..8a818cdb7606 100644
--- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
+++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
@@ -250,7 +250,8 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
 		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
 		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
 	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
-		     DIV_ROUND_UP(priv->config.clk_pre, temp));
+		     DIV_ROUND_UP(priv->config.clk_pre,
+				  MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD));
 
 	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
 		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
index 288c9c67aa74..ccb4045685cd 100644
--- a/drivers/phy/phy-core-mipi-dphy.c
+++ b/drivers/phy/phy-core-mipi-dphy.c
@@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
 
 	cfg->clk_miss = 0;
 	cfg->clk_post = 60000 + 52 * ui;
-	cfg->clk_pre = 8000;
+	cfg->clk_pre = 8;
 	cfg->clk_prepare = 38000;
 	cfg->clk_settle = 95000;
 	cfg->clk_term_en = 0;
@@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
 	if (cfg->clk_post < (60000 + 52 * ui))
 		return -EINVAL;
 
-	if (cfg->clk_pre < 8000)
+	if (cfg->clk_pre < 8)
 		return -EINVAL;
 
 	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
index 347dc79a18c1..67b0a17be7e3 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
@@ -364,7 +364,8 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
 	 * The value of counter for HS Tclk-pre
 	 * Tclk-pre = Tpin_txbyteclkhs * value
 	 */
-	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
+	clk_pre = DIV_ROUND_UP(cfg->clk_pre,
+			       MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD);
 
 	/*
 	 * The value of counter for HS Tlpx Time
diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
index a877ffee845d..ab1f736fbcd3 100644
--- a/include/linux/phy/phy-mipi-dphy.h
+++ b/include/linux/phy/phy-mipi-dphy.h
@@ -6,6 +6,8 @@
 #ifndef __PHY_MIPI_DPHY_H_
 #define __PHY_MIPI_DPHY_H_
 
+#define MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD	8
+
 /**
  * struct phy_configure_opts_mipi_dphy - MIPI D-PHY configuration set
  *
@@ -42,7 +44,7 @@ struct phy_configure_opts_mipi_dphy {
 	 * the transmitter prior to any associated Data Lane beginning
 	 * the transition from LP to HS mode.
 	 *
-	 * Minimum value: 8 UI
+	 * Minimum value: 8
 	 */
 	unsigned int		clk_pre;
 
-- 
2.25.1



From yu.tu at amlogic.com  Mon Jan 17 19:09:06 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 18 Jan 2022 11:09:06 +0800
Subject: [PATCH V6 0/5] Use CCF to describe the UART baud rate clock
Message-ID: <20220118030911.12815-1-yu.tu@amlogic.com>

Using the common Clock code to describe the UART baud rate
clock makes it easier for the UART driver to be compatible
with the baud rate requirements of the UART IP on different
meson chips. Add Meson S4 SoC compatible.

Yu Tu (5):
  tty: serial: meson: Move request the register region to probe
  tty: serial: meson: Use devm_ioremap_resource to get register mapped
    memory
  tty: serial: meson: Describes the calculation of the UART baud rate
    clock using a clock frame
  tty: serial: meson: Make some bit of the REG5 register writable
  tty: serial: meson: Added S4 SOC compatibility

V5 -> V6: Change error format as discussed in the email.
V4 -> V5: Change error format.
V3 -> V4: Change CCF to describe the UART baud rate clock as discussed
in the email.
V2 -> V3: add compatible = "amlogic,meson-gx-uart". Because it must change
the DTS before it can be deleted
V1 -> V2: Use CCF to describe the UART baud rate clock.Make some changes as
discussed in the email

Link:https://lore.kernel.org/linux-amlogic/20220110104214.25321-4-yu.tu at amlogic.com/

 drivers/tty/serial/meson_uart.c | 217 ++++++++++++++++++++++----------
 1 file changed, 149 insertions(+), 68 deletions(-)


base-commit: 4d66020dcef83314092f2c8c89152a8d122627e2
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 17 19:09:08 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 18 Jan 2022 11:09:08 +0800
Subject: [PATCH V6 2/5] tty: serial: meson: Use devm_ioremap_resource to get
 register mapped memory
In-Reply-To: <20220118030911.12815-1-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
Message-ID: <20220118030911.12815-3-yu.tu@amlogic.com>

Replace devm_request_mem_region and devm_ioremap with
devm_ioremap_resource to make the code cleaner.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 6b80e41b4cc1..7570958d010c 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -720,15 +720,7 @@ static int meson_uart_probe(struct platform_device *pdev)
 	if (!port)
 		return -ENOMEM;
 
-	if (!devm_request_mem_region(&pdev->dev, res_mem->start,
-				     resource_size(res_mem),
-				     dev_name(&pdev->dev))) {
-		dev_err(&pdev->dev, "Memory region busy\n");
-		return -EBUSY;
-	}
-
-	port->membase = devm_ioremap(&pdev->dev, res_mem->start,
-				     resource_size(res_mem));
+	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
 	if (IS_ERR(port->membase))
 		return PTR_ERR(port->membase);
 
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 17 19:09:07 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 18 Jan 2022 11:09:07 +0800
Subject: [PATCH V6 1/5] tty: serial: meson: Move request the register region
 to probe
In-Reply-To: <20220118030911.12815-1-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
Message-ID: <20220118030911.12815-2-yu.tu@amlogic.com>

This simplifies resetting the UART controller during probe
and will make it easier to integrate the common clock code
which will require the registers at probe time as well.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 45e00d928253..6b80e41b4cc1 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -395,24 +395,11 @@ static int meson_uart_verify_port(struct uart_port *port,
 
 static void meson_uart_release_port(struct uart_port *port)
 {
-	devm_iounmap(port->dev, port->membase);
-	port->membase = NULL;
-	devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
+	/* nothing to do */
 }
 
 static int meson_uart_request_port(struct uart_port *port)
 {
-	if (!devm_request_mem_region(port->dev, port->mapbase, port->mapsize,
-				     dev_name(port->dev))) {
-		dev_err(port->dev, "Memory region busy\n");
-		return -EBUSY;
-	}
-
-	port->membase = devm_ioremap(port->dev, port->mapbase,
-					     port->mapsize);
-	if (!port->membase)
-		return -ENOMEM;
-
 	return 0;
 }
 
@@ -733,6 +720,18 @@ static int meson_uart_probe(struct platform_device *pdev)
 	if (!port)
 		return -ENOMEM;
 
+	if (!devm_request_mem_region(&pdev->dev, res_mem->start,
+				     resource_size(res_mem),
+				     dev_name(&pdev->dev))) {
+		dev_err(&pdev->dev, "Memory region busy\n");
+		return -EBUSY;
+	}
+
+	port->membase = devm_ioremap(&pdev->dev, res_mem->start,
+				     resource_size(res_mem));
+	if (IS_ERR(port->membase))
+		return PTR_ERR(port->membase);
+
 	ret = meson_uart_probe_clocks(pdev, port);
 	if (ret)
 		return ret;
@@ -754,10 +753,7 @@ static int meson_uart_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, port);
 
 	/* reset port before registering (and possibly registering console) */
-	if (meson_uart_request_port(port) >= 0) {
-		meson_uart_reset(port);
-		meson_uart_release_port(port);
-	}
+	meson_uart_reset(port);
 
 	ret = uart_add_one_port(&meson_uart_driver, port);
 	if (ret)
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 17 19:09:09 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 18 Jan 2022 11:09:09 +0800
Subject: [PATCH V6 3/5] tty: serial: meson: Describes the calculation of the
 UART baud rate clock using a clock frame
In-Reply-To: <20220118030911.12815-1-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
Message-ID: <20220118030911.12815-4-yu.tu@amlogic.com>

Using the common Clock code to describe the UART baud rate clock
makes it easier for the UART driver to be compatible with the
baud rate requirements of the UART IP on different meson chips.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 195 +++++++++++++++++++++++---------
 1 file changed, 142 insertions(+), 53 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 7570958d010c..92fa91c825e6 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -65,9 +66,7 @@
 #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
 
 /* AML_UART_REG5 bits */
-#define AML_UART_BAUD_MASK		0x7fffff
 #define AML_UART_BAUD_USE		BIT(23)
-#define AML_UART_BAUD_XTAL		BIT(24)
 
 #define AML_UART_PORT_NUM		12
 #define AML_UART_PORT_OFFSET		6
@@ -76,6 +75,11 @@
 #define AML_UART_POLL_USEC		5
 #define AML_UART_TIMEOUT_USEC		10000
 
+struct meson_uart_data {
+	struct clk	*baud_clk;
+	bool		use_xtal_clk;
+};
+
 static struct uart_driver meson_uart_driver;
 
 static struct uart_port *meson_ports[AML_UART_PORT_NUM];
@@ -293,19 +297,17 @@ static int meson_uart_startup(struct uart_port *port)
 
 static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
 {
+	struct meson_uart_data *private_data = port->private_data;
 	u32 val;
 
 	while (!meson_uart_tx_empty(port))
 		cpu_relax();
 
-	if (port->uartclk == 24000000) {
-		val = ((port->uartclk / 3) / baud) - 1;
-		val |= AML_UART_BAUD_XTAL;
-	} else {
-		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
-	}
+	val = readl(port->membase + AML_UART_REG5);
 	val |= AML_UART_BAUD_USE;
 	writel(val, port->membase + AML_UART_REG5);
+
+	clk_set_rate(private_data->baud_clk, baud);
 }
 
 static void meson_uart_set_termios(struct uart_port *port,
@@ -395,11 +397,20 @@ static int meson_uart_verify_port(struct uart_port *port,
 
 static void meson_uart_release_port(struct uart_port *port)
 {
-	/* nothing to do */
+	struct meson_uart_data *private_data = port->private_data;
+
+	clk_disable_unprepare(private_data->baud_clk);
 }
 
 static int meson_uart_request_port(struct uart_port *port)
 {
+	struct meson_uart_data *private_data = port->private_data;
+	int ret;
+
+	ret = clk_prepare_enable(private_data->baud_clk);
+	if (ret)
+		return ret;
+
 	return 0;
 }
 
@@ -629,57 +640,105 @@ static struct uart_driver meson_uart_driver = {
 	.cons		= MESON_SERIAL_CONSOLE,
 };
 
-static inline struct clk *meson_uart_probe_clock(struct device *dev,
-						 const char *id)
-{
-	struct clk *clk = NULL;
-	int ret;
-
-	clk = devm_clk_get(dev, id);
-	if (IS_ERR(clk))
-		return clk;
-
-	ret = clk_prepare_enable(clk);
-	if (ret) {
-		dev_err(dev, "couldn't enable clk\n");
-		return ERR_PTR(ret);
-	}
-
-	devm_add_action_or_reset(dev,
-			(void(*)(void *))clk_disable_unprepare,
-			clk);
-
-	return clk;
-}
+static struct clk_div_table xtal_div_table[] = {
+	{0, 3},
+	{1, 1},
+	{2, 2},
+	{3, 2},
+};
 
-static int meson_uart_probe_clocks(struct platform_device *pdev,
-				   struct uart_port *port)
+static int meson_uart_probe_clocks(struct uart_port *port)
 {
-	struct clk *clk_xtal = NULL;
-	struct clk *clk_pclk = NULL;
-	struct clk *clk_baud = NULL;
+	struct meson_uart_data *private_data = port->private_data;
+	struct clk *clk_baud, *clk_xtal;
+	struct clk_hw *hw;
+	char clk_name[32];
+	struct clk_parent_data use_xtal_mux_parents[2] = {
+		{ .index = -1, },
+		{ .index = -1, },
+	};
 
-	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
-	if (IS_ERR(clk_pclk))
-		return PTR_ERR(clk_pclk);
+	clk_baud = devm_clk_get(port->dev, "baud");
+	if (IS_ERR(clk_baud)) {
+		dev_err(port->dev, "Failed to get the 'baud' clock\n");
+		return PTR_ERR(clk_baud);
+	}
 
-	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
+	clk_xtal = devm_clk_get(port->dev, "xtal");
 	if (IS_ERR(clk_xtal))
-		return PTR_ERR(clk_xtal);
-
-	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
-	if (IS_ERR(clk_baud))
-		return PTR_ERR(clk_baud);
+		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
+				     "Failed to get the 'xtal' clock\n");
+
+	if (private_data->use_xtal_clk) {
+		snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
+			 "xtal_div");
+		hw = devm_clk_hw_register_divider_table(port->dev,
+							clk_name,
+							__clk_get_name(clk_baud),
+							CLK_SET_RATE_NO_REPARENT,
+							port->membase + AML_UART_REG5,
+							26, 2,
+							CLK_DIVIDER_READ_ONLY,
+							xtal_div_table, NULL);
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		use_xtal_mux_parents[1].hw = hw;
+	} else {
+		snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
+			 "clk81_div4");
+		hw = devm_clk_hw_register_fixed_factor(port->dev,
+						       clk_name,
+						       __clk_get_name(clk_baud),
+						       CLK_SET_RATE_NO_REPARENT,
+						       1, 4);
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		use_xtal_mux_parents[0].hw = hw;
+	}
 
-	port->uartclk = clk_get_rate(clk_baud);
+	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
+		 "use_xtal");
+	hw = __devm_clk_hw_register_mux(port->dev, NULL,
+					clk_name,
+					ARRAY_SIZE(use_xtal_mux_parents),
+					NULL, NULL,
+					use_xtal_mux_parents,
+					CLK_SET_RATE_PARENT,
+					port->membase + AML_UART_REG5,
+					24, 0x1,
+					CLK_MUX_READ_ONLY,
+					NULL, NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	port->uartclk = clk_hw_get_rate(hw);
+
+	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
+		 "baud_div");
+	hw = devm_clk_hw_register_divider(port->dev,
+					  clk_name,
+					  clk_hw_get_name(hw),
+					  CLK_SET_RATE_PARENT,
+					  port->membase + AML_UART_REG5,
+					  0, 23,
+					  CLK_DIVIDER_ROUND_CLOSEST,
+					  NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	private_data->baud_clk = hw->clk;
 
 	return 0;
 }
 
 static int meson_uart_probe(struct platform_device *pdev)
 {
+	struct meson_uart_data *private_data;
 	struct resource *res_mem;
 	struct uart_port *port;
+	struct clk *pclk;
 	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
 	int ret = 0;
 	int irq;
@@ -705,6 +764,15 @@ static int meson_uart_probe(struct platform_device *pdev)
 	if (!res_mem)
 		return -ENODEV;
 
+	pclk = devm_clk_get(&pdev->dev, "pclk");
+	if (IS_ERR(pclk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(pclk),
+				     "Failed to get the 'pclk' clock\n");
+
+	ret = clk_prepare_enable(pclk);
+	if (ret)
+		return ret;
+
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0)
 		return irq;
@@ -724,9 +792,13 @@ static int meson_uart_probe(struct platform_device *pdev)
 	if (IS_ERR(port->membase))
 		return PTR_ERR(port->membase);
 
-	ret = meson_uart_probe_clocks(pdev, port);
-	if (ret)
-		return ret;
+	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
+				    GFP_KERNEL);
+	if (!private_data)
+		return -ENOMEM;
+
+	if (device_get_match_data(&pdev->dev))
+		private_data->use_xtal_clk = true;
 
 	port->iotype = UPIO_MEM;
 	port->mapbase = res_mem->start;
@@ -740,6 +812,11 @@ static int meson_uart_probe(struct platform_device *pdev)
 	port->x_char = 0;
 	port->ops = &meson_uart_ops;
 	port->fifosize = fifosize;
+	port->private_data = private_data;
+
+	ret = meson_uart_probe_clocks(port);
+	if (ret)
+		return ret;
 
 	meson_ports[pdev->id] = port;
 	platform_set_drvdata(pdev, port);
@@ -766,10 +843,22 @@ static int meson_uart_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id meson_uart_dt_match[] = {
-	{ .compatible = "amlogic,meson6-uart" },
-	{ .compatible = "amlogic,meson8-uart" },
-	{ .compatible = "amlogic,meson8b-uart" },
-	{ .compatible = "amlogic,meson-gx-uart" },
+	{
+		.compatible = "amlogic,meson6-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson8-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson8b-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson-gx-uart",
+		.data = (void *)true,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 17 19:09:10 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 18 Jan 2022 11:09:10 +0800
Subject: [PATCH V6 4/5] tty: serial: meson: Make some bit of the REG5 register
 writable
In-Reply-To: <20220118030911.12815-1-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
Message-ID: <20220118030911.12815-5-yu.tu@amlogic.com>

The UART_REG5 register defaults to 0. The console port is set in
ROMCODE. But other UART ports default to 0, so make bit24 and
bit[26,27] writable so that the UART can choose a more
appropriate clock.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 92fa91c825e6..4e7b2b38ab0a 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -678,7 +678,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
 							CLK_SET_RATE_NO_REPARENT,
 							port->membase + AML_UART_REG5,
 							26, 2,
-							CLK_DIVIDER_READ_ONLY,
+							CLK_DIVIDER_ROUND_CLOSEST,
 							xtal_div_table, NULL);
 		if (IS_ERR(hw))
 			return PTR_ERR(hw);
@@ -708,7 +708,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
 					CLK_SET_RATE_PARENT,
 					port->membase + AML_UART_REG5,
 					24, 0x1,
-					CLK_MUX_READ_ONLY,
+					CLK_MUX_ROUND_CLOSEST,
 					NULL, NULL);
 	if (IS_ERR(hw))
 		return PTR_ERR(hw);
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 17 19:09:11 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 18 Jan 2022 11:09:11 +0800
Subject: [PATCH V6 5/5] tty: serial: meson: Added S4 SOC compatibility
In-Reply-To: <20220118030911.12815-1-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
Message-ID: <20220118030911.12815-6-yu.tu@amlogic.com>

Make UART driver compatible with S4 SOC UART.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 4e7b2b38ab0a..af95a4676d28 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -859,6 +859,10 @@ static const struct of_device_id meson_uart_dt_match[] = {
 		.compatible = "amlogic,meson-gx-uart",
 		.data = (void *)true,
 	},
+	{
+		.compatible = "amlogic,meson-s4-uart",
+		.data = (void *)true,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
-- 
2.33.1



From andrzej.hajda at intel.com  Tue Jan 18 01:24:52 2022
From: andrzej.hajda at intel.com (Andrzej Hajda)
Date: Tue, 18 Jan 2022 10:24:52 +0100
Subject: [PATCH] phy: dphy: Correct clk_pre parameter
In-Reply-To: <20220118025918.1444288-1-victor.liu@nxp.com>
References: <20220118025918.1444288-1-victor.liu@nxp.com>
Message-ID: <96cd66cd-8e90-5f68-6009-f48015400aae@intel.com>

Hi,

On 18.01.2022 03:59, Liu Ying wrote:
> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> mentions that it should be in UI.  However, the dphy core driver wrongly
> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> is '8 UI', instead of 8.
>
> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
> value according to the D-PHY specification.
>
> I'm assuming that all impacted custom drivers shall program values in
> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
> specification mentions that the frequency of TxByteClkHS is exactly 1/8
> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
> custom driver code is changed to program those values as
> DIV_ROUND_UP(cfg->clk_pre, MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD), then.
>
> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
> as I don't have the hardwares.
>
> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Robert Foss <robert.foss at linaro.org>
> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> Cc: Jonas Karlman <jonas at kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> Cc: David Airlie <airlied at linux.ie>
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Cc: Vinod Koul <vkoul at kernel.org>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: Heiko Stuebner <heiko at sntech.de>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Guido G?nther <agx at sigxcpu.org>
> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
> Signed-off-by: Liu Ying <victor.liu at nxp.com>
> ---
>   drivers/gpu/drm/bridge/nwl-dsi.c                 | 7 ++-----
>   drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    | 3 ++-
>   drivers/phy/phy-core-mipi-dphy.c                 | 4 ++--
>   drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c | 3 ++-
>   include/linux/phy/phy-mipi-dphy.h                | 4 +++-
>   5 files changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
> index a7389a0facfb..f1fdcdf763ee 100644
> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> @@ -196,12 +196,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
>   /*
>    * ui2bc - UI time periods to byte clock cycles
>    */
> -static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
> +static u32 ui2bc(struct nwl_dsi *dsi, unsigned int ui)
>   {
> -	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> -
> -	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
> -				  dsi->mode.clock * 1000 * bpp);
> +	return DIV_ROUND_UP(ui, MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD);


I have some doubts here. According to specs:

 ??? UI - duration of any HS state on the Clock Lane,

 ??? TxByteClkHS - exactly 1/8 the High-Speed(HS) bit rate

I'd like to emphasize "BIT RATE" above (not clock rate).

In such case I would expect that ui2bc would take into account number of 
lanes:

byte clock cycles = div_round_up(ui * dsi->lanes, 8)

So in case of one lane we need 8 ticks to get byte, and in case of 4 
lanes 2 ticks are enough.

Am I correct, or I've missed sth?


>   }
>   
>   /*
> diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> index cd2332bf0e31..8a818cdb7606 100644
> --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> @@ -250,7 +250,8 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
>   		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
>   		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
>   	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
> -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
> +		     DIV_ROUND_UP(priv->config.clk_pre,
> +				  MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD));
>   
>   	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
>   		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
> diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
> index 288c9c67aa74..ccb4045685cd 100644
> --- a/drivers/phy/phy-core-mipi-dphy.c
> +++ b/drivers/phy/phy-core-mipi-dphy.c
> @@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
>   
>   	cfg->clk_miss = 0;
>   	cfg->clk_post = 60000 + 52 * ui;
> -	cfg->clk_pre = 8000;
> +	cfg->clk_pre = 8;
>   	cfg->clk_prepare = 38000;
>   	cfg->clk_settle = 95000;
>   	cfg->clk_term_en = 0;
> @@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
>   	if (cfg->clk_post < (60000 + 52 * ui))
>   		return -EINVAL;
>   
> -	if (cfg->clk_pre < 8000)
> +	if (cfg->clk_pre < 8)
>   		return -EINVAL;
>   
>   	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> index 347dc79a18c1..67b0a17be7e3 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> @@ -364,7 +364,8 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
>   	 * The value of counter for HS Tclk-pre
>   	 * Tclk-pre = Tpin_txbyteclkhs * value
>   	 */
> -	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
> +	clk_pre = DIV_ROUND_UP(cfg->clk_pre,
> +			       MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD);
>   
>   	/*
>   	 * The value of counter for HS Tlpx Time
> diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
> index a877ffee845d..ab1f736fbcd3 100644
> --- a/include/linux/phy/phy-mipi-dphy.h
> +++ b/include/linux/phy/phy-mipi-dphy.h
> @@ -6,6 +6,8 @@
>   #ifndef __PHY_MIPI_DPHY_H_
>   #define __PHY_MIPI_DPHY_H_
>   
> +#define MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD	8


Do we need to define it? I guess it is just BITS_PER_BYTE.


Regards

Andrzej


> +
>   /**
>    * struct phy_configure_opts_mipi_dphy - MIPI D-PHY configuration set
>    *
> @@ -42,7 +44,7 @@ struct phy_configure_opts_mipi_dphy {
>   	 * the transmitter prior to any associated Data Lane beginning
>   	 * the transition from LP to HS mode.
>   	 *
> -	 * Minimum value: 8 UI
> +	 * Minimum value: 8
>   	 */
>   	unsigned int		clk_pre;
>   


From jirislaby at kernel.org  Tue Jan 18 01:35:51 2022
From: jirislaby at kernel.org (Jiri Slaby)
Date: Tue, 18 Jan 2022 10:35:51 +0100
Subject: [PATCH V6 1/5] tty: serial: meson: Move request the register
 region to probe
In-Reply-To: <20220118030911.12815-2-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <20220118030911.12815-2-yu.tu@amlogic.com>
Message-ID: <a7267804-1400-c63d-50a0-72423f141317@kernel.org>

On 18. 01. 22, 4:09, Yu Tu wrote:
> This simplifies resetting the UART controller during probe
> and will make it easier to integrate the common clock code
> which will require the registers at probe time as well.
> 
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>

Reviewed-by: Jiri Slaby <jirislaby at kernel.org>

thanks,
-- 
js
suse labs


From jirislaby at kernel.org  Tue Jan 18 01:36:10 2022
From: jirislaby at kernel.org (Jiri Slaby)
Date: Tue, 18 Jan 2022 10:36:10 +0100
Subject: [PATCH V6 2/5] tty: serial: meson: Use devm_ioremap_resource to
 get register mapped memory
In-Reply-To: <20220118030911.12815-3-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <20220118030911.12815-3-yu.tu@amlogic.com>
Message-ID: <97dfc8b2-fded-01df-44e9-b24988a76d54@kernel.org>

On 18. 01. 22, 4:09, Yu Tu wrote:
> Replace devm_request_mem_region and devm_ioremap with
> devm_ioremap_resource to make the code cleaner.
> 
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>

Reviewed-by: Jiri Slaby <jirislaby at kernel.org>

thanks,
-- 
js


From jirislaby at kernel.org  Tue Jan 18 01:39:25 2022
From: jirislaby at kernel.org (Jiri Slaby)
Date: Tue, 18 Jan 2022 10:39:25 +0100
Subject: [PATCH V6 3/5] tty: serial: meson: Describes the calculation of
 the UART baud rate clock using a clock frame
In-Reply-To: <20220118030911.12815-4-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <20220118030911.12815-4-yu.tu@amlogic.com>
Message-ID: <7a8016ba-730b-f599-2032-31cf03990a55@kernel.org>

On 18. 01. 22, 4:09, Yu Tu wrote:
> Using the common Clock code to describe the UART baud rate clock
> makes it easier for the UART driver to be compatible with the
> baud rate requirements of the UART IP on different meson chips.
...
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
...
> @@ -629,57 +640,105 @@ static struct uart_driver meson_uart_driver = {
>   	.cons		= MESON_SERIAL_CONSOLE,
>   };
>   
> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
> -						 const char *id)
> -{
> -	struct clk *clk = NULL;
> -	int ret;
> -
> -	clk = devm_clk_get(dev, id);
> -	if (IS_ERR(clk))
> -		return clk;
> -
> -	ret = clk_prepare_enable(clk);
> -	if (ret) {
> -		dev_err(dev, "couldn't enable clk\n");
> -		return ERR_PTR(ret);
> -	}
> -
> -	devm_add_action_or_reset(dev,
> -			(void(*)(void *))clk_disable_unprepare,
> -			clk);
> -
> -	return clk;
> -}
> +static struct clk_div_table xtal_div_table[] = {

This can be const, right?

> +	{0, 3},
> +	{1, 1},
> +	{2, 2},
> +	{3, 2},

Not sure if you didn't remove too much whitespace. I think it should be 
like: "{ 0, 3 },". But I actually don't care, it's a minor thing.

I cannot comment on the rest (clk and OF part) as my knowledge is pretty 
limited there. Leaving up to others.

thanks,
-- 
js
suse labs


From victor.liu at nxp.com  Tue Jan 18 02:14:47 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Tue, 18 Jan 2022 18:14:47 +0800
Subject: [PATCH] phy: dphy: Correct clk_pre parameter
In-Reply-To: <96cd66cd-8e90-5f68-6009-f48015400aae@intel.com>
References: <20220118025918.1444288-1-victor.liu@nxp.com>
 <96cd66cd-8e90-5f68-6009-f48015400aae@intel.com>
Message-ID: <1d945988f774732c204f9dabdb8fa5795f0eca24.camel@nxp.com>

Hi Andrzej,

Thanks for your review.

On Tue, 2022-01-18 at 10:24 +0100, Andrzej Hajda wrote:
> Hi,
> 
> On 18.01.2022 03:59, Liu Ying wrote:
> > The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> > parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> > kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> > mentions that it should be in UI.  However, the dphy core driver wrongly
> > sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> > And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> > is '8 UI', instead of 8.
> > 
> > So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
> > member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
> > value according to the D-PHY specification.
> > 
> > I'm assuming that all impacted custom drivers shall program values in
> > TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
> > specification mentions that the frequency of TxByteClkHS is exactly 1/8
> > the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
> > custom driver code is changed to program those values as
> > DIV_ROUND_UP(cfg->clk_pre, MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD), then.
> > 
> > Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
> > Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
> > as I don't have the hardwares.
> > 
> > Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
> > Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> > Cc: Neil Armstrong <narmstrong at baylibre.com>
> > Cc: Robert Foss <robert.foss at linaro.org>
> > Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> > Cc: Jonas Karlman <jonas at kwiboo.se>
> > Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> > Cc: David Airlie <airlied at linux.ie>
> > Cc: Daniel Vetter <daniel at ffwll.ch>
> > Cc: Kishon Vijay Abraham I <kishon at ti.com>
> > Cc: Vinod Koul <vkoul at kernel.org>
> > Cc: Kevin Hilman <khilman at baylibre.com>
> > Cc: Jerome Brunet <jbrunet at baylibre.com>
> > Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> > Cc: Heiko Stuebner <heiko at sntech.de>
> > Cc: Maxime Ripard <mripard at kernel.org>
> > Cc: Guido G?nther <agx at sigxcpu.org>
> > Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
> > Signed-off-by: Liu Ying <victor.liu at nxp.com>
> > ---
> >   drivers/gpu/drm/bridge/nwl-dsi.c                 | 7 ++-----
> >   drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    | 3 ++-
> >   drivers/phy/phy-core-mipi-dphy.c                 | 4 ++--
> >   drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c | 3 ++-
> >   include/linux/phy/phy-mipi-dphy.h                | 4 +++-
> >   5 files changed, 11 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
> > index a7389a0facfb..f1fdcdf763ee 100644
> > --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> > +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> > @@ -196,12 +196,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
> >   /*
> >    * ui2bc - UI time periods to byte clock cycles
> >    */
> > -static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
> > +static u32 ui2bc(struct nwl_dsi *dsi, unsigned int ui)
> >   {
> > -	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> > -
> > -	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
> > -				  dsi->mode.clock * 1000 * bpp);
> > +	return DIV_ROUND_UP(ui, MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD);
> 
> I have some doubts here. According to specs:
> 
>      UI - duration of any HS state on the Clock Lane,
> 
>      TxByteClkHS - exactly 1/8 the High-Speed(HS) bit rate
> 
> I'd like to emphasize "BIT RATE" above (not clock rate).
> 
> In such case I would expect that ui2bc would take into account number of 
> lanes:
> 
> byte clock cycles = div_round_up(ui * dsi->lanes, 8)
> 
> So in case of one lane we need 8 ticks to get byte, and in case of 4 
> lanes 2 ticks are enough.
> 
> Am I correct, or I've missed sth?

Sorry, I think you are wrong.

The spec also mentions that it is recommended that all transmitting
Data Lane Modules share one TxByteClkHS signal.  So, usually,
TxByteClkHS has nothing to do with data lane number, but only UI - one
bit period is HS state.  I think the NWL DSI follows the recommended
implementation.

'Table 20 HS Transmitter AC Specifications' in the spec notes
that Applicable when supporting maximum HS bit rates ? 1 Gbps (UI ? 1
ns).  This hints that HS bit rate is 1/UI. 

> 
> 
> >   }
> >   
> >   /*
> > diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> > index cd2332bf0e31..8a818cdb7606 100644
> > --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> > +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> > @@ -250,7 +250,8 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
> >   		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
> >   		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
> >   	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
> > -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
> > +		     DIV_ROUND_UP(priv->config.clk_pre,
> > +				  MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD));
> >   
> >   	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
> >   		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
> > diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
> > index 288c9c67aa74..ccb4045685cd 100644
> > --- a/drivers/phy/phy-core-mipi-dphy.c
> > +++ b/drivers/phy/phy-core-mipi-dphy.c
> > @@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
> >   
> >   	cfg->clk_miss = 0;
> >   	cfg->clk_post = 60000 + 52 * ui;
> > -	cfg->clk_pre = 8000;
> > +	cfg->clk_pre = 8;
> >   	cfg->clk_prepare = 38000;
> >   	cfg->clk_settle = 95000;
> >   	cfg->clk_term_en = 0;
> > @@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
> >   	if (cfg->clk_post < (60000 + 52 * ui))
> >   		return -EINVAL;
> >   
> > -	if (cfg->clk_pre < 8000)
> > +	if (cfg->clk_pre < 8)
> >   		return -EINVAL;
> >   
> >   	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
> > diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> > index 347dc79a18c1..67b0a17be7e3 100644
> > --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> > +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> > @@ -364,7 +364,8 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
> >   	 * The value of counter for HS Tclk-pre
> >   	 * Tclk-pre = Tpin_txbyteclkhs * value
> >   	 */
> > -	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
> > +	clk_pre = DIV_ROUND_UP(cfg->clk_pre,
> > +			       MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD);
> >   
> >   	/*
> >   	 * The value of counter for HS Tlpx Time
> > diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
> > index a877ffee845d..ab1f736fbcd3 100644
> > --- a/include/linux/phy/phy-mipi-dphy.h
> > +++ b/include/linux/phy/phy-mipi-dphy.h
> > @@ -6,6 +6,8 @@
> >   #ifndef __PHY_MIPI_DPHY_H_
> >   #define __PHY_MIPI_DPHY_H_
> >   
> > +#define MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD	8
> 
> Do we need to define it? I guess it is just BITS_PER_BYTE.

Either way would do I think.  I'll wait for a while to see if others
have comment here.  If no, I may switch to use BITS_PER_BYTE in v2.

Regards,
Liu Ying

> 
> 
> Regards
> 
> Andrzej
> 
> 
> > +
> >   /**
> >    * struct phy_configure_opts_mipi_dphy - MIPI D-PHY configuration set
> >    *
> > @@ -42,7 +44,7 @@ struct phy_configure_opts_mipi_dphy {
> >   	 * the transmitter prior to any associated Data Lane beginning
> >   	 * the transition from LP to HS mode.
> >   	 *
> > -	 * Minimum value: 8 UI
> > +	 * Minimum value: 8
> >   	 */
> >   	unsigned int		clk_pre;
> >   



From andrzej.hajda at intel.com  Tue Jan 18 02:44:20 2022
From: andrzej.hajda at intel.com (Andrzej Hajda)
Date: Tue, 18 Jan 2022 11:44:20 +0100
Subject: [PATCH] phy: dphy: Correct clk_pre parameter
In-Reply-To: <1d945988f774732c204f9dabdb8fa5795f0eca24.camel@nxp.com>
References: <20220118025918.1444288-1-victor.liu@nxp.com>
 <96cd66cd-8e90-5f68-6009-f48015400aae@intel.com>
 <1d945988f774732c204f9dabdb8fa5795f0eca24.camel@nxp.com>
Message-ID: <51eda14f-5c37-c3af-84de-b591b8762a63@intel.com>


On 18.01.2022 11:14, Liu Ying wrote:
> Hi Andrzej,
>
> Thanks for your review.
>
> On Tue, 2022-01-18 at 10:24 +0100, Andrzej Hajda wrote:
>> Hi,
>>
>> On 18.01.2022 03:59, Liu Ying wrote:
>>> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
>>> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
>>> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
>>> mentions that it should be in UI.  However, the dphy core driver wrongly
>>> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
>>> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
>>> is '8 UI', instead of 8.
>>>
>>> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
>>> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
>>> value according to the D-PHY specification.
>>>
>>> I'm assuming that all impacted custom drivers shall program values in
>>> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
>>> specification mentions that the frequency of TxByteClkHS is exactly 1/8
>>> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
>>> custom driver code is changed to program those values as
>>> DIV_ROUND_UP(cfg->clk_pre, MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD), then.
>>>
>>> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
>>> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
>>> as I don't have the hardwares.
>>>
>>> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
>>> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
>>> Cc: Neil Armstrong <narmstrong at baylibre.com>
>>> Cc: Robert Foss <robert.foss at linaro.org>
>>> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
>>> Cc: Jonas Karlman <jonas at kwiboo.se>
>>> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
>>> Cc: David Airlie <airlied at linux.ie>
>>> Cc: Daniel Vetter <daniel at ffwll.ch>
>>> Cc: Kishon Vijay Abraham I <kishon at ti.com>
>>> Cc: Vinod Koul <vkoul at kernel.org>
>>> Cc: Kevin Hilman <khilman at baylibre.com>
>>> Cc: Jerome Brunet <jbrunet at baylibre.com>
>>> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
>>> Cc: Heiko Stuebner <heiko at sntech.de>
>>> Cc: Maxime Ripard <mripard at kernel.org>
>>> Cc: Guido G?nther <agx at sigxcpu.org>
>>> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
>>> Signed-off-by: Liu Ying <victor.liu at nxp.com>
>>> ---
>>>    drivers/gpu/drm/bridge/nwl-dsi.c                 | 7 ++-----
>>>    drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    | 3 ++-
>>>    drivers/phy/phy-core-mipi-dphy.c                 | 4 ++--
>>>    drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c | 3 ++-
>>>    include/linux/phy/phy-mipi-dphy.h                | 4 +++-
>>>    5 files changed, 11 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
>>> index a7389a0facfb..f1fdcdf763ee 100644
>>> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
>>> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
>>> @@ -196,12 +196,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
>>>    /*
>>>     * ui2bc - UI time periods to byte clock cycles
>>>     */
>>> -static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
>>> +static u32 ui2bc(struct nwl_dsi *dsi, unsigned int ui)
>>>    {
>>> -	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
>>> -
>>> -	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
>>> -				  dsi->mode.clock * 1000 * bpp);
>>> +	return DIV_ROUND_UP(ui, MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD);
>> I have some doubts here. According to specs:
>>
>>       UI - duration of any HS state on the Clock Lane,
>>
>>       TxByteClkHS - exactly 1/8 the High-Speed(HS) bit rate
>>
>> I'd like to emphasize "BIT RATE" above (not clock rate).
>>
>> In such case I would expect that ui2bc would take into account number of
>> lanes:
>>
>> byte clock cycles = div_round_up(ui * dsi->lanes, 8)
>>
>> So in case of one lane we need 8 ticks to get byte, and in case of 4
>> lanes 2 ticks are enough.
>>
>> Am I correct, or I've missed sth?
> Sorry, I think you are wrong.
>
> The spec also mentions that it is recommended that all transmitting
> Data Lane Modules share one TxByteClkHS signal.  So, usually,
> TxByteClkHS has nothing to do with data lane number, but only UI - one
> bit period is HS state.  I think the NWL DSI follows the recommended
> implementation.
>
> 'Table 20 HS Transmitter AC Specifications' in the spec notes
> that Applicable when supporting maximum HS bit rates ? 1 Gbps (UI ? 1
> ns).  This hints that HS bit rate is 1/UI.


OK, apparently "bit rate" in case of PHYs usually means "bit rate per lane".


Regards

Andrzej




From sboyd at kernel.org  Tue Jan 18 18:22:19 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 18 Jan 2022 18:22:19 -0800
Subject: [PATCH v9 4/4] clk: meson: add sub MMC clock controller driver
In-Reply-To: <fe77fd6b-788f-1694-f260-f95e54cf4ef3@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-5-liang.yang@amlogic.com>
 <20220113213513.9819AC36AEA@smtp.kernel.org>
 <09ff9044-9abc-d1ad-26c1-5e6ece56d30c@amlogic.com>
 <20220114230130.35EAAC36AE7@smtp.kernel.org>
 <fe77fd6b-788f-1694-f260-f95e54cf4ef3@amlogic.com>
Message-ID: <20220119022221.3AF83C340E0@smtp.kernel.org>

Quoting Liang Yang (2022-01-16 22:24:28)
> 
> 
> On 2022/1/15 7:01, Stephen Boyd wrote:
> > [ EXTERNAL EMAIL ]
> > 
> > Quoting Liang Yang (2022-01-13 21:14:46)
> >> On 2022/1/14 5:35, Stephen Boyd wrote:
> >>> Quoting Liang Yang (2022-01-13 03:57:45)
> >>>> diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c
> >>>> new file mode 100644
> >>>> index 000000000000..f53977f61390
> >>>> --- /dev/null
> >>>> +++ b/drivers/clk/meson/mmc-clkc.c
> >>>> @@ -0,0 +1,300 @@
> > [..]
> >>>> +
> >>>> +static int mmc_clkc_probe(struct platform_device *pdev)
> >>>> +{
> >>>> +       struct clk_hw_onecell_data *onecell_data;
> >>>> +       struct device *dev = &pdev->dev;
> >>>> +       struct mmc_clkc_data *data;
> >>>> +       struct regmap *map;
> >>>> +       struct clk_regmap *clk, *core;
> >>>> +       struct meson_sclk_div_data *div_data;
> >>>> +
> >>>> +       /*cast to drop the const in match->data*/
> >>>
> >>> Space after *, also why do we need to cast away const? The user of this
> >>> pointer passes it all the way down to mmc_clkc_register_clk() which
> >>> could take the data as const void pointer and decide to cast away const
> >>> there.
> >>
> >> if use 'const' here, it  will report a warning:
> >> drivers/clk/meson/mmc-clkc.c:224:7: error: assignment discards ?const?
> >> qualifier from pointer targe
> >> t type [-Werror=discarded-qualifiers]
> >>
> >>     data = (const struct mmc_clkc_data *)of_device_get_match_data(dev);
> > 
> > Of course. The type declaration up above needs const added to it.The parm of mmc_clkc_register_clk_with_parent(...., void *data) does not 
> have 'const', so make the type declaration cause a further 'const' cast 
> warning. Could i copy these infos just like below:

Why can't you push const down to the function that really cares to
remove const?


From victor.liu at nxp.com  Tue Jan 18 18:37:14 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Wed, 19 Jan 2022 10:37:14 +0800
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
Message-ID: <20220119023714.1498508-1-victor.liu@nxp.com>

The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
mentions that it should be in UI.  However, the dphy core driver wrongly
sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
is '8 UI', instead of 8.

So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
value according to the D-PHY specification.

I'm assuming that all impacted custom drivers shall program values in
TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
specification mentions that the frequency of TxByteClkHS is exactly 1/8
the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
custom driver code is changed to program those values as
DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.

Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
as I don't have the hardwares.

Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
Cc: Andrzej Hajda <andrzej.hajda at intel.com>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Robert Foss <robert.foss at linaro.org>
Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
Cc: Jonas Karlman <jonas at kwiboo.se>
Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
Cc: David Airlie <airlied at linux.ie>
Cc: Daniel Vetter <daniel at ffwll.ch>
Cc: Kishon Vijay Abraham I <kishon at ti.com>
Cc: Vinod Koul <vkoul at kernel.org>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: Heiko Stuebner <heiko at sntech.de>
Cc: Maxime Ripard <mripard at kernel.org>
Cc: Guido G?nther <agx at sigxcpu.org>
Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v1->v2:
* Use BITS_PER_BYTE macro. (Andrzej)
* Drop dsi argument from ui2bc() in nwl-dsi.c.

 drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
 drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
 drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
 drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
 include/linux/phy/phy-mipi-dphy.h                |  2 +-
 5 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index a7389a0facfb..af07eeb47ca0 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/math64.h>
@@ -196,12 +197,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
 /*
  * ui2bc - UI time periods to byte clock cycles
  */
-static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
+static u32 ui2bc(unsigned int ui)
 {
-	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
-
-	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
-				  dsi->mode.clock * 1000 * bpp);
+	return DIV_ROUND_UP(ui, BITS_PER_BYTE);
 }
 
 /*
@@ -232,12 +230,12 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi)
 	}
 
 	/* values in byte clock cycles */
-	cycles = ui2bc(dsi, cfg->clk_pre);
+	cycles = ui2bc(cfg->clk_pre);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
 	nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
 	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
-	cycles += ui2bc(dsi, cfg->clk_pre);
+	cycles += ui2bc(cfg->clk_pre);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
 	nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
 	cycles = ps2bc(dsi, cfg->hs_exit);
diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
index cd2332bf0e31..fdbd64c03e12 100644
--- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
+++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
@@ -9,6 +9,7 @@
 
 #include <linux/bitfield.h>
 #include <linux/bitops.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/io.h>
@@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
 		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
 		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
 	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
-		     DIV_ROUND_UP(priv->config.clk_pre, temp));
+		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
 
 	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
 		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
index 288c9c67aa74..ccb4045685cd 100644
--- a/drivers/phy/phy-core-mipi-dphy.c
+++ b/drivers/phy/phy-core-mipi-dphy.c
@@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
 
 	cfg->clk_miss = 0;
 	cfg->clk_post = 60000 + 52 * ui;
-	cfg->clk_pre = 8000;
+	cfg->clk_pre = 8;
 	cfg->clk_prepare = 38000;
 	cfg->clk_settle = 95000;
 	cfg->clk_term_en = 0;
@@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
 	if (cfg->clk_post < (60000 + 52 * ui))
 		return -EINVAL;
 
-	if (cfg->clk_pre < 8000)
+	if (cfg->clk_pre < 8)
 		return -EINVAL;
 
 	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
index 347dc79a18c1..630e01b5c19b 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
@@ -5,6 +5,7 @@
  * Author: Wyon Bi <bivvy.bi at rock-chips.com>
  */
 
+#include <linux/bits.h>
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/iopoll.h>
@@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
 	 * The value of counter for HS Tclk-pre
 	 * Tclk-pre = Tpin_txbyteclkhs * value
 	 */
-	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
+	clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);
 
 	/*
 	 * The value of counter for HS Tlpx Time
diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
index a877ffee845d..59a5e77ab409 100644
--- a/include/linux/phy/phy-mipi-dphy.h
+++ b/include/linux/phy/phy-mipi-dphy.h
@@ -42,7 +42,7 @@ struct phy_configure_opts_mipi_dphy {
 	 * the transmitter prior to any associated Data Lane beginning
 	 * the transition from LP to HS mode.
 	 *
-	 * Minimum value: 8 UI
+	 * Minimum value: 8
 	 */
 	unsigned int		clk_pre;
 
-- 
2.25.1



From liang.yang at amlogic.com  Tue Jan 18 18:55:38 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Wed, 19 Jan 2022 10:55:38 +0800
Subject: [PATCH v9 4/4] clk: meson: add sub MMC clock controller driver
In-Reply-To: <20220119022221.3AF83C340E0@smtp.kernel.org>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-5-liang.yang@amlogic.com>
 <20220113213513.9819AC36AEA@smtp.kernel.org>
 <09ff9044-9abc-d1ad-26c1-5e6ece56d30c@amlogic.com>
 <20220114230130.35EAAC36AE7@smtp.kernel.org>
 <fe77fd6b-788f-1694-f260-f95e54cf4ef3@amlogic.com>
 <20220119022221.3AF83C340E0@smtp.kernel.org>
Message-ID: <f8f1c6c6-3805-6371-87ea-06fc14862625@amlogic.com>

Hi Stephen,

On 2022/1/19 10:22, Stephen Boyd wrote:
> [ EXTERNAL EMAIL ]
> 
> Quoting Liang Yang (2022-01-16 22:24:28)
>>
>>
>> On 2022/1/15 7:01, Stephen Boyd wrote:
>>> [ EXTERNAL EMAIL ]
>>>
>>> Quoting Liang Yang (2022-01-13 21:14:46)
>>>> On 2022/1/14 5:35, Stephen Boyd wrote:
>>>>> Quoting Liang Yang (2022-01-13 03:57:45)
>>>>>> diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c
>>>>>> new file mode 100644
>>>>>> index 000000000000..f53977f61390
>>>>>> --- /dev/null
>>>>>> +++ b/drivers/clk/meson/mmc-clkc.c
>>>>>> @@ -0,0 +1,300 @@
>>> [..]
>>>>>> +
>>>>>> +static int mmc_clkc_probe(struct platform_device *pdev)
>>>>>> +{
>>>>>> +       struct clk_hw_onecell_data *onecell_data;
>>>>>> +       struct device *dev = &pdev->dev;
>>>>>> +       struct mmc_clkc_data *data;
>>>>>> +       struct regmap *map;
>>>>>> +       struct clk_regmap *clk, *core;
>>>>>> +       struct meson_sclk_div_data *div_data;
>>>>>> +
>>>>>> +       /*cast to drop the const in match->data*/
>>>>>
>>>>> Space after *, also why do we need to cast away const? The user of this
>>>>> pointer passes it all the way down to mmc_clkc_register_clk() which
>>>>> could take the data as const void pointer and decide to cast away const
>>>>> there.
>>>>
>>>> if use 'const' here, it  will report a warning:
>>>> drivers/clk/meson/mmc-clkc.c:224:7: error: assignment discards ?const?
>>>> qualifier from pointer targe
>>>> t type [-Werror=discarded-qualifiers]
>>>>
>>>>      data = (const struct mmc_clkc_data *)of_device_get_match_data(dev);
>>>
>>> Of course. The type declaration up above needs const added to it.The parm of mmc_clkc_register_clk_with_parent(...., void *data) does not
>> have 'const', so make the type declaration cause a further 'const' cast
>> warning. Could i copy these infos just like below:
> 
> Why can't you push const down to the function that really cares to
> remove const?
em, it is really ok to me. i will fix it next version.
> 
> .


From yu.tu at amlogic.com  Tue Jan 18 22:00:44 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Wed, 19 Jan 2022 14:00:44 +0800
Subject: [PATCH V6 3/5] tty: serial: meson: Describes the calculation of
 the UART baud rate clock using a clock frame
In-Reply-To: <7a8016ba-730b-f599-2032-31cf03990a55@kernel.org>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <20220118030911.12815-4-yu.tu@amlogic.com>
 <7a8016ba-730b-f599-2032-31cf03990a55@kernel.org>
Message-ID: <21eea0cd-5bf1-dec6-a776-f417aefa5bda@amlogic.com>

Hi Jiri,
	Thank you very much for your patient reply.I learned a lot from your 
response.

On 2022/1/18 17:39, Jiri Slaby wrote:
> [ EXTERNAL EMAIL ]
> 
> On 18. 01. 22, 4:09, Yu Tu wrote:
>> Using the common Clock code to describe the UART baud rate clock
>> makes it easier for the UART driver to be compatible with the
>> baud rate requirements of the UART IP on different meson chips.
> ...
>> --- a/drivers/tty/serial/meson_uart.c
>> +++ b/drivers/tty/serial/meson_uart.c
> ...
>> @@ -629,57 +640,105 @@ static struct uart_driver meson_uart_driver = {
>> ????? .cons??????? = MESON_SERIAL_CONSOLE,
>> ? };
>> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>> -???????????????????????? const char *id)
>> -{
>> -??? struct clk *clk = NULL;
>> -??? int ret;
>> -
>> -??? clk = devm_clk_get(dev, id);
>> -??? if (IS_ERR(clk))
>> -??????? return clk;
>> -
>> -??? ret = clk_prepare_enable(clk);
>> -??? if (ret) {
>> -??????? dev_err(dev, "couldn't enable clk\n");
>> -??????? return ERR_PTR(ret);
>> -??? }
>> -
>> -??? devm_add_action_or_reset(dev,
>> -??????????? (void(*)(void *))clk_disable_unprepare,
>> -??????????? clk);
>> -
>> -??? return clk;
>> -}
>> +static struct clk_div_table xtal_div_table[] = {
> 
> This can be const, right?
You are right.
> 
>> +??? {0, 3},
>> +??? {1, 1},
>> +??? {2, 2},
>> +??? {3, 2},
> 
> Not sure if you didn't remove too much whitespace. I think it should be 
> like: "{ 0, 3 },". But I actually don't care, it's a minor thing.
> 
Ok, I will correct it if it needs to be changed.
> I cannot comment on the rest (clk and OF part) as my knowledge is pretty 
> limited there. Leaving up to others.
> 
Anyway, thanks for your reply.
> thanks,


From qianggui.song at amlogic.com  Tue Jan 18 23:08:05 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Wed, 19 Jan 2022 15:08:05 +0800
Subject: [PATCH v2 0/4] irqchip/meson-gpio: Add support for Meson-S4 SoC
Message-ID: <20220119070809.15563-1-qianggui.song@amlogic.com>

This patchset add support for GPIO interrupt controller of Meson-S4 SoC
Which has something different with current other meson chips. To
support the new chips, current gpio irqchip driver need to rework as
below:
1. support more than 8 gpio irq lines.
2. add a set trigger type callback function.

With above work, add support for S4 gpio irqchip

Changes since v1 at [0]:
- fix leaking issue
- fix some typos
- change implementation of new feature.

[0] https://lore.kernel.org/linux-amlogic/20220108084218.31877-1-qianggui.song at amlogic.com/

Qianggui Song (4):
  dt-bindings: interrupt-controller: New binding for Meson-S4 SoCs
  irqchip/meson-gpio: support more than 8 channels gpio irq line
  irqchip/meson-gpio: add select trigger type callback
  irqchip/meson-gpio: Add support for meson s4 SoCs

 .../amlogic,meson-gpio-intc.txt               |   1 +
 drivers/irqchip/irq-meson-gpio.c              | 105 ++++++++++++++++--
 2 files changed, 97 insertions(+), 9 deletions(-)

-- 
2.34.1



From qianggui.song at amlogic.com  Tue Jan 18 23:08:06 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Wed, 19 Jan 2022 15:08:06 +0800
Subject: [PATCH v2 1/4] dt-bindings: interrupt-controller: New binding for
 Meson-S4 SoCs
In-Reply-To: <20220119070809.15563-1-qianggui.song@amlogic.com>
References: <20220119070809.15563-1-qianggui.song@amlogic.com>
Message-ID: <20220119070809.15563-2-qianggui.song@amlogic.com>

Update dt-binding document for GPIO interrupt controller of Meson-S4 SoCs

Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 .../bindings/interrupt-controller/amlogic,meson-gpio-intc.txt    | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
index 23b18b92c558..bde63f8f090e 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
@@ -18,6 +18,7 @@ Required properties:
     "amlogic,meson-g12a-gpio-intc" for G12A SoCs (S905D2, S905X2, S905Y2)
     "amlogic,meson-sm1-gpio-intc" for SM1 SoCs (S905D3, S905X3, S905Y3)
     "amlogic,meson-a1-gpio-intc" for A1 SoCs (A113L)
+    "amlogic,meson-s4-gpio-intc" for S4 SoCs (S802X2, S905Y4, S805X2G, S905W2)
 - reg : Specifies base physical address and size of the registers.
 - interrupt-controller : Identifies the node as an interrupt controller.
 - #interrupt-cells : Specifies the number of cells needed to encode an
-- 
2.34.1



From qianggui.song at amlogic.com  Tue Jan 18 23:08:07 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Wed, 19 Jan 2022 15:08:07 +0800
Subject: [PATCH v2 2/4] irqchip/meson-gpio: support more than 8 channels gpio
 irq line
In-Reply-To: <20220119070809.15563-1-qianggui.song@amlogic.com>
References: <20220119070809.15563-1-qianggui.song@amlogic.com>
Message-ID: <20220119070809.15563-3-qianggui.song@amlogic.com>

Current meson gpio irqchip driver only support 8 channels for gpio irq
line, later chips may have more then 8 channels, so need to modify code
to support more.

Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 drivers/irqchip/irq-meson-gpio.c | 33 +++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
index d90ff0b92480..eefe15e1b3a6 100644
--- a/drivers/irqchip/irq-meson-gpio.c
+++ b/drivers/irqchip/irq-meson-gpio.c
@@ -16,7 +16,6 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 
-#define NUM_CHANNEL 8
 #define MAX_INPUT_MUX 256
 
 #define REG_EDGE_POL	0x00
@@ -60,6 +59,7 @@ struct irq_ctl_ops {
 
 struct meson_gpio_irq_params {
 	unsigned int nr_hwirq;
+	unsigned int nr_channels;
 	bool support_edge_both;
 	unsigned int edge_both_offset;
 	unsigned int edge_single_offset;
@@ -81,6 +81,7 @@ struct meson_gpio_irq_params {
 	.edge_single_offset = 0,				\
 	.pol_low_offset = 16,					\
 	.pin_sel_mask = 0xff,					\
+	.nr_channels = 8,					\
 
 #define INIT_MESON_A1_COMMON_DATA(irqs)				\
 	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
@@ -90,6 +91,7 @@ struct meson_gpio_irq_params {
 	.edge_single_offset = 8,				\
 	.pol_low_offset = 0,					\
 	.pin_sel_mask = 0x7f,					\
+	.nr_channels = 8,					\
 
 static const struct meson_gpio_irq_params meson8_params = {
 	INIT_MESON8_COMMON_DATA(134)
@@ -136,8 +138,8 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
 struct meson_gpio_irq_controller {
 	const struct meson_gpio_irq_params *params;
 	void __iomem *base;
-	u32 channel_irqs[NUM_CHANNEL];
-	DECLARE_BITMAP(channel_map, NUM_CHANNEL);
+	u32 *channel_irqs;
+	unsigned long *channel_map;
 	spinlock_t lock;
 };
 
@@ -207,8 +209,8 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
 	spin_lock_irqsave(&ctl->lock, flags);
 
 	/* Find a free channel */
-	idx = find_first_zero_bit(ctl->channel_map, NUM_CHANNEL);
-	if (idx >= NUM_CHANNEL) {
+	idx = find_first_zero_bit(ctl->channel_map, ctl->params->nr_channels);
+	if (idx >= ctl->params->nr_channels) {
 		spin_unlock_irqrestore(&ctl->lock, flags);
 		pr_err("No channel available\n");
 		return -ENOSPC;
@@ -447,13 +449,26 @@ static int meson_gpio_irq_parse_dt(struct device_node *node, struct meson_gpio_i
 
 	ctl->params = match->data;
 
+	ctl->channel_irqs = kcalloc(ctl->params->nr_channels, sizeof(*ctl->channel_irqs),
+				    GFP_KERNEL);
+	if (!ctl->channel_irqs)
+		return -ENOMEM;
+
+	ctl->channel_map = bitmap_zalloc(ctl->params->nr_channels, GFP_KERNEL);
+	if (!ctl->channel_map) {
+		kfree(ctl->channel_irqs);
+		return -ENOMEM;
+	}
+
 	ret = of_property_read_variable_u32_array(node,
 						  "amlogic,channel-interrupts",
 						  ctl->channel_irqs,
-						  NUM_CHANNEL,
-						  NUM_CHANNEL);
+						  ctl->params->nr_channels,
+						  ctl->params->nr_channels);
 	if (ret < 0) {
-		pr_err("can't get %d channel interrupts\n", NUM_CHANNEL);
+		pr_err("can't get %d channel interrupts\n", ctl->params->nr_channels);
+		kfree(ctl->channel_map);
+		kfree(ctl->channel_irqs);
 		return ret;
 	}
 
@@ -507,7 +522,7 @@ static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *
 	}
 
 	pr_info("%d to %d gpio interrupt mux initialized\n",
-		ctl->params->nr_hwirq, NUM_CHANNEL);
+		ctl->params->nr_hwirq, ctl->params->nr_channels);
 
 	return 0;
 
-- 
2.34.1



From qianggui.song at amlogic.com  Tue Jan 18 23:08:08 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Wed, 19 Jan 2022 15:08:08 +0800
Subject: [PATCH v2 3/4] irqchip/meson-gpio: add select trigger type callback
In-Reply-To: <20220119070809.15563-1-qianggui.song@amlogic.com>
References: <20220119070809.15563-1-qianggui.song@amlogic.com>
Message-ID: <20220119070809.15563-4-qianggui.song@amlogic.com>

Due to some chips may use different registers and offset, provide
a set trigger type call back.

Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 drivers/irqchip/irq-meson-gpio.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
index eefe15e1b3a6..b511f9532adc 100644
--- a/drivers/irqchip/irq-meson-gpio.c
+++ b/drivers/irqchip/irq-meson-gpio.c
@@ -55,6 +55,8 @@ struct irq_ctl_ops {
 	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
 				 unsigned int channel, unsigned long hwirq);
 	void (*gpio_irq_init)(struct meson_gpio_irq_controller *ctl);
+	void (*gpio_irq_sel_type)(struct meson_gpio_irq_controller *ctl,
+				  unsigned int idx, u32 val);
 };
 
 struct meson_gpio_irq_params {
@@ -278,6 +280,12 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
 	 */
 	type &= IRQ_TYPE_SENSE_MASK;
 
+	/* Some controllers may have different calculation method*/
+	if (params->ops.gpio_irq_sel_type) {
+		params->ops.gpio_irq_sel_type(ctl, idx, type);
+		return 0;
+	}
+
 	/*
 	 * New controller support EDGE_BOTH trigger. This setting takes
 	 * precedence over the other edge/polarity settings
-- 
2.34.1



From qianggui.song at amlogic.com  Tue Jan 18 23:08:09 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Wed, 19 Jan 2022 15:08:09 +0800
Subject: [PATCH v2 4/4] irqchip/meson-gpio: Add support for meson s4 SoCs
In-Reply-To: <20220119070809.15563-1-qianggui.song@amlogic.com>
References: <20220119070809.15563-1-qianggui.song@amlogic.com>
Message-ID: <20220119070809.15563-5-qianggui.song@amlogic.com>

The meson s4 SoCs support 12 gpio irq lines compared with previous
serial chips and have something different, details are as below.

IRQ Number:
- 80:68 13 pins on bank Z
- 67:48 20 pins on bank X
- 47:36 12 pins on bank H
- 35:24 12 pins on bank D
- 23:22 2  pins on bank E
- 21:14 8  pins on bank C
- 13:0  13 pins on bank B

Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 drivers/irqchip/irq-meson-gpio.c | 64 ++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
index b511f9532adc..896201d2f01f 100644
--- a/drivers/irqchip/irq-meson-gpio.c
+++ b/drivers/irqchip/irq-meson-gpio.c
@@ -42,6 +42,9 @@
 #define REG_PIN_SEL_SHIFT(x)	(((x) % 4) * 8)
 #define REG_FILTER_SEL_SHIFT(x)	((x) * 4)
 
+/* Used for s4 chips */
+#define REG_EDGE_POL_S4	0x1c
+
 struct meson_gpio_irq_controller;
 static void meson8_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
 				    unsigned int channel, unsigned long hwirq);
@@ -50,6 +53,8 @@ static void meson_a1_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
 				      unsigned int channel,
 				      unsigned long hwirq);
 static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl);
+static void meson_s4_gpio_irq_sel_type(struct meson_gpio_irq_controller *ctl,
+				       unsigned int idx, u32 val);
 
 struct irq_ctl_ops {
 	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
@@ -95,6 +100,20 @@ struct meson_gpio_irq_params {
 	.pin_sel_mask = 0x7f,					\
 	.nr_channels = 8,					\
 
+#define INIT_MESON_S4_COMMON_DATA(irqs)				\
+	.nr_hwirq = irqs,					\
+	.ops = {						\
+		.gpio_irq_init = meson_a1_gpio_irq_init,	\
+		.gpio_irq_sel_pin = meson_a1_gpio_irq_sel_pin,	\
+		.gpio_irq_sel_type = meson_s4_gpio_irq_sel_type,\
+	},							\
+	.support_edge_both = true,				\
+	.edge_both_offset = 0,					\
+	.edge_single_offset = 12,				\
+	.pol_low_offset = 0,					\
+	.pin_sel_mask = 0xff,					\
+	.nr_channels = 12,					\
+
 static const struct meson_gpio_irq_params meson8_params = {
 	INIT_MESON8_COMMON_DATA(134)
 };
@@ -125,6 +144,10 @@ static const struct meson_gpio_irq_params a1_params = {
 	INIT_MESON_A1_COMMON_DATA(62)
 };
 
+static const struct meson_gpio_irq_params s4_params = {
+	INIT_MESON_S4_COMMON_DATA(82)
+};
+
 static const struct of_device_id meson_irq_gpio_matches[] = {
 	{ .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params },
 	{ .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params },
@@ -134,6 +157,7 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
 	{ .compatible = "amlogic,meson-g12a-gpio-intc", .data = &axg_params },
 	{ .compatible = "amlogic,meson-sm1-gpio-intc", .data = &sm1_params },
 	{ .compatible = "amlogic,meson-a1-gpio-intc", .data = &a1_params },
+	{ .compatible = "amlogic,meson-s4-gpio-intc", .data = &s4_params },
 	{ }
 };
 
@@ -200,6 +224,46 @@ static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl)
 	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL, BIT(31), BIT(31));
 }
 
+/*
+ * gpio irq relative registers for s4
+ * -PADCTRL_GPIO_IRQ_CTRL0
+ * bit[31]:    enable/disable all the irq lines
+ * bit[12-23]: single edge trigger
+ * bit[0-11]:  polarity trigger
+ *
+ * -PADCTRL_GPIO_IRQ_CTRL[X]
+ * bit[0-16]: 7 bits to choose gpio source for irq line 2*[X] - 2
+ * bit[16-22]:7 bits to choose gpio source for irq line 2*[X] - 1
+ * where X = 1-6
+ *
+ * -PADCTRL_GPIO_IRQ_CTRL[7]
+ * bit[0-11]: both edge trigger
+ */
+static void
+meson_s4_gpio_irq_sel_type(struct meson_gpio_irq_controller *ctl,
+			   unsigned int idx, unsigned int type)
+{
+	unsigned int val = 0;
+
+	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4, BIT(idx), 0);
+
+	if (type == IRQ_TYPE_EDGE_BOTH) {
+		val |= BIT(ctl->params->edge_both_offset + idx);
+		meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4,
+					   BIT(ctl->params->edge_both_offset + idx), val);
+		return;
+	}
+
+	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
+		val |= BIT(ctl->params->pol_low_offset + idx);
+
+	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+		val |= BIT(ctl->params->edge_single_offset + idx);
+
+	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
+				   BIT(idx) | BIT(12 + idx), val);
+};
+
 static int
 meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
 			       unsigned long  hwirq,
-- 
2.34.1



From andrzej.hajda at intel.com  Tue Jan 18 23:35:52 2022
From: andrzej.hajda at intel.com (Andrzej Hajda)
Date: Wed, 19 Jan 2022 08:35:52 +0100
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <20220119023714.1498508-1-victor.liu@nxp.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
Message-ID: <667a64ef-5121-ba92-964e-a9c075fc2375@intel.com>


On 19.01.2022 03:37, Liu Ying wrote:
> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> mentions that it should be in UI.  However, the dphy core driver wrongly
> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> is '8 UI', instead of 8.
>
> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
> value according to the D-PHY specification.
>
> I'm assuming that all impacted custom drivers shall program values in
> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
> specification mentions that the frequency of TxByteClkHS is exactly 1/8
> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
> custom driver code is changed to program those values as
> DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
>
> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
> as I don't have the hardwares.
>
> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Robert Foss <robert.foss at linaro.org>
> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> Cc: Jonas Karlman <jonas at kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> Cc: David Airlie <airlied at linux.ie>
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Cc: Vinod Koul <vkoul at kernel.org>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: Heiko Stuebner <heiko at sntech.de>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Guido G?nther <agx at sigxcpu.org>
> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
> Signed-off-by: Liu Ying <victor.liu at nxp.com>

Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>

Regards

Andrzej

> ---
> v1->v2:
> * Use BITS_PER_BYTE macro. (Andrzej)
> * Drop dsi argument from ui2bc() in nwl-dsi.c.
>
>   drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
>   drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
>   drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
>   drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
>   include/linux/phy/phy-mipi-dphy.h                |  2 +-
>   5 files changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
> index a7389a0facfb..af07eeb47ca0 100644
> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> @@ -7,6 +7,7 @@
>    */
>   
>   #include <linux/bitfield.h>
> +#include <linux/bits.h>
>   #include <linux/clk.h>
>   #include <linux/irq.h>
>   #include <linux/math64.h>
> @@ -196,12 +197,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
>   /*
>    * ui2bc - UI time periods to byte clock cycles
>    */
> -static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
> +static u32 ui2bc(unsigned int ui)
>   {
> -	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> -
> -	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
> -				  dsi->mode.clock * 1000 * bpp);
> +	return DIV_ROUND_UP(ui, BITS_PER_BYTE);
>   }
>   
>   /*
> @@ -232,12 +230,12 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi)
>   	}
>   
>   	/* values in byte clock cycles */
> -	cycles = ui2bc(dsi, cfg->clk_pre);
> +	cycles = ui2bc(cfg->clk_pre);
>   	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
>   	nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
>   	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
>   	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
> -	cycles += ui2bc(dsi, cfg->clk_pre);
> +	cycles += ui2bc(cfg->clk_pre);
>   	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
>   	nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
>   	cycles = ps2bc(dsi, cfg->hs_exit);
> diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> index cd2332bf0e31..fdbd64c03e12 100644
> --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> @@ -9,6 +9,7 @@
>   
>   #include <linux/bitfield.h>
>   #include <linux/bitops.h>
> +#include <linux/bits.h>
>   #include <linux/clk.h>
>   #include <linux/delay.h>
>   #include <linux/io.h>
> @@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
>   		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
>   		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
>   	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
> -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
> +		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
>   
>   	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
>   		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
> diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
> index 288c9c67aa74..ccb4045685cd 100644
> --- a/drivers/phy/phy-core-mipi-dphy.c
> +++ b/drivers/phy/phy-core-mipi-dphy.c
> @@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
>   
>   	cfg->clk_miss = 0;
>   	cfg->clk_post = 60000 + 52 * ui;
> -	cfg->clk_pre = 8000;
> +	cfg->clk_pre = 8;
>   	cfg->clk_prepare = 38000;
>   	cfg->clk_settle = 95000;
>   	cfg->clk_term_en = 0;
> @@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
>   	if (cfg->clk_post < (60000 + 52 * ui))
>   		return -EINVAL;
>   
> -	if (cfg->clk_pre < 8000)
> +	if (cfg->clk_pre < 8)
>   		return -EINVAL;
>   
>   	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> index 347dc79a18c1..630e01b5c19b 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> @@ -5,6 +5,7 @@
>    * Author: Wyon Bi <bivvy.bi at rock-chips.com>
>    */
>   
> +#include <linux/bits.h>
>   #include <linux/kernel.h>
>   #include <linux/clk.h>
>   #include <linux/iopoll.h>
> @@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
>   	 * The value of counter for HS Tclk-pre
>   	 * Tclk-pre = Tpin_txbyteclkhs * value
>   	 */
> -	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
> +	clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);
>   
>   	/*
>   	 * The value of counter for HS Tlpx Time
> diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
> index a877ffee845d..59a5e77ab409 100644
> --- a/include/linux/phy/phy-mipi-dphy.h
> +++ b/include/linux/phy/phy-mipi-dphy.h
> @@ -42,7 +42,7 @@ struct phy_configure_opts_mipi_dphy {
>   	 * the transmitter prior to any associated Data Lane beginning
>   	 * the transition from LP to HS mode.
>   	 *
> -	 * Minimum value: 8 UI
> +	 * Minimum value: 8
>   	 */
>   	unsigned int		clk_pre;
>   


From narmstrong at baylibre.com  Wed Jan 19 00:40:02 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 19 Jan 2022 09:40:02 +0100
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <20220119023714.1498508-1-victor.liu@nxp.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
Message-ID: <28e3f723-daf0-b3c5-ee10-519c4cabfe17@baylibre.com>

Hi,

On 19/01/2022 03:37, Liu Ying wrote:
> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> mentions that it should be in UI.  However, the dphy core driver wrongly
> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> is '8 UI', instead of 8.
> 
> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
> value according to the D-PHY specification.
> 
> I'm assuming that all impacted custom drivers shall program values in
> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
> specification mentions that the frequency of TxByteClkHS is exactly 1/8
> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
> custom driver code is changed to program those values as
> DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
> 
> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
> as I don't have the hardwares.
> 
> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Robert Foss <robert.foss at linaro.org>
> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> Cc: Jonas Karlman <jonas at kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> Cc: David Airlie <airlied at linux.ie>
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Cc: Vinod Koul <vkoul at kernel.org>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: Heiko Stuebner <heiko at sntech.de>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Guido G?nther <agx at sigxcpu.org>
> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
> Signed-off-by: Liu Ying <victor.liu at nxp.com>
> ---
> v1->v2:
> * Use BITS_PER_BYTE macro. (Andrzej)
> * Drop dsi argument from ui2bc() in nwl-dsi.c.
> 
>  drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
>  drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
>  drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
>  drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
>  include/linux/phy/phy-mipi-dphy.h                |  2 +-
>  5 files changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
> index a7389a0facfb..af07eeb47ca0 100644
> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> @@ -7,6 +7,7 @@
>   */
>  
>  #include <linux/bitfield.h>
> +#include <linux/bits.h>
>  #include <linux/clk.h>
>  #include <linux/irq.h>
>  #include <linux/math64.h>
> @@ -196,12 +197,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
>  /*
>   * ui2bc - UI time periods to byte clock cycles
>   */
> -static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
> +static u32 ui2bc(unsigned int ui)
>  {
> -	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> -
> -	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
> -				  dsi->mode.clock * 1000 * bpp);
> +	return DIV_ROUND_UP(ui, BITS_PER_BYTE);
>  }
>  
>  /*
> @@ -232,12 +230,12 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi)
>  	}
>  
>  	/* values in byte clock cycles */
> -	cycles = ui2bc(dsi, cfg->clk_pre);
> +	cycles = ui2bc(cfg->clk_pre);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
>  	nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
>  	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
> -	cycles += ui2bc(dsi, cfg->clk_pre);
> +	cycles += ui2bc(cfg->clk_pre);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
>  	nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
>  	cycles = ps2bc(dsi, cfg->hs_exit);
> diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> index cd2332bf0e31..fdbd64c03e12 100644
> --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> @@ -9,6 +9,7 @@
>  
>  #include <linux/bitfield.h>
>  #include <linux/bitops.h>
> +#include <linux/bits.h>
>  #include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/io.h>
> @@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
>  		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
>  		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
>  	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
> -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
> +		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
>  
>  	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
>  		     DIV_ROUND_UP(priv->config.hs_exit, temp) |

I'll try to run a test, currently the calculation gives 2, so this would give 1.

Neil

> diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
> index 288c9c67aa74..ccb4045685cd 100644
> --- a/drivers/phy/phy-core-mipi-dphy.c
> +++ b/drivers/phy/phy-core-mipi-dphy.c
> @@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
>  
>  	cfg->clk_miss = 0;
>  	cfg->clk_post = 60000 + 52 * ui;
> -	cfg->clk_pre = 8000;
> +	cfg->clk_pre = 8;
>  	cfg->clk_prepare = 38000;
>  	cfg->clk_settle = 95000;
>  	cfg->clk_term_en = 0;
> @@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
>  	if (cfg->clk_post < (60000 + 52 * ui))
>  		return -EINVAL;
>  
> -	if (cfg->clk_pre < 8000)
> +	if (cfg->clk_pre < 8)
>  		return -EINVAL;
>  
>  	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> index 347dc79a18c1..630e01b5c19b 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> @@ -5,6 +5,7 @@
>   * Author: Wyon Bi <bivvy.bi at rock-chips.com>
>   */
>  
> +#include <linux/bits.h>
>  #include <linux/kernel.h>
>  #include <linux/clk.h>
>  #include <linux/iopoll.h>
> @@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
>  	 * The value of counter for HS Tclk-pre
>  	 * Tclk-pre = Tpin_txbyteclkhs * value
>  	 */
> -	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
> +	clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);
>  
>  	/*
>  	 * The value of counter for HS Tlpx Time
> diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
> index a877ffee845d..59a5e77ab409 100644
> --- a/include/linux/phy/phy-mipi-dphy.h
> +++ b/include/linux/phy/phy-mipi-dphy.h
> @@ -42,7 +42,7 @@ struct phy_configure_opts_mipi_dphy {
>  	 * the transmitter prior to any associated Data Lane beginning
>  	 * the transition from LP to HS mode.
>  	 *
> -	 * Minimum value: 8 UI
> +	 * Minimum value: 8
>  	 */
>  	unsigned int		clk_pre;
>  
> 



From narmstrong at baylibre.com  Wed Jan 19 00:52:27 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 19 Jan 2022 09:52:27 +0100
Subject: [PATCH v2 3/4] irqchip/meson-gpio: add select trigger type
 callback
In-Reply-To: <20220119070809.15563-4-qianggui.song@amlogic.com>
References: <20220119070809.15563-1-qianggui.song@amlogic.com>
 <20220119070809.15563-4-qianggui.song@amlogic.com>
Message-ID: <fb7db50f-866a-233b-1c9b-093cd50473c8@baylibre.com>

Hi,

On 19/01/2022 08:08, Qianggui Song wrote:
> Due to some chips may use different registers and offset, provide
> a set trigger type call back.
> 
> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
> ---
>  drivers/irqchip/irq-meson-gpio.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
> index eefe15e1b3a6..b511f9532adc 100644
> --- a/drivers/irqchip/irq-meson-gpio.c
> +++ b/drivers/irqchip/irq-meson-gpio.c
> @@ -55,6 +55,8 @@ struct irq_ctl_ops {
>  	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
>  				 unsigned int channel, unsigned long hwirq);
>  	void (*gpio_irq_init)(struct meson_gpio_irq_controller *ctl);
> +	void (*gpio_irq_sel_type)(struct meson_gpio_irq_controller *ctl,
> +				  unsigned int idx, u32 val);
>  };
>  
>  struct meson_gpio_irq_params {
> @@ -278,6 +280,12 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
>  	 */
>  	type &= IRQ_TYPE_SENSE_MASK;
>  
> +	/* Some controllers may have different calculation method*/
> +	if (params->ops.gpio_irq_sel_type) {
> +		params->ops.gpio_irq_sel_type(ctl, idx, type);
> +		return 0;
> +	}
> +
>  	/*
>  	 * New controller support EDGE_BOTH trigger. This setting takes
>  	 * precedence over the other edge/polarity settings
> 

The comment on v1 hasn't been addresses here, it was asked to move the old controllers
sel_type to a callback and introduce an S4 callback instead of doing this.

Neil


From narmstrong at baylibre.com  Wed Jan 19 00:53:00 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 19 Jan 2022 09:53:00 +0100
Subject: [PATCH v2 2/4] irqchip/meson-gpio: support more than 8 channels
 gpio irq line
In-Reply-To: <20220119070809.15563-3-qianggui.song@amlogic.com>
References: <20220119070809.15563-1-qianggui.song@amlogic.com>
 <20220119070809.15563-3-qianggui.song@amlogic.com>
Message-ID: <4c6b7f6b-b9a2-c08d-7ac4-f5132808b1c5@baylibre.com>

On 19/01/2022 08:08, Qianggui Song wrote:
> Current meson gpio irqchip driver only support 8 channels for gpio irq
> line, later chips may have more then 8 channels, so need to modify code
> to support more.
> 
> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
> ---
>  drivers/irqchip/irq-meson-gpio.c | 33 +++++++++++++++++++++++---------
>  1 file changed, 24 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
> index d90ff0b92480..eefe15e1b3a6 100644
> --- a/drivers/irqchip/irq-meson-gpio.c
> +++ b/drivers/irqchip/irq-meson-gpio.c
> @@ -16,7 +16,6 @@
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  
> -#define NUM_CHANNEL 8
>  #define MAX_INPUT_MUX 256
>  
>  #define REG_EDGE_POL	0x00
> @@ -60,6 +59,7 @@ struct irq_ctl_ops {
>  
>  struct meson_gpio_irq_params {
>  	unsigned int nr_hwirq;
> +	unsigned int nr_channels;
>  	bool support_edge_both;
>  	unsigned int edge_both_offset;
>  	unsigned int edge_single_offset;
> @@ -81,6 +81,7 @@ struct meson_gpio_irq_params {
>  	.edge_single_offset = 0,				\
>  	.pol_low_offset = 16,					\
>  	.pin_sel_mask = 0xff,					\
> +	.nr_channels = 8,					\
>  
>  #define INIT_MESON_A1_COMMON_DATA(irqs)				\
>  	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
> @@ -90,6 +91,7 @@ struct meson_gpio_irq_params {
>  	.edge_single_offset = 8,				\
>  	.pol_low_offset = 0,					\
>  	.pin_sel_mask = 0x7f,					\
> +	.nr_channels = 8,					\
>  
>  static const struct meson_gpio_irq_params meson8_params = {
>  	INIT_MESON8_COMMON_DATA(134)
> @@ -136,8 +138,8 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
>  struct meson_gpio_irq_controller {
>  	const struct meson_gpio_irq_params *params;
>  	void __iomem *base;
> -	u32 channel_irqs[NUM_CHANNEL];
> -	DECLARE_BITMAP(channel_map, NUM_CHANNEL);
> +	u32 *channel_irqs;
> +	unsigned long *channel_map;
>  	spinlock_t lock;
>  };
>  
> @@ -207,8 +209,8 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
>  	spin_lock_irqsave(&ctl->lock, flags);
>  
>  	/* Find a free channel */
> -	idx = find_first_zero_bit(ctl->channel_map, NUM_CHANNEL);
> -	if (idx >= NUM_CHANNEL) {
> +	idx = find_first_zero_bit(ctl->channel_map, ctl->params->nr_channels);
> +	if (idx >= ctl->params->nr_channels) {
>  		spin_unlock_irqrestore(&ctl->lock, flags);
>  		pr_err("No channel available\n");
>  		return -ENOSPC;
> @@ -447,13 +449,26 @@ static int meson_gpio_irq_parse_dt(struct device_node *node, struct meson_gpio_i
>  
>  	ctl->params = match->data;
>  
> +	ctl->channel_irqs = kcalloc(ctl->params->nr_channels, sizeof(*ctl->channel_irqs),
> +				    GFP_KERNEL);
> +	if (!ctl->channel_irqs)
> +		return -ENOMEM;
> +
> +	ctl->channel_map = bitmap_zalloc(ctl->params->nr_channels, GFP_KERNEL);
> +	if (!ctl->channel_map) {
> +		kfree(ctl->channel_irqs);
> +		return -ENOMEM;
> +	}
> +
>  	ret = of_property_read_variable_u32_array(node,
>  						  "amlogic,channel-interrupts",
>  						  ctl->channel_irqs,
> -						  NUM_CHANNEL,
> -						  NUM_CHANNEL);
> +						  ctl->params->nr_channels,
> +						  ctl->params->nr_channels);
>  	if (ret < 0) {
> -		pr_err("can't get %d channel interrupts\n", NUM_CHANNEL);
> +		pr_err("can't get %d channel interrupts\n", ctl->params->nr_channels);
> +		kfree(ctl->channel_map);
> +		kfree(ctl->channel_irqs);
>  		return ret;
>  	}
>  
> @@ -507,7 +522,7 @@ static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *
>  	}
>  
>  	pr_info("%d to %d gpio interrupt mux initialized\n",
> -		ctl->params->nr_hwirq, NUM_CHANNEL);
> +		ctl->params->nr_hwirq, ctl->params->nr_channels);
>  
>  	return 0;
>  
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From narmstrong at baylibre.com  Wed Jan 19 01:11:51 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 19 Jan 2022 10:11:51 +0100
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <28e3f723-daf0-b3c5-ee10-519c4cabfe17@baylibre.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
 <28e3f723-daf0-b3c5-ee10-519c4cabfe17@baylibre.com>
Message-ID: <5a638561-c704-49e7-1fed-70e26fedb186@baylibre.com>

On 19/01/2022 09:40, Neil Armstrong wrote:
> Hi,
> 
> On 19/01/2022 03:37, Liu Ying wrote:
>> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
>> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
>> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
>> mentions that it should be in UI.  However, the dphy core driver wrongly
>> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
>> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
>> is '8 UI', instead of 8.
>>
>> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
>> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
>> value according to the D-PHY specification.
>>
>> I'm assuming that all impacted custom drivers shall program values in
>> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
>> specification mentions that the frequency of TxByteClkHS is exactly 1/8
>> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
>> custom driver code is changed to program those values as
>> DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
>>
>> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
>> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
>> as I don't have the hardwares.
>>
>> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
>> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
>> Cc: Neil Armstrong <narmstrong at baylibre.com>
>> Cc: Robert Foss <robert.foss at linaro.org>
>> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
>> Cc: Jonas Karlman <jonas at kwiboo.se>
>> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
>> Cc: David Airlie <airlied at linux.ie>
>> Cc: Daniel Vetter <daniel at ffwll.ch>
>> Cc: Kishon Vijay Abraham I <kishon at ti.com>
>> Cc: Vinod Koul <vkoul at kernel.org>
>> Cc: Kevin Hilman <khilman at baylibre.com>
>> Cc: Jerome Brunet <jbrunet at baylibre.com>
>> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
>> Cc: Heiko Stuebner <heiko at sntech.de>
>> Cc: Maxime Ripard <mripard at kernel.org>
>> Cc: Guido G?nther <agx at sigxcpu.org>
>> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
>> Signed-off-by: Liu Ying <victor.liu at nxp.com>
>> ---
>> v1->v2:
>> * Use BITS_PER_BYTE macro. (Andrzej)
>> * Drop dsi argument from ui2bc() in nwl-dsi.c.
>>
>>  drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
>>  drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
>>  drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
>>  drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
>>  include/linux/phy/phy-mipi-dphy.h                |  2 +-
>>  5 files changed, 12 insertions(+), 12 deletions(-)
>>
[...]

>> diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>> index cd2332bf0e31..fdbd64c03e12 100644
>> --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>> +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>> @@ -9,6 +9,7 @@
>>  
>>  #include <linux/bitfield.h>
>>  #include <linux/bitops.h>
>> +#include <linux/bits.h>
>>  #include <linux/clk.h>
>>  #include <linux/delay.h>
>>  #include <linux/io.h>
>> @@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
>>  		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
>>  		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
>>  	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
>> -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
>> +		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
>>  
>>  	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
>>  		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
> 
> I'll try to run a test, currently the calculation gives 2, so this would give 1.

The Amlogic vendor code does:

/* >8*ui */
#define DPHY_TIME_CLK_PRE(ui)       (10 * ui)

t_ui = lcd_timing.bit_rate

t_ui = (1000000 * 100) / (dsi_ui / 1000); /*100*ns */
temp = t_ui * 8; /* lane_byte cycle time */

dphy->clk_pre = ((DPHY_TIME_CLK_PRE(t_ui) + temp - 1) / temp) & 0xff;

PHY Registers only says:
MIPI_DSI_CLK_TIM1	[31:0]
7:0 	R/W	0	 tCLK_PRE

> 
> Neil
> 

[...]


From victor.liu at nxp.com  Wed Jan 19 02:01:08 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Wed, 19 Jan 2022 18:01:08 +0800
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <5a638561-c704-49e7-1fed-70e26fedb186@baylibre.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
 <28e3f723-daf0-b3c5-ee10-519c4cabfe17@baylibre.com>
 <5a638561-c704-49e7-1fed-70e26fedb186@baylibre.com>
Message-ID: <8ad2cd76e80056192395ca5b73ff514e59881ba3.camel@nxp.com>

Hi Neil,

On Wed, 2022-01-19 at 10:11 +0100, Neil Armstrong wrote:
> On 19/01/2022 09:40, Neil Armstrong wrote:
> > Hi,
> > 
> > On 19/01/2022 03:37, Liu Ying wrote:
> > > The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> > > parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> > > kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> > > mentions that it should be in UI.  However, the dphy core driver wrongly
> > > sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> > > And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> > > is '8 UI', instead of 8.
> > > 
> > > So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
> > > member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
> > > value according to the D-PHY specification.
> > > 
> > > I'm assuming that all impacted custom drivers shall program values in
> > > TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
> > > specification mentions that the frequency of TxByteClkHS is exactly 1/8
> > > the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
> > > custom driver code is changed to program those values as
> > > DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
> > > 
> > > Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
> > > Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
> > > as I don't have the hardwares.
> > > 
> > > Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
> > > Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> > > Cc: Neil Armstrong <narmstrong at baylibre.com>
> > > Cc: Robert Foss <robert.foss at linaro.org>
> > > Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> > > Cc: Jonas Karlman <jonas at kwiboo.se>
> > > Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> > > Cc: David Airlie <airlied at linux.ie>
> > > Cc: Daniel Vetter <daniel at ffwll.ch>
> > > Cc: Kishon Vijay Abraham I <kishon at ti.com>
> > > Cc: Vinod Koul <vkoul at kernel.org>
> > > Cc: Kevin Hilman <khilman at baylibre.com>
> > > Cc: Jerome Brunet <jbrunet at baylibre.com>
> > > Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> > > Cc: Heiko Stuebner <heiko at sntech.de>
> > > Cc: Maxime Ripard <mripard at kernel.org>
> > > Cc: Guido G?nther <agx at sigxcpu.org>
> > > Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
> > > Signed-off-by: Liu Ying <victor.liu at nxp.com>
> > > ---
> > > v1->v2:
> > > * Use BITS_PER_BYTE macro. (Andrzej)
> > > * Drop dsi argument from ui2bc() in nwl-dsi.c.
> > > 
> > >  drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
> > >  drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
> > >  drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
> > >  drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
> > >  include/linux/phy/phy-mipi-dphy.h                |  2 +-
> > >  5 files changed, 12 insertions(+), 12 deletions(-)
> > > 
> [...]
> 
> > > diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> > > index cd2332bf0e31..fdbd64c03e12 100644
> > > --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> > > +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> > > @@ -9,6 +9,7 @@
> > >  
> > >  #include <linux/bitfield.h>
> > >  #include <linux/bitops.h>
> > > +#include <linux/bits.h>
> > >  #include <linux/clk.h>
> > >  #include <linux/delay.h>
> > >  #include <linux/io.h>
> > > @@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
> > >  		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
> > >  		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
> > >  	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
> > > -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
> > > +		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
> > >  
> > >  	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
> > >  		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
> > 
> > I'll try to run a test, currently the calculation gives 2, so this would give 1.
> 
> The Amlogic vendor code does:
> 
> /* >8*ui */
> #define DPHY_TIME_CLK_PRE(ui)       (10 * ui)

This looks like clk_pre time is 10 * ui, which matches the comment
'>8*ui' - longer time 8 * ui.

> 
> t_ui = lcd_timing.bit_rate
> 
> t_ui = (1000000 * 100) / (dsi_ui / 1000); /*100*ns */
> temp = t_ui * 8; /* lane_byte cycle time */

If I read correctly, this temp in vendor code is TxByteClkHS period
time in picoseconds. So...

> 
> dphy->clk_pre = ((DPHY_TIME_CLK_PRE(t_ui) + temp - 1) / temp) & 0xff;

IIUC, 'dphy->clk_pre' essentially means dphy->clk_pre = DIV_ROUND_UP(10
* ui, temp), that is, the time for dphy->clk_pre is no less than 
10 * ui.  The D-PHY spec (v1.2)'s saying is that the minimum time for
dphy->clk_pre is 8 * ui.  So, it looks like meson is stricter than the
spec.

However, the vendor code doesn't seem to match the current meson driver
implementation.  The temp in driver code is also TxByteClkHS period
time in picoseconds. And, without this patch, I'm assuming that
priv->config.clk_pre is 8000.  So, it looks like MIPI_DSI_CLK_TIM1 is
set to DIV_ROUND_UP(8000, temp).  This '8000' does _not_ reflect
'10 * ui'.

So, 3 choices for meson, up to you:
1) If meson really requires the time for clk_pre no less than
10 * ui, then sth like DIV_ROUND_UP(10, BITS_PER_BYTE) can be used.
2) If meson follows the spec's minimum value, then the patch does
things right for meson.
3) Force to use 8000 picoseconds for clk_pre, that is, use sth like
DIV_ROUND_UP(8000, temp).

With this patch applied, do you see any display artifacts by visual
check? Or even checked signals through DSI analyzer?

Regards,
Liu Ying

> 
> PHY Registers only says:
> MIPI_DSI_CLK_TIM1	[31:0]
> 7:0 	R/W	0	 tCLK_PRE
> 
> > Neil
> > 
> 
> [...]



From narmstrong at baylibre.com  Wed Jan 19 02:11:19 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 19 Jan 2022 11:11:19 +0100
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <8ad2cd76e80056192395ca5b73ff514e59881ba3.camel@nxp.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
 <28e3f723-daf0-b3c5-ee10-519c4cabfe17@baylibre.com>
 <5a638561-c704-49e7-1fed-70e26fedb186@baylibre.com>
 <8ad2cd76e80056192395ca5b73ff514e59881ba3.camel@nxp.com>
Message-ID: <e02c9226-2dfb-5931-60e3-a22e51172c30@baylibre.com>

Hi,

On 19/01/2022 11:01, Liu Ying wrote:
> Hi Neil,
> 
> On Wed, 2022-01-19 at 10:11 +0100, Neil Armstrong wrote:
>> On 19/01/2022 09:40, Neil Armstrong wrote:
>>> Hi,
>>>
>>> On 19/01/2022 03:37, Liu Ying wrote:
>>>> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
>>>> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
>>>> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
>>>> mentions that it should be in UI.  However, the dphy core driver wrongly
>>>> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
>>>> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
>>>> is '8 UI', instead of 8.
>>>>
>>>> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
>>>> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
>>>> value according to the D-PHY specification.
>>>>
>>>> I'm assuming that all impacted custom drivers shall program values in
>>>> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
>>>> specification mentions that the frequency of TxByteClkHS is exactly 1/8
>>>> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
>>>> custom driver code is changed to program those values as
>>>> DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
>>>>
>>>> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
>>>> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
>>>> as I don't have the hardwares.
>>>>
>>>> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
>>>> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
>>>> Cc: Neil Armstrong <narmstrong at baylibre.com>
>>>> Cc: Robert Foss <robert.foss at linaro.org>
>>>> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
>>>> Cc: Jonas Karlman <jonas at kwiboo.se>
>>>> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
>>>> Cc: David Airlie <airlied at linux.ie>
>>>> Cc: Daniel Vetter <daniel at ffwll.ch>
>>>> Cc: Kishon Vijay Abraham I <kishon at ti.com>
>>>> Cc: Vinod Koul <vkoul at kernel.org>
>>>> Cc: Kevin Hilman <khilman at baylibre.com>
>>>> Cc: Jerome Brunet <jbrunet at baylibre.com>
>>>> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
>>>> Cc: Heiko Stuebner <heiko at sntech.de>
>>>> Cc: Maxime Ripard <mripard at kernel.org>
>>>> Cc: Guido G?nther <agx at sigxcpu.org>
>>>> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
>>>> Signed-off-by: Liu Ying <victor.liu at nxp.com>
>>>> ---
>>>> v1->v2:
>>>> * Use BITS_PER_BYTE macro. (Andrzej)
>>>> * Drop dsi argument from ui2bc() in nwl-dsi.c.
>>>>
>>>>  drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
>>>>  drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
>>>>  drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
>>>>  drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
>>>>  include/linux/phy/phy-mipi-dphy.h                |  2 +-
>>>>  5 files changed, 12 insertions(+), 12 deletions(-)
>>>>
>> [...]
>>
>>>> diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>>>> index cd2332bf0e31..fdbd64c03e12 100644
>>>> --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>>>> +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>>>> @@ -9,6 +9,7 @@
>>>>  
>>>>  #include <linux/bitfield.h>
>>>>  #include <linux/bitops.h>
>>>> +#include <linux/bits.h>
>>>>  #include <linux/clk.h>
>>>>  #include <linux/delay.h>
>>>>  #include <linux/io.h>
>>>> @@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
>>>>  		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
>>>>  		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
>>>>  	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
>>>> -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
>>>> +		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
>>>>  
>>>>  	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
>>>>  		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
>>>
>>> I'll try to run a test, currently the calculation gives 2, so this would give 1.
>>
>> The Amlogic vendor code does:
>>
>> /* >8*ui */
>> #define DPHY_TIME_CLK_PRE(ui)       (10 * ui)
> 
> This looks like clk_pre time is 10 * ui, which matches the comment
> '>8*ui' - longer time 8 * ui.
> 
>>
>> t_ui = lcd_timing.bit_rate
>>
>> t_ui = (1000000 * 100) / (dsi_ui / 1000); /*100*ns */
>> temp = t_ui * 8; /* lane_byte cycle time */
> 
> If I read correctly, this temp in vendor code is TxByteClkHS period
> time in picoseconds. So...
> 
>>
>> dphy->clk_pre = ((DPHY_TIME_CLK_PRE(t_ui) + temp - 1) / temp) & 0xff;
> 
> IIUC, 'dphy->clk_pre' essentially means dphy->clk_pre = DIV_ROUND_UP(10
> * ui, temp), that is, the time for dphy->clk_pre is no less than 
> 10 * ui.  The D-PHY spec (v1.2)'s saying is that the minimum time for
> dphy->clk_pre is 8 * ui.  So, it looks like meson is stricter than the
> spec.
> 
> However, the vendor code doesn't seem to match the current meson driver
> implementation.  The temp in driver code is also TxByteClkHS period
> time in picoseconds. And, without this patch, I'm assuming that
> priv->config.clk_pre is 8000.  So, it looks like MIPI_DSI_CLK_TIM1 is
> set to DIV_ROUND_UP(8000, temp).  This '8000' does _not_ reflect
> '10 * ui'.
> 
> So, 3 choices for meson, up to you:
> 1) If meson really requires the time for clk_pre no less than
> 10 * ui, then sth like DIV_ROUND_UP(10, BITS_PER_BYTE) can be used.
> 2) If meson follows the spec's minimum value, then the patch does
> things right for meson.
> 3) Force to use 8000 picoseconds for clk_pre, that is, use sth like
> DIV_ROUND_UP(8000, temp).
> 
> With this patch applied, do you see any display artifacts by visual
> check? Or even checked signals through DSI analyzer?

Thanks for the feedback, I'm currently trying to put the setup back to
run a test with this change.

Neil

> 
> Regards,
> Liu Ying
> 
>>
>> PHY Registers only says:
>> MIPI_DSI_CLK_TIM1	[31:0]
>> 7:0 	R/W	0	 tCLK_PRE
>>
>>> Neil
>>>
>>
>> [...]
> 



From narmstrong at baylibre.com  Wed Jan 19 02:47:01 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 19 Jan 2022 11:47:01 +0100
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <e02c9226-2dfb-5931-60e3-a22e51172c30@baylibre.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
 <28e3f723-daf0-b3c5-ee10-519c4cabfe17@baylibre.com>
 <5a638561-c704-49e7-1fed-70e26fedb186@baylibre.com>
 <8ad2cd76e80056192395ca5b73ff514e59881ba3.camel@nxp.com>
 <e02c9226-2dfb-5931-60e3-a22e51172c30@baylibre.com>
Message-ID: <661a7c69-0da6-32f5-ffa0-58426c5825e0@baylibre.com>

Hi,

On 19/01/2022 11:11, Neil Armstrong wrote:
> Hi,
> 
> On 19/01/2022 11:01, Liu Ying wrote:
>> Hi Neil,
>>
>> On Wed, 2022-01-19 at 10:11 +0100, Neil Armstrong wrote:
>>> On 19/01/2022 09:40, Neil Armstrong wrote:
>>>> Hi,
>>>>
>>>> On 19/01/2022 03:37, Liu Ying wrote:
>>>>> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
>>>>> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
>>>>> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
>>>>> mentions that it should be in UI.  However, the dphy core driver wrongly
>>>>> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
>>>>> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
>>>>> is '8 UI', instead of 8.
>>>>>
>>>>> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
>>>>> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
>>>>> value according to the D-PHY specification.
>>>>>
>>>>> I'm assuming that all impacted custom drivers shall program values in
>>>>> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
>>>>> specification mentions that the frequency of TxByteClkHS is exactly 1/8
>>>>> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
>>>>> custom driver code is changed to program those values as
>>>>> DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
>>>>>
>>>>> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
>>>>> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
>>>>> as I don't have the hardwares.
>>>>>
>>>>> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
>>>>> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
>>>>> Cc: Neil Armstrong <narmstrong at baylibre.com>
>>>>> Cc: Robert Foss <robert.foss at linaro.org>
>>>>> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
>>>>> Cc: Jonas Karlman <jonas at kwiboo.se>
>>>>> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
>>>>> Cc: David Airlie <airlied at linux.ie>
>>>>> Cc: Daniel Vetter <daniel at ffwll.ch>
>>>>> Cc: Kishon Vijay Abraham I <kishon at ti.com>
>>>>> Cc: Vinod Koul <vkoul at kernel.org>
>>>>> Cc: Kevin Hilman <khilman at baylibre.com>
>>>>> Cc: Jerome Brunet <jbrunet at baylibre.com>
>>>>> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
>>>>> Cc: Heiko Stuebner <heiko at sntech.de>
>>>>> Cc: Maxime Ripard <mripard at kernel.org>
>>>>> Cc: Guido G?nther <agx at sigxcpu.org>
>>>>> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
>>>>> Signed-off-by: Liu Ying <victor.liu at nxp.com>
>>>>> ---
>>>>> v1->v2:
>>>>> * Use BITS_PER_BYTE macro. (Andrzej)
>>>>> * Drop dsi argument from ui2bc() in nwl-dsi.c.
>>>>>
>>>>>  drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
>>>>>  drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
>>>>>  drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
>>>>>  drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
>>>>>  include/linux/phy/phy-mipi-dphy.h                |  2 +-
>>>>>  5 files changed, 12 insertions(+), 12 deletions(-)
>>>>>
>>> [...]
>>>
>>>>> diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>>>>> index cd2332bf0e31..fdbd64c03e12 100644
>>>>> --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>>>>> +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>>>>> @@ -9,6 +9,7 @@
>>>>>  
>>>>>  #include <linux/bitfield.h>
>>>>>  #include <linux/bitops.h>
>>>>> +#include <linux/bits.h>
>>>>>  #include <linux/clk.h>
>>>>>  #include <linux/delay.h>
>>>>>  #include <linux/io.h>
>>>>> @@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
>>>>>  		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
>>>>>  		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
>>>>>  	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
>>>>> -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
>>>>> +		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
>>>>>  
>>>>>  	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
>>>>>  		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
>>>>
>>>> I'll try to run a test, currently the calculation gives 2, so this would give 1.
>>>
>>> The Amlogic vendor code does:
>>>
>>> /* >8*ui */
>>> #define DPHY_TIME_CLK_PRE(ui)       (10 * ui)
>>
>> This looks like clk_pre time is 10 * ui, which matches the comment
>> '>8*ui' - longer time 8 * ui.
>>
>>>
>>> t_ui = lcd_timing.bit_rate
>>>
>>> t_ui = (1000000 * 100) / (dsi_ui / 1000); /*100*ns */
>>> temp = t_ui * 8; /* lane_byte cycle time */
>>
>> If I read correctly, this temp in vendor code is TxByteClkHS period
>> time in picoseconds. So...
>>
>>>
>>> dphy->clk_pre = ((DPHY_TIME_CLK_PRE(t_ui) + temp - 1) / temp) & 0xff;
>>
>> IIUC, 'dphy->clk_pre' essentially means dphy->clk_pre = DIV_ROUND_UP(10
>> * ui, temp), that is, the time for dphy->clk_pre is no less than 
>> 10 * ui.  The D-PHY spec (v1.2)'s saying is that the minimum time for
>> dphy->clk_pre is 8 * ui.  So, it looks like meson is stricter than the
>> spec.
>>
>> However, the vendor code doesn't seem to match the current meson driver
>> implementation.  The temp in driver code is also TxByteClkHS period
>> time in picoseconds. And, without this patch, I'm assuming that
>> priv->config.clk_pre is 8000.  So, it looks like MIPI_DSI_CLK_TIM1 is
>> set to DIV_ROUND_UP(8000, temp).  This '8000' does _not_ reflect
>> '10 * ui'.
>>
>> So, 3 choices for meson, up to you:
>> 1) If meson really requires the time for clk_pre no less than
>> 10 * ui, then sth like DIV_ROUND_UP(10, BITS_PER_BYTE) can be used.
>> 2) If meson follows the spec's minimum value, then the patch does
>> things right for meson.
>> 3) Force to use 8000 picoseconds for clk_pre, that is, use sth like
>> DIV_ROUND_UP(8000, temp).
>>
>> With this patch applied, do you see any display artifacts by visual
>> check? Or even checked signals through DSI analyzer?
> 
> Thanks for the feedback, I'm currently trying to put the setup back to
> run a test with this change.

I don't see any visible artifacts.

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com> # for phy-meson-axg-mipi-dphy.c
Tested-by: Neil Armstrong <narmstrong at baylibre.com> # for phy-meson-axg-mipi-dphy.c

Thanks,

> 
> Neil
> 
>>
>> Regards,
>> Liu Ying
>>
>>>
>>> PHY Registers only says:
>>> MIPI_DSI_CLK_TIM1	[31:0]
>>> 7:0 	R/W	0	 tCLK_PRE
>>>
>>>> Neil
>>>>
>>>
>>> [...]
>>
> 



From agx at sigxcpu.org  Wed Jan 19 03:47:12 2022
From: agx at sigxcpu.org (Guido =?iso-8859-1?Q?G=FCnther?=)
Date: Wed, 19 Jan 2022 12:47:12 +0100
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <20220119023714.1498508-1-victor.liu@nxp.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
Message-ID: <Yef6QJMNm1AAabp/@qwark.sigxcpu.org>

Hi,
On Wed, Jan 19, 2022 at 10:37:14AM +0800, Liu Ying wrote:
> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> mentions that it should be in UI.  However, the dphy core driver wrongly
> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> is '8 UI', instead of 8.
> 
> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
> value according to the D-PHY specification.
> 
> I'm assuming that all impacted custom drivers shall program values in
> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
> specification mentions that the frequency of TxByteClkHS is exactly 1/8
> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
> custom driver code is changed to program those values as
> DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
> 
> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
> as I don't have the hardwares.
> 
> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Robert Foss <robert.foss at linaro.org>
> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> Cc: Jonas Karlman <jonas at kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> Cc: David Airlie <airlied at linux.ie>
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Cc: Vinod Koul <vkoul at kernel.org>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: Heiko Stuebner <heiko at sntech.de>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Guido G?nther <agx at sigxcpu.org>
> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
> Signed-off-by: Liu Ying <victor.liu at nxp.com>
> ---
> v1->v2:
> * Use BITS_PER_BYTE macro. (Andrzej)
> * Drop dsi argument from ui2bc() in nwl-dsi.c.
> 
>  drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
>  drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
>  drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
>  drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
>  include/linux/phy/phy-mipi-dphy.h                |  2 +-
>  5 files changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
> index a7389a0facfb..af07eeb47ca0 100644
> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> @@ -7,6 +7,7 @@
>   */
>  
>  #include <linux/bitfield.h>
> +#include <linux/bits.h>
>  #include <linux/clk.h>
>  #include <linux/irq.h>
>  #include <linux/math64.h>
> @@ -196,12 +197,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
>  /*
>   * ui2bc - UI time periods to byte clock cycles
>   */
> -static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
> +static u32 ui2bc(unsigned int ui)
>  {
> -	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> -
> -	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
> -				  dsi->mode.clock * 1000 * bpp);
> +	return DIV_ROUND_UP(ui, BITS_PER_BYTE);
>  }
>  
>  /*
> @@ -232,12 +230,12 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi)
>  	}
>  
>  	/* values in byte clock cycles */
> -	cycles = ui2bc(dsi, cfg->clk_pre);
> +	cycles = ui2bc(cfg->clk_pre);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
>  	nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
>  	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
> -	cycles += ui2bc(dsi, cfg->clk_pre);
> +	cycles += ui2bc(cfg->clk_pre);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
>  	nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
>  	cycles = ps2bc(dsi, cfg->hs_exit);
> diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> index cd2332bf0e31..fdbd64c03e12 100644
> --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> @@ -9,6 +9,7 @@
>  
>  #include <linux/bitfield.h>
>  #include <linux/bitops.h>
> +#include <linux/bits.h>
>  #include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/io.h>
> @@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
>  		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
>  		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
>  	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
> -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
> +		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
>  
>  	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
>  		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
> diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
> index 288c9c67aa74..ccb4045685cd 100644
> --- a/drivers/phy/phy-core-mipi-dphy.c
> +++ b/drivers/phy/phy-core-mipi-dphy.c
> @@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
>  
>  	cfg->clk_miss = 0;
>  	cfg->clk_post = 60000 + 52 * ui;
> -	cfg->clk_pre = 8000;
> +	cfg->clk_pre = 8;
>  	cfg->clk_prepare = 38000;
>  	cfg->clk_settle = 95000;
>  	cfg->clk_term_en = 0;
> @@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
>  	if (cfg->clk_post < (60000 + 52 * ui))
>  		return -EINVAL;
>  
> -	if (cfg->clk_pre < 8000)
> +	if (cfg->clk_pre < 8)
>  		return -EINVAL;
>  
>  	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> index 347dc79a18c1..630e01b5c19b 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> @@ -5,6 +5,7 @@
>   * Author: Wyon Bi <bivvy.bi at rock-chips.com>
>   */
>  
> +#include <linux/bits.h>
>  #include <linux/kernel.h>
>  #include <linux/clk.h>
>  #include <linux/iopoll.h>
> @@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
>  	 * The value of counter for HS Tclk-pre
>  	 * Tclk-pre = Tpin_txbyteclkhs * value
>  	 */
> -	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
> +	clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);
>  
>  	/*
>  	 * The value of counter for HS Tlpx Time
> diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
> index a877ffee845d..59a5e77ab409 100644
> --- a/include/linux/phy/phy-mipi-dphy.h
> +++ b/include/linux/phy/phy-mipi-dphy.h
> @@ -42,7 +42,7 @@ struct phy_configure_opts_mipi_dphy {
>  	 * the transmitter prior to any associated Data Lane beginning
>  	 * the transition from LP to HS mode.
>  	 *
> -	 * Minimum value: 8 UI
> +	 * Minimum value: 8
>  	 */
>  	unsigned int		clk_pre;


Tested on the Librem 5 (imx8mq) with it's rather picky panel:

Tested-by: Guido G?nther <agx at sigxcpu.org>

Cheers
 -- Guido


>  
> -- 
> 2.25.1
> 


From maz at kernel.org  Wed Jan 19 05:31:58 2022
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 19 Jan 2022 13:31:58 +0000
Subject: [PATCH v2 2/4] irqchip/meson-gpio: support more than 8 channels
 gpio irq line
In-Reply-To: <20220119070809.15563-3-qianggui.song@amlogic.com>
References: <20220119070809.15563-1-qianggui.song@amlogic.com>
 <20220119070809.15563-3-qianggui.song@amlogic.com>
Message-ID: <87czkn97ht.wl-maz@kernel.org>

On Wed, 19 Jan 2022 07:08:07 +0000,
Qianggui Song <qianggui.song at amlogic.com> wrote:
> 
> Current meson gpio irqchip driver only support 8 channels for gpio irq
> line, later chips may have more then 8 channels, so need to modify code
> to support more.
> 
> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
> ---
>  drivers/irqchip/irq-meson-gpio.c | 33 +++++++++++++++++++++++---------
>  1 file changed, 24 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
> index d90ff0b92480..eefe15e1b3a6 100644
> --- a/drivers/irqchip/irq-meson-gpio.c
> +++ b/drivers/irqchip/irq-meson-gpio.c
> @@ -16,7 +16,6 @@
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  
> -#define NUM_CHANNEL 8
>  #define MAX_INPUT_MUX 256
>  
>  #define REG_EDGE_POL	0x00
> @@ -60,6 +59,7 @@ struct irq_ctl_ops {
>  
>  struct meson_gpio_irq_params {
>  	unsigned int nr_hwirq;
> +	unsigned int nr_channels;
>  	bool support_edge_both;
>  	unsigned int edge_both_offset;
>  	unsigned int edge_single_offset;
> @@ -81,6 +81,7 @@ struct meson_gpio_irq_params {
>  	.edge_single_offset = 0,				\
>  	.pol_low_offset = 16,					\
>  	.pin_sel_mask = 0xff,					\
> +	.nr_channels = 8,					\
>  
>  #define INIT_MESON_A1_COMMON_DATA(irqs)				\
>  	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
> @@ -90,6 +91,7 @@ struct meson_gpio_irq_params {
>  	.edge_single_offset = 8,				\
>  	.pol_low_offset = 0,					\
>  	.pin_sel_mask = 0x7f,					\
> +	.nr_channels = 8,					\
>  
>  static const struct meson_gpio_irq_params meson8_params = {
>  	INIT_MESON8_COMMON_DATA(134)
> @@ -136,8 +138,8 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
>  struct meson_gpio_irq_controller {
>  	const struct meson_gpio_irq_params *params;
>  	void __iomem *base;
> -	u32 channel_irqs[NUM_CHANNEL];
> -	DECLARE_BITMAP(channel_map, NUM_CHANNEL);
> +	u32 *channel_irqs;
> +	unsigned long *channel_map;

This really is over-engineering at its best.

With your new fancy HW, you have at most 12 bits being used in this
bitmap. So why not have a single unsigned long, no dynamic allocation,
and simply an assertion somewhere that checks that nr_channel is never
bigger than BITS_PER_LONG? Less code, less memory wasted, less problems.

	M.

-- 
Without deviation from the norm, progress is not possible.


From khilman at baylibre.com  Wed Jan 19 14:37:00 2022
From: khilman at baylibre.com (Kevin Hilman)
Date: Wed, 19 Jan 2022 14:37:00 -0800
Subject: [PATCH V6 0/5] Use CCF to describe the UART baud rate clock
In-Reply-To: <20220118030911.12815-1-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
Message-ID: <7hfspjqrn7.fsf@baylibre.com>

Hello,

Yu Tu <yu.tu at amlogic.com> writes:

> Using the common Clock code to describe the UART baud rate
> clock makes it easier for the UART driver to be compatible
> with the baud rate requirements of the UART IP on different
> meson chips. Add Meson S4 SoC compatible.

Could you describe how this was tested and on which SoCs?  There seem to
be some changes in this series that might affect previous SoCs.

Thanks,

Kevin




From victor.liu at nxp.com  Wed Jan 19 19:00:26 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Thu, 20 Jan 2022 11:00:26 +0800
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <20220119023714.1498508-1-victor.liu@nxp.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
Message-ID: <c371d737fd5e7e19e966d7aec42da0c3edd9a556.camel@nxp.com>

Hi Heiko, Wyon,

On Wed, 2022-01-19 at 10:37 +0800, Liu Ying wrote:
> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> mentions that it should be in UI.  However, the dphy core driver wrongly
> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> is '8 UI', instead of 8.
> 
> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
> value according to the D-PHY specification.
> 
> I'm assuming that all impacted custom drivers shall program values in
> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
> specification mentions that the frequency of TxByteClkHS is exactly 1/8
> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
> custom driver code is changed to program those values as
> DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
> 
> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
> as I don't have the hardwares.
> 
> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Robert Foss <robert.foss at linaro.org>
> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> Cc: Jonas Karlman <jonas at kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> Cc: David Airlie <airlied at linux.ie>
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Cc: Vinod Koul <vkoul at kernel.org>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: Heiko Stuebner <heiko at sntech.de>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Guido G?nther <agx at sigxcpu.org>
> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
> Signed-off-by: Liu Ying <victor.liu at nxp.com>
> ---
> v1->v2:
> * Use BITS_PER_BYTE macro. (Andrzej)
> * Drop dsi argument from ui2bc() in nwl-dsi.c.
> 
>  drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
>  drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
>  drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
>  drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
>  include/linux/phy/phy-mipi-dphy.h                |  2 +-
>  5 files changed, 12 insertions(+), 12 deletions(-)

[...]

> diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
> index 288c9c67aa74..ccb4045685cd 100644
> --- a/drivers/phy/phy-core-mipi-dphy.c
> +++ b/drivers/phy/phy-core-mipi-dphy.c
> @@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
>  
>  	cfg->clk_miss = 0;
>  	cfg->clk_post = 60000 + 52 * ui;
> -	cfg->clk_pre = 8000;
> +	cfg->clk_pre = 8;
>  	cfg->clk_prepare = 38000;
>  	cfg->clk_settle = 95000;
>  	cfg->clk_term_en = 0;
> @@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
>  	if (cfg->clk_post < (60000 + 52 * ui))
>  		return -EINVAL;
>  
> -	if (cfg->clk_pre < 8000)
> +	if (cfg->clk_pre < 8)
>  		return -EINVAL;
>  
>  	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> index 347dc79a18c1..630e01b5c19b 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> @@ -5,6 +5,7 @@
>   * Author: Wyon Bi <bivvy.bi at rock-chips.com>
>   */
>  
> +#include <linux/bits.h>
>  #include <linux/kernel.h>
>  #include <linux/clk.h>
>  #include <linux/iopoll.h>
> @@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
>  	 * The value of counter for HS Tclk-pre
>  	 * Tclk-pre = Tpin_txbyteclkhs * value
>  	 */
> -	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
> +	clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);

For the Rockchip part, can you please give a test? Any comments?

We already have T-b tags on i.MX8mq and Meson platforms.

Regards,
Liu Ying

>  
>  	/*
>  	 * The value of counter for HS Tlpx Time
> diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
> index a877ffee845d..59a5e77ab409 100644
> --- a/include/linux/phy/phy-mipi-dphy.h
> +++ b/include/linux/phy/phy-mipi-dphy.h
> @@ -42,7 +42,7 @@ struct phy_configure_opts_mipi_dphy {
>  	 * the transmitter prior to any associated Data Lane beginning
>  	 * the transition from LP to HS mode.
>  	 *
> -	 * Minimum value: 8 UI
> +	 * Minimum value: 8
>  	 */
>  	unsigned int		clk_pre;
>  



From narmstrong at baylibre.com  Thu Jan 20 00:33:51 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 09:33:51 +0100
Subject: [PATCH v2 0/6] drm/meson: add support for MIPI DSI Display
Message-ID: <20220120083357.1541262-1-narmstrong@baylibre.com>

The Amlogic G12A, G12B & SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
glue on the same Amlogic SoCs.

This adds support for the glue managing the transceiver, mimicing the init flow provided
by Amlogic to setup the ENCL encoder, the glue, the transceiver, the digital D-PHY and the
Analog PHY in the proper way.

The DW-MIPI-DSI transceiver + D-PHY are clocked by the GP0 PLL, and the ENCL encoder + VIU
pixel reader by the VCLK2 clock using the HDMI PLL.

The DW-MIPI-DSI transceiver gets this pixel stream as input clocked with the VCLK2 clock.

An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
DW-MIPI-DSI transceiver.

This patchset is based on an earlier attempt at [1] for the AXG SoCs, but:
- the AXG has a single clock source for both transceiver + pixel, which makes it an
  exception instead of a rule, it's simpler to add support for G12A then add AXG on it
- previous glue code was a single monolitic code mixing encoders & bridges, this version
  is aligned on the previous cleanup done on HDMI & CVBS bridges architecture at [2]
- since the only output of AXG is DSI, AXG VPU support is post-poned until we implement
  single-clock DSI support specific case on top of this.

Changes from v1 at [3]:
- fixed DSI host bindings
- add reviewed-by tags for bindings
- moved magic values to defines thanks to Martin's searches
- added proper prefixes to defines
- moved phy_configure to phy_init() dw-mipi-dsi callback
- moved phy_on to a new phy_power_on() dw-mipi-dsi callback
- correctly return phy_init/configure errors to callback returns

[1] https://lore.kernel.org/r/20200907081825.1654-1-narmstrong at baylibre.com
[2] https://lore.kernel.org/r/20211020123947.2585572-1-narmstrong at baylibre.com

Neil Armstrong (6):
  dt-bindings: display: add Amlogic MIPI DSI Host Controller bindings
  dt-bindings: display: meson-vpu: add third DPI output port
  drm/meson: venc: add ENCL encoder setup for MIPI-DSI output
  drm/meson: vclk: add DSI clock config
  drm/meson: add DSI encoder
  drm/meson: add support for MIPI-DSI transceiver

 .../display/amlogic,meson-dw-mipi-dsi.yaml    | 116 ++++++
 .../bindings/display/amlogic,meson-vpu.yaml   |   5 +
 drivers/gpu/drm/meson/Kconfig                 |   7 +
 drivers/gpu/drm/meson/Makefile                |   3 +-
 drivers/gpu/drm/meson/meson_drv.c             |   7 +
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c     | 357 ++++++++++++++++++
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h     | 160 ++++++++
 drivers/gpu/drm/meson/meson_encoder_dsi.c     | 160 ++++++++
 drivers/gpu/drm/meson/meson_encoder_dsi.h     |  12 +
 drivers/gpu/drm/meson/meson_registers.h       |  15 +
 drivers/gpu/drm/meson/meson_vclk.c            |  47 +++
 drivers/gpu/drm/meson/meson_vclk.h            |   1 +
 drivers/gpu/drm/meson/meson_venc.c            | 211 ++++++++++-
 drivers/gpu/drm/meson/meson_venc.h            |   6 +
 drivers/gpu/drm/meson/meson_vpp.h             |   2 +
 15 files changed, 1106 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
 create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
 create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
 create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.c
 create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.h

-- 
2.25.1



From narmstrong at baylibre.com  Thu Jan 20 00:33:52 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 09:33:52 +0100
Subject: [PATCH v2 1/6] dt-bindings: display: add Amlogic MIPI DSI Host
 Controller bindings
In-Reply-To: <20220120083357.1541262-1-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
Message-ID: <20220120083357.1541262-2-narmstrong@baylibre.com>

The Amlogic G12A, G12B & SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI Glue
on the same Amlogic SoCs.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../display/amlogic,meson-dw-mipi-dsi.yaml    | 116 ++++++++++++++++++
 1 file changed, 116 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml

diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
new file mode 100644
index 000000000000..e057659545a9
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
@@ -0,0 +1,116 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2020 BayLibre, SAS
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/display/amlogic,meson-dw-mipi-dsi.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Amlogic specific extensions to the Synopsys Designware MIPI DSI Host Controller
+
+maintainers:
+  - Neil Armstrong <narmstrong at baylibre.com>
+
+description: |
+  The Amlogic Meson Synopsys Designware Integration is composed of
+  - A Synopsys DesignWare MIPI DSI Host Controller IP
+  - A TOP control block controlling the Clocks & Resets of the IP
+
+allOf:
+  - $ref: dsi-controller.yaml#
+
+properties:
+  compatible:
+    enum:
+      - amlogic,meson-g12a-dw-mipi-dsi
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    minItems: 2
+
+  clock-names:
+    minItems: 2
+    items:
+      - const: pclk
+      - const: px_clk
+      - const: meas_clk
+
+  resets:
+    minItems: 1
+
+  reset-names:
+    items:
+      - const: top
+
+  phys:
+    minItems: 1
+
+  phy-names:
+    items:
+      - const: dphy
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Input node to receive pixel data.
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: DSI output node to panel.
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - phys
+  - phy-names
+  - ports
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    dsi at 7000 {
+          compatible = "amlogic,meson-g12a-dw-mipi-dsi";
+          reg = <0x6000 0x400>;
+          resets = <&reset_top>;
+          reset-names = "top";
+          clocks = <&clk_pclk>, <&clk_px>;
+          clock-names = "pclk", "px_clk";
+          phys = <&mipi_dphy>;
+          phy-names = "dphy";
+
+          ports {
+              #address-cells = <1>;
+              #size-cells = <0>;
+
+              /* VPU VENC Input */
+              mipi_dsi_venc_port: port at 0 {
+                  reg = <0>;
+
+                  mipi_dsi_in: endpoint {
+                       remote-endpoint = <&dpi_out>;
+                  };
+              };
+
+              /* DSI Output */
+              mipi_dsi_panel_port: port at 1 {
+                  reg = <1>;
+
+                  mipi_out_panel: endpoint {
+                      remote-endpoint = <&mipi_in_panel>;
+                  };
+              };
+          };
+    };
-- 
2.25.1



From narmstrong at baylibre.com  Thu Jan 20 00:33:53 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 09:33:53 +0100
Subject: [PATCH v2 2/6] dt-bindings: display: meson-vpu: add third DPI output
 port
In-Reply-To: <20220120083357.1541262-1-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
Message-ID: <20220120083357.1541262-3-narmstrong@baylibre.com>

Add third port corresponding to the ENCL DPI encoder used to connect
to DSI or LVDS transceivers.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../devicetree/bindings/display/amlogic,meson-vpu.yaml       | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
index 851cb0781217..525a01a38568 100644
--- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
+++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
@@ -92,6 +92,11 @@ properties:
     description:
       A port node pointing to the HDMI-TX port node.
 
+  port at 2:
+    $ref: /schemas/graph.yaml#/properties/port
+    description:
+      A port node pointing to the DPI port node (e.g. DSI or LVDS transceiver).
+
   "#address-cells":
     const: 1
 
-- 
2.25.1



From narmstrong at baylibre.com  Thu Jan 20 00:33:54 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 09:33:54 +0100
Subject: [PATCH v2 3/6] drm/meson: venc: add ENCL encoder setup for MIPI-DSI
 output
In-Reply-To: <20220120083357.1541262-1-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
Message-ID: <20220120083357.1541262-4-narmstrong@baylibre.com>

This adds supports for the ENCL encoder connected to a MIPI-DSI transceiver on the
Amlogic AXG, G12A, G12B & SM1 SoCs.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpu/drm/meson/meson_registers.h |  15 ++
 drivers/gpu/drm/meson/meson_venc.c      | 211 +++++++++++++++++++++++-
 drivers/gpu/drm/meson/meson_venc.h      |   6 +
 drivers/gpu/drm/meson/meson_vpp.h       |   2 +
 4 files changed, 232 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h
index 0f3cafab8860..a422a8df1641 100644
--- a/drivers/gpu/drm/meson/meson_registers.h
+++ b/drivers/gpu/drm/meson/meson_registers.h
@@ -1300,13 +1300,28 @@
 #define RDMA_STATUS2 0x1116
 #define RDMA_STATUS3 0x1117
 #define L_GAMMA_CNTL_PORT 0x1400
+#define		L_GAMMA_CNTL_PORT_VCOM_POL	BIT(7)	/* RW */
+#define		L_GAMMA_CNTL_PORT_RVS_OUT	BIT(6)	/* RW */
+#define		L_GAMMA_CNTL_PORT_ADR_RDY	BIT(5)	/* Read Only */
+#define		L_GAMMA_CNTL_PORT_WR_RDY	BIT(4)	/* Read Only */
+#define		L_GAMMA_CNTL_PORT_RD_RDY	BIT(3)	/* Read Only */
+#define		L_GAMMA_CNTL_PORT_TR		BIT(2)	/* RW */
+#define		L_GAMMA_CNTL_PORT_SET		BIT(1)	/* RW */
+#define		L_GAMMA_CNTL_PORT_EN		BIT(0)	/* RW */
 #define L_GAMMA_DATA_PORT 0x1401
 #define L_GAMMA_ADDR_PORT 0x1402
+#define		L_GAMMA_ADDR_PORT_RD		BIT(12)
+#define		L_GAMMA_ADDR_PORT_AUTO_INC	BIT(11)
+#define		L_GAMMA_ADDR_PORT_SEL_R		BIT(10)
+#define		L_GAMMA_ADDR_PORT_SEL_G		BIT(9)
+#define		L_GAMMA_ADDR_PORT_SEL_B		BIT(8)
+#define		L_GAMMA_ADDR_PORT_ADDR		GENMASK(7, 0)
 #define L_GAMMA_VCOM_HSWITCH_ADDR 0x1403
 #define L_RGB_BASE_ADDR 0x1405
 #define L_RGB_COEFF_ADDR 0x1406
 #define L_POL_CNTL_ADDR 0x1407
 #define L_DITH_CNTL_ADDR 0x1408
+#define		L_DITH_CNTL_DITH10_EN	BIT(10)
 #define L_GAMMA_PROBE_CTRL 0x1409
 #define L_GAMMA_PROBE_COLOR_L 0x140a
 #define L_GAMMA_PROBE_COLOR_H 0x140b
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
index 3c55ed003359..eb2ac0549d46 100644
--- a/drivers/gpu/drm/meson/meson_venc.c
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/export.h>
+#include <linux/iopoll.h>
 
 #include <drm/drm_modes.h>
 
@@ -1557,6 +1558,205 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
 }
 EXPORT_SYMBOL_GPL(meson_venc_hdmi_mode_set);
 
+static unsigned short meson_encl_gamma_table[256] = {
+	0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
+	64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
+	128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188,
+	192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252,
+	256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 304, 308, 312, 316,
+	320, 324, 328, 332, 336, 340, 344, 348, 352, 356, 360, 364, 368, 372, 376, 380,
+	384, 388, 392, 396, 400, 404, 408, 412, 416, 420, 424, 428, 432, 436, 440, 444,
+	448, 452, 456, 460, 464, 468, 472, 476, 480, 484, 488, 492, 496, 500, 504, 508,
+	512, 516, 520, 524, 528, 532, 536, 540, 544, 548, 552, 556, 560, 564, 568, 572,
+	576, 580, 584, 588, 592, 596, 600, 604, 608, 612, 616, 620, 624, 628, 632, 636,
+	640, 644, 648, 652, 656, 660, 664, 668, 672, 676, 680, 684, 688, 692, 696, 700,
+	704, 708, 712, 716, 720, 724, 728, 732, 736, 740, 744, 748, 752, 756, 760, 764,
+	768, 772, 776, 780, 784, 788, 792, 796, 800, 804, 808, 812, 816, 820, 824, 828,
+	832, 836, 840, 844, 848, 852, 856, 860, 864, 868, 872, 876, 880, 884, 888, 892,
+	896, 900, 904, 908, 912, 916, 920, 924, 928, 932, 936, 940, 944, 948, 952, 956,
+	960, 964, 968, 972, 976, 980, 984, 988, 992, 996, 1000, 1004, 1008, 1012, 1016, 1020,
+};
+
+static void meson_encl_set_gamma_table(struct meson_drm *priv, u16 *data,
+				       u32 rgb_mask)
+{
+	int i, ret;
+	u32 reg;
+
+	writel_bits_relaxed(L_GAMMA_CNTL_PORT_EN, 0,
+			    priv->io_base + _REG(L_GAMMA_CNTL_PORT));
+
+	ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT),
+					 reg, reg & L_GAMMA_CNTL_PORT_ADR_RDY, 10, 10000);
+	if (ret)
+		pr_warn("%s: GAMMA ADR_RDY timeout\n", __func__);
+
+	writel_relaxed(L_GAMMA_ADDR_PORT_AUTO_INC | rgb_mask |
+		       FIELD_PREP(L_GAMMA_ADDR_PORT_ADDR, 0),
+		       priv->io_base + _REG(L_GAMMA_ADDR_PORT));
+
+	for (i = 0; i < 256; i++) {
+		ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT),
+						 reg, reg & L_GAMMA_CNTL_PORT_WR_RDY,
+						 10, 10000);
+		if (ret)
+			pr_warn_once("%s: GAMMA WR_RDY timeout\n", __func__);
+
+		writel_relaxed(data[i], priv->io_base + _REG(L_GAMMA_DATA_PORT));
+	}
+
+	ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT),
+					 reg, reg & L_GAMMA_CNTL_PORT_ADR_RDY, 10, 10000);
+	if (ret)
+		pr_warn("%s: GAMMA ADR_RDY timeout\n", __func__);
+
+	writel_relaxed(L_GAMMA_ADDR_PORT_AUTO_INC | rgb_mask |
+		       FIELD_PREP(L_GAMMA_ADDR_PORT_ADDR, 0x23),
+		       priv->io_base + _REG(L_GAMMA_ADDR_PORT));
+}
+
+void meson_encl_load_gamma(struct meson_drm *priv)
+{
+	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_R);
+	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_G);
+	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_B);
+
+	writel_bits_relaxed(L_GAMMA_CNTL_PORT_EN, L_GAMMA_CNTL_PORT_EN,
+			    priv->io_base + _REG(L_GAMMA_CNTL_PORT));
+}
+
+void meson_venc_mipi_dsi_mode_set(struct meson_drm *priv,
+				  const struct drm_display_mode *mode)
+{
+	unsigned int max_pxcnt;
+	unsigned int max_lncnt;
+	unsigned int havon_begin;
+	unsigned int havon_end;
+	unsigned int vavon_bline;
+	unsigned int vavon_eline;
+	unsigned int hso_begin;
+	unsigned int hso_end;
+	unsigned int vso_begin;
+	unsigned int vso_end;
+	unsigned int vso_bline;
+	unsigned int vso_eline;
+
+	max_pxcnt = mode->htotal - 1;
+	max_lncnt = mode->vtotal - 1;
+	havon_begin = mode->htotal - mode->hsync_start;
+	havon_end = havon_begin + mode->hdisplay - 1;
+	vavon_bline = mode->vtotal - mode->vsync_start;
+	vavon_eline = vavon_bline + mode->vdisplay - 1;
+	hso_begin = 0;
+	hso_end = mode->hsync_end - mode->hsync_start;
+	vso_begin = 0;
+	vso_end = 0;
+	vso_bline = 0;
+	vso_eline = mode->vsync_end - mode->vsync_start;
+
+	meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCL);
+
+	writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
+
+	writel_relaxed(ENCL_PX_LN_CNT_SHADOW_EN, priv->io_base + _REG(ENCL_VIDEO_MODE));
+	writel_relaxed(ENCL_VIDEO_MODE_ADV_VFIFO_EN |
+		       ENCL_VIDEO_MODE_ADV_GAIN_HDTV |
+		       ENCL_SEL_GAMMA_RGB_IN, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
+
+	writel_relaxed(ENCL_VIDEO_FILT_CTRL_BYPASS_FILTER,
+		       priv->io_base + _REG(ENCL_VIDEO_FILT_CTRL));
+	writel_relaxed(max_pxcnt, priv->io_base + _REG(ENCL_VIDEO_MAX_PXCNT));
+	writel_relaxed(max_lncnt, priv->io_base + _REG(ENCL_VIDEO_MAX_LNCNT));
+	writel_relaxed(havon_begin, priv->io_base + _REG(ENCL_VIDEO_HAVON_BEGIN));
+	writel_relaxed(havon_end, priv->io_base + _REG(ENCL_VIDEO_HAVON_END));
+	writel_relaxed(vavon_bline, priv->io_base + _REG(ENCL_VIDEO_VAVON_BLINE));
+	writel_relaxed(vavon_eline, priv->io_base + _REG(ENCL_VIDEO_VAVON_ELINE));
+
+	writel_relaxed(hso_begin, priv->io_base + _REG(ENCL_VIDEO_HSO_BEGIN));
+	writel_relaxed(hso_end, priv->io_base + _REG(ENCL_VIDEO_HSO_END));
+	writel_relaxed(vso_begin, priv->io_base + _REG(ENCL_VIDEO_VSO_BEGIN));
+	writel_relaxed(vso_end, priv->io_base + _REG(ENCL_VIDEO_VSO_END));
+	writel_relaxed(vso_bline, priv->io_base + _REG(ENCL_VIDEO_VSO_BLINE));
+	writel_relaxed(vso_eline, priv->io_base + _REG(ENCL_VIDEO_VSO_ELINE));
+	writel_relaxed(ENCL_VIDEO_RGBIN_RGB | ENCL_VIDEO_RGBIN_ZBLK,
+		       priv->io_base + _REG(ENCL_VIDEO_RGBIN_CTRL));
+
+	/* default black pattern */
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_MDSEL));
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_Y));
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CB));
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CR));
+	writel_relaxed(1, priv->io_base + _REG(ENCL_TST_EN));
+	writel_bits_relaxed(ENCL_VIDEO_MODE_ADV_VFIFO_EN, 0,
+			    priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
+
+	writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
+
+	writel_relaxed(0, priv->io_base + _REG(L_RGB_BASE_ADDR));
+	writel_relaxed(0x400, priv->io_base + _REG(L_RGB_COEFF_ADDR)); /* Magic value */
+
+	writel_relaxed(L_DITH_CNTL_DITH10_EN, priv->io_base + _REG(L_DITH_CNTL_ADDR));
+
+	/* DE signal for TTL */
+	writel_relaxed(havon_begin, priv->io_base + _REG(L_OEH_HS_ADDR));
+	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_OEH_HE_ADDR));
+	writel_relaxed(vavon_bline, priv->io_base + _REG(L_OEH_VS_ADDR));
+	writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEH_VE_ADDR));
+
+	/* DE signal for TTL */
+	writel_relaxed(havon_begin, priv->io_base + _REG(L_OEV1_HS_ADDR));
+	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_OEV1_HE_ADDR));
+	writel_relaxed(vavon_bline, priv->io_base + _REG(L_OEV1_VS_ADDR));
+	writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEV1_VE_ADDR));
+
+	/* Hsync signal for TTL */
+	if (mode->flags & DRM_MODE_FLAG_PHSYNC) {
+		writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HS_ADDR));
+		writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HE_ADDR));
+	} else {
+		writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HS_ADDR));
+		writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HE_ADDR));
+	}
+	writel_relaxed(0, priv->io_base + _REG(L_STH1_VS_ADDR));
+	writel_relaxed(max_lncnt, priv->io_base + _REG(L_STH1_VE_ADDR));
+
+	/* Vsync signal for TTL */
+	writel_relaxed(vso_begin, priv->io_base + _REG(L_STV1_HS_ADDR));
+	writel_relaxed(vso_end, priv->io_base + _REG(L_STV1_HE_ADDR));
+	if (mode->flags & DRM_MODE_FLAG_PVSYNC) {
+		writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VS_ADDR));
+		writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VE_ADDR));
+	} else {
+		writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VS_ADDR));
+		writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VE_ADDR));
+	}
+
+	/* DE signal */
+	writel_relaxed(havon_begin, priv->io_base + _REG(L_DE_HS_ADDR));
+	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_DE_HE_ADDR));
+	writel_relaxed(vavon_bline, priv->io_base + _REG(L_DE_VS_ADDR));
+	writel_relaxed(vavon_eline, priv->io_base + _REG(L_DE_VE_ADDR));
+
+	/* Hsync signal */
+	writel_relaxed(hso_begin, priv->io_base + _REG(L_HSYNC_HS_ADDR));
+	writel_relaxed(hso_end, priv->io_base + _REG(L_HSYNC_HE_ADDR));
+	writel_relaxed(0, priv->io_base + _REG(L_HSYNC_VS_ADDR));
+	writel_relaxed(max_lncnt, priv->io_base + _REG(L_HSYNC_VE_ADDR));
+
+	/* Vsync signal */
+	writel_relaxed(vso_begin, priv->io_base + _REG(L_VSYNC_HS_ADDR));
+	writel_relaxed(vso_end, priv->io_base + _REG(L_VSYNC_HE_ADDR));
+	writel_relaxed(vso_bline, priv->io_base + _REG(L_VSYNC_VS_ADDR));
+	writel_relaxed(vso_eline, priv->io_base + _REG(L_VSYNC_VE_ADDR));
+
+	writel_relaxed(0, priv->io_base + _REG(L_INV_CNT_ADDR));
+	writel_relaxed(L_TCON_MISC_SEL_STV1 | L_TCON_MISC_SEL_STV2,
+		       priv->io_base + _REG(L_TCON_MISC_SEL_ADDR));
+
+	priv->venc.current_mode = MESON_VENC_MODE_MIPI_DSI;
+}
+EXPORT_SYMBOL_GPL(meson_venc_mipi_dsi_mode_set);
+
 void meson_venci_cvbs_mode_set(struct meson_drm *priv,
 			       struct meson_cvbs_enci_mode *mode)
 {
@@ -1747,8 +1947,15 @@ unsigned int meson_venci_get_field(struct meson_drm *priv)
 
 void meson_venc_enable_vsync(struct meson_drm *priv)
 {
-	writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
-		       priv->io_base + _REG(VENC_INTCTRL));
+	switch (priv->venc.current_mode) {
+	case MESON_VENC_MODE_MIPI_DSI:
+		writel_relaxed(VENC_INTCTRL_ENCP_LNRST_INT_EN,
+			       priv->io_base + _REG(VENC_INTCTRL));
+		break;
+	default:
+		writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
+			       priv->io_base + _REG(VENC_INTCTRL));
+	}
 	regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25));
 }
 
diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h
index 9138255ffc9e..0f59adb1c6db 100644
--- a/drivers/gpu/drm/meson/meson_venc.h
+++ b/drivers/gpu/drm/meson/meson_venc.h
@@ -21,6 +21,7 @@ enum {
 	MESON_VENC_MODE_CVBS_PAL,
 	MESON_VENC_MODE_CVBS_NTSC,
 	MESON_VENC_MODE_HDMI,
+	MESON_VENC_MODE_MIPI_DSI,
 };
 
 struct meson_cvbs_enci_mode {
@@ -47,6 +48,9 @@ struct meson_cvbs_enci_mode {
 	unsigned int analog_sync_adj;
 };
 
+/* LCD Encoder gamma setup */
+void meson_encl_load_gamma(struct meson_drm *priv);
+
 /* HDMI Clock parameters */
 enum drm_mode_status
 meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode);
@@ -63,6 +67,8 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
 			      unsigned int ycrcb_map,
 			      bool yuv420_mode,
 			      const struct drm_display_mode *mode);
+void meson_venc_mipi_dsi_mode_set(struct meson_drm *priv,
+				  const struct drm_display_mode *mode);
 unsigned int meson_venci_get_field(struct meson_drm *priv);
 
 void meson_venc_enable_vsync(struct meson_drm *priv);
diff --git a/drivers/gpu/drm/meson/meson_vpp.h b/drivers/gpu/drm/meson/meson_vpp.h
index afc9553ed8d3..b790042a1650 100644
--- a/drivers/gpu/drm/meson/meson_vpp.h
+++ b/drivers/gpu/drm/meson/meson_vpp.h
@@ -12,6 +12,8 @@
 struct drm_rect;
 struct meson_drm;
 
+/* Mux VIU/VPP to ENCL */
+#define MESON_VIU_VPP_MUX_ENCL	0x0
 /* Mux VIU/VPP to ENCI */
 #define MESON_VIU_VPP_MUX_ENCI	0x5
 /* Mux VIU/VPP to ENCP */
-- 
2.25.1



From narmstrong at baylibre.com  Thu Jan 20 00:33:55 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 09:33:55 +0100
Subject: [PATCH v2 4/6] drm/meson: vclk: add DSI clock config
In-Reply-To: <20220120083357.1541262-1-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
Message-ID: <20220120083357.1541262-5-narmstrong@baylibre.com>

The DSI path used the ENCL pixel encoder, thus this adds a clock
config using the HDMI PLL in order to feed the ENCL encoder via the
VCLK2 path and the CTS_ENCL clock output.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpu/drm/meson/meson_vclk.c | 47 ++++++++++++++++++++++++++++++
 drivers/gpu/drm/meson/meson_vclk.h |  1 +
 2 files changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
index 2a82119eb58e..5e4d982be1c8 100644
--- a/drivers/gpu/drm/meson/meson_vclk.c
+++ b/drivers/gpu/drm/meson/meson_vclk.c
@@ -55,6 +55,8 @@
 #define VCLK2_DIV_MASK		0xff
 #define VCLK2_DIV_EN		BIT(16)
 #define VCLK2_DIV_RESET		BIT(17)
+#define CTS_ENCL_SEL_MASK	(0xf << 12)
+#define CTS_ENCL_SEL_SHIFT	12
 #define CTS_VDAC_SEL_MASK	(0xf << 28)
 #define CTS_VDAC_SEL_SHIFT	28
 #define HHI_VIID_CLK_CNTL	0x12c /* 0x4b offset in data sheet */
@@ -83,6 +85,7 @@
 #define VCLK_DIV12_EN		BIT(4)
 #define HHI_VID_CLK_CNTL2	0x194 /* 0x65 offset in data sheet */
 #define CTS_ENCI_EN		BIT(0)
+#define CTS_ENCL_EN		BIT(3)
 #define CTS_ENCP_EN		BIT(2)
 #define CTS_VDAC_EN		BIT(4)
 #define HDMI_TX_PIXEL_EN	BIT(5)
@@ -1024,6 +1027,47 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
 	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
 }
 
+static void meson_dsi_clock_config(struct meson_drm *priv, unsigned int freq)
+{
+	meson_hdmi_pll_generic_set(priv, freq * 10);
+
+	/* Setup vid_pll divider value /5 */
+	meson_vid_pll_set(priv, VID_PLL_DIV_5);
+
+	/* Disable VCLK2 */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, 0);
+
+	/* Setup the VCLK2 divider value /2 */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV, VCLK2_DIV_MASK, 2 - 1);
+
+	/* select vid_pll for vclk2 */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
+			   VCLK2_SEL_MASK, (0 << VCLK2_SEL_SHIFT));
+
+	/* enable vclk2 gate */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN);
+
+	/* select vclk2_div1 for encl */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
+			   CTS_ENCL_SEL_MASK, (8 << CTS_ENCL_SEL_SHIFT));
+
+	/* release vclk2_div_reset and enable vclk2_div */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV, VCLK2_DIV_EN | VCLK2_DIV_RESET,
+			   VCLK2_DIV_EN);
+
+	/* enable vclk2_div1 gate */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_DIV1_EN, VCLK2_DIV1_EN);
+
+	/* reset vclk2 */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_SOFT_RESET, VCLK2_SOFT_RESET);
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_SOFT_RESET, 0);
+
+	/* enable encl_clk */
+	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2, CTS_ENCL_EN, CTS_ENCL_EN);
+
+	usleep_range(10000, 11000);
+}
+
 void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
 		      unsigned int phy_freq, unsigned int vclk_freq,
 		      unsigned int venc_freq, unsigned int dac_freq,
@@ -1050,6 +1094,9 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
 		meson_vclk_set(priv, phy_freq, 0, 0, 0,
 			       VID_PLL_DIV_5, 2, 1, 1, false, false);
 		return;
+	} else if (target == MESON_VCLK_TARGET_DSI) {
+		meson_dsi_clock_config(priv, phy_freq);
+		return;
 	}
 
 	hdmi_tx_div = vclk_freq / dac_freq;
diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h
index 60617aaf18dd..1152b3af8d2e 100644
--- a/drivers/gpu/drm/meson/meson_vclk.h
+++ b/drivers/gpu/drm/meson/meson_vclk.h
@@ -17,6 +17,7 @@ enum {
 	MESON_VCLK_TARGET_CVBS = 0,
 	MESON_VCLK_TARGET_HDMI = 1,
 	MESON_VCLK_TARGET_DMT = 2,
+	MESON_VCLK_TARGET_DSI = 3,
 };
 
 /* 27MHz is the CVBS Pixel Clock */
-- 
2.25.1



From narmstrong at baylibre.com  Thu Jan 20 00:33:56 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 09:33:56 +0100
Subject: [PATCH v2 5/6] drm/meson: add DSI encoder
In-Reply-To: <20220120083357.1541262-1-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
Message-ID: <20220120083357.1541262-6-narmstrong@baylibre.com>

This adds an encoder bridge designed to drive a MIPI-DSI display
by using the ENCL encoder through the internal MIPI DSI transceiver
connected to the output of the ENCL pixel encoder.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpu/drm/meson/Makefile            |   2 +-
 drivers/gpu/drm/meson/meson_drv.c         |   7 +
 drivers/gpu/drm/meson/meson_encoder_dsi.c | 160 ++++++++++++++++++++++
 drivers/gpu/drm/meson/meson_encoder_dsi.h |  12 ++
 4 files changed, 180 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.c
 create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.h

diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
index 3afa31bdc950..833e18c20603 100644
--- a/drivers/gpu/drm/meson/Makefile
+++ b/drivers/gpu/drm/meson/Makefile
@@ -2,7 +2,7 @@
 meson-drm-y := meson_drv.o meson_plane.o meson_crtc.o meson_encoder_cvbs.o
 meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_overlay.o
 meson-drm-y += meson_rdma.o meson_osd_afbcd.o
-meson-drm-y += meson_encoder_hdmi.o
+meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o
 
 obj-$(CONFIG_DRM_MESON) += meson-drm.o
 obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index 26aeaf0ab86e..15344cf9f913 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -33,6 +33,7 @@
 #include "meson_registers.h"
 #include "meson_encoder_cvbs.h"
 #include "meson_encoder_hdmi.h"
+#include "meson_encoder_dsi.h"
 #include "meson_viu.h"
 #include "meson_vpp.h"
 #include "meson_rdma.h"
@@ -323,6 +324,12 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
 	if (ret)
 		goto exit_afbcd;
 
+	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
+		ret = meson_encoder_dsi_init(priv);
+		if (ret)
+			goto free_drm;
+	}
+
 	ret = meson_plane_create(priv);
 	if (ret)
 		goto exit_afbcd;
diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.c b/drivers/gpu/drm/meson/meson_encoder_dsi.c
new file mode 100644
index 000000000000..12a586316183
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_encoder_dsi.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
+#include <drm/drm_device.h>
+#include <drm/drm_probe_helper.h>
+
+#include "meson_drv.h"
+#include "meson_encoder_dsi.h"
+#include "meson_registers.h"
+#include "meson_venc.h"
+#include "meson_vclk.h"
+
+struct meson_encoder_dsi {
+	struct drm_encoder encoder;
+	struct drm_bridge bridge;
+	struct drm_bridge *next_bridge;
+	struct meson_drm *priv;
+};
+
+#define bridge_to_meson_encoder_dsi(x) \
+	container_of(x, struct meson_encoder_dsi, bridge)
+
+static int meson_encoder_dsi_attach(struct drm_bridge *bridge,
+				    enum drm_bridge_attach_flags flags)
+{
+	struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
+
+	return drm_bridge_attach(bridge->encoder, encoder_dsi->next_bridge,
+				 &encoder_dsi->bridge, flags);
+}
+
+static void meson_encoder_dsi_mode_set(struct drm_bridge *bridge,
+				       const struct drm_display_mode *mode,
+				       const struct drm_display_mode *adjusted_mode)
+{
+	struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
+	struct meson_drm *priv = encoder_dsi->priv;
+
+	meson_vclk_setup(priv, MESON_VCLK_TARGET_DSI, mode->clock, 0, 0, 0, false);
+
+	meson_venc_mipi_dsi_mode_set(priv, mode);
+	meson_encl_load_gamma(priv);
+
+	writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
+
+	writel_bits_relaxed(ENCL_VIDEO_MODE_ADV_VFIFO_EN, ENCL_VIDEO_MODE_ADV_VFIFO_EN,
+			    priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_EN));
+}
+
+static void meson_encoder_dsi_atomic_enable(struct drm_bridge *bridge,
+					    struct drm_bridge_state *bridge_state)
+{
+	struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
+	struct meson_drm *priv = encoder_dsi->priv;
+
+	writel_bits_relaxed(BIT(0), 0, priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL));
+
+	writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
+}
+
+static void meson_encoder_dsi_atomic_disable(struct drm_bridge *bridge,
+					     struct drm_bridge_state *bridge_state)
+{
+	struct meson_encoder_dsi *meson_encoder_dsi =
+					bridge_to_meson_encoder_dsi(bridge);
+	struct meson_drm *priv = meson_encoder_dsi->priv;
+
+	writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
+
+	writel_bits_relaxed(BIT(0), BIT(0), priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL));
+}
+
+static const struct drm_bridge_funcs meson_encoder_dsi_bridge_funcs = {
+	.attach	= meson_encoder_dsi_attach,
+	/*
+	 * TOFIX: remove when dw-mipi-dsi moves out of mode_set
+	 * We should get rid of mode_set, but until dw-mipi-dsi uses it
+	 * we need to setup the pixel clock before the following
+	 * bridge tries to setup the HW.
+	 */
+	.mode_set = meson_encoder_dsi_mode_set,
+	.atomic_enable = meson_encoder_dsi_atomic_enable,
+	.atomic_disable	= meson_encoder_dsi_atomic_disable,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+};
+
+int meson_encoder_dsi_init(struct meson_drm *priv)
+{
+	struct meson_encoder_dsi *meson_encoder_dsi;
+	struct device_node *remote;
+	int ret;
+
+	meson_encoder_dsi = devm_kzalloc(priv->dev, sizeof(*meson_encoder_dsi), GFP_KERNEL);
+	if (!meson_encoder_dsi)
+		return -ENOMEM;
+
+	/* DSI Transceiver Bridge */
+	remote = of_graph_get_remote_node(priv->dev->of_node, 2, 0);
+	if (!remote) {
+		dev_err(priv->dev, "DSI transceiver device is disabled");
+		return 0;
+	}
+
+	meson_encoder_dsi->next_bridge = of_drm_find_bridge(remote);
+	if (!meson_encoder_dsi->next_bridge) {
+		dev_dbg(priv->dev, "Failed to find DSI transceiver bridge: %d\n", ret);
+		return -EPROBE_DEFER;
+	}
+
+	/* DSI Encoder Bridge */
+	meson_encoder_dsi->bridge.funcs = &meson_encoder_dsi_bridge_funcs;
+	meson_encoder_dsi->bridge.of_node = priv->dev->of_node;
+	meson_encoder_dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
+
+	drm_bridge_add(&meson_encoder_dsi->bridge);
+
+	meson_encoder_dsi->priv = priv;
+
+	/* Encoder */
+	ret = drm_simple_encoder_init(priv->drm, &meson_encoder_dsi->encoder,
+				      DRM_MODE_ENCODER_DSI);
+	if (ret) {
+		dev_err(priv->dev, "Failed to init DSI encoder: %d\n", ret);
+		return ret;
+	}
+
+	meson_encoder_dsi->encoder.possible_crtcs = BIT(0);
+
+	/* Attach DSI Encoder Bridge to Encoder */
+	ret = drm_bridge_attach(&meson_encoder_dsi->encoder, &meson_encoder_dsi->bridge, NULL, 0);
+	if (ret) {
+		dev_err(priv->dev, "Failed to attach bridge: %d\n", ret);
+		return ret;
+	}
+
+	/*
+	 * We should have now in place:
+	 * encoder->[dsi encoder bridge]->[dw-mipi-dsi bridge]->[panel bridge]->[panel]
+	 */
+
+	dev_dbg(priv->dev, "DSI encoder initialized\n");
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.h b/drivers/gpu/drm/meson/meson_encoder_dsi.h
new file mode 100644
index 000000000000..0f4b641eb633
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_encoder_dsi.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2021 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ */
+
+#ifndef __MESON_ENCODER_DSI_H
+#define __MESON_ENCODER_DSI_H
+
+int meson_encoder_dsi_init(struct meson_drm *priv);
+
+#endif /* __MESON_ENCODER_DSI_H */
-- 
2.25.1



From narmstrong at baylibre.com  Thu Jan 20 00:33:57 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 09:33:57 +0100
Subject: [PATCH v2 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <20220120083357.1541262-1-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
Message-ID: <20220120083357.1541262-7-narmstrong@baylibre.com>

The Amlogic G12A/G12B/SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
Glue on other Amlogic SoCs.

This adds support for the Glue managing the transceiver, mimicing the init flow provided
by Amlogic to setup the ENCL encoder, the glue, the transceiver, the digital D-PHY and the
Analog PHY in the proper way.

An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
DW-MIPI-DSI transceiver.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpu/drm/meson/Kconfig             |   7 +
 drivers/gpu/drm/meson/Makefile            |   1 +
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 357 ++++++++++++++++++++++
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h | 160 ++++++++++
 4 files changed, 525 insertions(+)
 create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
 create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h

diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
index 6c70fc3214af..71a1364b51e1 100644
--- a/drivers/gpu/drm/meson/Kconfig
+++ b/drivers/gpu/drm/meson/Kconfig
@@ -17,3 +17,10 @@ config DRM_MESON_DW_HDMI
 	default y if DRM_MESON
 	select DRM_DW_HDMI
 	imply DRM_DW_HDMI_I2S_AUDIO
+
+config DRM_MESON_DW_MIPI_DSI
+	tristate "MIPI DSI Synopsys Controller support for Amlogic Meson Display"
+	depends on DRM_MESON
+	default y if DRM_MESON
+	select DRM_DW_MIPI_DSI
+	select GENERIC_PHY_MIPI_DPHY
diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
index 833e18c20603..43071bdbd4b9 100644
--- a/drivers/gpu/drm/meson/Makefile
+++ b/drivers/gpu/drm/meson/Makefile
@@ -6,3 +6,4 @@ meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o
 
 obj-$(CONFIG_DRM_MESON) += meson-drm.o
 obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
+obj-$(CONFIG_DRM_MESON_DW_MIPI_DSI) += meson_dw_mipi_dsi.o
diff --git a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
new file mode 100644
index 000000000000..75f373152caf
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
@@ -0,0 +1,357 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2021 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/reset.h>
+#include <linux/phy/phy.h>
+
+#include <video/mipi_display.h>
+
+#include <drm/bridge/dw_mipi_dsi.h>
+#include <drm/drm_mipi_dsi.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_device.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_print.h>
+
+#include "meson_drv.h"
+#include "meson_dw_mipi_dsi.h"
+#include "meson_registers.h"
+#include "meson_venc.h"
+
+#define DRIVER_NAME "meson-dw-mipi-dsi"
+#define DRIVER_DESC "Amlogic Meson MIPI-DSI DRM driver"
+
+struct meson_dw_mipi_dsi {
+	struct meson_drm *priv;
+	struct device *dev;
+	void __iomem *base;
+	struct phy *phy;
+	union phy_configure_opts phy_opts;
+	struct dw_mipi_dsi *dmd;
+	struct dw_mipi_dsi_plat_data pdata;
+	struct mipi_dsi_device *dsi_device;
+	const struct drm_display_mode *mode;
+	struct clk *px_clk;
+};
+
+#define encoder_to_meson_dw_mipi_dsi(x) \
+	container_of(x, struct meson_dw_mipi_dsi, encoder)
+
+static void meson_dw_mipi_dsi_hw_init(struct meson_dw_mipi_dsi *mipi_dsi)
+{
+	/* Software reset */
+	writel_bits_relaxed(MIPI_DSI_TOP_SW_RESET_DWC | MIPI_DSI_TOP_SW_RESET_INTR |
+			    MIPI_DSI_TOP_SW_RESET_DPI | MIPI_DSI_TOP_SW_RESET_TIMING,
+			    MIPI_DSI_TOP_SW_RESET_DWC | MIPI_DSI_TOP_SW_RESET_INTR |
+			    MIPI_DSI_TOP_SW_RESET_DPI | MIPI_DSI_TOP_SW_RESET_TIMING,
+			    mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);
+	writel_bits_relaxed(MIPI_DSI_TOP_SW_RESET_DWC | MIPI_DSI_TOP_SW_RESET_INTR |
+			    MIPI_DSI_TOP_SW_RESET_DPI | MIPI_DSI_TOP_SW_RESET_TIMING,
+			    0, mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);
+
+	/* Enable clocks */
+	writel_bits_relaxed(MIPI_DSI_TOP_CLK_SYSCLK_EN | MIPI_DSI_TOP_CLK_PIXCLK_EN,
+			    MIPI_DSI_TOP_CLK_SYSCLK_EN | MIPI_DSI_TOP_CLK_PIXCLK_EN,
+			    mipi_dsi->base + MIPI_DSI_TOP_CLK_CNTL);
+
+	/* Take memory out of power down */
+	writel_relaxed(0, mipi_dsi->base + MIPI_DSI_TOP_MEM_PD);
+}
+
+static int dw_mipi_dsi_phy_init(void *priv_data)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+	unsigned int dpi_data_format, venc_data_width;
+	int ret;
+
+	ret = clk_set_rate(mipi_dsi->px_clk, mipi_dsi->phy_opts.mipi_dphy.hs_clk_rate);
+	if (ret) {
+		pr_err("Failed to set DSI PLL rate %lu\n",
+		       mipi_dsi->phy_opts.mipi_dphy.hs_clk_rate);
+
+		return ret;
+	}
+
+	switch (mipi_dsi->dsi_device->format) {
+	case MIPI_DSI_FMT_RGB888:
+		dpi_data_format = DPI_COLOR_24BIT;
+		venc_data_width = VENC_IN_COLOR_24B;
+		break;
+	case MIPI_DSI_FMT_RGB666:
+		dpi_data_format = DPI_COLOR_18BIT_CFG_2;
+		venc_data_width = VENC_IN_COLOR_18B;
+		break;
+	case MIPI_DSI_FMT_RGB666_PACKED:
+	case MIPI_DSI_FMT_RGB565:
+		return -EINVAL;
+	};
+
+	/* Configure color format for DPI register */
+	writel_relaxed(FIELD_PREP(MIPI_DSI_TOP_DPI_COLOR_MODE, dpi_data_format) |
+		       FIELD_PREP(MIPI_DSI_TOP_IN_COLOR_MODE, venc_data_width) |
+		       FIELD_PREP(MIPI_DSI_TOP_COMP2_SEL, 2) |
+		       FIELD_PREP(MIPI_DSI_TOP_COMP1_SEL, 1) |
+		       FIELD_PREP(MIPI_DSI_TOP_COMP0_SEL, 0) |
+		       (mipi_dsi->mode->flags & DRM_MODE_FLAG_NHSYNC ?
+				0 : MIPI_DSI_TOP_HSYNC_INVERT) |
+		       (mipi_dsi->mode->flags & DRM_MODE_FLAG_NVSYNC ?
+				0 : MIPI_DSI_TOP_VSYNC_INVERT),
+			mipi_dsi->base + MIPI_DSI_TOP_CNTL);
+
+	return phy_configure(mipi_dsi->phy, &mipi_dsi->phy_opts);
+}
+
+static void dw_mipi_dsi_phy_power_on(void *priv_data)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+
+	if (phy_power_on(mipi_dsi->phy))
+		dev_warn(mipi_dsi->dev, "Failed to power on PHY\n");
+}
+
+static void dw_mipi_dsi_phy_power_off(void *priv_data)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+
+	if (phy_power_off(mipi_dsi->phy))
+		dev_warn(mipi_dsi->dev, "Failed to power off PHY\n");
+}
+
+static int
+dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
+			  unsigned long mode_flags, u32 lanes, u32 format,
+			  unsigned int *lane_mbps)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+	int bpp;
+
+	mipi_dsi->mode = mode;
+
+	bpp = mipi_dsi_pixel_format_to_bpp(mipi_dsi->dsi_device->format);
+
+	phy_mipi_dphy_get_default_config(mode->clock * 1000,
+					 bpp, mipi_dsi->dsi_device->lanes,
+					 &mipi_dsi->phy_opts.mipi_dphy);
+
+	*lane_mbps = mipi_dsi->phy_opts.mipi_dphy.hs_clk_rate / 1000000;
+
+	return 0;
+}
+
+static int
+dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
+			   struct dw_mipi_dsi_dphy_timing *timing)
+{
+	/* TOFIX handle other cases */
+
+	timing->clk_lp2hs = 37;
+	timing->clk_hs2lp = 135;
+	timing->data_lp2hs = 50;
+	timing->data_hs2lp = 3;
+
+	return 0;
+}
+
+static int
+dw_mipi_dsi_get_esc_clk_rate(void *priv_data, unsigned int *esc_clk_rate)
+{
+	*esc_clk_rate = 4; /* Mhz */
+
+	return 0;
+}
+
+static const struct dw_mipi_dsi_phy_ops meson_dw_mipi_dsi_phy_ops = {
+	.init = dw_mipi_dsi_phy_init,
+	.power_on = dw_mipi_dsi_phy_power_on,
+	.power_off = dw_mipi_dsi_phy_power_off,
+	.get_lane_mbps = dw_mipi_dsi_get_lane_mbps,
+	.get_timing = dw_mipi_dsi_phy_get_timing,
+	.get_esc_clk_rate = dw_mipi_dsi_get_esc_clk_rate,
+};
+
+static int meson_dw_mipi_dsi_bind(struct device *dev, struct device *master, void *data)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = dev_get_drvdata(dev);
+	struct drm_device *drm = data;
+	struct meson_drm *priv = drm->dev_private;
+
+	/* Check before if we are supposed to have a sub-device... */
+	if (!mipi_dsi->dsi_device) {
+		dw_mipi_dsi_remove(mipi_dsi->dmd);
+		return -EPROBE_DEFER;
+	}
+
+	mipi_dsi->priv = priv;
+
+	meson_dw_mipi_dsi_hw_init(mipi_dsi);
+
+	return 0;
+}
+
+static const struct component_ops meson_dw_mipi_dsi_ops = {
+	.bind	= meson_dw_mipi_dsi_bind,
+};
+
+static int meson_dw_mipi_dsi_host_attach(void *priv_data,
+					 struct mipi_dsi_device *device)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+
+	mipi_dsi->dsi_device = device;
+
+	switch (device->format) {
+	case MIPI_DSI_FMT_RGB888:
+		break;
+	case MIPI_DSI_FMT_RGB666:
+		break;
+	case MIPI_DSI_FMT_RGB666_PACKED:
+	case MIPI_DSI_FMT_RGB565:
+		dev_err(mipi_dsi->dev, "invalid pixel format %d\n", device->format);
+		return -EINVAL;
+	};
+
+	return phy_init(mipi_dsi->phy);
+}
+
+static int meson_dw_mipi_dsi_host_detach(void *priv_data,
+					 struct mipi_dsi_device *device)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+
+	if (device == mipi_dsi->dsi_device)
+		mipi_dsi->dsi_device = NULL;
+	else
+		return -EINVAL;
+
+	return phy_exit(mipi_dsi->phy);
+}
+
+static const struct dw_mipi_dsi_host_ops meson_dw_mipi_dsi_host_ops = {
+	.attach = meson_dw_mipi_dsi_host_attach,
+	.detach = meson_dw_mipi_dsi_host_detach,
+};
+
+static int meson_dw_mipi_dsi_probe(struct platform_device *pdev)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi;
+	struct reset_control *top_rst;
+	struct resource *res;
+	int ret;
+
+	mipi_dsi = devm_kzalloc(&pdev->dev, sizeof(*mipi_dsi), GFP_KERNEL);
+	if (!mipi_dsi)
+		return -ENOMEM;
+
+	mipi_dsi->dev = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mipi_dsi->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mipi_dsi->base))
+		return PTR_ERR(mipi_dsi->base);
+
+	mipi_dsi->phy = devm_phy_get(&pdev->dev, "dphy");
+	if (IS_ERR(mipi_dsi->phy)) {
+		ret = PTR_ERR(mipi_dsi->phy);
+		dev_err(&pdev->dev, "failed to get mipi dphy: %d\n", ret);
+		return ret;
+	}
+
+	mipi_dsi->px_clk = devm_clk_get(&pdev->dev, "px_clk");
+	if (IS_ERR(mipi_dsi->px_clk)) {
+		dev_err(&pdev->dev, "Unable to get PLL clk\n");
+		return PTR_ERR(mipi_dsi->px_clk);
+	}
+
+	/*
+	 * We use a TOP reset signal because the APB reset signal
+	 * is handled by the TOP control registers.
+	 */
+	top_rst = devm_reset_control_get_exclusive(&pdev->dev, "top");
+	if (IS_ERR(top_rst)) {
+		ret = PTR_ERR(top_rst);
+
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Unable to get reset control: %d\n", ret);
+
+		return ret;
+	}
+
+	ret = clk_prepare_enable(mipi_dsi->px_clk);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to prepare/enable PX clock\n");
+		return ret;
+	}
+
+	reset_control_assert(top_rst);
+	usleep_range(10, 20);
+	reset_control_deassert(top_rst);
+
+	/* MIPI DSI Controller */
+
+	mipi_dsi->pdata.base = mipi_dsi->base;
+	mipi_dsi->pdata.max_data_lanes = 4;
+	mipi_dsi->pdata.phy_ops = &meson_dw_mipi_dsi_phy_ops;
+	mipi_dsi->pdata.host_ops = &meson_dw_mipi_dsi_host_ops;
+	mipi_dsi->pdata.priv_data = mipi_dsi;
+	platform_set_drvdata(pdev, mipi_dsi);
+
+	mipi_dsi->dmd = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata);
+	if (IS_ERR(mipi_dsi->dmd)) {
+		ret = PTR_ERR(mipi_dsi->dmd);
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev,
+				"Failed to probe dw_mipi_dsi: %d\n", ret);
+		goto err_clkdisable;
+	}
+
+	return component_add(mipi_dsi->dev, &meson_dw_mipi_dsi_ops);
+
+err_clkdisable:
+	clk_disable_unprepare(mipi_dsi->px_clk);
+
+	return ret;
+}
+
+static int meson_dw_mipi_dsi_remove(struct platform_device *pdev)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = dev_get_drvdata(&pdev->dev);
+
+	dw_mipi_dsi_remove(mipi_dsi->dmd);
+
+	component_del(mipi_dsi->dev, &meson_dw_mipi_dsi_ops);
+
+	clk_disable_unprepare(mipi_dsi->px_clk);
+
+	return 0;
+}
+
+static const struct of_device_id meson_dw_mipi_dsi_of_table[] = {
+	{ .compatible = "amlogic,meson-g12a-dw-mipi-dsi", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, meson_dw_mipi_dsi_of_table);
+
+static struct platform_driver meson_dw_mipi_dsi_platform_driver = {
+	.probe		= meson_dw_mipi_dsi_probe,
+	.remove		= meson_dw_mipi_dsi_remove,
+	.driver		= {
+		.name		= DRIVER_NAME,
+		.of_match_table	= meson_dw_mipi_dsi_of_table,
+	},
+};
+module_platform_driver(meson_dw_mipi_dsi_platform_driver);
+
+MODULE_AUTHOR("Neil Armstrong <narmstrong at baylibre.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.h b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
new file mode 100644
index 000000000000..e1bd6b85d6a3
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
@@ -0,0 +1,160 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ * Copyright (C) 2018 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __MESON_DW_MIPI_DSI_H
+#define __MESON_DW_MIPI_DSI_H
+
+/* Top-level registers */
+/* [31: 4]    Reserved.     Default 0.
+ *     [3] RW timing_rst_n: Default 1.
+ *		1=Assert SW reset of timing feature.   0=Release reset.
+ *     [2] RW dpi_rst_n: Default 1.
+ *		1=Assert SW reset on mipi_dsi_host_dpi block.   0=Release reset.
+ *     [1] RW intr_rst_n: Default 1.
+ *		1=Assert SW reset on mipi_dsi_host_intr block.  0=Release reset.
+ *     [0] RW dwc_rst_n:  Default 1.
+ *		1=Assert SW reset on IP core.   0=Release reset.
+ */
+#define MIPI_DSI_TOP_SW_RESET                      0x3c0
+
+#define MIPI_DSI_TOP_SW_RESET_DWC	BIT(0)
+#define MIPI_DSI_TOP_SW_RESET_INTR	BIT(1)
+#define MIPI_DSI_TOP_SW_RESET_DPI	BIT(2)
+#define MIPI_DSI_TOP_SW_RESET_TIMING	BIT(3)
+
+/* [31: 5] Reserved.   Default 0.
+ *     [4] RW manual_edpihalt: Default 0.
+ *		1=Manual suspend VencL; 0=do not suspend VencL.
+ *     [3] RW auto_edpihalt_en: Default 0.
+ *		1=Enable IP's edpihalt signal to suspend VencL;
+ *		0=IP's edpihalt signal does not affect VencL.
+ *     [2] RW clock_freerun: Apply to auto-clock gate only. Default 0.
+ *		0=Default, use auto-clock gating to save power;
+ *		1=use free-run clock, disable auto-clock gating, for debug mode.
+ *     [1] RW enable_pixclk: A manual clock gate option, due to DWC IP does not
+ *		have auto-clock gating. 1=Enable pixclk.      Default 0.
+ *     [0] RW enable_sysclk: A manual clock gate option, due to DWC IP does not
+ *		have auto-clock gating. 1=Enable sysclk.      Default 0.
+ */
+#define MIPI_DSI_TOP_CLK_CNTL                      0x3c4
+
+#define MIPI_DSI_TOP_CLK_SYSCLK_EN	BIT(0)
+#define MIPI_DSI_TOP_CLK_PIXCLK_EN	BIT(1)
+
+/* [31:24]    Reserved. Default 0.
+ * [23:20] RW dpi_color_mode: Define DPI pixel format. Default 0.
+ *		0=16-bit RGB565 config 1;
+ *		1=16-bit RGB565 config 2;
+ *		2=16-bit RGB565 config 3;
+ *		3=18-bit RGB666 config 1;
+ *		4=18-bit RGB666 config 2;
+ *		5=24-bit RGB888;
+ *		6=20-bit YCbCr 4:2:2;
+ *		7=24-bit YCbCr 4:2:2;
+ *		8=16-bit YCbCr 4:2:2;
+ *		9=30-bit RGB;
+ *		10=36-bit RGB;
+ *		11=12-bit YCbCr 4:2:0.
+ *    [19] Reserved. Default 0.
+ * [18:16] RW in_color_mode:  Define VENC data width. Default 0.
+ *		0=30-bit pixel;
+ *		1=24-bit pixel;
+ *		2=18-bit pixel, RGB666;
+ *		3=16-bit pixel, RGB565.
+ * [15:14] RW chroma_subsample: Define method of chroma subsampling. Default 0.
+ *		Applicable to YUV422 or YUV420 only.
+ *		0=Use even pixel's chroma;
+ *		1=Use odd pixel's chroma;
+ *		2=Use averaged value between even and odd pair.
+ * [13:12] RW comp2_sel:  Select which component to be Cr or B: Default 2.
+ *		0=comp0; 1=comp1; 2=comp2.
+ * [11:10] RW comp1_sel:  Select which component to be Cb or G: Default 1.
+ *		0=comp0; 1=comp1; 2=comp2.
+ *  [9: 8] RW comp0_sel:  Select which component to be Y  or R: Default 0.
+ *		0=comp0; 1=comp1; 2=comp2.
+ *     [7]    Reserved. Default 0.
+ *     [6] RW de_pol:  Default 0.
+ *		If DE input is active low, set to 1 to invert to active high.
+ *     [5] RW hsync_pol: Default 0.
+ *		If HS input is active low, set to 1 to invert to active high.
+ *     [4] RW vsync_pol: Default 0.
+ *		If VS input is active low, set to 1 to invert to active high.
+ *     [3] RW dpicolorm: Signal to IP.   Default 0.
+ *     [2] RW dpishutdn: Signal to IP.   Default 0.
+ *     [1]    Reserved.  Default 0.
+ *     [0]    Reserved.  Default 0.
+ */
+#define MIPI_DSI_TOP_CNTL                          0x3c8
+
+/* VENC data width */
+#define VENC_IN_COLOR_30B   0x0
+#define VENC_IN_COLOR_24B   0x1
+#define VENC_IN_COLOR_18B   0x2
+#define VENC_IN_COLOR_16B   0x3
+
+/* DPI pixel format */
+#define DPI_COLOR_16BIT_CFG_1		0
+#define DPI_COLOR_16BIT_CFG_2		1
+#define DPI_COLOR_16BIT_CFG_3		2
+#define DPI_COLOR_18BIT_CFG_1		3
+#define DPI_COLOR_18BIT_CFG_2		4
+#define DPI_COLOR_24BIT			5
+#define DPI_COLOR_20BIT_YCBCR_422	6
+#define DPI_COLOR_24BIT_YCBCR_422	7
+#define DPI_COLOR_16BIT_YCBCR_422	8
+#define DPI_COLOR_30BIT			9
+#define DPI_COLOR_36BIT			10
+#define DPI_COLOR_12BIT_YCBCR_420	11
+
+#define MIPI_DSI_TOP_DPI_COLOR_MODE	GENMASK(23, 20)
+#define MIPI_DSI_TOP_IN_COLOR_MODE	GENMASK(18, 16)
+#define MIPI_DSI_TOP_CHROMA_SUBSAMPLE	GENMASK(15, 14)
+#define MIPI_DSI_TOP_COMP2_SEL		GENMASK(13, 12)
+#define MIPI_DSI_TOP_COMP1_SEL		GENMASK(11, 10)
+#define MIPI_DSI_TOP_COMP0_SEL		GENMASK(9, 8)
+#define MIPI_DSI_TOP_DE_INVERT		BIT(6)
+#define MIPI_DSI_TOP_HSYNC_INVERT	BIT(5)
+#define MIPI_DSI_TOP_VSYNC_INVERT	BIT(4)
+#define MIPI_DSI_TOP_DPICOLORM		BIT(3)
+#define MIPI_DSI_TOP_DPISHUTDN		BIT(2)
+
+#define MIPI_DSI_TOP_SUSPEND_CNTL                  0x3cc
+#define MIPI_DSI_TOP_SUSPEND_LINE                  0x3d0
+#define MIPI_DSI_TOP_SUSPEND_PIX                   0x3d4
+#define MIPI_DSI_TOP_MEAS_CNTL                     0x3d8
+/* [0] R  stat_edpihalt:  edpihalt signal from IP.    Default 0. */
+#define MIPI_DSI_TOP_STAT                          0x3dc
+#define MIPI_DSI_TOP_MEAS_STAT_TE0                 0x3e0
+#define MIPI_DSI_TOP_MEAS_STAT_TE1                 0x3e4
+#define MIPI_DSI_TOP_MEAS_STAT_VS0                 0x3e8
+#define MIPI_DSI_TOP_MEAS_STAT_VS1                 0x3ec
+/* [31:16] RW intr_stat/clr. Default 0.
+ *		For each bit, read as this interrupt level status,
+ *		write 1 to clear.
+ * [31:22] Reserved
+ * [   21] stat/clr of eof interrupt
+ * [   21] vde_fall interrupt
+ * [   19] stat/clr of de_rise interrupt
+ * [   18] stat/clr of vs_fall interrupt
+ * [   17] stat/clr of vs_rise interrupt
+ * [   16] stat/clr of dwc_edpite interrupt
+ * [15: 0] RW intr_enable. Default 0.
+ *		For each bit, 1=enable this interrupt, 0=disable.
+ *	[15: 6] Reserved
+ *	[    5] eof interrupt
+ *	[    4] de_fall interrupt
+ *	[    3] de_rise interrupt
+ *	[    2] vs_fall interrupt
+ *	[    1] vs_rise interrupt
+ *	[    0] dwc_edpite interrupt
+ */
+#define MIPI_DSI_TOP_INTR_CNTL_STAT                0x3f0
+// 31: 2    Reserved.   Default 0.
+//  1: 0 RW mem_pd.     Default 3.
+#define MIPI_DSI_TOP_MEM_PD                        0x3f4
+
+#endif /* __MESON_DW_MIPI_DSI_H */
-- 
2.25.1



From yu.tu at amlogic.com  Thu Jan 20 00:43:05 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Thu, 20 Jan 2022 16:43:05 +0800
Subject: [PATCH V6 0/5] Use CCF to describe the UART baud rate clock
In-Reply-To: <7hfspjqrn7.fsf@baylibre.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <7hfspjqrn7.fsf@baylibre.com>
Message-ID: <cc3b971f-c630-4ce2-e6dd-c13bcba89d22@amlogic.com>

Hi Kevin,
	Thank you very much for your reply.

On 2022/1/20 6:37, Kevin Hilman wrote:
> [ EXTERNAL EMAIL ]
> 
> Hello,
> 
> Yu Tu <yu.tu at amlogic.com> writes:
> 
>> Using the common Clock code to describe the UART baud rate
>> clock makes it easier for the UART driver to be compatible
>> with the baud rate requirements of the UART IP on different
>> meson chips. Add Meson S4 SoC compatible.
> 
> Could you describe how this was tested and on which SoCs?  There seem to
> be some changes in this series that might affect previous SoCs.
> 
For me, the board starts normally and prints. My intention was to add 
the S4 SOC UART compatible, but for the S4 our baud rate clock is 
calculated at 12MHz by default.So a series of changes were made at your 
suggestion.

Since most SoCs are too old, I was able to find all the platforms myself 
such as Meson6, Meson8, Meson8b, GXL and so on. I only tested it with 
G12A and S4.But when I talked to Martin earlier he tried meson8b's log.
The test patch is in the attachment.

I have found that on some boards with this change, the initcall_debug 
Uart driver takes longer to initialize. Running the stty command to 
change the baud rate at the same time may cause a jam.

I'd love to know what else you suggest.

> Thanks,
> 
> Kevin
> 
> 
-------------- next part --------------
?# cat /sys/kernel/debug/clk//clk_summary | head
                                 enable  prepare  protect                                duty  hardware
   clock                          count    count    count        rate   accuracy phase  cycle    enable
-------------------------------------------------------------------------------------------------------
 xtal                                 6        6        0    24000000          0     0  50000         Y
    ff803000.serial#xtal_div          1        1        0    12000000          0     0  50000         Y
       ff803000.serial#use_xtal       1        1        0    12000000          0     0  50000         Y
          ff803000.serial#baud_div       1        1        0      115385          0     0  50000         Y
    cts_oscin                         0        0        0    24000000          0     0  50000         Y
       g12a_ao_cec_pre                0        0        0    24000000          0     0  50000         N
          g12a_ao_cec_div             0        0        0       32742          0     0  50000         Y
-------------- next part --------------
# cat /sys/kernel/debug/clk/clk_summary 
                                 enable  prepare  protect                                duty  hardware
   clock                          count    count    count        rate   accuracy phase  cycle    enable
-------------------------------------------------------------------------------------------------------
[...]
 xtal                                 6        6        2    24000000          0     0  50000         Y
[...]
    c81004c0.serial#xtal_div3         0        0        0     8000000          0     0  50000         Y
[...]
    fixed_pll_dco                     1        1        0  2550000000          0     0  50000         Y
       fixed_pll                      1        1        0  2550000000          0     0  50000         Y
[...]
          fclk_div3_div               1        1        0   850000000          0     0  50000         Y
             fclk_div3                2        2        0   850000000          0     0  50000         Y
[...]
                mpeg_clk_sel          1        1        0   850000000          0     0  50000         Y
                   mpeg_clk_div       1        1        0   141666667          0     0  50000         Y
                      clk81          17       20        0   141666667          0     0  50000         Y
[...]
                         c81004c0.serial#clk81_div4       1        1        0    35416666          0     0  50000         Y
                            c81004c0.serial#use_xtal       1        1        0    35416666          0     0  50000         Y
                               c81004c0.serial#baud_div       1        1        0      115364          0     0  50000         Y
-------------- next part --------------
?# cat /sys/kernel/debug/clk/clk_summary | head
                                 enable  prepare  protect                                duty  hardware
   clock                          count    count    count        rate   accuracy phase  cycle    enable
-------------------------------------------------------------------------------------------------------
 xtal                                 7        7        0    24000000          0     0  50000         Y
    fe07a000.serial#xtal_div          1        1        0    12000000          0     0  50000         Y
       fe07a000.serial#use_xtal       1        1        0    12000000          0     0  50000         Y
          fe07a000.serial#baud_div       1        1        0      923077          0     0  50000         Y
    hdcp22_skpclk_mux                 0        0        0    24000000          0     0  50000         Y
       hdcp22_skpclk_div              0        0        0    24000000          0     0  50000         Y
          hdcp22_skpclk_gate          0        0        0    24000000          0     0  50000         N

From narmstrong at baylibre.com  Thu Jan 20 00:59:03 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 09:59:03 +0100
Subject: [PATCH V2 2/2] soc: s4: Add support for power domains controller
In-Reply-To: <2022011810264745683311@amlogic.com>
References: <20211230094434.3053195-1-shunzhou.jiang@amlogic.com>
 <20211230094434.3053195-3-shunzhou.jiang@amlogic.com>
 <CAFBinCALAOJz16=u7r8tLM6ditriq=-NOACS2HRLrWs5B_FkVA@mail.gmail.com>
 <b2a9b8f0-2b12-c49f-9609-21999b1fffc8@baylibre.com>
 <2022011810264745683311@amlogic.com>
Message-ID: <b846de5f-cf30-c000-ea37-61d79bcd4e7e@baylibre.com>

Hi Shunzhou,

On 18/01/2022 03:26, shunzhou.jiang at amlogic.com wrote:
> Dears Neil & Martin:
> Sorry for my late reply
> S4_VPU_HDMI:? for vpu domain,? this domain provide power to many moudles(osd,?vpp,?hdr,?dv,?di), if close, will cause system crash
> S4_USB_COMB?domain: for usb, if not always on,? all usb status will clear to 0, that's not right status for usb
> S4_ETH: for ethernet online wakeup, and if power down, status also not right
>>> +?????? SEC_PD(S4_VPU_HDMI,???? GENPD_FLAG_ALWAYS_ON),
>>> +?????? SEC_PD(S4_USB_COMB,???? GENPD_FLAG_ALWAYS_ON),
>>> +?????? SEC_PD(S4_GE2D,???????? 0),
>>> +?????? SEC_PD(S4_ETH,????????? GENPD_FLAG_ALWAYS_ON),

Thanks for clarifications, can you resend the patchset with those infos in comments like it was done for A1 ?

Thanks,
Neil

> 
>  
> Shunzhou Jiang
> SW Department
> 
>     ?
>     *From:*?Neil Armstrong <mailto:narmstrong at baylibre.com>
>     *Date:*?2022-01-12?16:36
>     *To:*?Martin Blumenstingl <mailto:martin.blumenstingl at googlemail.com>; Shunzhou.Jiang <mailto:shunzhou.jiang at amlogic.com>
>     *CC:*?devicetree <mailto:devicetree at vger.kernel.org>; linux-arm-kernel <mailto:linux-arm-kernel at lists.infradead.org>; linux-amlogic <mailto:linux-amlogic at lists.infradead.org>; linux-kernel <mailto:linux-kernel at vger.kernel.org>; khilman <mailto:khilman at baylibre.com>; jbrunet <mailto:jbrunet at baylibre.com>
>     *Subject:*?Re: [PATCH V2 2/2] soc: s4: Add support for power domains controller
>     [ EXTERNAL EMAIL ]
>     ?
>     Hi Shunzhou,
>     ?
>     On 30/12/2021 23:15, Martin Blumenstingl wrote:
>     > On Thu, Dec 30, 2021 at 10:44 AM Shunzhou.Jiang
>     > <shunzhou.jiang at amlogic.com> wrote:
>     >>
>     >> From: Shunzhou Jiang <shunzhou.jiang at amlogic.com>
>     >>
>     >> Add support s4 Power controller. In s4, power control
>     >> registers are in secure domain, and should be accessed by smc.
>     >>
>     >> Signed-off-by: Shunzhou Jiang <shunzhou.jiang at amlogic.com>
>     > Also here I don't have any datasheet to compare this with, so this gets my:
>     > Acked-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
>     >
>     > [...]
>     >> +?????? SEC_PD(S4_VPU_HDMI,???? GENPD_FLAG_ALWAYS_ON),
>     >> +?????? SEC_PD(S4_USB_COMB,???? GENPD_FLAG_ALWAYS_ON),
>     >> +?????? SEC_PD(S4_GE2D,???????? 0),
>     >> +?????? SEC_PD(S4_ETH,????????? GENPD_FLAG_ALWAYS_ON),
>     > For the A1 SoC's UART entry we have the following comment which
>     > explains why we want to to be "always on":
>     >?? UART should keep working in ATF after suspend and before resume
>     >
>     > If for some reason you need to re-send this series then it would be
>     > great if you could add a comment above each entry with
>     > GENPD_FLAG_ALWAYS_ON.
>     > It will help others (like me) understand these SoCs better.
>     ?
>     Can you resend with those comments added so I can apply the patches ?
>     ?
>     Thanks,
>     Neil
>     ?
>     >
>     >
>     > Best regards,
>     > Martin
>     >
>     ?
> 


From jagan at amarulasolutions.com  Thu Jan 20 03:03:22 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Thu, 20 Jan 2022 16:33:22 +0530
Subject: [PATCH 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <70d1af3f-bc00-4afd-1157-1cf70d3b2c88@baylibre.com>
References: <20200907081825.1654-1-narmstrong@baylibre.com>
 <20200907081825.1654-7-narmstrong@baylibre.com>
 <CAMty3ZBEmafG8LS_yv4eektvUoHwYFoV=-8wohUXgsvpRbZqtA@mail.gmail.com>
 <70d1af3f-bc00-4afd-1157-1cf70d3b2c88@baylibre.com>
Message-ID: <CAMty3ZC9Cp=8=iF=KYCWjwb-wk+VrPBzH+6L14H6iZcSm3CZjA@mail.gmail.com>

On Wed, Jan 12, 2022 at 1:49 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> Hi,
>
> On 12/01/2022 08:24, Jagan Teki wrote:
> > Hi Neil,
> >
> > On Mon, Sep 7, 2020 at 1:48 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
> >>
> >> The Amlogic AXg SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a), with a custom
> >> glue managing the IP resets, clock and data input similar to the DW-HDMI Glue on other
> >> Amlogic SoCs.
> >>
> >> This adds support for the Glue managing the transceiver, mimicing the init flow provided
> >> by Amlogic to setup the ENCl encoder, the glue, the transceiver, the digital D-PHY and the
> >> Analog PHY in the proper way.
> >>
> >> The DW-MIPI-DSI transceiver + D-PHY are directly clocked by the VCLK2 clock, which pixel clock
> >> is derived and feeds the ENCL encoder and the VIU pixel reader.
> >>
> >> An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
> >> DW-MIPI-DSI transceiver.
> >>
> >> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> >> ---
>
> [..]
>
> >> +
> >> +static const struct component_ops meson_dw_mipi_dsi_ops = {
> >> +       .bind   = meson_dw_mipi_dsi_bind,
> >> +       .unbind = meson_dw_mipi_dsi_unbind,
> >> +};
> >
> > Do you thought of non-component based meson DSI like STM DSI? It
> > require changes from meson drm but just to understand if you have any
> > such plan.
>
> I have no such plans for now, note this serie has been rewritten at [1] but still
> with based with components.
>
> If worth it, the plan is to get it with components and than yes if it's simpler
> drop components completely.

Dropping components make the pipeline well suited for bridges as we
are moving bridge-driven pipelines in other areas.

>
> I'll have a look at how ST does

ST has no components. As I said above, eventually there would be
common bridge driver for dw-mipi-dsi if meson and rockchip moving away
from components.

Thanks,
Jagan.


From narmstrong at baylibre.com  Thu Jan 20 05:28:11 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 14:28:11 +0100
Subject: [PATCH 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <CAMty3ZC9Cp=8=iF=KYCWjwb-wk+VrPBzH+6L14H6iZcSm3CZjA@mail.gmail.com>
References: <20200907081825.1654-1-narmstrong@baylibre.com>
 <20200907081825.1654-7-narmstrong@baylibre.com>
 <CAMty3ZBEmafG8LS_yv4eektvUoHwYFoV=-8wohUXgsvpRbZqtA@mail.gmail.com>
 <70d1af3f-bc00-4afd-1157-1cf70d3b2c88@baylibre.com>
 <CAMty3ZC9Cp=8=iF=KYCWjwb-wk+VrPBzH+6L14H6iZcSm3CZjA@mail.gmail.com>
Message-ID: <e1fa9887-da2e-3a69-0e2e-3a6d07e13cb5@baylibre.com>

Hi Jagan,

On 20/01/2022 12:03, Jagan Teki wrote:
> On Wed, Jan 12, 2022 at 1:49 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>>
>> Hi,
>>
>> On 12/01/2022 08:24, Jagan Teki wrote:
>>> Hi Neil,
>>>
>>> On Mon, Sep 7, 2020 at 1:48 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>>>>
>>>> The Amlogic AXg SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a), with a custom
>>>> glue managing the IP resets, clock and data input similar to the DW-HDMI Glue on other
>>>> Amlogic SoCs.
>>>>
>>>> This adds support for the Glue managing the transceiver, mimicing the init flow provided
>>>> by Amlogic to setup the ENCl encoder, the glue, the transceiver, the digital D-PHY and the
>>>> Analog PHY in the proper way.
>>>>
>>>> The DW-MIPI-DSI transceiver + D-PHY are directly clocked by the VCLK2 clock, which pixel clock
>>>> is derived and feeds the ENCL encoder and the VIU pixel reader.
>>>>
>>>> An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
>>>> DW-MIPI-DSI transceiver.
>>>>
>>>> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
>>>> ---
>>
>> [..]
>>
>>>> +
>>>> +static const struct component_ops meson_dw_mipi_dsi_ops = {
>>>> +       .bind   = meson_dw_mipi_dsi_bind,
>>>> +       .unbind = meson_dw_mipi_dsi_unbind,
>>>> +};
>>>
>>> Do you thought of non-component based meson DSI like STM DSI? It
>>> require changes from meson drm but just to understand if you have any
>>> such plan.
>>
>> I have no such plans for now, note this serie has been rewritten at [1] but still
>> with based with components.
>>
>> If worth it, the plan is to get it with components and than yes if it's simpler
>> drop components completely.
> 
> Dropping components make the pipeline well suited for bridges as we
> are moving bridge-driven pipelines in other areas.
> 
>>
>> I'll have a look at how ST does
> 
> ST has no components. As I said above, eventually there would be
> common bridge driver for dw-mipi-dsi if meson and rockchip moving away
> from components.

ST driver is much more simpler.

And having a common dw-mipi-dsi is unreal since each HW has a different glue HW
me must handle. Even if we moved all the glue handling under drm/bridge/synopsys,
we would need a different set of callbacks for each HW for each compatible
which is basically the actual situation except components.

Neil

> 
> Thanks,
> Jagan.
> 



From jagan at amarulasolutions.com  Thu Jan 20 06:22:54 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Thu, 20 Jan 2022 19:52:54 +0530
Subject: [PATCH v2 5/6] drm/meson: add DSI encoder
In-Reply-To: <20220120083357.1541262-6-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
 <20220120083357.1541262-6-narmstrong@baylibre.com>
Message-ID: <CAMty3ZCrcQchnne1KU1RQA6MfwRQS8dObJQcOF_H7fEQ57wa0w@mail.gmail.com>

On Thu, Jan 20, 2022 at 2:04 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> This adds an encoder bridge designed to drive a MIPI-DSI display
> by using the ENCL encoder through the internal MIPI DSI transceiver
> connected to the output of the ENCL pixel encoder.
>
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> ---
>  drivers/gpu/drm/meson/Makefile            |   2 +-
>  drivers/gpu/drm/meson/meson_drv.c         |   7 +
>  drivers/gpu/drm/meson/meson_encoder_dsi.c | 160 ++++++++++++++++++++++
>  drivers/gpu/drm/meson/meson_encoder_dsi.h |  12 ++
>  4 files changed, 180 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.c
>  create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.h
>
> diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
> index 3afa31bdc950..833e18c20603 100644
> --- a/drivers/gpu/drm/meson/Makefile
> +++ b/drivers/gpu/drm/meson/Makefile
> @@ -2,7 +2,7 @@
>  meson-drm-y := meson_drv.o meson_plane.o meson_crtc.o meson_encoder_cvbs.o
>  meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_overlay.o
>  meson-drm-y += meson_rdma.o meson_osd_afbcd.o
> -meson-drm-y += meson_encoder_hdmi.o
> +meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o
>
>  obj-$(CONFIG_DRM_MESON) += meson-drm.o
>  obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
> diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
> index 26aeaf0ab86e..15344cf9f913 100644
> --- a/drivers/gpu/drm/meson/meson_drv.c
> +++ b/drivers/gpu/drm/meson/meson_drv.c
> @@ -33,6 +33,7 @@
>  #include "meson_registers.h"
>  #include "meson_encoder_cvbs.h"
>  #include "meson_encoder_hdmi.h"
> +#include "meson_encoder_dsi.h"
>  #include "meson_viu.h"
>  #include "meson_vpp.h"
>  #include "meson_rdma.h"
> @@ -323,6 +324,12 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
>         if (ret)
>                 goto exit_afbcd;
>
> +       if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
> +               ret = meson_encoder_dsi_init(priv);
> +               if (ret)
> +                       goto free_drm;
> +       }
> +
>         ret = meson_plane_create(priv);
>         if (ret)
>                 goto exit_afbcd;
> diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.c b/drivers/gpu/drm/meson/meson_encoder_dsi.c
> new file mode 100644
> index 000000000000..12a586316183
> --- /dev/null
> +++ b/drivers/gpu/drm/meson/meson_encoder_dsi.c
> @@ -0,0 +1,160 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2016 BayLibre, SAS
> + * Author: Neil Armstrong <narmstrong at baylibre.com>
> + * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/of_graph.h>
> +
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_simple_kms_helper.h>
> +#include <drm/drm_bridge.h>
> +#include <drm/drm_bridge_connector.h>
> +#include <drm/drm_device.h>
> +#include <drm/drm_probe_helper.h>
> +
> +#include "meson_drv.h"
> +#include "meson_encoder_dsi.h"
> +#include "meson_registers.h"
> +#include "meson_venc.h"
> +#include "meson_vclk.h"
> +
> +struct meson_encoder_dsi {
> +       struct drm_encoder encoder;
> +       struct drm_bridge bridge;
> +       struct drm_bridge *next_bridge;
> +       struct meson_drm *priv;
> +};
> +
> +#define bridge_to_meson_encoder_dsi(x) \
> +       container_of(x, struct meson_encoder_dsi, bridge)
> +
> +static int meson_encoder_dsi_attach(struct drm_bridge *bridge,
> +                                   enum drm_bridge_attach_flags flags)
> +{
> +       struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
> +
> +       return drm_bridge_attach(bridge->encoder, encoder_dsi->next_bridge,
> +                                &encoder_dsi->bridge, flags);
> +}
> +
> +static void meson_encoder_dsi_mode_set(struct drm_bridge *bridge,
> +                                      const struct drm_display_mode *mode,
> +                                      const struct drm_display_mode *adjusted_mode)
> +{
> +       struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
> +       struct meson_drm *priv = encoder_dsi->priv;
> +
> +       meson_vclk_setup(priv, MESON_VCLK_TARGET_DSI, mode->clock, 0, 0, 0, false);
> +
> +       meson_venc_mipi_dsi_mode_set(priv, mode);
> +       meson_encl_load_gamma(priv);
> +
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
> +
> +       writel_bits_relaxed(ENCL_VIDEO_MODE_ADV_VFIFO_EN, ENCL_VIDEO_MODE_ADV_VFIFO_EN,
> +                           priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_EN));
> +}
> +
> +static void meson_encoder_dsi_atomic_enable(struct drm_bridge *bridge,
> +                                           struct drm_bridge_state *bridge_state)
> +{
> +       struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
> +       struct meson_drm *priv = encoder_dsi->priv;
> +
> +       writel_bits_relaxed(BIT(0), 0, priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL));
> +
> +       writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
> +}
> +
> +static void meson_encoder_dsi_atomic_disable(struct drm_bridge *bridge,
> +                                            struct drm_bridge_state *bridge_state)
> +{
> +       struct meson_encoder_dsi *meson_encoder_dsi =
> +                                       bridge_to_meson_encoder_dsi(bridge);
> +       struct meson_drm *priv = meson_encoder_dsi->priv;
> +
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
> +
> +       writel_bits_relaxed(BIT(0), BIT(0), priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL));
> +}
> +
> +static const struct drm_bridge_funcs meson_encoder_dsi_bridge_funcs = {
> +       .attach = meson_encoder_dsi_attach,
> +       /*
> +        * TOFIX: remove when dw-mipi-dsi moves out of mode_set
> +        * We should get rid of mode_set, but until dw-mipi-dsi uses it
> +        * we need to setup the pixel clock before the following
> +        * bridge tries to setup the HW.
> +        */
> +       .mode_set = meson_encoder_dsi_mode_set,
> +       .atomic_enable = meson_encoder_dsi_atomic_enable,
> +       .atomic_disable = meson_encoder_dsi_atomic_disable,
> +       .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
> +       .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> +       .atomic_reset = drm_atomic_helper_bridge_reset,
> +};
> +
> +int meson_encoder_dsi_init(struct meson_drm *priv)
> +{
> +       struct meson_encoder_dsi *meson_encoder_dsi;
> +       struct device_node *remote;
> +       int ret;
> +
> +       meson_encoder_dsi = devm_kzalloc(priv->dev, sizeof(*meson_encoder_dsi), GFP_KERNEL);
> +       if (!meson_encoder_dsi)
> +               return -ENOMEM;
> +
> +       /* DSI Transceiver Bridge */
> +       remote = of_graph_get_remote_node(priv->dev->of_node, 2, 0);
> +       if (!remote) {
> +               dev_err(priv->dev, "DSI transceiver device is disabled");
> +               return 0;
> +       }
> +
> +       meson_encoder_dsi->next_bridge = of_drm_find_bridge(remote);
> +       if (!meson_encoder_dsi->next_bridge) {
> +               dev_dbg(priv->dev, "Failed to find DSI transceiver bridge: %d\n", ret);
> +               return -EPROBE_DEFER;
> +       }
> +
> +       /* DSI Encoder Bridge */
> +       meson_encoder_dsi->bridge.funcs = &meson_encoder_dsi_bridge_funcs;
> +       meson_encoder_dsi->bridge.of_node = priv->dev->of_node;
> +       meson_encoder_dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
> +
> +       drm_bridge_add(&meson_encoder_dsi->bridge);
> +
> +       meson_encoder_dsi->priv = priv;
> +
> +       /* Encoder */
> +       ret = drm_simple_encoder_init(priv->drm, &meson_encoder_dsi->encoder,
> +                                     DRM_MODE_ENCODER_DSI);
> +       if (ret) {
> +               dev_err(priv->dev, "Failed to init DSI encoder: %d\n", ret);
> +               return ret;
> +       }
> +
> +       meson_encoder_dsi->encoder.possible_crtcs = BIT(0);
> +
> +       /* Attach DSI Encoder Bridge to Encoder */
> +       ret = drm_bridge_attach(&meson_encoder_dsi->encoder, &meson_encoder_dsi->bridge, NULL, 0);
> +       if (ret) {
> +               dev_err(priv->dev, "Failed to attach bridge: %d\n", ret);
> +               return ret;
> +       }
> +
> +       /*
> +        * We should have now in place:
> +        * encoder->[dsi encoder bridge]->[dw-mipi-dsi bridge]->[panel bridge]->[panel]
> +        */

Reviewed-by: Jagan Teki <jagan at amarulasolutions.com>


From jagan at amarulasolutions.com  Thu Jan 20 06:24:55 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Thu, 20 Jan 2022 19:54:55 +0530
Subject: [PATCH v2 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <20220120083357.1541262-7-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
 <20220120083357.1541262-7-narmstrong@baylibre.com>
Message-ID: <CAMty3ZBvbPvKgUpNW1LVho5_S9kwzNioE0SxvX_E8bmgw-+fXw@mail.gmail.com>

On Thu, Jan 20, 2022 at 2:04 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> The Amlogic G12A/G12B/SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
> with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
> Glue on other Amlogic SoCs.
>
> This adds support for the Glue managing the transceiver, mimicing the init flow provided
> by Amlogic to setup the ENCL encoder, the glue, the transceiver, the digital D-PHY and the
> Analog PHY in the proper way.
>
> An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
> DW-MIPI-DSI transceiver.
>
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> ---
>  drivers/gpu/drm/meson/Kconfig             |   7 +
>  drivers/gpu/drm/meson/Makefile            |   1 +
>  drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 357 ++++++++++++++++++++++
>  drivers/gpu/drm/meson/meson_dw_mipi_dsi.h | 160 ++++++++++
>  4 files changed, 525 insertions(+)
>  create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
>  create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
>
> diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
> index 6c70fc3214af..71a1364b51e1 100644
> --- a/drivers/gpu/drm/meson/Kconfig
> +++ b/drivers/gpu/drm/meson/Kconfig
> @@ -17,3 +17,10 @@ config DRM_MESON_DW_HDMI
>         default y if DRM_MESON
>         select DRM_DW_HDMI
>         imply DRM_DW_HDMI_I2S_AUDIO
> +
> +config DRM_MESON_DW_MIPI_DSI
> +       tristate "MIPI DSI Synopsys Controller support for Amlogic Meson Display"
> +       depends on DRM_MESON
> +       default y if DRM_MESON
> +       select DRM_DW_MIPI_DSI
> +       select GENERIC_PHY_MIPI_DPHY
> diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
> index 833e18c20603..43071bdbd4b9 100644
> --- a/drivers/gpu/drm/meson/Makefile
> +++ b/drivers/gpu/drm/meson/Makefile
> @@ -6,3 +6,4 @@ meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o
>
>  obj-$(CONFIG_DRM_MESON) += meson-drm.o
>  obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
> +obj-$(CONFIG_DRM_MESON_DW_MIPI_DSI) += meson_dw_mipi_dsi.o

Can the naming convention prefix with dw-mipi-dsi like other glue
drivers follow?

Jagan.


From narmstrong at baylibre.com  Thu Jan 20 08:26:20 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 17:26:20 +0100
Subject: [PATCH v2 3/6] drm/meson: venc: add ENCL encoder setup for
 MIPI-DSI output
In-Reply-To: <20220120083357.1541262-4-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
 <20220120083357.1541262-4-narmstrong@baylibre.com>
Message-ID: <17810339-0e9c-0042-b6f7-927f5fe00421@baylibre.com>

On 20/01/2022 09:33, Neil Armstrong wrote:
> This adds supports for the ENCL encoder connected to a MIPI-DSI transceiver on the
> Amlogic AXG, G12A, G12B & SM1 SoCs.
> 
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> ---
>  drivers/gpu/drm/meson/meson_registers.h |  15 ++
>  drivers/gpu/drm/meson/meson_venc.c      | 211 +++++++++++++++++++++++-
>  drivers/gpu/drm/meson/meson_venc.h      |   6 +
>  drivers/gpu/drm/meson/meson_vpp.h       |   2 +
>  4 files changed, 232 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h
> index 0f3cafab8860..a422a8df1641 100644
> --- a/drivers/gpu/drm/meson/meson_registers.h
> +++ b/drivers/gpu/drm/meson/meson_registers.h
> @@ -1300,13 +1300,28 @@
>  #define RDMA_STATUS2 0x1116
>  #define RDMA_STATUS3 0x1117
>  #define L_GAMMA_CNTL_PORT 0x1400
> +#define		L_GAMMA_CNTL_PORT_VCOM_POL	BIT(7)	/* RW */
> +#define		L_GAMMA_CNTL_PORT_RVS_OUT	BIT(6)	/* RW */
> +#define		L_GAMMA_CNTL_PORT_ADR_RDY	BIT(5)	/* Read Only */
> +#define		L_GAMMA_CNTL_PORT_WR_RDY	BIT(4)	/* Read Only */
> +#define		L_GAMMA_CNTL_PORT_RD_RDY	BIT(3)	/* Read Only */
> +#define		L_GAMMA_CNTL_PORT_TR		BIT(2)	/* RW */
> +#define		L_GAMMA_CNTL_PORT_SET		BIT(1)	/* RW */
> +#define		L_GAMMA_CNTL_PORT_EN		BIT(0)	/* RW */
>  #define L_GAMMA_DATA_PORT 0x1401
>  #define L_GAMMA_ADDR_PORT 0x1402
> +#define		L_GAMMA_ADDR_PORT_RD		BIT(12)
> +#define		L_GAMMA_ADDR_PORT_AUTO_INC	BIT(11)
> +#define		L_GAMMA_ADDR_PORT_SEL_R		BIT(10)
> +#define		L_GAMMA_ADDR_PORT_SEL_G		BIT(9)
> +#define		L_GAMMA_ADDR_PORT_SEL_B		BIT(8)
> +#define		L_GAMMA_ADDR_PORT_ADDR		GENMASK(7, 0)
>  #define L_GAMMA_VCOM_HSWITCH_ADDR 0x1403
>  #define L_RGB_BASE_ADDR 0x1405
>  #define L_RGB_COEFF_ADDR 0x1406
>  #define L_POL_CNTL_ADDR 0x1407
>  #define L_DITH_CNTL_ADDR 0x1408
> +#define		L_DITH_CNTL_DITH10_EN	BIT(10)
>  #define L_GAMMA_PROBE_CTRL 0x1409
>  #define L_GAMMA_PROBE_COLOR_L 0x140a
>  #define L_GAMMA_PROBE_COLOR_H 0x140b

OK Somehow the following disappeared from the patchset...

 #define VENC_INTCTRL 0x1b6e
 #define		VENC_INTCTRL_ENCI_LNRST_INT_EN  BIT(1)
-#define		VENC_INTCTRL_ENCP_LNRST_INT_EN  BIT(9)
 #define VENC_INTFLAG 0x1b6f

 #define ENCL_VIDEO_MODE 0x1ca7
-#define		ENCL_PX_LN_CNT_SHADOW_EN	BIT(15)
 #define ENCL_VIDEO_MODE_ADV 0x1ca8
-#define		ENCL_VIDEO_MODE_ADV_VFIFO_EN	BIT(3)
-#define		ENCL_VIDEO_MODE_ADV_GAIN_HDTV	BIT(4)
-#define		ENCL_SEL_GAMMA_RGB_IN		BIT(10)
 #define ENCL_DBG_PX_RST 0x1ca9
 #define ENCL_VIDEO_FILT_CTRL 0x1cc2

-#define		ENCL_VIDEO_FILT_CTRL_BYPASS_FILTER	BIT(12)
 #define ENCL_VIDEO_OFLD_VPEQ_OFST 0x1cc3

 #define ENCL_VIDEO_RGBIN_CTRL 0x1cc7
-#define		ENCL_VIDEO_RGBIN_RGB	BIT(0)
-#define		ENCL_VIDEO_RGBIN_ZBLK	BIT(1)
 #define ENCL_MAX_LINE_SWITCH_POINT 0x1cc8


 #define L_TCON_MISC_SEL_ADDR 0x1441
-#define		L_TCON_MISC_SEL_STV1	BIT(4)
-#define		L_TCON_MISC_SEL_STV2	BIT(5)
 #define L_DUAL_PORT_CNTL_ADDR 0x1442

I'll resend with those

> diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
> index 3c55ed003359..eb2ac0549d46 100644
> --- a/drivers/gpu/drm/meson/meson_venc.c
> +++ b/drivers/gpu/drm/meson/meson_venc.c
> @@ -6,6 +6,7 @@
>   */
>  
>  #include <linux/export.h>
> +#include <linux/iopoll.h>
>  
>  #include <drm/drm_modes.h>
>  
> @@ -1557,6 +1558,205 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
>  }
>  EXPORT_SYMBOL_GPL(meson_venc_hdmi_mode_set);
>  
> +static unsigned short meson_encl_gamma_table[256] = {
> +	0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
> +	64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
> +	128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188,
> +	192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252,
> +	256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 304, 308, 312, 316,
> +	320, 324, 328, 332, 336, 340, 344, 348, 352, 356, 360, 364, 368, 372, 376, 380,
> +	384, 388, 392, 396, 400, 404, 408, 412, 416, 420, 424, 428, 432, 436, 440, 444,
> +	448, 452, 456, 460, 464, 468, 472, 476, 480, 484, 488, 492, 496, 500, 504, 508,
> +	512, 516, 520, 524, 528, 532, 536, 540, 544, 548, 552, 556, 560, 564, 568, 572,
> +	576, 580, 584, 588, 592, 596, 600, 604, 608, 612, 616, 620, 624, 628, 632, 636,
> +	640, 644, 648, 652, 656, 660, 664, 668, 672, 676, 680, 684, 688, 692, 696, 700,
> +	704, 708, 712, 716, 720, 724, 728, 732, 736, 740, 744, 748, 752, 756, 760, 764,
> +	768, 772, 776, 780, 784, 788, 792, 796, 800, 804, 808, 812, 816, 820, 824, 828,
> +	832, 836, 840, 844, 848, 852, 856, 860, 864, 868, 872, 876, 880, 884, 888, 892,
> +	896, 900, 904, 908, 912, 916, 920, 924, 928, 932, 936, 940, 944, 948, 952, 956,
> +	960, 964, 968, 972, 976, 980, 984, 988, 992, 996, 1000, 1004, 1008, 1012, 1016, 1020,
> +};
> +
> +static void meson_encl_set_gamma_table(struct meson_drm *priv, u16 *data,
> +				       u32 rgb_mask)
> +{
> +	int i, ret;
> +	u32 reg;
> +
> +	writel_bits_relaxed(L_GAMMA_CNTL_PORT_EN, 0,
> +			    priv->io_base + _REG(L_GAMMA_CNTL_PORT));
> +
> +	ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT),
> +					 reg, reg & L_GAMMA_CNTL_PORT_ADR_RDY, 10, 10000);
> +	if (ret)
> +		pr_warn("%s: GAMMA ADR_RDY timeout\n", __func__);
> +
> +	writel_relaxed(L_GAMMA_ADDR_PORT_AUTO_INC | rgb_mask |
> +		       FIELD_PREP(L_GAMMA_ADDR_PORT_ADDR, 0),
> +		       priv->io_base + _REG(L_GAMMA_ADDR_PORT));
> +
> +	for (i = 0; i < 256; i++) {
> +		ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT),
> +						 reg, reg & L_GAMMA_CNTL_PORT_WR_RDY,
> +						 10, 10000);
> +		if (ret)
> +			pr_warn_once("%s: GAMMA WR_RDY timeout\n", __func__);
> +
> +		writel_relaxed(data[i], priv->io_base + _REG(L_GAMMA_DATA_PORT));
> +	}
> +
> +	ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT),
> +					 reg, reg & L_GAMMA_CNTL_PORT_ADR_RDY, 10, 10000);
> +	if (ret)
> +		pr_warn("%s: GAMMA ADR_RDY timeout\n", __func__);
> +
> +	writel_relaxed(L_GAMMA_ADDR_PORT_AUTO_INC | rgb_mask |
> +		       FIELD_PREP(L_GAMMA_ADDR_PORT_ADDR, 0x23),
> +		       priv->io_base + _REG(L_GAMMA_ADDR_PORT));
> +}
> +
> +void meson_encl_load_gamma(struct meson_drm *priv)
> +{
> +	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_R);
> +	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_G);
> +	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_B);
> +
> +	writel_bits_relaxed(L_GAMMA_CNTL_PORT_EN, L_GAMMA_CNTL_PORT_EN,
> +			    priv->io_base + _REG(L_GAMMA_CNTL_PORT));
> +}
> +
> +void meson_venc_mipi_dsi_mode_set(struct meson_drm *priv,
> +				  const struct drm_display_mode *mode)
> +{
> +	unsigned int max_pxcnt;
> +	unsigned int max_lncnt;
> +	unsigned int havon_begin;
> +	unsigned int havon_end;
> +	unsigned int vavon_bline;
> +	unsigned int vavon_eline;
> +	unsigned int hso_begin;
> +	unsigned int hso_end;
> +	unsigned int vso_begin;
> +	unsigned int vso_end;
> +	unsigned int vso_bline;
> +	unsigned int vso_eline;
> +
> +	max_pxcnt = mode->htotal - 1;
> +	max_lncnt = mode->vtotal - 1;
> +	havon_begin = mode->htotal - mode->hsync_start;
> +	havon_end = havon_begin + mode->hdisplay - 1;
> +	vavon_bline = mode->vtotal - mode->vsync_start;
> +	vavon_eline = vavon_bline + mode->vdisplay - 1;
> +	hso_begin = 0;
> +	hso_end = mode->hsync_end - mode->hsync_start;
> +	vso_begin = 0;
> +	vso_end = 0;
> +	vso_bline = 0;
> +	vso_eline = mode->vsync_end - mode->vsync_start;
> +
> +	meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCL);
> +
> +	writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
> +
> +	writel_relaxed(ENCL_PX_LN_CNT_SHADOW_EN, priv->io_base + _REG(ENCL_VIDEO_MODE));
> +	writel_relaxed(ENCL_VIDEO_MODE_ADV_VFIFO_EN |
> +		       ENCL_VIDEO_MODE_ADV_GAIN_HDTV |
> +		       ENCL_SEL_GAMMA_RGB_IN, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
> +
> +	writel_relaxed(ENCL_VIDEO_FILT_CTRL_BYPASS_FILTER,
> +		       priv->io_base + _REG(ENCL_VIDEO_FILT_CTRL));
> +	writel_relaxed(max_pxcnt, priv->io_base + _REG(ENCL_VIDEO_MAX_PXCNT));
> +	writel_relaxed(max_lncnt, priv->io_base + _REG(ENCL_VIDEO_MAX_LNCNT));
> +	writel_relaxed(havon_begin, priv->io_base + _REG(ENCL_VIDEO_HAVON_BEGIN));
> +	writel_relaxed(havon_end, priv->io_base + _REG(ENCL_VIDEO_HAVON_END));
> +	writel_relaxed(vavon_bline, priv->io_base + _REG(ENCL_VIDEO_VAVON_BLINE));
> +	writel_relaxed(vavon_eline, priv->io_base + _REG(ENCL_VIDEO_VAVON_ELINE));
> +
> +	writel_relaxed(hso_begin, priv->io_base + _REG(ENCL_VIDEO_HSO_BEGIN));
> +	writel_relaxed(hso_end, priv->io_base + _REG(ENCL_VIDEO_HSO_END));
> +	writel_relaxed(vso_begin, priv->io_base + _REG(ENCL_VIDEO_VSO_BEGIN));
> +	writel_relaxed(vso_end, priv->io_base + _REG(ENCL_VIDEO_VSO_END));
> +	writel_relaxed(vso_bline, priv->io_base + _REG(ENCL_VIDEO_VSO_BLINE));
> +	writel_relaxed(vso_eline, priv->io_base + _REG(ENCL_VIDEO_VSO_ELINE));
> +	writel_relaxed(ENCL_VIDEO_RGBIN_RGB | ENCL_VIDEO_RGBIN_ZBLK,
> +		       priv->io_base + _REG(ENCL_VIDEO_RGBIN_CTRL));
> +
> +	/* default black pattern */
> +	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_MDSEL));
> +	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_Y));
> +	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CB));
> +	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CR));
> +	writel_relaxed(1, priv->io_base + _REG(ENCL_TST_EN));
> +	writel_bits_relaxed(ENCL_VIDEO_MODE_ADV_VFIFO_EN, 0,
> +			    priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
> +
> +	writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
> +
> +	writel_relaxed(0, priv->io_base + _REG(L_RGB_BASE_ADDR));
> +	writel_relaxed(0x400, priv->io_base + _REG(L_RGB_COEFF_ADDR)); /* Magic value */
> +
> +	writel_relaxed(L_DITH_CNTL_DITH10_EN, priv->io_base + _REG(L_DITH_CNTL_ADDR));
> +
> +	/* DE signal for TTL */
> +	writel_relaxed(havon_begin, priv->io_base + _REG(L_OEH_HS_ADDR));
> +	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_OEH_HE_ADDR));
> +	writel_relaxed(vavon_bline, priv->io_base + _REG(L_OEH_VS_ADDR));
> +	writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEH_VE_ADDR));
> +
> +	/* DE signal for TTL */
> +	writel_relaxed(havon_begin, priv->io_base + _REG(L_OEV1_HS_ADDR));
> +	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_OEV1_HE_ADDR));
> +	writel_relaxed(vavon_bline, priv->io_base + _REG(L_OEV1_VS_ADDR));
> +	writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEV1_VE_ADDR));
> +
> +	/* Hsync signal for TTL */
> +	if (mode->flags & DRM_MODE_FLAG_PHSYNC) {
> +		writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HS_ADDR));
> +		writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HE_ADDR));
> +	} else {
> +		writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HS_ADDR));
> +		writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HE_ADDR));
> +	}
> +	writel_relaxed(0, priv->io_base + _REG(L_STH1_VS_ADDR));
> +	writel_relaxed(max_lncnt, priv->io_base + _REG(L_STH1_VE_ADDR));
> +
> +	/* Vsync signal for TTL */
> +	writel_relaxed(vso_begin, priv->io_base + _REG(L_STV1_HS_ADDR));
> +	writel_relaxed(vso_end, priv->io_base + _REG(L_STV1_HE_ADDR));
> +	if (mode->flags & DRM_MODE_FLAG_PVSYNC) {
> +		writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VS_ADDR));
> +		writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VE_ADDR));
> +	} else {
> +		writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VS_ADDR));
> +		writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VE_ADDR));
> +	}
> +
> +	/* DE signal */
> +	writel_relaxed(havon_begin, priv->io_base + _REG(L_DE_HS_ADDR));
> +	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_DE_HE_ADDR));
> +	writel_relaxed(vavon_bline, priv->io_base + _REG(L_DE_VS_ADDR));
> +	writel_relaxed(vavon_eline, priv->io_base + _REG(L_DE_VE_ADDR));
> +
> +	/* Hsync signal */
> +	writel_relaxed(hso_begin, priv->io_base + _REG(L_HSYNC_HS_ADDR));
> +	writel_relaxed(hso_end, priv->io_base + _REG(L_HSYNC_HE_ADDR));
> +	writel_relaxed(0, priv->io_base + _REG(L_HSYNC_VS_ADDR));
> +	writel_relaxed(max_lncnt, priv->io_base + _REG(L_HSYNC_VE_ADDR));
> +
> +	/* Vsync signal */
> +	writel_relaxed(vso_begin, priv->io_base + _REG(L_VSYNC_HS_ADDR));
> +	writel_relaxed(vso_end, priv->io_base + _REG(L_VSYNC_HE_ADDR));
> +	writel_relaxed(vso_bline, priv->io_base + _REG(L_VSYNC_VS_ADDR));
> +	writel_relaxed(vso_eline, priv->io_base + _REG(L_VSYNC_VE_ADDR));
> +
> +	writel_relaxed(0, priv->io_base + _REG(L_INV_CNT_ADDR));
> +	writel_relaxed(L_TCON_MISC_SEL_STV1 | L_TCON_MISC_SEL_STV2,
> +		       priv->io_base + _REG(L_TCON_MISC_SEL_ADDR));
> +
> +	priv->venc.current_mode = MESON_VENC_MODE_MIPI_DSI;
> +}
> +EXPORT_SYMBOL_GPL(meson_venc_mipi_dsi_mode_set);
> +
>  void meson_venci_cvbs_mode_set(struct meson_drm *priv,
>  			       struct meson_cvbs_enci_mode *mode)
>  {
> @@ -1747,8 +1947,15 @@ unsigned int meson_venci_get_field(struct meson_drm *priv)
>  
>  void meson_venc_enable_vsync(struct meson_drm *priv)
>  {
> -	writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
> -		       priv->io_base + _REG(VENC_INTCTRL));
> +	switch (priv->venc.current_mode) {
> +	case MESON_VENC_MODE_MIPI_DSI:
> +		writel_relaxed(VENC_INTCTRL_ENCP_LNRST_INT_EN,
> +			       priv->io_base + _REG(VENC_INTCTRL));
> +		break;
> +	default:
> +		writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
> +			       priv->io_base + _REG(VENC_INTCTRL));
> +	}
>  	regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25));
>  }
>  
> diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h
> index 9138255ffc9e..0f59adb1c6db 100644
> --- a/drivers/gpu/drm/meson/meson_venc.h
> +++ b/drivers/gpu/drm/meson/meson_venc.h
> @@ -21,6 +21,7 @@ enum {
>  	MESON_VENC_MODE_CVBS_PAL,
>  	MESON_VENC_MODE_CVBS_NTSC,
>  	MESON_VENC_MODE_HDMI,
> +	MESON_VENC_MODE_MIPI_DSI,
>  };
>  
>  struct meson_cvbs_enci_mode {
> @@ -47,6 +48,9 @@ struct meson_cvbs_enci_mode {
>  	unsigned int analog_sync_adj;
>  };
>  
> +/* LCD Encoder gamma setup */
> +void meson_encl_load_gamma(struct meson_drm *priv);
> +
>  /* HDMI Clock parameters */
>  enum drm_mode_status
>  meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode);
> @@ -63,6 +67,8 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
>  			      unsigned int ycrcb_map,
>  			      bool yuv420_mode,
>  			      const struct drm_display_mode *mode);
> +void meson_venc_mipi_dsi_mode_set(struct meson_drm *priv,
> +				  const struct drm_display_mode *mode);
>  unsigned int meson_venci_get_field(struct meson_drm *priv);
>  
>  void meson_venc_enable_vsync(struct meson_drm *priv);
> diff --git a/drivers/gpu/drm/meson/meson_vpp.h b/drivers/gpu/drm/meson/meson_vpp.h
> index afc9553ed8d3..b790042a1650 100644
> --- a/drivers/gpu/drm/meson/meson_vpp.h
> +++ b/drivers/gpu/drm/meson/meson_vpp.h
> @@ -12,6 +12,8 @@
>  struct drm_rect;
>  struct meson_drm;
>  
> +/* Mux VIU/VPP to ENCL */
> +#define MESON_VIU_VPP_MUX_ENCL	0x0
>  /* Mux VIU/VPP to ENCI */
>  #define MESON_VIU_VPP_MUX_ENCI	0x5
>  /* Mux VIU/VPP to ENCP */
> 



From narmstrong at baylibre.com  Thu Jan 20 08:30:14 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 17:30:14 +0100
Subject: [PATCH v2 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <CAMty3ZBvbPvKgUpNW1LVho5_S9kwzNioE0SxvX_E8bmgw-+fXw@mail.gmail.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
 <20220120083357.1541262-7-narmstrong@baylibre.com>
 <CAMty3ZBvbPvKgUpNW1LVho5_S9kwzNioE0SxvX_E8bmgw-+fXw@mail.gmail.com>
Message-ID: <b2086dd4-643f-26b3-3930-4d8beb170b75@baylibre.com>

Hi,

On 20/01/2022 15:24, Jagan Teki wrote:
> On Thu, Jan 20, 2022 at 2:04 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>>
>> The Amlogic G12A/G12B/SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
>> with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
>> Glue on other Amlogic SoCs.
>>
>> This adds support for the Glue managing the transceiver, mimicing the init flow provided
>> by Amlogic to setup the ENCL encoder, the glue, the transceiver, the digital D-PHY and the
>> Analog PHY in the proper way.
>>
>> An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
>> DW-MIPI-DSI transceiver.
>>
>> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
>> ---
>>  drivers/gpu/drm/meson/Kconfig             |   7 +
>>  drivers/gpu/drm/meson/Makefile            |   1 +
>>  drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 357 ++++++++++++++++++++++
>>  drivers/gpu/drm/meson/meson_dw_mipi_dsi.h | 160 ++++++++++
>>  4 files changed, 525 insertions(+)
>>  create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
>>  create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
>>
>> diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
>> index 6c70fc3214af..71a1364b51e1 100644
>> --- a/drivers/gpu/drm/meson/Kconfig
>> +++ b/drivers/gpu/drm/meson/Kconfig
>> @@ -17,3 +17,10 @@ config DRM_MESON_DW_HDMI
>>         default y if DRM_MESON
>>         select DRM_DW_HDMI
>>         imply DRM_DW_HDMI_I2S_AUDIO
>> +
>> +config DRM_MESON_DW_MIPI_DSI
>> +       tristate "MIPI DSI Synopsys Controller support for Amlogic Meson Display"
>> +       depends on DRM_MESON
>> +       default y if DRM_MESON
>> +       select DRM_DW_MIPI_DSI
>> +       select GENERIC_PHY_MIPI_DPHY
>> diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
>> index 833e18c20603..43071bdbd4b9 100644
>> --- a/drivers/gpu/drm/meson/Makefile
>> +++ b/drivers/gpu/drm/meson/Makefile
>> @@ -6,3 +6,4 @@ meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o
>>
>>  obj-$(CONFIG_DRM_MESON) += meson-drm.o
>>  obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
>> +obj-$(CONFIG_DRM_MESON_DW_MIPI_DSI) += meson_dw_mipi_dsi.o
> 
> Can the naming convention prefix with dw-mipi-dsi like other glue
> drivers follow?

Seems only rockchip names their glue like that:

$ find drivers/gpu/drm/ -name "*dw*mipi*dsi*.c"
drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
drivers/gpu/drm/stm/dw_mipi_dsi-stm.c

If you look at dw-hdmi it's even worse:

$ find drivers/gpu/drm/ -name "*dw*hdmi*.c" | grep -v mod
drivers/gpu/drm/meson/meson_dw_hdmi.c
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
drivers/gpu/drm/imx/dw_hdmi-imx.c
drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c

Neil
> 
> Jagan.
> 


From jagan at amarulasolutions.com  Thu Jan 20 10:32:06 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Fri, 21 Jan 2022 00:02:06 +0530
Subject: [PATCH v2 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <b2086dd4-643f-26b3-3930-4d8beb170b75@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
 <20220120083357.1541262-7-narmstrong@baylibre.com>
 <CAMty3ZBvbPvKgUpNW1LVho5_S9kwzNioE0SxvX_E8bmgw-+fXw@mail.gmail.com>
 <b2086dd4-643f-26b3-3930-4d8beb170b75@baylibre.com>
Message-ID: <CAMty3ZCb=oTw8inrk0MNHtjfJPVMKm2u-L8YSr=e0eQZ9HyQbA@mail.gmail.com>

On Thu, Jan 20, 2022 at 10:00 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> Hi,
>
> On 20/01/2022 15:24, Jagan Teki wrote:
> > On Thu, Jan 20, 2022 at 2:04 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
> >>
> >> The Amlogic G12A/G12B/SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
> >> with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
> >> Glue on other Amlogic SoCs.
> >>
> >> This adds support for the Glue managing the transceiver, mimicing the init flow provided
> >> by Amlogic to setup the ENCL encoder, the glue, the transceiver, the digital D-PHY and the
> >> Analog PHY in the proper way.
> >>
> >> An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
> >> DW-MIPI-DSI transceiver.
> >>
> >> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> >> ---
> >>  drivers/gpu/drm/meson/Kconfig             |   7 +
> >>  drivers/gpu/drm/meson/Makefile            |   1 +
> >>  drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 357 ++++++++++++++++++++++
> >>  drivers/gpu/drm/meson/meson_dw_mipi_dsi.h | 160 ++++++++++
> >>  4 files changed, 525 insertions(+)
> >>  create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
> >>  create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
> >>
> >> diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
> >> index 6c70fc3214af..71a1364b51e1 100644
> >> --- a/drivers/gpu/drm/meson/Kconfig
> >> +++ b/drivers/gpu/drm/meson/Kconfig
> >> @@ -17,3 +17,10 @@ config DRM_MESON_DW_HDMI
> >>         default y if DRM_MESON
> >>         select DRM_DW_HDMI
> >>         imply DRM_DW_HDMI_I2S_AUDIO
> >> +
> >> +config DRM_MESON_DW_MIPI_DSI
> >> +       tristate "MIPI DSI Synopsys Controller support for Amlogic Meson Display"
> >> +       depends on DRM_MESON
> >> +       default y if DRM_MESON
> >> +       select DRM_DW_MIPI_DSI
> >> +       select GENERIC_PHY_MIPI_DPHY
> >> diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
> >> index 833e18c20603..43071bdbd4b9 100644
> >> --- a/drivers/gpu/drm/meson/Makefile
> >> +++ b/drivers/gpu/drm/meson/Makefile
> >> @@ -6,3 +6,4 @@ meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o
> >>
> >>  obj-$(CONFIG_DRM_MESON) += meson-drm.o
> >>  obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
> >> +obj-$(CONFIG_DRM_MESON_DW_MIPI_DSI) += meson_dw_mipi_dsi.o
> >
> > Can the naming convention prefix with dw-mipi-dsi like other glue
> > drivers follow?
>
> Seems only rockchip names their glue like that:
>
> $ find drivers/gpu/drm/ -name "*dw*mipi*dsi*.c"
> drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
> drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
>
> If you look at dw-hdmi it's even worse:
>
> $ find drivers/gpu/drm/ -name "*dw*hdmi*.c" | grep -v mod
> drivers/gpu/drm/meson/meson_dw_hdmi.c
> drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
> drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> drivers/gpu/drm/imx/dw_hdmi-imx.c
> drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c

Look like there is no standard naming, thanks.

Jagan.


From jagan at amarulasolutions.com  Thu Jan 20 10:33:10 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Fri, 21 Jan 2022 00:03:10 +0530
Subject: [PATCH v2 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <20220120083357.1541262-7-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
 <20220120083357.1541262-7-narmstrong@baylibre.com>
Message-ID: <CAMty3ZBdzW++6mCaqCLuL0QWwY7ve1vmLSPhaS8QqYji_jDXSg@mail.gmail.com>

On Thu, Jan 20, 2022 at 2:04 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> The Amlogic G12A/G12B/SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
> with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
> Glue on other Amlogic SoCs.
>
> This adds support for the Glue managing the transceiver, mimicing the init flow provided
> by Amlogic to setup the ENCL encoder, the glue, the transceiver, the digital D-PHY and the
> Analog PHY in the proper way.
>
> An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
> DW-MIPI-DSI transceiver.
>
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> ---

Reviewed-by: Jagan Teki <jagan at amarulasolutions.com>


From jbrunet at baylibre.com  Thu Jan 20 13:40:31 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Thu, 20 Jan 2022 22:40:31 +0100
Subject: [PATCH V6 3/5] tty: serial: meson: Describes the calculation of
 the UART baud rate clock using a clock frame
In-Reply-To: <20220118030911.12815-4-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <20220118030911.12815-4-yu.tu@amlogic.com>
Message-ID: <1jfspi2i5s.fsf@starbuckisacylon.baylibre.com>


On Tue 18 Jan 2022 at 11:09, Yu Tu <yu.tu at amlogic.com> wrote:

> Using the common Clock code to describe the UART baud rate clock
> makes it easier for the UART driver to be compatible with the
> baud rate requirements of the UART IP on different meson chips.
>
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>  drivers/tty/serial/meson_uart.c | 195 +++++++++++++++++++++++---------
>  1 file changed, 142 insertions(+), 53 deletions(-)
>
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 7570958d010c..92fa91c825e6 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -6,6 +6,7 @@
>   */
>  
>  #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>  #include <linux/console.h>
>  #include <linux/delay.h>
>  #include <linux/init.h>
> @@ -65,9 +66,7 @@
>  #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>  
>  /* AML_UART_REG5 bits */
> -#define AML_UART_BAUD_MASK		0x7fffff
>  #define AML_UART_BAUD_USE		BIT(23)
> -#define AML_UART_BAUD_XTAL		BIT(24)
>  
>  #define AML_UART_PORT_NUM		12
>  #define AML_UART_PORT_OFFSET		6
> @@ -76,6 +75,11 @@
>  #define AML_UART_POLL_USEC		5
>  #define AML_UART_TIMEOUT_USEC		10000
>  
> +struct meson_uart_data {
> +	struct clk	*baud_clk;
> +	bool		use_xtal_clk;
> +};
> +
>  static struct uart_driver meson_uart_driver;
>  
>  static struct uart_port *meson_ports[AML_UART_PORT_NUM];
> @@ -293,19 +297,17 @@ static int meson_uart_startup(struct uart_port *port)
>  
>  static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
>  {
> +	struct meson_uart_data *private_data = port->private_data;
>  	u32 val;
>  
>  	while (!meson_uart_tx_empty(port))
>  		cpu_relax();
>  
> -	if (port->uartclk == 24000000) {
> -		val = ((port->uartclk / 3) / baud) - 1;
> -		val |= AML_UART_BAUD_XTAL;
> -	} else {
> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
> -	}
> +	val = readl(port->membase + AML_UART_REG5);
>  	val |= AML_UART_BAUD_USE;
>  	writel(val, port->membase + AML_UART_REG5);
> +
> +	clk_set_rate(private_data->baud_clk, baud);
>  }
>  
>  static void meson_uart_set_termios(struct uart_port *port,
> @@ -395,11 +397,20 @@ static int meson_uart_verify_port(struct uart_port *port,
>  
>  static void meson_uart_release_port(struct uart_port *port)
>  {
> -	/* nothing to do */
> +	struct meson_uart_data *private_data = port->private_data;
> +
> +	clk_disable_unprepare(private_data->baud_clk);
>  }
>  
>  static int meson_uart_request_port(struct uart_port *port)
>  {
> +	struct meson_uart_data *private_data = port->private_data;
> +	int ret;
> +
> +	ret = clk_prepare_enable(private_data->baud_clk);
> +	if (ret)
> +		return ret;
> +
>  	return 0;
>  }
>  
> @@ -629,57 +640,105 @@ static struct uart_driver meson_uart_driver = {
>  	.cons		= MESON_SERIAL_CONSOLE,
>  };
>  
> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
> -						 const char *id)
> -{
> -	struct clk *clk = NULL;
> -	int ret;
> -
> -	clk = devm_clk_get(dev, id);
> -	if (IS_ERR(clk))
> -		return clk;
> -
> -	ret = clk_prepare_enable(clk);
> -	if (ret) {
> -		dev_err(dev, "couldn't enable clk\n");
> -		return ERR_PTR(ret);
> -	}
> -
> -	devm_add_action_or_reset(dev,
> -			(void(*)(void *))clk_disable_unprepare,
> -			clk);
> -
> -	return clk;
> -}
> +static struct clk_div_table xtal_div_table[] = {
> +	{0, 3},
> +	{1, 1},
> +	{2, 2},
> +	{3, 2},
> +};
>  
> -static int meson_uart_probe_clocks(struct platform_device *pdev,
> -				   struct uart_port *port)
> +static int meson_uart_probe_clocks(struct uart_port *port)
>  {
> -	struct clk *clk_xtal = NULL;
> -	struct clk *clk_pclk = NULL;
> -	struct clk *clk_baud = NULL;
> +	struct meson_uart_data *private_data = port->private_data;
> +	struct clk *clk_baud, *clk_xtal;
> +	struct clk_hw *hw;
> +	char clk_name[32];
> +	struct clk_parent_data use_xtal_mux_parents[2] = {
> +		{ .index = -1, },
> +		{ .index = -1, },
> +	};

You are using hw pointers later, you don't need to init the index to -1
I think

>  
> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
> -	if (IS_ERR(clk_pclk))
> -		return PTR_ERR(clk_pclk);
> +	clk_baud = devm_clk_get(port->dev, "baud");
> +	if (IS_ERR(clk_baud)) {
> +		dev_err(port->dev, "Failed to get the 'baud' clock\n");
> +		return PTR_ERR(clk_baud);
> +	}
>  
> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>  	if (IS_ERR(clk_xtal))
> -		return PTR_ERR(clk_xtal);
> -
> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
> -	if (IS_ERR(clk_baud))
> -		return PTR_ERR(clk_baud);
> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
> +				     "Failed to get the 'xtal' clock\n");
> +
> +	if (private_data->use_xtal_clk) {
> +		snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
> +			 "xtal_div");
> +		hw = devm_clk_hw_register_divider_table(port->dev,
> +							clk_name,
> +							__clk_get_name(clk_baud),
> +							CLK_SET_RATE_NO_REPARENT,
> +							port->membase + AML_UART_REG5,
> +							26, 2,
> +							CLK_DIVIDER_READ_ONLY,
> +							xtal_div_table, NULL);
> +		if (IS_ERR(hw))
> +			return PTR_ERR(hw);
> +
> +		use_xtal_mux_parents[1].hw = hw;
> +	} else {
> +		snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
> +			 "clk81_div4");
> +		hw = devm_clk_hw_register_fixed_factor(port->dev,
> +						       clk_name,
> +						       __clk_get_name(clk_baud),
> +						       CLK_SET_RATE_NO_REPARENT,
> +						       1, 4);
> +		if (IS_ERR(hw))
> +			return PTR_ERR(hw);
> +
> +		use_xtal_mux_parents[0].hw = hw;
> +	}

The above is still wrong.

use_xtal_mux_parents initialize both parent to nothing
And you init the parent in the conditional above.
It is means only one path is actually set instead of both.

The mux always has 2 sources - Both should be set regardless of the HW version
You just add
* /4 on path 0 on legacy SoC
* the funky divider on path 1 on newer SoC.

>  
> -	port->uartclk = clk_get_rate(clk_baud);
> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
> +		 "use_xtal");
> +	hw = __devm_clk_hw_register_mux(port->dev, NULL,
> +					clk_name,
> +					ARRAY_SIZE(use_xtal_mux_parents),
> +					NULL, NULL,
> +					use_xtal_mux_parents,
> +					CLK_SET_RATE_PARENT,
> +					port->membase + AML_UART_REG5,
> +					24, 0x1,
> +					CLK_MUX_READ_ONLY,
> +					NULL, NULL);
> +	if (IS_ERR(hw))
> +		return PTR_ERR(hw);
> +
> +	port->uartclk = clk_hw_get_rate(hw);
> +
> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
> +		 "baud_div");
> +	hw = devm_clk_hw_register_divider(port->dev,
> +					  clk_name,
> +					  clk_hw_get_name(hw),
> +					  CLK_SET_RATE_PARENT,
> +					  port->membase + AML_UART_REG5,
> +					  0, 23,
> +					  CLK_DIVIDER_ROUND_CLOSEST,
> +					  NULL);
> +	if (IS_ERR(hw))
> +		return PTR_ERR(hw);
> +
> +	private_data->baud_clk = hw->clk;
>  
>  	return 0;
>  }
>  
>  static int meson_uart_probe(struct platform_device *pdev)
>  {
> +	struct meson_uart_data *private_data;
>  	struct resource *res_mem;
>  	struct uart_port *port;
> +	struct clk *pclk;
>  	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
>  	int ret = 0;
>  	int irq;
> @@ -705,6 +764,15 @@ static int meson_uart_probe(struct platform_device *pdev)
>  	if (!res_mem)
>  		return -ENODEV;
>  
> +	pclk = devm_clk_get(&pdev->dev, "pclk");
> +	if (IS_ERR(pclk))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(pclk),
> +				     "Failed to get the 'pclk' clock\n");
> +
> +	ret = clk_prepare_enable(pclk);
> +	if (ret)
> +		return ret;
> +

I think this is unbalanced. 

>  	irq = platform_get_irq(pdev, 0);
>  	if (irq < 0)
>  		return irq;
> @@ -724,9 +792,13 @@ static int meson_uart_probe(struct platform_device *pdev)
>  	if (IS_ERR(port->membase))
>  		return PTR_ERR(port->membase);
>  
> -	ret = meson_uart_probe_clocks(pdev, port);
> -	if (ret)
> -		return ret;
> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
> +				    GFP_KERNEL);
> +	if (!private_data)
> +		return -ENOMEM;
> +
> +	if (device_get_match_data(&pdev->dev))
> +		private_data->use_xtal_clk = true;
>  
>  	port->iotype = UPIO_MEM;
>  	port->mapbase = res_mem->start;
> @@ -740,6 +812,11 @@ static int meson_uart_probe(struct platform_device *pdev)
>  	port->x_char = 0;
>  	port->ops = &meson_uart_ops;
>  	port->fifosize = fifosize;
> +	port->private_data = private_data;
> +
> +	ret = meson_uart_probe_clocks(port);
> +	if (ret)
> +		return ret;
>  
>  	meson_ports[pdev->id] = port;
>  	platform_set_drvdata(pdev, port);
> @@ -766,10 +843,22 @@ static int meson_uart_remove(struct platform_device *pdev)
>  }
>  
>  static const struct of_device_id meson_uart_dt_match[] = {
> -	{ .compatible = "amlogic,meson6-uart" },
> -	{ .compatible = "amlogic,meson8-uart" },
> -	{ .compatible = "amlogic,meson8b-uart" },
> -	{ .compatible = "amlogic,meson-gx-uart" },
> +	{
> +		.compatible = "amlogic,meson6-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson8-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson8b-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson-gx-uart",
> +		.data = (void *)true,
> +	},
>  	{ /* sentinel */ },
>  };
>  MODULE_DEVICE_TABLE(of, meson_uart_dt_match);



From jbrunet at baylibre.com  Thu Jan 20 13:48:05 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Thu, 20 Jan 2022 22:48:05 +0100
Subject: [PATCH V6 3/5] tty: serial: meson: Describes the calculation of
 the UART baud rate clock using a clock frame
In-Reply-To: <7a8016ba-730b-f599-2032-31cf03990a55@kernel.org>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <20220118030911.12815-4-yu.tu@amlogic.com>
 <7a8016ba-730b-f599-2032-31cf03990a55@kernel.org>
Message-ID: <1jbl062i4o.fsf@starbuckisacylon.baylibre.com>


On Tue 18 Jan 2022 at 10:39, Jiri Slaby <jirislaby at kernel.org> wrote:

> On 18. 01. 22, 4:09, Yu Tu wrote:
>> Using the common Clock code to describe the UART baud rate clock
>> makes it easier for the UART driver to be compatible with the
>> baud rate requirements of the UART IP on different meson chips.
> ...
>> --- a/drivers/tty/serial/meson_uart.c
>> +++ b/drivers/tty/serial/meson_uart.c
> ...
>> @@ -629,57 +640,105 @@ static struct uart_driver meson_uart_driver = {
>>   	.cons		= MESON_SERIAL_CONSOLE,
>>   };
>>   -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>> -						 const char *id)
>> -{
>> -	struct clk *clk = NULL;
>> -	int ret;
>> -
>> -	clk = devm_clk_get(dev, id);
>> -	if (IS_ERR(clk))
>> -		return clk;
>> -
>> -	ret = clk_prepare_enable(clk);
>> -	if (ret) {
>> -		dev_err(dev, "couldn't enable clk\n");
>> -		return ERR_PTR(ret);
>> -	}
>> -
>> -	devm_add_action_or_reset(dev,
>> -			(void(*)(void *))clk_disable_unprepare,
>> -			clk);
>> -
>> -	return clk;
>> -}
>> +static struct clk_div_table xtal_div_table[] = {
>
> This can be const, right?
>
>> +	{0, 3},
>> +	{1, 1},
>> +	{2, 2},
>> +	{3, 2},
>
> Not sure if you didn't remove too much whitespace. I think it should be
> like: "{ 0, 3 },". But I actually don't care, it's a minor thing.

Seconds
It worth fixing in the next version

>
> I cannot comment on the rest (clk and OF part) as my knowledge is pretty
> limited there. Leaving up to others.
>
> thanks,



From jbrunet at baylibre.com  Thu Jan 20 13:49:28 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Thu, 20 Jan 2022 22:49:28 +0100
Subject: [PATCH V6 4/5] tty: serial: meson: Make some bit of the REG5
 register writable
In-Reply-To: <20220118030911.12815-5-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <20220118030911.12815-5-yu.tu@amlogic.com>
Message-ID: <1j7dau2hxi.fsf@starbuckisacylon.baylibre.com>


On Tue 18 Jan 2022 at 11:09, Yu Tu <yu.tu at amlogic.com> wrote:

> The UART_REG5 register defaults to 0. The console port is set in
> ROMCODE. But other UART ports default to 0, so make bit24 and
> bit[26,27] writable so that the UART can choose a more
> appropriate clock.

Suggestion: Instead of talking bits (which is a bit cryptic) tell us
what is actually does

Something like:
 Make the internal clock source mux and divider writeable, allowing the
 uart to deviate from the settings intially applied by the ROMCode and
 using the most appropriate clocks

>
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>  drivers/tty/serial/meson_uart.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 92fa91c825e6..4e7b2b38ab0a 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -678,7 +678,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
>  							CLK_SET_RATE_NO_REPARENT,
>  							port->membase + AML_UART_REG5,
>  							26, 2,
> -							CLK_DIVIDER_READ_ONLY,
> +							CLK_DIVIDER_ROUND_CLOSEST,
>  							xtal_div_table, NULL);
>  		if (IS_ERR(hw))
>  			return PTR_ERR(hw);
> @@ -708,7 +708,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
>  					CLK_SET_RATE_PARENT,
>  					port->membase + AML_UART_REG5,
>  					24, 0x1,
> -					CLK_MUX_READ_ONLY,
> +					CLK_MUX_ROUND_CLOSEST,
>  					NULL, NULL);
>  	if (IS_ERR(hw))
>  		return PTR_ERR(hw);



From yu.tu at amlogic.com  Thu Jan 20 18:51:56 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Fri, 21 Jan 2022 10:51:56 +0800
Subject: [PATCH V6 3/5] tty: serial: meson: Describes the calculation of
 the UART baud rate clock using a clock frame
In-Reply-To: <1jfspi2i5s.fsf@starbuckisacylon.baylibre.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <20220118030911.12815-4-yu.tu@amlogic.com>
 <1jfspi2i5s.fsf@starbuckisacylon.baylibre.com>
Message-ID: <9d8ff96b-8a1d-6778-cb71-1e5855303f8a@amlogic.com>

Hi Jerome ,
	Thank you very much for your reply.
	At present, it is found that after using CCF to describe baud rate 
clock, when using stty to change baud rate, the situation will be stuck. 
  If initcall_debug is enabled, the initialization of the UART driver 
takes longer . Shall we discuss this first and change it as you suggest? 
I have replied to Kevin about this question yesterday.
Do you need to discuss it? What should I do next?

On 2022/1/21 5:40, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> 
> On Tue 18 Jan 2022 at 11:09, Yu Tu <yu.tu at amlogic.com> wrote:
> 
>> Using the common Clock code to describe the UART baud rate clock
>> makes it easier for the UART driver to be compatible with the
>> baud rate requirements of the UART IP on different meson chips.
>>
>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>> ---
>>   drivers/tty/serial/meson_uart.c | 195 +++++++++++++++++++++++---------
>>   1 file changed, 142 insertions(+), 53 deletions(-)
>>
>> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
>> index 7570958d010c..92fa91c825e6 100644
>> --- a/drivers/tty/serial/meson_uart.c
>> +++ b/drivers/tty/serial/meson_uart.c
>> @@ -6,6 +6,7 @@
>>    */
>>   
>>   #include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>>   #include <linux/console.h>
>>   #include <linux/delay.h>
>>   #include <linux/init.h>
>> @@ -65,9 +66,7 @@
>>   #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>>   
>>   /* AML_UART_REG5 bits */
>> -#define AML_UART_BAUD_MASK		0x7fffff
>>   #define AML_UART_BAUD_USE		BIT(23)
>> -#define AML_UART_BAUD_XTAL		BIT(24)
>>   
>>   #define AML_UART_PORT_NUM		12
>>   #define AML_UART_PORT_OFFSET		6
>> @@ -76,6 +75,11 @@
>>   #define AML_UART_POLL_USEC		5
>>   #define AML_UART_TIMEOUT_USEC		10000
>>   
>> +struct meson_uart_data {
>> +	struct clk	*baud_clk;
>> +	bool		use_xtal_clk;
>> +};
>> +
>>   static struct uart_driver meson_uart_driver;
>>   
>>   static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>> @@ -293,19 +297,17 @@ static int meson_uart_startup(struct uart_port *port)
>>   
>>   static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
>>   {
>> +	struct meson_uart_data *private_data = port->private_data;
>>   	u32 val;
>>   
>>   	while (!meson_uart_tx_empty(port))
>>   		cpu_relax();
>>   
>> -	if (port->uartclk == 24000000) {
>> -		val = ((port->uartclk / 3) / baud) - 1;
>> -		val |= AML_UART_BAUD_XTAL;
>> -	} else {
>> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>> -	}
>> +	val = readl(port->membase + AML_UART_REG5);
>>   	val |= AML_UART_BAUD_USE;
>>   	writel(val, port->membase + AML_UART_REG5);
>> +
>> +	clk_set_rate(private_data->baud_clk, baud);
>>   }
>>   
>>   static void meson_uart_set_termios(struct uart_port *port,
>> @@ -395,11 +397,20 @@ static int meson_uart_verify_port(struct uart_port *port,
>>   
>>   static void meson_uart_release_port(struct uart_port *port)
>>   {
>> -	/* nothing to do */
>> +	struct meson_uart_data *private_data = port->private_data;
>> +
>> +	clk_disable_unprepare(private_data->baud_clk);
>>   }
>>   
>>   static int meson_uart_request_port(struct uart_port *port)
>>   {
>> +	struct meson_uart_data *private_data = port->private_data;
>> +	int ret;
>> +
>> +	ret = clk_prepare_enable(private_data->baud_clk);
>> +	if (ret)
>> +		return ret;
>> +
>>   	return 0;
>>   }
>>   
>> @@ -629,57 +640,105 @@ static struct uart_driver meson_uart_driver = {
>>   	.cons		= MESON_SERIAL_CONSOLE,
>>   };
>>   
>> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>> -						 const char *id)
>> -{
>> -	struct clk *clk = NULL;
>> -	int ret;
>> -
>> -	clk = devm_clk_get(dev, id);
>> -	if (IS_ERR(clk))
>> -		return clk;
>> -
>> -	ret = clk_prepare_enable(clk);
>> -	if (ret) {
>> -		dev_err(dev, "couldn't enable clk\n");
>> -		return ERR_PTR(ret);
>> -	}
>> -
>> -	devm_add_action_or_reset(dev,
>> -			(void(*)(void *))clk_disable_unprepare,
>> -			clk);
>> -
>> -	return clk;
>> -}
>> +static struct clk_div_table xtal_div_table[] = {
>> +	{0, 3},
>> +	{1, 1},
>> +	{2, 2},
>> +	{3, 2},
>> +};
>>   
>> -static int meson_uart_probe_clocks(struct platform_device *pdev,
>> -				   struct uart_port *port)
>> +static int meson_uart_probe_clocks(struct uart_port *port)
>>   {
>> -	struct clk *clk_xtal = NULL;
>> -	struct clk *clk_pclk = NULL;
>> -	struct clk *clk_baud = NULL;
>> +	struct meson_uart_data *private_data = port->private_data;
>> +	struct clk *clk_baud, *clk_xtal;
>> +	struct clk_hw *hw;
>> +	char clk_name[32];
>> +	struct clk_parent_data use_xtal_mux_parents[2] = {
>> +		{ .index = -1, },
>> +		{ .index = -1, },
>> +	};
> 
> You are using hw pointers later, you don't need to init the index to -1
> I think
> 
>>   
>> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>> -	if (IS_ERR(clk_pclk))
>> -		return PTR_ERR(clk_pclk);
>> +	clk_baud = devm_clk_get(port->dev, "baud");
>> +	if (IS_ERR(clk_baud)) {
>> +		dev_err(port->dev, "Failed to get the 'baud' clock\n");
>> +		return PTR_ERR(clk_baud);
>> +	}
>>   
>> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>>   	if (IS_ERR(clk_xtal))
>> -		return PTR_ERR(clk_xtal);
>> -
>> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>> -	if (IS_ERR(clk_baud))
>> -		return PTR_ERR(clk_baud);
>> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>> +				     "Failed to get the 'xtal' clock\n");
>> +
>> +	if (private_data->use_xtal_clk) {
>> +		snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
>> +			 "xtal_div");
>> +		hw = devm_clk_hw_register_divider_table(port->dev,
>> +							clk_name,
>> +							__clk_get_name(clk_baud),
>> +							CLK_SET_RATE_NO_REPARENT,
>> +							port->membase + AML_UART_REG5,
>> +							26, 2,
>> +							CLK_DIVIDER_READ_ONLY,
>> +							xtal_div_table, NULL);
>> +		if (IS_ERR(hw))
>> +			return PTR_ERR(hw);
>> +
>> +		use_xtal_mux_parents[1].hw = hw;
>> +	} else {
>> +		snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
>> +			 "clk81_div4");
>> +		hw = devm_clk_hw_register_fixed_factor(port->dev,
>> +						       clk_name,
>> +						       __clk_get_name(clk_baud),
>> +						       CLK_SET_RATE_NO_REPARENT,
>> +						       1, 4);
>> +		if (IS_ERR(hw))
>> +			return PTR_ERR(hw);
>> +
>> +		use_xtal_mux_parents[0].hw = hw;
>> +	}
> 
> The above is still wrong.
> 
> use_xtal_mux_parents initialize both parent to nothing
> And you init the parent in the conditional above.
> It is means only one path is actually set instead of both.
> 
> The mux always has 2 sources - Both should be set regardless of the HW version
> You just add
> * /4 on path 0 on legacy SoC
> * the funky divider on path 1 on newer SoC.
> 
>>   
>> -	port->uartclk = clk_get_rate(clk_baud);
>> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
>> +		 "use_xtal");
>> +	hw = __devm_clk_hw_register_mux(port->dev, NULL,
>> +					clk_name,
>> +					ARRAY_SIZE(use_xtal_mux_parents),
>> +					NULL, NULL,
>> +					use_xtal_mux_parents,
>> +					CLK_SET_RATE_PARENT,
>> +					port->membase + AML_UART_REG5,
>> +					24, 0x1,
>> +					CLK_MUX_READ_ONLY,
>> +					NULL, NULL);
>> +	if (IS_ERR(hw))
>> +		return PTR_ERR(hw);
>> +
>> +	port->uartclk = clk_hw_get_rate(hw);
>> +
>> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
>> +		 "baud_div");
>> +	hw = devm_clk_hw_register_divider(port->dev,
>> +					  clk_name,
>> +					  clk_hw_get_name(hw),
>> +					  CLK_SET_RATE_PARENT,
>> +					  port->membase + AML_UART_REG5,
>> +					  0, 23,
>> +					  CLK_DIVIDER_ROUND_CLOSEST,
>> +					  NULL);
>> +	if (IS_ERR(hw))
>> +		return PTR_ERR(hw);
>> +
>> +	private_data->baud_clk = hw->clk;
>>   
>>   	return 0;
>>   }
>>   
>>   static int meson_uart_probe(struct platform_device *pdev)
>>   {
>> +	struct meson_uart_data *private_data;
>>   	struct resource *res_mem;
>>   	struct uart_port *port;
>> +	struct clk *pclk;
>>   	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
>>   	int ret = 0;
>>   	int irq;
>> @@ -705,6 +764,15 @@ static int meson_uart_probe(struct platform_device *pdev)
>>   	if (!res_mem)
>>   		return -ENODEV;
>>   
>> +	pclk = devm_clk_get(&pdev->dev, "pclk");
>> +	if (IS_ERR(pclk))
>> +		return dev_err_probe(&pdev->dev, PTR_ERR(pclk),
>> +				     "Failed to get the 'pclk' clock\n");
>> +
>> +	ret = clk_prepare_enable(pclk);
>> +	if (ret)
>> +		return ret;
>> +
> 
> I think this is unbalanced.
> 
>>   	irq = platform_get_irq(pdev, 0);
>>   	if (irq < 0)
>>   		return irq;
>> @@ -724,9 +792,13 @@ static int meson_uart_probe(struct platform_device *pdev)
>>   	if (IS_ERR(port->membase))
>>   		return PTR_ERR(port->membase);
>>   
>> -	ret = meson_uart_probe_clocks(pdev, port);
>> -	if (ret)
>> -		return ret;
>> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
>> +				    GFP_KERNEL);
>> +	if (!private_data)
>> +		return -ENOMEM;
>> +
>> +	if (device_get_match_data(&pdev->dev))
>> +		private_data->use_xtal_clk = true;
>>   
>>   	port->iotype = UPIO_MEM;
>>   	port->mapbase = res_mem->start;
>> @@ -740,6 +812,11 @@ static int meson_uart_probe(struct platform_device *pdev)
>>   	port->x_char = 0;
>>   	port->ops = &meson_uart_ops;
>>   	port->fifosize = fifosize;
>> +	port->private_data = private_data;
>> +
>> +	ret = meson_uart_probe_clocks(port);
>> +	if (ret)
>> +		return ret;
>>   
>>   	meson_ports[pdev->id] = port;
>>   	platform_set_drvdata(pdev, port);
>> @@ -766,10 +843,22 @@ static int meson_uart_remove(struct platform_device *pdev)
>>   }
>>   
>>   static const struct of_device_id meson_uart_dt_match[] = {
>> -	{ .compatible = "amlogic,meson6-uart" },
>> -	{ .compatible = "amlogic,meson8-uart" },
>> -	{ .compatible = "amlogic,meson8b-uart" },
>> -	{ .compatible = "amlogic,meson-gx-uart" },
>> +	{
>> +		.compatible = "amlogic,meson6-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson8-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson8b-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-gx-uart",
>> +		.data = (void *)true,
>> +	},
>>   	{ /* sentinel */ },
>>   };
>>   MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
> 


From liang.yang at amlogic.com  Thu Jan 20 23:45:04 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 21 Jan 2022 15:45:04 +0800
Subject: [PATCH v10 0/4] clk: meson: add a sub EMMC clock controller support
Message-ID: <20220121074508.42168-1-liang.yang@amlogic.com>

This driver will add a MMC clock controller driver support.
The original idea about adding a clock controller is during the
discussion in the NAND driver mainline effort[1].

This driver is tested in the S400 board (AXG platform) with NAND driver.

Changes since v9 [10]
 - use clk_parent_data instead of parent_names

Changes since v8 [9]
 - use MESON_SCLK_ONE_BASED instead of CLK_DIVIDER_ONE_BASED
 - use struct_size to caculate onecell_data
 - add clk-phase-delay.h
 - define CLK_DELAY_STEP_PS_GX and CLK_DELAY_STEP_PS_AXG

Changes since v7 [8]
 - move meson_clk_get_phase_delay_data() from header to driver
 - CONFIG sclk-div with COMMON_CLK_AMLOGIC instead of COMMON_CLK_AMLOGIC_AUDIO
 - remove onecell date and ID for internal MUX clk
 - use helper for functions for ONE_BASED in sclk-div
 - add ONE_BASED support for duty cycle

Changes since v6 [7]:
 - add one based support for sclk divier
 - alloc sclk in probe for multiple instance
 - fix coding styles

Changes since v5 [6]:
 - remove divider ops with .init and use sclk_div instead
 - drop CLK_DIVIDER_ROUND_CLOSEST in mux and div
 - drop the useless type cast 

Changes since v4 [5]:
 - use struct parm in phase delay driver
 - remove 0 delay releted part in phase delay driver
 - don't rebuild the parent name once again
 - add divider ops with .init

Changes since v3 [4]:
 - separate clk-phase-delay driver
 - replace clk_get_rate() with clk_hw_get_rate()
 - collect Rob's R-Y
 - drop 'meson-' prefix from compatible string

 Changes since v2 [3]:
 - squash dt-binding clock-id patch
 - update license
 - fix alignment
 - construct a clk register helper() function

Changes since v1 [2]:
 - implement phase clock
 - update compatible name
 - adjust file name
 - divider probe() into small functions, and re-use them

[1] https://lkml.kernel.org/r/20180628090034.0637a062 at xps13
[2] https://lkml.kernel.org/r/20180703145716.31860-1-yixun.lan at amlogic.com
[3] https://lkml.kernel.org/r/20180710163658.6175-1-yixun.lan at amlogic.com
[4] https://lkml.kernel.org/r/20180712211244.11428-1-yixun.lan at amlogic.com
[5] https://lkml.kernel.org/r/20180809070724.11935-4-yixun.lan at amlogic.com
[6] https://lkml.kernel.org/r/1539839245-13793-1-git-send-email-jianxin.pan at amlogic.com
[7] https://lkml.kernel.org/r/1541089855-19356-1-git-send-email-jianxin.pan at amlogic.com
[8] https://lkml.kernel.org/r/1544457877-51301-1-git-send-email-jianxin.pan at amlogic.com
[9] https://lkml.kernel.org/r/1545063850-21504-1-git-send-email-jianxin.pan at amlogic.com
[10] https://lore.kernel.org/all/20220113115745.45826-1-liang.yang at amlogic.com/
Liang Yang (4):
  clk: meson: add one based divider support for sclk
  clk: meson: add emmc sub clock phase delay driver
  clk: meson: add DT documentation for emmc clock controller
  clk: meson: add sub MMC clock controller driver

 .../bindings/clock/amlogic,mmc-clkc.yaml      |  64 ++++
 drivers/clk/meson/Kconfig                     |  18 ++
 drivers/clk/meson/Makefile                    |   2 +
 drivers/clk/meson/clk-phase-delay.c           |  69 ++++
 drivers/clk/meson/clk-phase-delay.h           |  20 ++
 drivers/clk/meson/mmc-clkc.c                  | 302 ++++++++++++++++++
 drivers/clk/meson/sclk-div.c                  |  59 ++--
 drivers/clk/meson/sclk-div.h                  |   3 +
 include/dt-bindings/clock/amlogic,mmc-clkc.h  |  14 +
 9 files changed, 529 insertions(+), 22 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
 create mode 100644 drivers/clk/meson/clk-phase-delay.c
 create mode 100644 drivers/clk/meson/clk-phase-delay.h
 create mode 100644 drivers/clk/meson/mmc-clkc.c
 create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h

-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan 20 23:45:05 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 21 Jan 2022 15:45:05 +0800
Subject: [PATCH v10 1/4] clk: meson: add one based divider support for sclk
In-Reply-To: <20220121074508.42168-1-liang.yang@amlogic.com>
References: <20220121074508.42168-1-liang.yang@amlogic.com>
Message-ID: <20220121074508.42168-2-liang.yang@amlogic.com>

When MESON_SCLK_ONE_BASED flag is set, the sclk divider will be:
one based divider (div = val), and zero value gates the clock

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 drivers/clk/meson/sclk-div.c | 59 ++++++++++++++++++++++--------------
 drivers/clk/meson/sclk-div.h |  3 ++
 2 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/drivers/clk/meson/sclk-div.c b/drivers/clk/meson/sclk-div.c
index 76d31c0a3342..4ddc1763a12d 100644
--- a/drivers/clk/meson/sclk-div.c
+++ b/drivers/clk/meson/sclk-div.c
@@ -4,16 +4,17 @@
  * Author: Jerome Brunet <jbrunet at baylibre.com>
  *
  * Sample clock generator divider:
- * This HW divider gates with value 0 but is otherwise a zero based divider:
+ * This HW divider gates with value 0:
  *
  * val >= 1
- * divider = val + 1
+ * divider = val + 1 if ONE_BASED is not set, otherwise divider = val.
  *
  * The duty cycle may also be set for the LR clock variant. The duty cycle
  * ratio is:
  *
  * hi = [0 - val]
- * duty_cycle = (1 + hi) / (1 + val)
+ * duty_cycle = (1 + hi) / (1 + val) if ONE_BASED is not set, otherwise:
+ * duty_cycle = hi / (1 + val)
  */
 
 #include <linux/clk-provider.h>
@@ -28,22 +29,37 @@ meson_sclk_div_data(struct clk_regmap *clk)
 	return (struct meson_sclk_div_data *)clk->data;
 }
 
-static int sclk_div_maxval(struct meson_sclk_div_data *sclk)
+static inline int sclk_get_reg(int val, unsigned char flag)
 {
-	return (1 << sclk->div.width) - 1;
+	if ((flag & MESON_SCLK_ONE_BASED) || !val)
+		return val;
+	return val - 1;
+}
+
+static inline int sclk_get_divider(int reg, unsigned char flag)
+{
+	if (flag & MESON_SCLK_ONE_BASED)
+		return reg;
+	return reg + 1;
 }
 
 static int sclk_div_maxdiv(struct meson_sclk_div_data *sclk)
 {
-	return sclk_div_maxval(sclk) + 1;
+	unsigned int reg = (1 << sclk->div.width) - 1;
+
+	return sclk_get_divider(reg, sclk->flags);
 }
 
 static int sclk_div_getdiv(struct clk_hw *hw, unsigned long rate,
-			   unsigned long prate, int maxdiv)
+			   unsigned long prate)
 {
 	int div = DIV_ROUND_CLOSEST_ULL((u64)prate, rate);
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk);
+	int mindiv = sclk_get_divider(1, sclk->flags);
+	int maxdiv = sclk_div_maxdiv(sclk);
 
-	return clamp(div, 2, maxdiv);
+	return clamp(div, mindiv, maxdiv);
 }
 
 static int sclk_div_bestdiv(struct clk_hw *hw, unsigned long rate,
@@ -51,25 +67,25 @@ static int sclk_div_bestdiv(struct clk_hw *hw, unsigned long rate,
 			    struct meson_sclk_div_data *sclk)
 {
 	struct clk_hw *parent = clk_hw_get_parent(hw);
-	int bestdiv = 0, i;
+	int bestdiv = 0, i, mindiv;
 	unsigned long maxdiv, now, parent_now;
 	unsigned long best = 0, best_parent = 0;
 
 	if (!rate)
 		rate = 1;
 
-	maxdiv = sclk_div_maxdiv(sclk);
-
 	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT))
-		return sclk_div_getdiv(hw, rate, *prate, maxdiv);
+		return sclk_div_getdiv(hw, rate, *prate);
 
 	/*
 	 * The maximum divider we can use without overflowing
 	 * unsigned long in rate * i below
 	 */
+	maxdiv = sclk_div_maxdiv(sclk);
 	maxdiv = min(ULONG_MAX / rate, maxdiv);
+	mindiv = sclk_get_divider(1, sclk->flags);
 
-	for (i = 2; i <= maxdiv; i++) {
+	for (i = mindiv; i <= maxdiv; i++) {
 		/*
 		 * It's the most ideal case if the requested rate can be
 		 * divided from parent clock without needing to change
@@ -115,10 +131,7 @@ static void sclk_apply_ratio(struct clk_regmap *clk,
 					    sclk->cached_duty.num,
 					    sclk->cached_duty.den);
 
-	if (hi)
-		hi -= 1;
-
-	meson_parm_write(clk->map, &sclk->hi, hi);
+	meson_parm_write(clk->map, &sclk->hi, sclk_get_reg(hi, sclk->flags));
 }
 
 static int sclk_div_set_duty_cycle(struct clk_hw *hw,
@@ -149,7 +162,7 @@ static int sclk_div_get_duty_cycle(struct clk_hw *hw,
 	}
 
 	hi = meson_parm_read(clk->map, &sclk->hi);
-	duty->num = hi + 1;
+	duty->num = sclk_get_divider(hi, sclk->flags);
 	duty->den = sclk->cached_div;
 	return 0;
 }
@@ -157,10 +170,13 @@ static int sclk_div_get_duty_cycle(struct clk_hw *hw,
 static void sclk_apply_divider(struct clk_regmap *clk,
 			       struct meson_sclk_div_data *sclk)
 {
+	unsigned int div;
+
 	if (MESON_PARM_APPLICABLE(&sclk->hi))
 		sclk_apply_ratio(clk, sclk);
 
-	meson_parm_write(clk->map, &sclk->div, sclk->cached_div - 1);
+	div = sclk_get_reg(sclk->cached_div, sclk->flags);
+	meson_parm_write(clk->map, &sclk->div, div);
 }
 
 static int sclk_div_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -168,9 +184,8 @@ static int sclk_div_set_rate(struct clk_hw *hw, unsigned long rate,
 {
 	struct clk_regmap *clk = to_clk_regmap(hw);
 	struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk);
-	unsigned long maxdiv = sclk_div_maxdiv(sclk);
 
-	sclk->cached_div = sclk_div_getdiv(hw, rate, prate, maxdiv);
+	sclk->cached_div = sclk_div_getdiv(hw, rate, prate);
 
 	if (clk_hw_is_enabled(hw))
 		sclk_apply_divider(clk, sclk);
@@ -228,7 +243,7 @@ static int sclk_div_init(struct clk_hw *hw)
 	if (!val)
 		sclk->cached_div = sclk_div_maxdiv(sclk);
 	else
-		sclk->cached_div = val + 1;
+		sclk->cached_div = sclk_get_divider(val, sclk->flags);
 
 	sclk_div_get_duty_cycle(hw, &sclk->cached_duty);
 
diff --git a/drivers/clk/meson/sclk-div.h b/drivers/clk/meson/sclk-div.h
index b64b2a32005f..944dab5ec0cf 100644
--- a/drivers/clk/meson/sclk-div.h
+++ b/drivers/clk/meson/sclk-div.h
@@ -10,11 +10,14 @@
 #include <linux/clk-provider.h>
 #include "parm.h"
 
+#define MESON_SCLK_ONE_BASED	BIT(0)
+
 struct meson_sclk_div_data {
 	struct parm div;
 	struct parm hi;
 	unsigned int cached_div;
 	struct clk_duty cached_duty;
+	u8 flags;
 };
 
 extern const struct clk_ops meson_sclk_div_ops;
-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan 20 23:45:06 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 21 Jan 2022 15:45:06 +0800
Subject: [PATCH v10 2/4] clk: meson: add emmc sub clock phase delay driver
In-Reply-To: <20220121074508.42168-1-liang.yang@amlogic.com>
References: <20220121074508.42168-1-liang.yang@amlogic.com>
Message-ID: <20220121074508.42168-3-liang.yang@amlogic.com>

Export the emmc sub clock phase delay ops which will be used
by the emmc sub clock driver itself.

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 drivers/clk/meson/Kconfig           |  4 ++
 drivers/clk/meson/Makefile          |  1 +
 drivers/clk/meson/clk-phase-delay.c | 69 +++++++++++++++++++++++++++++
 drivers/clk/meson/clk-phase-delay.h | 20 +++++++++
 4 files changed, 94 insertions(+)
 create mode 100644 drivers/clk/meson/clk-phase-delay.c
 create mode 100644 drivers/clk/meson/clk-phase-delay.h

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 3014e2f1fbb4..bb0f59eea366 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -18,6 +18,10 @@ config COMMON_CLK_MESON_PHASE
 	tristate
 	select COMMON_CLK_MESON_REGMAP
 
+config COMMON_CLK_MESON_PHASE_DELAY
+	tristate
+	select COMMON_CLK_MESON_REGMAP
+
 config COMMON_CLK_MESON_PLL
 	tristate
 	select COMMON_CLK_MESON_REGMAP
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index b3ef5f67820f..99fe4eeed000 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_MPLL) += clk-mpll.o
 obj-$(CONFIG_COMMON_CLK_MESON_PHASE) += clk-phase.o
 obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o
 obj-$(CONFIG_COMMON_CLK_MESON_REGMAP) += clk-regmap.o
+obj-$(CONFIG_COMMON_CLK_MESON_PHASE_DELAY) += clk-phase-delay.o
 obj-$(CONFIG_COMMON_CLK_MESON_SCLK_DIV) += sclk-div.o
 obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
 
diff --git a/drivers/clk/meson/clk-phase-delay.c b/drivers/clk/meson/clk-phase-delay.c
new file mode 100644
index 000000000000..3c1ae0ee2a24
--- /dev/null
+++ b/drivers/clk/meson/clk-phase-delay.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+
+#include "clk-regmap.h"
+#include "clk-phase-delay.h"
+
+static inline struct meson_clk_phase_delay_data *
+meson_clk_get_phase_delay_data(struct clk_regmap *clk)
+{
+	return clk->data;
+}
+
+static int meson_clk_phase_delay_get_phase(struct clk_hw *hw)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_clk_phase_delay_data *ph;
+	unsigned long period_ps, p, d;
+	int degrees;
+
+	ph = meson_clk_get_phase_delay_data(clk);
+	p = meson_parm_read(clk->map, &ph->phase);
+	degrees = p * 360 / (1 << (ph->phase.width));
+
+	period_ps = DIV_ROUND_UP_ULL(NSEC_PER_SEC * 1000ull,
+				     clk_hw_get_rate(hw));
+
+	d = meson_parm_read(clk->map, &ph->delay);
+	degrees += d * ph->delay_step_ps * 360 / period_ps;
+	degrees %= 360;
+
+	return degrees;
+}
+
+static int meson_clk_phase_delay_set_phase(struct clk_hw *hw, int degrees)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_clk_phase_delay_data *ph;
+	unsigned long period_ps, d = 0;
+	unsigned int p;
+
+	ph = meson_clk_get_phase_delay_data(clk);
+	period_ps = DIV_ROUND_UP_ULL(NSEC_PER_SEC * 1000ull,
+				     clk_hw_get_rate(hw));
+
+	/*
+	 * First compute the phase index (p), the remainder (r) is the
+	 * part we'll try to acheive using the delays (d).
+	 */
+	p = 360 / 1 << (ph->phase.width);
+	degrees = degrees / p;
+	d = DIV_ROUND_CLOSEST((degrees % p) * period_ps,
+			      360 * ph->delay_step_ps);
+	d = min(d, PMASK(ph->delay.width));
+
+	meson_parm_write(clk->map, &ph->phase, degrees);
+	meson_parm_write(clk->map, &ph->delay, d);
+	return 0;
+}
+
+const struct clk_ops meson_clk_phase_delay_ops = {
+	.get_phase = meson_clk_phase_delay_get_phase,
+	.set_phase = meson_clk_phase_delay_set_phase,
+};
+EXPORT_SYMBOL_GPL(meson_clk_phase_delay_ops);
diff --git a/drivers/clk/meson/clk-phase-delay.h b/drivers/clk/meson/clk-phase-delay.h
new file mode 100644
index 000000000000..b4f211d02c84
--- /dev/null
+++ b/drivers/clk/meson/clk-phase-delay.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __MESON_CLK_PHASE_DELAY_H
+#define __MESON_CLK_PHASE_DELAY_H
+
+#include <linux/clk-provider.h>
+#include "parm.h"
+
+struct meson_clk_phase_delay_data {
+	struct parm     phase;
+	struct parm     delay;
+	unsigned int    delay_step_ps;
+};
+
+extern const struct clk_ops meson_clk_phase_delay_ops;
+
+#endif /* __MESON_CLK_PHASE_DELAY_H */
-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan 20 23:45:07 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 21 Jan 2022 15:45:07 +0800
Subject: [PATCH v10 3/4] clk: meson: add DT documentation for emmc clock
 controller
In-Reply-To: <20220121074508.42168-1-liang.yang@amlogic.com>
References: <20220121074508.42168-1-liang.yang@amlogic.com>
Message-ID: <20220121074508.42168-4-liang.yang@amlogic.com>

Document the MMC sub clock controller driver, the potential consumer
of this driver is MMC or NAND. Also add four clock bindings IDs which
provided by this driver.

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 .../bindings/clock/amlogic,mmc-clkc.yaml      | 64 +++++++++++++++++++
 include/dt-bindings/clock/amlogic,mmc-clkc.h  | 14 ++++
 2 files changed, 78 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
 create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h

diff --git a/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
new file mode 100644
index 000000000000..0fe2e33c2082
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,mmc-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic MMC Sub Clock Controller Driver Device Tree Bindings
+
+maintainers:
+  - jianxin.pan at amlogic.com
+  - liang.yang at amlogic.com
+
+properties:
+  compatible:
+    enum:
+      - "amlogic,axg-mmc-clkc", "syscon"
+      - "amlogic,gx-mmc-clkc", "syscon"
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: "clkin0", "clkin1"
+
+  "#clock-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    sd_mmc_c_clkc: clock-controller at 7000 {
+	compatible = "amlogic,axg-mmc-clkc", "syscon";
+	reg = <0x0 0x7000 0x0 0x4>;
+	#clock-cells = <1>;
+
+	clock-names = "clkin0", "clkin1";
+	clocks = <&clkc CLKID_SD_EMMC_C_CLK0>,
+		 <&clkc CLKID_FCLK_DIV2>;
+     };
+
+  - |
+    sd_emmc_b_clkc: clock-controller at 5000 {
+	compatible = "amlogic,axg-mmc-clkc", "syscon";
+	reg = <0x0 0x5000 0x0 0x4>;
+
+	#clock-cells = <1>;
+	clock-names = "clkin0", "clkin1";
+	clocks = <&clkc CLKID_SD_EMMC_B_CLK0>,
+		 <&clkc CLKID_FCLK_DIV2>;
+    };
+
+...
\ No newline at end of file
diff --git a/include/dt-bindings/clock/amlogic,mmc-clkc.h b/include/dt-bindings/clock/amlogic,mmc-clkc.h
new file mode 100644
index 000000000000..71301517b183
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,mmc-clkc.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __MMC_CLKC_H
+#define __MMC_CLKC_H
+
+#define CLKID_MMC_DIV		0
+#define CLKID_MMC_PHASE_CORE	1
+#define CLKID_MMC_PHASE_TX	2
+#define CLKID_MMC_PHASE_RX	3
+
+#endif
-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan 20 23:45:08 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 21 Jan 2022 15:45:08 +0800
Subject: [PATCH v10 4/4] clk: meson: add sub MMC clock controller driver
In-Reply-To: <20220121074508.42168-1-liang.yang@amlogic.com>
References: <20220121074508.42168-1-liang.yang@amlogic.com>
Message-ID: <20220121074508.42168-5-liang.yang@amlogic.com>

The patch will add a MMC clock controller driver which used by MMC or NAND,
It provide a mux and divider clock, and three phase clocks - core, tx, tx.

Two clocks are provided as the parent of MMC clock controller from
upper layer clock controller - eg "amlogic,axg-clkc" in AXG platform.

To specify which clock the MMC or NAND driver may consume,
the preprocessor macros in the dt-bindings/clock/amlogic,mmc-clkc.h header
can be used in the device tree sources.

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 drivers/clk/meson/Kconfig    |  14 ++
 drivers/clk/meson/Makefile   |   1 +
 drivers/clk/meson/mmc-clkc.c | 302 +++++++++++++++++++++++++++++++++++
 3 files changed, 317 insertions(+)
 create mode 100644 drivers/clk/meson/mmc-clkc.c

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index bb0f59eea366..5f344a0892cb 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -39,6 +39,20 @@ config COMMON_CLK_MESON_AO_CLKC
 	select COMMON_CLK_MESON_REGMAP
 	select RESET_CONTROLLER
 
+config COMMON_CLK_MMC_MESON
+	tristate "Meson MMC Sub Clock Controller Driver"
+	depends on ARCH_MESON || COMPILE_TEST
+	select MFD_SYSCON
+	select COMMON_CLK_AMLOGIC
+	select COMMON_CLK_MESON_PHASE
+	select COMMON_CLK_MESON_PHASE_DELAY
+	select COMMON_CLK_MESON_SCLK_DIV
+	help
+	  Support for the MMC sub clock controller on
+	  Amlogic Meson Platform, which includes S905 (GXBB, GXL),
+	  A113D/X (AXG) devices. Say Y if you want this
+	  clock enabled.
+
 config COMMON_CLK_MESON_EE_CLKC
 	tristate
 	select COMMON_CLK_MESON_REGMAP
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 99fe4eeed000..7a7ffb37a726 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
 
 obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
 obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
+obj-$(CONFIG_COMMON_CLK_MMC_MESON) += mmc-clkc.o
 obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
 obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
 obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c
new file mode 100644
index 000000000000..e42c4015c7a3
--- /dev/null
+++ b/drivers/clk/meson/mmc-clkc.c
@@ -0,0 +1,302 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/of_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/amlogic,mmc-clkc.h>
+
+#include "sclk-div.h"
+#include "clk-phase-delay.h"
+#include "clk-regmap.h"
+#include "clk-phase.h"
+
+/* clock ID used by internal driver */
+
+#define SD_EMMC_CLOCK		0
+#define CLK_DELAY_STEP_PS_GX	200
+#define CLK_DELAY_STEP_PS_AXG	78
+#define MUX_CLK_NUM_PARENTS	2
+#define MMC_MAX_CLKS		4
+
+static struct clk_parent_data mmc_clkc_parent_data[MUX_CLK_NUM_PARENTS];
+
+struct mmc_clkc_data {
+	struct meson_clk_phase_delay_data tx;
+	struct meson_clk_phase_delay_data rx;
+};
+
+static struct clk_regmap_mux_data mmc_clkc_mux_data = {
+	.offset = SD_EMMC_CLOCK,
+	.mask   = 0x3,
+	.shift  = 6,
+};
+
+static const struct meson_sclk_div_data mmc_clkc_div_data = {
+	.div = {
+		.reg_off = SD_EMMC_CLOCK,
+		.width   = 6,
+	},
+	.flags = MESON_SCLK_ONE_BASED,
+};
+
+static struct meson_clk_phase_data mmc_clkc_core_phase = {
+	.ph = {
+		.reg_off = SD_EMMC_CLOCK,
+		.shift   = 8,
+		.width   = 2,
+	}
+};
+
+static const struct mmc_clkc_data mmc_clkc_gx_data = {
+	.tx = {
+		.phase = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 10,
+			.width   = 2,
+		},
+		.delay = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 16,
+			.width   = 4,
+		},
+		.delay_step_ps = CLK_DELAY_STEP_PS_GX,
+	},
+	.rx = {
+		.phase = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 12,
+			.width   = 2,
+		},
+		.delay = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 20,
+			.width   = 4,
+		},
+		.delay_step_ps   = CLK_DELAY_STEP_PS_GX,
+	},
+};
+
+static const struct mmc_clkc_data mmc_clkc_axg_data = {
+	.tx = {
+		.phase = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 10,
+			.width   = 2,
+		},
+		.delay = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 16,
+			.width   = 6,
+		},
+		.delay_step_ps   = CLK_DELAY_STEP_PS_AXG,
+	},
+	.rx = {
+		.phase = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 12,
+			.width   = 2,
+		},
+		.delay = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 22,
+			.width   = 6,
+		},
+		.delay_step_ps   = CLK_DELAY_STEP_PS_AXG,
+	},
+};
+
+static const struct of_device_id mmc_clkc_match_table[] = {
+	{
+		.compatible	= "amlogic,gx-mmc-clkc",
+		.data		= &mmc_clkc_gx_data
+	},
+	{
+		.compatible	= "amlogic,axg-mmc-clkc",
+		.data		= &mmc_clkc_axg_data
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, mmc_clkc_match_table);
+
+static struct clk_regmap *
+mmc_clkc_register_clk(struct device *dev, struct regmap *map,
+		      struct clk_init_data *init,
+		      const char *suffix, void *data)
+{
+	struct clk_regmap *clk;
+	char *name;
+	int ret;
+
+	clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
+	if (!clk)
+		return ERR_PTR(-ENOMEM);
+
+	name = kasprintf(GFP_KERNEL, "%s#%s", dev_name(dev), suffix);
+	if (!name)
+		return ERR_PTR(-ENOMEM);
+
+	init->name = name;
+	clk->map = map;
+	clk->data = data;
+	clk->hw.init = init;
+	ret = devm_clk_hw_register(dev, &clk->hw);
+	if (ret)
+		clk = ERR_PTR(ret);
+
+	kfree(name);
+	return clk;
+}
+
+static struct clk_regmap *mmc_clkc_register_mux(struct device *dev,
+						struct regmap *map)
+{
+	struct clk_init_data init = {0};
+	struct clk_regmap *mux;
+	struct clk *clk;
+	int i;
+
+	for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
+		char name[8];
+
+		snprintf(name, sizeof(name), "clkin%d", i);
+		clk = devm_clk_get(dev, name);
+		if (IS_ERR(clk)) {
+			if (clk != ERR_PTR(-EPROBE_DEFER))
+				dev_err_probe(dev, PTR_ERR(clk),
+					      "Missing clock\n");
+			return ERR_CAST(clk);
+		}
+
+		mmc_clkc_parent_data[i].fw_name = __clk_get_name(clk);
+	}
+
+	init.ops = &clk_regmap_mux_ops;
+	init.flags = CLK_SET_RATE_PARENT;
+	init.parent_data = mmc_clkc_parent_data;
+	init.num_parents = MUX_CLK_NUM_PARENTS;
+
+	mux = mmc_clkc_register_clk(dev, map, &init, "mux", &mmc_clkc_mux_data);
+	if (IS_ERR(mux))
+		dev_err(dev, "Mux clock registration failed\n");
+
+	return mux;
+}
+
+static struct clk_regmap *
+mmc_clkc_register_clk_with_parent(struct device *dev, struct regmap *map,
+				  char *suffix, const struct clk_hw *hw,
+				  unsigned long flags,
+				  const struct clk_ops *ops, void *data)
+{
+	struct clk_init_data init;
+	struct clk_regmap *clk;
+	const char *parent_name = clk_hw_get_name(hw);
+
+	init.ops = ops;
+	init.flags = flags;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+	clk = mmc_clkc_register_clk(dev, map, &init, suffix, data);
+	if (IS_ERR(clk))
+		dev_err(dev, "%s clock registration failed\n", suffix);
+
+	return clk;
+}
+
+static int mmc_clkc_probe(struct platform_device *pdev)
+{
+	struct clk_hw_onecell_data *onecell_data;
+	struct device *dev = &pdev->dev;
+	const struct mmc_clkc_data *data;
+	struct regmap *map;
+	struct clk_regmap *clk, *core;
+	struct meson_sclk_div_data *div_data, *tx, *rx;
+
+	data = of_device_get_match_data(dev);
+	if (!data)
+		return -ENODEV;
+
+	/* cast to drop the const */
+	tx = (struct meson_sclk_div_data *)&data->tx;
+	rx = (struct meson_sclk_div_data *)&data->rx;
+
+	map = syscon_node_to_regmap(dev->of_node);
+	if (IS_ERR(map)) {
+		dev_err(dev, "could not find mmc clock controller\n");
+		return PTR_ERR(map);
+	}
+
+	onecell_data = devm_kzalloc(dev,
+				    struct_size(onecell_data, hws,
+						MMC_MAX_CLKS),
+				    GFP_KERNEL);
+	if (!onecell_data)
+		return -ENOMEM;
+
+	clk = mmc_clkc_register_mux(dev, map);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	div_data = devm_kzalloc(dev, sizeof(*div_data), GFP_KERNEL);
+	if (!div_data)
+		return -ENOMEM;
+
+	memcpy(div_data, &mmc_clkc_div_data, sizeof(*div_data));
+	clk = mmc_clkc_register_clk_with_parent(dev, map, "div",
+						&clk->hw,
+						CLK_SET_RATE_PARENT,
+						&meson_sclk_div_ops,
+						div_data);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	onecell_data->hws[CLKID_MMC_DIV] = &clk->hw;
+	core = mmc_clkc_register_clk_with_parent(dev, map, "core",
+						 &clk->hw,
+						 CLK_SET_RATE_PARENT,
+						 &meson_clk_phase_ops,
+						 &mmc_clkc_core_phase);
+	if (IS_ERR(core))
+		return PTR_ERR(core);
+	onecell_data->hws[CLKID_MMC_PHASE_CORE] = &core->hw;
+	clk = mmc_clkc_register_clk_with_parent(dev, map, "rx",
+						&core->hw,  0,
+						&meson_clk_phase_delay_ops,
+						rx);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+	onecell_data->hws[CLKID_MMC_PHASE_RX] = &clk->hw;
+	clk = mmc_clkc_register_clk_with_parent(dev, map, "tx",
+						&core->hw,  0,
+						&meson_clk_phase_delay_ops,
+						tx);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	onecell_data->hws[CLKID_MMC_PHASE_TX] = &clk->hw;
+	onecell_data->num = MMC_MAX_CLKS;
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   onecell_data);
+}
+
+static struct platform_driver mmc_clkc_driver = {
+	.probe		= mmc_clkc_probe,
+	.driver		= {
+		.name	= "meson-mmc-clkc",
+		.of_match_table = of_match_ptr(mmc_clkc_match_table),
+	},
+};
+
+module_platform_driver(mmc_clkc_driver);
+
+MODULE_DESCRIPTION("Amlogic AXG MMC clock driver");
+MODULE_AUTHOR("Jianxin Pan <jianxin.pan at amlogic.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.34.1



From christianshewitt at gmail.com  Fri Jan 21 23:32:18 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Sat, 22 Jan 2022 07:32:18 +0000
Subject: [PATCH 0/3] arm64: dts: meson: add BL32 reserved region to Beelink
 g12b devices
Message-ID: <20220122073221.2398-1-christianshewitt@gmail.com>

This resolves a long-running issue where Beelink GT-King/Pro and
GS-King-X wedge on boot or shortly after when booting from vendor
u-boot. In some distros the issue is often reported as triggered
by large file transfers to/from USB or SD cards. Reserving the
BL32 memory region prevents the issue.

Christian Hewitt (3):
  arm64: dts: meson: add BL32 reserved-memory region to GT-King
  arm64: dts: meson: add BL32 reserved-memory region to GT-King Pro
  arm64: dts: meson: add BL32 reserved-memory region to GS-King-X

 arch/arm64/boot/dts/amlogic/meson-g12b-gsking-x.dts   | 8 ++++++++
 arch/arm64/boot/dts/amlogic/meson-g12b-gtking-pro.dts | 8 ++++++++
 arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts     | 8 ++++++++
 3 files changed, 24 insertions(+)

-- 
2.17.1



From christianshewitt at gmail.com  Fri Jan 21 23:32:19 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Sat, 22 Jan 2022 07:32:19 +0000
Subject: [PATCH 1/3] arm64: dts: meson: add BL32 reserved-memory region to
 GT-King
In-Reply-To: <20220122073221.2398-1-christianshewitt@gmail.com>
References: <20220122073221.2398-1-christianshewitt@gmail.com>
Message-ID: <20220122073221.2398-2-christianshewitt@gmail.com>

Add an additional reserved memory region for the BL32 trusted firmware
shipping in Beelink g12b devices. This fixes a long running issue with
boxes booting from Vendor u-boot where the board wedges during boot or
soon after due to the (un)reserved region being overwritten.

Fixes commit c5522ff9c729 ("arm64: dts: meson-g12b-gtking: add initial device-tree")
Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts
index 5d96c1449050..58a300d6b545 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts
@@ -19,6 +19,14 @@
 		rtc1 = &vrtc;
 	};
 
+	reserved-memory {
+		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
+		secmon_reserved_bl32: secmon at 5300000 {
+			reg = <0x0 0x05300000 0x0 0x2000000>;
+			no-map;
+		};
+	};
+
 	spdif_dit: audio-codec-1 {
 		#sound-dai-cells = <0>;
 		compatible = "linux,spdif-dit";
-- 
2.17.1



From christianshewitt at gmail.com  Fri Jan 21 23:32:20 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Sat, 22 Jan 2022 07:32:20 +0000
Subject: [PATCH 2/3] arm64: dts: meson: add BL32 reserved-memory region to
 GT-King Pro
In-Reply-To: <20220122073221.2398-1-christianshewitt@gmail.com>
References: <20220122073221.2398-1-christianshewitt@gmail.com>
Message-ID: <20220122073221.2398-3-christianshewitt@gmail.com>

Add an additional reserved memory region for the BL32 trusted firmware
shipping in Beelink g12b devices. This fixes a long running issue with
boxes booting from Vendor u-boot where the board wedges during boot or
soon after due to the (un)reserved region being overwritten.

Fixes commit 0b928e4e412b ("arm64: dts: meson-g12b-gtking-pro: add initial device-tree")
Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-g12b-gtking-pro.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-gtking-pro.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-gtking-pro.dts
index 707daf92787b..7782fc9fc12b 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-gtking-pro.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-gtking-pro.dts
@@ -19,6 +19,14 @@
 		rtc1 = &vrtc;
 	};
 
+	reserved-memory {
+		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
+		secmon_reserved_bl32: secmon at 5300000 {
+			reg = <0x0 0x05300000 0x0 0x2000000>;
+			no-map;
+		};
+	};
+
 	gpio-keys-polled {
 		compatible = "gpio-keys-polled";
 		#address-cells = <1>;
-- 
2.17.1



From christianshewitt at gmail.com  Fri Jan 21 23:32:21 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Sat, 22 Jan 2022 07:32:21 +0000
Subject: [PATCH 3/3] arm64: dts: meson: add BL32 reserved-memory region to
 GS-King-X
In-Reply-To: <20220122073221.2398-1-christianshewitt@gmail.com>
References: <20220122073221.2398-1-christianshewitt@gmail.com>
Message-ID: <20220122073221.2398-4-christianshewitt@gmail.com>

Add an additional reserved memory region for the BL32 trusted firmware
shipping in Beelink g12b devices. This fixes a long running issue with
boxes booting from Vendor u-boot where the board wedges during boot or
soon after due to the (un)reserved region being overwritten.

Fixes commit 93db2ce05204 ("arm64: dts: meson: add initial Beelink GS-King-X device-tree")
Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Furkan Kardame <furkan at fkardame.com>
---
 arch/arm64/boot/dts/amlogic/meson-g12b-gsking-x.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-gsking-x.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-gsking-x.dts
index 6c7bfacbad78..c6178cbe3a9b 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-gsking-x.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-gsking-x.dts
@@ -20,6 +20,14 @@
 		rtc1 = &vrtc;
 	};
 
+	reserved-memory {
+		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
+		secmon_reserved_bl32: secmon at 5300000 {
+			reg = <0x0 0x05300000 0x0 0x2000000>;
+			no-map;
+		};
+	};
+
 	gpio-keys-polled {
 		compatible = "gpio-keys-polled";
 		#address-cells = <1>;
-- 
2.17.1



From laurent.pinchart at ideasonboard.com  Sun Jan 23 14:15:08 2022
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 24 Jan 2022 00:15:08 +0200
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <20220119023714.1498508-1-victor.liu@nxp.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
Message-ID: <Ye3TbIj5LMvGVRIg@pendragon.ideasonboard.com>

Hi Liu,

Thank you for the patch.

On Wed, Jan 19, 2022 at 10:37:14AM +0800, Liu Ying wrote:
> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> mentions that it should be in UI.  However, the dphy core driver wrongly
> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> is '8 UI', instead of 8.

I'm not sure I'd change the kernel doc. Other fields that are documented
as "Time, in picoseconds" have min/max values expressed in ps, so
clk_pre, documented as "Time, in UI" doesn't appear wrong if the minimum
value is "8 UI".

Otherwise, this patch looks fine to me. With or without dropping that
documentation change,

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
> value according to the D-PHY specification.
> 
> I'm assuming that all impacted custom drivers shall program values in
> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
> specification mentions that the frequency of TxByteClkHS is exactly 1/8
> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
> custom driver code is changed to program those values as
> DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
> 
> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
> as I don't have the hardwares.
> 
> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Robert Foss <robert.foss at linaro.org>
> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> Cc: Jonas Karlman <jonas at kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> Cc: David Airlie <airlied at linux.ie>
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Cc: Vinod Koul <vkoul at kernel.org>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: Heiko Stuebner <heiko at sntech.de>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Guido G?nther <agx at sigxcpu.org>
> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
> Signed-off-by: Liu Ying <victor.liu at nxp.com>
> ---
> v1->v2:
> * Use BITS_PER_BYTE macro. (Andrzej)
> * Drop dsi argument from ui2bc() in nwl-dsi.c.
> 
>  drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
>  drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
>  drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
>  drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
>  include/linux/phy/phy-mipi-dphy.h                |  2 +-
>  5 files changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
> index a7389a0facfb..af07eeb47ca0 100644
> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> @@ -7,6 +7,7 @@
>   */
>  
>  #include <linux/bitfield.h>
> +#include <linux/bits.h>
>  #include <linux/clk.h>
>  #include <linux/irq.h>
>  #include <linux/math64.h>
> @@ -196,12 +197,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
>  /*
>   * ui2bc - UI time periods to byte clock cycles
>   */
> -static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
> +static u32 ui2bc(unsigned int ui)
>  {
> -	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> -
> -	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
> -				  dsi->mode.clock * 1000 * bpp);
> +	return DIV_ROUND_UP(ui, BITS_PER_BYTE);
>  }
>  
>  /*
> @@ -232,12 +230,12 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi)
>  	}
>  
>  	/* values in byte clock cycles */
> -	cycles = ui2bc(dsi, cfg->clk_pre);
> +	cycles = ui2bc(cfg->clk_pre);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
>  	nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
>  	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
> -	cycles += ui2bc(dsi, cfg->clk_pre);
> +	cycles += ui2bc(cfg->clk_pre);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
>  	nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
>  	cycles = ps2bc(dsi, cfg->hs_exit);
> diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> index cd2332bf0e31..fdbd64c03e12 100644
> --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> @@ -9,6 +9,7 @@
>  
>  #include <linux/bitfield.h>
>  #include <linux/bitops.h>
> +#include <linux/bits.h>
>  #include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/io.h>
> @@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
>  		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
>  		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
>  	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
> -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
> +		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
>  
>  	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
>  		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
> diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
> index 288c9c67aa74..ccb4045685cd 100644
> --- a/drivers/phy/phy-core-mipi-dphy.c
> +++ b/drivers/phy/phy-core-mipi-dphy.c
> @@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
>  
>  	cfg->clk_miss = 0;
>  	cfg->clk_post = 60000 + 52 * ui;
> -	cfg->clk_pre = 8000;
> +	cfg->clk_pre = 8;
>  	cfg->clk_prepare = 38000;
>  	cfg->clk_settle = 95000;
>  	cfg->clk_term_en = 0;
> @@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
>  	if (cfg->clk_post < (60000 + 52 * ui))
>  		return -EINVAL;
>  
> -	if (cfg->clk_pre < 8000)
> +	if (cfg->clk_pre < 8)
>  		return -EINVAL;
>  
>  	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> index 347dc79a18c1..630e01b5c19b 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> @@ -5,6 +5,7 @@
>   * Author: Wyon Bi <bivvy.bi at rock-chips.com>
>   */
>  
> +#include <linux/bits.h>
>  #include <linux/kernel.h>
>  #include <linux/clk.h>
>  #include <linux/iopoll.h>
> @@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
>  	 * The value of counter for HS Tclk-pre
>  	 * Tclk-pre = Tpin_txbyteclkhs * value
>  	 */
> -	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
> +	clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);
>  
>  	/*
>  	 * The value of counter for HS Tlpx Time
> diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
> index a877ffee845d..59a5e77ab409 100644
> --- a/include/linux/phy/phy-mipi-dphy.h
> +++ b/include/linux/phy/phy-mipi-dphy.h
> @@ -42,7 +42,7 @@ struct phy_configure_opts_mipi_dphy {
>  	 * the transmitter prior to any associated Data Lane beginning
>  	 * the transition from LP to HS mode.
>  	 *
> -	 * Minimum value: 8 UI
> +	 * Minimum value: 8
>  	 */
>  	unsigned int		clk_pre;
>  

-- 
Regards,

Laurent Pinchart


From victor.liu at nxp.com  Sun Jan 23 18:31:48 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 24 Jan 2022 10:31:48 +0800
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <Ye3TbIj5LMvGVRIg@pendragon.ideasonboard.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
 <Ye3TbIj5LMvGVRIg@pendragon.ideasonboard.com>
Message-ID: <bd5a0d5ac47c4b139ef5eaaaa9dd8a4e5429516f.camel@nxp.com>

Hi Laurent,

On Mon, 2022-01-24 at 00:15 +0200, Laurent Pinchart wrote:
> Hi Liu,
> 
> Thank you for the patch.

Thank you for your review.

> 
> On Wed, Jan 19, 2022 at 10:37:14AM +0800, Liu Ying wrote:
> > The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> > parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> > kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> > mentions that it should be in UI.  However, the dphy core driver wrongly
> > sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> > And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> > is '8 UI', instead of 8.
> 
> I'm not sure I'd change the kernel doc. Other fields that are documented
> as "Time, in picoseconds" have min/max values expressed in ps, so
> clk_pre, documented as "Time, in UI" doesn't appear wrong if the minimum
> value is "8 UI".
> 
> Otherwise, this patch looks fine to me. With or without dropping that
> documentation change,

I'll drop the documentation change in v3.

Regards,
Liu Ying

> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> 



From victor.liu at nxp.com  Sun Jan 23 18:32:53 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 24 Jan 2022 10:32:53 +0800
Subject: [PATCH v3] phy: dphy: Correct clk_pre parameter
Message-ID: <20220124023253.1457834-1-victor.liu@nxp.com>

The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
mentions that it should be in UI.  However, the dphy core driver wrongly
sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
is '8 UI', instead of 8.

So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
value according to the D-PHY specification.

I'm assuming that all impacted custom drivers shall program values in
TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
specification mentions that the frequency of TxByteClkHS is exactly 1/8
the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
custom driver code is changed to program those values as
DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.

Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
as I don't have the hardwares.

Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
Cc: Andrzej Hajda <andrzej.hajda at intel.com>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Robert Foss <robert.foss at linaro.org>
Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
Cc: Jonas Karlman <jonas at kwiboo.se>
Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
Cc: David Airlie <airlied at linux.ie>
Cc: Daniel Vetter <daniel at ffwll.ch>
Cc: Kishon Vijay Abraham I <kishon at ti.com>
Cc: Vinod Koul <vkoul at kernel.org>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: Heiko Stuebner <heiko at sntech.de>
Cc: Maxime Ripard <mripard at kernel.org>
Cc: Guido G?nther <agx at sigxcpu.org>
Cc: Wyon Bi <bivvy.bi at rock-chips.com>
Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
Reviewed-by: Neil Armstrong <narmstrong at baylibre.com> # for phy-meson-axg-mipi-dphy.c
Tested-by: Neil Armstrong <narmstrong at baylibre.com> # for phy-meson-axg-mipi-dphy.c
Tested-by: Guido G?nther <agx at sigxcpu.org> # Librem 5 (imx8mq) with it's rather picky panel
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v2->v3:
* Drop D-PHY documentation change. (Laurent)
* Collect R-b tags and T-b tags.
* Cc Wyon.

v1->v2:
* Use BITS_PER_BYTE macro. (Andrzej)
* Drop dsi argument from ui2bc() in nwl-dsi.c.

 drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
 drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
 drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
 drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index a7389a0facfb..af07eeb47ca0 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/math64.h>
@@ -196,12 +197,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
 /*
  * ui2bc - UI time periods to byte clock cycles
  */
-static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
+static u32 ui2bc(unsigned int ui)
 {
-	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
-
-	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
-				  dsi->mode.clock * 1000 * bpp);
+	return DIV_ROUND_UP(ui, BITS_PER_BYTE);
 }
 
 /*
@@ -232,12 +230,12 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi)
 	}
 
 	/* values in byte clock cycles */
-	cycles = ui2bc(dsi, cfg->clk_pre);
+	cycles = ui2bc(cfg->clk_pre);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
 	nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
 	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
-	cycles += ui2bc(dsi, cfg->clk_pre);
+	cycles += ui2bc(cfg->clk_pre);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
 	nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
 	cycles = ps2bc(dsi, cfg->hs_exit);
diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
index cd2332bf0e31..fdbd64c03e12 100644
--- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
+++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
@@ -9,6 +9,7 @@
 
 #include <linux/bitfield.h>
 #include <linux/bitops.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/io.h>
@@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
 		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
 		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
 	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
-		     DIV_ROUND_UP(priv->config.clk_pre, temp));
+		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
 
 	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
 		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
index 288c9c67aa74..ccb4045685cd 100644
--- a/drivers/phy/phy-core-mipi-dphy.c
+++ b/drivers/phy/phy-core-mipi-dphy.c
@@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
 
 	cfg->clk_miss = 0;
 	cfg->clk_post = 60000 + 52 * ui;
-	cfg->clk_pre = 8000;
+	cfg->clk_pre = 8;
 	cfg->clk_prepare = 38000;
 	cfg->clk_settle = 95000;
 	cfg->clk_term_en = 0;
@@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
 	if (cfg->clk_post < (60000 + 52 * ui))
 		return -EINVAL;
 
-	if (cfg->clk_pre < 8000)
+	if (cfg->clk_pre < 8)
 		return -EINVAL;
 
 	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
index 347dc79a18c1..630e01b5c19b 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
@@ -5,6 +5,7 @@
  * Author: Wyon Bi <bivvy.bi at rock-chips.com>
  */
 
+#include <linux/bits.h>
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/iopoll.h>
@@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
 	 * The value of counter for HS Tclk-pre
 	 * Tclk-pre = Tpin_txbyteclkhs * value
 	 */
-	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
+	clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);
 
 	/*
 	 * The value of counter for HS Tlpx Time
-- 
2.25.1



From victor.liu at nxp.com  Sun Jan 23 18:40:07 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 24 Jan 2022 10:40:07 +0800
Subject: [PATCH v4] phy: dphy: Correct clk_pre parameter
Message-ID: <20220124024007.1465018-1-victor.liu@nxp.com>

The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
mentions that it should be in UI.  However, the dphy core driver wrongly
sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.

So, let's fix the dphy core driver to correctly reflect the T-CLK-PRE
parameter's minimum value according to the D-PHY specification.

I'm assuming that all impacted custom drivers shall program values in
TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
specification mentions that the frequency of TxByteClkHS is exactly 1/8
the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
custom driver code is changed to program those values as
DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.

Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
as I don't have the hardwares.

Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
Cc: Andrzej Hajda <andrzej.hajda at intel.com>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Robert Foss <robert.foss at linaro.org>
Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
Cc: Jonas Karlman <jonas at kwiboo.se>
Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
Cc: David Airlie <airlied at linux.ie>
Cc: Daniel Vetter <daniel at ffwll.ch>
Cc: Kishon Vijay Abraham I <kishon at ti.com>
Cc: Vinod Koul <vkoul at kernel.org>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: Heiko Stuebner <heiko at sntech.de>
Cc: Maxime Ripard <mripard at kernel.org>
Cc: Guido G?nther <agx at sigxcpu.org>
Cc: Wyon Bi <bivvy.bi at rock-chips.com>
Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
Reviewed-by: Neil Armstrong <narmstrong at baylibre.com> # for phy-meson-axg-mipi-dphy.c
Tested-by: Neil Armstrong <narmstrong at baylibre.com> # for phy-meson-axg-mipi-dphy.c
Tested-by: Guido G?nther <agx at sigxcpu.org> # Librem 5 (imx8mq) with it's rather picky panel
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v3->v4:
* Fix commit message as the patch doesn't fix D-PHY documentation.

v2->v3:
* Drop D-PHY documentation change. (Laurent)
* Collect R-b tags and T-b tags.
* Cc Wyon.

v1->v2:
* Use BITS_PER_BYTE macro. (Andrzej)
* Drop dsi argument from ui2bc() in nwl-dsi.c.

 drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
 drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
 drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
 drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index a7389a0facfb..af07eeb47ca0 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/math64.h>
@@ -196,12 +197,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
 /*
  * ui2bc - UI time periods to byte clock cycles
  */
-static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
+static u32 ui2bc(unsigned int ui)
 {
-	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
-
-	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
-				  dsi->mode.clock * 1000 * bpp);
+	return DIV_ROUND_UP(ui, BITS_PER_BYTE);
 }
 
 /*
@@ -232,12 +230,12 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi)
 	}
 
 	/* values in byte clock cycles */
-	cycles = ui2bc(dsi, cfg->clk_pre);
+	cycles = ui2bc(cfg->clk_pre);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
 	nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
 	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
-	cycles += ui2bc(dsi, cfg->clk_pre);
+	cycles += ui2bc(cfg->clk_pre);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
 	nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
 	cycles = ps2bc(dsi, cfg->hs_exit);
diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
index cd2332bf0e31..fdbd64c03e12 100644
--- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
+++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
@@ -9,6 +9,7 @@
 
 #include <linux/bitfield.h>
 #include <linux/bitops.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/io.h>
@@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
 		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
 		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
 	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
-		     DIV_ROUND_UP(priv->config.clk_pre, temp));
+		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
 
 	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
 		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
index 288c9c67aa74..ccb4045685cd 100644
--- a/drivers/phy/phy-core-mipi-dphy.c
+++ b/drivers/phy/phy-core-mipi-dphy.c
@@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
 
 	cfg->clk_miss = 0;
 	cfg->clk_post = 60000 + 52 * ui;
-	cfg->clk_pre = 8000;
+	cfg->clk_pre = 8;
 	cfg->clk_prepare = 38000;
 	cfg->clk_settle = 95000;
 	cfg->clk_term_en = 0;
@@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
 	if (cfg->clk_post < (60000 + 52 * ui))
 		return -EINVAL;
 
-	if (cfg->clk_pre < 8000)
+	if (cfg->clk_pre < 8)
 		return -EINVAL;
 
 	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
index 347dc79a18c1..630e01b5c19b 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
@@ -5,6 +5,7 @@
  * Author: Wyon Bi <bivvy.bi at rock-chips.com>
  */
 
+#include <linux/bits.h>
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/iopoll.h>
@@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
 	 * The value of counter for HS Tclk-pre
 	 * Tclk-pre = Tpin_txbyteclkhs * value
 	 */
-	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
+	clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);
 
 	/*
 	 * The value of counter for HS Tlpx Time
-- 
2.25.1



From khilman at baylibre.com  Mon Jan 24 11:58:04 2022
From: khilman at baylibre.com (Kevin Hilman)
Date: Mon, 24 Jan 2022 11:58:04 -0800
Subject: [PATCH V6 0/5] Use CCF to describe the UART baud rate clock
In-Reply-To: <cc3b971f-c630-4ce2-e6dd-c13bcba89d22@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <7hfspjqrn7.fsf@baylibre.com>
 <cc3b971f-c630-4ce2-e6dd-c13bcba89d22@amlogic.com>
Message-ID: <7hbl00ykhf.fsf@baylibre.com>

Yu Tu <yu.tu at amlogic.com> writes:

> Hi Kevin,
> 	Thank you very much for your reply.
>
> On 2022/1/20 6:37, Kevin Hilman wrote:
>> [ EXTERNAL EMAIL ]
>> 
>> Hello,
>> 
>> Yu Tu <yu.tu at amlogic.com> writes:
>> 
>>> Using the common Clock code to describe the UART baud rate
>>> clock makes it easier for the UART driver to be compatible
>>> with the baud rate requirements of the UART IP on different
>>> meson chips. Add Meson S4 SoC compatible.
>> 
>> Could you describe how this was tested and on which SoCs?  There seem to
>> be some changes in this series that might affect previous SoCs.
>> 
> For me, the board starts normally and prints. My intention was to add 
> the S4 SOC UART compatible, but for the S4 our baud rate clock is 
> calculated at 12MHz by default.So a series of changes were made at your 
> suggestion.
>
> Since most SoCs are too old, I was able to find all the platforms myself 
> such as Meson6, Meson8, Meson8b, GXL and so on. I only tested it with 
> G12A and S4.But when I talked to Martin earlier he tried meson8b's log.
> The test patch is in the attachment.
>
> I have found that on some boards with this change, the initcall_debug 
> Uart driver takes longer to initialize. Running the stty command to 
> change the baud rate at the same time may cause a jam.

This kind of detail is important to document in the cover letter,
including a bit more detail on how to reproduce so that other can help
test or may have ideas for how to solve.

> I'd love to know what else you suggest.

I don't expect you to be able to test on all SoCs, but just to list what
SoCs and which boards you tested on.  This way, those who have other
boards can help test and we can have a better idea of how this was
tested before merging.

Thanks,

Kevin


From khilman at baylibre.com  Mon Jan 24 12:02:28 2022
From: khilman at baylibre.com (Kevin Hilman)
Date: Mon, 24 Jan 2022 12:02:28 -0800
Subject: [PATCH 0/3] arm64: dts: meson: add BL32 reserved region to
 Beelink g12b devices
In-Reply-To: <20220122073221.2398-1-christianshewitt@gmail.com>
References: <20220122073221.2398-1-christianshewitt@gmail.com>
Message-ID: <7h7daoyka3.fsf@baylibre.com>

Christian Hewitt <christianshewitt at gmail.com> writes:

> This resolves a long-running issue where Beelink GT-King/Pro and
> GS-King-X wedge on boot or shortly after when booting from vendor
> u-boot. In some distros the issue is often reported as triggered
> by large file transfers to/from USB or SD cards. Reserving the
> BL32 memory region prevents the issue.

The BL32 is typically common for the SoC family, so this change should
probably go into the g12b.dtsi.  Or probably even
meson-g12-common.dtsi, which is where the BL31 reserved-memory is
described.

Kevin




From khilman at baylibre.com  Mon Jan 24 14:05:17 2022
From: khilman at baylibre.com (Kevin Hilman)
Date: Mon, 24 Jan 2022 14:05:17 -0800
Subject: [PATCH] mmc: meson: Fix usage of meson_mmc_post_req()
In-Reply-To: <20220106105453.3875119-1-rong.chen@amlogic.com>
References: <20220106105453.3875119-1-rong.chen@amlogic.com>
Message-ID: <7htudsx00y.fsf@baylibre.com>

Hello Rong,

First, thank you finding the issue and for submitting a fix!

Rong Chen <rong.chen at amlogic.com> writes:

> To ensure the DMA moves data correctly from memory to
> peripherals, DMA unmapping when the MMC request done
> with calls meson_mmc_post_req().
>
> Signed-off-by: Rong Chen <rong.chen at amlogic.com>

The patch looks correct, but I think I think the changelog could be
improved.  If I understand the code correctly, I think what you're doing
is:

"""
Currently meson_mmc_post_req() is called in meson_mmc_request() right
after _start_cmd().  This could lead to DMA unmapping before the request
is actually finished.

To fix, ton't call meson_mmc_post_req() until _request_done().
"""

Kevin

> ---
>  drivers/mmc/host/meson-gx-mmc.c | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
> index 8f36536cb1b6..6a9554ae4b1c 100644
> --- a/drivers/mmc/host/meson-gx-mmc.c
> +++ b/drivers/mmc/host/meson-gx-mmc.c
> @@ -173,6 +173,7 @@ struct meson_host {
>  	int irq;
>  
>  	bool vqmmc_enabled;
> +	bool needs_pre_post_req;
>  };
>  
>  #define CMD_CFG_LENGTH_MASK GENMASK(8, 0)
> @@ -663,6 +664,8 @@ static void meson_mmc_request_done(struct mmc_host *mmc,
>  	struct meson_host *host = mmc_priv(mmc);
>  
>  	host->cmd = NULL;
> +	if (host->needs_pre_post_req)
> +		meson_mmc_post_req(mmc, mrq, 0);
>  	mmc_request_done(host->mmc, mrq);
>  }
>  
> @@ -880,7 +883,7 @@ static int meson_mmc_validate_dram_access(struct mmc_host *mmc, struct mmc_data
>  static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
>  {
>  	struct meson_host *host = mmc_priv(mmc);
> -	bool needs_pre_post_req = mrq->data &&
> +	host->needs_pre_post_req = mrq->data &&
>  			!(mrq->data->host_cookie & SD_EMMC_PRE_REQ_DONE);
>  
>  	/*
> @@ -896,22 +899,19 @@ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
>  		}
>  	}
>  
> -	if (needs_pre_post_req) {
> +	if (host->needs_pre_post_req) {
>  		meson_mmc_get_transfer_mode(mmc, mrq);
>  		if (!meson_mmc_desc_chain_mode(mrq->data))
> -			needs_pre_post_req = false;
> +			host->needs_pre_post_req = false;
>  	}
>  
> -	if (needs_pre_post_req)
> +	if (host->needs_pre_post_req)
>  		meson_mmc_pre_req(mmc, mrq);
>  
>  	/* Stop execution */
>  	writel(0, host->regs + SD_EMMC_START);
>  
>  	meson_mmc_start_cmd(mmc, mrq->sbc ?: mrq->cmd);
> -
> -	if (needs_pre_post_req)
> -		meson_mmc_post_req(mmc, mrq, 0);
>  }
>  
>  static void meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command *cmd)
>
> base-commit: 356f3f2c5756bbb67a515760966a40fc7043cdda
> -- 
> 2.25.1


From christianshewitt at gmail.com  Mon Jan 24 20:03:09 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Tue, 25 Jan 2022 08:03:09 +0400
Subject: [PATCH 0/3] arm64: dts: meson: add BL32 reserved region to
 Beelink g12b devices
In-Reply-To: <7h7daoyka3.fsf@baylibre.com>
References: <20220122073221.2398-1-christianshewitt@gmail.com>
 <7h7daoyka3.fsf@baylibre.com>
Message-ID: <3A7E4C5F-AECB-4A3E-B074-E2E3419DD749@gmail.com>

> 
> On 25 Jan 2022, at 12:02 am, Kevin Hilman <khilman at baylibre.com> wrote:
> 
> Christian Hewitt <christianshewitt at gmail.com> writes:
> 
>> This resolves a long-running issue where Beelink GT-King/Pro and
>> GS-King-X wedge on boot or shortly after when booting from vendor
>> u-boot. In some distros the issue is often reported as triggered
>> by large file transfers to/from USB or SD cards. Reserving the
>> BL32 memory region prevents the issue.
> 
> The BL32 is typically common for the SoC family, so this change should
> probably go into the g12b.dtsi.  Or probably even
> meson-g12-common.dtsi, which is where the BL31 reserved-memory is
> described.

Hi Kevin,

Would you be okay with the same change applied to GX devices too? - I
normally have these two catch-all patches in my tree to deal with random
tv box hardware and it would be great to drop them:

https://github.com/chewitt/linux/commit/4315ea4612389fc08d0a008b562cafbda96374fc
https://github.com/chewitt/linux/commit/3c0df794baa7ea9d32d8ad54530b5a056c770ea9

Christian

From narmstrong at baylibre.com  Tue Jan 25 06:54:34 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 25 Jan 2022 15:54:34 +0100
Subject: [PATCH v10 0/4] clk: meson: add a sub EMMC clock controller
 support
In-Reply-To: <20220121074508.42168-1-liang.yang@amlogic.com>
References: <20220121074508.42168-1-liang.yang@amlogic.com>
Message-ID: <f5a429f2-ffbc-ea03-810a-45a0f90959a2@baylibre.com>

Hi Liang,

On 21/01/2022 08:45, Liang Yang wrote:
> This driver will add a MMC clock controller driver support.
> The original idea about adding a clock controller is during the
> discussion in the NAND driver mainline effort[1].
> 
> This driver is tested in the S400 board (AXG platform) with NAND driver.

Thanks a lot for providing a fixed and updated version of this serie.

After some chat with Jerome and Kevin, it seems the way the eMMC clock reuse
for NAND was designed nearly 4 years doesn't look accurate anymore.

Having a separate clk driver designed to replace the eMMC node when NAND is
used on the board seems over engineered.

Actually having the clock code you add in this serie _but_ directly in
the NAND looks far better, and more coherent since having Linux runtime
detection of eMMC vs NAND will never happen and even this serie required
some DT modification from the bootloader.

I'll let Jerome or Kevin add more details if they want, but I think you should resurrect
the work you pushed in [1] & [2] but:
- passing the eMMC clk registers as a third "reg" cell
- passing the same "clocks" phandle as the eMMC node
- adding the eMMC clock code in the NAND driver directly

I'm open to discussions if you consider the current approach is still superior.

Thanks,
Neil

[1] https://lore.kernel.org/r/20220106033130.37623-1-liang.yang at amlogic.com
[2] https://lore.kernel.org/r/20220106032504.23310-1-liang.yang at amlogic.com

> 
> Changes since v9 [10]
>  - use clk_parent_data instead of parent_names
> 
> Changes since v8 [9]
>  - use MESON_SCLK_ONE_BASED instead of CLK_DIVIDER_ONE_BASED
>  - use struct_size to caculate onecell_data
>  - add clk-phase-delay.h
>  - define CLK_DELAY_STEP_PS_GX and CLK_DELAY_STEP_PS_AXG
> 
> Changes since v7 [8]
>  - move meson_clk_get_phase_delay_data() from header to driver
>  - CONFIG sclk-div with COMMON_CLK_AMLOGIC instead of COMMON_CLK_AMLOGIC_AUDIO
>  - remove onecell date and ID for internal MUX clk
>  - use helper for functions for ONE_BASED in sclk-div
>  - add ONE_BASED support for duty cycle
> 
> Changes since v6 [7]:
>  - add one based support for sclk divier
>  - alloc sclk in probe for multiple instance
>  - fix coding styles
> 
> Changes since v5 [6]:
>  - remove divider ops with .init and use sclk_div instead
>  - drop CLK_DIVIDER_ROUND_CLOSEST in mux and div
>  - drop the useless type cast 
> 
> Changes since v4 [5]:
>  - use struct parm in phase delay driver
>  - remove 0 delay releted part in phase delay driver
>  - don't rebuild the parent name once again
>  - add divider ops with .init
> 
> Changes since v3 [4]:
>  - separate clk-phase-delay driver
>  - replace clk_get_rate() with clk_hw_get_rate()
>  - collect Rob's R-Y
>  - drop 'meson-' prefix from compatible string
> 
>  Changes since v2 [3]:
>  - squash dt-binding clock-id patch
>  - update license
>  - fix alignment
>  - construct a clk register helper() function
> 
> Changes since v1 [2]:
>  - implement phase clock
>  - update compatible name
>  - adjust file name
>  - divider probe() into small functions, and re-use them
> 
> [1] https://lkml.kernel.org/r/20180628090034.0637a062 at xps13
> [2] https://lkml.kernel.org/r/20180703145716.31860-1-yixun.lan at amlogic.com
> [3] https://lkml.kernel.org/r/20180710163658.6175-1-yixun.lan at amlogic.com
> [4] https://lkml.kernel.org/r/20180712211244.11428-1-yixun.lan at amlogic.com
> [5] https://lkml.kernel.org/r/20180809070724.11935-4-yixun.lan at amlogic.com
> [6] https://lkml.kernel.org/r/1539839245-13793-1-git-send-email-jianxin.pan at amlogic.com
> [7] https://lkml.kernel.org/r/1541089855-19356-1-git-send-email-jianxin.pan at amlogic.com
> [8] https://lkml.kernel.org/r/1544457877-51301-1-git-send-email-jianxin.pan at amlogic.com
> [9] https://lkml.kernel.org/r/1545063850-21504-1-git-send-email-jianxin.pan at amlogic.com
> [10] https://lore.kernel.org/all/20220113115745.45826-1-liang.yang at amlogic.com/
> Liang Yang (4):
>   clk: meson: add one based divider support for sclk
>   clk: meson: add emmc sub clock phase delay driver
>   clk: meson: add DT documentation for emmc clock controller
>   clk: meson: add sub MMC clock controller driver
> 
>  .../bindings/clock/amlogic,mmc-clkc.yaml      |  64 ++++
>  drivers/clk/meson/Kconfig                     |  18 ++
>  drivers/clk/meson/Makefile                    |   2 +
>  drivers/clk/meson/clk-phase-delay.c           |  69 ++++
>  drivers/clk/meson/clk-phase-delay.h           |  20 ++
>  drivers/clk/meson/mmc-clkc.c                  | 302 ++++++++++++++++++
>  drivers/clk/meson/sclk-div.c                  |  59 ++--
>  drivers/clk/meson/sclk-div.h                  |   3 +
>  include/dt-bindings/clock/amlogic,mmc-clkc.h  |  14 +
>  9 files changed, 529 insertions(+), 22 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>  create mode 100644 drivers/clk/meson/clk-phase-delay.c
>  create mode 100644 drivers/clk/meson/clk-phase-delay.h
>  create mode 100644 drivers/clk/meson/mmc-clkc.c
>  create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
> 



From narmstrong at baylibre.com  Tue Jan 25 07:01:18 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 25 Jan 2022 16:01:18 +0100
Subject: [PATCH 0/3] arm64: dts: meson: add BL32 reserved region to
 Beelink g12b devices
In-Reply-To: <C8B4EA0E-6593-4C42-B116-F9C043D29452@gmail.com>
References: <20220122073221.2398-1-christianshewitt@gmail.com>
 <7h7daoyka3.fsf@baylibre.com>
 <C8B4EA0E-6593-4C42-B116-F9C043D29452@gmail.com>
Message-ID: <4a8727f4-fbdd-33f7-1f1b-c4baf92ad986@baylibre.com>

Hi,

On 25/01/2022 05:02, Christian Hewitt wrote:
> 
>> On 25 Jan 2022, at 12:02 am, Kevin Hilman <khilman at baylibre.com <mailto:khilman at baylibre.com>> wrote:
>>
>> Christian Hewitt <christianshewitt at gmail.com <mailto:christianshewitt at gmail.com>> writes:
>>
>>> This resolves a long-running issue where Beelink GT-King/Pro and
>>> GS-King-X wedge on boot or shortly after when booting from vendor
>>> u-boot. In some distros the issue is often reported as triggered
>>> by large file transfers to/from USB or SD cards. Reserving the
>>> BL32 memory region prevents the issue.
>>
>> The BL32 is typically common for the SoC family, so this change should
>> probably go into the g12b.dtsi. ?Or probably even
>> meson-g12-common.dtsi, which is where the BL31 reserved-memory is
>> described.
> 
> Hi Kevin,
> 
> Would you be okay with the same change applied to GX devices too? - I
> normally have these two catch-all patches in my tree to deal with random
> tv box hardware and it would be great to drop them:
> 
> https://github.com/chewitt/linux/commit/4315ea4612389fc08d0a008b562cafbda96374fc <https://github.com/chewitt/linux/commit/4315ea4612389fc08d0a008b562cafbda96374fc>
> https://github.com/chewitt/linux/commit/3c0df794baa7ea9d32d8ad54530b5a056c770ea9 <https://github.com/chewitt/linux/commit/3c0df794baa7ea9d32d8ad54530b5a056c770ea9>

Sure, it has been done in a similar way for bl31:
https://github.com/torvalds/linux/commit/48e21ded0432ee1e2359d4143d7a6925cefee1b5

in a perfect work we wouldn't need this since mainline U-Boot does the job by reserving these
memory zones, but vendor u-boot exists and isn't avoidable.

Neil

> 
> Christian



From christianshewitt at gmail.com  Tue Jan 25 20:49:51 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 26 Jan 2022 04:49:51 +0000
Subject: [PATCH 0/3] arm64: dts: meson: add ATF BL32 reserved-memory regions
Message-ID: <20220126044954.19069-1-christianshewitt@gmail.com>

This series supersedes [0] which fixed a long-running kernel panic issue
seen with Beelink G12B devices booted from Amlogic vendor firmware. The
same issue exists with a wider set of devices from GXBB to SM1, although
it is not often seen due to my kernel fork including 'catch-all' patches
for some time (the meson-gx patch was suggested by Matheusz in 2019) and
many distros actively supporting Amlogic hardware consuming some or all
of my regular patchset.

I've also included a cleanup to the SEI510/SEI610 board files. If that's
not desirable feel free to ignore that patch. I also dropped the fixes
tagging as I'm not sure what original commits could be targetted. If you
think fixes are good please provide some guidance and I'll be happy to
send a revised series.

[0] https://patchwork.kernel.org/project/linux-amlogic/list/?series=607446

Christian Hewitt (3):
  arm64: dts: meson-gx: add ATF BL32 reserved-memory region
  arm64: dts: meson-g12: add ATF BL32 reserved-memory region
  arm64: dts: meson-g12: drop BL32 region from SEI510/SEI610

 arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 6 ++++++
 arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts | 8 --------
 arch/arm64/boot/dts/amlogic/meson-gx.dtsi         | 6 ++++++
 arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts  | 8 --------
 4 files changed, 12 insertions(+), 16 deletions(-)

-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 25 20:49:52 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 26 Jan 2022 04:49:52 +0000
Subject: [PATCH 1/3] arm64: dts: meson-gx: add ATF BL32 reserved-memory region
In-Reply-To: <20220126044954.19069-1-christianshewitt@gmail.com>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
Message-ID: <20220126044954.19069-2-christianshewitt@gmail.com>

Add an additional reserved memory region for the BL32 trusted firmware
present in many devices that boot from Amlogic vendor u-boot.

Suggested-by: Mateusz Krzak <kszaquitto at gmail.com>
Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index 6b457b2c30a4..aa14ea017a61 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -49,6 +49,12 @@
 			no-map;
 		};
 
+		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
+		secmon_reserved_bl32: secmon at 5300000 {
+			reg = <0x0 0x05300000 0x0 0x2000000>;
+			no-map;
+		};
+
 		linux,cma {
 			compatible = "shared-dma-pool";
 			reusable;
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 25 20:49:53 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 26 Jan 2022 04:49:53 +0000
Subject: [PATCH 2/3] arm64: dts: meson-g12: add ATF BL32 reserved-memory region
In-Reply-To: <20220126044954.19069-1-christianshewitt@gmail.com>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
Message-ID: <20220126044954.19069-3-christianshewitt@gmail.com>

Add an additional reserved memory region for the BL32 trusted firmware
present in many devices that boot from Amlogic vendor u-boot.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index 6d99c23261fb..45947c1031c4 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -107,6 +107,12 @@
 			no-map;
 		};
 
+		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
+		secmon_reserved_bl32: secmon at 5300000 {
+			reg = <0x0 0x05300000 0x0 0x2000000>;
+			no-map;
+		};
+
 		linux,cma {
 			compatible = "shared-dma-pool";
 			reusable;
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 25 20:49:54 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 26 Jan 2022 04:49:54 +0000
Subject: [PATCH 3/3] arm64: dts: meson-g12: drop BL32 region from SEI510/SEI610
In-Reply-To: <20220126044954.19069-1-christianshewitt@gmail.com>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
Message-ID: <20220126044954.19069-4-christianshewitt@gmail.com>

The BL32/TEE reserved-memory region is now inherited from the common
family dtsi (meson-g12-common) so we can drop it from board files.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts | 8 --------
 arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts  | 8 --------
 2 files changed, 16 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
index d8838dde0f0f..4fb31c2ba31c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
@@ -157,14 +157,6 @@
 		regulator-always-on;
 	};
 
-	reserved-memory {
-		/* TEE Reserved Memory */
-		bl32_reserved: bl32 at 5000000 {
-			reg = <0x0 0x05300000 0x0 0x2000000>;
-			no-map;
-		};
-	};
-
 	sdio_pwrseq: sdio-pwrseq {
 		compatible = "mmc-pwrseq-simple";
 		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
index 427475846fc7..a5d79f2f7c19 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
@@ -203,14 +203,6 @@
 		regulator-always-on;
 	};
 
-	reserved-memory {
-		/* TEE Reserved Memory */
-		bl32_reserved: bl32 at 5000000 {
-			reg = <0x0 0x05300000 0x0 0x2000000>;
-			no-map;
-		};
-	};
-
 	sdio_pwrseq: sdio-pwrseq {
 		compatible = "mmc-pwrseq-simple";
 		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
-- 
2.17.1



From adeep at lexina.in  Tue Jan 25 21:35:00 2022
From: adeep at lexina.in (Vyacheslav)
Date: Wed, 26 Jan 2022 08:35:00 +0300
Subject: [PATCH 1/3] arm64: dts: meson-gx: add ATF BL32 reserved-memory
 region
In-Reply-To: <20220126044954.19069-2-christianshewitt@gmail.com>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
 <20220126044954.19069-2-christianshewitt@gmail.com>
Message-ID: <a279c365-0615-1c7f-5596-dec9ad1c8229@lexina.in>

Hi!

26.01.2022 07:49, Christian Hewitt wrote:
> Add an additional reserved memory region for the BL32 trusted firmware
> present in many devices that boot from Amlogic vendor u-boot.
> 
> Suggested-by: Mateusz Krzak <kszaquitto at gmail.com>
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>   arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> index 6b457b2c30a4..aa14ea017a61 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> @@ -49,6 +49,12 @@
>   			no-map;
>   		};
>   
> +		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
> +		secmon_reserved_bl32: secmon at 5300000 {
> +			reg = <0x0 0x05300000 0x0 0x2000000>;
> +			no-map;
> +		};
> +
How do I check if we need a similar patch for axg boards?


>   		linux,cma {
>   			compatible = "shared-dma-pool";
>   			reusable;
> 



From shunzhou.jiang at amlogic.com  Tue Jan 25 22:10:16 2022
From: shunzhou.jiang at amlogic.com (Shunzhou Jiang)
Date: Wed, 26 Jan 2022 14:10:16 +0800
Subject: [PATCH 0/2] Power: meson-s4: add s4 power domain driver
Message-ID: <20220126061018.705338-1-shunzhou.jiang@amlogic.com>

This patchset adds Power controller driver support for Meson-S4 SoC
Likes Meson-A1, the power domains register only can access in secure world

Shunzhou Jiang (2):
  dt-bindings: power: add Amlogic s4 power domains bindings
  soc: s4: Add support for power domains controller

 .../power/amlogic,meson-sec-pwrc.yaml         |  3 ++-
 drivers/soc/amlogic/meson-secure-pwrc.c       | 21 +++++++++++++++++++
 include/dt-bindings/power/meson-s4-power.h    | 19 +++++++++++++++++
 3 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 include/dt-bindings/power/meson-s4-power.h

-- 
2.34.1



From shunzhou.jiang at amlogic.com  Tue Jan 25 22:10:17 2022
From: shunzhou.jiang at amlogic.com (Shunzhou Jiang)
Date: Wed, 26 Jan 2022 14:10:17 +0800
Subject: [PATCH 1/2] dt-bindings: power: add Amlogic s4 power domains bindings
In-Reply-To: <20220126061018.705338-1-shunzhou.jiang@amlogic.com>
References: <20220126061018.705338-1-shunzhou.jiang@amlogic.com>
Message-ID: <20220126061018.705338-2-shunzhou.jiang@amlogic.com>

Add the bindings for the Amlogic Secure power domains, controlling the
secure power domains.

The bindings targets the Amlogic s4, in which the power domains registers
are in secure world.

Signed-off-by: Shunzhou Jiang <shunzhou.jiang at amlogic.com>
---
 .../power/amlogic,meson-sec-pwrc.yaml         |  3 ++-
 include/dt-bindings/power/meson-s4-power.h    | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)
 create mode 100644 include/dt-bindings/power/meson-s4-power.h

diff --git a/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml b/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml
index 5dae04d2936c..7657721a4e96 100644
--- a/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml
+++ b/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml
@@ -12,13 +12,14 @@ maintainers:
   - Jianxin Pan <jianxin.pan at amlogic.com>
 
 description: |+
-  Secure Power Domains used in Meson A1/C1 SoCs, and should be the child node
+  Secure Power Domains used in Meson A1/C1/S4 SoCs, and should be the child node
   of secure-monitor.
 
 properties:
   compatible:
     enum:
       - amlogic,meson-a1-pwrc
+      - amlogic,meson-s4-pwrc
 
   "#power-domain-cells":
     const: 1
diff --git a/include/dt-bindings/power/meson-s4-power.h b/include/dt-bindings/power/meson-s4-power.h
new file mode 100644
index 000000000000..462dd2cb938b
--- /dev/null
+++ b/include/dt-bindings/power/meson-s4-power.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (c) 2021 Amlogic, Inc.
+ * Author: Shunzhou Jiang <shunzhou.jiang at amlogic.com>
+ */
+
+#ifndef _DT_BINDINGS_MESON_S4_POWER_H
+#define _DT_BINDINGS_MESON_S4_POWER_H
+
+#define PWRC_S4_DOS_HEVC_ID	0
+#define PWRC_S4_DOS_VDEC_ID	1
+#define PWRC_S4_VPU_HDMI_ID	2
+#define PWRC_S4_USB_COMB_ID	3
+#define PWRC_S4_GE2D_ID		4
+#define PWRC_S4_ETH_ID		5
+#define PWRC_S4_DEMOD_ID	6
+#define PWRC_S4_AUDIO_ID	7
+
+#endif
-- 
2.34.1



From shunzhou.jiang at amlogic.com  Tue Jan 25 22:10:18 2022
From: shunzhou.jiang at amlogic.com (Shunzhou Jiang)
Date: Wed, 26 Jan 2022 14:10:18 +0800
Subject: [PATCH 2/2] soc: s4: Add support for power domains controller
In-Reply-To: <20220126061018.705338-1-shunzhou.jiang@amlogic.com>
References: <20220126061018.705338-1-shunzhou.jiang@amlogic.com>
Message-ID: <20220126061018.705338-3-shunzhou.jiang@amlogic.com>

Add support s4 Power controller. In s4, power control
registers are in secure domain, and should be accessed by smc.

Signed-off-by: Shunzhou Jiang <shunzhou.jiang at amlogic.com>
---
 drivers/soc/amlogic/meson-secure-pwrc.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/soc/amlogic/meson-secure-pwrc.c b/drivers/soc/amlogic/meson-secure-pwrc.c
index 59bd195fa9c9..8fee01aabab6 100644
--- a/drivers/soc/amlogic/meson-secure-pwrc.c
+++ b/drivers/soc/amlogic/meson-secure-pwrc.c
@@ -11,6 +11,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <dt-bindings/power/meson-a1-power.h>
+#include <dt-bindings/power/meson-s4-power.h>
 #include <linux/arm-smccc.h>
 #include <linux/firmware/meson/meson_sm.h>
 #include <linux/module.h>
@@ -119,6 +120,17 @@ static struct meson_secure_pwrc_domain_desc a1_pwrc_domains[] = {
 	SEC_PD(RSA,	0),
 };
 
+static struct meson_secure_pwrc_domain_desc s4_pwrc_domains[] = {
+	SEC_PD(S4_DOS_HEVC,	0),
+	SEC_PD(S4_DOS_VDEC,	0),
+	SEC_PD(S4_VPU_HDMI,	GENPD_FLAG_ALWAYS_ON),
+	SEC_PD(S4_USB_COMB,	GENPD_FLAG_ALWAYS_ON),
+	SEC_PD(S4_GE2D,		0),
+	SEC_PD(S4_ETH,		GENPD_FLAG_ALWAYS_ON),
+	SEC_PD(S4_DEMOD,	0),
+	SEC_PD(S4_AUDIO,	0),
+};
+
 static int meson_secure_pwrc_probe(struct platform_device *pdev)
 {
 	int i;
@@ -187,11 +199,20 @@ static struct meson_secure_pwrc_domain_data meson_secure_a1_pwrc_data = {
 	.count = ARRAY_SIZE(a1_pwrc_domains),
 };
 
+static struct meson_secure_pwrc_domain_data meson_secure_s4_pwrc_data = {
+	.domains = s4_pwrc_domains,
+	.count = ARRAY_SIZE(s4_pwrc_domains),
+};
+
 static const struct of_device_id meson_secure_pwrc_match_table[] = {
 	{
 		.compatible = "amlogic,meson-a1-pwrc",
 		.data = &meson_secure_a1_pwrc_data,
 	},
+	{
+		.compatible = "amlogic,meson-s4-pwrc",
+		.data = &meson_secure_s4_pwrc_data,
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, meson_secure_pwrc_match_table);
-- 
2.34.1



From christianshewitt at gmail.com  Tue Jan 25 23:12:42 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 26 Jan 2022 11:12:42 +0400
Subject: [PATCH 1/3] arm64: dts: meson-gx: add ATF BL32 reserved-memory
 region
In-Reply-To: <a279c365-0615-1c7f-5596-dec9ad1c8229@lexina.in>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
 <20220126044954.19069-2-christianshewitt@gmail.com>
 <a279c365-0615-1c7f-5596-dec9ad1c8229@lexina.in>
Message-ID: <343C247D-4F10-4E88-B971-5A1F41A2C892@gmail.com>


> On 26 Jan 2022, at 9:35 am, Vyacheslav <adeep at lexina.in> wrote:
> 
> Hi!
> 
> 26.01.2022 07:49, Christian Hewitt wrote:
>> Add an additional reserved memory region for the BL32 trusted firmware
>> present in many devices that boot from Amlogic vendor u-boot.
>> Suggested-by: Mateusz Krzak <kszaquitto at gmail.com>
>> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
>> ---
>>  arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 6 ++++++
>>  1 file changed, 6 insertions(+)
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
>> index 6b457b2c30a4..aa14ea017a61 100644
>> --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
>> +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
>> @@ -49,6 +49,12 @@
>>  			no-map;
>>  		};
>>  +		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
>> +		secmon_reserved_bl32: secmon at 5300000 {
>> +			reg = <0x0 0x05300000 0x0 0x2000000>;
>> +			no-map;
>> +		};
>> +
> How do I check if we need a similar patch for axg boards?

Are they booting using Amlogic (vendor) u-boot sources that
include bl32.img in the FIP signing recipe?

If booting from upstream u-boot, like JetHome boards, it?s
nothing to worry about.

Christian



From liang.yang at amlogic.com  Wed Jan 26 01:08:42 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Wed, 26 Jan 2022 17:08:42 +0800
Subject: [PATCH v10 0/4] clk: meson: add a sub EMMC clock controller
 support
In-Reply-To: <f5a429f2-ffbc-ea03-810a-45a0f90959a2@baylibre.com>
References: <20220121074508.42168-1-liang.yang@amlogic.com>
 <f5a429f2-ffbc-ea03-810a-45a0f90959a2@baylibre.com>
Message-ID: <6eb4f247-367b-d460-6314-fc94ccd00b89@amlogic.com>

Hi Neil,

On 2022/1/25 22:54, Neil Armstrong wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi Liang,
> 
> On 21/01/2022 08:45, Liang Yang wrote:
>> This driver will add a MMC clock controller driver support.
>> The original idea about adding a clock controller is during the
>> discussion in the NAND driver mainline effort[1].
>>
>> This driver is tested in the S400 board (AXG platform) with NAND driver.
> 
> Thanks a lot for providing a fixed and updated version of this serie.
> 
> After some chat with Jerome and Kevin, it seems the way the eMMC clock reuse
> for NAND was designed nearly 4 years doesn't look accurate anymore.
> 
> Having a separate clk driver designed to replace the eMMC node when NAND is
> used on the board seems over engineered.
> 
> Actually having the clock code you add in this serie _but_ directly in
> the NAND looks far better, and more coherent since having Linux runtime
> detection of eMMC vs NAND will never happen and even this serie required
> some DT modification from the bootloader.
> 
> I'll let Jerome or Kevin add more details if they want, but I think you should resurrect
> the work you pushed in [1] & [2] but:
> - passing the eMMC clk registers as a third "reg" cell
Does it just need to define a 'reg' resource in NFC node and not 
'syscon' here?
> - passing the same "clocks" phandle as the eMMC node
> - adding the eMMC clock code in the NAND driver directly
> 
> I'm open to discussions if you consider the current approach is still superior.

I don't have persuasive ideas, but really it shares the common clock 
implementation for both NFC and EMMC. and we don't need to paste the 
same code in NFC and EMMC.

> 
> Thanks,
> Neil
> 
> [1] https://lore.kernel.org/r/20220106033130.37623-1-liang.yang at amlogic.com
> [2] https://lore.kernel.org/r/20220106032504.23310-1-liang.yang at amlogic.com
> 
>>
>> Changes since v9 [10]
>>   - use clk_parent_data instead of parent_names
>>
>> Changes since v8 [9]
>>   - use MESON_SCLK_ONE_BASED instead of CLK_DIVIDER_ONE_BASED
>>   - use struct_size to caculate onecell_data
>>   - add clk-phase-delay.h
>>   - define CLK_DELAY_STEP_PS_GX and CLK_DELAY_STEP_PS_AXG
>>
>> Changes since v7 [8]
>>   - move meson_clk_get_phase_delay_data() from header to driver
>>   - CONFIG sclk-div with COMMON_CLK_AMLOGIC instead of COMMON_CLK_AMLOGIC_AUDIO
>>   - remove onecell date and ID for internal MUX clk
>>   - use helper for functions for ONE_BASED in sclk-div
>>   - add ONE_BASED support for duty cycle
>>
>> Changes since v6 [7]:
>>   - add one based support for sclk divier
>>   - alloc sclk in probe for multiple instance
>>   - fix coding styles
>>
>> Changes since v5 [6]:
>>   - remove divider ops with .init and use sclk_div instead
>>   - drop CLK_DIVIDER_ROUND_CLOSEST in mux and div
>>   - drop the useless type cast
>>
>> Changes since v4 [5]:
>>   - use struct parm in phase delay driver
>>   - remove 0 delay releted part in phase delay driver
>>   - don't rebuild the parent name once again
>>   - add divider ops with .init
>>
>> Changes since v3 [4]:
>>   - separate clk-phase-delay driver
>>   - replace clk_get_rate() with clk_hw_get_rate()
>>   - collect Rob's R-Y
>>   - drop 'meson-' prefix from compatible string
>>
>>   Changes since v2 [3]:
>>   - squash dt-binding clock-id patch
>>   - update license
>>   - fix alignment
>>   - construct a clk register helper() function
>>
>> Changes since v1 [2]:
>>   - implement phase clock
>>   - update compatible name
>>   - adjust file name
>>   - divider probe() into small functions, and re-use them
>>
>> [1] https://lkml.kernel.org/r/20180628090034.0637a062 at xps13
>> [2] https://lkml.kernel.org/r/20180703145716.31860-1-yixun.lan at amlogic.com
>> [3] https://lkml.kernel.org/r/20180710163658.6175-1-yixun.lan at amlogic.com
>> [4] https://lkml.kernel.org/r/20180712211244.11428-1-yixun.lan at amlogic.com
>> [5] https://lkml.kernel.org/r/20180809070724.11935-4-yixun.lan at amlogic.com
>> [6] https://lkml.kernel.org/r/1539839245-13793-1-git-send-email-jianxin.pan at amlogic.com
>> [7] https://lkml.kernel.org/r/1541089855-19356-1-git-send-email-jianxin.pan at amlogic.com
>> [8] https://lkml.kernel.org/r/1544457877-51301-1-git-send-email-jianxin.pan at amlogic.com
>> [9] https://lkml.kernel.org/r/1545063850-21504-1-git-send-email-jianxin.pan at amlogic.com
>> [10] https://lore.kernel.org/all/20220113115745.45826-1-liang.yang at amlogic.com/
>> Liang Yang (4):
>>    clk: meson: add one based divider support for sclk
>>    clk: meson: add emmc sub clock phase delay driver
>>    clk: meson: add DT documentation for emmc clock controller
>>    clk: meson: add sub MMC clock controller driver
>>
>>   .../bindings/clock/amlogic,mmc-clkc.yaml      |  64 ++++
>>   drivers/clk/meson/Kconfig                     |  18 ++
>>   drivers/clk/meson/Makefile                    |   2 +
>>   drivers/clk/meson/clk-phase-delay.c           |  69 ++++
>>   drivers/clk/meson/clk-phase-delay.h           |  20 ++
>>   drivers/clk/meson/mmc-clkc.c                  | 302 ++++++++++++++++++
>>   drivers/clk/meson/sclk-div.c                  |  59 ++--
>>   drivers/clk/meson/sclk-div.h                  |   3 +
>>   include/dt-bindings/clock/amlogic,mmc-clkc.h  |  14 +
>>   9 files changed, 529 insertions(+), 22 deletions(-)
>>   create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>>   create mode 100644 drivers/clk/meson/clk-phase-delay.c
>>   create mode 100644 drivers/clk/meson/clk-phase-delay.h
>>   create mode 100644 drivers/clk/meson/mmc-clkc.c
>>   create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
>>
> 
> .


From jbrunet at baylibre.com  Wed Jan 26 01:14:55 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Wed, 26 Jan 2022 10:14:55 +0100
Subject: [PATCH v10 0/4] clk: meson: add a sub EMMC clock controller
 support
In-Reply-To: <6eb4f247-367b-d460-6314-fc94ccd00b89@amlogic.com>
References: <20220121074508.42168-1-liang.yang@amlogic.com>
 <f5a429f2-ffbc-ea03-810a-45a0f90959a2@baylibre.com>
 <6eb4f247-367b-d460-6314-fc94ccd00b89@amlogic.com>
Message-ID: <1jy23226sa.fsf@starbuckisacylon.baylibre.com>


On Wed 26 Jan 2022 at 17:08, Liang Yang <liang.yang at amlogic.com> wrote:

> Hi Neil,
>
> On 2022/1/25 22:54, Neil Armstrong wrote:
>> [ EXTERNAL EMAIL ]
>> Hi Liang,
>> On 21/01/2022 08:45, Liang Yang wrote:
>>> This driver will add a MMC clock controller driver support.
>>> The original idea about adding a clock controller is during the
>>> discussion in the NAND driver mainline effort[1].
>>>
>>> This driver is tested in the S400 board (AXG platform) with NAND driver.
>> Thanks a lot for providing a fixed and updated version of this serie.
>> After some chat with Jerome and Kevin, it seems the way the eMMC clock
>> reuse
>> for NAND was designed nearly 4 years doesn't look accurate anymore.
>> Having a separate clk driver designed to replace the eMMC node when NAND
>> is
>> used on the board seems over engineered.
>> Actually having the clock code you add in this serie _but_ directly in
>> the NAND looks far better, and more coherent since having Linux runtime
>> detection of eMMC vs NAND will never happen and even this serie required
>> some DT modification from the bootloader.
>> I'll let Jerome or Kevin add more details if they want, but I think you
>> should resurrect
>> the work you pushed in [1] & [2] but:
>> - passing the eMMC clk registers as a third "reg" cell
> Does it just need to define a 'reg' resource in NFC node and not 'syscon'
> here?

Yes

>> - passing the same "clocks" phandle as the eMMC node
>> - adding the eMMC clock code in the NAND driver directly
>> I'm open to discussions if you consider the current approach is still
>> superior.
>
> I don't have persuasive ideas, but really it shares the common clock
> implementation for both NFC and EMMC. and we don't need to paste the 
> same code in NFC and EMMC.

You don't need to copy everything. If I understood correctly, all the
Rx/Tx should not be needed. Yes, there is some duplication as it stands but
it allows to avoid coupling the MMC and NAND driver. We can still think
about optimizing things later on. Let's get something simply working
first.

>
>> Thanks,
>> Neil
>> [1]
>> https://lore.kernel.org/r/20220106033130.37623-1-liang.yang at amlogic.com
>> [2] https://lore.kernel.org/r/20220106032504.23310-1-liang.yang at amlogic.com
>> 
>>>
>>> Changes since v9 [10]
>>>   - use clk_parent_data instead of parent_names
>>>
>>> Changes since v8 [9]
>>>   - use MESON_SCLK_ONE_BASED instead of CLK_DIVIDER_ONE_BASED
>>>   - use struct_size to caculate onecell_data
>>>   - add clk-phase-delay.h
>>>   - define CLK_DELAY_STEP_PS_GX and CLK_DELAY_STEP_PS_AXG
>>>
>>> Changes since v7 [8]
>>>   - move meson_clk_get_phase_delay_data() from header to driver
>>>   - CONFIG sclk-div with COMMON_CLK_AMLOGIC instead of COMMON_CLK_AMLOGIC_AUDIO
>>>   - remove onecell date and ID for internal MUX clk
>>>   - use helper for functions for ONE_BASED in sclk-div
>>>   - add ONE_BASED support for duty cycle
>>>
>>> Changes since v6 [7]:
>>>   - add one based support for sclk divier
>>>   - alloc sclk in probe for multiple instance
>>>   - fix coding styles
>>>
>>> Changes since v5 [6]:
>>>   - remove divider ops with .init and use sclk_div instead
>>>   - drop CLK_DIVIDER_ROUND_CLOSEST in mux and div
>>>   - drop the useless type cast
>>>
>>> Changes since v4 [5]:
>>>   - use struct parm in phase delay driver
>>>   - remove 0 delay releted part in phase delay driver
>>>   - don't rebuild the parent name once again
>>>   - add divider ops with .init
>>>
>>> Changes since v3 [4]:
>>>   - separate clk-phase-delay driver
>>>   - replace clk_get_rate() with clk_hw_get_rate()
>>>   - collect Rob's R-Y
>>>   - drop 'meson-' prefix from compatible string
>>>
>>>   Changes since v2 [3]:
>>>   - squash dt-binding clock-id patch
>>>   - update license
>>>   - fix alignment
>>>   - construct a clk register helper() function
>>>
>>> Changes since v1 [2]:
>>>   - implement phase clock
>>>   - update compatible name
>>>   - adjust file name
>>>   - divider probe() into small functions, and re-use them
>>>
>>> [1] https://lkml.kernel.org/r/20180628090034.0637a062 at xps13
>>> [2] https://lkml.kernel.org/r/20180703145716.31860-1-yixun.lan at amlogic.com
>>> [3] https://lkml.kernel.org/r/20180710163658.6175-1-yixun.lan at amlogic.com
>>> [4] https://lkml.kernel.org/r/20180712211244.11428-1-yixun.lan at amlogic.com
>>> [5] https://lkml.kernel.org/r/20180809070724.11935-4-yixun.lan at amlogic.com
>>> [6] https://lkml.kernel.org/r/1539839245-13793-1-git-send-email-jianxin.pan at amlogic.com
>>> [7] https://lkml.kernel.org/r/1541089855-19356-1-git-send-email-jianxin.pan at amlogic.com
>>> [8] https://lkml.kernel.org/r/1544457877-51301-1-git-send-email-jianxin.pan at amlogic.com
>>> [9] https://lkml.kernel.org/r/1545063850-21504-1-git-send-email-jianxin.pan at amlogic.com
>>> [10] https://lore.kernel.org/all/20220113115745.45826-1-liang.yang at amlogic.com/
>>> Liang Yang (4):
>>>    clk: meson: add one based divider support for sclk
>>>    clk: meson: add emmc sub clock phase delay driver
>>>    clk: meson: add DT documentation for emmc clock controller
>>>    clk: meson: add sub MMC clock controller driver
>>>
>>>   .../bindings/clock/amlogic,mmc-clkc.yaml      |  64 ++++
>>>   drivers/clk/meson/Kconfig                     |  18 ++
>>>   drivers/clk/meson/Makefile                    |   2 +
>>>   drivers/clk/meson/clk-phase-delay.c           |  69 ++++
>>>   drivers/clk/meson/clk-phase-delay.h           |  20 ++
>>>   drivers/clk/meson/mmc-clkc.c                  | 302 ++++++++++++++++++
>>>   drivers/clk/meson/sclk-div.c                  |  59 ++--
>>>   drivers/clk/meson/sclk-div.h                  |   3 +
>>>   include/dt-bindings/clock/amlogic,mmc-clkc.h  |  14 +
>>>   9 files changed, 529 insertions(+), 22 deletions(-)
>>>   create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>>>   create mode 100644 drivers/clk/meson/clk-phase-delay.c
>>>   create mode 100644 drivers/clk/meson/clk-phase-delay.h
>>>   create mode 100644 drivers/clk/meson/mmc-clkc.c
>>>   create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
>>>
>> .



From liang.yang at amlogic.com  Wed Jan 26 01:42:17 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Wed, 26 Jan 2022 17:42:17 +0800
Subject: [PATCH v10 0/4] clk: meson: add a sub EMMC clock controller
 support
In-Reply-To: <1jy23226sa.fsf@starbuckisacylon.baylibre.com>
References: <20220121074508.42168-1-liang.yang@amlogic.com>
 <f5a429f2-ffbc-ea03-810a-45a0f90959a2@baylibre.com>
 <6eb4f247-367b-d460-6314-fc94ccd00b89@amlogic.com>
 <1jy23226sa.fsf@starbuckisacylon.baylibre.com>
Message-ID: <27bf78f7-23b9-d759-28eb-0594006a30c6@amlogic.com>

Hi Jerome,

On 2022/1/26 17:14, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> 
> On Wed 26 Jan 2022 at 17:08, Liang Yang <liang.yang at amlogic.com> wrote:
> 
>> Hi Neil,
>>
>> On 2022/1/25 22:54, Neil Armstrong wrote:
>>> [ EXTERNAL EMAIL ]
>>> Hi Liang,
>>> On 21/01/2022 08:45, Liang Yang wrote:
>>>> This driver will add a MMC clock controller driver support.
>>>> The original idea about adding a clock controller is during the
>>>> discussion in the NAND driver mainline effort[1].
>>>>
>>>> This driver is tested in the S400 board (AXG platform) with NAND driver.
>>> Thanks a lot for providing a fixed and updated version of this serie.
>>> After some chat with Jerome and Kevin, it seems the way the eMMC clock
>>> reuse
>>> for NAND was designed nearly 4 years doesn't look accurate anymore.
>>> Having a separate clk driver designed to replace the eMMC node when NAND
>>> is
>>> used on the board seems over engineered.
>>> Actually having the clock code you add in this serie _but_ directly in
>>> the NAND looks far better, and more coherent since having Linux runtime
>>> detection of eMMC vs NAND will never happen and even this serie required
>>> some DT modification from the bootloader.
>>> I'll let Jerome or Kevin add more details if they want, but I think you
>>> should resurrect
>>> the work you pushed in [1] & [2] but:
>>> - passing the eMMC clk registers as a third "reg" cell
>> Does it just need to define a 'reg' resource in NFC node and not 'syscon'
>> here?
> 
> Yes
> 
>>> - passing the same "clocks" phandle as the eMMC node
>>> - adding the eMMC clock code in the NAND driver directly
>>> I'm open to discussions if you consider the current approach is still
>>> superior.
>>
>> I don't have persuasive ideas, but really it shares the common clock
>> implementation for both NFC and EMMC. and we don't need to paste the
>> same code in NFC and EMMC.
> 
> You don't need to copy everything. If I understood correctly, all the
> Rx/Tx should not be needed. Yes, there is some duplication as it stands but
> it allows to avoid coupling the MMC and NAND driver. We can still think
> about optimizing things later on. Let's get something simply working
> first.
ok. i will do it. thank you.
> 
>>
>>> Thanks,
>>> Neil
>>> [1]
>>> https://lore.kernel.org/r/20220106033130.37623-1-liang.yang at amlogic.com
>>> [2] https://lore.kernel.org/r/20220106032504.23310-1-liang.yang at amlogic.com
>>>
>>>>
>>>> Changes since v9 [10]
>>>>    - use clk_parent_data instead of parent_names
>>>>
>>>> Changes since v8 [9]
>>>>    - use MESON_SCLK_ONE_BASED instead of CLK_DIVIDER_ONE_BASED
>>>>    - use struct_size to caculate onecell_data
>>>>    - add clk-phase-delay.h
>>>>    - define CLK_DELAY_STEP_PS_GX and CLK_DELAY_STEP_PS_AXG
>>>>
>>>> Changes since v7 [8]
>>>>    - move meson_clk_get_phase_delay_data() from header to driver
>>>>    - CONFIG sclk-div with COMMON_CLK_AMLOGIC instead of COMMON_CLK_AMLOGIC_AUDIO
>>>>    - remove onecell date and ID for internal MUX clk
>>>>    - use helper for functions for ONE_BASED in sclk-div
>>>>    - add ONE_BASED support for duty cycle
>>>>
>>>> Changes since v6 [7]:
>>>>    - add one based support for sclk divier
>>>>    - alloc sclk in probe for multiple instance
>>>>    - fix coding styles
>>>>
>>>> Changes since v5 [6]:
>>>>    - remove divider ops with .init and use sclk_div instead
>>>>    - drop CLK_DIVIDER_ROUND_CLOSEST in mux and div
>>>>    - drop the useless type cast
>>>>
>>>> Changes since v4 [5]:
>>>>    - use struct parm in phase delay driver
>>>>    - remove 0 delay releted part in phase delay driver
>>>>    - don't rebuild the parent name once again
>>>>    - add divider ops with .init
>>>>
>>>> Changes since v3 [4]:
>>>>    - separate clk-phase-delay driver
>>>>    - replace clk_get_rate() with clk_hw_get_rate()
>>>>    - collect Rob's R-Y
>>>>    - drop 'meson-' prefix from compatible string
>>>>
>>>>    Changes since v2 [3]:
>>>>    - squash dt-binding clock-id patch
>>>>    - update license
>>>>    - fix alignment
>>>>    - construct a clk register helper() function
>>>>
>>>> Changes since v1 [2]:
>>>>    - implement phase clock
>>>>    - update compatible name
>>>>    - adjust file name
>>>>    - divider probe() into small functions, and re-use them
>>>>
>>>> [1] https://lkml.kernel.org/r/20180628090034.0637a062 at xps13
>>>> [2] https://lkml.kernel.org/r/20180703145716.31860-1-yixun.lan at amlogic.com
>>>> [3] https://lkml.kernel.org/r/20180710163658.6175-1-yixun.lan at amlogic.com
>>>> [4] https://lkml.kernel.org/r/20180712211244.11428-1-yixun.lan at amlogic.com
>>>> [5] https://lkml.kernel.org/r/20180809070724.11935-4-yixun.lan at amlogic.com
>>>> [6] https://lkml.kernel.org/r/1539839245-13793-1-git-send-email-jianxin.pan at amlogic.com
>>>> [7] https://lkml.kernel.org/r/1541089855-19356-1-git-send-email-jianxin.pan at amlogic.com
>>>> [8] https://lkml.kernel.org/r/1544457877-51301-1-git-send-email-jianxin.pan at amlogic.com
>>>> [9] https://lkml.kernel.org/r/1545063850-21504-1-git-send-email-jianxin.pan at amlogic.com
>>>> [10] https://lore.kernel.org/all/20220113115745.45826-1-liang.yang at amlogic.com/
>>>> Liang Yang (4):
>>>>     clk: meson: add one based divider support for sclk
>>>>     clk: meson: add emmc sub clock phase delay driver
>>>>     clk: meson: add DT documentation for emmc clock controller
>>>>     clk: meson: add sub MMC clock controller driver
>>>>
>>>>    .../bindings/clock/amlogic,mmc-clkc.yaml      |  64 ++++
>>>>    drivers/clk/meson/Kconfig                     |  18 ++
>>>>    drivers/clk/meson/Makefile                    |   2 +
>>>>    drivers/clk/meson/clk-phase-delay.c           |  69 ++++
>>>>    drivers/clk/meson/clk-phase-delay.h           |  20 ++
>>>>    drivers/clk/meson/mmc-clkc.c                  | 302 ++++++++++++++++++
>>>>    drivers/clk/meson/sclk-div.c                  |  59 ++--
>>>>    drivers/clk/meson/sclk-div.h                  |   3 +
>>>>    include/dt-bindings/clock/amlogic,mmc-clkc.h  |  14 +
>>>>    9 files changed, 529 insertions(+), 22 deletions(-)
>>>>    create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>>>>    create mode 100644 drivers/clk/meson/clk-phase-delay.c
>>>>    create mode 100644 drivers/clk/meson/clk-phase-delay.h
>>>>    create mode 100644 drivers/clk/meson/mmc-clkc.c
>>>>    create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
>>>>
>>> .
> 
> .


From linmq006 at gmail.com  Wed Jan 26 03:04:47 2022
From: linmq006 at gmail.com (Miaoqian Lin)
Date: Wed, 26 Jan 2022 11:04:47 +0000
Subject: [PATCH] spi: meson-spicc: add IRQ check in meson_spicc_probe
Message-ID: <20220126110447.24549-1-linmq006@gmail.com>

This check misses checking for  platform_get_irq()'s call and may passes
the negative error codes to devm_request_irq(), which takes unsigned IRQ #,
causing it to fail with -EINVAL, overriding an original error code.
Stop calling devm_request_irq() with invalid IRQ #s.

Fixes: 454fa271bc4e ("spi: Add Meson SPICC driver")
Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
---
 drivers/spi/spi-meson-spicc.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c
index c208efeadd18..0bc7daa7afc8 100644
--- a/drivers/spi/spi-meson-spicc.c
+++ b/drivers/spi/spi-meson-spicc.c
@@ -693,6 +693,11 @@ static int meson_spicc_probe(struct platform_device *pdev)
 	writel_relaxed(0, spicc->base + SPICC_INTREG);
 
 	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		ret = irq;
+		goto out_master;
+	}
+
 	ret = devm_request_irq(&pdev->dev, irq, meson_spicc_irq,
 			       0, NULL, spicc);
 	if (ret) {
-- 
2.17.1



From broonie at kernel.org  Wed Jan 26 07:36:52 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:36:52 +0000
Subject: [PATCH] spi: meson-spicc: add IRQ check in meson_spicc_probe
In-Reply-To: <20220126110447.24549-1-linmq006@gmail.com>
References: <20220126110447.24549-1-linmq006@gmail.com>
Message-ID: <164321141213.490397.12590014811818910927.b4-ty@kernel.org>

On Wed, 26 Jan 2022 11:04:47 +0000, Miaoqian Lin wrote:
> This check misses checking for  platform_get_irq()'s call and may passes
> the negative error codes to devm_request_irq(), which takes unsigned IRQ #,
> causing it to fail with -EINVAL, overriding an original error code.
> Stop calling devm_request_irq() with invalid IRQ #s.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-linus

Thanks!

[1/1] spi: meson-spicc: add IRQ check in meson_spicc_probe
      commit: e937440f7fc444a3e3f1fb75ea65292d6f433a44

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From theleks at ko-hh.de  Wed Jan 26 15:43:25 2022
From: theleks at ko-hh.de (Lutz Koschorreck)
Date: Thu, 27 Jan 2022 00:43:25 +0100
Subject: [PATCH] arm64: dts: meson-sm1-odroid: use correct enable-gpio pin
 for tf-io regulator
Message-ID: <20220126234325.GA7363@odroid-VirtualBox>

The interrupt pin of the external ethernet phy is used, instead of the
enable-gpio pin of the tf-io regulator. The GPIOE_2 pin is located in
the gpio_ao bank.
Using open drain prevents reboot issues.

This causes phy interrupt problems at system startup.
[   76.645190] irq 36: nobody cared (try booting with the "irqpoll" option)
[   76.649617] CPU: 0 PID: 1416 Comm: irq/36-0.0:00 Not tainted 5.16.0 #2
[   76.649629] Hardware name: Hardkernel ODROID-HC4 (DT)
[   76.649635] Call trace:
[   76.649638]  dump_backtrace+0x0/0x1c8
[   76.649658]  show_stack+0x14/0x60
[   76.649667]  dump_stack_lvl+0x64/0x7c
[   76.649676]  dump_stack+0x14/0x2c
[   76.649683]  __report_bad_irq+0x38/0xe8
[   76.649695]  note_interrupt+0x220/0x3a0
[   76.649704]  handle_irq_event_percpu+0x58/0x88
[   76.649713]  handle_irq_event+0x44/0xd8
[   76.649721]  handle_fasteoi_irq+0xa8/0x130
[   76.649730]  generic_handle_domain_irq+0x38/0x58
[   76.649738]  gic_handle_irq+0x9c/0xb8
[   76.649747]  call_on_irq_stack+0x28/0x38
[   76.649755]  do_interrupt_handler+0x7c/0x80
[   76.649763]  el1_interrupt+0x34/0x80
[   76.649772]  el1h_64_irq_handler+0x14/0x20
[   76.649781]  el1h_64_irq+0x74/0x78
[   76.649788]  irq_finalize_oneshot.part.56+0x68/0xf8
[   76.649796]  irq_thread_fn+0x5c/0x98
[   76.649804]  irq_thread+0x13c/0x260
[   76.649812]  kthread+0x144/0x178
[   76.649822]  ret_from_fork+0x10/0x20
[   76.649830] handlers:
[   76.653170] [<0000000025a6cd31>] irq_default_primary_handler threaded [<0000000093580eb7>] phy_interrupt
[   76.661256] Disabling IRQ #36

Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")

Signed-off-by: Lutz Koschorreck <theleks at ko-hh.de>
---
 arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
index 0bd1e98a0eef..ddb1b345397f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
@@ -48,7 +48,7 @@ tf_io: gpio-regulator-tf_io {
 		regulator-max-microvolt = <3300000>;
 		vin-supply = <&vcc_5v>;
 
-		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
+		enable-gpio = <&gpio_ao GPIOE_2 GPIO_OPEN_DRAIN>;
 		enable-active-high;
 		regulator-always-on;
 
-- 
2.25.1



From vkoul at kernel.org  Wed Jan 26 22:27:07 2022
From: vkoul at kernel.org (Vinod Koul)
Date: Thu, 27 Jan 2022 11:57:07 +0530
Subject: [PATCH v6 0/3] phy: amlogic: fix shared reset control use
In-Reply-To: <20220111095255.176141-1-aouledameur@baylibre.com>
References: <20220111095255.176141-1-aouledameur@baylibre.com>
Message-ID: <YfI7O5EvRI+m+QAj@matsya>

On 11-01-22, 10:52, Amjad Ouled-Ameur wrote:
> This patchset fixes a usb suspend warning seen on the libretech-cc by
> using reset_control_rearm() call of the reset framework API. 
> This call allows a reset consummer to release the reset line even when 
> just triggered so that it may be triggered again by other reset
> consummers.
> 
> reset_control_(de)assert() calls are called, in some meson usb drivers, 
> on a shared reset line when reset_control_reset has been used. This is not
> allowed by the reset framework.
> 
> Finally the meson usb drivers are updated to use this new call, which
> solves the suspend issue addressed by the previous reverted 
> commit 7a410953d1fb ("usb: dwc3: meson-g12a: fix shared reset control
> use").

Applied, thanks

-- 
~Vinod


From narmstrong at baylibre.com  Thu Jan 27 02:15:12 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 11:15:12 +0100
Subject: [PATCH] arm64: dts: meson-sm1-odroid: use correct enable-gpio pin
 for tf-io regulator
In-Reply-To: <20220126234325.GA7363@odroid-VirtualBox>
References: <20220126234325.GA7363@odroid-VirtualBox>
Message-ID: <651adde5-4887-4701-5183-6a35a443574c@baylibre.com>

Hi,

On 27/01/2022 00:43, Lutz Koschorreck wrote:
> The interrupt pin of the external ethernet phy is used, instead of the
> enable-gpio pin of the tf-io regulator. The GPIOE_2 pin is located in
> the gpio_ao bank.
> Using open drain prevents reboot issues.
> 
> This causes phy interrupt problems at system startup.
> [   76.645190] irq 36: nobody cared (try booting with the "irqpoll" option)
> [   76.649617] CPU: 0 PID: 1416 Comm: irq/36-0.0:00 Not tainted 5.16.0 #2
> [   76.649629] Hardware name: Hardkernel ODROID-HC4 (DT)
> [   76.649635] Call trace:
> [   76.649638]  dump_backtrace+0x0/0x1c8
> [   76.649658]  show_stack+0x14/0x60
> [   76.649667]  dump_stack_lvl+0x64/0x7c
> [   76.649676]  dump_stack+0x14/0x2c
> [   76.649683]  __report_bad_irq+0x38/0xe8
> [   76.649695]  note_interrupt+0x220/0x3a0
> [   76.649704]  handle_irq_event_percpu+0x58/0x88
> [   76.649713]  handle_irq_event+0x44/0xd8
> [   76.649721]  handle_fasteoi_irq+0xa8/0x130
> [   76.649730]  generic_handle_domain_irq+0x38/0x58
> [   76.649738]  gic_handle_irq+0x9c/0xb8
> [   76.649747]  call_on_irq_stack+0x28/0x38
> [   76.649755]  do_interrupt_handler+0x7c/0x80
> [   76.649763]  el1_interrupt+0x34/0x80
> [   76.649772]  el1h_64_irq_handler+0x14/0x20
> [   76.649781]  el1h_64_irq+0x74/0x78
> [   76.649788]  irq_finalize_oneshot.part.56+0x68/0xf8
> [   76.649796]  irq_thread_fn+0x5c/0x98
> [   76.649804]  irq_thread+0x13c/0x260
> [   76.649812]  kthread+0x144/0x178
> [   76.649822]  ret_from_fork+0x10/0x20
> [   76.649830] handlers:
> [   76.653170] [<0000000025a6cd31>] irq_default_primary_handler threaded [<0000000093580eb7>] phy_interrupt
> [   76.661256] Disabling IRQ #36
> 
> Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
> 
> Signed-off-by: Lutz Koschorreck <theleks at ko-hh.de>
> ---
>  arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> index 0bd1e98a0eef..ddb1b345397f 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> @@ -48,7 +48,7 @@ tf_io: gpio-regulator-tf_io {
>  		regulator-max-microvolt = <3300000>;
>  		vin-supply = <&vcc_5v>;
>  
> -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_OPEN_DRAIN>;

Wow, indeed it's not the right GPIO chip... my bad.

>  		enable-active-high;
>  		regulator-always-on;
>  

Concerning the GPIO_OPEN_DRAIN, it's right since the line has a pull-up, does it really fix reboot issues ?

Anyway, can you split the changes ? First for gpio_ao, second for GPIO_OPEN_DRAIN ?

Neil



From narmstrong at baylibre.com  Thu Jan 27 02:44:25 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 11:44:25 +0100
Subject: [PATCH 1/3] arm64: dts: meson-gx: add ATF BL32 reserved-memory
 region
In-Reply-To: <a279c365-0615-1c7f-5596-dec9ad1c8229@lexina.in>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
 <20220126044954.19069-2-christianshewitt@gmail.com>
 <a279c365-0615-1c7f-5596-dec9ad1c8229@lexina.in>
Message-ID: <3924894b-d479-7ec2-ff68-b830137f3b79@baylibre.com>

Hi,

On 26/01/2022 06:35, Vyacheslav wrote:
> Hi!
> 
> 26.01.2022 07:49, Christian Hewitt wrote:
>> Add an additional reserved memory region for the BL32 trusted firmware
>> present in many devices that boot from Amlogic vendor u-boot.
>>
>> Suggested-by: Mateusz Krzak <kszaquitto at gmail.com>
>> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
>> ---
>> ? arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 6 ++++++
>> ? 1 file changed, 6 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
>> index 6b457b2c30a4..aa14ea017a61 100644
>> --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
>> +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
>> @@ -49,6 +49,12 @@
>> ????????????? no-map;
>> ????????? };
>> ? +??????? /* 32 MiB reserved for ARM Trusted Firmware (BL32) */
>> +??????? secmon_reserved_bl32: secmon at 5300000 {
>> +??????????? reg = <0x0 0x05300000 0x0 0x2000000>;
>> +??????????? no-map;
>> +??????? };
>> +
> How do I check if we need a similar patch for axg boards?
> 
> 
>> ????????? linux,cma {
>> ????????????? compatible = "shared-dma-pool";
>> ????????????? reusable;
>>
> 

For AXG board with BL32 booting from vendor u-boot, yes.

Neil


From narmstrong at baylibre.com  Thu Jan 27 02:46:08 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 11:46:08 +0100
Subject: [PATCH 1/3] arm64: dts: meson-gx: add ATF BL32 reserved-memory
 region
In-Reply-To: <20220126044954.19069-2-christianshewitt@gmail.com>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
 <20220126044954.19069-2-christianshewitt@gmail.com>
Message-ID: <517ef196-e622-7ed5-c3be-55ac3f054b74@baylibre.com>

On 26/01/2022 05:49, Christian Hewitt wrote:
> Add an additional reserved memory region for the BL32 trusted firmware
> present in many devices that boot from Amlogic vendor u-boot.
> 
> Suggested-by: Mateusz Krzak <kszaquitto at gmail.com>
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> index 6b457b2c30a4..aa14ea017a61 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> @@ -49,6 +49,12 @@
>  			no-map;
>  		};
>  
> +		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
> +		secmon_reserved_bl32: secmon at 5300000 {
> +			reg = <0x0 0x05300000 0x0 0x2000000>;
> +			no-map;
> +		};
> +
>  		linux,cma {
>  			compatible = "shared-dma-pool";
>  			reusable;
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From narmstrong at baylibre.com  Thu Jan 27 02:46:19 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 11:46:19 +0100
Subject: [PATCH 2/3] arm64: dts: meson-g12: add ATF BL32 reserved-memory
 region
In-Reply-To: <20220126044954.19069-3-christianshewitt@gmail.com>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
 <20220126044954.19069-3-christianshewitt@gmail.com>
Message-ID: <af845f03-6bd4-cc78-2b7c-a32257f8773f@baylibre.com>

On 26/01/2022 05:49, Christian Hewitt wrote:
> Add an additional reserved memory region for the BL32 trusted firmware
> present in many devices that boot from Amlogic vendor u-boot.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> index 6d99c23261fb..45947c1031c4 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> @@ -107,6 +107,12 @@
>  			no-map;
>  		};
>  
> +		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
> +		secmon_reserved_bl32: secmon at 5300000 {
> +			reg = <0x0 0x05300000 0x0 0x2000000>;
> +			no-map;
> +		};
> +
>  		linux,cma {
>  			compatible = "shared-dma-pool";
>  			reusable;
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From narmstrong at baylibre.com  Thu Jan 27 02:46:33 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 11:46:33 +0100
Subject: [PATCH 3/3] arm64: dts: meson-g12: drop BL32 region from
 SEI510/SEI610
In-Reply-To: <20220126044954.19069-4-christianshewitt@gmail.com>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
 <20220126044954.19069-4-christianshewitt@gmail.com>
Message-ID: <cea820b0-5ca6-4a34-3d57-92e593785001@baylibre.com>

On 26/01/2022 05:49, Christian Hewitt wrote:
> The BL32/TEE reserved-memory region is now inherited from the common
> family dtsi (meson-g12-common) so we can drop it from board files.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts | 8 --------
>  arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts  | 8 --------
>  2 files changed, 16 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
> index d8838dde0f0f..4fb31c2ba31c 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
> @@ -157,14 +157,6 @@
>  		regulator-always-on;
>  	};
>  
> -	reserved-memory {
> -		/* TEE Reserved Memory */
> -		bl32_reserved: bl32 at 5000000 {
> -			reg = <0x0 0x05300000 0x0 0x2000000>;
> -			no-map;
> -		};
> -	};
> -
>  	sdio_pwrseq: sdio-pwrseq {
>  		compatible = "mmc-pwrseq-simple";
>  		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
> index 427475846fc7..a5d79f2f7c19 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
> @@ -203,14 +203,6 @@
>  		regulator-always-on;
>  	};
>  
> -	reserved-memory {
> -		/* TEE Reserved Memory */
> -		bl32_reserved: bl32 at 5000000 {
> -			reg = <0x0 0x05300000 0x0 0x2000000>;
> -			no-map;
> -		};
> -	};
> -
>  	sdio_pwrseq: sdio-pwrseq {
>  		compatible = "mmc-pwrseq-simple";
>  		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From tobetter at gmail.com  Thu Jan 27 04:25:46 2022
From: tobetter at gmail.com (Dongjin Kim)
Date: Thu, 27 Jan 2022 21:25:46 +0900
Subject: [PATCH] arm64: dts: meson-sm1: fix wrong GPIO domain for GPIOE_2
Message-ID: <YfKPSvnFKOaLr74+@anyang>

GPIOE_2 is in AO domain and "<&gpio GPIOE_2 ...>" changes the state of
GPIOZ_14 connected to INTR of 'RTL8211F' on ODROID-HC and TF_PWR_EN of
'FC8731' on BPI-M5

Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
Fixes: 976e920183e4 ("arm64: dts: meson-sm1: add Banana PI BPI-M5 board dts")

Signed-off-by: Dongjin Kim <tobetter at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts | 2 +-
 arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
index 212c6aa5a3b8..5751c48620ed 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
@@ -123,7 +123,7 @@ vddio_c: regulator-vddio_c {
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <3300000>;
 
-		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
+		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
 		enable-active-high;
 		regulator-always-on;
 
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
index bf29afac645f..d4349b355e4a 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
@@ -52,7 +52,7 @@ tf_io: gpio-regulator-tf_io {
 		regulator-max-microvolt = <3300000>;
 		vin-supply = <&vcc_5v>;
 
-		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
+		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
 		enable-active-high;
 		regulator-always-on;
 
-- 
2.32.0



From tobetter at gmail.com  Thu Jan 27 04:29:25 2022
From: tobetter at gmail.com (Dongjin Kim)
Date: Thu, 27 Jan 2022 21:29:25 +0900
Subject: [PATCH] arm64: dts: meson-g12b-odroid-n2: fix typo 'dio2133'
Message-ID: <YfKQJejh0bfGYvof@anyang>

Typo in audio amplifier node, dioo2133 -> dio2133

Signed-off-by: Dongjin Kim <tobetter at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
index aa5898a58b89..120f2551a28b 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
@@ -22,7 +22,7 @@ aliases {
 		spi0 = &spicc0;
 	};
 
-	dioo2133: audio-amplifier-0 {
+	dio2133: audio-amplifier-0 {
 		compatible = "simple-audio-amplifier";
 		enable-gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>;
 		VCC-supply = <&vcc_5v>;
@@ -222,7 +222,7 @@ sound {
 		audio-widgets = "Line", "Lineout";
 		audio-aux-devs = <&tdmout_b>, <&tdmout_c>, <&tdmin_a>,
 				 <&tdmin_b>, <&tdmin_c>, <&tdmin_lb>,
-				 <&dioo2133>;
+				 <&dio2133>;
 		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
 				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
 				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
-- 
2.32.0



From theleks at ko-hh.de  Thu Jan 27 04:38:14 2022
From: theleks at ko-hh.de (Lutz Koschorreck)
Date: Thu, 27 Jan 2022 13:38:14 +0100
Subject: [PATCH] arm64: dts: meson-sm1-odroid: use correct enable-gpio
 pin for tf-io regulator
In-Reply-To: <651adde5-4887-4701-5183-6a35a443574c@baylibre.com>
References: <20220126234325.GA7363@odroid-VirtualBox>
 <651adde5-4887-4701-5183-6a35a443574c@baylibre.com>
Message-ID: <20220127123814.GA152653@odroid-VirtualBox>

On Thu, Jan 27, 2022 at 11:15:12AM +0100, Neil Armstrong wrote:
> Hi,
> 
> On 27/01/2022 00:43, Lutz Koschorreck wrote:
> > The interrupt pin of the external ethernet phy is used, instead of the
> > enable-gpio pin of the tf-io regulator. The GPIOE_2 pin is located in
> > the gpio_ao bank.
> > Using open drain prevents reboot issues.
> > 
> > This causes phy interrupt problems at system startup.
> > [   76.645190] irq 36: nobody cared (try booting with the "irqpoll" option)
> > [   76.649617] CPU: 0 PID: 1416 Comm: irq/36-0.0:00 Not tainted 5.16.0 #2
> > [   76.649629] Hardware name: Hardkernel ODROID-HC4 (DT)
> > [   76.649635] Call trace:
> > [   76.649638]  dump_backtrace+0x0/0x1c8
> > [   76.649658]  show_stack+0x14/0x60
> > [   76.649667]  dump_stack_lvl+0x64/0x7c
> > [   76.649676]  dump_stack+0x14/0x2c
> > [   76.649683]  __report_bad_irq+0x38/0xe8
> > [   76.649695]  note_interrupt+0x220/0x3a0
> > [   76.649704]  handle_irq_event_percpu+0x58/0x88
> > [   76.649713]  handle_irq_event+0x44/0xd8
> > [   76.649721]  handle_fasteoi_irq+0xa8/0x130
> > [   76.649730]  generic_handle_domain_irq+0x38/0x58
> > [   76.649738]  gic_handle_irq+0x9c/0xb8
> > [   76.649747]  call_on_irq_stack+0x28/0x38
> > [   76.649755]  do_interrupt_handler+0x7c/0x80
> > [   76.649763]  el1_interrupt+0x34/0x80
> > [   76.649772]  el1h_64_irq_handler+0x14/0x20
> > [   76.649781]  el1h_64_irq+0x74/0x78
> > [   76.649788]  irq_finalize_oneshot.part.56+0x68/0xf8
> > [   76.649796]  irq_thread_fn+0x5c/0x98
> > [   76.649804]  irq_thread+0x13c/0x260
> > [   76.649812]  kthread+0x144/0x178
> > [   76.649822]  ret_from_fork+0x10/0x20
> > [   76.649830] handlers:
> > [   76.653170] [<0000000025a6cd31>] irq_default_primary_handler threaded [<0000000093580eb7>] phy_interrupt
> > [   76.661256] Disabling IRQ #36
> > 
> > Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
> > 
> > Signed-off-by: Lutz Koschorreck <theleks at ko-hh.de>
> > ---
> >  arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > index 0bd1e98a0eef..ddb1b345397f 100644
> > --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > @@ -48,7 +48,7 @@ tf_io: gpio-regulator-tf_io {
> >  		regulator-max-microvolt = <3300000>;
> >  		vin-supply = <&vcc_5v>;
> >  
> > -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> > +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_OPEN_DRAIN>;
> 
> Wow, indeed it's not the right GPIO chip... my bad.
> 
> >  		enable-active-high;
> >  		regulator-always-on;
> >  
> 
> Concerning the GPIO_OPEN_DRAIN, it's right since the line has a pull-up, does it really fix reboot issues ?
There is a 10k pull up on the pin of C4 and HC4. Therefore it is fine to
set to GPIO_OPEN_DRAIN. If this pin is left ACTIVE_HIGH and I call
reboot, the bootloader is does not came up, it is an boot loop. Tobetter
fixed that with a reset device driver, but I think using GPIO_OPEN_DRAIN
is the right solution.
> 
> Anyway, can you split the changes ? First for gpio_ao, second for GPIO_OPEN_DRAIN ?
Yes of cause. I will generate a new patch set.
> 
> Neil
> 
> 
> _______________________________________________
> linux-amlogic mailing list
> linux-amlogic at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-amlogic


From narmstrong at baylibre.com  Thu Jan 27 04:59:19 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 13:59:19 +0100
Subject: [PATCH] arm64: dts: meson-g12b-odroid-n2: fix typo 'dio2133'
In-Reply-To: <YfKQJejh0bfGYvof@anyang>
References: <YfKQJejh0bfGYvof@anyang>
Message-ID: <51093ba3-b562-d2de-07ef-e4af8dfdffac@baylibre.com>

On 27/01/2022 13:29, Dongjin Kim wrote:
> Typo in audio amplifier node, dioo2133 -> dio2133
>

Fixes: ef599f5f3e10 ("arm64: dts: meson: convert ODROID-N2 to dtsi")
Fixes: 67d141c1f8e6 ("arm64: dts: meson: odroid-n2: add jack audio output support")

> Signed-off-by: Dongjin Kim <tobetter at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
> index aa5898a58b89..120f2551a28b 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
> @@ -22,7 +22,7 @@ aliases {
>  		spi0 = &spicc0;
>  	};
>  
> -	dioo2133: audio-amplifier-0 {
> +	dio2133: audio-amplifier-0 {
>  		compatible = "simple-audio-amplifier";
>  		enable-gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>;
>  		VCC-supply = <&vcc_5v>;
> @@ -222,7 +222,7 @@ sound {
>  		audio-widgets = "Line", "Lineout";
>  		audio-aux-devs = <&tdmout_b>, <&tdmout_c>, <&tdmin_a>,
>  				 <&tdmin_b>, <&tdmin_c>, <&tdmin_lb>,
> -				 <&dioo2133>;
> +				 <&dio2133>;
>  		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
>  				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
>  				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From narmstrong at baylibre.com  Thu Jan 27 05:00:11 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 14:00:11 +0100
Subject: [PATCH] arm64: dts: meson-sm1: fix wrong GPIO domain for GPIOE_2
In-Reply-To: <YfKPSvnFKOaLr74+@anyang>
References: <YfKPSvnFKOaLr74+@anyang>
Message-ID: <dcb67b4e-6a46-86a6-b21f-99263cc9ff05@baylibre.com>

Hi,

On 27/01/2022 13:25, Dongjin Kim wrote:
> GPIOE_2 is in AO domain and "<&gpio GPIOE_2 ...>" changes the state of
> GPIOZ_14 connected to INTR of 'RTL8211F' on ODROID-HC and TF_PWR_EN of
> 'FC8731' on BPI-M5
> 
> Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
> Fixes: 976e920183e4 ("arm64: dts: meson-sm1: add Banana PI BPI-M5 board dts")
> 
> Signed-off-by: Dongjin Kim <tobetter at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts | 2 +-
>  arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi     | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> index 212c6aa5a3b8..5751c48620ed 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> @@ -123,7 +123,7 @@ vddio_c: regulator-vddio_c {
>  		regulator-min-microvolt = <1800000>;
>  		regulator-max-microvolt = <3300000>;
>  
> -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
>  		enable-active-high;
>  		regulator-always-on;
>  
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> index bf29afac645f..d4349b355e4a 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> @@ -52,7 +52,7 @@ tf_io: gpio-regulator-tf_io {
>  		regulator-max-microvolt = <3300000>;
>  		vin-supply = <&vcc_5v>;
>  
> -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
>  		enable-active-high;
>  		regulator-always-on;
>  
> 
Thanks for the fixes,
can you send 2 patches fixing each files instead ?

Thanks,
Neil


From theleks at ko-hh.de  Thu Jan 27 05:05:37 2022
From: theleks at ko-hh.de (Lutz Koschorreck)
Date: Thu, 27 Jan 2022 14:05:37 +0100
Subject: [PATCH v2] arm64: dts: meson-sm1-odroid: use correct enable-gpio pin
 for tf-io regulator
Message-ID: <20220127130537.GA187347@odroid-VirtualBox>

The interrupt pin of the external ethernet phy is used, instead of the
enable-gpio pin of the tf-io regulator. The GPIOE_2 pin is located in
the gpio_ao bank.

This causes phy interrupt problems at system startup.
[   76.645190] irq 36: nobody cared (try booting with the "irqpoll" option)
[   76.649617] CPU: 0 PID: 1416 Comm: irq/36-0.0:00 Not tainted 5.16.0 #2
[   76.649629] Hardware name: Hardkernel ODROID-HC4 (DT)
[   76.649635] Call trace:
[   76.649638]  dump_backtrace+0x0/0x1c8
[   76.649658]  show_stack+0x14/0x60
[   76.649667]  dump_stack_lvl+0x64/0x7c
[   76.649676]  dump_stack+0x14/0x2c
[   76.649683]  __report_bad_irq+0x38/0xe8
[   76.649695]  note_interrupt+0x220/0x3a0
[   76.649704]  handle_irq_event_percpu+0x58/0x88
[   76.649713]  handle_irq_event+0x44/0xd8
[   76.649721]  handle_fasteoi_irq+0xa8/0x130
[   76.649730]  generic_handle_domain_irq+0x38/0x58
[   76.649738]  gic_handle_irq+0x9c/0xb8
[   76.649747]  call_on_irq_stack+0x28/0x38
[   76.649755]  do_interrupt_handler+0x7c/0x80
[   76.649763]  el1_interrupt+0x34/0x80
[   76.649772]  el1h_64_irq_handler+0x14/0x20
[   76.649781]  el1h_64_irq+0x74/0x78
[   76.649788]  irq_finalize_oneshot.part.56+0x68/0xf8
[   76.649796]  irq_thread_fn+0x5c/0x98
[   76.649804]  irq_thread+0x13c/0x260
[   76.649812]  kthread+0x144/0x178
[   76.649822]  ret_from_fork+0x10/0x20
[   76.649830] handlers:
[   76.653170] [<0000000025a6cd31>] irq_default_primary_handler threaded [<0000000093580eb7>] phy_interrupt
[   76.661256] Disabling IRQ #36

Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")

Signed-off-by: Lutz Koschorreck <theleks at ko-hh.de>

only gpio bank
---
 arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
index 0bd1e98a0eef..ed7cd5f53046 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
@@ -48,7 +48,7 @@ tf_io: gpio-regulator-tf_io {
 		regulator-max-microvolt = <3300000>;
 		vin-supply = <&vcc_5v>;
 
-		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
+		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
 		enable-active-high;
 		regulator-always-on;
 
-- 
2.25.1



From narmstrong at baylibre.com  Thu Jan 27 05:09:20 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 14:09:20 +0100
Subject: [PATCH v2] arm64: dts: meson-sm1-odroid: use correct enable-gpio
 pin for tf-io regulator
In-Reply-To: <20220127130537.GA187347@odroid-VirtualBox>
References: <20220127130537.GA187347@odroid-VirtualBox>
Message-ID: <af32f4e8-5ee2-9d16-3880-f681d1c3de6d@baylibre.com>

On 27/01/2022 14:05, Lutz Koschorreck wrote:
> The interrupt pin of the external ethernet phy is used, instead of the
> enable-gpio pin of the tf-io regulator. The GPIOE_2 pin is located in
> the gpio_ao bank.
> 
> This causes phy interrupt problems at system startup.
> [   76.645190] irq 36: nobody cared (try booting with the "irqpoll" option)
> [   76.649617] CPU: 0 PID: 1416 Comm: irq/36-0.0:00 Not tainted 5.16.0 #2
> [   76.649629] Hardware name: Hardkernel ODROID-HC4 (DT)
> [   76.649635] Call trace:
> [   76.649638]  dump_backtrace+0x0/0x1c8
> [   76.649658]  show_stack+0x14/0x60
> [   76.649667]  dump_stack_lvl+0x64/0x7c
> [   76.649676]  dump_stack+0x14/0x2c
> [   76.649683]  __report_bad_irq+0x38/0xe8
> [   76.649695]  note_interrupt+0x220/0x3a0
> [   76.649704]  handle_irq_event_percpu+0x58/0x88
> [   76.649713]  handle_irq_event+0x44/0xd8
> [   76.649721]  handle_fasteoi_irq+0xa8/0x130
> [   76.649730]  generic_handle_domain_irq+0x38/0x58
> [   76.649738]  gic_handle_irq+0x9c/0xb8
> [   76.649747]  call_on_irq_stack+0x28/0x38
> [   76.649755]  do_interrupt_handler+0x7c/0x80
> [   76.649763]  el1_interrupt+0x34/0x80
> [   76.649772]  el1h_64_irq_handler+0x14/0x20
> [   76.649781]  el1h_64_irq+0x74/0x78
> [   76.649788]  irq_finalize_oneshot.part.56+0x68/0xf8
> [   76.649796]  irq_thread_fn+0x5c/0x98
> [   76.649804]  irq_thread+0x13c/0x260
> [   76.649812]  kthread+0x144/0x178
> [   76.649822]  ret_from_fork+0x10/0x20
> [   76.649830] handlers:
> [   76.653170] [<0000000025a6cd31>] irq_default_primary_handler threaded [<0000000093580eb7>] phy_interrupt
> [   76.661256] Disabling IRQ #36
> 
> Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
> 
> Signed-off-by: Lutz Koschorreck <theleks at ko-hh.de>
> 
> only gpio bank

Spurious lines, will remove while applying

> ---
>  arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> index 0bd1e98a0eef..ed7cd5f53046 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> @@ -48,7 +48,7 @@ tf_io: gpio-regulator-tf_io {
>  		regulator-max-microvolt = <3300000>;
>  		vin-supply = <&vcc_5v>;
>  
> -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
>  		enable-active-high;
>  		regulator-always-on;
>  
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From tobetter at gmail.com  Thu Jan 27 06:53:38 2022
From: tobetter at gmail.com (Dongjin Kim)
Date: Thu, 27 Jan 2022 23:53:38 +0900
Subject: [PATCH] arm64: dts: meson-sm1: fix wrong GPIO domain for GPIOE_2
In-Reply-To: <dcb67b4e-6a46-86a6-b21f-99263cc9ff05@baylibre.com>
References: <YfKPSvnFKOaLr74+@anyang>
 <dcb67b4e-6a46-86a6-b21f-99263cc9ff05@baylibre.com>
Message-ID: <20220127145338.GB2417963@paju>

On Thu, Jan 27, 2022 at 02:00:11PM +0100, Neil Armstrong wrote:
> Hi,
> 
> On 27/01/2022 13:25, Dongjin Kim wrote:
> > GPIOE_2 is in AO domain and "<&gpio GPIOE_2 ...>" changes the state of
> > GPIOZ_14 connected to INTR of 'RTL8211F' on ODROID-HC and TF_PWR_EN of
> > 'FC8731' on BPI-M5
> > 
> > Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
> > Fixes: 976e920183e4 ("arm64: dts: meson-sm1: add Banana PI BPI-M5 board dts")
> > 
> > Signed-off-by: Dongjin Kim <tobetter at gmail.com>
> > ---
> >  arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts | 2 +-
> >  arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi     | 2 +-
> >  2 files changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> > index 212c6aa5a3b8..5751c48620ed 100644
> > --- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> > +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> > @@ -123,7 +123,7 @@ vddio_c: regulator-vddio_c {
> >  		regulator-min-microvolt = <1800000>;
> >  		regulator-max-microvolt = <3300000>;
> >  
> > -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> > +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
> >  		enable-active-high;
> >  		regulator-always-on;
> >  
> > diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > index bf29afac645f..d4349b355e4a 100644
> > --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > @@ -52,7 +52,7 @@ tf_io: gpio-regulator-tf_io {
> >  		regulator-max-microvolt = <3300000>;
> >  		vin-supply = <&vcc_5v>;
> >  
> > -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> > +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
> >  		enable-active-high;
> >  		regulator-always-on;
> >  
> > 
> Thanks for the fixes,
> can you send 2 patches fixing each files instead ?
> 
> Thanks,
> Neil

Sure.
By the way, I would drop a fix for 'meson-sm1-odroid.dtsi' since I found a
patch just now.
https://patchwork.kernel.org/project/linux-amlogic/patch/20220127130537.GA187347 at odroid-VirtualBox/

Thanks,
Dongjin.


From narmstrong at baylibre.com  Thu Jan 27 07:04:37 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 16:04:37 +0100
Subject: [PATCH] arm64: dts: meson-sm1: fix wrong GPIO domain for GPIOE_2
In-Reply-To: <20220127145338.GB2417963@paju>
References: <YfKPSvnFKOaLr74+@anyang>
 <dcb67b4e-6a46-86a6-b21f-99263cc9ff05@baylibre.com>
 <20220127145338.GB2417963@paju>
Message-ID: <ec1e087f-efee-fb02-9ae2-3039725538e4@baylibre.com>

Hi,

On 27/01/2022 15:53, Dongjin Kim wrote:
> On Thu, Jan 27, 2022 at 02:00:11PM +0100, Neil Armstrong wrote:
>> Hi,
>>
>> On 27/01/2022 13:25, Dongjin Kim wrote:
>>> GPIOE_2 is in AO domain and "<&gpio GPIOE_2 ...>" changes the state of
>>> GPIOZ_14 connected to INTR of 'RTL8211F' on ODROID-HC and TF_PWR_EN of
>>> 'FC8731' on BPI-M5
>>>
>>> Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
>>> Fixes: 976e920183e4 ("arm64: dts: meson-sm1: add Banana PI BPI-M5 board dts")
>>>
>>> Signed-off-by: Dongjin Kim <tobetter at gmail.com>
>>> ---
>>>  arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts | 2 +-
>>>  arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi     | 2 +-
>>>  2 files changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
>>> index 212c6aa5a3b8..5751c48620ed 100644
>>> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
>>> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
>>> @@ -123,7 +123,7 @@ vddio_c: regulator-vddio_c {
>>>  		regulator-min-microvolt = <1800000>;
>>>  		regulator-max-microvolt = <3300000>;
>>>  
>>> -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
>>> +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
>>>  		enable-active-high;
>>>  		regulator-always-on;
>>>  
>>> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
>>> index bf29afac645f..d4349b355e4a 100644
>>> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
>>> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
>>> @@ -52,7 +52,7 @@ tf_io: gpio-regulator-tf_io {
>>>  		regulator-max-microvolt = <3300000>;
>>>  		vin-supply = <&vcc_5v>;
>>>  
>>> -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
>>> +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
>>>  		enable-active-high;
>>>  		regulator-always-on;
>>>  
>>>
>> Thanks for the fixes,
>> can you send 2 patches fixing each files instead ?
>>
>> Thanks,
>> Neil
> 
> Sure.
> By the way, I would drop a fix for 'meson-sm1-odroid.dtsi' since I found a
> patch just now.
> https://patchwork.kernel.org/project/linux-amlogic/patch/20220127130537.GA187347 at odroid-VirtualBox/

Sure, you sent the v1 at the same time, and he just resend a new version.

Neil

> 
> Thanks,
> Dongjin.
> 



From tobetter at gmail.com  Thu Jan 27 07:16:56 2022
From: tobetter at gmail.com (Dongjin Kim)
Date: Fri, 28 Jan 2022 00:16:56 +0900
Subject: [PATCH] arm64: dts: meson-sm1-bananapi-m5: fix wrong GPIO domain for
 GPIOE_2
Message-ID: <20220127151656.GA2419733@paju>

GPIOE_2 is in AO domain and "<&gpio GPIOE_2 ...>" changes the state of
TF_PWR_EN of 'FC8731' on BPI-M5

Fixes: 976e920183e4 ("arm64: dts: meson-sm1: add Banana PI BPI-M5 board dts")

Signed-off-by: Dongjin Kim <tobetter at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
index 212c6aa5a3b8..5751c48620ed 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
@@ -123,7 +123,7 @@ vddio_c: regulator-vddio_c {
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <3300000>;
 
-		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
+		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
 		enable-active-high;
 		regulator-always-on;
 
-- 
2.25.1



From narmstrong at baylibre.com  Thu Jan 27 07:17:57 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 16:17:57 +0100
Subject: [PATCH] arm64: dts: meson-sm1-bananapi-m5: fix wrong GPIO domain
 for GPIOE_2
In-Reply-To: <20220127151656.GA2419733@paju>
References: <20220127151656.GA2419733@paju>
Message-ID: <6cd58652-f24e-3919-589f-d71eb0e8070f@baylibre.com>

On 27/01/2022 16:16, Dongjin Kim wrote:
> GPIOE_2 is in AO domain and "<&gpio GPIOE_2 ...>" changes the state of
> TF_PWR_EN of 'FC8731' on BPI-M5
> 
> Fixes: 976e920183e4 ("arm64: dts: meson-sm1: add Banana PI BPI-M5 board dts")
> 
> Signed-off-by: Dongjin Kim <tobetter at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> index 212c6aa5a3b8..5751c48620ed 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> @@ -123,7 +123,7 @@ vddio_c: regulator-vddio_c {
>  		regulator-min-microvolt = <1800000>;
>  		regulator-max-microvolt = <3300000>;
>  
> -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
>  		enable-active-high;
>  		regulator-always-on;
>  
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>

Thanks !

Neil


From liang.yang at amlogic.com  Fri Jan 28 03:32:35 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 28 Jan 2022 19:32:35 +0800
Subject: [PATCH v2 0/2] refine the NFC clock framework
Message-ID: <20220128113237.39996-1-liang.yang@amlogic.com>

Background firstly, 
EMMC and NAND has the same clock control register named 'SD_EMMC_CLOCK' which is
defined in EMMC port internally. bit0~5 of 'SD_EMMC_CLOCK' is the divider and
bit6~7 is the mux for fix pll and xtal.
Previously a common MMC sub clock framework is implemented and shared by EMMC and
NAND, but that is coupling the EMMC and NAND, although EMMC and NAND is mutually
exclusive. see the link:
[https://lore.kernel.org/all/1jy23226sa.fsf at starbuckisacylon.baylibre.com/]
Now we plan to abandon common mmc sub clock framework and recovery the series.

Changes since v1 [2]
 - use clk_parent_data instead of parent_names
 - define a reg resource instead of sd_emmc_c_clkc 
 
[1]
https://lore.kernel.org/r/20220106033130.37623-1-liang.yang at amlogic.com
https://lore.kernel.org/r/20220106032504.23310-1-liang.yang at amlogic.com
Liang Yang (2):
  mtd: rawnand: meson: discard the common MMC sub clock framework
  dt-bindings: nand: meson: refine Amlogic NAND controller driver

 .../bindings/mtd/amlogic,meson-nand.txt       |  60 -------
 .../bindings/mtd/amlogic,meson-nand.yaml      |  70 ++++++++
 drivers/mtd/nand/raw/meson_nand.c             | 161 ++++++++++--------
 3 files changed, 159 insertions(+), 132 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml

-- 
2.34.1



From liang.yang at amlogic.com  Fri Jan 28 03:32:36 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 28 Jan 2022 19:32:36 +0800
Subject: [PATCH v2 1/2] mtd: rawnand: meson: discard the common MMC sub clock
 framework
In-Reply-To: <20220128113237.39996-1-liang.yang@amlogic.com>
References: <20220128113237.39996-1-liang.yang@amlogic.com>
Message-ID: <20220128113237.39996-2-liang.yang@amlogic.com>

EMMC and NAND has the same clock control register named 'SD_EMMC_CLOCK' which is
defined in EMMC port internally. bit0~5 of 'SD_EMMC_CLOCK' is the divider and
bit6~7 is the mux for fix pll and xtal.
Previously a common MMC sub clock framework is implemented and shared by EMMC and
NAND, but that is coupling the EMMC and NAND, although EMMC and NAND is mutually
exclusive.

Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 drivers/mtd/nand/raw/meson_nand.c | 161 +++++++++++++++++-------------
 1 file changed, 89 insertions(+), 72 deletions(-)

diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
index ac3be92872d0..f6a3d5c2ea1c 100644
--- a/drivers/mtd/nand/raw/meson_nand.c
+++ b/drivers/mtd/nand/raw/meson_nand.c
@@ -2,7 +2,7 @@
 /*
  * Amlogic Meson Nand Flash Controller Driver
  *
- * Copyright (c) 2018 Amlogic, inc.
+ * Copyright (c) 2018-2021 Amlogic, inc.
  * Author: Liang Yang <liang.yang at amlogic.com>
  */
 
@@ -10,6 +10,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/mtd/rawnand.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mfd/syscon.h>
@@ -19,6 +20,7 @@
 #include <linux/iopoll.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_address.h>
 #include <linux/sched/task_stack.h>
 
 #define NFC_REG_CMD		0x00
@@ -104,6 +106,9 @@
 
 #define PER_INFO_BYTE		8
 
+#define CLK_DIV_SHIFT		0
+#define CLK_DIV_WIDTH		6
+
 struct meson_nfc_nand_chip {
 	struct list_head node;
 	struct nand_chip nand;
@@ -151,15 +156,17 @@ struct meson_nfc {
 	struct nand_controller controller;
 	struct clk *core_clk;
 	struct clk *device_clk;
-	struct clk *phase_tx;
-	struct clk *phase_rx;
+	struct clk *nand_clk;
+	struct clk_divider nand_divider;
 
 	unsigned long clk_rate;
 	u32 bus_timing;
 
 	struct device *dev;
-	void __iomem *reg_base;
-	struct regmap *reg_clk;
+	struct {
+		void __iomem *reg_base;
+		void __iomem *sd_emmc_clock;
+	} res;
 	struct completion completion;
 	struct list_head chips;
 	const struct meson_nfc_data *data;
@@ -244,8 +251,8 @@ static void meson_nfc_select_chip(struct nand_chip *nand, int chip)
 	}
 	if (nfc->bus_timing != meson_chip->bus_timing) {
 		value = (NFC_CLK_CYCLE - 1) | (meson_chip->bus_timing << 5);
-		writel(value, nfc->reg_base + NFC_REG_CFG);
-		writel((1 << 31), nfc->reg_base + NFC_REG_CMD);
+		writel(value, nfc->res.reg_base + NFC_REG_CFG);
+		writel((1 << 31), nfc->res.reg_base + NFC_REG_CMD);
 		nfc->bus_timing =  meson_chip->bus_timing;
 	}
 }
@@ -253,13 +260,13 @@ static void meson_nfc_select_chip(struct nand_chip *nand, int chip)
 static void meson_nfc_cmd_idle(struct meson_nfc *nfc, u32 time)
 {
 	writel(nfc->param.chip_select | NFC_CMD_IDLE | (time & 0x3ff),
-	       nfc->reg_base + NFC_REG_CMD);
+	       nfc->res.reg_base + NFC_REG_CMD);
 }
 
 static void meson_nfc_cmd_seed(struct meson_nfc *nfc, u32 seed)
 {
 	writel(NFC_CMD_SEED | (0xc2 + (seed & 0x7fff)),
-	       nfc->reg_base + NFC_REG_CMD);
+	       nfc->res.reg_base + NFC_REG_CMD);
 }
 
 static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir,
@@ -276,7 +283,7 @@ static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir,
 	if (raw) {
 		len = mtd->writesize + mtd->oobsize;
 		cmd = (len & GENMASK(5, 0)) | scrambler | DMA_DIR(dir);
-		writel(cmd, nfc->reg_base + NFC_REG_CMD);
+		writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 		return;
 	}
 
@@ -285,7 +292,7 @@ static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir,
 	cmd = CMDRWGEN(DMA_DIR(dir), scrambler, bch,
 		       NFC_CMD_SHORTMODE_DISABLE, pagesize, pages);
 
-	writel(cmd, nfc->reg_base + NFC_REG_CMD);
+	writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 }
 
 static void meson_nfc_drain_cmd(struct meson_nfc *nfc)
@@ -312,7 +319,7 @@ static int meson_nfc_wait_cmd_finish(struct meson_nfc *nfc,
 	int ret;
 
 	/* wait cmd fifo is empty */
-	ret = readl_relaxed_poll_timeout(nfc->reg_base + NFC_REG_CMD, cmd_size,
+	ret = readl_relaxed_poll_timeout(nfc->res.reg_base + NFC_REG_CMD, cmd_size,
 					 !NFC_CMD_GET_SIZE(cmd_size),
 					 10, timeout_ms * 1000);
 	if (ret)
@@ -396,16 +403,16 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
 	meson_nfc_drain_cmd(nfc);
 	meson_nfc_wait_cmd_finish(nfc, CMD_FIFO_EMPTY_TIMEOUT);
 
-	cfg = readl(nfc->reg_base + NFC_REG_CFG);
+	cfg = readl(nfc->res.reg_base + NFC_REG_CFG);
 	cfg |= NFC_RB_IRQ_EN;
-	writel(cfg, nfc->reg_base + NFC_REG_CFG);
+	writel(cfg, nfc->res.reg_base + NFC_REG_CFG);
 
 	reinit_completion(&nfc->completion);
 
 	/* use the max erase time as the maximum clock for waiting R/B */
 	cmd = NFC_CMD_RB | NFC_CMD_RB_INT
 		| nfc->param.chip_select | nfc->timing.tbers_max;
-	writel(cmd, nfc->reg_base + NFC_REG_CMD);
+	writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 
 	ret = wait_for_completion_timeout(&nfc->completion,
 					  msecs_to_jiffies(timeout_ms));
@@ -485,10 +492,10 @@ static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf,
 		return ret;
 	}
 	cmd = GENCMDDADDRL(NFC_CMD_ADL, nfc->daddr);
-	writel(cmd, nfc->reg_base + NFC_REG_CMD);
+	writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 
 	cmd = GENCMDDADDRH(NFC_CMD_ADH, nfc->daddr);
-	writel(cmd, nfc->reg_base + NFC_REG_CMD);
+	writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 
 	if (infobuf) {
 		nfc->iaddr = dma_map_single(nfc->dev, infobuf, infolen, dir);
@@ -500,10 +507,10 @@ static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf,
 			return ret;
 		}
 		cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr);
-		writel(cmd, nfc->reg_base + NFC_REG_CMD);
+		writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 
 		cmd = GENCMDIADDRH(NFC_CMD_AIH, nfc->iaddr);
-		writel(cmd, nfc->reg_base + NFC_REG_CMD);
+		writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 	}
 
 	return ret;
@@ -537,7 +544,7 @@ static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len)
 		goto out;
 
 	cmd = NFC_CMD_N2M | (len & GENMASK(5, 0));
-	writel(cmd, nfc->reg_base + NFC_REG_CMD);
+	writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 
 	meson_nfc_drain_cmd(nfc);
 	meson_nfc_wait_cmd_finish(nfc, 1000);
@@ -561,7 +568,7 @@ static int meson_nfc_write_buf(struct nand_chip *nand, u8 *buf, int len)
 		return ret;
 
 	cmd = NFC_CMD_M2N | (len & GENMASK(5, 0));
-	writel(cmd, nfc->reg_base + NFC_REG_CMD);
+	writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 
 	meson_nfc_drain_cmd(nfc);
 	meson_nfc_wait_cmd_finish(nfc, 1000);
@@ -610,11 +617,11 @@ static int meson_nfc_rw_cmd_prepare_and_execute(struct nand_chip *nand,
 
 	for (i = 0; i < cmd_num; i++)
 		writel_relaxed(nfc->cmdfifo.cmd[i],
-			       nfc->reg_base + NFC_REG_CMD);
+			       nfc->res.reg_base + NFC_REG_CMD);
 
 	if (in) {
 		nfc->cmdfifo.rw.cmd1 = cs | NFC_CMD_CLE | NAND_CMD_READSTART;
-		writel(nfc->cmdfifo.rw.cmd1, nfc->reg_base + NFC_REG_CMD);
+		writel(nfc->cmdfifo.rw.cmd1, nfc->res.reg_base + NFC_REG_CMD);
 		meson_nfc_queue_rb(nfc, PSEC_TO_MSEC(sdr->tR_max));
 	} else {
 		meson_nfc_cmd_idle(nfc, nfc->timing.tadl);
@@ -660,7 +667,7 @@ static int meson_nfc_write_page_sub(struct nand_chip *nand,
 	}
 
 	cmd = nfc->param.chip_select | NFC_CMD_CLE | NAND_CMD_PAGEPROG;
-	writel(cmd, nfc->reg_base + NFC_REG_CMD);
+	writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 	meson_nfc_queue_rb(nfc, PSEC_TO_MSEC(sdr->tPROG_max));
 
 	meson_nfc_dma_buffer_release(nand, data_len, info_len, DMA_TO_DEVICE);
@@ -912,7 +919,7 @@ static int meson_nfc_exec_op(struct nand_chip *nand,
 		case NAND_OP_CMD_INSTR:
 			cmd = nfc->param.chip_select | NFC_CMD_CLE;
 			cmd |= instr->ctx.cmd.opcode & 0xff;
-			writel(cmd, nfc->reg_base + NFC_REG_CMD);
+			writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 			meson_nfc_cmd_idle(nfc, delay_idle);
 			break;
 
@@ -920,7 +927,7 @@ static int meson_nfc_exec_op(struct nand_chip *nand,
 			for (i = 0; i < instr->ctx.addr.naddrs; i++) {
 				cmd = nfc->param.chip_select | NFC_CMD_ALE;
 				cmd |= instr->ctx.addr.addrs[i] & 0xff;
-				writel(cmd, nfc->reg_base + NFC_REG_CMD);
+				writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 			}
 			meson_nfc_cmd_idle(nfc, delay_idle);
 			break;
@@ -988,6 +995,8 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
 static int meson_nfc_clk_init(struct meson_nfc *nfc)
 {
 	int ret;
+	struct clk_init_data init = {0};
+	struct clk_parent_data nfc_divider_parent_data[1];
 
 	/* request core clock */
 	nfc->core_clk = devm_clk_get(nfc->dev, "core");
@@ -1002,21 +1011,26 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
 		return PTR_ERR(nfc->device_clk);
 	}
 
-	nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
-	if (IS_ERR(nfc->phase_tx)) {
-		dev_err(nfc->dev, "failed to get TX clk\n");
-		return PTR_ERR(nfc->phase_tx);
-	}
-
-	nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
-	if (IS_ERR(nfc->phase_rx)) {
-		dev_err(nfc->dev, "failed to get RX clk\n");
-		return PTR_ERR(nfc->phase_rx);
-	}
+	init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
+	init.ops = &clk_divider_ops;
+	nfc_divider_parent_data[0].fw_name = __clk_get_name(nfc->device_clk);
+	init.parent_data = nfc_divider_parent_data;
+	init.num_parents = 1;
+	nfc->nand_divider.reg = nfc->res.sd_emmc_clock;
+	nfc->nand_divider.shift = CLK_DIV_SHIFT;
+	nfc->nand_divider.width = CLK_DIV_WIDTH;
+	nfc->nand_divider.hw.init = &init;
+	nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
+				  CLK_DIVIDER_ROUND_CLOSEST |
+				  CLK_DIVIDER_ALLOW_ZERO;
+
+	nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
+	if (IS_ERR(nfc->nand_clk))
+		return PTR_ERR(nfc->nand_clk);
 
 	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
-	regmap_update_bits(nfc->reg_clk,
-			   0, CLK_SELECT_NAND, CLK_SELECT_NAND);
+	writel(CLK_SELECT_NAND | readl(nfc->res.sd_emmc_clock),
+	       nfc->res.sd_emmc_clock);
 
 	ret = clk_prepare_enable(nfc->core_clk);
 	if (ret) {
@@ -1030,29 +1044,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
 		goto err_device_clk;
 	}
 
-	ret = clk_prepare_enable(nfc->phase_tx);
-	if (ret) {
-		dev_err(nfc->dev, "failed to enable TX clock\n");
-		goto err_phase_tx;
-	}
-
-	ret = clk_prepare_enable(nfc->phase_rx);
+	ret = clk_prepare_enable(nfc->nand_clk);
 	if (ret) {
-		dev_err(nfc->dev, "failed to enable RX clock\n");
-		goto err_phase_rx;
+		dev_err(nfc->dev, "pre enable NFC divider fail\n");
+		goto err_nand_clk;
 	}
 
 	ret = clk_set_rate(nfc->device_clk, 24000000);
 	if (ret)
-		goto err_disable_rx;
+		goto err_disable_clk;
 
 	return 0;
 
-err_disable_rx:
-	clk_disable_unprepare(nfc->phase_rx);
-err_phase_rx:
-	clk_disable_unprepare(nfc->phase_tx);
-err_phase_tx:
+err_disable_clk:
+	clk_disable_unprepare(nfc->nand_clk);
+err_nand_clk:
 	clk_disable_unprepare(nfc->device_clk);
 err_device_clk:
 	clk_disable_unprepare(nfc->core_clk);
@@ -1061,8 +1067,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
 
 static void meson_nfc_disable_clk(struct meson_nfc *nfc)
 {
-	clk_disable_unprepare(nfc->phase_rx);
-	clk_disable_unprepare(nfc->phase_tx);
+	clk_disable_unprepare(nfc->nand_clk);
 	clk_disable_unprepare(nfc->device_clk);
 	clk_disable_unprepare(nfc->core_clk);
 }
@@ -1339,12 +1344,12 @@ static irqreturn_t meson_nfc_irq(int irq, void *id)
 	struct meson_nfc *nfc = id;
 	u32 cfg;
 
-	cfg = readl(nfc->reg_base + NFC_REG_CFG);
+	cfg = readl(nfc->res.reg_base + NFC_REG_CFG);
 	if (!(cfg & NFC_RB_IRQ_EN))
 		return IRQ_NONE;
 
 	cfg &= ~(NFC_RB_IRQ_EN);
-	writel(cfg, nfc->reg_base + NFC_REG_CFG);
+	writel(cfg, nfc->res.reg_base + NFC_REG_CFG);
 
 	complete(&nfc->completion);
 	return IRQ_HANDLED;
@@ -1370,11 +1375,31 @@ static const struct of_device_id meson_nfc_id_table[] = {
 };
 MODULE_DEVICE_TABLE(of, meson_nfc_id_table);
 
+static int meson_nfc_reg_resource(struct device *dev, struct meson_nfc *nfc)
+{
+	struct resource res;
+	void __iomem *base[2];
+	struct device_node *node = dev->of_node;
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		if (of_address_to_resource(node, i, &res))
+			return -ENOENT;
+
+		base[i] = devm_ioremap_resource(dev, &res);
+		if (IS_ERR(base))
+			return PTR_ERR(base);
+	}
+	nfc->res.reg_base = base[0];
+	nfc->res.sd_emmc_clock = base[1];
+
+	return 0;
+}
+
 static int meson_nfc_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct meson_nfc *nfc;
-	struct resource *res;
 	int ret, irq;
 
 	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
@@ -1388,20 +1413,12 @@ static int meson_nfc_probe(struct platform_device *pdev)
 	nand_controller_init(&nfc->controller);
 	INIT_LIST_HEAD(&nfc->chips);
 	init_completion(&nfc->completion);
-
 	nfc->dev = dev;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	nfc->reg_base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(nfc->reg_base))
-		return PTR_ERR(nfc->reg_base);
-
-	nfc->reg_clk =
-		syscon_regmap_lookup_by_phandle(dev->of_node,
-						"amlogic,mmc-syscon");
-	if (IS_ERR(nfc->reg_clk)) {
-		dev_err(dev, "Failed to lookup clock base\n");
-		return PTR_ERR(nfc->reg_clk);
+	ret = meson_nfc_reg_resource(dev, nfc);
+	if (ret) {
+		dev_err(dev, "Failed to get reg resource\n");
+		return ret;
 	}
 
 	irq = platform_get_irq(pdev, 0);
@@ -1414,7 +1431,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	writel(0, nfc->reg_base + NFC_REG_CFG);
+	writel(0, nfc->res.reg_base + NFC_REG_CFG);
 	ret = devm_request_irq(dev, irq, meson_nfc_irq, 0, dev_name(dev), nfc);
 	if (ret) {
 		dev_err(dev, "failed to request NFC IRQ\n");
-- 
2.34.1



From liang.yang at amlogic.com  Fri Jan 28 03:32:37 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 28 Jan 2022 19:32:37 +0800
Subject: [PATCH v2 2/2] dt-bindings: nand: meson: refine Amlogic NAND
 controller driver
In-Reply-To: <20220128113237.39996-1-liang.yang@amlogic.com>
References: <20220128113237.39996-1-liang.yang@amlogic.com>
Message-ID: <20220128113237.39996-3-liang.yang@amlogic.com>

convert txt to yaml and refine the meson NFC clock document.

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 .../bindings/mtd/amlogic,meson-nand.txt       | 60 ----------------
 .../bindings/mtd/amlogic,meson-nand.yaml      | 70 +++++++++++++++++++
 2 files changed, 70 insertions(+), 60 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml

diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
deleted file mode 100644
index 5794ab1147c1..000000000000
--- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-Amlogic NAND Flash Controller (NFC) for GXBB/GXL/AXG family SoCs
-
-This file documents the properties in addition to those available in
-the MTD NAND bindings.
-
-Required properties:
-- compatible : contains one of:
-  - "amlogic,meson-gxl-nfc"
-  - "amlogic,meson-axg-nfc"
-- clocks     :
-	A list of phandle + clock-specifier pairs for the clocks listed
-	in clock-names.
-
-- clock-names: Should contain the following:
-	"core" - NFC module gate clock
-	"device" - device clock from eMMC sub clock controller
-	"rx" - rx clock phase
-	"tx" - tx clock phase
-
-- amlogic,mmc-syscon	: Required for NAND clocks, it's shared with SD/eMMC
-				controller port C
-
-Optional children nodes:
-Children nodes represent the available nand chips.
-
-Other properties:
-see Documentation/devicetree/bindings/mtd/nand-controller.yaml for generic bindings.
-
-Example demonstrate on AXG SoC:
-
-	sd_emmc_c_clkc: mmc at 7000 {
-		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
-		reg = <0x0 0x7000 0x0 0x800>;
-	};
-
-	nand-controller at 7800 {
-		compatible = "amlogic,meson-axg-nfc";
-		reg = <0x0 0x7800 0x0 0x100>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
-
-		clocks = <&clkc CLKID_SD_EMMC_C>,
-			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
-			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
-			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
-		clock-names = "core", "device", "rx", "tx";
-		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
-
-		pinctrl-names = "default";
-		pinctrl-0 = <&nand_pins>;
-
-		nand at 0 {
-			reg = <0>;
-			#address-cells = <1>;
-			#size-cells = <1>;
-
-			nand-on-flash-bbt;
-		};
-	};
diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml
new file mode 100644
index 000000000000..671f0a8fdc7c
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,mmc-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic NAND Flash Controller (NFC) for GXBB/GXL/AXG family SoCs
+
+maintainers:
+  - liang.yang at amlogic.com
+
+properties:
+  compatible:
+    enum:
+      - "amlogic,meson-gxl-nfc"
+      - "amlogic,meson-axg-nfc"
+
+  reg:
+    maxItems: 2
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: "core", "device"
+
+  "#clock-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    nand-controller at 7800 {
+	compatible = "amlogic,meson-axg-nfc";
+	reg = <0x0 0x7800 0x0 0x100>,
+	      <0x0 0x7000 0x0 0x1>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
+
+	clocks = <&clkc CLKID_SD_EMMC_C>,
+		<&clkc CLKID_FCLK_DIV2>;
+	clock-names = "core", "device";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&nand_pins>;
+
+	nand at 0 {
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		nand-on-flash-bbt;
+	};
+     };
+
+...
\ No newline at end of file
-- 
2.34.1



From miquel.raynal at bootlin.com  Fri Jan 28 03:40:36 2022
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Fri, 28 Jan 2022 12:40:36 +0100
Subject: [PATCH v2 1/2] mtd: rawnand: meson: discard the common MMC sub
 clock framework
In-Reply-To: <20220128113237.39996-2-liang.yang@amlogic.com>
References: <20220128113237.39996-1-liang.yang@amlogic.com>
 <20220128113237.39996-2-liang.yang@amlogic.com>
Message-ID: <20220128124036.25fe0539@xps13>

Hi Liang,

liang.yang at amlogic.com wrote on Fri, 28 Jan 2022 19:32:36 +0800:

> EMMC and NAND has the same clock control register named 'SD_EMMC_CLOCK' which is

have

> defined in EMMC port internally. bit0~5 of 'SD_EMMC_CLOCK' is the divider and
> bit6~7 is the mux for fix pll and xtal.

> Previously a common MMC sub clock framework is implemented and shared by EMMC and

I believe you meant that this hasa already been contributed? I would
then rephrase with:

A common MMC and NAND sub-clock has been implemented and can be used by
the eMMC and NAND controller (which are mutually exclusive anyway).

Let's use this new clock.

> NAND, but that is coupling the EMMC and NAND, although EMMC and NAND is mutually
> exclusive.
> 
> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997

No change Ids.

> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
> ---
>  drivers/mtd/nand/raw/meson_nand.c | 161 +++++++++++++++++-------------
>  1 file changed, 89 insertions(+), 72 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
> index ac3be92872d0..f6a3d5c2ea1c 100644
> --- a/drivers/mtd/nand/raw/meson_nand.c
> +++ b/drivers/mtd/nand/raw/meson_nand.c
> @@ -2,7 +2,7 @@
>  /*
>   * Amlogic Meson Nand Flash Controller Driver
>   *
> - * Copyright (c) 2018 Amlogic, inc.
> + * Copyright (c) 2018-2021 Amlogic, inc.

Please don't.

>   * Author: Liang Yang <liang.yang at amlogic.com>
>   */
>  
> @@ -10,6 +10,7 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/interrupt.h>
>  #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>  #include <linux/mtd/rawnand.h>
>  #include <linux/mtd/mtd.h>
>  #include <linux/mfd/syscon.h>
> @@ -19,6 +20,7 @@
>  #include <linux/iopoll.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
> +#include <linux/of_address.h>
>  #include <linux/sched/task_stack.h>
>  
>  #define NFC_REG_CMD		0x00
> @@ -104,6 +106,9 @@
>  
>  #define PER_INFO_BYTE		8
>  
> +#define CLK_DIV_SHIFT		0
> +#define CLK_DIV_WIDTH		6
> +
>  struct meson_nfc_nand_chip {
>  	struct list_head node;
>  	struct nand_chip nand;
> @@ -151,15 +156,17 @@ struct meson_nfc {
>  	struct nand_controller controller;
>  	struct clk *core_clk;
>  	struct clk *device_clk;
> -	struct clk *phase_tx;
> -	struct clk *phase_rx;
> +	struct clk *nand_clk;
> +	struct clk_divider nand_divider;
>  
>  	unsigned long clk_rate;
>  	u32 bus_timing;
>  
>  	struct device *dev;
> -	void __iomem *reg_base;
> -	struct regmap *reg_clk;
> +	struct {
> +		void __iomem *reg_base;
> +		void __iomem *sd_emmc_clock;
> +	} res;

Please split your commit: first the mechanical changes, then the use of
the new area or something like that.

Otherwise there are too many lines changed, I can't spot where it is
interesting.

Thanks,
Miqu?l


From liang.yang at amlogic.com  Fri Jan 28 04:16:26 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 28 Jan 2022 20:16:26 +0800
Subject: [PATCH v2 1/2] mtd: rawnand: meson: discard the common MMC sub
 clock framework
In-Reply-To: <20220128124036.25fe0539@xps13>
References: <20220128113237.39996-1-liang.yang@amlogic.com>
 <20220128113237.39996-2-liang.yang@amlogic.com>
 <20220128124036.25fe0539@xps13>
Message-ID: <e87b40f0-140e-0521-b861-7481cfc1507d@amlogic.com>

Hi Miquel,

Thanks for the review and quick response.

On 2022/1/28 19:40, Miquel Raynal wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi Liang,
> 
> liang.yang at amlogic.com wrote on Fri, 28 Jan 2022 19:32:36 +0800:
> 
>> EMMC and NAND has the same clock control register named 'SD_EMMC_CLOCK' which is
> 
> have
ok
> 
>> defined in EMMC port internally. bit0~5 of 'SD_EMMC_CLOCK' is the divider and
>> bit6~7 is the mux for fix pll and xtal.
> 
>> Previously a common MMC sub clock framework is implemented and shared by EMMC and
> 
> I believe you meant that this hasa already been contributed? I would
> then rephrase with:
> 
> A common MMC and NAND sub-clock has been implemented and can be used by
> the eMMC and NAND controller (which are mutually exclusive anyway).
> 
> Let's use this new clock.
ok. thanks
> 
>> NAND, but that is coupling the EMMC and NAND, although EMMC and NAND is mutually
>> exclusive.
>>
>> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
> 
> No change Ids.
ok. i will delete next version.
> 
>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>> ---
>>   drivers/mtd/nand/raw/meson_nand.c | 161 +++++++++++++++++-------------
>>   1 file changed, 89 insertions(+), 72 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>> index ac3be92872d0..f6a3d5c2ea1c 100644
>> --- a/drivers/mtd/nand/raw/meson_nand.c
>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>> @@ -2,7 +2,7 @@
>>   /*
>>    * Amlogic Meson Nand Flash Controller Driver
>>    *
>> - * Copyright (c) 2018 Amlogic, inc.
>> + * Copyright (c) 2018-2021 Amlogic, inc.
> 
> Please don't.
> 
>>    * Author: Liang Yang <liang.yang at amlogic.com>
>>    */
>>   
>> @@ -10,6 +10,7 @@
>>   #include <linux/dma-mapping.h>
>>   #include <linux/interrupt.h>
>>   #include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>>   #include <linux/mtd/rawnand.h>
>>   #include <linux/mtd/mtd.h>
>>   #include <linux/mfd/syscon.h>
>> @@ -19,6 +20,7 @@
>>   #include <linux/iopoll.h>
>>   #include <linux/of.h>
>>   #include <linux/of_device.h>
>> +#include <linux/of_address.h>
>>   #include <linux/sched/task_stack.h>
>>   
>>   #define NFC_REG_CMD		0x00
>> @@ -104,6 +106,9 @@
>>   
>>   #define PER_INFO_BYTE		8
>>   
>> +#define CLK_DIV_SHIFT		0
>> +#define CLK_DIV_WIDTH		6
>> +
>>   struct meson_nfc_nand_chip {
>>   	struct list_head node;
>>   	struct nand_chip nand;
>> @@ -151,15 +156,17 @@ struct meson_nfc {
>>   	struct nand_controller controller;
>>   	struct clk *core_clk;
>>   	struct clk *device_clk;
>> -	struct clk *phase_tx;
>> -	struct clk *phase_rx;
>> +	struct clk *nand_clk;
>> +	struct clk_divider nand_divider;
>>   
>>   	unsigned long clk_rate;
>>   	u32 bus_timing;
>>   
>>   	struct device *dev;
>> -	void __iomem *reg_base;
>> -	struct regmap *reg_clk;
>> +	struct {
>> +		void __iomem *reg_base;
>> +		void __iomem *sd_emmc_clock;
>> +	} res;
> 
> Please split your commit: first the mechanical changes, then the use of
> the new area or something like that.
> 
> Otherwise there are too many lines changed, I can't spot where it is
> interesting.

ok. i will split it next version. thanks.

> 
> Thanks,
> Miqu?l
> 
> .


From theleks at ko-hh.de  Fri Jan 28 11:31:50 2022
From: theleks at ko-hh.de (Lutz Koschorreck)
Date: Fri, 28 Jan 2022 20:31:50 +0100
Subject: [PATCH] arm64: dts: meson-sm1-odroid: fix boot loop after reboot
Message-ID: <20220128193150.GA1304381@odroid-VirtualBox>

Since the correct gpio pin is used for enabling tf-io regulator the
system did not boot correctly after calling reboot.

[   36.862443] reboot: Restarting system
bl31 reboot reason: 0xd
bl31 reboot reason: 0x0
system cmd  1.
SM1:BL:511f6b:81ca2f;FEAT:A0F83180:20282000;POC:B;RCY:0;SPINOR:0;CHK:1F;EMMC:800;NAND:81;SD?:0;SD:0;READ:0;0.0;CHK:0;
bl2_stage_init 0x01
bl2_stage_init 0x81
hw id:?SM1:BL:511f6b:81ca2f;FEAT:A0F83180:20282000;POC:B;RCY:0;SPINOR:0;CHK:1F;EMMC:800;NAND:81;SD?:0;SD:400;USB:8;LOOP:1;SPINOR:0;CHK:1F;EMMC:800;NAND:81;SD?:0;SD:400;USB:8;LOOP:2;SPINOR:0;CHK:1F;EMMC:800;NAND:81;SD?:0;SD:400;USB:8;LOOP:3;SPINOR:0;CHK:1F;EMMC:800;NAND:81;SD?:0;SD:400;USB:8;LOOP:4;SPINOR:0;CHK:1F;EMMC:800;NAND:81;SD?:0;SD:400;USB:8;LOOP:5;SPINOR:0;CHK:1F;EMMC:800;NAND:81;SD?:0;SD:400;USB:8;

Setting the gpio to open drain solves the issue.

Signed-off-by: Lutz Koschorreck <theleks at ko-hh.de>
---
 arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
index ed7cd5f53046..ddb1b345397f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
@@ -48,7 +48,7 @@ tf_io: gpio-regulator-tf_io {
 		regulator-max-microvolt = <3300000>;
 		vin-supply = <&vcc_5v>;
 
-		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
+		enable-gpio = <&gpio_ao GPIOE_2 GPIO_OPEN_DRAIN>;
 		enable-active-high;
 		regulator-always-on;
 
-- 
2.25.1



From theleks at ko-hh.de  Sat Jan 29 16:21:08 2022
From: theleks at ko-hh.de (Lutz Koschorreck)
Date: Sun, 30 Jan 2022 01:21:08 +0100
Subject: [PATCH] arm64: dts: meson-sm1-odroid: use correct enable-gpio
 pin for tf-io regulator
In-Reply-To: <20220127123814.GA152653@odroid-VirtualBox>
References: <20220126234325.GA7363@odroid-VirtualBox>
 <651adde5-4887-4701-5183-6a35a443574c@baylibre.com>
 <20220127123814.GA152653@odroid-VirtualBox>
Message-ID: <20220130002108.GA408329@odroid-VirtualBox>

On Thu, Jan 27, 2022 at 01:38:14PM +0100, Lutz Koschorreck wrote:
> On Thu, Jan 27, 2022 at 11:15:12AM +0100, Neil Armstrong wrote:
> > Hi,
> > 
> > On 27/01/2022 00:43, Lutz Koschorreck wrote:
> > > The interrupt pin of the external ethernet phy is used, instead of the
> > > enable-gpio pin of the tf-io regulator. The GPIOE_2 pin is located in
> > > the gpio_ao bank.
> > > Using open drain prevents reboot issues.
> > > 
> > > This causes phy interrupt problems at system startup.
> > > [   76.645190] irq 36: nobody cared (try booting with the "irqpoll" option)
> > > [   76.649617] CPU: 0 PID: 1416 Comm: irq/36-0.0:00 Not tainted 5.16.0 #2
> > > [   76.649629] Hardware name: Hardkernel ODROID-HC4 (DT)
> > > [   76.649635] Call trace:
> > > [   76.649638]  dump_backtrace+0x0/0x1c8
> > > [   76.649658]  show_stack+0x14/0x60
> > > [   76.649667]  dump_stack_lvl+0x64/0x7c
> > > [   76.649676]  dump_stack+0x14/0x2c
> > > [   76.649683]  __report_bad_irq+0x38/0xe8
> > > [   76.649695]  note_interrupt+0x220/0x3a0
> > > [   76.649704]  handle_irq_event_percpu+0x58/0x88
> > > [   76.649713]  handle_irq_event+0x44/0xd8
> > > [   76.649721]  handle_fasteoi_irq+0xa8/0x130
> > > [   76.649730]  generic_handle_domain_irq+0x38/0x58
> > > [   76.649738]  gic_handle_irq+0x9c/0xb8
> > > [   76.649747]  call_on_irq_stack+0x28/0x38
> > > [   76.649755]  do_interrupt_handler+0x7c/0x80
> > > [   76.649763]  el1_interrupt+0x34/0x80
> > > [   76.649772]  el1h_64_irq_handler+0x14/0x20
> > > [   76.649781]  el1h_64_irq+0x74/0x78
> > > [   76.649788]  irq_finalize_oneshot.part.56+0x68/0xf8
> > > [   76.649796]  irq_thread_fn+0x5c/0x98
> > > [   76.649804]  irq_thread+0x13c/0x260
> > > [   76.649812]  kthread+0x144/0x178
> > > [   76.649822]  ret_from_fork+0x10/0x20
> > > [   76.649830] handlers:
> > > [   76.653170] [<0000000025a6cd31>] irq_default_primary_handler threaded [<0000000093580eb7>] phy_interrupt
> > > [   76.661256] Disabling IRQ #36
> > > 
> > > Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
> > > 
> > > Signed-off-by: Lutz Koschorreck <theleks at ko-hh.de>
> > > ---
> > >  arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > > index 0bd1e98a0eef..ddb1b345397f 100644
> > > --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > > +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > > @@ -48,7 +48,7 @@ tf_io: gpio-regulator-tf_io {
> > >  		regulator-max-microvolt = <3300000>;
> > >  		vin-supply = <&vcc_5v>;
> > >  
> > > -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> > > +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_OPEN_DRAIN>;
> > 
> > Wow, indeed it's not the right GPIO chip... my bad.
> > 
> > >  		enable-active-high;
> > >  		regulator-always-on;
> > >  
> > 
> > Concerning the GPIO_OPEN_DRAIN, it's right since the line has a pull-up, does it really fix reboot issues ?
> There is a 10k pull up on the pin of C4 and HC4. Therefore it is fine to
> set to GPIO_OPEN_DRAIN. If this pin is left ACTIVE_HIGH and I call
> reboot, the bootloader is does not came up, it is an boot loop. Tobetter
> fixed that with a reset device driver, but I think using GPIO_OPEN_DRAIN
> is the right solution.
Sorry, this comment is not entirely correct. The GPIO_OPEN_DRAIN is
needed to fix a boot loop at bl2 level. Also it look like that the reset
driver fixes the boot loop at BL3X boot level and is needed for proper
operation.
> > 
> > Anyway, can you split the changes ? First for gpio_ao, second for GPIO_OPEN_DRAIN ?
> Yes of cause. I will generate a new patch set.
> > 
> > Neil
> > 
> > 
> > _______________________________________________
> > linux-amlogic mailing list
> > linux-amlogic at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-amlogic
> 
> _______________________________________________
> linux-amlogic mailing list
> linux-amlogic at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-amlogic


From linus.walleij at linaro.org  Sat Jan 29 17:53:17 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 30 Jan 2022 02:53:17 +0100
Subject: [PATCH v4 0/3] pinctrl: meson-s4: add pinctrl driver
In-Reply-To: <20220113031044.2665-1-qianggui.song@amlogic.com>
References: <20220113031044.2665-1-qianggui.song@amlogic.com>
Message-ID: <CACRpkda-jP8m-os6tjXQj3zOykzDq5cfTp9ir+T-H16N4ZAWcg@mail.gmail.com>

On Thu, Jan 13, 2022 at 4:10 AM Qianggui Song <qianggui.song at amlogic.com> wrote:

> This patchset adds Pin controller driver support for Meson-S4 SoC
> which shares the same register layout with previous Meson-A1
>
> Changes since v3 at [2]:
> - collect Martin's Acked-by and Reviewed-by
> - remove useless empty line

Patches applied for v5.18!

Yours,
Linus Walleij


From thierry.reding at gmail.com  Mon Jan 31 23:47:47 2022
From: thierry.reding at gmail.com (Thierry Reding)
Date: Tue, 1 Feb 2022 08:47:47 +0100
Subject: [PATCH 1/4] pwm: meson: Drop always false check from .request()
In-Reply-To: <20211108134628.120474-1-u.kleine-koenig@pengutronix.de>
References: <20211108134628.120474-1-u.kleine-koenig@pengutronix.de>
Message-ID: <Yfjlo4JS490V95hM@orome>

On Mon, Nov 08, 2021 at 02:46:24PM +0100, Uwe Kleine-K?nig wrote:
> In .request() pwm_get_chip_data() returns NULL always since commit
> e926b12c611c ("pwm: Clear chip_data in pwm_put()"). (And if it didn't
> returning 0 would be wrong because then .request() wouldn't reenable
> the clk which the other driver code depends on.)
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
> ---
>  drivers/pwm/pwm-meson.c | 8 +-------
>  1 file changed, 1 insertion(+), 7 deletions(-)

All four patches applied, thanks.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-amlogic/attachments/20220201/0b250b47/attachment.sig>

