* Re: [PATCH v3 8/9] dt-bindings: xlnx: Add VTC and TPG bindings
From: Krzysztof Kozlowski @ 2024-03-22 5:57 UTC (permalink / raw)
To: Anatoliy Klymenko, Laurent Pinchart, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Daniel Vetter,
Michal Simek, Andrzej Hajda, Neil Armstrong, Robert Foss,
Jonas Karlman, Jernej Skrabec, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Mauro Carvalho Chehab
Cc: Tomi Valkeinen, dri-devel, linux-arm-kernel, linux-kernel,
devicetree, linux-media
In-Reply-To: <20240321-dp-live-fmt-v3-8-d5090d796b7e@amd.com>
On 21/03/2024 21:43, Anatoliy Klymenko wrote:
> DO NOT MERGE. REFERENCE ONLY.
Why? What are you doing here and why nothing about this is explained?
>
> Add binding for AMD/Xilinx Video Timing Controller and Test Pattern
> Generator.
>
> Copy media-bus-formats.h into dt-bindings/media to suplement TPG DT node.
Still not tested. Do not send untested code to the lists.
NAK
Best regards,
Krzysztof
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 1/8] drm: xlnx: Fix kerneldoc
From: Tomi Valkeinen @ 2024-03-22 5:50 UTC (permalink / raw)
To: Sean Anderson, Randy Dunlap
Cc: Michal Simek, David Airlie, linux-kernel, Daniel Vetter,
linux-arm-kernel, Laurent Pinchart, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, dri-devel
In-Reply-To: <2c38ac1c-cc0e-43b3-86d3-5b6a2f00f9e7@linux.dev>
On 21/03/2024 17:33, Sean Anderson wrote:
> On 3/20/24 02:05, Randy Dunlap wrote:
>>
>>
>> On 3/19/24 22:42, Tomi Valkeinen wrote:
>>> On 20/03/2024 00:51, Sean Anderson wrote:
>>>> Fix a few errors in the kerneldoc. Mostly this addresses missing/renamed
>>>> members.
>>>>
>>>> Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
>>>> ---
>>>>
>>>> Changes in v2:
>>>> - New
>>>>
>>>> drivers/gpu/drm/xlnx/zynqmp_disp.c | 6 +++---
>>>> drivers/gpu/drm/xlnx/zynqmp_dpsub.h | 1 +
>>>> drivers/gpu/drm/xlnx/zynqmp_kms.h | 4 ++--
>>>> 3 files changed, 6 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
>>>> index 407bc07cec69..f79bf3fb8110 100644
>>>> --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
>>>> +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
>>>> @@ -128,9 +128,9 @@ struct zynqmp_disp_layer {
>>>> * struct zynqmp_disp - Display controller
>>>> * @dev: Device structure
>>>> * @dpsub: Display subsystem
>>>> - * @blend.base: Register I/O base address for the blender
>>>> - * @avbuf.base: Register I/O base address for the audio/video buffer manager
>>>> - * @audio.base: Registers I/O base address for the audio mixer
>>>> + * @blend: Register I/O base address for the blender
>>>> + * @avbuf: Register I/O base address for the audio/video buffer manager
>>>> + * @audio: Registers I/O base address for the audio mixer
>>>
>>> Afaics, the kernel doc guide:
>>>
>>> https://docs.kernel.org/doc-guide/kernel-doc.html#nested-structs-unions
>>>
>>> says that the current version is correct. Or is the issue that while, say, 'base' is documented, 'blend' was not?
>>
>> Hi,
>>
>> I would do it more like so:
>>
>> ---
>> drivers/gpu/drm/xlnx/zynqmp_disp.c | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff -- a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
>> --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
>> +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
>> @@ -128,8 +128,11 @@ struct zynqmp_disp_layer {
>> * struct zynqmp_disp - Display controller
>> * @dev: Device structure
>> * @dpsub: Display subsystem
>> + * @blend: blender iomem info
>> * @blend.base: Register I/O base address for the blender
>> + * @avbuf: audio/video buffer iomem info
>> * @avbuf.base: Register I/O base address for the audio/video buffer manager
>> + * @audio: audio mixer iomem info
>> * @audio.base: Registers I/O base address for the audio mixer
>> * @layers: Layers (planes)
>> */
>>
>>
>> but in my testing, Sean's way or my way result in no warning/errors.
>>
>
> The specific errors are:
>
> ../drivers/gpu/drm/xlnx/zynqmp_disp.c:151: warning: Function parameter or struct member 'blend' not described in 'zynqmp_disp'
> ../drivers/gpu/drm/xlnx/zynqmp_disp.c:151: warning: Function parameter or struct member 'avbuf' not described in 'zynqmp_disp'
> ../drivers/gpu/drm/xlnx/zynqmp_disp.c:151: warning: Function parameter or struct member 'audio' not described in 'zynqmp_disp'
>
> I don't see the need to document a single-member struct twice. Actually,
But if only the struct is documented, then we're documenting the wrong
thing. A tool showing to the user what blend.base is would miss that
documentation.
> maybe it would be better to just lift the .base member to live in
> zynqmp_disp. But I think that would be better in another series.
Yes, there's not much point with the structs.
Tomi
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 2/3] dt-bindings: remoteproc: add Versal-NET platform
From: Krzysztof Kozlowski @ 2024-03-22 5:44 UTC (permalink / raw)
To: Tanmay Shah, andersson, mathieu.poirier, robh+dt,
krzysztof.kozlowski+dt, conor+dt, michal.simek, ben.levinsky
Cc: linux-remoteproc, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <091c5ff9-dce9-4c63-a2ca-39d570e2f0a5@amd.com>
On 21/03/2024 16:13, Tanmay Shah wrote:
>
>
> On 3/21/24 2:39 AM, Krzysztof Kozlowski wrote:
>> On 20/03/2024 16:14, Tanmay Shah wrote:
>>>
>>>
>>> On 3/20/24 2:40 AM, Krzysztof Kozlowski wrote:
>>>> On 19/03/2024 15:42, Tanmay Shah wrote:
>>>>>
>>>>>
>>>>> On 3/19/24 12:30 AM, Krzysztof Kozlowski wrote:
>>>>>> On 19/03/2024 01:51, Tanmay Shah wrote:
>>>>>>> Hello Krzysztof,
>>>>>>>
>>>>>>> Thanks for reviews. Please find my comments below.
>>>>>>>
>>>>>>> On 3/17/24 1:53 PM, Krzysztof Kozlowski wrote:
>>>>>>>> On 15/03/2024 22:15, Tanmay Shah wrote:
>>>>>>>>> AMD-Xilinx Versal-NET platform is successor of Versal platform. It
>>>>>>>>> contains multiple clusters of cortex-R52 real-time processing units.
>>>>>>>>> Each cluster contains two cores of cortex-R52 processors. Each cluster
>>>>>>>>> can be configured in lockstep mode or split mode.
>>>>>>>>>
>>>>>>>>> Each R52 core is assigned 128KB of TCM memory. ATCM memory is 64KB, BTCM
>>>>>>>>> and CTCM memoreis are 32KB each. Each TCM memory has its own dedicated
>>>>>>>>> power-domain that needs to be requested before using it.
>>>>>>>>>
>>>>>>>>> Signed-off-by: Tanmay Shah <tanmay.shah@amd.com>
>>>>>>>>> ---
>>>>>>>>> .../remoteproc/xlnx,zynqmp-r5fss.yaml | 220 +++++++++++++++---
>>>>>>>>> 1 file changed, 184 insertions(+), 36 deletions(-)
>>>>>>>>>
>>>>>>>>> diff --git a/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml b/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml
>>>>>>>>> index 711da0272250..55654ee02eef 100644
>>>>>>>>> --- a/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml
>>>>>>>>> +++ b/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml
>>>>>>>>> @@ -18,7 +18,9 @@ description: |
>>>>>>>>>
>>>>>>>>> properties:
>>>>>>>>> compatible:
>>>>>>>>> - const: xlnx,zynqmp-r5fss
>>>>>>>>> + enum:
>>>>>>>>> + - xlnx,zynqmp-r5fss
>>>>>>>>> + - xlnx,versal-net-r52fss
>>>>>>>>>
>>>>>>>>> "#address-cells":
>>>>>>>>> const: 2
>>>>>>>>> @@ -64,7 +66,9 @@ patternProperties:
>>>>>>>>>
>>>>>>>>> properties:
>>>>>>>>> compatible:
>>>>>>>>> - const: xlnx,zynqmp-r5f
>>>>>>>>> + enum:
>>>>>>>>> + - xlnx,zynqmp-r5f
>>>>>>>>> + - xlnx,versal-net-r52f
>>>>>>>>>
>>>>>>>>> reg:
>>>>>>>>> minItems: 1
>>>>>>>>> @@ -135,9 +139,11 @@ required:
>>>>>>>>> allOf:
>>>>>>>>> - if:
>>>>>>>>> properties:
>>>>>>>>> - xlnx,cluster-mode:
>>>>>>>>> - enum:
>>>>>>>>> - - 1
>>>>>>>>> + compatible:
>>>>>>>>> + contains:
>>>>>>>>> + enum:
>>>>>>>>> + - xlnx,versal-net-r52fss
>>>>>>>>
>>>>>>>> Why do you touch these lines?
>>>>>>>>
>>>>>>>>> +
>>>>>>>>> then:
>>>>>>>>> patternProperties:
>>>>>>>>> "^r5f@[0-9a-f]+$":
>>>>>>>>> @@ -149,16 +155,14 @@ allOf:
>>>>>>>>> items:
>>>>>>>>> - description: ATCM internal memory
>>>>>>>>> - description: BTCM internal memory
>>>>>>>>> - - description: extra ATCM memory in lockstep mode
>>>>>>>>> - - description: extra BTCM memory in lockstep mode
>>>>>>>>> + - description: CTCM internal memory
>>>>>>>>>
>>>>>>>>> reg-names:
>>>>>>>>> minItems: 1
>>>>>>>>> items:
>>>>>>>>> - - const: atcm0
>>>>>>>>> - - const: btcm0
>>>>>>>>> - - const: atcm1
>>>>>>>>> - - const: btcm1
>>>>>>>>> + - const: atcm
>>>>>>>>> + - const: btcm
>>>>>>>>> + - const: ctcm
>>>>>>>>>
>>>>>>>>> power-domains:
>>>>>>>>> minItems: 2
>>>>>>>>> @@ -166,33 +170,70 @@ allOf:
>>>>>>>>> - description: RPU core power domain
>>>>>>>>> - description: ATCM power domain
>>>>>>>>> - description: BTCM power domain
>>>>>>>>> - - description: second ATCM power domain
>>>>>>>>> - - description: second BTCM power domain
>>>>>>>>> + - description: CTCM power domain
>>>>>>>>>
>>>>>>>>> else:
>>>>>>>>> - patternProperties:
>>>>>>>>> - "^r5f@[0-9a-f]+$":
>>>>>>>>> - type: object
>>>>>>>>> -
>>>>>>>>> - properties:
>>>>>>>>> - reg:
>>>>>>>>> - minItems: 1
>>>>>>>>> - items:
>>>>>>>>> - - description: ATCM internal memory
>>>>>>>>> - - description: BTCM internal memory
>>>>>>>>> -
>>>>>>>>> - reg-names:
>>>>>>>>> - minItems: 1
>>>>>>>>> - items:
>>>>>>>>> - - const: atcm0
>>>>>>>>> - - const: btcm0
>>>>>>>>> -
>>>>>>>>> - power-domains:
>>>>>>>>> - minItems: 2
>>>>>>>>> - items:
>>>>>>>>> - - description: RPU core power domain
>>>>>>>>> - - description: ATCM power domain
>>>>>>>>> - - description: BTCM power domain
>>>>>>>>> + allOf:
>>>>>>>>> + - if:
>>>>>>>>> + properties:
>>>>>>>>> + xlnx,cluster-mode:
>>>>>>>>> + enum:
>>>>>>>>> + - 1
>>>>>>>>
>>>>>>>> Whatever you did here, is not really readable. You have now multiple
>>>>>>>> if:then:if:then embedded.
>>>>>>>
>>>>>>> For ZynqMP platform, TCM can be configured differently in lockstep mode
>>>>>>> and split mode.
>>>>>>>
>>>>>>> For Versal-NET no such configuration is available, but new CTCM memory
>>>>>>> is added.
>>>>>>>
>>>>>>> So, I am trying to achieve following representation of TCM for both:
>>>>>>>
>>>>>>> if: versal-net compatible
>>>>>>> then:
>>>>>>> ATCM - 64KB
>>>>>>> BTCM - 32KB
>>>>>>> CTCM - 32KB
>>>>>>>
>>>>>>> else: (ZynqMP compatible)
>>>>>>> if:
>>>>>>> xlnx,cluster-mode (lockstep mode)
>>>>>>> then:
>>>>>>> ATCM0 - 64KB
>>>>>>> BTCM0 - 64KB
>>>>>>> ATCM1 - 64KB
>>>>>>> BTCM1 - 64KB
>>>>>>> else: (split mode)
>>>>>>> ATCM0 - 64KB
>>>>>>> BTCM0 - 64KB
>>>>>>>
>>>>>>>
>>>>>>> If bindings are getting complicated, does it make sense to introduce
>>>>>>> new file for Versal-NET bindings? Let me know how you would like me
>>>>>>> to proceed.
>>>>>>
>>>>>> All this is broken in your previous patchset, but now we nicely see.
>>>>>>
>>>>>> No, this does not work like this. You do not have entirely different
>>>>>> programming models in one device, don't you?
>>>>>>
>>>>>
>>>>> I don't understand what do you mean? Programming model is same. Only number
>>>>> of TCMs are changing based on configuration and platform. I can certainly
>>>>> list different compatible for different platforms as requested. But other than
>>>>> that not sure what needs to be fixed.
>>>>
>>>> You cannot have same programming model with different memory mappings.
>>>> Anyway, please follow writing bindings rules: all of your different
>>>> devices must have dedicated compatible. I really though we talked about
>>>> two IPs on same SoC...
>>>
>>> I agree that Versal compatible should be added, I will do that in next revision.
>>>
>>> For ZynqMP case, it is two IPs on same SOC. In lockstep mode and split mode,
>>> same SOC is configuring TCM differently.
>>>
>>> How this should be resolved for Versal-NET ? Driver avoids such TCM configuration
>>> for Versal-NET.
>>
>> Binding should describe the hardware, not what driver is doing
>> currently, so the question is: does your device have such properties or
>> not? Anyway, you need compatible per each variant and each SoC
>> implementation.
>
> Thanks for reviews.
>
> Okay in that case I believe I should add one more property to current bindings for TCM
> configuration.
>
I am not sure if you understand how IRC works... You sent me message on
IRC about this topic and shortly after you quit. So how am I supposed to
send reply? IRC does not work like that...
> From our discussion I conclude to following next steps:
>
> 1) I will send Versal and Versal-NET support as part of previous series (v14) so we get
> bigger picture in the first place.
>
> 2) Add separate compatible for versal platform.
> Use device compatible string to maintain
> backward compatibility and not machine (root node) compatible string.
>
> 3) Add tcm,mode property in bindings and each device must configure TCM based on that
> property only and not based on compatible string.
>
> 4) Versal-NET will disallow tcm,mode property in bindings as no such configuration is
> possible for that platform.
I really don't know your SoCs. What about Zynq? You keep using here
names all over the place, but I am not Xilinx maintainer.
Best regards,
Krzysztof
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v1 0/2] media: rockchip: rga: Add rk3568 support
From: Jianfeng Liu @ 2024-03-22 5:42 UTC (permalink / raw)
To: liujianfeng1994
Cc: conor+dt, devicetree, ezequiel, heiko, jacob-chen,
krzysztof.kozlowski+dt, linux-arm-kernel, linux-kernel,
linux-media, linux-rockchip, mchehab, robh, sfr
In-Reply-To: <20240322052915.3507937-1-liujianfeng1994@gmail.com>
I am really sorry guys, this patch is for rk3588, I wrote a wrong title.
Do I need to send a v2 patch just changing title of the cover letter?
Regards,
Jianfeng
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v1 1/2] dt-bindings: media: rockchip-rga: add rockchip,rk3588-rga
From: Jianfeng Liu @ 2024-03-22 5:29 UTC (permalink / raw)
To: devicetree, linux-arm-kernel, linux-rockchip, linux-kernel,
linux-media
Cc: robh, krzysztof.kozlowski+dt, conor+dt, heiko, jacob-chen,
ezequiel, mchehab, liujianfeng1994, sfr
In-Reply-To: <20240322052915.3507937-1-liujianfeng1994@gmail.com>
Add a new compatible for the rk3588 Rockchip SoC, which also features an
RGA, which is called RGA2 in the TRM Part2. It is the same core as used
on the rk3288 and rk3568, which documents the same RGA2.
Signed-off-by: Jianfeng Liu <liujianfeng1994@gmail.com>
---
Documentation/devicetree/bindings/media/rockchip-rga.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/media/rockchip-rga.yaml b/Documentation/devicetree/bindings/media/rockchip-rga.yaml
index ea2342222..ac17cda65 100644
--- a/Documentation/devicetree/bindings/media/rockchip-rga.yaml
+++ b/Documentation/devicetree/bindings/media/rockchip-rga.yaml
@@ -24,6 +24,7 @@ properties:
- enum:
- rockchip,rk3228-rga
- rockchip,rk3568-rga
+ - rockchip,rk3588-rga
- const: rockchip,rk3288-rga
reg:
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v2 5/8] drm: zynqmp_dp: Don't retrain the link in our IRQ
From: Tomi Valkeinen @ 2024-03-22 5:32 UTC (permalink / raw)
To: Sean Anderson
Cc: Michal Simek, David Airlie, linux-kernel, Daniel Vetter,
linux-arm-kernel, Laurent Pinchart, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, dri-devel
In-Reply-To: <b2bef7f9-fe46-45d0-a09b-50777f71f43c@linux.dev>
On 21/03/2024 21:17, Sean Anderson wrote:
> On 3/21/24 15:08, Tomi Valkeinen wrote:
>> On 21/03/2024 20:01, Sean Anderson wrote:
>>> On 3/21/24 13:25, Tomi Valkeinen wrote:
>>>> On 21/03/2024 17:52, Sean Anderson wrote:
>>>>> On 3/20/24 02:53, Tomi Valkeinen wrote:
>>>>>> On 20/03/2024 00:51, Sean Anderson wrote:
>>>>>>> Retraining the link can take a while, and might involve waiting for
>>>>>>> DPCD reads/writes to complete. This is inappropriate for an IRQ handler.
>>>>>>> Just schedule this work for later completion. This is racy, but will be
>>>>>>> fixed in the next commit.
>>>>>>
>>>>>> You should add the locks first, and use them here, rather than first
>>>>>> adding a buggy commit and fixing it in the next one.
>>>>>
>>>>> I didn't think I could add the locks first since I only noticed the IRQ
>>>>> was threaded right before sending out this series. So yeah, we could add
>>>>> locking, add the workqueue, and then unthread the IRQ.
>>>>>
>>>>>>> Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
>>>>>>> ---
>>>>>>> Actually, on second look this IRQ is threaded. So why do we have a
>>>>>>> workqueue for HPD events? Maybe we should make it unthreaded?
>>>>>>
>>>>>> Indeed, there's not much work being done in the IRQ handler. I don't know why it's threaded.
>>>>>>
>>>>>> We could move the queued work to be inside the threaded irq handler,
>>>>>> but with a quick look, the HPD work has lines like "msleep(100)" (and
>>>>>> that's inside a for loop...), which is probably not a good thing to do
>>>>>> even in threaded irq handler.
>>>>>>
>>>>>> Although I'm not sure if that code is good to have anywhere. Why do we
>>>>>> even have such code in the HPD work path... We already got the HPD
>>>>>> interrupt. What does "It takes some delay (ex, 100 ~ 500 msec) to get
>>>>>> the HPD signal with some monitors" even mean...
>>>>>
>>>>> The documentation for this bit is
>>>>>
>>>>> | HPD_STATE 0 ro 0x0 Contains the raw state of the HPD pin on the DisplayPort connector.
>>>>>
>>>>> So I think the idea is to perform some debouncing.
>>>>
>>>> Hmm, it just looks a bit odd to me. It can sleep for a second. And the wording "It takes some delay (ex, 100 ~ 500 msec) to get the HPD signal with some monitors" makes it sound like some kind of a hack...
>>>>
>>>> The docs mention debounce once:
>>>>
>>>> https://docs.amd.com/r/en-US/pg299-v-dp-txss1/Hot-Plug-Detection
>>>
>>> Are you sure this is the right document? This seems to be documentation for [1]. Is that instantiated as a hard block on the ZynqMP?
>>>
>>> [1] https://www.xilinx.com/products/intellectual-property/ef-di-displayport.html
>>
>> You're right, wrong document. The registers and bitfield names I looked at just matched, so I didn't think it through...
>>
>> The right doc says even less:
>>
>> https://docs.amd.com/r/en-US/ug1085-zynq-ultrascale-trm/Upon-HPD-Assertion
>>
>>>> But it's not immediately obvious what the SW must do and what's done by the HW. Debounce is not mentioned later, e.g. in the HPD Event Handling. But if debounce is needed, wouldn't it be perhaps in a few milliseconds, instead of hundreds of milliseconds...
>>>
>>> Well, the DP spec says
>>>
>>> | If the HPD is the result of a new device being connected, either
>>> | directly to the Source device (signaled by a long HPD), –or– downstream
>>> | of a Branch device (indicated by incrementing the DFP_COUNT field value
>>> | in the DOWN_STREAM_PORT_COUNT register (DPCD 00007h[3:0]) and signaled
>>> | by an IRQ_HPD pulse), the Source device shall read the new DisplayID or
>>> | legacy EDID that has been made available to it to ensure that content
>>> | being transmitted over the link is able to be properly received and
>>> | rendered.
>>> |
>>> | Informative Note: If the HPD signal toggling (or bouncing) is the
>>> | result of the Hot Unplug followed by Hot Plug of a
>>> | cable-connector assembly, the HPD signal is likely
>>> | to remain unstable during the de-bouncing period,
>>> | which is in the order of tens of milliseconds. The
>>> | Source device may either check the HPD signal’s
>>> | stability before initiating an AUX read transaction,
>>> | –or– immediately initiate the AUX read transaction
>>> | after each HPD rising edge.
>>>
>>> So a 100 ms delay seems plausible for some monitors.
>>
>> I read the text above as "it may take tens of milliseconds for HPD to stabilize". So polling it for total of 100ms sounds fine, but we're polling it for 1000ms.
>>
>> And I think checking for stability is fine, but for detect() I think it goes overboard: if the cable is disconnected, every detect call spends a second checking for HPD, even if we haven't seen any sign of an HPD =).
>>
>> And if we're checking the HPD stability, wouldn't we, say, poll the HPD for some time, and see if it stays the same? At the moment the code proceeds right away if HPD is high, but keeps polling if HPD is low.
>>
>>> That said, maybe we can just skip this and always read the DPCD.
>>
>> If the HPD is bouncing, is the AUX line also unstable?
>>
>> I don't mind a HPD stability check, I think it makes sense as (I think) the HW doesn't handle de-bouncing here. I think think it could be much much shorter than what it is now, and that it would make sense to observe the HPD for a period, instead of just waiting for the HPD to go high.
>>
>> But this could also be left for later, I don't think it matters in the context of this series.
>>
>>>> zynqmp_dp_bridge_detect() is used for drm_bridge_funcs.detect(), and if the cable is not connected, it'll sleep for 1 second (probably more) until returning not connected. It just doesn't sound correct to me.
>>>>
>>>> Well, it's not part of this patch as such, but related to the amount of time we spend in the interrupt handler (and also the detect()).
>>>>
>>>>>> Would it be possible to clean up the work funcs a bit (I haven't
>>>>>> looked a the new work func yet), to remove the worst extra sleeps, and
>>>>>> just do all that inside the threaded irq handler?
>>>>>
>>>>> Probably not, since a HPD IRQ results in link retraining, which can take a while.
>>>>
>>>> But is it any different if you have a workqueue? Isn't a threaded interrupt handler basically the same thing?
>>>>
>>>> Probably at least the zynqmp_dp_hpd_work_func() could be done in the threaded irq just fine, if the insane 1s sleep can be dropped.
>>>
>>> Anything involving AUX shouldn't been in an IRQ, since
>>> zynqmp_dp_aux_transfer will retry for up to 50ms by default.
>>
>> Perhaps. I'm still not sure if that's a problem. If a threaded irq is essentially a workqueue dedicated for this device, and we don't need to handle other irqs while the work is being done, then... What's the difference with a threaded irq and a workqueue?
>>
>> Oh, but we do need to handle irqs, we have the vblank irq in there. We don't want the vblanks to stop if there's a HPD IRQ.
>>
>> Btw, looks like zynqmp_dpsub_drm_handle_vblank() can sleep, so we can't move to non-threaded irq.
>
> I don't see that. We have
>
> zynqmp_dpsub_drm_handle_vblank
> drm_crtc_handle_vblank
> drm_handle_vblank
> spin_lock_irqsave(...)
> ...
> spin_lock_irqsave(...)
> vblank_disable_fn(...)
> spin_lock_irqsave(...)
> ...
> spin_lock_irqrestore(...)
>
> so no sleeping AFAICT.
Sorry, I don't know what code-path I was following where I saw mutexes.
I shouldn't look at code so late at night...
>>>>>> Do we need to handle interrupts while either delayed work is being done?
>>>>>
>>>>> Probably not.
>>>>>
>>>>>> If we do need a delayed work, would just one work be enough which
>>>>>> handles both HPD_EVENT and HPD_IRQ, instead of two?
>>>>>
>>>>> Maybe, but then we need to determine which pending events we need to
>>>>> handle. I think since we have only two events it will be easier to just
>>>>> have separate workqueues.
>>>>
>>>> The less concurrency, the better...Which is why it would be nice to do it all in the threaded irq.
>>>
>>> Yeah, but we can use a mutex for this which means there is not too much
>>> interesting going on.
>>
>> Ok. Yep, if we get (hopefully) a single mutex with clearly defined fields that it protects, I'm ok with workqueues.
>>
>> I'd still prefer just one workqueue, though...
>
> Yeah, but then we need a spinlock or something to tell the workqueue what it should do.
Yep. We could also always look at the HPD (if we drop the big sleeps) in
the wq, and have a flag for the HPD IRQ, which would reduce the state to
a single bit.
Tomi
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v6 10/14] drm/mediatek: Support "None" alpha blending in OVL
From: Shawn Sung @ 2024-03-22 5:28 UTC (permalink / raw)
To: Chun-Kuang Hu, AngeloGioacchino Del Regno
Cc: Philipp Zabel, David Airlie, Daniel Vetter, Matthias Brugger,
Bibby Hsieh, CK Hu, Nancy . Lin, Fei Shao, Sean Paul, Jason Chen,
dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Hsiao Chien Sung
In-Reply-To: <20240322052829.9893-1-shawn.sung@mediatek.com>
From: Hsiao Chien Sung <shawn.sung@mediatek.com>
Support "None" blend mode on MediaTek's chips.
Please refer to the description of the commit
"drm/mediatek: Support alpha blending in display driver"
for more information.
Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index b1e5d453316cc..a936f338ab79d 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -484,7 +484,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
con |= state->base.alpha & OVL_CON_ALPHA;
}
- if (state->base.fb && !state->base.fb->format->has_alpha)
+ if (blend_mode == DRM_MODE_BLEND_PIXEL_NONE ||
+ (state->base.fb && !state->base.fb->format->has_alpha))
ignore_pixel_alpha = OVL_CONST_BLEND;
if (pending->rotation & DRM_MODE_REFLECT_Y) {
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v6 05/14] drm/mediatek: Set DRM mode configs accordingly
From: Shawn Sung @ 2024-03-22 5:28 UTC (permalink / raw)
To: Chun-Kuang Hu, AngeloGioacchino Del Regno
Cc: Philipp Zabel, David Airlie, Daniel Vetter, Matthias Brugger,
Bibby Hsieh, CK Hu, Nancy . Lin, Fei Shao, Sean Paul, Jason Chen,
dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Hsiao Chien Sung
In-Reply-To: <20240322052829.9893-1-shawn.sung@mediatek.com>
From: Hsiao Chien Sung <shawn.sung@mediatek.com>
Set DRM mode configs limitation according to the hardware capabilities
and pass the IGT checks as below:
- The test "graphics.IgtKms.kms_plane" requires a frame buffer with
width of 4512 pixels (> 4096).
- The test "graphics.IgtKms.kms_cursor_crc" checks if the cursor size is
defined, and run the test with cursor size from 1x1 to 512x512.
Please notice that the test conditions may change as IGT is updated.
Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_drm_drv.c | 22 ++++++++++++++++++++++
drivers/gpu/drm/mediatek/mtk_drm_drv.h | 3 +++
2 files changed, 25 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 621015b64674d..8e04e9576f7f2 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -296,6 +296,9 @@ static const struct mtk_mmsys_driver_data mt8188_vdosys0_driver_data = {
.conn_routes = mt8188_mtk_ddp_main_routes,
.num_conn_routes = ARRAY_SIZE(mt8188_mtk_ddp_main_routes),
.mmsys_dev_num = 2,
+ .max_width = 8191,
+ .min_width = 1,
+ .min_height = 1,
};
static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
@@ -310,6 +313,9 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
.main_path = mt8195_mtk_ddp_main,
.main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
.mmsys_dev_num = 2,
+ .max_width = 8191,
+ .min_width = 1,
+ .min_height = 1,
};
static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
@@ -317,6 +323,9 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
.ext_len = ARRAY_SIZE(mt8195_mtk_ddp_ext),
.mmsys_id = 1,
.mmsys_dev_num = 2,
+ .max_width = 8191,
+ .min_width = 2, /* 2-pixel align when ethdr is bypassed */
+ .min_height = 1,
};
static const struct of_device_id mtk_drm_of_ids[] = {
@@ -495,6 +504,15 @@ static int mtk_drm_kms_init(struct drm_device *drm)
for (j = 0; j < private->data->mmsys_dev_num; j++) {
priv_n = private->all_drm_private[j];
+ if (priv_n->data->max_width)
+ drm->mode_config.max_width = priv_n->data->max_width;
+
+ if (priv_n->data->min_width)
+ drm->mode_config.min_width = priv_n->data->min_width;
+
+ if (priv_n->data->min_height)
+ drm->mode_config.min_height = priv_n->data->min_height;
+
if (i == CRTC_MAIN && priv_n->data->main_len) {
ret = mtk_crtc_create(drm, priv_n->data->main_path,
priv_n->data->main_len, j,
@@ -522,6 +540,10 @@ static int mtk_drm_kms_init(struct drm_device *drm)
}
}
+ /* IGT will check if the cursor size is configured */
+ drm->mode_config.cursor_width = drm->mode_config.max_width;
+ drm->mode_config.cursor_height = drm->mode_config.max_height;
+
/* Use OVL device for all DMA memory allocations */
crtc = drm_crtc_from_index(drm, 0);
if (crtc)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 78d698ede1bf8..8917a14d7c0f2 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -46,6 +46,9 @@ struct mtk_mmsys_driver_data {
bool shadow_register;
unsigned int mmsys_id;
unsigned int mmsys_dev_num;
+
+ int max_width;
+ int min_width, min_height;
};
struct mtk_drm_private {
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v6 03/14] drm/mediatek: Add missing plane settings when async update
From: Shawn Sung @ 2024-03-22 5:28 UTC (permalink / raw)
To: Chun-Kuang Hu, AngeloGioacchino Del Regno
Cc: Philipp Zabel, David Airlie, Daniel Vetter, Matthias Brugger,
Bibby Hsieh, CK Hu, Nancy . Lin, Fei Shao, Sean Paul, Jason Chen,
dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Hsiao Chien Sung
In-Reply-To: <20240322052829.9893-1-shawn.sung@mediatek.com>
From: Hsiao Chien Sung <shawn.sung@mediatek.com>
Fix an issue that plane coordinate was not saved when
calling async update.
Fixes: 920fffcc8912 ("drm/mediatek: update cursors by using async atomic update")
Reviewed-by: CK Hu <ck.hu@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_plane.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_plane.c b/drivers/gpu/drm/mediatek/mtk_plane.c
index 4625deb21d406..a74b26d359857 100644
--- a/drivers/gpu/drm/mediatek/mtk_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_plane.c
@@ -227,6 +227,8 @@ static void mtk_plane_atomic_async_update(struct drm_plane *plane,
plane->state->src_y = new_state->src_y;
plane->state->src_h = new_state->src_h;
plane->state->src_w = new_state->src_w;
+ plane->state->dst.x1 = new_state->dst.x1;
+ plane->state->dst.y1 = new_state->dst.y1;
mtk_plane_update_new_state(new_state, new_plane_state);
swap(plane->state->fb, new_state->fb);
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v1 2/2] arm64: dts: rockchip: Add RGA2 support to rk3588
From: Jianfeng Liu @ 2024-03-22 5:29 UTC (permalink / raw)
To: devicetree, linux-arm-kernel, linux-rockchip, linux-kernel,
linux-media
Cc: robh, krzysztof.kozlowski+dt, conor+dt, heiko, jacob-chen,
ezequiel, mchehab, liujianfeng1994, sfr
In-Reply-To: <20240322052915.3507937-1-liujianfeng1994@gmail.com>
RK3588 also features a RGA2 block. Add the necessary device tree
node.
Signed-off-by: Jianfeng Liu <liujianfeng1994@gmail.com>
---
arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
index 87b83c87b..8f130177b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
@@ -387,6 +387,17 @@ psci {
method = "smc";
};
+ rga: rga@fdb80000 {
+ compatible = "rockchip,rk3588-rga", "rockchip,rk3288-rga";
+ reg = <0x0 0xfdb80000 0x0 0x180>;
+ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru ACLK_RGA2>, <&cru HCLK_RGA2>, <&cru CLK_RGA2_CORE>;
+ clock-names = "aclk", "hclk", "sclk";
+ resets = <&cru SRST_RGA2_CORE>, <&cru SRST_A_RGA2>, <&cru SRST_H_RGA2>;
+ reset-names = "core", "axi", "ahb";
+ power-domains = <&power RK3588_PD_VDPU>;
+ };
+
spll: clock-0 {
compatible = "fixed-clock";
clock-frequency = <702000000>;
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v1 0/2] media: rockchip: rga: Add rk3568 support
From: Jianfeng Liu @ 2024-03-22 5:29 UTC (permalink / raw)
To: devicetree, linux-arm-kernel, linux-rockchip, linux-kernel,
linux-media
Cc: robh, krzysztof.kozlowski+dt, conor+dt, heiko, jacob-chen,
ezequiel, mchehab, liujianfeng1994, sfr
The RGA2 on the Rockchip rk3588 is the same core as the RGA2 on the
Rockchip rk3288 and rk3568.
This series adds the necessary device tree binding and node in the device
tree to enable the RGA2 on the Rockchip rk3588.
Tested on rock5b with gstreamer command:
gst-launch-1.0 videotestsrc ! video/x-raw,format=BGRx ! v4l2convert ! xvimagesink
Jianfeng Liu (2):
dt-bindings: media: rockchip-rga: add rockchip,rk3588-rga
arm64: dts: rockchip: Add RGA2 support to rk3588
.../devicetree/bindings/media/rockchip-rga.yaml | 1 +
arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 11 +++++++++++
2 files changed, 12 insertions(+)
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v6 00/14] Support IGT in display driver
From: Shawn Sung @ 2024-03-22 5:28 UTC (permalink / raw)
To: Chun-Kuang Hu, AngeloGioacchino Del Regno
Cc: Philipp Zabel, David Airlie, Daniel Vetter, Matthias Brugger,
Bibby Hsieh, CK Hu, Nancy . Lin, Fei Shao, Sean Paul, Jason Chen,
dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Hsiao Chien Sung
From: Hsiao Chien Sung <shawn.sung@mediatek.com>
This series is based on 20240322012808.26234-1-shawn.sung@mediatek.com.
This series adds support for running IGT (Intel GPU Tool) tests
with MediaTek display driver. The following changes will be
applied:
1. Add a new API for creating GCE thread loop to retrieve CRCs
from the hardware component
2. Support hardware CRC calculation in both VDOSYS0 and VDOSYS1
3. Support alpha blending in both VDOSYS0 and VDOSYS1
Changes in v6:
- Use drm_vblank_work to deffer the CRC work into bottom halves
- Separate the patches for "Premultiplied" and "None" alpha blending
Changes in v5:
- Add more descriptions to the codes
- Add DRM mode configs to the driver data
- Squash and rearrange the commits
Changes in v4:
- Separate the patch into smaller ones
- Change the title of some patches
- Revert the changes that are not related to the series
Changes in v3:
- Modify the dt-binding document of Mediatek OVL
- Set DRM mode configs accroding to the hardware capabilities
- Replace cmdq_pkt_jump_absolute() with cmdq_pkt_jump()
Changes in v2:
- Simplify CMDQ by adding commands that are currently used only
- Integrate CRC related codes into new APIs for Mixer and OVL to reuse
- Add CPU version CRC retrieval when CMDQ is disabled
Hsiao Chien Sung (14):
soc: mediatek: Disable 9-bit alpha in ETHDR
drm/mediatek: Add OVL compatible name for MT8195
drm/mediatek: Add missing plane settings when async update
drm/mediatek: Add DRM_MODE_ROTATE_0 to rotation property
drm/mediatek: Set DRM mode configs accordingly
drm/mediatek: Turn off the layers with zero width or height
drm/mediatek: Support alpha blending in display driver
drm/mediatek: Support "Pre-multiplied" alpha blending in OVL
drm/mediatek: Support "Pre-multiplied" alpha blending in Mixer
drm/mediatek: Support "None" alpha blending in OVL
drm/mediatek: Support "None" alpha blending in Mixer
drm/mediatek: Support CRC in display driver
drm/mediatek: Support CRC in OVL
drm/mediatek: Support CRC in OVL adaptor
drivers/gpu/drm/mediatek/mtk_crtc.c | 260 +++++++++++++++
drivers/gpu/drm/mediatek/mtk_crtc.h | 38 +++
drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 6 +
drivers/gpu/drm/mediatek/mtk_ddp_comp.h | 9 +-
drivers/gpu/drm/mediatek/mtk_disp_drv.h | 6 +
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 304 ++++++++++++++++--
.../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 23 +-
drivers/gpu/drm/mediatek/mtk_drm_drv.c | 24 ++
drivers/gpu/drm/mediatek/mtk_drm_drv.h | 3 +
drivers/gpu/drm/mediatek/mtk_ethdr.c | 94 +++++-
drivers/gpu/drm/mediatek/mtk_ethdr.h | 5 +
drivers/gpu/drm/mediatek/mtk_plane.c | 15 +-
drivers/soc/mediatek/mtk-mmsys.c | 1 +
13 files changed, 744 insertions(+), 44 deletions(-)
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v6 09/14] drm/mediatek: Support "Pre-multiplied" alpha blending in Mixer
From: Shawn Sung @ 2024-03-22 5:28 UTC (permalink / raw)
To: Chun-Kuang Hu, AngeloGioacchino Del Regno
Cc: Philipp Zabel, David Airlie, Daniel Vetter, Matthias Brugger,
Bibby Hsieh, CK Hu, Nancy . Lin, Fei Shao, Sean Paul, Jason Chen,
dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Hsiao Chien Sung
In-Reply-To: <20240322052829.9893-1-shawn.sung@mediatek.com>
From: Hsiao Chien Sung <shawn.sung@mediatek.com>
Support "Pre-multiplied" blend mode on MediaTek's chips.
Before this patch, only the "Coverage" mode is supported.
Please refer to the description of the commit
"drm/mediatek: Support alpha blending in display driver"
for more information.
Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_ethdr.c | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
index 6bf398850e85f..4b12ca285e84b 100644
--- a/drivers/gpu/drm/mediatek/mtk_ethdr.c
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -5,6 +5,7 @@
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
+#include <drm/drm_blend.h>
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/of.h>
@@ -35,6 +36,7 @@
#define MIX_SRC_L0_EN BIT(0)
#define MIX_L_SRC_CON(n) (0x28 + 0x18 * (n))
#define NON_PREMULTI_SOURCE (2 << 12)
+#define PREMULTI_SOURCE (3 << 12)
#define MIX_L_SRC_SIZE(n) (0x30 + 0x18 * (n))
#define MIX_L_SRC_OFFSET(n) (0x34 + 0x18 * (n))
#define MIX_FUNC_DCM0 0x120
@@ -153,7 +155,8 @@ void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
struct mtk_plane_pending_state *pending = &state->pending;
unsigned int offset = (pending->x & 1) << 31 | pending->y << 16 | pending->x;
unsigned int align_width = ALIGN_DOWN(pending->width, 2);
- unsigned int alpha_con = 0;
+ unsigned int mix_con = NON_PREMULTI_SOURCE;
+ bool replace_src_a = false;
dev_dbg(dev, "%s+ idx:%d", __func__, idx);
@@ -170,19 +173,27 @@ void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
return;
}
- if (state->base.fb && state->base.fb->format->has_alpha)
- alpha_con = MIXER_ALPHA_AEN | MIXER_ALPHA;
+ mix_con |= MIXER_ALPHA_AEN | (state->base.alpha & MIXER_ALPHA);
- mtk_mmsys_mixer_in_config(priv->mmsys_dev, idx + 1, alpha_con ? false : true,
- DEFAULT_9BIT_ALPHA,
+ if (state->base.pixel_blend_mode != DRM_MODE_BLEND_COVERAGE)
+ mix_con |= PREMULTI_SOURCE;
+
+ if (state->base.fb && !state->base.fb->format->has_alpha) {
+ /*
+ * Mixer doesn't support CONST_BLD mode,
+ * use a trick to make the output equivalent
+ */
+ replace_src_a = true;
+ }
+
+ mtk_mmsys_mixer_in_config(priv->mmsys_dev, idx + 1, replace_src_a, MIXER_ALPHA,
pending->x & 1 ? MIXER_INX_MODE_EVEN_EXTEND :
MIXER_INX_MODE_BYPASS, align_width / 2 - 1, cmdq_pkt);
mtk_ddp_write(cmdq_pkt, pending->height << 16 | align_width, &mixer->cmdq_base,
mixer->regs, MIX_L_SRC_SIZE(idx));
mtk_ddp_write(cmdq_pkt, offset, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_OFFSET(idx));
- mtk_ddp_write_mask(cmdq_pkt, alpha_con, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_CON(idx),
- 0x1ff);
+ mtk_ddp_write(cmdq_pkt, mix_con, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_CON(idx));
mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &mixer->cmdq_base, mixer->regs, MIX_SRC_CON,
BIT(idx));
}
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v6 02/14] drm/mediatek: Add OVL compatible name for MT8195
From: Shawn Sung @ 2024-03-22 5:28 UTC (permalink / raw)
To: Chun-Kuang Hu, AngeloGioacchino Del Regno
Cc: Philipp Zabel, David Airlie, Daniel Vetter, Matthias Brugger,
Bibby Hsieh, CK Hu, Nancy . Lin, Fei Shao, Sean Paul, Jason Chen,
dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Hsiao Chien Sung
In-Reply-To: <20240322052829.9893-1-shawn.sung@mediatek.com>
From: Hsiao Chien Sung <shawn.sung@mediatek.com>
Add OVL compatible name for MT8195.
Without this commit, DRM won't work after modifying the device tree.
Reviewed-by: CK Hu <ck.hu@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 4710cd8b7288b..621015b64674d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -761,6 +761,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
.data = (void *)MTK_DISP_OVL },
{ .compatible = "mediatek,mt8192-disp-ovl",
.data = (void *)MTK_DISP_OVL },
+ { .compatible = "mediatek,mt8195-disp-ovl",
+ .data = (void *)MTK_DISP_OVL },
{ .compatible = "mediatek,mt8183-disp-ovl-2l",
.data = (void *)MTK_DISP_OVL_2L },
{ .compatible = "mediatek,mt8192-disp-ovl-2l",
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v6 13/14] drm/mediatek: Support CRC in OVL
From: Shawn Sung @ 2024-03-22 5:28 UTC (permalink / raw)
To: Chun-Kuang Hu, AngeloGioacchino Del Regno
Cc: Philipp Zabel, David Airlie, Daniel Vetter, Matthias Brugger,
Bibby Hsieh, CK Hu, Nancy . Lin, Fei Shao, Sean Paul, Jason Chen,
dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Hsiao Chien Sung
In-Reply-To: <20240322052829.9893-1-shawn.sung@mediatek.com>
From: Hsiao Chien Sung <shawn.sung@mediatek.com>
We choose OVL as the CRC generator from other hardware
components that are also capable of calculating CRCs,
since its frame done event triggers vblanks, it can be
used as a signal to know when is safe to retrieve CRC of
the frame.
Please note that position of the hardware component
that is chosen as CRC generator in the display path is
significant. For example, while OVL is the first module
in VDOSYS0, its CRC won't be affected by the modules
after it, which means effects applied by PQ, Gamma,
Dither or any other components after OVL won't be
calculated in CRC generation.
Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 3 +
drivers/gpu/drm/mediatek/mtk_disp_drv.h | 3 +
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 198 ++++++++++++++++++++++--
3 files changed, 194 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
index 17b0364112922..cb71effda9c2a 100644
--- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
@@ -351,6 +351,9 @@ static const struct mtk_ddp_comp_funcs ddp_ovl = {
.clk_enable = mtk_ovl_clk_enable,
.clk_disable = mtk_ovl_clk_disable,
.config = mtk_ovl_config,
+ .crc_cnt = mtk_ovl_crc_cnt,
+ .crc_entry = mtk_ovl_crc_entry,
+ .crc_read = mtk_ovl_crc_read,
.start = mtk_ovl_start,
.stop = mtk_ovl_stop,
.register_vblank_cb = mtk_ovl_register_vblank_cb,
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 082ac18fe04aa..c476056a5cbb5 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -105,6 +105,9 @@ void mtk_ovl_enable_vblank(struct device *dev);
void mtk_ovl_disable_vblank(struct device *dev);
const u32 *mtk_ovl_get_formats(struct device *dev);
size_t mtk_ovl_get_num_formats(struct device *dev);
+size_t mtk_ovl_crc_cnt(struct device *dev);
+u32 *mtk_ovl_crc_entry(struct device *dev);
+void mtk_ovl_crc_read(struct device *dev);
void mtk_ovl_adaptor_add_comp(struct device *dev, struct mtk_mutex *mutex);
void mtk_ovl_adaptor_remove_comp(struct device *dev, struct mtk_mutex *mutex);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index a936f338ab79d..279e6193e7975 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -24,12 +24,20 @@
#define OVL_FME_CPL_INT BIT(1)
#define DISP_REG_OVL_INTSTA 0x0008
#define DISP_REG_OVL_EN 0x000c
+#define OVL_EN BIT(0)
+#define OVL_OP_8BIT_MODE BIT(4)
+#define OVL_HG_FOVL_CK_ON BIT(8)
+#define OVL_HF_FOVL_CK_ON BIT(10)
+#define DISP_REG_OVL_TRIG 0x0010
+#define OVL_CRC_EN BIT(8)
+#define OVL_CRC_CLR BIT(9)
#define DISP_REG_OVL_RST 0x0014
#define DISP_REG_OVL_ROI_SIZE 0x0020
#define DISP_REG_OVL_DATAPATH_CON 0x0024
#define OVL_LAYER_SMI_ID_EN BIT(0)
#define OVL_BGCLR_SEL_IN BIT(2)
#define OVL_LAYER_AFBC_EN(n) BIT(4+n)
+#define OVL_OUTPUT_CLAMP BIT(26)
#define DISP_REG_OVL_ROI_BGCLR 0x0028
#define DISP_REG_OVL_SRC_CON 0x002c
#define DISP_REG_OVL_CON(n) (0x0030 + 0x20 * (n))
@@ -42,7 +50,26 @@
#define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n))
#define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n))
#define DISP_REG_OVL_ADDR_MT2701 0x0040
+#define DISP_REG_OVL_CRC 0x0270
+#define OVL_CRC_OUT_MASK GENMASK(30, 0)
#define DISP_REG_OVL_CLRFMT_EXT 0x02D0
+#define DISP_REG_OVL_CLRFMT_EXT1 0x02D8
+#define OVL_CLRFMT_EXT1_CSC_EN(n) (1 << (((n) * 4) + 1))
+#define DISP_REG_OVL_Y2R_PARA_R0(n) (0x0134 + 0x28 * (n))
+#define OVL_Y2R_PARA_C_CF_RMY (GENMASK(14, 0))
+#define DISP_REG_OVL_Y2R_PARA_G0(n) (0x013c + 0x28 * (n))
+#define OVL_Y2R_PARA_C_CF_GMU (GENMASK(30, 16))
+#define DISP_REG_OVL_Y2R_PARA_B1(n) (0x0148 + 0x28 * (n))
+#define OVL_Y2R_PARA_C_CF_BMV (GENMASK(14, 0))
+#define DISP_REG_OVL_Y2R_PARA_YUV_A_0(n) (0x014c + 0x28 * (n))
+#define OVL_Y2R_PARA_C_CF_YA (GENMASK(10, 0))
+#define OVL_Y2R_PARA_C_CF_UA (GENMASK(26, 16))
+#define DISP_REG_OVL_Y2R_PARA_YUV_A_1(n) (0x0150 + 0x28 * (n))
+#define OVL_Y2R_PARA_C_CF_VA (GENMASK(10, 0))
+#define DISP_REG_OVL_Y2R_PRE_ADD2(n) (0x0154 + 0x28 * (n))
+#define DISP_REG_OVL_R2R_R0(n) (0x0500 + 0x40 * (n))
+#define DISP_REG_OVL_R2R_G1(n) (0x0510 + 0x40 * (n))
+#define DISP_REG_OVL_R2R_B2(n) (0x0520 + 0x40 * (n))
#define DISP_REG_OVL_ADDR_MT8173 0x0f40
#define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n))
#define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04)
@@ -55,6 +82,8 @@
#define OVL_CON_CLRFMT_MAN BIT(23)
#define OVL_CON_BYTE_SWAP BIT(24)
#define OVL_CON_RGB_SWAP BIT(25)
+#define OVL_CON_MTX_AUTO_DIS BIT(26)
+#define OVL_CON_MTX_EN BIT(27)
#define OVL_CON_CLRFMT_RGB (1 << 12)
#define OVL_CON_CLRFMT_RGBA8888 (2 << 12)
#define OVL_CON_CLRFMT_ARGB8888 (3 << 12)
@@ -62,6 +91,7 @@
#define OVL_CON_CLRFMT_YUYV (5 << 12)
#define OVL_CON_MTX_YUV_TO_RGB (6 << 16)
#define OVL_CON_CLRFMT_PARGB8888 (OVL_CON_CLRFMT_ARGB8888 | OVL_CON_CLRFMT_MAN)
+#define OVL_CON_MTX_PROGRAMMABLE (8 << 16)
#define OVL_CON_CLRFMT_RGB565(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
0 : OVL_CON_CLRFMT_RGB)
#define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
@@ -131,6 +161,10 @@ static const u32 mt8195_formats[] = {
DRM_FORMAT_YUYV,
};
+static const u32 mt8195_ovl_crc_ofs[] = {
+ DISP_REG_OVL_CRC,
+};
+
struct mtk_disp_ovl_data {
unsigned int addr;
unsigned int gmc_bits;
@@ -141,12 +175,15 @@ struct mtk_disp_ovl_data {
const u32 *formats;
size_t num_formats;
bool supports_clrfmt_ext;
+ const u32 *crc_ofs;
+ size_t crc_cnt;
};
/*
* struct mtk_disp_ovl - DISP_OVL driver structure
* @crtc: associated crtc to report vblank events to
* @data: platform data
+ * @crc: crc related information
*/
struct mtk_disp_ovl {
struct drm_crtc *crtc;
@@ -156,8 +193,31 @@ struct mtk_disp_ovl {
const struct mtk_disp_ovl_data *data;
void (*vblank_cb)(void *data);
void *vblank_cb_data;
+ resource_size_t regs_pa;
+ struct mtk_crtc_crc crc;
};
+size_t mtk_ovl_crc_cnt(struct device *dev)
+{
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+ return ovl->crc.cnt;
+}
+
+u32 *mtk_ovl_crc_entry(struct device *dev)
+{
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+ return ovl->crc.va;
+}
+
+void mtk_ovl_crc_read(struct device *dev)
+{
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+ mtk_crtc_read_crc(&ovl->crc, ovl->regs);
+}
+
static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
{
struct mtk_disp_ovl *priv = dev_id;
@@ -237,21 +297,40 @@ void mtk_ovl_clk_disable(struct device *dev)
void mtk_ovl_start(struct device *dev)
{
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+ unsigned int reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
- if (ovl->data->smi_id_en) {
- unsigned int reg;
+ if (ovl->data->smi_id_en)
+ reg |= OVL_LAYER_SMI_ID_EN;
- reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
- reg = reg | OVL_LAYER_SMI_ID_EN;
- writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
+ /*
+ * When doing Y2R conversion, it's common to get an output
+ * that is larger than 10 bits (negative numbers).
+ * Enable this bit to clamp the output to 10 bits per channel
+ * (should always be enabled)
+ */
+ reg |= OVL_OUTPUT_CLAMP;
+ writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
+
+ reg = OVL_EN;
+ if (ovl->data->crc_cnt) {
+ /* enable crc and its related clocks */
+ writel_relaxed(OVL_CRC_EN, ovl->regs + DISP_REG_OVL_TRIG);
+ reg |= OVL_OP_8BIT_MODE | OVL_HG_FOVL_CK_ON | OVL_HF_FOVL_CK_ON;
}
- writel_relaxed(0x1, ovl->regs + DISP_REG_OVL_EN);
+ writel_relaxed(reg, ovl->regs + DISP_REG_OVL_EN);
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ mtk_crtc_start_crc_cmdq(&ovl->crc);
+#endif
}
void mtk_ovl_stop(struct device *dev)
{
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ mtk_crtc_stop_crc_cmdq(&ovl->crc);
+#endif
writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_EN);
if (ovl->data->smi_id_en) {
unsigned int reg;
@@ -488,6 +567,83 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
(state->base.fb && !state->base.fb->format->has_alpha))
ignore_pixel_alpha = OVL_CONST_BLEND;
+ /*
+ * OVL only supports 8 bits data in CRC calculation, transform 10-bit
+ * RGB to 8-bit RGB by leveraging the ability of the Y2R (YUV-to-RGB)
+ * hardware to multiply coefficients, although there is nothing to do
+ * with the YUV format.
+ */
+ if (ovl->data->supports_clrfmt_ext) {
+ u32 y2r_coef = 0, y2r_offset = 0, r2r_coef = 0, csc_en = 0;
+
+ if (is_10bit_rgb(fmt)) {
+ con |= OVL_CON_MTX_AUTO_DIS | OVL_CON_MTX_EN | OVL_CON_MTX_PROGRAMMABLE;
+
+ /*
+ * Y2R coefficient setting
+ * bit 13 is 2^1, bit 12 is 2^0, bit 11 is 2^-1,
+ * bit 10 is 2^-2 = 0.25
+ */
+ y2r_coef = BIT(10);
+
+ /* -1 in 10bit */
+ y2r_offset = GENMASK(10, 0) - 1;
+
+ /*
+ * R2R coefficient setting
+ * bit 19 is 2^1, bit 18 is 2^0, bit 17 is 2^-1,
+ * bit 20 is 2^2 = 4
+ */
+ r2r_coef = BIT(20);
+
+ /* CSC_EN is for R2R */
+ csc_en = OVL_CLRFMT_EXT1_CSC_EN(idx);
+
+ /*
+ * 1. YUV input data - 1 and shift right for 2 bits to remove it
+ * [R'] [0.25 0 0] [Y in - 1]
+ * [G'] = [ 0 0.25 0] * [U in - 1]
+ * [B'] [ 0 0 0.25] [V in - 1]
+ *
+ * 2. shift left for 2 bit letting the last 2 bits become 0
+ * [R out] [ 4 0 0] [R']
+ * [G out] = [ 0 4 0] * [G']
+ * [B out] [ 0 0 4] [B']
+ */
+ }
+
+ mtk_ddp_write_mask(cmdq_pkt, y2r_coef,
+ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_R0(idx),
+ OVL_Y2R_PARA_C_CF_RMY);
+ mtk_ddp_write_mask(cmdq_pkt, (y2r_coef << 16),
+ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_G0(idx),
+ OVL_Y2R_PARA_C_CF_GMU);
+ mtk_ddp_write_mask(cmdq_pkt, y2r_coef,
+ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_B1(idx),
+ OVL_Y2R_PARA_C_CF_BMV);
+
+ mtk_ddp_write_mask(cmdq_pkt, y2r_offset,
+ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_YUV_A_0(idx),
+ OVL_Y2R_PARA_C_CF_YA);
+ mtk_ddp_write_mask(cmdq_pkt, (y2r_offset << 16),
+ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_YUV_A_0(idx),
+ OVL_Y2R_PARA_C_CF_UA);
+ mtk_ddp_write_mask(cmdq_pkt, y2r_offset,
+ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_YUV_A_1(idx),
+ OVL_Y2R_PARA_C_CF_VA);
+
+ mtk_ddp_write_relaxed(cmdq_pkt, r2r_coef,
+ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_R2R_R0(idx));
+ mtk_ddp_write_relaxed(cmdq_pkt, r2r_coef,
+ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_R2R_G1(idx));
+ mtk_ddp_write_relaxed(cmdq_pkt, r2r_coef,
+ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_R2R_B2(idx));
+
+ mtk_ddp_write_mask(cmdq_pkt, csc_en,
+ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_CLRFMT_EXT1,
+ OVL_CLRFMT_EXT1_CSC_EN(idx));
+ }
+
if (pending->rotation & DRM_MODE_REFLECT_Y) {
con |= OVL_CON_VIRT_FLIP;
addr += (pending->height - 1) * pending->pitch;
@@ -594,15 +750,31 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
dev_err(dev, "failed to ioremap ovl\n");
return PTR_ERR(priv->regs);
}
+
+ priv->data = of_device_get_match_data(dev);
+ platform_set_drvdata(pdev, priv);
+
+ if (priv->data->crc_cnt) {
+ mtk_crtc_init_crc(&priv->crc,
+ priv->data->crc_ofs, priv->data->crc_cnt,
+ DISP_REG_OVL_TRIG, OVL_CRC_CLR);
+ }
+
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
if (ret)
dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
-#endif
-
- priv->data = of_device_get_match_data(dev);
- platform_set_drvdata(pdev, priv);
+ if (priv->data->crc_cnt) {
+ if (of_property_read_u32_index(dev->of_node,
+ "mediatek,gce-events", 0,
+ &priv->crc.cmdq_event)) {
+ dev_warn(dev, "failed to get gce-events for crc\n");
+ }
+ priv->crc.cmdq_reg = &priv->cmdq_reg;
+ mtk_crtc_create_crc_cmdq(dev, &priv->crc);
+ }
+#endif
ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
IRQF_TRIGGER_NONE, dev_name(dev), priv);
if (ret < 0) {
@@ -623,6 +795,10 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
static void mtk_disp_ovl_remove(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+ mtk_crtc_destroy_crc(&ovl->crc);
component_del(&pdev->dev, &mtk_disp_ovl_component_ops);
pm_runtime_disable(&pdev->dev);
}
@@ -693,6 +869,8 @@ static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = {
.formats = mt8195_formats,
.num_formats = ARRAY_SIZE(mt8195_formats),
.supports_clrfmt_ext = true,
+ .crc_ofs = mt8195_ovl_crc_ofs,
+ .crc_cnt = ARRAY_SIZE(mt8195_ovl_crc_ofs),
};
static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v6 14/14] drm/mediatek: Support CRC in OVL adaptor
From: Shawn Sung @ 2024-03-22 5:28 UTC (permalink / raw)
To: Chun-Kuang Hu, AngeloGioacchino Del Regno
Cc: Philipp Zabel, David Airlie, Daniel Vetter, Matthias Brugger,
Bibby Hsieh, CK Hu, Nancy . Lin, Fei Shao, Sean Paul, Jason Chen,
dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Hsiao Chien Sung
In-Reply-To: <20240322052829.9893-1-shawn.sung@mediatek.com>
From: Hsiao Chien Sung <shawn.sung@mediatek.com>
We choose Mixer as CRC generator in OVL adaptor since
its frame done event will trigger vblanks, we can know
when is safe to retrieve CRC of the frame.
In OVL adaptor, there's no image procession after Mixer,
unlike the OVL in VDOSYS0, Mixer's CRC will include all
the effects that are applied to the frame.
Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 3 +
drivers/gpu/drm/mediatek/mtk_disp_drv.h | 3 +
.../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 21 +++++++
drivers/gpu/drm/mediatek/mtk_ethdr.c | 61 +++++++++++++++++++
drivers/gpu/drm/mediatek/mtk_ethdr.h | 5 ++
5 files changed, 93 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
index cb71effda9c2a..8aab373ce67c9 100644
--- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
@@ -406,6 +406,9 @@ static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
.clk_enable = mtk_ovl_adaptor_clk_enable,
.clk_disable = mtk_ovl_adaptor_clk_disable,
.config = mtk_ovl_adaptor_config,
+ .crc_cnt = mtk_ovl_adaptor_crc_cnt,
+ .crc_entry = mtk_ovl_adaptor_crc_entry,
+ .crc_read = mtk_ovl_adaptor_crc_read,
.start = mtk_ovl_adaptor_start,
.stop = mtk_ovl_adaptor_stop,
.layer_nr = mtk_ovl_adaptor_layer_nr,
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index c476056a5cbb5..24af08b1c86d6 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -138,6 +138,9 @@ const u32 *mtk_ovl_adaptor_get_formats(struct device *dev);
size_t mtk_ovl_adaptor_get_num_formats(struct device *dev);
enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device *dev,
const struct drm_display_mode *mode);
+size_t mtk_ovl_adaptor_crc_cnt(struct device *dev);
+u32 *mtk_ovl_adaptor_crc_entry(struct device *dev);
+void mtk_ovl_adaptor_crc_read(struct device *dev);
void mtk_rdma_bypass_shadow(struct device *dev);
int mtk_rdma_clk_enable(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
index 494f7bf4a7881..9c5e565e6ef92 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -207,6 +207,27 @@ void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
mtk_ethdr_layer_config(ethdr, idx, state, cmdq_pkt);
}
+size_t mtk_ovl_adaptor_crc_cnt(struct device *dev)
+{
+ struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+
+ return mtk_ethdr_crc_cnt(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
+}
+
+u32 *mtk_ovl_adaptor_crc_entry(struct device *dev)
+{
+ struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+
+ return mtk_ethdr_crc_entry(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
+}
+
+void mtk_ovl_adaptor_crc_read(struct device *dev)
+{
+ struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+
+ mtk_ethdr_crc_read(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
+}
+
void mtk_ovl_adaptor_config(struct device *dev, unsigned int w,
unsigned int h, unsigned int vrefresh,
unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
index 951e3e82a6a1a..52caf75052d98 100644
--- a/drivers/gpu/drm/mediatek/mtk_ethdr.c
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -24,6 +24,9 @@
#define MIX_FME_CPL_INTEN BIT(1)
#define MIX_INTSTA 0x8
#define MIX_EN 0xc
+#define MIX_TRIG 0x10
+#define MIX_TRIG_CRC_EN BIT(8)
+#define MIX_TRIG_CRC_RST BIT(9)
#define MIX_RST 0x14
#define MIX_ROI_SIZE 0x18
#define MIX_DATAPATH_CON 0x1c
@@ -39,6 +42,11 @@
#define PREMULTI_SOURCE (3 << 12)
#define MIX_L_SRC_SIZE(n) (0x30 + 0x18 * (n))
#define MIX_L_SRC_OFFSET(n) (0x34 + 0x18 * (n))
+
+/* CRC register offsets for odd and even lines */
+#define MIX_CRC_ODD 0x110
+#define MIX_CRC_EVEN 0x114
+
#define MIX_FUNC_DCM0 0x120
#define MIX_FUNC_DCM1 0x124
#define MIX_FUNC_DCM_ENABLE 0xffffffff
@@ -82,6 +90,7 @@ struct mtk_ethdr {
void *vblank_cb_data;
int irq;
struct reset_control *reset_ctl;
+ struct mtk_crtc_crc crc;
};
static const char * const ethdr_clk_str[] = {
@@ -100,6 +109,32 @@ static const char * const ethdr_clk_str[] = {
"vdo_be_async",
};
+static const u32 ethdr_crc_ofs[] = {
+ MIX_CRC_ODD,
+ MIX_CRC_EVEN,
+};
+
+size_t mtk_ethdr_crc_cnt(struct device *dev)
+{
+ struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+ return priv->crc.cnt;
+}
+
+u32 *mtk_ethdr_crc_entry(struct device *dev)
+{
+ struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+ return priv->crc.va;
+}
+
+void mtk_ethdr_crc_read(struct device *dev)
+{
+ struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+ mtk_crtc_read_crc(&priv->crc, priv->ethdr_comp[ETHDR_MIXER].regs);
+}
+
void mtk_ethdr_register_vblank_cb(struct device *dev,
void (*vblank_cb)(void *),
void *vblank_cb_data)
@@ -256,6 +291,13 @@ void mtk_ethdr_start(struct device *dev)
struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
writel(1, mixer->regs + MIX_EN);
+
+ if (priv->crc.cnt) {
+ writel(MIX_TRIG_CRC_EN, mixer->regs + MIX_TRIG);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ mtk_crtc_start_crc_cmdq(&priv->crc);
+#endif
+ }
}
void mtk_ethdr_stop(struct device *dev)
@@ -263,6 +305,9 @@ void mtk_ethdr_stop(struct device *dev)
struct mtk_ethdr *priv = dev_get_drvdata(dev);
struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ mtk_crtc_stop_crc_cmdq(&priv->crc);
+#endif
writel(0, mixer->regs + MIX_EN);
writel(1, mixer->regs + MIX_RST);
reset_control_reset(priv->reset_ctl);
@@ -317,6 +362,9 @@ static int mtk_ethdr_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
+ mtk_crtc_init_crc(&priv->crc, ethdr_crc_ofs, ARRAY_SIZE(ethdr_crc_ofs),
+ MIX_TRIG, MIX_TRIG_CRC_RST);
+
for (i = 0; i < ETHDR_ID_MAX; i++) {
priv->ethdr_comp[i].dev = dev;
priv->ethdr_comp[i].regs = of_iomap(dev->of_node, i);
@@ -325,6 +373,16 @@ static int mtk_ethdr_probe(struct platform_device *pdev)
&priv->ethdr_comp[i].cmdq_base, i);
if (ret)
dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+
+ if (i == ETHDR_MIXER) {
+ if (of_property_read_u32_index(dev->of_node,
+ "mediatek,gce-events", i,
+ &priv->crc.cmdq_event)) {
+ dev_warn(dev, "failed to get gce-events for crc\n");
+ }
+ priv->crc.cmdq_reg = &priv->ethdr_comp[i].cmdq_base;
+ mtk_crtc_create_crc_cmdq(dev, &priv->crc);
+ }
#endif
dev_dbg(dev, "[DRM]regs:0x%p, node:%d\n", priv->ethdr_comp[i].regs, i);
}
@@ -365,6 +423,9 @@ static int mtk_ethdr_probe(struct platform_device *pdev)
static int mtk_ethdr_remove(struct platform_device *pdev)
{
+ struct mtk_ethdr *priv = dev_get_drvdata(&pdev->dev);
+
+ mtk_crtc_destroy_crc(&priv->crc);
component_del(&pdev->dev, &mtk_ethdr_component_ops);
return 0;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.h b/drivers/gpu/drm/mediatek/mtk_ethdr.h
index 81af9edea3f74..d17d7256bd120 100644
--- a/drivers/gpu/drm/mediatek/mtk_ethdr.h
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.h
@@ -22,4 +22,9 @@ void mtk_ethdr_register_vblank_cb(struct device *dev,
void mtk_ethdr_unregister_vblank_cb(struct device *dev);
void mtk_ethdr_enable_vblank(struct device *dev);
void mtk_ethdr_disable_vblank(struct device *dev);
+
+size_t mtk_ethdr_crc_cnt(struct device *dev);
+u32 *mtk_ethdr_crc_entry(struct device *dev);
+void mtk_ethdr_crc_read(struct device *dev);
+
#endif
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v6 08/14] drm/mediatek: Support "Pre-multiplied" alpha blending in OVL
From: Shawn Sung @ 2024-03-22 5:28 UTC (permalink / raw)
To: Chun-Kuang Hu, AngeloGioacchino Del Regno
Cc: Philipp Zabel, David Airlie, Daniel Vetter, Matthias Brugger,
Bibby Hsieh, CK Hu, Nancy . Lin, Fei Shao, Sean Paul, Jason Chen,
dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Hsiao Chien Sung
In-Reply-To: <20240322052829.9893-1-shawn.sung@mediatek.com>
From: Hsiao Chien Sung <shawn.sung@mediatek.com>
Support "Pre-multiplied" blend mode on MediaTek's chips.
Before this patch, only the "coverage" mode is supported.
Please refer to the description of the commit
"drm/mediatek: Support alpha blending in display driver"
for more information.
Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 84 +++++++++++++++++++++----
1 file changed, 73 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 2a767a823c83a..b1e5d453316cc 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -38,6 +38,7 @@
#define DISP_REG_OVL_PITCH_MSB(n) (0x0040 + 0x20 * (n))
#define OVL_PITCH_MSB_2ND_SUBBUF BIT(16)
#define DISP_REG_OVL_PITCH(n) (0x0044 + 0x20 * (n))
+#define OVL_CONST_BLEND BIT(28)
#define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n))
#define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n))
#define DISP_REG_OVL_ADDR_MT2701 0x0040
@@ -51,13 +52,16 @@
#define GMC_THRESHOLD_HIGH ((1 << GMC_THRESHOLD_BITS) / 4)
#define GMC_THRESHOLD_LOW ((1 << GMC_THRESHOLD_BITS) / 8)
+#define OVL_CON_CLRFMT_MAN BIT(23)
#define OVL_CON_BYTE_SWAP BIT(24)
-#define OVL_CON_MTX_YUV_TO_RGB (6 << 16)
+#define OVL_CON_RGB_SWAP BIT(25)
#define OVL_CON_CLRFMT_RGB (1 << 12)
#define OVL_CON_CLRFMT_RGBA8888 (2 << 12)
#define OVL_CON_CLRFMT_ARGB8888 (3 << 12)
#define OVL_CON_CLRFMT_UYVY (4 << 12)
#define OVL_CON_CLRFMT_YUYV (5 << 12)
+#define OVL_CON_MTX_YUV_TO_RGB (6 << 16)
+#define OVL_CON_CLRFMT_PARGB8888 (OVL_CON_CLRFMT_ARGB8888 | OVL_CON_CLRFMT_MAN)
#define OVL_CON_CLRFMT_RGB565(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
0 : OVL_CON_CLRFMT_RGB)
#define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
@@ -71,6 +75,24 @@
#define OVL_CON_VIRT_FLIP BIT(9)
#define OVL_CON_HORZ_FLIP BIT(10)
+#define OVL_COLOR_ALPHA GENMASK(31, 24)
+
+static inline bool is_10bit_rgb(u32 fmt)
+{
+ switch (fmt) {
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_ARGB2101010:
+ case DRM_FORMAT_RGBX1010102:
+ case DRM_FORMAT_RGBA1010102:
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_ABGR2101010:
+ case DRM_FORMAT_BGRX1010102:
+ case DRM_FORMAT_BGRA1010102:
+ return true;
+ }
+ return false;
+}
+
static const u32 mt8173_formats[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
@@ -88,12 +110,20 @@ static const u32 mt8173_formats[] = {
static const u32 mt8195_formats[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_XRGB2101010,
DRM_FORMAT_ARGB2101010,
DRM_FORMAT_BGRX8888,
DRM_FORMAT_BGRA8888,
+ DRM_FORMAT_BGRX1010102,
DRM_FORMAT_BGRA1010102,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_XBGR2101010,
+ DRM_FORMAT_ABGR2101010,
+ DRM_FORMAT_RGBX8888,
+ DRM_FORMAT_RGBA8888,
+ DRM_FORMAT_RGBX1010102,
+ DRM_FORMAT_RGBA1010102,
DRM_FORMAT_RGB888,
DRM_FORMAT_BGR888,
DRM_FORMAT_RGB565,
@@ -253,9 +283,7 @@ static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format,
reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT);
reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx);
- if (format == DRM_FORMAT_RGBA1010102 ||
- format == DRM_FORMAT_BGRA1010102 ||
- format == DRM_FORMAT_ARGB2101010)
+ if (is_10bit_rgb(format))
bit_depth = OVL_CON_CLRFMT_10_BIT;
reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx);
@@ -273,7 +301,13 @@ void mtk_ovl_config(struct device *dev, unsigned int w,
if (w != 0 && h != 0)
mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, &ovl->cmdq_reg, ovl->regs,
DISP_REG_OVL_ROI_SIZE);
- mtk_ddp_write_relaxed(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_ROI_BGCLR);
+
+ /*
+ * The background color should be opaque black (ARGB),
+ * otherwise there will be no effect with alpha blend
+ */
+ mtk_ddp_write_relaxed(cmdq_pkt, OVL_COLOR_ALPHA, &ovl->cmdq_reg,
+ ovl->regs, DISP_REG_OVL_ROI_BGCLR);
mtk_ddp_write(cmdq_pkt, 0x1, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST);
mtk_ddp_write(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST);
@@ -353,7 +387,8 @@ void mtk_ovl_layer_off(struct device *dev, unsigned int idx,
DISP_REG_OVL_RDMA_CTRL(idx));
}
-static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
+static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt,
+ unsigned int blend_mode)
{
/* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX"
* is defined in mediatek HW data sheet.
@@ -372,17 +407,37 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
return OVL_CON_CLRFMT_RGB888(ovl) | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_RGBX8888:
case DRM_FORMAT_RGBA8888:
+ return blend_mode == DRM_MODE_BLEND_COVERAGE ?
+ OVL_CON_CLRFMT_ARGB8888 :
+ OVL_CON_CLRFMT_PARGB8888;
+ case DRM_FORMAT_RGBX1010102:
+ case DRM_FORMAT_RGBA1010102:
return OVL_CON_CLRFMT_ARGB8888;
case DRM_FORMAT_BGRX8888:
case DRM_FORMAT_BGRA8888:
+ return OVL_CON_BYTE_SWAP |
+ (blend_mode == DRM_MODE_BLEND_COVERAGE ?
+ OVL_CON_CLRFMT_ARGB8888 :
+ OVL_CON_CLRFMT_PARGB8888);
+ case DRM_FORMAT_BGRX1010102:
case DRM_FORMAT_BGRA1010102:
return OVL_CON_CLRFMT_ARGB8888 | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ARGB8888:
+ return blend_mode == DRM_MODE_BLEND_COVERAGE ?
+ OVL_CON_CLRFMT_RGBA8888 :
+ OVL_CON_CLRFMT_PARGB8888;
+ case DRM_FORMAT_XRGB2101010:
case DRM_FORMAT_ARGB2101010:
return OVL_CON_CLRFMT_RGBA8888;
case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_ABGR8888:
+ return OVL_CON_RGB_SWAP |
+ (blend_mode == DRM_MODE_BLEND_COVERAGE ?
+ OVL_CON_CLRFMT_RGBA8888 :
+ OVL_CON_CLRFMT_PARGB8888);
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_ABGR2101010:
return OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_UYVY:
return OVL_CON_CLRFMT_UYVY | OVL_CON_MTX_YUV_TO_RGB;
@@ -404,6 +459,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
unsigned int fmt = pending->format;
unsigned int offset = (pending->y << 16) | pending->x;
unsigned int src_size = (pending->height << 16) | pending->width;
+ unsigned int blend_mode = state->base.pixel_blend_mode;
+ unsigned int ignore_pixel_alpha = 0;
unsigned int con;
bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR;
union overlay_pitch {
@@ -421,9 +478,14 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
return;
}
- con = ovl_fmt_convert(ovl, fmt);
- if (state->base.fb && state->base.fb->format->has_alpha)
- con |= OVL_CON_AEN | OVL_CON_ALPHA;
+ con = ovl_fmt_convert(ovl, fmt, blend_mode);
+ if (state->base.fb) {
+ con |= OVL_CON_AEN;
+ con |= state->base.alpha & OVL_CON_ALPHA;
+ }
+
+ if (state->base.fb && !state->base.fb->format->has_alpha)
+ ignore_pixel_alpha = OVL_CONST_BLEND;
if (pending->rotation & DRM_MODE_REFLECT_Y) {
con |= OVL_CON_VIRT_FLIP;
@@ -440,8 +502,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs,
DISP_REG_OVL_CON(idx));
- mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb, &ovl->cmdq_reg, ovl->regs,
- DISP_REG_OVL_PITCH(idx));
+ mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb | ignore_pixel_alpha,
+ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH(idx));
mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs,
DISP_REG_OVL_SRC_SIZE(idx));
mtk_ddp_write_relaxed(cmdq_pkt, offset, &ovl->cmdq_reg, ovl->regs,
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v6 06/14] drm/mediatek: Turn off the layers with zero width or height
From: Shawn Sung @ 2024-03-22 5:28 UTC (permalink / raw)
To: Chun-Kuang Hu, AngeloGioacchino Del Regno
Cc: Philipp Zabel, David Airlie, Daniel Vetter, Matthias Brugger,
Bibby Hsieh, CK Hu, Nancy . Lin, Fei Shao, Sean Paul, Jason Chen,
dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Hsiao Chien Sung
In-Reply-To: <20240322052829.9893-1-shawn.sung@mediatek.com>
From: Hsiao Chien Sung <shawn.sung@mediatek.com>
We found that IGT (Intel GPU Tool) will try to commit layers with
zero width or height and lead to undefined behaviors in hardware.
Disable the layers in such a situation.
Fixes: 777b7bc86a0a ("UPSTREAM: drm/mediatek: Add ovl_adaptor support for MT8195")
Fixes: fa97fe71f6f9 ("UPSTREAM: drm/mediatek: Add ETHDR support for MT8195")
Reviewed-by: CK Hu <ck.hu@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 2 +-
drivers/gpu/drm/mediatek/mtk_ethdr.c | 7 ++++++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
index 4fbf61c6b5423..494f7bf4a7881 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -158,7 +158,7 @@ void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
merge = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 + idx];
ethdr = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0];
- if (!pending->enable) {
+ if (!pending->enable || !pending->width || !pending->height) {
mtk_merge_stop_cmdq(merge, cmdq_pkt);
mtk_mdp_rdma_stop(rdma_l, cmdq_pkt);
mtk_mdp_rdma_stop(rdma_r, cmdq_pkt);
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
index ac4132210585e..6bf398850e85f 100644
--- a/drivers/gpu/drm/mediatek/mtk_ethdr.c
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -160,7 +160,12 @@ void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
if (idx >= 4)
return;
- if (!pending->enable) {
+ if (!pending->enable || !pending->width || !pending->height) {
+ /*
+ * instead of disabling layer with MIX_SRC_CON directly
+ * set the size to 0 to avoid screen shift due to mixer
+ * mode switch (hardware behavior)
+ */
mtk_ddp_write(cmdq_pkt, 0, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(idx));
return;
}
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v6 12/14] drm/mediatek: Support CRC in display driver
From: Shawn Sung @ 2024-03-22 5:28 UTC (permalink / raw)
To: Chun-Kuang Hu, AngeloGioacchino Del Regno
Cc: Philipp Zabel, David Airlie, Daniel Vetter, Matthias Brugger,
Bibby Hsieh, CK Hu, Nancy . Lin, Fei Shao, Sean Paul, Jason Chen,
dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Hsiao Chien Sung
In-Reply-To: <20240322052829.9893-1-shawn.sung@mediatek.com>
From: Hsiao Chien Sung <shawn.sung@mediatek.com>
Register CRC related function pointers to support
CRC retrieval.
Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_crtc.c | 260 ++++++++++++++++++++++++
drivers/gpu/drm/mediatek/mtk_crtc.h | 38 ++++
drivers/gpu/drm/mediatek/mtk_ddp_comp.h | 3 +
3 files changed, 301 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c
index d811e4e73a36c..6440c5fb336d7 100644
--- a/drivers/gpu/drm/mediatek/mtk_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
@@ -18,6 +18,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
+#include <drm/drm_vblank_work.h>
#include "mtk_crtc.h"
#include "mtk_ddp_comp.h"
@@ -69,6 +70,9 @@ struct mtk_crtc {
/* lock for display hardware access */
struct mutex hw_lock;
bool config_updating;
+
+ struct mtk_ddp_comp *crc_provider;
+ struct drm_vblank_work crc_work;
};
struct mtk_crtc_state {
@@ -703,6 +707,71 @@ static void mtk_crtc_update_output(struct drm_crtc *crtc,
}
}
+static void mtk_crtc_crc_work(struct kthread_work *base)
+{
+ struct drm_vblank_work *work = to_drm_vblank_work(base);
+ struct mtk_crtc *mtk_crtc =
+ container_of(work, typeof(*mtk_crtc), crc_work);
+
+ if (mtk_crtc->base.crc.opened) {
+ struct mtk_ddp_comp *comp = mtk_crtc->crc_provider;
+ u64 vblank = drm_crtc_vblank_count(&mtk_crtc->base);
+
+ comp->funcs->crc_read(comp->dev);
+
+ /* could take more than 50ms to finish */
+ drm_crtc_add_crc_entry(&mtk_crtc->base, true, vblank,
+ comp->funcs->crc_entry(comp->dev));
+
+ drm_vblank_work_schedule(&mtk_crtc->crc_work, vblank + 1, true);
+ }
+}
+
+static int mtk_crtc_set_crc_source(struct drm_crtc *crtc, const char *src)
+{
+ struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
+
+ if (!src)
+ return -EINVAL;
+
+ if (strcmp(src, "auto") != 0) {
+ DRM_ERROR("%s(crtc-%d): unknown source '%s'\n",
+ __func__, drm_crtc_index(crtc), src);
+ return -EINVAL;
+ }
+
+ /*
+ * skip the first crc because the first frame (vblank + 1) is configured
+ * by mtk_crtc_ddp_hw_init() when atomic enable
+ */
+ drm_vblank_work_schedule(&mtk_crtc->crc_work,
+ drm_crtc_vblank_count(crtc) + 2, false);
+ return 0;
+}
+
+static int mtk_crtc_verify_crc_source(struct drm_crtc *crtc, const char *src,
+ size_t *cnt)
+{
+ struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
+ struct mtk_ddp_comp *comp = mtk_crtc->crc_provider;
+
+ if (!comp) {
+ DRM_ERROR("%s(crtc-%d): no crc provider\n",
+ __func__, drm_crtc_index(crtc));
+ return -ENOENT;
+ }
+
+ if (src && strcmp(src, "auto") != 0) {
+ DRM_ERROR("%s(crtc-%d): unknown source '%s'\n",
+ __func__, drm_crtc_index(crtc), src);
+ return -EINVAL;
+ }
+
+ *cnt = comp->funcs->crc_cnt(comp->dev);
+
+ return 0;
+}
+
int mtk_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
struct mtk_plane_state *state)
{
@@ -751,6 +820,8 @@ static void mtk_crtc_atomic_enable(struct drm_crtc *crtc,
drm_crtc_vblank_on(crtc);
mtk_crtc->enabled = true;
+
+ drm_vblank_work_init(&mtk_crtc->crc_work, crtc, mtk_crtc_crc_work);
}
static void mtk_crtc_atomic_disable(struct drm_crtc *crtc,
@@ -840,6 +911,8 @@ static const struct drm_crtc_funcs mtk_crtc_funcs = {
.atomic_destroy_state = mtk_crtc_destroy_state,
.enable_vblank = mtk_crtc_enable_vblank,
.disable_vblank = mtk_crtc_disable_vblank,
+ .set_crc_source = mtk_crtc_set_crc_source,
+ .verify_crc_source = mtk_crtc_verify_crc_source,
};
static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
@@ -1033,6 +1106,11 @@ int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,
if (comp->funcs->ctm_set)
has_ctm = true;
+
+ if (comp->funcs->crc_cnt &&
+ comp->funcs->crc_entry &&
+ comp->funcs->crc_read)
+ mtk_crtc->crc_provider = comp;
}
mtk_ddp_comp_register_vblank_cb(comp, mtk_crtc_ddp_irq,
@@ -1136,3 +1214,185 @@ int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,
return 0;
}
+
+void mtk_crtc_init_crc(struct mtk_crtc_crc *crc, const u32 *crc_offset_table,
+ size_t crc_count, u32 reset_offset, u32 reset_mask)
+{
+ crc->ofs = crc_offset_table;
+ crc->cnt = crc_count;
+ crc->rst_ofs = reset_offset;
+ crc->rst_msk = reset_mask;
+ crc->va = kcalloc(crc->cnt, sizeof(*crc->va), GFP_KERNEL);
+ if (!crc->va) {
+ DRM_ERROR("failed to allocate memory for crc\n");
+ crc->cnt = 0;
+ }
+}
+
+void mtk_crtc_read_crc(struct mtk_crtc_crc *crc, void __iomem *reg)
+{
+ if (!crc->cnt || !crc->ofs || !crc->va)
+ return;
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ /* sync to see the most up-to-date copy of the DMA buffer */
+ dma_sync_single_for_cpu(crc->cmdq_client.chan->mbox->dev,
+ crc->pa, crc->cnt * sizeof(*crc->va),
+ DMA_FROM_DEVICE);
+#endif
+}
+
+void mtk_crtc_destroy_crc(struct mtk_crtc_crc *crc)
+{
+ if (!crc->cnt)
+ return;
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ if (crc->pa) {
+ dma_unmap_single(crc->cmdq_client.chan->mbox->dev,
+ crc->pa, crc->cnt * sizeof(*crc->va),
+ DMA_TO_DEVICE);
+ crc->pa = 0;
+ }
+ if (crc->cmdq_client.chan) {
+ mtk_drm_cmdq_pkt_destroy(&crc->cmdq_handle);
+ mbox_free_channel(crc->cmdq_client.chan);
+ crc->cmdq_client.chan = NULL;
+ }
+#endif
+ kfree(crc->va);
+ crc->va = NULL;
+ crc->cnt = 0;
+}
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+/**
+ * mtk_crtc_create_crc_cmdq - Create a CMDQ thread for syncing the CRCs
+ * @dev: Kernel device node of the CRC provider
+ * @crc: Pointer of the CRC to init
+ *
+ * This function will create a looping thread on GCE (Global Command Engine) to
+ * keep the CRC up to date by monitoring the assigned event (usually the frame
+ * done event) of the CRC provider, and read the CRCs from the registers to a
+ * shared memory for the workqueue to read. To start/stop the looping thread,
+ * please call `mtk_crtc_start_crc_cmdq()` and `mtk_crtc_stop_crc_cmdq()`
+ * defined blow.
+ *
+ * The reason why we don't update the CRCs with CPU is that the front porch of
+ * 4K60 timing in CEA-861 is less than 60us, and register read/write speed is
+ * relatively unreliable comparing to GCE due to the bus design.
+ *
+ * We must create a new thread instead of using the original one for plane
+ * update is because:
+ * 1. We cannot add another wait-for-event command at the end of cmdq packet, or
+ * the cmdq callback will delay for too long
+ * 2. Will get the CRC of the previous frame if using the existed wait-for-event
+ * command which is at the beginning of the packet
+ */
+void mtk_crtc_create_crc_cmdq(struct device *dev, struct mtk_crtc_crc *crc)
+{
+ int i;
+
+ if (!crc->cnt) {
+ dev_warn(dev, "%s: not support\n", __func__);
+ goto cleanup;
+ }
+
+ if (!crc->ofs) {
+ dev_warn(dev, "%s: not defined\n", __func__);
+ goto cleanup;
+ }
+
+ crc->cmdq_client.client.dev = dev;
+ crc->cmdq_client.client.tx_block = false;
+ crc->cmdq_client.client.knows_txdone = true;
+ crc->cmdq_client.client.rx_callback = NULL;
+ crc->cmdq_client.chan = mbox_request_channel(&crc->cmdq_client.client, 0);
+ if (IS_ERR(crc->cmdq_client.chan)) {
+ dev_warn(dev, "%s: failed to create mailbox client\n", __func__);
+ crc->cmdq_client.chan = NULL;
+ goto cleanup;
+ }
+
+ if (mtk_drm_cmdq_pkt_create(&crc->cmdq_client, &crc->cmdq_handle, PAGE_SIZE)) {
+ dev_warn(dev, "%s: failed to create cmdq packet\n", __func__);
+ goto cleanup;
+ }
+
+ if (!crc->va) {
+ dev_warn(dev, "%s: no memory\n", __func__);
+ goto cleanup;
+ }
+
+ /* map the entry to get a dma address for cmdq to store the crc */
+ crc->pa = dma_map_single(crc->cmdq_client.chan->mbox->dev,
+ crc->va, crc->cnt * sizeof(*crc->va),
+ DMA_FROM_DEVICE);
+
+ if (dma_mapping_error(crc->cmdq_client.chan->mbox->dev, crc->pa)) {
+ dev_err(dev, "%s: failed to map dma\n", __func__);
+ goto cleanup;
+ }
+
+ if (crc->cmdq_event)
+ cmdq_pkt_wfe(&crc->cmdq_handle, crc->cmdq_event, true);
+
+ for (i = 0; i < crc->cnt; i++) {
+ /* put crc to spr1 register */
+ cmdq_pkt_read_s(&crc->cmdq_handle, crc->cmdq_reg->subsys,
+ crc->cmdq_reg->offset + crc->ofs[i],
+ CMDQ_THR_SPR_IDX1);
+
+ /* copy spr1 register to physical address of the crc */
+ cmdq_pkt_assign(&crc->cmdq_handle, CMDQ_THR_SPR_IDX0,
+ CMDQ_ADDR_HIGH(crc->pa + i * sizeof(*crc->va)));
+ cmdq_pkt_write_s(&crc->cmdq_handle, CMDQ_THR_SPR_IDX0,
+ CMDQ_ADDR_LOW(crc->pa + i * sizeof(*crc->va)),
+ CMDQ_THR_SPR_IDX1);
+ }
+ /* reset crc */
+ mtk_ddp_write_mask(&crc->cmdq_handle, ~0, crc->cmdq_reg, 0,
+ crc->rst_ofs, crc->rst_msk);
+
+ /* clear reset bit */
+ mtk_ddp_write_mask(&crc->cmdq_handle, 0, crc->cmdq_reg, 0,
+ crc->rst_ofs, crc->rst_msk);
+
+ /* jump to head of the cmdq packet */
+ cmdq_pkt_jump(&crc->cmdq_handle, crc->cmdq_handle.pa_base);
+
+ return;
+cleanup:
+ mtk_crtc_destroy_crc(crc);
+}
+
+/**
+ * mtk_crtc_start_crc_cmdq - Start the GCE looping thread for CRC update
+ * @crc: Pointer of the CRC information
+ */
+void mtk_crtc_start_crc_cmdq(struct mtk_crtc_crc *crc)
+{
+ if (!crc->cmdq_client.chan)
+ return;
+
+ dma_sync_single_for_device(crc->cmdq_client.chan->mbox->dev,
+ crc->cmdq_handle.pa_base,
+ crc->cmdq_handle.cmd_buf_size,
+ DMA_TO_DEVICE);
+ mbox_send_message(crc->cmdq_client.chan, &crc->cmdq_handle);
+ mbox_client_txdone(crc->cmdq_client.chan, 0);
+}
+
+/**
+ * mtk_crtc_stop_crc_cmdq - Stop the GCE looping thread for CRC update
+ * @crc: Pointer of the CRC information
+ */
+void mtk_crtc_stop_crc_cmdq(struct mtk_crtc_crc *crc)
+{
+ if (!crc->cmdq_client.chan)
+ return;
+
+ /* remove all the commands from the cmdq packet */
+ mbox_flush(crc->cmdq_client.chan, 2000);
+}
+#endif
diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.h b/drivers/gpu/drm/mediatek/mtk_crtc.h
index 388e900b6f4de..a79c4611754e4 100644
--- a/drivers/gpu/drm/mediatek/mtk_crtc.h
+++ b/drivers/gpu/drm/mediatek/mtk_crtc.h
@@ -14,6 +14,34 @@
#define MTK_MAX_BPC 10
#define MTK_MIN_BPC 3
+/**
+ * struct mtk_crtc_crc - crc related information
+ * @ofs: register offset of crc
+ * @rst_ofs: register offset of crc reset
+ * @rst_msk: register mask of crc reset
+ * @cnt: count of crc
+ * @va: pointer to the start of crc array
+ * @pa: physical address of the crc for gce to access
+ * @cmdq_event: the event to trigger the cmdq
+ * @cmdq_reg: address of the register that cmdq is going to access
+ * @cmdq_client: handler to control cmdq (mbox channel, thread ...etc.)
+ * @cmdq_handle: cmdq packet to store the commands
+ */
+struct mtk_crtc_crc {
+ const u32 *ofs;
+ u32 rst_ofs;
+ u32 rst_msk;
+ size_t cnt;
+ u32 *va;
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ dma_addr_t pa;
+ u32 cmdq_event;
+ struct cmdq_client_reg *cmdq_reg;
+ struct cmdq_client cmdq_client;
+ struct cmdq_pkt cmdq_handle;
+#endif
+};
+
void mtk_crtc_commit(struct drm_crtc *crtc);
int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,
unsigned int path_len, int priv_data_index,
@@ -25,4 +53,14 @@ void mtk_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
struct drm_atomic_state *plane_state);
struct device *mtk_crtc_dma_dev_get(struct drm_crtc *crtc);
+void mtk_crtc_init_crc(struct mtk_crtc_crc *crc, const u32 *crc_offset_table,
+ size_t crc_count, u32 reset_offset, u32 reset_mask);
+void mtk_crtc_read_crc(struct mtk_crtc_crc *crc, void __iomem *reg);
+void mtk_crtc_destroy_crc(struct mtk_crtc_crc *crc);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+void mtk_crtc_create_crc_cmdq(struct device *dev, struct mtk_crtc_crc *crc);
+void mtk_crtc_start_crc_cmdq(struct mtk_crtc_crc *crc);
+void mtk_crtc_stop_crc_cmdq(struct mtk_crtc_crc *crc);
+#endif
+
#endif /* MTK_CRTC_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
index f7fe2e08dc8e2..b9c79e740abe0 100644
--- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
@@ -88,6 +88,9 @@ struct mtk_ddp_comp_funcs {
void (*remove)(struct device *dev, struct mtk_mutex *mutex);
unsigned int (*encoder_index)(struct device *dev);
enum drm_mode_status (*mode_valid)(struct device *dev, const struct drm_display_mode *mode);
+ size_t (*crc_cnt)(struct device *dev);
+ u32 *(*crc_entry)(struct device *dev);
+ void (*crc_read)(struct device *dev);
};
struct mtk_ddp_comp {
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v6 04/14] drm/mediatek: Add DRM_MODE_ROTATE_0 to rotation property
From: Shawn Sung @ 2024-03-22 5:28 UTC (permalink / raw)
To: Chun-Kuang Hu, AngeloGioacchino Del Regno
Cc: Philipp Zabel, David Airlie, Daniel Vetter, Matthias Brugger,
Bibby Hsieh, CK Hu, Nancy . Lin, Fei Shao, Sean Paul, Jason Chen,
dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Hsiao Chien Sung
In-Reply-To: <20240322052829.9893-1-shawn.sung@mediatek.com>
From: Hsiao Chien Sung <shawn.sung@mediatek.com>
Always add DRM_MODE_ROTATE_0 to rotation property to meet
IGT's (Intel GPU Tools) requirement.
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_ddp_comp.h | 6 +++++-
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 21 +++++++++------------
drivers/gpu/drm/mediatek/mtk_plane.c | 2 +-
3 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
index 26236691ce4c2..f7fe2e08dc8e2 100644
--- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
@@ -192,7 +192,11 @@ unsigned int mtk_ddp_comp_supported_rotations(struct mtk_ddp_comp *comp)
if (comp->funcs && comp->funcs->supported_rotations)
return comp->funcs->supported_rotations(comp->dev);
- return 0;
+ /*
+ * In order to pass IGT tests, DRM_MODE_ROTATE_0 is required when
+ * rotation is not supported.
+ */
+ return DRM_MODE_ROTATE_0;
}
static inline unsigned int mtk_ddp_comp_layer_nr(struct mtk_ddp_comp *comp)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 0ebeaf9830d83..2a767a823c83a 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -288,6 +288,10 @@ unsigned int mtk_ovl_layer_nr(struct device *dev)
unsigned int mtk_ovl_supported_rotations(struct device *dev)
{
+ /*
+ * although currently OVL can only do reflection,
+ * reflect x + reflect y = rotate 180
+ */
return DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y;
}
@@ -296,27 +300,20 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int idx,
struct mtk_plane_state *mtk_state)
{
struct drm_plane_state *state = &mtk_state->base;
- unsigned int rotation = 0;
- rotation = drm_rotation_simplify(state->rotation,
- DRM_MODE_ROTATE_0 |
- DRM_MODE_REFLECT_X |
- DRM_MODE_REFLECT_Y);
- rotation &= ~DRM_MODE_ROTATE_0;
-
- /* We can only do reflection, not rotation */
- if ((rotation & DRM_MODE_ROTATE_MASK) != 0)
+ /* check if any unsupported rotation is set */
+ if (state->rotation & ~mtk_ovl_supported_rotations(dev))
return -EINVAL;
/*
* TODO: Rotating/reflecting YUV buffers is not supported at this time.
* Only RGB[AX] variants are supported.
+ * Since DRM_MODE_ROTATE_0 means "no rotation", we should not
+ * reject layers with this property.
*/
- if (state->fb->format->is_yuv && rotation != 0)
+ if (state->fb->format->is_yuv && (state->rotation & ~DRM_MODE_ROTATE_0))
return -EINVAL;
- state->rotation = rotation;
-
return 0;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_plane.c b/drivers/gpu/drm/mediatek/mtk_plane.c
index a74b26d359857..1723d4333f371 100644
--- a/drivers/gpu/drm/mediatek/mtk_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_plane.c
@@ -338,7 +338,7 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
return err;
}
- if (supported_rotations & ~DRM_MODE_ROTATE_0) {
+ if (supported_rotations) {
err = drm_plane_create_rotation_property(plane,
DRM_MODE_ROTATE_0,
supported_rotations);
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v6 11/14] drm/mediatek: Support "None" alpha blending in Mixer
From: Shawn Sung @ 2024-03-22 5:28 UTC (permalink / raw)
To: Chun-Kuang Hu, AngeloGioacchino Del Regno
Cc: Philipp Zabel, David Airlie, Daniel Vetter, Matthias Brugger,
Bibby Hsieh, CK Hu, Nancy . Lin, Fei Shao, Sean Paul, Jason Chen,
dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Hsiao Chien Sung
In-Reply-To: <20240322052829.9893-1-shawn.sung@mediatek.com>
From: Hsiao Chien Sung <shawn.sung@mediatek.com>
Support "None" blend mode on MediaTek's chips.
Please refer to the description of the commit
"drm/mediatek: Support alpha blending in display driver"
for more information.
Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_ethdr.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
index 4b12ca285e84b..951e3e82a6a1a 100644
--- a/drivers/gpu/drm/mediatek/mtk_ethdr.c
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -178,7 +178,8 @@ void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
if (state->base.pixel_blend_mode != DRM_MODE_BLEND_COVERAGE)
mix_con |= PREMULTI_SOURCE;
- if (state->base.fb && !state->base.fb->format->has_alpha) {
+ if (state->base.pixel_blend_mode == DRM_MODE_BLEND_PIXEL_NONE ||
+ (state->base.fb && !state->base.fb->format->has_alpha)) {
/*
* Mixer doesn't support CONST_BLD mode,
* use a trick to make the output equivalent
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v6 07/14] drm/mediatek: Support alpha blending in display driver
From: Shawn Sung @ 2024-03-22 5:28 UTC (permalink / raw)
To: Chun-Kuang Hu, AngeloGioacchino Del Regno
Cc: Philipp Zabel, David Airlie, Daniel Vetter, Matthias Brugger,
Bibby Hsieh, CK Hu, Nancy . Lin, Fei Shao, Sean Paul, Jason Chen,
dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Hsiao Chien Sung
In-Reply-To: <20240322052829.9893-1-shawn.sung@mediatek.com>
From: Hsiao Chien Sung <shawn.sung@mediatek.com>
Support "Pre-multiplied" and "None" blend mode on MediaTek's chips by
adding correct blend mode property when the planes init.
Before this patch, only the "Coverage" mode (default) is supported.
For more information, there are three pixel blend modes in DRM driver:
"None", "Pre-multiplied", and "Coverage".
To understand the difference between these modes, let's take a look at
the following two approaches to do alpha blending:
1. Straight:
dst.RGB = src.RGB * src.A + dst.RGB * (1 - src.A)
This is straightforward and easy to understand, when the source layer is
compositing with the destination layer, it's alpha will affect the
result. This is also known as "post-multiplied", or "Coverage" mode.
2. Pre-multiplied:
dst.RGB = src.RGB + dst.RGB * (1 - src.A)
Since the source RGB have already multiplied its alpha, only destination
RGB need to multiply it. This is the "Pre-multiplied" mode in DRM.
For the "None" blend mode in DRM, it means the pixel alpha is ignored
when compositing the layers, only the constant alpha for the composited
layer will take effects.
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: CK Hu <ck.hu@mediatek.com>
Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_plane.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_plane.c b/drivers/gpu/drm/mediatek/mtk_plane.c
index 1723d4333f371..5bf757a3ef202 100644
--- a/drivers/gpu/drm/mediatek/mtk_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_plane.c
@@ -346,6 +346,17 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
DRM_INFO("Create rotation property failed\n");
}
+ err = drm_plane_create_alpha_property(plane);
+ if (err)
+ DRM_ERROR("failed to create property: alpha\n");
+
+ err = drm_plane_create_blend_mode_property(plane,
+ BIT(DRM_MODE_BLEND_PREMULTI) |
+ BIT(DRM_MODE_BLEND_COVERAGE) |
+ BIT(DRM_MODE_BLEND_PIXEL_NONE));
+ if (err)
+ DRM_ERROR("failed to create property: blend_mode\n");
+
drm_plane_helper_add(plane, &mtk_plane_helper_funcs);
return 0;
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v6 01/14] soc: mediatek: Disable 9-bit alpha in ETHDR
From: Shawn Sung @ 2024-03-22 5:28 UTC (permalink / raw)
To: Chun-Kuang Hu, AngeloGioacchino Del Regno
Cc: Philipp Zabel, David Airlie, Daniel Vetter, Matthias Brugger,
Bibby Hsieh, CK Hu, Nancy . Lin, Fei Shao, Sean Paul, Jason Chen,
dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Hsiao Chien Sung
In-Reply-To: <20240322052829.9893-1-shawn.sung@mediatek.com>
From: Hsiao Chien Sung <shawn.sung@mediatek.com>
ETHDR 9-bit alpha should be disabled by default,
otherwise alpha blending will not work.
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
drivers/soc/mediatek/mtk-mmsys.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index afb2c40c85c15..00eff18a3bcea 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -236,6 +236,7 @@ void mtk_mmsys_mixer_in_config(struct device *dev, int idx, bool alpha_sel, u16
mtk_mmsys_update_bits(mmsys, MT8195_VDO1_MIXER_IN1_ALPHA + (idx - 1) * 4, ~0,
alpha << 16 | alpha, cmdq_pkt);
+ mtk_mmsys_update_bits(mmsys, MT8195_VDO1_HDR_TOP_CFG, BIT(15 + idx), 0, cmdq_pkt);
mtk_mmsys_update_bits(mmsys, MT8195_VDO1_HDR_TOP_CFG, BIT(19 + idx),
alpha_sel << (19 + idx), cmdq_pkt);
mtk_mmsys_update_bits(mmsys, MT8195_VDO1_MIXER_IN1_PAD + (idx - 1) * 4,
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH 1/3] dt-bindings: mtd: atmel-nand: convert txt to yaml
From: Balamanikandan.Gunasundar @ 2024-03-22 4:27 UTC (permalink / raw)
To: conor
Cc: robh, conor+dt, linux-kernel, vigneshr, alexandre.belloni,
devicetree, richard, claudiu.beznea, linux-mtd,
krzysztof.kozlowski+dt, miquel.raynal, linux-arm-kernel
In-Reply-To: <20240320-quicksand-attentive-14610103237b@spud>
Hi Conor,
On 20/03/24 10:05 pm, Conor Dooley wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
>
> ForwardedMessage.eml
>
> Subject:
> Re: [PATCH 1/3] dt-bindings: mtd: atmel-nand: convert txt to yaml
> From:
> Conor Dooley <conor@kernel.org>
> Date:
> 20/03/24, 10:05 pm
>
> To:
> Balamanikandan Gunasundar <balamanikandan.gunasundar@microchip.com>
> CC:
> Miquel Raynal <miquel.raynal@bootlin.com>, Richard Weinberger
> <richard@nod.at>, Vignesh Raghavendra <vigneshr@ti.com>, Rob Herring
> <robh@kernel.org>, Krzysztof Kozlowski
> <krzysztof.kozlowski+dt@linaro.org>, Conor Dooley <conor+dt@kernel.org>,
> Nicolas Ferre <nicolas.ferre@microchip.com>, Alexandre Belloni
> <alexandre.belloni@bootlin.com>, Claudiu Beznea
> <claudiu.beznea@tuxon.dev>, linux-mtd@lists.infradead.org,
> devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
> linux-kernel@vger.kernel.org
>
>
> On Wed, Mar 20, 2024 at 11:22:07AM +0530, Balamanikandan Gunasundar wrote:
>> Convert text to yaml for atmel nand controller
>>
>> Signed-off-by: Balamanikandan Gunasundar<balamanikandan.gunasundar@microchip.com>
>> ---
>> .../devicetree/bindings/mtd/atmel-nand.txt | 50 -------
>> .../devicetree/bindings/mtd/atmel-nand.yaml | 166 +++++++++++++++++++++
>> MAINTAINERS | 2 +-
>> 3 files changed, 167 insertions(+), 51 deletions(-)
>> diff --git a/Documentation/devicetree/bindings/mtd/atmel-nand.yaml b/Documentation/devicetree/bindings/mtd/atmel-nand.yaml
>> new file mode 100644
>> index 000000000000..a5482d292293
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mtd/atmel-nand.yaml
> Filename matching a compatible please.
>
>> @@ -0,0 +1,166 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id:http://devicetree.org/schemas/mtd/atmel-nand.yaml#
>> +$schema:http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Atmel NAND flash controller
>> +
>> +maintainers:
>> + - Balamanikandan Gunasundar<balamanikandan.gunasundar@microchip.com>
>> +
>> +description: |
>> + The NAND flash controller node should be defined under the EBI bus (see
>> + Documentation/devicetree/bindings/memory-controllers/atmel,ebi.txt|yaml).
> text|yaml?
>
>> + One or several NAND devices can be defined under this NAND controller.
>> + The NAND controller might be connected to an ECC engine.
>> +
>> +properties:
>> + compatible:
>> + oneOf:
>> + - items:
>> + - enum:
> This is just an enum, drop the items and oneof.
>
>> + - atmel,at91rm9200-nand-controller
>> + - atmel,at91sam9260-nand-controller
>> + - atmel,at91sam9261-nand-controller
>> + - atmel,at91sam9g45-nand-controller
>> + - atmel,sama5d3-nand-controller
>> + - microchip,sam9x60-nand-controller
>> +
>> + ranges:
>> + description: empty ranges property to forward EBI ranges definitions.
>> +
>> + ecc-engine:
>> + description:
>> + phandle to the PMECC block. Only meaningful if the SoC embeds a PMECC
>> + engine.
>> +
>> +allOf:
>> + - if:
>> + properties:
>> + compatible:
>> + contains:
>> + enum:
>> + - atmel,at91rm9200-nand-controller
>> + - atmel,at91sam9260-nand-controller
>> + - atmel,at91sam9261-nand-controller
>> + - atmel,at91sam9g45-nand-controller
>> + - atmel,sama5d3-nand-controller
>> + - microchip,sam9x60-nand-controller
>> + then:
>> + properties:
>> + "#address-cells":
>> + const: 2
>> +
>> + "#size-cells":
>> + const: 1
> Why is this in an if? Isn't this all of the devices in the binding?
>
The default nand-controller.yaml defines this as const values.
(#address-cell : 1 and #size-cells : 1). I am trying to override this
const value. May be I should think about better approach ?
>> +
>> + - if:
>> + properties:
>> + compatible:
>> + contains:
>> + const: atmel,sama5d3-nand-controller
>> + then:
>> + properties:
>> + atmel,nfc-io:
>> + $ref: /schemas/types.yaml#/definitions/phandle
>> + description: phandle to the NFC IO block.
>> +
>> + atmel,nfc-sram:
>> + $ref: /schemas/types.yaml#/definitions/phandle
>> + description: phandle to the NFC SRAM block
> Please define the properties at the top level and use if statements to
> constrain them.
>
>> +
>> +required:
>> + - compatible
>> + - ranges
>> + - "#address-cells"
>> + - "#size-cells"
>> +
>> +patternProperties:
>> + "^nand@[a-f0-9]$":
>> + type: object
>> + $ref: nand-chip.yaml#
>> + description:
>> + NAND chip bindings. All generic properties described in
>> + Documentation/devicetree/bindings/mtd/{common,nand}.txt also apply to
>> + the NAND device node, and NAND partitions should be defined under the
>> + NAND node as described in
>> + Documentation/devicetree/bindings/mtd/partition.txt.
> These files do not exist.
>
Apologies for copying the content from the text file. I will correct this.
>> + properties:
>> + reg:
>> + minItems: 1
>> + description:
>> + describes the CS lines assigned to the NAND device. If the NAND device
>> + exposes multiple CS lines (multi-dies chips), your reg property will
>> + contain X tuples of 3 entries.
> The "if" here is not accurate. Your binding mandates there being 3
> entries.
>
>> + reg = <0x3 0x0 0x800000>;
>> + 1st entry - the CS line this NAND chip is connected to
>> + 2nd entry - the base offset of the memory region assigned to this
>> + device (always 0)
>> + 3rd entry - the memory region size (always 0x800000)
>> +
>> + rb-gpios:
>> + description:
>> + the GPIO(s) used to check the Ready/Busy status of the NAND.
>> +
>> + cs-gpios:
>> + description:
>> + the GPIO(s) used to control the CS line.
>> +
>> + det-gpios:
>> + description:
>> + the GPIO used to detect if a Smartmedia Card is present.
>> +
>> + "atmel,rb":
>> + description:
>> + an integer identifying the native Ready/Busy pin. Only meaningful
>> + on sama5 SoCs.
> Then please constrain it to sama5 SoCs only 🙂
>
>> + $ref: /schemas/types.yaml#/definitions/uint32
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> + - |
>> + nfc_io: nfc-io@70000000 {
>> + compatible = "atmel,sama5d3-nfc-io", "syscon";
>> + reg = <0x70000000 0x8000000>;
>> + };
> What's this got to do with the binding?
>
>> + pmecc: ecc-engine@ffffc070 {
>> + compatible = "atmel,at91sam9g45-pmecc";
>> + reg = <0xffffc070 0x490>,
>> + <0xffffc500 0x100>;
>> + };
>> +
>> + ebi: ebi@10000000 {
> Drop the unused label.
>
> Same applies here, read the coding style about how to write dts nodes
> please.
>
Yes. I should fix the alignment. I will send a v2 shortly
Thanks,
Bala
> Thanks,
> Conor.
>
>> + compatible = "atmel,sama5d3-ebi";
>> + #address-cells = <2>;
>> + #size-cells = <1>;
>> + atmel,smc = <&hsmc>;
>> + reg = <0x10000000 0x10000000
>> + 0x40000000 0x30000000>;
>> + ranges = <0x0 0x0 0x10000000 0x10000000
>> + 0x1 0x0 0x40000000 0x10000000
>> + 0x2 0x0 0x50000000 0x10000000
>> + 0x3 0x0 0x60000000 0x10000000>;
>> + clocks = <&mck>;
>> +
>> + nandflash_controller: nandflash-controller {
>> + compatible = "atmel,sama5d3-nand-controller";
>> + ecc-engine = <&pmecc>;
>> + #address-cells = <2>;
>> + #size-cells = <1>;
>> + ranges;
>> +
>> + nand@3 {
>> + reg = <0x3 0x0 0x800000>;
>> + atmel,rb = <0>;
>> +
>> + /*
>> + * Put generic NAND/MTD properties and
>> + * subnodes here.
>> + */
>> + };
>> + };
>> + };
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index b6582bd3eb2c..3f2a6756223f 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -14503,7 +14503,7 @@ MICROCHIP NAND DRIVER
>> M: Balamanikandan Gunasundar<balamanikandan.gunasundar@microchip.com>
>> L: linux-mtd@lists.infradead.org
>> S: Supported
>> -F: Documentation/devicetree/bindings/mtd/atmel-nand.txt
>> +F: Documentation/devicetree/bindings/mtd/atmel-*.yaml
>> F: drivers/mtd/nand/raw/atmel/*
>>
>> MICROCHIP OTPC DRIVER
>>
>> --
>> 2.25.1
>>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3] dt-bindings: i2c: nxp,pnx-i2c: Convert to dtschema
From: Animesh Agarwal @ 2024-03-22 4:03 UTC (permalink / raw)
To: Andi Shyti
Cc: Conor Dooley, Vladimir Zapolskiy, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-arm-kernel, linux-i2c,
devicetree, linux-kernel
In-Reply-To: <171105547918.707638.11304000819202245225.b4-ty@kernel.org>
On Fri, Mar 22, 2024 at 2:41 AM Andi Shyti <andi.shyti@kernel.org> wrote:
> Applied to i2c/i2c-host on
>
> git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux.git
>
> Thank you,
> Andi
>
> Patches applied
> ===============
> [1/1] dt-bindings: i2c: nxp,pnx-i2c: Convert to dtschema
> commit: e73b7060deb7da42f4e887cb726d0c7019a84cd0
Thanks Andi.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox