Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [RFC PATCH] net: stmmac: Fix the problem about interrupt storm
From: cathy cai @ 2024-04-03  2:01 UTC (permalink / raw)
  To: Romain Gantois
  Cc: Cathy Cai, davem, edumazet, kuba, pabeni, mcoquelin.stm32, netdev,
	linux-kernel, xuewen.yan94, cixi.geng1, wade.shu, zhiguo.niu,
	alexandre.torgue, joabreu, linux-stm32, linux-arm-kernel
In-Reply-To: <d1da7fdb-10f6-7f69-4820-520469c0193c@bootlin.com>

Hi Romain,

On Sun, Mar 31, 2024 at 4:35 PM Romain Gantois
<romain.gantois@bootlin.com> wrote:
>
> Hello Cathy,
>
> On Wed, 27 Mar 2024, Cathy Cai wrote:
>
> > Tx queue time out then reset adapter. When reset the adapter, stmmac driver
> > sets the state to STMMAC_DOWN and calls dev_close() function. If an interrupt
> > is triggered at this instant after setting state to STMMAC_DOWN, before the
> > dev_close() call.
> >
> ...
> > -     set_bit(STMMAC_DOWN, &priv->state);
> >       dev_close(priv->dev);
> > +     set_bit(STMMAC_DOWN, &priv->state);
> >       dev_open(priv->dev, NULL);
> >       clear_bit(STMMAC_DOWN, &priv->state);
> >       clear_bit(STMMAC_RESETING, &priv->state);
>
> If this IRQ issue can happen whenever STMMAC_DOWN is set while the net device is
> open, then it could also happen between the dev_open() and
> clear_bit(STMMAC_DOWN) calls right? So you'd have to clear STMMAC_DOWN before
> calling dev_open() but then I don't see the usefulness of setting STMMAC_DOWN
> and clearing it immediately. Maybe closing and opening the net device should be
> enough?
>
 Yes. It could also happen between the dev_open() and
clear_bit(STMMAC_DOWN) calls.
Although we did not reproduce this scenario, it should have happened
if we had increased
the number of test samples. In addition, I found that other people had
similar problems before.
The link is:
https://lore.kernel.org/all/20210208140820.10410-11-Sergey.Semin@baikalelectronics.ru/

>
> Moreover, it seems strange to me that stmmac_interrupt() unconditionnally
> ignores interrupts when the driver is in STMMAC_DOWN state. This seems like
> dangerous behaviour, since it could cause IRQ storm issues whenever something
> in the driver sets this state. I'm not too familiar with the interrupt handling
> in this driver, but maybe stmmac_interrupt() could clear interrupts
> unconditionnally in the STMMAC_DOWN state?
>
Clear interrupts unconditionally in the STMMAC_DOWN state directly
certainly won't cause this problem.
This may be too rough, maybe this design has other considerations.

>
> Best Regards,
>
> --
> Romain Gantois, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com

 Best Regards,
Cathy

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v2] dt-bindings: watchdog: aspeed,ast2400-wdt: Convert to DT schema
From: Andrew Jeffery @ 2024-04-03  2:04 UTC (permalink / raw)
  To: wim, linux
  Cc: Andrew Jeffery, robh, krzysztof.kozlowski+dt, conor+dt, joel, zev,
	linux-watchdog, devicetree, linux-arm-kernel, linux-aspeed,
	linux-kernel

Squash warnings such as:

```
arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-galaxy100.dtb: /ahb/apb@1e600000/watchdog@1e785000: failed to match any schema with compatible: ['aspeed,ast2400-wdt']
```

The schema binding additionally defines the clocks property over the
prose binding to align with use of the node in the DTS files.

Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
---
v2: Address feedback from Rob and Zev

    - Rob: https://lore.kernel.org/linux-watchdog/20240402180718.GA358505-robh@kernel.org/
    - Zev: https://lore.kernel.org/linux-watchdog/65722a59-2e94-4616-81e1-835615b0e600@hatter.bewilderbeest.net/

v1: https://lore.kernel.org/linux-watchdog/20240402120118.282035-1-andrew@codeconstruct.com.au/

 .../bindings/watchdog/aspeed,ast2400-wdt.yaml | 142 ++++++++++++++++++
 .../bindings/watchdog/aspeed-wdt.txt          |  73 ---------
 2 files changed, 142 insertions(+), 73 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/watchdog/aspeed,ast2400-wdt.yaml
 delete mode 100644 Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt

diff --git a/Documentation/devicetree/bindings/watchdog/aspeed,ast2400-wdt.yaml b/Documentation/devicetree/bindings/watchdog/aspeed,ast2400-wdt.yaml
new file mode 100644
index 000000000000..be78a9865584
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/aspeed,ast2400-wdt.yaml
@@ -0,0 +1,142 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/watchdog/aspeed,ast2400-wdt.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Aspeed watchdog timer controllers
+
+maintainers:
+  - Andrew Jeffery <andrew@codeconstruct.com.au>
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2400-wdt
+      - aspeed,ast2500-wdt
+      - aspeed,ast2600-wdt
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description: >
+      The clock used to drive the watchdog counter. From the AST2500 no source
+      other than the 1MHz clock can be selected, so the clocks property is
+      optional.
+
+  aspeed,reset-type:
+    $ref: /schemas/types.yaml#/definitions/string
+    enum:
+      - cpu
+      - soc
+      - system
+      - none
+    default: system
+    description: >
+      The watchdog can be programmed to generate one of three different types of
+      reset when a timeout occcurs.
+
+      Specifying 'cpu' will only reset the processor on a timeout event.
+
+      Specifying 'soc' will reset a configurable subset of the SoC's controllers
+      on a timeout event. Controllers critical to the SoC's operation may remain
+      untouched. The set of SoC controllers to reset may be specified via the
+      aspeed,reset-mask property if the node has the aspeed,ast2500-wdt or
+      aspeed,ast2600-wdt compatible.
+
+      Specifying 'system' will reset all controllers on a timeout event, as if
+      EXTRST had been asserted.
+
+      Specifying 'none' will cause the timeout event to have no reset effect.
+      Another watchdog engine on the chip must be used for chip reset operations.
+
+  aspeed,alt-boot:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description: >
+      Direct the watchdog to configure the SoC to boot from the alternative boot
+      region if a timeout occurs.
+
+  aspeed,external-signal:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description: >
+      Assert the timeout event on an external signal pin associated with the
+      watchdog controller instance. The pin must be muxed appropriately.
+
+  aspeed,ext-pulse-duration:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: >
+      The duration, in microseconds, of the pulse emitted on the external signal
+      pin.
+
+  aspeed,ext-push-pull:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description: >
+      If aspeed,external-signal is specified in the node, set the external
+      signal pin's drive type to push-pull. If aspeed,ext-push-pull is not
+      specified then the pin is configured as open-drain.
+
+  aspeed,ext-active-high:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description: >
+      If both aspeed,external-signal and aspeed,ext-push-pull are specified in
+      the node, set the pulse polarity to active-high. If aspeed,ext-active-high
+      is not specified then the pin is configured as active-low.
+
+  aspeed,reset-mask:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    minItems: 1
+    maxItems: 2
+    description: >
+      A bitmask indicating which peripherals will be reset if the watchdog
+      timer expires. On AST2500 SoCs this should be a single word defined using
+      the AST2500_WDT_RESET_* macros; on AST2600 SoCs this should be a two-word
+      array with the first word defined using the AST2600_WDT_RESET1_* macros,
+      and the second word defined using the AST2600_WDT_RESET2_* macros.
+
+required:
+  - compatible
+  - reg
+
+allOf:
+  - if:
+      anyOf:
+        - required:
+            - aspeed,ext-push-pull
+        - required:
+            - aspeed,ext-active-high
+        - required:
+            - aspeed,reset-mask
+    then:
+      properties:
+        compatible:
+          enum:
+            - aspeed,ast2500-wdt
+            - aspeed,ast2600-wdt
+  - if:
+      required:
+        - aspeed,ext-active-high
+    then:
+      required:
+        - aspeed,ext-push-pull
+
+additionalProperties: false
+
+examples:
+  - |
+    watchdog@1e785000 {
+        compatible = "aspeed,ast2400-wdt";
+        reg = <0x1e785000 0x1c>;
+        aspeed,reset-type = "system";
+        aspeed,external-signal;
+    };
+  - |
+    #include <dt-bindings/watchdog/aspeed-wdt.h>
+    watchdog@1e785040 {
+        compatible = "aspeed,ast2600-wdt";
+        reg = <0x1e785040 0x40>;
+        aspeed,reset-type = "soc";
+        aspeed,reset-mask = <AST2600_WDT_RESET1_DEFAULT
+                            (AST2600_WDT_RESET2_DEFAULT & ~AST2600_WDT_RESET2_LPC)>;
+    };
diff --git a/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt b/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt
deleted file mode 100644
index 3208adb3e52e..000000000000
--- a/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-Aspeed Watchdog Timer
-
-Required properties:
- - compatible: must be one of:
-	- "aspeed,ast2400-wdt"
-	- "aspeed,ast2500-wdt"
-	- "aspeed,ast2600-wdt"
-
- - reg: physical base address of the controller and length of memory mapped
-   region
-
-Optional properties:
-
- - aspeed,reset-type = "cpu|soc|system|none"
-
-   Reset behavior - Whenever a timeout occurs the watchdog can be programmed
-   to generate one of three different, mutually exclusive, types of resets.
-
-   Type "none" can be specified to indicate that no resets are to be done.
-   This is useful in situations where another watchdog engine on chip is
-   to perform the reset.
-
-   If 'aspeed,reset-type=' is not specified the default is to enable system
-   reset.
-
-   Reset types:
-
-        - cpu: Reset CPU on watchdog timeout
-
-        - soc: Reset 'System on Chip' on watchdog timeout
-
-        - system: Reset system on watchdog timeout
-
-        - none: No reset is performed on timeout. Assumes another watchdog
-                engine is responsible for this.
-
- - aspeed,alt-boot:    If property is present then boot from alternate block.
- - aspeed,external-signal: If property is present then signal is sent to
-			external reset counter (only WDT1 and WDT2). If not
-			specified no external signal is sent.
- - aspeed,ext-pulse-duration: External signal pulse duration in microseconds
-
-Optional properties for AST2500-compatible watchdogs:
- - aspeed,ext-push-pull: If aspeed,external-signal is present, set the pin's
-			 drive type to push-pull. The default is open-drain.
- - aspeed,ext-active-high: If aspeed,external-signal is present and and the pin
-			   is configured as push-pull, then set the pulse
-			   polarity to active-high. The default is active-low.
-
-Optional properties for AST2500- and AST2600-compatible watchdogs:
- - aspeed,reset-mask: A bitmask indicating which peripherals will be reset if
-		      the watchdog timer expires.  On AST2500 this should be a
-		      single word defined using the AST2500_WDT_RESET_* macros;
-		      on AST2600 this should be a two-word array with the first
-		      word defined using the AST2600_WDT_RESET1_* macros and the
-		      second word defined using the AST2600_WDT_RESET2_* macros.
-
-Examples:
-
-	wdt1: watchdog@1e785000 {
-		compatible = "aspeed,ast2400-wdt";
-		reg = <0x1e785000 0x1c>;
-		aspeed,reset-type = "system";
-		aspeed,external-signal;
-	};
-
-	#include <dt-bindings/watchdog/aspeed-wdt.h>
-	wdt2: watchdog@1e785040 {
-		compatible = "aspeed,ast2600-wdt";
-		reg = <0x1e785040 0x40>;
-		aspeed,reset-mask = <AST2600_WDT_RESET1_DEFAULT
-				     (AST2600_WDT_RESET2_DEFAULT & ~AST2600_WDT_RESET2_LPC)>;
-	};
-- 
2.39.2


_______________________________________________
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] arm64: Fix double TCR_T0SZ_OFFSET shift
From: Seongsu Park @ 2024-04-03  2:08 UTC (permalink / raw)
  To: 'Will Deacon'
  Cc: catalin.marinas, ardb, mark.rutland, linux-arm-kernel,
	linux-kernel, 'Leem	ChaeHoon', 'Gyeonggeon Choi',
	'Soomin Cho', 'DaeRo Lee', 'kmasta'
In-Reply-To: <20240402115841.GA16533@willie-the-truck>



> On Tue, Apr 02, 2024 at 07:49:50PM +0900, Seongsu Park wrote:
> > We have already shifted the value of t0sz in TCR_T0SZ by
TCR_T0SZ_OFFSET.
> > So, the TCR_T0SZ_OFFSET shift here should be removed.
> >
> > Co-developed-by: Leem ChaeHoon <infinite.run@gmail.com>
> > Signed-off-by: Leem ChaeHoon <infinite.run@gmail.com>
> > Co-developed-by: Gyeonggeon Choi <gychoi@student.42seoul.kr>
> > Signed-off-by: Gyeonggeon Choi <gychoi@student.42seoul.kr>
> > Co-developed-by: Soomin Cho <to.soomin@gmail.com>
> > Signed-off-by: Soomin Cho <to.soomin@gmail.com>
> > Co-developed-by: DaeRo Lee <skseofh@gmail.com>
> > Signed-off-by: DaeRo Lee <skseofh@gmail.com>
> > Co-developed-by: kmasta <kmasta.study@gmail.com>
> > Signed-off-by: kmasta <kmasta.study@gmail.com>
> > Signed-off-by: Seongsu Park <sgsu.park@samsung.com>
> 
> heh, that's quite a lot of people. Did you remove three chars each? :p
We are studying the Linux kernel based on arm64 together every Saturday for
7 hours! :)
> 
> > ---
> >  arch/arm64/include/asm/mmu_context.h | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/include/asm/mmu_context.h
> > b/arch/arm64/include/asm/mmu_context.h
> > index c768d16b81a4..58de99836d2e 100644
> > --- a/arch/arm64/include/asm/mmu_context.h
> > +++ b/arch/arm64/include/asm/mmu_context.h
> > @@ -76,7 +76,7 @@ static inline void __cpu_set_tcr_t0sz(unsigned long
> t0sz)
> >  		return;
> >
> >  	tcr &= ~TCR_T0SZ_MASK;
> > -	tcr |= t0sz << TCR_T0SZ_OFFSET;
> > +	tcr |= t0sz;
> 
> Thankfully, TCR_T0SZ_OFFSET is 0 so this isn't as alarming as it looks.
> Even so, if we're going to make the code consistent, then shouldn't the
> earlier conditional be updated too?
> 
> 	if ((tcr & TCR_T0SZ_MASK) >> TCR_T0SZ_OFFSET == t0sz)
> 		return;
> 
> seems to assume that t0sz is unshifted.
> 
> Will
Thank you for feedback. I'll send v2 patch.


_______________________________________________
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] irqchip/gic-v3-its: Don't need VSYNC if VMAPP with {V, Alloc}=={0, x}
From: Tangnianyao @ 2024-04-03  2:18 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: tglx, linux-arm-kernel, linux-kernel, guoyang2, wangwudi
In-Reply-To: <86il0zubh1.wl-maz@kernel.org>



On 4/2/2024 21:43, Marc Zyngier wrote:
> On Tue, 02 Apr 2024 14:32:40 +0100,
> Tangnianyao <tangnianyao@huawei.com> wrote:
>>
>>
>> On 4/2/2024 20:35, Marc Zyngier wrote:
>>> On Tue, 02 Apr 2024 12:41:47 +0100,
>>> t00849498 <tangnianyao@huawei.com> wrote:
>>>> From GIC spec, a VMAPP with {V, Alloc}=={0, x} is self-synchronizing,
>>> It'd be nice to quote the part of the spec (5.3.19).
>> yes, that's quote from GIC spec.
>>>> This means the ITS command queue does not show the command as
>>>> consumed until all of its effects are completed. A VSYNC with unmapped
>>>> vpeid is not needed.
>>>>
>>>> Signed-off-by: t00849498 <tangnianyao@huawei.com>
>>> Previous contributions with the same email address had the name
>>> "Nianyao Tang" associated with it. Was it wrong in the past? Or is the
>>> above wrong?
>> Sorry, the above name is wrong, should be "Nianyao Tang".
>>>> ---
>>>>  drivers/irqchip/irq-gic-v3-its.c | 4 ++++
>>>>  1 file changed, 4 insertions(+)
>>>>
>>>> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
>>>> index fca888b36680..a0ca5dcbb245 100644
>>>> --- a/drivers/irqchip/irq-gic-v3-its.c
>>>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>>>> @@ -789,6 +789,7 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its,
>>>>  	unsigned long vpt_addr, vconf_addr;
>>>>  	u64 target;
>>>>  	bool alloc;
>>>> +	bool unmap_v4_1 = !desc->its_vmapp_cmd.valid && is_v4_1(its);
>>>>
>>>>  	its_encode_cmd(cmd, GITS_CMD_VMAPP);
>>>>  	its_encode_vpeid(cmd, desc->its_vmapp_cmd.vpe->vpe_id);
>>>> @@ -832,6 +833,9 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its,
>>>>  out:
>>>>  	its_fixup_cmd(cmd);
>>>>  
>>>> +	if (unmap_v4_1)
>>>> +		return NULL;
>>>> +
>>>>  	return valid_vpe(its, desc->its_vmapp_cmd.vpe);
>>>>  }
>>>>  
>>> This is a bit ugly. We already have a whole block dedicated to
>>> handling VMAPP with V=0 and GICv4.1, and it'd be more readable to keep
>>> all that code together. Something like the untested patch below.
>> Thank you for quick fix, it would be great to remove this VSYNC. ITS handling VSYNC unmap
>> vpeid may waste some time, trigger exception and needed to be
>> handled.
> Do you actually see an exception being delivered from this?
>
> In any case, feel free to respin the patch after having tested this
> diff, with the commit message fixed and a Fixes: tag attached to it.

In our developing implemenation, ITS would report RAS when doing vsync
and reaching an invalid vpe table entry. It is reasonable to report RAS, right?

It just reports, and kernel can still run normally regardless of this RAS message.

> Thanks,
>
> 	M.
>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v2] arm64: Fix double TCR_T0SZ_OFFSET shift
From: Seongsu Park @ 2024-04-03  2:42 UTC (permalink / raw)
  To: will, catalin.marinas, ardb, mark.rutland
  Cc: linux-arm-kernel, linux-kernel, sgsu.park, Leem ChaeHoon,
	Gyeonggeon Choi, Soomin Cho, DaeRo Lee, kmasta
In-Reply-To: <CGME20240403024240epcas1p155cd55ca8c1dae6114b970cf3f57084e@epcas1p1.samsung.com>

We have already shifted the value of t0sz in TCR_T0SZ by TCR_T0SZ_OFFSET.
So, the TCR_T0SZ_OFFSET shift here should be removed.

Co-developed-by: Leem ChaeHoon <infinite.run@gmail.com>
Signed-off-by: Leem ChaeHoon <infinite.run@gmail.com>
Co-developed-by: Gyeonggeon Choi <gychoi@student.42seoul.kr>
Signed-off-by: Gyeonggeon Choi <gychoi@student.42seoul.kr>
Co-developed-by: Soomin Cho <to.soomin@gmail.com>
Signed-off-by: Soomin Cho <to.soomin@gmail.com>
Co-developed-by: DaeRo Lee <skseofh@gmail.com>
Signed-off-by: DaeRo Lee <skseofh@gmail.com>
Co-developed-by: kmasta <kmasta.study@gmail.com>
Signed-off-by: kmasta <kmasta.study@gmail.com>
Signed-off-by: Seongsu Park <sgsu.park@samsung.com>
---

Changes in v2:
- Condition is updated

---
 arch/arm64/include/asm/mmu_context.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index c768d16b81a4..bd19f4c758b7 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -72,11 +72,11 @@ static inline void __cpu_set_tcr_t0sz(unsigned long t0sz)
 {
 	unsigned long tcr = read_sysreg(tcr_el1);
 
-	if ((tcr & TCR_T0SZ_MASK) >> TCR_T0SZ_OFFSET == t0sz)
+	if ((tcr & TCR_T0SZ_MASK) == t0sz)
 		return;
 
 	tcr &= ~TCR_T0SZ_MASK;
-	tcr |= t0sz << TCR_T0SZ_OFFSET;
+	tcr |= t0sz;
 	write_sysreg(tcr, tcr_el1);
 	isb();
 }
-- 
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] net: ethernet: mtk_eth_soc: Reuse value using READ_ONCE instead of re-rereading it
From: linke li @ 2024-04-03  2:54 UTC (permalink / raw)
  Cc: xujianhao01, linke li, Felix Fietkau, Sean Wang, Mark Lee,
	Lorenzo Bianconi, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Matthias Brugger, AngeloGioacchino Del Regno, netdev,
	linux-kernel, linux-arm-kernel, linux-mediatek

In mtk_flow_entry_update_l2, the hwe->ib1 is read using READ_ONCE at the
beginning of the function, checked, and then re-read from hwe->ib1,
may void all guarantees of the checks. Reuse the value that was read by
READ_ONCE to ensure the consistency of the ib1 throughout the function.

Signed-off-by: linke li <lilinke99@qq.com>
---
 drivers/net/ethernet/mediatek/mtk_ppe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
index b2a5d9c3733d..8b3cdfc4d407 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -580,7 +580,7 @@ mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
 
 		idle = cur_idle;
 		entry->data.ib1 &= ~ib1_ts_mask;
-		entry->data.ib1 |= hwe->ib1 & ib1_ts_mask;
+		entry->data.ib1 |= ib1 & ib1_ts_mask;
 	}
 }
 
-- 
2.39.3 (Apple Git-146)


_______________________________________________
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/7] arm64: dts: imx8-ss-lsio: fix pwm lpcg indices
From: Frank Li @ 2024-04-03  3:10 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Fabio Estevam, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, NXP Linux Team,
	Marcel Ziswiler, Philippe Schenker, Max Krummenacher,
	Alexander Stein, Joakim Zhang, devicetree, linux-arm-kernel,
	linux-kernel, stable
In-Reply-To: <ZgyzxmuMIK87C2nW@dragon>

On Wed, Apr 03, 2024 at 09:41:26AM +0800, Shawn Guo wrote:
> On Tue, Apr 02, 2024 at 11:09:17AM -0400, Frank Li wrote:
> > On Mon, Apr 01, 2024 at 08:04:56PM -0300, Fabio Estevam wrote:
> > > On Mon, Apr 1, 2024 at 7:25 PM Frank Li <Frank.Li@nxp.com> wrote:
> > > >
> > > > lpcg's arg0 should use clock indices instead of index.
> > > >
> > > > pwm0_lpcg: clock-controller@5d400000 {
> > > >         ...                                                // Col1  Col2
> > > >         clocks = <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>,  // 0     0
> > > >                  <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>,  // 1     1
> > > >                  <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>,  // 2     4
> > > >                  <&lsio_bus_clk>,                          // 3     5
> > > >                  <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>;  // 4     6
> > > >         clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_1>,
> > > >                         <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_5>,
> > > >                         <IMX_LPCG_CLK_6>;
> > > > };
> > > >
> > > > Col1: index, which exited dts try to get.
> > > 
> > > I cannot understand this sentence, sorry.
> > 
> > This base on downstream dts code.  Downstream code use index in 'Col1' to
> > get clock.
> 
> So s/exited/existing you meant?

Yes, sorry for typo. 

Frank

> 
> Shawn
> 

_______________________________________________
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 1/3] ARM: dts: Modify GPIO table for Asrock X570D4U BMC
From: Andrew Jeffery @ 2024-04-03  3:21 UTC (permalink / raw)
  To: Renze Nicolai, linux-arm-kernel, devicetree, linux-kernel,
	linux-aspeed, arnd, olof, soc, robh+dt, krzysztof.kozlowski+dt,
	joel, andrew
In-Reply-To: <20240329130152.878944-2-renze@rnplus.nl>

Hi Renze,

Do you mind running this patch and the others in the series through
./scripts/checkpatch.pl? Generally patches sent to the list should not
generate warnings.

It looks like these patches are generated against Joel's bmc/for-next
branch. He's applied your original X570D4U devicetree patch there,
(though that also causes checkpatch warnings).

On Fri, 2024-03-29 at 14:01 +0100, Renze Nicolai wrote:
> This commit removes button-nmi-n, this board does not have support for an NMI button.
> Input status-locatorled-n has been renamed to input-locatorled-n to better indicate the signal type.
> The suffix -n has been appended to the name of control-locatorbutton, button-power, control-power, button-reset, control-reset, input-id0, input-id1, input-id2, output-bmc-ready to reflect the inverted signal polarity.
> GPIO output-rtc-battery-voltage-read-enable has been renamed to output-hwm-vbat-enable, input-alert1-n to input-aux-smb-alert-n, input-alert3-n to input-psu-smb-alert-n, input-mfg to input-mfg-mode-n and input-caseopen to input-case-open-n.
> And GPIOs input-bmc-smb-present-n, input-pcie-wake-n, input-sleep-s3-n, input-sleep-s5-n and input-power-good have been added.
> 

For instance, checkpatch warns about these lines in the commit message
being too long. They should be wrapped at 72 characters.

Additionally, the description forms a bit of a list of things the patch
is doing. Patches are easier to review when they only do one thing, as
it removes the need to assess whether there are subtle interactions
between the several things, and if so, whether they're expected and
correct.

I'd prefer this change be split up so there's no need for such
concerns.

> Signed-off-by: Renze Nicolai <renze@rnplus.nl>
> ---
>  .../dts/aspeed/aspeed-bmc-asrock-x570d4u.dts  | 116 +++++++++---------
>  1 file changed, 58 insertions(+), 58 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-x570d4u.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-x570d4u.dts
> index 3c975bc41ae7..34bc382bf492 100644
> --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-x570d4u.dts
> +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-x570d4u.dts
> @@ -79,64 +79,64 @@ iio-hwmon {
>  &gpio {
>  	status = "okay";
>  	gpio-line-names =
> -	/*A0-A3*/       "status-locatorled-n",                    "",                      "button-nmi-n",          "",
> -	/*A4-A7*/       "",                                       "",                      "",                      "",
> -	/*B0-B3*/       "input-bios-post-cmplt-n",                "",                      "",                      "",
> -	/*B4-B7*/       "",                                       "",                      "",                      "",
> -	/*C0-C3*/       "",                                       "",                      "",                      "",
> -	/*C4-C7*/       "",                                       "",                      "control-locatorbutton", "",
> -	/*D0-D3*/       "button-power",                           "control-power",         "button-reset",          "control-reset",
> -	/*D4-D7*/       "",                                       "",                      "",                      "",
> -	/*E0-E3*/       "",                                       "",                      "",                      "",
> -	/*E4-E7*/       "",                                       "",                      "",                      "",
> -	/*F0-F3*/       "",                                       "",                      "",                      "",
> -	/*F4-F7*/       "",                                       "",                      "",                      "",
> -	/*G0-G3*/       "output-rtc-battery-voltage-read-enable", "input-id0",             "input-id1",             "input-id2",
> -	/*G4-G7*/       "input-alert1-n",                         "input-alert2-n",        "input-alert3-n",        "",
> -	/*H0-H3*/       "",                                       "",                      "",                      "",
> -	/*H4-H7*/       "input-mfg",                              "",                      "led-heartbeat-n",       "input-caseopen",
> -	/*I0-I3*/       "",                                       "",                      "",                      "",
> -	/*I4-I7*/       "",                                       "",                      "",                      "",
> -	/*J0-J3*/       "output-bmc-ready",                       "",                      "",                      "",
> -	/*J4-J7*/       "",                                       "",                      "",                      "",
> -	/*K0-K3*/       "",                                       "",                      "",                      "",
> -	/*K4-K7*/       "",                                       "",                      "",                      "",
> -	/*L0-L3*/       "",                                       "",                      "",                      "",
> -	/*L4-L7*/       "",                                       "",                      "",                      "",
> -	/*M0-M3*/       "",                                       "",                      "",                      "",
> -	/*M4-M7*/       "",                                       "",                      "",                      "",
> -	/*N0-N3*/       "",                                       "",                      "",                      "",
> -	/*N4-N7*/       "",                                       "",                      "",                      "",
> -	/*O0-O3*/       "",                                       "",                      "",                      "",
> -	/*O4-O7*/       "",                                       "",                      "",                      "",
> -	/*P0-P3*/       "",                                       "",                      "",                      "",
> -	/*P4-P7*/       "",                                       "",                      "",                      "",
> -	/*Q0-Q3*/       "",                                       "",                      "",                      "",
> -	/*Q4-Q7*/       "",                                       "",                      "",                      "",
> -	/*R0-R3*/       "",                                       "",                      "",                      "",
> -	/*R4-R7*/       "",                                       "",                      "",                      "",
> -	/*S0-S3*/       "input-bmc-pchhot-n",                     "",                      "",                      "",
> -	/*S4-S7*/       "",                                       "",                      "",                      "",
> -	/*T0-T3*/       "",                                       "",                      "",                      "",
> -	/*T4-T7*/       "",                                       "",                      "",                      "",
> -	/*U0-U3*/       "",                                       "",                      "",                      "",
> -	/*U4-U7*/       "",                                       "",                      "",                      "",
> -	/*V0-V3*/       "",                                       "",                      "",                      "",
> -	/*V4-V7*/       "",                                       "",                      "",                      "",
> -	/*W0-W3*/       "",                                       "",                      "",                      "",
> -	/*W4-W7*/       "",                                       "",                      "",                      "",
> -	/*X0-X3*/       "",                                       "",                      "",                      "",
> -	/*X4-X7*/       "",                                       "",                      "",                      "",
> -	/*Y0-Y3*/       "",                                       "",                      "",                      "",
> -	/*Y4-Y7*/       "",                                       "",                      "",                      "",
> -	/*Z0-Z3*/       "",                                       "",                      "led-fault-n",           "output-bmc-throttle-n",
> -	/*Z4-Z7*/       "",                                       "",                      "",                      "",
> -	/*AA0-AA3*/     "input-cpu1-thermtrip-latch-n",           "",                      "input-cpu1-prochot-n",  "",
> -	/*AA4-AC7*/     "",                                       "",                      "",                      "",
> -	/*AB0-AB3*/     "",                                       "",                      "",                      "",
> -	/*AB4-AC7*/     "",                                       "",                      "",                      "",
> -	/*AC0-AC3*/     "",                                       "",                      "",                      "",
> -	/*AC4-AC7*/     "",                                       "",                      "",                      "";
> +	/*A0-A3*/       "input-locatorled-n",                     "",                      "",                        "",
> +	/*A4-A7*/       "",                                       "",                      "",                        "",
> +	/*B0-B3*/       "input-bios-post-cmplt-n",                "",                      "",                        "",
> +	/*B4-B7*/       "",                                       "",                      "",                        "",
> +	/*C0-C3*/       "",                                       "",                      "",                        "",
> +	/*C4-C7*/       "",                                       "",                      "control-locatorbutton-n", "",
> +	/*D0-D3*/       "button-power-n",                         "control-power-n",       "button-reset-n",          "control-reset-n",
> +	/*D4-D7*/       "",                                       "",                      "",                        "",
> +	/*E0-E3*/       "",                                       "",                      "",                        "",
> +	/*E4-E7*/       "",                                       "",                      "",                        "",
> +	/*F0-F3*/       "",                                       "",                      "",                        "",
> +	/*F4-F7*/       "",                                       "",                      "",                        "",
> +	/*G0-G3*/       "output-hwm-vbat-enable",                 "input-id0-n",           "input-id1-n",             "input-id2-n",
> +	/*G4-G7*/       "input-aux-smb-alert-n",                  "",                      "input-psu-smb-alert-n",   "",
> +	/*H0-H3*/       "",                                       "",                      "",                        "",
> +	/*H4-H7*/       "input-mfg-mode-n",                       "",                      "led-heartbeat-n",         "input-case-open-n",
> +	/*I0-I3*/       "",                                       "",                      "",                        "",
> +	/*I4-I7*/       "",                                       "",                      "",                        "",
> +	/*J0-J3*/       "output-bmc-ready-n",                     "",                      "",                        "",
> +	/*J4-J7*/       "",                                       "",                      "",                        "",
> +	/*K0-K3*/       "",                                       "",                      "",                        "",
> +	/*K4-K7*/       "",                                       "",                      "",                        "",
> +	/*L0-L3*/       "",                                       "",                      "",                        "",
> +	/*L4-L7*/       "",                                       "",                      "",                        "",
> +	/*M0-M3*/       "",                                       "",                      "",                        "",
> +	/*M4-M7*/       "",                                       "",                      "",                        "",
> +	/*N0-N3*/       "",                                       "",                      "",                        "",
> +	/*N4-N7*/       "",                                       "",                      "",                        "",
> +	/*O0-O3*/       "",                                       "",                      "",                        "",
> +	/*O4-O7*/       "",                                       "",                      "",                        "",
> +	/*P0-P3*/       "",                                       "",                      "",                        "",
> +	/*P4-P7*/       "",                                       "",                      "",                        "",
> +	/*Q0-Q3*/       "",                                       "",                      "",                        "",
> +	/*Q4-Q7*/       "input-bmc-smb-present-n",                "",                      "",                        "input-pcie-wake-n",
> +	/*R0-R3*/       "",                                       "",                      "",                        "",
> +	/*R4-R7*/       "",                                       "",                      "",                        "",
> +	/*S0-S3*/       "input-bmc-pchhot-n",                     "",                      "",                        "",
> +	/*S4-S7*/       "",                                       "",                      "",                        "",
> +	/*T0-T3*/       "",                                       "",                      "",                        "",
> +	/*T4-T7*/       "",                                       "",                      "",                        "",
> +	/*U0-U3*/       "",                                       "",                      "",                        "",
> +	/*U4-U7*/       "",                                       "",                      "",                        "",
> +	/*V0-V3*/       "",                                       "",                      "",                        "",
> +	/*V4-V7*/       "",                                       "",                      "",                        "",
> +	/*W0-W3*/       "",                                       "",                      "",                        "",
> +	/*W4-W7*/       "",                                       "",                      "",                        "",
> +	/*X0-X3*/       "",                                       "",                      "",                        "",
> +	/*X4-X7*/       "",                                       "",                      "",                        "",
> +	/*Y0-Y3*/       "input-sleep-s3-n",                       "input-sleep-s5-n",      "",                        "",
> +	/*Y4-Y7*/       "",                                       "",                      "",                        "",
> +	/*Z0-Z3*/       "",                                       "",                      "led-fault-n",             "output-bmc-throttle-n",
> +	/*Z4-Z7*/       "",                                       "",                      "",                        "",
> +	/*AA0-AA3*/     "input-cpu1-thermtrip-latch-n",           "",                      "input-cpu1-prochot-n",    "",
> +	/*AA4-AC7*/     "",                                       "",                      "",                        "",
> +	/*AB0-AB3*/     "",                                       "input-power-good",      "",                        "",
> +	/*AB4-AC7*/     "",                                       "",                      "",                        "",
> +	/*AC0-AC3*/     "",                                       "",                      "",                        "",
> +	/*AC4-AC7*/     "",                                       "",                      "",                        "";
>  };
>  

I'd like some discussion in the commit message of whether these names
align with net names in the schematic, follow the OpenBMC GPIO naming
guidelines, or use some other strategy entirely.

Also, the columnisation of the names leads to more warnings from
checkpatch (due to line length). Other Aspeed-based devicetrees tend
not to make the whitespace so significant, and generally group the
GPIOs by complete banks. I prefer that the X570D4U devicetree is
consistent with the others.

Andrew

_______________________________________________
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] ARM: dts: Disable unused ADC channels for Asrock X570D4U BMC
From: Andrew Jeffery @ 2024-04-03  3:29 UTC (permalink / raw)
  To: Renze Nicolai, linux-arm-kernel, devicetree, linux-kernel,
	linux-aspeed, arnd, olof, soc, robh+dt, krzysztof.kozlowski+dt,
	joel, andrew
In-Reply-To: <20240329130152.878944-3-renze@rnplus.nl>

Hi Renze,

On Fri, 2024-03-29 at 14:01 +0100, Renze Nicolai wrote:
> This commit disables unused ADC channels and labels the ADC channels used with their function.

Please run this through checkpatch and address the warnings.

Also, the submitting patches documentation[1] suggests using the
imperative mood - instead of "This commit disables ...", use "Disable
...". The change subject is phrased the expected way.

[1]: https://docs.kernel.org/process/submitting-patches.html

Taking the subject and the description together, the description feels
a little redundant. Maybe it could be trimmed back to

> Also, label the ADC channels used with their function.

Andrew


_______________________________________________
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 3/3] ARM: dts: Modify I2C bus configuration
From: Andrew Jeffery @ 2024-04-03  3:30 UTC (permalink / raw)
  To: Renze Nicolai, linux-arm-kernel, devicetree, linux-kernel,
	linux-aspeed, arnd, olof, soc, robh+dt, krzysztof.kozlowski+dt,
	joel, andrew
In-Reply-To: <20240329130152.878944-4-renze@rnplus.nl>

Hi Renze,

On Fri, 2024-03-29 at 14:01 +0100, Renze Nicolai wrote:
> This commit enables I2C bus 8 which is exposed on the IPMB_1 connector on the X570D4U mainboard.
> Additionally it adds a descriptive comment to I2C busses 1 and 5.

checkpatch on this one too :)

Cheers,

Andrew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v3 1/2] media: dt-bindings: i2c: add GalaxyCore GC05A2 image sensor
From: Zhi Mao @ 2024-04-03  3:38 UTC (permalink / raw)
  To: mchehab, robh+dt, krzysztof.kozlowski+dt, sakari.ailus
  Cc: laurent.pinchart, shengnan.wang, yaya.chang,
	Project_Global_Chrome_Upstream_Group, yunkec, conor+dt,
	matthias.bgg, angelogioacchino.delregno, jacopo.mondi, zhi.mao,
	10572168, hverkuil-cisco, heiko, jernej.skrabec, macromorgan,
	linus.walleij, hdegoede, tomi.valkeinen, gerald.loacker,
	andy.shevchenko, bingbu.cao, dan.scally, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek,
	Krzysztof Kozlowski
In-Reply-To: <20240403033825.9072-1-zhi.mao@mediatek.com>

Add YAML device tree binding for GC05A2 CMOS image sensor,
and the relevant MAINTAINERS entries.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
---
 .../bindings/media/i2c/galaxycore,gc05a2.yaml | 112 ++++++++++++++++++
 1 file changed, 112 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/galaxycore,gc05a2.yaml

diff --git a/Documentation/devicetree/bindings/media/i2c/galaxycore,gc05a2.yaml b/Documentation/devicetree/bindings/media/i2c/galaxycore,gc05a2.yaml
new file mode 100644
index 000000000000..0e7a7b5ac89f
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/galaxycore,gc05a2.yaml
@@ -0,0 +1,112 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright (c) 2023 MediaTek Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/galaxycore,gc05a2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: GalaxyCore gc05a2 1/5" 5M Pixel MIPI CSI-2 sensor
+
+maintainers:
+  - Zhi Mao <zhi.mao@mediatek.com>
+
+description:
+  The gc05a2 is a raw image sensor with an MIPI CSI-2 image data
+  interface and CCI (I2C compatible) control bus. The output format
+  is raw Bayer.
+
+properties:
+  compatible:
+    const: galaxycore,gc05a2
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  dovdd-supply: true
+
+  avdd-supply: true
+
+  dvdd-supply: true
+
+  reset-gpios:
+    description: Reference to the GPIO connected to the RESETB pin.
+    maxItems: 1
+
+  port:
+    $ref: /schemas/graph.yaml#/$defs/port-base
+    additionalProperties: false
+    description:
+      Output port node, single endpoint describing the CSI-2 transmitter.
+
+    properties:
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          data-lanes:
+            oneOf:
+              - items:
+                  - const: 1
+                  - const: 2
+                  - const: 3
+                  - const: 4
+              - items:
+                  - const: 1
+                  - const: 2
+
+          link-frequencies: true
+
+        required:
+          - data-lanes
+          - link-frequencies
+
+    required:
+      - endpoint
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - dovdd-supply
+  - avdd-supply
+  - dvdd-supply
+  - reset-gpios
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        sensor@37 {
+            compatible =  "galaxycore,gc05a2";
+            reg = <0x37>;
+
+            clocks = <&gc05a2_clk>;
+
+            reset-gpios = <&pio 21 GPIO_ACTIVE_LOW>;
+
+            avdd-supply = <&gc05a2_avdd>;
+            dovdd-supply = <&gc05a2_dovdd>;
+            dvdd-supply = <&gc05a2_dvdd>;
+
+            port {
+                sensor_out: endpoint {
+                    data-lanes = <1 2>;
+                    link-frequencies = /bits/ 64 <448000000 224000000>;
+                    remote-endpoint = <&seninf_csi_port_1_in>;
+                };
+            };
+        };
+    };
+
+...
-- 
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 related

* [PATCH v3 2/2] media: i2c: Add GC05A2 image sensor driver
From: Zhi Mao @ 2024-04-03  3:38 UTC (permalink / raw)
  To: mchehab, robh+dt, krzysztof.kozlowski+dt, sakari.ailus
  Cc: laurent.pinchart, shengnan.wang, yaya.chang,
	Project_Global_Chrome_Upstream_Group, yunkec, conor+dt,
	matthias.bgg, angelogioacchino.delregno, jacopo.mondi, zhi.mao,
	10572168, hverkuil-cisco, heiko, jernej.skrabec, macromorgan,
	linus.walleij, hdegoede, tomi.valkeinen, gerald.loacker,
	andy.shevchenko, bingbu.cao, dan.scally, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <20240403033825.9072-1-zhi.mao@mediatek.com>

Add a V4L2 sub-device driver for Galaxycore GC05A2 image sensor.

Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
---
 drivers/media/i2c/Kconfig  |   10 +
 drivers/media/i2c/Makefile |    1 +
 drivers/media/i2c/gc05a2.c | 1383 ++++++++++++++++++++++++++++++++++++
 3 files changed, 1394 insertions(+)
 create mode 100644 drivers/media/i2c/gc05a2.c

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 56f276b920ab..97993bf160f9 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -70,6 +70,16 @@ config VIDEO_GC0308
 	  To compile this driver as a module, choose M here: the
 	  module will be called gc0308.
 
+config VIDEO_GC05A2
+	tristate "GalaxyCore gc05a2 sensor support"
+	select V4L2_CCI_I2C
+	help
+	  This is a Video4Linux2 sensor driver for the GalaxyCore gc05a2
+	  camera.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gc05a2.
+
 config VIDEO_GC2145
 	select V4L2_CCI_I2C
 	tristate "GalaxyCore GC2145 sensor support"
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index dfbe6448b549..8ed6faf0f854 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
 obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
 obj-$(CONFIG_VIDEO_ET8EK8) += et8ek8/
 obj-$(CONFIG_VIDEO_GC0308) += gc0308.o
+obj-$(CONFIG_VIDEO_GC05A2) += gc05a2.o
 obj-$(CONFIG_VIDEO_GC2145) += gc2145.o
 obj-$(CONFIG_VIDEO_HI556) += hi556.o
 obj-$(CONFIG_VIDEO_HI846) += hi846.o
diff --git a/drivers/media/i2c/gc05a2.c b/drivers/media/i2c/gc05a2.c
new file mode 100644
index 000000000000..461d33055a3b
--- /dev/null
+++ b/drivers/media/i2c/gc05a2.c
@@ -0,0 +1,1383 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for GalaxyCore gc05a2 image sensor
+ *
+ * Copyright 2024 MediaTek
+ *
+ * Zhi Mao <zhi.mao@mediatek.com>
+ */
+#include <linux/array_size.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/container_of.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/math64.h>
+#include <linux/mod_devicetable.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/types.h>
+#include <linux/units.h>
+
+#include <media/v4l2-cci.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+
+#define GC05A2_REG_TEST_PATTERN_EN CCI_REG8(0x008c)
+#define GC05A2_REG_TEST_PATTERN_IDX CCI_REG8(0x008d)
+#define GC05A2_TEST_PATTERN_EN 0x01
+
+#define GC05A2_STREAMING_REG CCI_REG8(0x0100)
+
+#define GC05A2_FLIP_REG CCI_REG8(0x0101)
+#define GC05A2_FLIP_H_MASK BIT(0)
+#define GC05A2_FLIP_V_MASK BIT(1)
+
+#define GC05A2_EXP_REG CCI_REG16(0x0202)
+#define GC05A2_EXP_MARGIN 16
+#define GC05A2_EXP_MIN 4
+#define GC05A2_EXP_STEP 1
+
+#define GC05A2_AGAIN_REG CCI_REG16(0x0204)
+#define GC05A2_AGAIN_MIN 1024
+#define GC05A2_AGAIN_MAX (1024 * 16)
+#define GC05A2_AGAIN_STEP 1
+
+#define GC05A2_FRAME_LENGTH_REG CCI_REG16(0x0340)
+#define GC05A2_VTS_MAX 0xffff
+
+#define GC05A2_REG_CHIP_ID CCI_REG16(0x03f0)
+#define GC05A2_CHIP_ID 0x05a2
+
+#define GC05A2_NATIVE_WIDTH 2592
+#define GC05A2_NATIVE_HEIGHT 1944
+
+#define GC05A2_DEFAULT_CLK_FREQ (24 * HZ_PER_MHZ)
+#define GC05A2_MBUS_CODE MEDIA_BUS_FMT_SGRBG10_1X10
+#define GC05A2_DATA_LANES 2
+#define GC05A2_RGB_DEPTH 10
+#define GC05A2_SLEEP_US  (2 * USEC_PER_MSEC)
+
+static const char *const gc05a2_test_pattern_menu[] = {
+	"No Pattern",  "Fade_to_gray_Color Bar", "Color Bar",
+	"PN9",	       "Horizental_gradient",    "Checkboard Pattern",
+	"Slant",       "Resolution",	         "Solid Black",
+	"Solid White",
+};
+
+static const s64 gc05a2_link_freq_menu_items[] = {
+	(448 * HZ_PER_MHZ),
+	(224 * HZ_PER_MHZ),
+};
+
+static const char *const gc05a2_supply_name[] = {
+	"avdd",
+	"dvdd",
+	"dovdd",
+};
+
+struct gc05a2 {
+	struct device *dev;
+	struct v4l2_subdev sd;
+	struct media_pad pad;
+
+	struct clk *xclk;
+	struct regulator_bulk_data supplies[ARRAY_SIZE(gc05a2_supply_name)];
+	struct gpio_desc *reset_gpio;
+
+	struct v4l2_ctrl_handler ctrls;
+	struct v4l2_ctrl *pixel_rate;
+	struct v4l2_ctrl *link_freq;
+	struct v4l2_ctrl *exposure;
+	struct v4l2_ctrl *vblank;
+	struct v4l2_ctrl *hblank;
+	struct v4l2_ctrl *hflip;
+	struct v4l2_ctrl *vflip;
+
+	struct regmap *regmap;
+	unsigned long link_freq_bitmap;
+
+	/* True if the device has been identified */
+	bool identified;
+	const struct gc05a2_mode *cur_mode;
+};
+
+struct gc05a2_reg_list {
+	u32 num_of_regs;
+	const struct cci_reg_sequence *regs;
+};
+
+static const struct cci_reg_sequence mode_2592x1944[] = {
+	/* system */
+	{ CCI_REG8(0x0135), 0x01 },
+
+	/* pre_setting */
+	{ CCI_REG8(0x0084), 0x21 },
+	{ CCI_REG8(0x0d05), 0xcc },
+	{ CCI_REG8(0x0218), 0x00 },
+	{ CCI_REG8(0x005e), 0x48 },
+	{ CCI_REG8(0x0d06), 0x01 },
+	{ CCI_REG8(0x0007), 0x16 },
+	{ CCI_REG8(0x0101), 0x00 },
+
+	/* analog */
+	{ CCI_REG8(0x0342), 0x07 },
+	{ CCI_REG8(0x0343), 0x28 },
+	{ CCI_REG8(0x0220), 0x07 },
+	{ CCI_REG8(0x0221), 0xd0 },
+	{ CCI_REG8(0x0202), 0x07 },
+	{ CCI_REG8(0x0203), 0x32 },
+	{ CCI_REG8(0x0340), 0x07 },
+	{ CCI_REG8(0x0341), 0xf0 },
+	{ CCI_REG8(0x0219), 0x00 },
+	{ CCI_REG8(0x0346), 0x00 },
+	{ CCI_REG8(0x0347), 0x04 },
+	{ CCI_REG8(0x0d14), 0x00 },
+	{ CCI_REG8(0x0d13), 0x05 },
+	{ CCI_REG8(0x0d16), 0x05 },
+	{ CCI_REG8(0x0d15), 0x1d },
+	{ CCI_REG8(0x00c0), 0x0a },
+	{ CCI_REG8(0x00c1), 0x30 },
+	{ CCI_REG8(0x034a), 0x07 },
+	{ CCI_REG8(0x034b), 0xa8 },
+	{ CCI_REG8(0x0e0a), 0x00 },
+	{ CCI_REG8(0x0e0b), 0x00 },
+	{ CCI_REG8(0x0e0e), 0x03 },
+	{ CCI_REG8(0x0e0f), 0x00 },
+	{ CCI_REG8(0x0e06), 0x0a },
+	{ CCI_REG8(0x0e23), 0x15 },
+	{ CCI_REG8(0x0e24), 0x15 },
+	{ CCI_REG8(0x0e2a), 0x10 },
+	{ CCI_REG8(0x0e2b), 0x10 },
+	{ CCI_REG8(0x0e17), 0x49 },
+	{ CCI_REG8(0x0e1b), 0x1c },
+	{ CCI_REG8(0x0e3a), 0x36 },
+	{ CCI_REG8(0x0d11), 0x84 },
+	{ CCI_REG8(0x0e52), 0x14 },
+	{ CCI_REG8(0x000b), 0x10 },
+	{ CCI_REG8(0x0008), 0x08 },
+	{ CCI_REG8(0x0223), 0x17 },
+	{ CCI_REG8(0x0d27), 0x39 },
+	{ CCI_REG8(0x0d22), 0x00 },
+	{ CCI_REG8(0x03f6), 0x0d },
+	{ CCI_REG8(0x0d04), 0x07 },
+	{ CCI_REG8(0x03f3), 0x72 },
+	{ CCI_REG8(0x03f4), 0xb8 },
+	{ CCI_REG8(0x03f5), 0xbc },
+	{ CCI_REG8(0x0d02), 0x73 },
+
+	/* auto load start */
+	{ CCI_REG8(0x00cb), 0x00 },
+
+	/* OUT 2592*1944 */
+	{ CCI_REG8(0x0350), 0x01 },
+	{ CCI_REG8(0x0353), 0x00 },
+	{ CCI_REG8(0x0354), 0x08 },
+	{ CCI_REG8(0x034c), 0x0a },
+	{ CCI_REG8(0x034d), 0x20 },
+	{ CCI_REG8(0x021f), 0x14 },
+
+	/* MIPI */
+	{ CCI_REG8(0x0107), 0x05 },
+	{ CCI_REG8(0x0117), 0x01 },
+	{ CCI_REG8(0x0d81), 0x00 },
+	{ CCI_REG8(0x0d84), 0x0c },
+	{ CCI_REG8(0x0d85), 0xa8 },
+	{ CCI_REG8(0x0d86), 0x06 },
+	{ CCI_REG8(0x0d87), 0x55 },
+	{ CCI_REG8(0x0db3), 0x06 },
+	{ CCI_REG8(0x0db4), 0x08 },
+	{ CCI_REG8(0x0db5), 0x1e },
+	{ CCI_REG8(0x0db6), 0x02 },
+	{ CCI_REG8(0x0db8), 0x12 },
+	{ CCI_REG8(0x0db9), 0x0a },
+	{ CCI_REG8(0x0d93), 0x06 },
+	{ CCI_REG8(0x0d94), 0x09 },
+	{ CCI_REG8(0x0d95), 0x0d },
+	{ CCI_REG8(0x0d99), 0x0b },
+	{ CCI_REG8(0x0084), 0x01 },
+
+	/* OUT */
+	{ CCI_REG8(0x0110), 0x01 },
+};
+
+static const struct cci_reg_sequence mode_1280x720[] = {
+	/* system */
+	{ CCI_REG8(0x0135), 0x05 },
+
+	/*pre_setting*/
+	{ CCI_REG8(0x0084), 0x21 },
+	{ CCI_REG8(0x0d05), 0xcc },
+	{ CCI_REG8(0x0218), 0x80 },
+	{ CCI_REG8(0x005e), 0x49 },
+	{ CCI_REG8(0x0d06), 0x81 },
+	{ CCI_REG8(0x0007), 0x16 },
+	{ CCI_REG8(0x0101), 0x00 },
+
+	/* analog */
+	{ CCI_REG8(0x0342), 0x07 },
+	{ CCI_REG8(0x0343), 0x10 },
+	{ CCI_REG8(0x0220), 0x07 },
+	{ CCI_REG8(0x0221), 0xd0 },
+	{ CCI_REG8(0x0202), 0x03 },
+	{ CCI_REG8(0x0203), 0x32 },
+	{ CCI_REG8(0x0340), 0x04 },
+	{ CCI_REG8(0x0341), 0x08 },
+	{ CCI_REG8(0x0219), 0x00 },
+	{ CCI_REG8(0x0346), 0x01 },
+	{ CCI_REG8(0x0347), 0x00 },
+	{ CCI_REG8(0x0d14), 0x00 },
+	{ CCI_REG8(0x0d13), 0x05 },
+	{ CCI_REG8(0x0d16), 0x05 },
+	{ CCI_REG8(0x0d15), 0x1d },
+	{ CCI_REG8(0x00c0), 0x0a },
+	{ CCI_REG8(0x00c1), 0x30 },
+	{ CCI_REG8(0x034a), 0x05 },
+	{ CCI_REG8(0x034b), 0xb0 },
+	{ CCI_REG8(0x0e0a), 0x00 },
+	{ CCI_REG8(0x0e0b), 0x00 },
+	{ CCI_REG8(0x0e0e), 0x03 },
+	{ CCI_REG8(0x0e0f), 0x00 },
+	{ CCI_REG8(0x0e06), 0x0a },
+	{ CCI_REG8(0x0e23), 0x15 },
+	{ CCI_REG8(0x0e24), 0x15 },
+	{ CCI_REG8(0x0e2a), 0x10 },
+	{ CCI_REG8(0x0e2b), 0x10 },
+	{ CCI_REG8(0x0e17), 0x49 },
+	{ CCI_REG8(0x0e1b), 0x1c },
+	{ CCI_REG8(0x0e3a), 0x36 },
+	{ CCI_REG8(0x0d11), 0x84 },
+	{ CCI_REG8(0x0e52), 0x14 },
+	{ CCI_REG8(0x000b), 0x0e },
+	{ CCI_REG8(0x0008), 0x03 },
+	{ CCI_REG8(0x0223), 0x16 },
+	{ CCI_REG8(0x0d27), 0x39 },
+	{ CCI_REG8(0x0d22), 0x00 },
+	{ CCI_REG8(0x03f6), 0x0d },
+	{ CCI_REG8(0x0d04), 0x07 },
+	{ CCI_REG8(0x03f3), 0x72 },
+	{ CCI_REG8(0x03f4), 0xb8 },
+	{ CCI_REG8(0x03f5), 0xbc },
+	{ CCI_REG8(0x0d02), 0x73 },
+
+	/* auto load start */
+	{ CCI_REG8(0x00cb), 0xfc },
+
+	/* OUT 1280x720 */
+	{ CCI_REG8(0x0350), 0x01 },
+	{ CCI_REG8(0x0353), 0x00 },
+	{ CCI_REG8(0x0354), 0x0c },
+	{ CCI_REG8(0x034c), 0x05 },
+	{ CCI_REG8(0x034d), 0x00 },
+	{ CCI_REG8(0x021f), 0x14 },
+
+	/* MIPI */
+	{ CCI_REG8(0x0107), 0x05 },
+	{ CCI_REG8(0x0117), 0x01 },
+	{ CCI_REG8(0x0d81), 0x00 },
+	{ CCI_REG8(0x0d84), 0x06 },
+	{ CCI_REG8(0x0d85), 0x40 },
+	{ CCI_REG8(0x0d86), 0x03 },
+	{ CCI_REG8(0x0d87), 0x21 },
+	{ CCI_REG8(0x0db3), 0x03 },
+	{ CCI_REG8(0x0db4), 0x04 },
+	{ CCI_REG8(0x0db5), 0x0d },
+	{ CCI_REG8(0x0db6), 0x01 },
+	{ CCI_REG8(0x0db8), 0x04 },
+	{ CCI_REG8(0x0db9), 0x06 },
+	{ CCI_REG8(0x0d93), 0x03 },
+	{ CCI_REG8(0x0d94), 0x04 },
+	{ CCI_REG8(0x0d95), 0x05 },
+	{ CCI_REG8(0x0d99), 0x06 },
+	{ CCI_REG8(0x0084), 0x01 },
+
+	/* OUT */
+	{ CCI_REG8(0x0110), 0x01 },
+};
+
+static const struct cci_reg_sequence mode_table_common[] = {
+	{ GC05A2_STREAMING_REG, 0x00 },
+	/* system */
+	{ CCI_REG8(0x0315), 0xd4 },
+	{ CCI_REG8(0x0d06), 0x01 },
+	{ CCI_REG8(0x0a70), 0x80 },
+	{ CCI_REG8(0x031a), 0x00 },
+	{ CCI_REG8(0x0314), 0x00 },
+	{ CCI_REG8(0x0130), 0x08 },
+	{ CCI_REG8(0x0132), 0x01 },
+	{ CCI_REG8(0x0136), 0x38 },
+	{ CCI_REG8(0x0137), 0x03 },
+	{ CCI_REG8(0x0134), 0x5b },
+	{ CCI_REG8(0x031c), 0xe0 },
+	{ CCI_REG8(0x0d82), 0x14 },
+	{ CCI_REG8(0x0dd1), 0x56 },
+
+	/* gate_mode */
+	{ CCI_REG8(0x0af4), 0x01 },
+	{ CCI_REG8(0x0002), 0x10 },
+	{ CCI_REG8(0x00c3), 0x34 },
+
+	/* auto load start */
+	{ CCI_REG8(0x00c4), 0x00 },
+	{ CCI_REG8(0x00c5), 0x01 },
+	{ CCI_REG8(0x0af6), 0x00 },
+	{ CCI_REG8(0x0ba0), 0x17 },
+	{ CCI_REG8(0x0ba1), 0x00 },
+	{ CCI_REG8(0x0ba2), 0x00 },
+	{ CCI_REG8(0x0ba3), 0x00 },
+	{ CCI_REG8(0x0ba4), 0x03 },
+	{ CCI_REG8(0x0ba5), 0x00 },
+	{ CCI_REG8(0x0ba6), 0x00 },
+	{ CCI_REG8(0x0ba7), 0x00 },
+	{ CCI_REG8(0x0ba8), 0x40 },
+	{ CCI_REG8(0x0ba9), 0x00 },
+	{ CCI_REG8(0x0baa), 0x00 },
+	{ CCI_REG8(0x0bab), 0x00 },
+	{ CCI_REG8(0x0bac), 0x40 },
+	{ CCI_REG8(0x0bad), 0x00 },
+	{ CCI_REG8(0x0bae), 0x00 },
+	{ CCI_REG8(0x0baf), 0x00 },
+	{ CCI_REG8(0x0bb0), 0x02 },
+	{ CCI_REG8(0x0bb1), 0x00 },
+	{ CCI_REG8(0x0bb2), 0x00 },
+	{ CCI_REG8(0x0bb3), 0x00 },
+	{ CCI_REG8(0x0bb8), 0x02 },
+	{ CCI_REG8(0x0bb9), 0x00 },
+	{ CCI_REG8(0x0bba), 0x00 },
+	{ CCI_REG8(0x0bbb), 0x00 },
+	{ CCI_REG8(0x0a70), 0x80 },
+	{ CCI_REG8(0x0a71), 0x00 },
+	{ CCI_REG8(0x0a72), 0x00 },
+	{ CCI_REG8(0x0a66), 0x00 },
+	{ CCI_REG8(0x0a67), 0x80 },
+	{ CCI_REG8(0x0a4d), 0x4e },
+	{ CCI_REG8(0x0a50), 0x00 },
+	{ CCI_REG8(0x0a4f), 0x0c },
+	{ CCI_REG8(0x0a66), 0x00 },
+	{ CCI_REG8(0x00ca), 0x00 },
+	{ CCI_REG8(0x00cc), 0x00 },
+	{ CCI_REG8(0x00cd), 0x00 },
+	{ CCI_REG8(0x0aa1), 0x00 },
+	{ CCI_REG8(0x0aa2), 0xe0 },
+	{ CCI_REG8(0x0aa3), 0x00 },
+	{ CCI_REG8(0x0aa4), 0x40 },
+	{ CCI_REG8(0x0a90), 0x03 },
+	{ CCI_REG8(0x0a91), 0x0e },
+	{ CCI_REG8(0x0a94), 0x80 },
+
+	/* standby */
+	{ CCI_REG8(0x0af6), 0x20 },
+	{ CCI_REG8(0x0b00), 0x91 },
+	{ CCI_REG8(0x0b01), 0x17 },
+	{ CCI_REG8(0x0b02), 0x01 },
+	{ CCI_REG8(0x0b03), 0x00 },
+	{ CCI_REG8(0x0b04), 0x01 },
+	{ CCI_REG8(0x0b05), 0x17 },
+	{ CCI_REG8(0x0b06), 0x01 },
+	{ CCI_REG8(0x0b07), 0x00 },
+	{ CCI_REG8(0x0ae9), 0x01 },
+	{ CCI_REG8(0x0aea), 0x02 },
+	{ CCI_REG8(0x0ae8), 0x53 },
+	{ CCI_REG8(0x0ae8), 0x43 },
+
+	/* gain_partition */
+	{ CCI_REG8(0x0af6), 0x30 },
+	{ CCI_REG8(0x0b00), 0x08 },
+	{ CCI_REG8(0x0b01), 0x0f },
+	{ CCI_REG8(0x0b02), 0x00 },
+	{ CCI_REG8(0x0b04), 0x1c },
+	{ CCI_REG8(0x0b05), 0x24 },
+	{ CCI_REG8(0x0b06), 0x00 },
+	{ CCI_REG8(0x0b08), 0x30 },
+	{ CCI_REG8(0x0b09), 0x40 },
+	{ CCI_REG8(0x0b0a), 0x00 },
+	{ CCI_REG8(0x0b0c), 0x0e },
+	{ CCI_REG8(0x0b0d), 0x2a },
+	{ CCI_REG8(0x0b0e), 0x00 },
+	{ CCI_REG8(0x0b10), 0x0e },
+	{ CCI_REG8(0x0b11), 0x2b },
+	{ CCI_REG8(0x0b12), 0x00 },
+	{ CCI_REG8(0x0b14), 0x0e },
+	{ CCI_REG8(0x0b15), 0x23 },
+	{ CCI_REG8(0x0b16), 0x00 },
+	{ CCI_REG8(0x0b18), 0x0e },
+	{ CCI_REG8(0x0b19), 0x24 },
+	{ CCI_REG8(0x0b1a), 0x00 },
+	{ CCI_REG8(0x0b1c), 0x0c },
+	{ CCI_REG8(0x0b1d), 0x0c },
+	{ CCI_REG8(0x0b1e), 0x00 },
+	{ CCI_REG8(0x0b20), 0x03 },
+	{ CCI_REG8(0x0b21), 0x03 },
+	{ CCI_REG8(0x0b22), 0x00 },
+	{ CCI_REG8(0x0b24), 0x0e },
+	{ CCI_REG8(0x0b25), 0x0e },
+	{ CCI_REG8(0x0b26), 0x00 },
+	{ CCI_REG8(0x0b28), 0x03 },
+	{ CCI_REG8(0x0b29), 0x03 },
+	{ CCI_REG8(0x0b2a), 0x00 },
+	{ CCI_REG8(0x0b2c), 0x12 },
+	{ CCI_REG8(0x0b2d), 0x12 },
+	{ CCI_REG8(0x0b2e), 0x00 },
+	{ CCI_REG8(0x0b30), 0x08 },
+	{ CCI_REG8(0x0b31), 0x08 },
+	{ CCI_REG8(0x0b32), 0x00 },
+	{ CCI_REG8(0x0b34), 0x14 },
+	{ CCI_REG8(0x0b35), 0x14 },
+	{ CCI_REG8(0x0b36), 0x00 },
+	{ CCI_REG8(0x0b38), 0x10 },
+	{ CCI_REG8(0x0b39), 0x10 },
+	{ CCI_REG8(0x0b3a), 0x00 },
+	{ CCI_REG8(0x0b3c), 0x16 },
+	{ CCI_REG8(0x0b3d), 0x16 },
+	{ CCI_REG8(0x0b3e), 0x00 },
+	{ CCI_REG8(0x0b40), 0x10 },
+	{ CCI_REG8(0x0b41), 0x10 },
+	{ CCI_REG8(0x0b42), 0x00 },
+	{ CCI_REG8(0x0b44), 0x19 },
+	{ CCI_REG8(0x0b45), 0x19 },
+	{ CCI_REG8(0x0b46), 0x00 },
+	{ CCI_REG8(0x0b48), 0x16 },
+	{ CCI_REG8(0x0b49), 0x16 },
+	{ CCI_REG8(0x0b4a), 0x00 },
+	{ CCI_REG8(0x0b4c), 0x19 },
+	{ CCI_REG8(0x0b4d), 0x19 },
+	{ CCI_REG8(0x0b4e), 0x00 },
+	{ CCI_REG8(0x0b50), 0x16 },
+	{ CCI_REG8(0x0b51), 0x16 },
+	{ CCI_REG8(0x0b52), 0x00 },
+	{ CCI_REG8(0x0b80), 0x01 },
+	{ CCI_REG8(0x0b81), 0x00 },
+	{ CCI_REG8(0x0b82), 0x00 },
+	{ CCI_REG8(0x0b84), 0x00 },
+	{ CCI_REG8(0x0b85), 0x00 },
+	{ CCI_REG8(0x0b86), 0x00 },
+	{ CCI_REG8(0x0b88), 0x01 },
+	{ CCI_REG8(0x0b89), 0x6a },
+	{ CCI_REG8(0x0b8a), 0x00 },
+	{ CCI_REG8(0x0b8c), 0x00 },
+	{ CCI_REG8(0x0b8d), 0x01 },
+	{ CCI_REG8(0x0b8e), 0x00 },
+	{ CCI_REG8(0x0b90), 0x01 },
+	{ CCI_REG8(0x0b91), 0xf6 },
+	{ CCI_REG8(0x0b92), 0x00 },
+	{ CCI_REG8(0x0b94), 0x00 },
+	{ CCI_REG8(0x0b95), 0x02 },
+	{ CCI_REG8(0x0b96), 0x00 },
+	{ CCI_REG8(0x0b98), 0x02 },
+	{ CCI_REG8(0x0b99), 0xc4 },
+	{ CCI_REG8(0x0b9a), 0x00 },
+	{ CCI_REG8(0x0b9c), 0x00 },
+	{ CCI_REG8(0x0b9d), 0x03 },
+	{ CCI_REG8(0x0b9e), 0x00 },
+	{ CCI_REG8(0x0ba0), 0x03 },
+	{ CCI_REG8(0x0ba1), 0xd8 },
+	{ CCI_REG8(0x0ba2), 0x00 },
+	{ CCI_REG8(0x0ba4), 0x00 },
+	{ CCI_REG8(0x0ba5), 0x04 },
+	{ CCI_REG8(0x0ba6), 0x00 },
+	{ CCI_REG8(0x0ba8), 0x05 },
+	{ CCI_REG8(0x0ba9), 0x4d },
+	{ CCI_REG8(0x0baa), 0x00 },
+	{ CCI_REG8(0x0bac), 0x00 },
+	{ CCI_REG8(0x0bad), 0x05 },
+	{ CCI_REG8(0x0bae), 0x00 },
+	{ CCI_REG8(0x0bb0), 0x07 },
+	{ CCI_REG8(0x0bb1), 0x3e },
+	{ CCI_REG8(0x0bb2), 0x00 },
+	{ CCI_REG8(0x0bb4), 0x00 },
+	{ CCI_REG8(0x0bb5), 0x06 },
+	{ CCI_REG8(0x0bb6), 0x00 },
+	{ CCI_REG8(0x0bb8), 0x0a },
+	{ CCI_REG8(0x0bb9), 0x1a },
+	{ CCI_REG8(0x0bba), 0x00 },
+	{ CCI_REG8(0x0bbc), 0x09 },
+	{ CCI_REG8(0x0bbd), 0x36 },
+	{ CCI_REG8(0x0bbe), 0x00 },
+	{ CCI_REG8(0x0bc0), 0x0e },
+	{ CCI_REG8(0x0bc1), 0x66 },
+	{ CCI_REG8(0x0bc2), 0x00 },
+	{ CCI_REG8(0x0bc4), 0x10 },
+	{ CCI_REG8(0x0bc5), 0x06 },
+	{ CCI_REG8(0x0bc6), 0x00 },
+	{ CCI_REG8(0x02c1), 0xe0 },
+	{ CCI_REG8(0x0207), 0x04 },
+	{ CCI_REG8(0x02c2), 0x10 },
+	{ CCI_REG8(0x02c3), 0x74 },
+	{ CCI_REG8(0x02c5), 0x09 },
+	{ CCI_REG8(0x02c1), 0xe0 },
+	{ CCI_REG8(0x0207), 0x04 },
+	{ CCI_REG8(0x02c2), 0x10 },
+	{ CCI_REG8(0x02c5), 0x09 },
+	{ CCI_REG8(0x02c1), 0xe0 },
+	{ CCI_REG8(0x0207), 0x04 },
+	{ CCI_REG8(0x02c2), 0x10 },
+	{ CCI_REG8(0x02c5), 0x09 },
+
+	/* auto load CH_GAIN */
+	{ CCI_REG8(0x0aa1), 0x15 },
+	{ CCI_REG8(0x0aa2), 0x50 },
+	{ CCI_REG8(0x0aa3), 0x00 },
+	{ CCI_REG8(0x0aa4), 0x09 },
+	{ CCI_REG8(0x0a90), 0x25 },
+	{ CCI_REG8(0x0a91), 0x0e },
+	{ CCI_REG8(0x0a94), 0x80 },
+
+	/* ISP */
+	{ CCI_REG8(0x0050), 0x00 },
+	{ CCI_REG8(0x0089), 0x83 },
+	{ CCI_REG8(0x005a), 0x40 },
+	{ CCI_REG8(0x00c3), 0x35 },
+	{ CCI_REG8(0x00c4), 0x80 },
+	{ CCI_REG8(0x0080), 0x10 },
+	{ CCI_REG8(0x0040), 0x12 },
+	{ CCI_REG8(0x0053), 0x0a },
+	{ CCI_REG8(0x0054), 0x44 },
+	{ CCI_REG8(0x0055), 0x32 },
+	{ CCI_REG8(0x0058), 0x89 },
+	{ CCI_REG8(0x004a), 0x03 },
+	{ CCI_REG8(0x0048), 0xf0 },
+	{ CCI_REG8(0x0049), 0x0f },
+	{ CCI_REG8(0x0041), 0x20 },
+	{ CCI_REG8(0x0043), 0x0a },
+	{ CCI_REG8(0x009d), 0x08 },
+	{ CCI_REG8(0x0236), 0x40 },
+
+	/* gain */
+	{ CCI_REG8(0x0204), 0x04 },
+	{ CCI_REG8(0x0205), 0x00 },
+	{ CCI_REG8(0x02b3), 0x00 },
+	{ CCI_REG8(0x02b4), 0x00 },
+	{ CCI_REG8(0x009e), 0x01 },
+	{ CCI_REG8(0x009f), 0x94 },
+
+	/* auto load REG */
+	{ CCI_REG8(0x0aa1), 0x10 },
+	{ CCI_REG8(0x0aa2), 0xf8 },
+	{ CCI_REG8(0x0aa3), 0x00 },
+	{ CCI_REG8(0x0aa4), 0x1f },
+	{ CCI_REG8(0x0a90), 0x11 },
+	{ CCI_REG8(0x0a91), 0x0e },
+	{ CCI_REG8(0x0a94), 0x80 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x0a90), 0x00 },
+	{ CCI_REG8(0x0a70), 0x00 },
+	{ CCI_REG8(0x0a67), 0x00 },
+	{ CCI_REG8(0x0af4), 0x29 },
+
+	/* DPHY */
+	{ CCI_REG8(0x0d80), 0x07 },
+	{ CCI_REG8(0x0dd3), 0x18 },
+
+	/* CISCTL_Reset */
+	{ CCI_REG8(0x031c), 0x80 },
+	{ CCI_REG8(0x03fe), 0x30 },
+	{ CCI_REG8(0x0d17), 0x06 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x0d17), 0x00 },
+	{ CCI_REG8(0x031c), 0x93 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x031c), 0x80 },
+	{ CCI_REG8(0x03fe), 0x30 },
+	{ CCI_REG8(0x0d17), 0x06 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x0d17), 0x00 },
+	{ CCI_REG8(0x031c), 0x93 },
+};
+
+struct gc05a2_mode {
+	u32 width;
+	u32 height;
+	const struct gc05a2_reg_list reg_list;
+
+	u32 hts; /* Horizontal timining size */
+	u32 vts_def; /* Default vertical timining size */
+	u32 vts_min; /* Min vertical timining size */
+};
+
+/* Declare modes in order, from biggest to smallest height. */
+static const struct gc05a2_mode gc05a2_modes[] = {
+	{
+		/* 2592*1944@30fps */
+		.width = GC05A2_NATIVE_WIDTH,
+		.height = GC05A2_NATIVE_HEIGHT,
+		.reg_list = {
+			.num_of_regs = ARRAY_SIZE(mode_2592x1944),
+			.regs = mode_2592x1944,
+		},
+		.hts = 3664,
+		.vts_def = 2032,
+		.vts_min = 2032,
+	},
+	{
+		/* 1280*720@60fps */
+		.width = 1280,
+		.height = 720,
+		.reg_list = {
+			.num_of_regs = ARRAY_SIZE(mode_1280x720),
+			.regs = mode_1280x720,
+		},
+		.hts = 3616,
+		.vts_def = 1032,
+		.vts_min = 1032,
+	},
+};
+
+static inline struct gc05a2 *to_gc05a2(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct gc05a2, sd);
+}
+
+static int gc05a2_power_on(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct gc05a2 *gc05a2 = to_gc05a2(sd);
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(gc05a2_supply_name),
+				    gc05a2->supplies);
+	if (ret < 0) {
+		dev_err(gc05a2->dev, "failed to enable regulators: %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(gc05a2->xclk);
+	if (ret < 0) {
+		regulator_bulk_disable(ARRAY_SIZE(gc05a2_supply_name),
+				       gc05a2->supplies);
+		dev_err(gc05a2->dev, "clk prepare enable failed\n");
+		return ret;
+	}
+
+	fsleep(GC05A2_SLEEP_US);
+
+	gpiod_set_value_cansleep(gc05a2->reset_gpio, 0);
+	fsleep(GC05A2_SLEEP_US);
+
+	return 0;
+}
+
+static int gc05a2_power_off(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct gc05a2 *gc05a2 = to_gc05a2(sd);
+
+	clk_disable_unprepare(gc05a2->xclk);
+	gpiod_set_value_cansleep(gc05a2->reset_gpio, 1);
+	regulator_bulk_disable(ARRAY_SIZE(gc05a2_supply_name),
+			       gc05a2->supplies);
+
+	return 0;
+}
+
+static int gc05a2_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *sd_state,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index > 0)
+		return -EINVAL;
+
+	code->code = GC05A2_MBUS_CODE;
+
+	return 0;
+}
+
+static int gc05a2_enum_frame_size(struct v4l2_subdev *subdev,
+				  struct v4l2_subdev_state *sd_state,
+				  struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->code != GC05A2_MBUS_CODE)
+		return -EINVAL;
+
+	if (fse->index >= ARRAY_SIZE(gc05a2_modes))
+		return -EINVAL;
+
+	fse->min_width = gc05a2_modes[fse->index].width;
+	fse->max_width = gc05a2_modes[fse->index].width;
+	fse->min_height = gc05a2_modes[fse->index].height;
+	fse->max_height = gc05a2_modes[fse->index].height;
+
+	return 0;
+}
+
+static int gc05a2_update_cur_mode_controls(struct gc05a2 *gc05a2,
+					   const struct gc05a2_mode *mode)
+{
+	s64 exposure_max, h_blank;
+	int ret;
+
+	ret = __v4l2_ctrl_modify_range(gc05a2->vblank,
+				       mode->vts_min - mode->height,
+				       GC05A2_VTS_MAX - mode->height, 1,
+				       mode->vts_def - mode->height);
+	if (ret) {
+		dev_err(gc05a2->dev, "VB ctrl range update failed\n");
+		return ret;
+	}
+
+	h_blank = mode->hts - mode->width;
+	ret = __v4l2_ctrl_modify_range(gc05a2->hblank, h_blank, h_blank, 1,
+				       h_blank);
+	if (ret) {
+		dev_err(gc05a2->dev, "HB ctrl range update failed\n");
+		return ret;
+	}
+
+	exposure_max = mode->vts_def - GC05A2_EXP_MARGIN;
+	ret = __v4l2_ctrl_modify_range(gc05a2->exposure, GC05A2_EXP_MIN,
+				       exposure_max, GC05A2_EXP_STEP,
+				       exposure_max);
+	if (ret) {
+		dev_err(gc05a2->dev, "exposure ctrl range update failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void gc05a2_update_pad_format(struct gc05a2 *gc08a3,
+				     const struct gc05a2_mode *mode,
+				     struct v4l2_mbus_framefmt *fmt)
+{
+	fmt->width = mode->width;
+	fmt->height = mode->height;
+	fmt->code = GC05A2_MBUS_CODE;
+	fmt->field = V4L2_FIELD_NONE;
+	fmt->colorspace = V4L2_COLORSPACE_RAW;
+	fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
+	fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+	fmt->xfer_func = V4L2_XFER_FUNC_NONE;
+}
+
+static int gc05a2_set_format(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_state *state,
+			     struct v4l2_subdev_format *fmt)
+{
+	struct gc05a2 *gc05a2 = to_gc05a2(sd);
+	struct v4l2_mbus_framefmt *mbus_fmt;
+	struct v4l2_rect *crop;
+	const struct gc05a2_mode *mode;
+
+	mode = v4l2_find_nearest_size(gc05a2_modes, ARRAY_SIZE(gc05a2_modes),
+				      width, height, fmt->format.width,
+				      fmt->format.height);
+
+	/* update crop info to subdev state */
+	crop = v4l2_subdev_state_get_crop(state, 0);
+	crop->width = mode->width;
+	crop->height = mode->height;
+
+	/* update fmt info to subdev state */
+	gc05a2_update_pad_format(gc05a2, mode, &fmt->format);
+	mbus_fmt = v4l2_subdev_state_get_format(state, 0);
+	*mbus_fmt = fmt->format;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+		return 0;
+	gc05a2->cur_mode = mode;
+	gc05a2_update_cur_mode_controls(gc05a2, mode);
+
+	return 0;
+}
+
+static int gc05a2_get_selection(struct v4l2_subdev *sd,
+				struct v4l2_subdev_state *state,
+				struct v4l2_subdev_selection *sel)
+{
+	switch (sel->target) {
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+	case V4L2_SEL_TGT_CROP:
+		sel->r = *v4l2_subdev_state_get_crop(state, 0);
+		break;
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		sel->r.top = 0;
+		sel->r.left = 0;
+		sel->r.width = GC05A2_NATIVE_WIDTH;
+		sel->r.height = GC05A2_NATIVE_HEIGHT;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int gc05a2_init_state(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_state *state)
+{
+	struct v4l2_subdev_format fmt = {
+		.which = V4L2_SUBDEV_FORMAT_TRY,
+		.pad = 0,
+		.format = {
+			.code = GC05A2_MBUS_CODE,
+			.width = gc05a2_modes[0].width,
+			.height = gc05a2_modes[0].height,
+		},
+	};
+
+	gc05a2_set_format(sd, state, &fmt);
+
+	return 0;
+}
+
+static int gc05a2_set_ctrl_hflip(struct gc05a2 *gc05a2, u32 ctrl_val)
+{
+	int ret;
+	u64 val;
+
+	ret = cci_read(gc05a2->regmap, GC05A2_FLIP_REG, &val, NULL);
+	if (ret) {
+		dev_err(gc05a2->dev, "read hflip register failed: %d\n", ret);
+		return ret;
+	}
+
+	return cci_update_bits(gc05a2->regmap, GC05A2_FLIP_REG,
+			       GC05A2_FLIP_H_MASK,
+			       ctrl_val ? GC05A2_FLIP_H_MASK : 0, NULL);
+}
+
+static int gc05a2_set_ctrl_vflip(struct gc05a2 *gc05a2, u32 ctrl_val)
+{
+	int ret;
+	u64 val;
+
+	ret = cci_read(gc05a2->regmap, GC05A2_FLIP_REG, &val, NULL);
+	if (ret) {
+		dev_err(gc05a2->dev, "read vflip register failed: %d\n", ret);
+		return ret;
+	}
+
+	return cci_update_bits(gc05a2->regmap, GC05A2_FLIP_REG,
+			       GC05A2_FLIP_V_MASK,
+			       ctrl_val ? GC05A2_FLIP_V_MASK : 0, NULL);
+}
+
+static int gc05a2_test_pattern(struct gc05a2 *gc05a2, u32 pattern_menu)
+{
+	u32 pattern;
+	int ret;
+
+	if (pattern_menu) {
+		switch (pattern_menu) {
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+		case 5:
+		case 6:
+		case 7:
+			pattern = pattern_menu << 4;
+			break;
+
+		case 8:
+			pattern = 0;
+			break;
+
+		case 9:
+			pattern = 4;
+			break;
+
+		default:
+			pattern = 0x00;
+			break;
+		}
+
+		ret = cci_write(gc05a2->regmap, GC05A2_REG_TEST_PATTERN_IDX,
+				pattern, NULL);
+		if (ret)
+			return ret;
+
+		return cci_write(gc05a2->regmap, GC05A2_REG_TEST_PATTERN_EN,
+				 GC05A2_TEST_PATTERN_EN, NULL);
+	} else {
+		return cci_write(gc05a2->regmap, GC05A2_REG_TEST_PATTERN_EN,
+				 0x00, NULL);
+	}
+}
+
+static int gc05a2_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct gc05a2 *gc05a2 =
+		container_of(ctrl->handler, struct gc05a2, ctrls);
+	int ret = 0;
+	s64 exposure_max;
+	struct v4l2_subdev_state *state;
+	const struct v4l2_mbus_framefmt *format;
+
+	state = v4l2_subdev_get_locked_active_state(&gc05a2->sd);
+	format = v4l2_subdev_state_get_format(state, 0);
+
+	if (ctrl->id == V4L2_CID_VBLANK) {
+		/* Update max exposure while meeting expected vblanking */
+		exposure_max = format->height + ctrl->val - GC05A2_EXP_MARGIN;
+		__v4l2_ctrl_modify_range(gc05a2->exposure,
+					 gc05a2->exposure->minimum,
+					 exposure_max, gc05a2->exposure->step,
+					 exposure_max);
+	}
+
+	/*
+	 * Applying V4L2 control value only happens
+	 * when power is on for streaming.
+	 */
+	if (!pm_runtime_get_if_active(gc05a2->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		ret = cci_write(gc05a2->regmap, GC05A2_EXP_REG,
+				ctrl->val, NULL);
+		break;
+
+	case V4L2_CID_ANALOGUE_GAIN:
+		ret = cci_write(gc05a2->regmap, GC05A2_AGAIN_REG,
+				ctrl->val, NULL);
+		break;
+
+	case V4L2_CID_VBLANK:
+		ret = cci_write(gc05a2->regmap, GC05A2_FRAME_LENGTH_REG,
+				gc05a2->cur_mode->height + ctrl->val, NULL);
+		break;
+
+	case V4L2_CID_HFLIP:
+		ret = gc05a2_set_ctrl_hflip(gc05a2, ctrl->val);
+		break;
+
+	case V4L2_CID_VFLIP:
+		ret = gc05a2_set_ctrl_vflip(gc05a2, ctrl->val);
+		break;
+
+	case V4L2_CID_TEST_PATTERN:
+		ret = gc05a2_test_pattern(gc05a2, ctrl->val);
+		break;
+
+	default:
+		break;
+	}
+
+	pm_runtime_put(gc05a2->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops gc05a2_ctrl_ops = {
+	.s_ctrl = gc05a2_set_ctrl,
+};
+
+static int gc05a2_identify_module(struct gc05a2 *gc05a2)
+{
+	u64 val;
+	int ret;
+
+	if (gc05a2->identified)
+		return 0;
+
+	ret = cci_read(gc05a2->regmap, GC05A2_REG_CHIP_ID, &val, NULL);
+	if (ret)
+		return ret;
+
+	if (val != GC05A2_CHIP_ID) {
+		dev_err(gc05a2->dev, "chip id mismatch: 0x%x!=0x%llx",
+			GC05A2_CHIP_ID, val);
+		return -ENXIO;
+	}
+
+	gc05a2->identified = true;
+
+	return 0;
+}
+
+static int gc05a2_start_streaming(struct gc05a2 *gc05a2)
+{
+	const struct gc05a2_mode *mode;
+	const struct gc05a2_reg_list *reg_list;
+	int ret;
+
+	ret = pm_runtime_resume_and_get(gc05a2->dev);
+	if (ret < 0)
+		return ret;
+
+	ret = gc05a2_identify_module(gc05a2);
+	if (ret)
+		goto err_rpm_put;
+
+	ret = cci_multi_reg_write(gc05a2->regmap,
+				  mode_table_common,
+				  ARRAY_SIZE(mode_table_common), NULL);
+	if (ret)
+		goto err_rpm_put;
+
+	mode = gc05a2->cur_mode;
+	reg_list = &mode->reg_list;
+
+	ret = cci_multi_reg_write(gc05a2->regmap,
+				  reg_list->regs, reg_list->num_of_regs, NULL);
+	if (ret < 0)
+		goto err_rpm_put;
+
+	ret = __v4l2_ctrl_handler_setup(&gc05a2->ctrls);
+	if (ret < 0) {
+		dev_err(gc05a2->dev, "could not sync v4l2 controls\n");
+		goto err_rpm_put;
+	}
+
+	ret = cci_write(gc05a2->regmap, GC05A2_STREAMING_REG, 1, NULL);
+	if (ret < 0) {
+		dev_err(gc05a2->dev, "write STREAMING_REG failed: %d\n", ret);
+		goto err_rpm_put;
+	}
+
+	return 0;
+
+err_rpm_put:
+	pm_runtime_put(gc05a2->dev);
+	return ret;
+}
+
+static int gc05a2_stop_streaming(struct gc05a2 *gc05a2)
+{
+	int ret;
+
+	ret = cci_write(gc05a2->regmap, GC05A2_STREAMING_REG, 0, NULL);
+	if (ret < 0)
+		dev_err(gc05a2->dev, "could not sent stop streaming %d\n", ret);
+
+	pm_runtime_put(gc05a2->dev);
+	return ret;
+}
+
+static int gc05a2_s_stream(struct v4l2_subdev *subdev, int enable)
+{
+	struct gc05a2 *gc05a2 = to_gc05a2(subdev);
+	struct v4l2_subdev_state *state;
+	int ret;
+
+	state = v4l2_subdev_lock_and_get_active_state(subdev);
+
+	if (enable)
+		ret = gc05a2_start_streaming(gc05a2);
+	else
+		ret = gc05a2_stop_streaming(gc05a2);
+
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static const struct v4l2_subdev_video_ops gc05a2_video_ops = {
+	.s_stream = gc05a2_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops gc05a2_subdev_pad_ops = {
+	.enum_mbus_code = gc05a2_enum_mbus_code,
+	.enum_frame_size = gc05a2_enum_frame_size,
+	.get_fmt = v4l2_subdev_get_fmt,
+	.set_fmt = gc05a2_set_format,
+	.get_selection = gc05a2_get_selection,
+};
+
+static const struct v4l2_subdev_core_ops gc05a2_core_ops = {
+	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_ops gc05a2_subdev_ops = {
+	.core = &gc05a2_core_ops,
+	.video = &gc05a2_video_ops,
+	.pad = &gc05a2_subdev_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops gc05a2_internal_ops = {
+	.init_state = gc05a2_init_state,
+};
+
+static int gc05a2_get_regulators(struct device *dev, struct gc05a2 *gc05a2)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(gc05a2_supply_name); i++)
+		gc05a2->supplies[i].supply = gc05a2_supply_name[i];
+
+	return devm_regulator_bulk_get(dev, ARRAY_SIZE(gc05a2_supply_name),
+				       gc05a2->supplies);
+}
+
+static int gc05a2_parse_fwnode(struct gc05a2 *gc05a2)
+{
+	struct fwnode_handle *endpoint;
+	struct v4l2_fwnode_endpoint bus_cfg = {
+		.bus_type = V4L2_MBUS_CSI2_DPHY,
+	};
+	int ret;
+	struct device *dev = gc05a2->dev;
+
+	endpoint =
+		fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0,
+						FWNODE_GRAPH_ENDPOINT_NEXT);
+	if (!endpoint) {
+		dev_err(dev, "endpoint node not found\n");
+		return -EINVAL;
+	}
+
+	ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);
+	if (ret) {
+		dev_err(dev, "parsing endpoint node failed\n");
+		goto done;
+	}
+
+	ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
+				       bus_cfg.nr_of_link_frequencies,
+				       gc05a2_link_freq_menu_items,
+				       ARRAY_SIZE(gc05a2_link_freq_menu_items),
+				       &gc05a2->link_freq_bitmap);
+	if (ret)
+		goto done;
+
+done:
+	v4l2_fwnode_endpoint_free(&bus_cfg);
+	fwnode_handle_put(endpoint);
+	return ret;
+}
+
+static u64 gc05a2_to_pixel_rate(u32 f_index)
+{
+	u64 pixel_rate =
+		gc05a2_link_freq_menu_items[f_index] * 2 * GC05A2_DATA_LANES;
+
+	return div_u64(pixel_rate, GC05A2_RGB_DEPTH);
+}
+
+static int gc05a2_init_controls(struct gc05a2 *gc05a2)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&gc05a2->sd);
+	const struct gc05a2_mode *mode = &gc05a2_modes[0];
+	const struct v4l2_ctrl_ops *ops = &gc05a2_ctrl_ops;
+	struct v4l2_fwnode_device_properties props;
+	struct v4l2_ctrl_handler *ctrl_hdlr;
+	s64 exposure_max, h_blank;
+	int ret;
+
+	ctrl_hdlr = &gc05a2->ctrls;
+	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 9);
+	if (ret)
+		return ret;
+
+	gc05a2->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &gc05a2_ctrl_ops,
+					  V4L2_CID_HFLIP, 0, 1, 1, 0);
+	gc05a2->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &gc05a2_ctrl_ops,
+					  V4L2_CID_VFLIP, 0, 1, 1, 0);
+	v4l2_ctrl_cluster(2, &gc05a2->hflip);
+
+	gc05a2->link_freq =
+	v4l2_ctrl_new_int_menu(ctrl_hdlr,
+			       &gc05a2_ctrl_ops,
+			       V4L2_CID_LINK_FREQ,
+			       ARRAY_SIZE(gc05a2_link_freq_menu_items) - 1,
+			       0,
+			       gc05a2_link_freq_menu_items);
+	if (gc05a2->link_freq)
+		gc05a2->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	gc05a2->pixel_rate =
+		v4l2_ctrl_new_std(ctrl_hdlr,
+				  &gc05a2_ctrl_ops,
+				  V4L2_CID_PIXEL_RATE, 0,
+				  gc05a2_to_pixel_rate(0),
+				  1,
+				  gc05a2_to_pixel_rate(0));
+
+	gc05a2->vblank =
+		v4l2_ctrl_new_std(ctrl_hdlr,
+				  &gc05a2_ctrl_ops, V4L2_CID_VBLANK,
+				  mode->vts_min - mode->height,
+				  GC05A2_VTS_MAX - mode->height, 1,
+				  mode->vts_def - mode->height);
+
+	h_blank = mode->hts - mode->width;
+	gc05a2->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &gc05a2_ctrl_ops,
+					   V4L2_CID_HBLANK, h_blank, h_blank, 1,
+					   h_blank);
+	if (gc05a2->hblank)
+		gc05a2->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	v4l2_ctrl_new_std(ctrl_hdlr, &gc05a2_ctrl_ops,
+			  V4L2_CID_ANALOGUE_GAIN, GC05A2_AGAIN_MIN,
+			  GC05A2_AGAIN_MAX, GC05A2_AGAIN_STEP,
+			  GC05A2_AGAIN_MIN);
+
+	exposure_max = mode->vts_def - GC05A2_EXP_MARGIN;
+	gc05a2->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &gc05a2_ctrl_ops,
+					     V4L2_CID_EXPOSURE, GC05A2_EXP_MIN,
+					     exposure_max, GC05A2_EXP_STEP,
+					     exposure_max);
+
+	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &gc05a2_ctrl_ops,
+				     V4L2_CID_TEST_PATTERN,
+				     ARRAY_SIZE(gc05a2_test_pattern_menu) - 1,
+				     0, 0, gc05a2_test_pattern_menu);
+
+	/* register properties to fwnode (e.g. rotation, orientation) */
+	ret = v4l2_fwnode_device_parse(&client->dev, &props);
+	if (ret)
+		goto error_ctrls;
+
+	ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, ops, &props);
+	if (ret)
+		goto error_ctrls;
+
+	if (ctrl_hdlr->error) {
+		ret = ctrl_hdlr->error;
+		goto error_ctrls;
+	}
+
+	gc05a2->sd.ctrl_handler = ctrl_hdlr;
+
+	return 0;
+
+error_ctrls:
+	v4l2_ctrl_handler_free(ctrl_hdlr);
+
+	return ret;
+}
+
+static int gc05a2_probe(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+	struct gc05a2 *gc05a2;
+	int ret;
+
+	gc05a2 = devm_kzalloc(dev, sizeof(*gc05a2), GFP_KERNEL);
+	if (!gc05a2)
+		return -ENOMEM;
+
+	gc05a2->dev = dev;
+
+	ret = gc05a2_parse_fwnode(gc05a2);
+	if (ret)
+		return ret;
+
+	gc05a2->regmap = devm_cci_regmap_init_i2c(client, 16);
+	if (IS_ERR(gc05a2->regmap))
+		return dev_err_probe(dev, PTR_ERR(gc05a2->regmap),
+				     "failed to init CCI\n");
+
+	gc05a2->xclk = devm_clk_get(dev, NULL);
+	if (IS_ERR(gc05a2->xclk))
+		return dev_err_probe(dev, PTR_ERR(gc05a2->xclk),
+				     "failed to get xclk\n");
+
+	ret = clk_set_rate(gc05a2->xclk, GC05A2_DEFAULT_CLK_FREQ);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to set xclk frequency\n");
+
+	ret = gc05a2_get_regulators(dev, gc05a2);
+	if (ret < 0)
+		return dev_err_probe(dev, ret,
+				     "failed to get regulators\n");
+
+	gc05a2->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(gc05a2->reset_gpio))
+		return dev_err_probe(dev, PTR_ERR(gc05a2->reset_gpio),
+				     "failed to get gpio\n");
+
+	v4l2_i2c_subdev_init(&gc05a2->sd, client, &gc05a2_subdev_ops);
+	gc05a2->sd.internal_ops = &gc05a2_internal_ops;
+	gc05a2->cur_mode = &gc05a2_modes[0];
+
+	ret = gc05a2_init_controls(gc05a2);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to init controls\n");
+
+	gc05a2->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+			    V4L2_SUBDEV_FL_HAS_EVENTS;
+	gc05a2->pad.flags = MEDIA_PAD_FL_SOURCE;
+	gc05a2->sd.dev = &client->dev;
+	gc05a2->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+
+	ret = media_entity_pads_init(&gc05a2->sd.entity, 1, &gc05a2->pad);
+	if (ret < 0) {
+		dev_err(dev, "could not register media entity\n");
+		goto err_v4l2_ctrl_handler_free;
+	}
+
+	gc05a2->sd.state_lock = gc05a2->ctrls.lock;
+	ret = v4l2_subdev_init_finalize(&gc05a2->sd);
+	if (ret < 0) {
+		dev_err(dev, "v4l2 subdev init error: %d\n", ret);
+		goto err_media_entity_cleanup;
+	}
+
+	pm_runtime_set_active(gc05a2->dev);
+	pm_runtime_enable(gc05a2->dev);
+	pm_runtime_set_autosuspend_delay(gc05a2->dev, 1000);
+	pm_runtime_use_autosuspend(gc05a2->dev);
+	pm_runtime_idle(gc05a2->dev);
+
+	ret = v4l2_async_register_subdev_sensor(&gc05a2->sd);
+	if (ret < 0) {
+		dev_err(dev, "could not register v4l2 device\n");
+		goto err_rpm;
+	}
+
+	return 0;
+
+err_rpm:
+	pm_runtime_disable(gc05a2->dev);
+	v4l2_subdev_cleanup(&gc05a2->sd);
+
+err_media_entity_cleanup:
+	media_entity_cleanup(&gc05a2->sd.entity);
+
+err_v4l2_ctrl_handler_free:
+	v4l2_ctrl_handler_free(&gc05a2->ctrls);
+
+	return ret;
+}
+
+static void gc05a2_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct gc05a2 *gc05a2 = to_gc05a2(sd);
+
+	v4l2_async_unregister_subdev(&gc05a2->sd);
+	v4l2_subdev_cleanup(sd);
+	media_entity_cleanup(&gc05a2->sd.entity);
+	v4l2_ctrl_handler_free(&gc05a2->ctrls);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		gc05a2_power_off(gc05a2->dev);
+	pm_runtime_set_suspended(&client->dev);
+}
+
+static const struct of_device_id gc05a2_of_match[] = {
+	{ .compatible = "galaxycore,gc05a2" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, gc05a2_of_match);
+
+static DEFINE_RUNTIME_DEV_PM_OPS(gc05a2_pm_ops,
+				 gc05a2_power_off,
+				 gc05a2_power_on,
+				 NULL);
+
+static struct i2c_driver gc05a2_i2c_driver = {
+	.driver = {
+		.of_match_table = gc05a2_of_match,
+		.pm = pm_ptr(&gc05a2_pm_ops),
+		.name  = "gc05a2",
+	},
+	.probe = gc05a2_probe,
+	.remove = gc05a2_remove,
+};
+module_i2c_driver(gc05a2_i2c_driver);
+
+MODULE_DESCRIPTION("GalaxyCore gc05a2 Camera driver");
+MODULE_AUTHOR("Zhi Mao <zhi.mao@mediatek.com>");
+MODULE_LICENSE("GPL");
-- 
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 related

* Re: [PATCH 1/3] media: mediatek: vcodec: fix h264 multi statless decoder smatch warning
From: Yunfei Dong (董云飞) @ 2024-04-03  3:45 UTC (permalink / raw)
  To: nhebert@chromium.org, benjamin.gaignard@collabora.com,
	nfraprado@collabora.com, angelogioacchino.delregno@collabora.com,
	nicolas.dufresne@collabora.com, hverkuil-cisco@xs4all.nl
  Cc: linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org,
	frkoenig@chromium.org, stevecho@chromium.org,
	linux-media@vger.kernel.org, devicetree@vger.kernel.org,
	daniel@ffwll.ch, Project_Global_Chrome_Upstream_Group,
	hsinyi@chromium.org, linux-arm-kernel@lists.infradead.org
In-Reply-To: <4949bd54-8c32-4490-ab19-d38796d29ac1@collabora.com>

Hi AngeloGioacchino,

Thanks for your reviewing.
On Tue, 2024-04-02 at 11:50 +0200, AngeloGioacchino Del Regno wrote:
> Il 29/02/24 10:56, Yunfei Dong ha scritto:
> > Fix smatch static checker warning for vdec_h264_req_multi_if.c.
> > Leading to kernel crash when fb is NULL.
> > 
> > Fixes: 397edc703a10 ("media: mediatek: vcodec: add h264 decoder")
> > Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> > ---
> >   .../vcodec/decoder/vdec/vdec_h264_req_multi_if.c         | 9
> > +++++++--
> >   1 file changed, 7 insertions(+), 2 deletions(-)
> > 
> > diff --git
> > a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req
> > _multi_if.c
> > b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req
> > _multi_if.c
> > index 0e741e0dc8ba..ab8e708e0df1 100644
> > ---
> > a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req
> > _multi_if.c
> > +++
> > b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req
> > _multi_if.c
> > @@ -724,11 +724,16 @@ static int vdec_h264_slice_single_decode(void
> > *h_vdec, struct mtk_vcodec_mem *bs
> >   		return vpu_dec_reset(vpu);
> >   
> >   	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
> > +	if (!fb) {
> > +		mtk_vdec_err(inst->ctx, "fb buffer is NULL");
> > +		return -EBUSY;
> > +	}
> > +
> >   	src_buf_info = container_of(bs, struct mtk_video_dec_buf,
> > bs_buffer);
> >   	dst_buf_info = container_of(fb, struct mtk_video_dec_buf,
> > frame_buffer);
> >   
> > -	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
> > -	c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
> 
> You're changing the behavior here, can you please explain why this
> change is valid
> into the commit description?
> 
The driver already add the condition to check whether fb is NULL at the
front, no need these two lines again.

> Thanks,
> Angelo
> 
Best Regards,
Yunfei Dong
> > +	y_fb_dma = (u64)fb->base_y.dma_addr;
> > +	c_fb_dma = (u64)fb->base_c.dma_addr;
> >   	mtk_vdec_debug(inst->ctx, "[h264-dec] [%d] y_dma=%llx
> > c_dma=%llx",
> >   		       inst->ctx->decoded_frame_cnt, y_fb_dma,
> > c_fb_dma);
> >   
> 
> 
> 
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v3 0/2]  media: i2c: Add support for GC05A2 sensor
From: Zhi Mao @ 2024-04-03  3:38 UTC (permalink / raw)
  To: mchehab, robh+dt, krzysztof.kozlowski+dt, sakari.ailus
  Cc: laurent.pinchart, shengnan.wang, yaya.chang,
	Project_Global_Chrome_Upstream_Group, yunkec, conor+dt,
	matthias.bgg, angelogioacchino.delregno, jacopo.mondi, zhi.mao,
	10572168, hverkuil-cisco, heiko, jernej.skrabec, macromorgan,
	linus.walleij, hdegoede, tomi.valkeinen, gerald.loacker,
	andy.shevchenko, bingbu.cao, dan.scally, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek

This series adds YAML DT binding and V4L2 sub-device driver for Galaxycore's
GC05A2 5-megapixel 10-bit RAW CMOS 1/5" sensor, with an MIPI CSI-2 image data
interface and the I2C control bus.

The driver is implemented with V4L2 framework.
 - Async registered as a V4L2 sub-device.
 - As the first component of camera system including Seninf, ISP pipeline.
 - A media entity that provides one source pad in common.
 - Used in camera features on ChromeOS application.

Also this driver supports following features:
 - manual exposure and analog gain control support
 - vertical blanking control support
 - test pattern support
 - media controller support
 - runtime PM support
 - support resolution: 2592x1944@30fps, 1280x720@60fps

Previous versions of this patch-set can be found here:
v2:https://lore.kernel.org/linux-media/20240323014751.4989-1-zhi.mao@mediatek.com/
v1:https://lore.kernel.org/linux-media/20240316025253.2300-1-zhi.mao@mediatek.com/
v0:https://lore.kernel.org/linux-media/20240313054409.8073-1-zhi.mao@mediatek.com/

This series is based on linux-next, tag: next-20240402
Changes in v3:
- gc05a2 sensor driver:
-- remove gc05a2_power_on() in function:probe(),
   and use pm_runtime_resume_and_get() to power on sensor in function:start_streaming()
-- move gc05a2_identify_module() frome function:probe() to function:start_streaming()

Thanks

Zhi Mao (2):
  media: dt-bindings: i2c: add GalaxyCore GC05A2 image sensor
  media: i2c: Add GC05A2 image sensor driver

 .../bindings/media/i2c/galaxycore,gc05a2.yaml |  112 ++
 drivers/media/i2c/Kconfig                     |   10 +
 drivers/media/i2c/Makefile                    |    1 +
 drivers/media/i2c/gc05a2.c                    | 1383 +++++++++++++++++
 4 files changed, 1506 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/galaxycore,gc05a2.yaml
 create mode 100644 drivers/media/i2c/gc05a2.c

-- 
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

* [PATCH v1 1/1] drm/mediatek/dp: The register is written with the parsed DTS SSC value.
From: Liankun Yang @ 2024-04-03  4:05 UTC (permalink / raw)
  To: chunkuang.hu, p.zabel, chunfeng.yun, vkoul, kishon, matthias.bgg,
	angelogioacchino.delregno, jitao.shi, mac.shen, liankun.yang
  Cc: dri-devel, linux-mediatek, linux-arm-kernel, linux-phy,
	linux-kernel

[Description]
Severe screen flickering has been observed on the external display
when the DP projection function is used with the market expansion dock.

[Root cause]
It has been discovered through analysis that severe screen flickering
will occur when using the current default settings of
SC (Spread Spectrum Clocking) after it is opened.

[Solution]
Reducing SSC capability on the test platform can
resolve the screen flickering issue.

By configuring SSC parameters in DTS, locating the DP SSC node
in phy-mtk-dp, parsing the current value of SSC, and writing this value
into PHY to configure SSC can solve the screen flickering problem.

[Test]
The SSC configuration values are read from DTS, parsed in the driver,
and then written to the hardware. The test results indicate that
there is no screen flickering.

Signed-off-by: Liankun Yang <liankun.yang@mediatek.com>
---
 drivers/phy/mediatek/phy-mtk-dp.c | 61 +++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/drivers/phy/mediatek/phy-mtk-dp.c b/drivers/phy/mediatek/phy-mtk-dp.c
index d7024a144335..13e5d3c33784 100644
--- a/drivers/phy/mediatek/phy-mtk-dp.c
+++ b/drivers/phy/mediatek/phy-mtk-dp.c
@@ -25,6 +25,10 @@
 #define BIT_RATE_HBR2			2
 #define BIT_RATE_HBR3			3
 
+#define MTK_DP_PHY_DIG_GLB_DA_REG_14	(PHY_OFFSET + 0xD8)
+#define XTP_GLB_TXPLL_SSC_DELTA_RBR_DEFAULT	GENMASK(15, 0)
+#define XTP_GLB_TXPLL_SSC_DELTA_HBR_DEFAULT	GENMASK(31, 16)
+
 #define MTK_DP_PHY_DIG_SW_RST		(PHY_OFFSET + 0x38)
 #define DP_GLB_SW_RST_PHYD		BIT(0)
 
@@ -78,10 +82,57 @@
 #define DRIVING_PARAM_8_DEFAULT	(XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \
 				 XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT)
 
+#define SSC_SETTING	"dp-ssc-setting"
+#define RG_XTP_GLB_TXPLL_SSC_DELTA_RBR	"ssc-delta-rbr"
+#define RG_XTP_GLB_TXPLL_SSC_DELTA_HBR	"ssc-delta-hbr"
+
 struct mtk_dp_phy {
 	struct regmap *regs;
+	struct device *dev;
 };
 
+static int mtk_dp_set_ssc_config(struct phy *phy, struct mtk_dp_phy *dp_phy,
+		struct device_node *ssc_node, const char *mode_name, u32 ssc_reg_offset)
+{
+	int ret;
+	u32 read_value = 0;
+
+	ret = of_property_read_u32(ssc_node, mode_name, &read_value);
+	if (ret) {
+		dev_err(&phy->dev, "Read fail,DPTX is not %s\n", mode_name);
+		return -EINVAL;
+	}
+
+	if (!read_value) {
+		dev_err(&phy->dev, "Read value is NULL\n");
+		return -ENOMEM;
+	}
+
+	if (!strcmp(mode_name, RG_XTP_GLB_TXPLL_SSC_DELTA_RBR)) {
+		regmap_update_bits(dp_phy->regs, ssc_reg_offset,
+			   XTP_GLB_TXPLL_SSC_DELTA_RBR_DEFAULT, read_value);
+	} else if (!strcmp(mode_name, RG_XTP_GLB_TXPLL_SSC_DELTA_HBR)) {
+		read_value = read_value << 16 | 0x0000;
+		regmap_update_bits(dp_phy->regs, ssc_reg_offset,
+			   XTP_GLB_TXPLL_SSC_DELTA_HBR_DEFAULT, read_value);
+	}
+
+	return 0;
+}
+
+static struct device_node *mtk_dp_get_ssc_node(struct phy *phy, struct mtk_dp_phy *dp_phy)
+{
+	struct device_node *mode_node = NULL;
+
+	mode_node = of_find_node_by_name(dp_phy->dev->of_node, SSC_SETTING);
+	if (!mode_node) {
+		dev_err(&phy->dev, "SSC node is NULL\n");
+		return NULL;
+	}
+
+	return mode_node;
+}
+
 static int mtk_dp_phy_init(struct phy *phy)
 {
 	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
@@ -109,6 +160,7 @@ static int mtk_dp_phy_init(struct phy *phy)
 static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
 {
 	struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
+	struct device_node *ssc_node = NULL;
 	u32 val;
 
 	if (opts->dp.set_rate) {
@@ -137,6 +189,14 @@ static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
 	regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1,
 			   TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
 
+	ssc_node = mtk_dp_get_ssc_node(phy, dp_phy);
+	if (ssc_node) {
+		mtk_dp_set_ssc_config(phy, dp_phy, ssc_node, RG_XTP_GLB_TXPLL_SSC_DELTA_RBR,
+			MTK_DP_PHY_DIG_GLB_DA_REG_14);
+		mtk_dp_set_ssc_config(phy, dp_phy, ssc_node, RG_XTP_GLB_TXPLL_SSC_DELTA_HBR,
+			MTK_DP_PHY_DIG_GLB_DA_REG_14);
+	}
+
 	return 0;
 }
 
@@ -186,6 +246,7 @@ static int mtk_dp_phy_probe(struct platform_device *pdev)
 	if (!dev->of_node)
 		phy_create_lookup(phy, "dp", dev_name(dev));
 
+	dp_phy->dev = dev;
 	return 0;
 }
 
-- 
2.43.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 v1 2/2] media: i2c: Add GC05A2 image sensor driver
From: Zhi Mao (毛智) @ 2024-04-03  4:24 UTC (permalink / raw)
  To: sakari.ailus@linux.intel.com
  Cc: heiko@sntech.de, gerald.loacker@wolfvision.net,
	robh+dt@kernel.org, yunkec@chromium.org,
	linux-kernel@vger.kernel.org, dan.scally@ideasonboard.com,
	linux-media@vger.kernel.org,
	Shengnan Wang (王圣男), hdegoede@redhat.com,
	linus.walleij@linaro.org, andy.shevchenko@gmail.com,
	Yaya Chang (張雅清), mchehab@kernel.org,
	jacopo.mondi@ideasonboard.com, jernej.skrabec@gmail.com,
	linux-mediatek@lists.infradead.org, bingbu.cao@intel.com,
	Project_Global_Chrome_Upstream_Group, conor+dt@kernel.org,
	10572168@qq.com, hverkuil-cisco@xs4all.nl,
	tomi.valkeinen@ideasonboard.com,
	krzysztof.kozlowski+dt@linaro.org,
	linux-arm-kernel@lists.infradead.org, matthias.bgg@gmail.com,
	laurent.pinchart@ideasonboard.com, devicetree@vger.kernel.org,
	angelogioacchino.delregno@collabora.com, macromorgan@hotmail.com
In-Reply-To: <8a6bbbdde57283b5bf8cab0ea7ecb0f201d437e7.camel@mediatek.com>

Hi Sakari,

Update gc05a2 driver patch.

On Sat, 2024-03-23 at 10:59 +0800, zhi.mao@mediatek.com wrote:
> Hi Sakari,
> 
> Thanks for your review.
> 
> On Wed, 2024-03-20 at 07:29 +0000, Sakari Ailus wrote:
> >  	 
> > External email : Please do not click links or open attachments
> > until
> > you have verified the sender or the content.
> >  Hi Zhi,
> > 
> > Thanks for the set.
> > 
> > On Sat, Mar 16, 2024 at 10:52:53AM +0800, Zhi Mao wrote:
> > > +static int gc05a2_set_ctrl(struct v4l2_ctrl *ctrl)
> > > +{
> > > +struct gc05a2 *gc05a2 =
> > > +container_of(ctrl->handler, struct gc05a2, ctrls);
> > > +int ret = 0;
> > > +s64 exposure_max;
> > > +struct v4l2_subdev_state *state;
> > > +const struct v4l2_mbus_framefmt *format;
> > > +
> > > +state = v4l2_subdev_get_locked_active_state(&gc05a2->sd);
> > > +format = v4l2_subdev_state_get_format(state, 0);
> > > +
> > > +if (ctrl->id == V4L2_CID_VBLANK) {
> > > +/* Update max exposure while meeting expected vblanking */
> > > +exposure_max = format->height + ctrl->val - GC05A2_EXP_MARGIN;
> > > +__v4l2_ctrl_modify_range(gc05a2->exposure,
> > > + gc05a2->exposure->minimum,
> > > + exposure_max, gc05a2->exposure->step,
> > > + exposure_max);
> > > +}
> > > +
> > > +/*
> > > + * Applying V4L2 control value only happens
> > > + * when power is on for streaming.
> > > + */
> > > +if (!pm_runtime_get_if_in_use(gc05a2->dev))
> > 
> > This should be pm_runtime_get_if_active(). Please assume it takes a
> > single
> > argument (the device)---see commit
> > c0ef3df8dbaef51ee4cfd58a471adf2eaee6f6b3.
> > 
> > The same comment applies to the GC08A3 if it uses autosuspend,
> > please
> > post
> > a new patch for that.
> > 
> 
> fixed, patch as below: 
> gc05a patch:v2 
> 
> 
https://lore.kernel.org/linux-media/20240323014751.4989-1-zhi.mao@mediatek.com/
> 

gc05a driver was updated to patch:v3

https://lore.kernel.org/linux-media/20240403033825.9072-1-zhi.mao@mediatek.com/


> gc08a patch:v8
> 
> 
https://lore.kernel.org/linux-media/20240323023851.5503-1-zhi.mao@mediatek.com/
> 
> > -- 
> > Kind regards,
> > 
> > Sakari Ailus
_______________________________________________
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 1/7] arm64: dts: imx8-ss-lsio: fix pwm lpcg indices
From: Shawn Guo @ 2024-04-03  4:44 UTC (permalink / raw)
  To: Frank Li
  Cc: Fabio Estevam, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, NXP Linux Team,
	Marcel Ziswiler, Philippe Schenker, Max Krummenacher,
	Alexander Stein, Joakim Zhang, devicetree, linux-arm-kernel,
	linux-kernel, stable
In-Reply-To: <ZgzIjziArPh8wnHA@lizhi-Precision-Tower-5810>

On Tue, Apr 02, 2024 at 11:10:07PM -0400, Frank Li wrote:
> On Wed, Apr 03, 2024 at 09:41:26AM +0800, Shawn Guo wrote:
> > On Tue, Apr 02, 2024 at 11:09:17AM -0400, Frank Li wrote:
> > > On Mon, Apr 01, 2024 at 08:04:56PM -0300, Fabio Estevam wrote:
> > > > On Mon, Apr 1, 2024 at 7:25 PM Frank Li <Frank.Li@nxp.com> wrote:
> > > > >
> > > > > lpcg's arg0 should use clock indices instead of index.
> > > > >
> > > > > pwm0_lpcg: clock-controller@5d400000 {
> > > > >         ...                                                // Col1  Col2
> > > > >         clocks = <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>,  // 0     0
> > > > >                  <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>,  // 1     1
> > > > >                  <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>,  // 2     4
> > > > >                  <&lsio_bus_clk>,                          // 3     5
> > > > >                  <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>;  // 4     6
> > > > >         clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_1>,
> > > > >                         <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_5>,
> > > > >                         <IMX_LPCG_CLK_6>;
> > > > > };
> > > > >
> > > > > Col1: index, which exited dts try to get.
> > > > 
> > > > I cannot understand this sentence, sorry.
> > > 
> > > This base on downstream dts code.  Downstream code use index in 'Col1' to
> > > get clock.
> > 
> > So s/exited/existing you meant?
> 
> Yes, sorry for typo. 

I fixed the typo and applied the series, thanks!

Shawn


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v2] ASoC: sunxi: sun4i-i2s: Support 32-bit audio formats
From: John Watts @ 2024-04-03  3:47 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland
  Cc: linux-sound, linux-arm-kernel, linux-sunxi, linux-kernel,
	John Watts

The I2S cores used in the H3 onwards support 32-bit sample rates.
Support these by adding a per-variant PCM format list.

Signed-off-by: John Watts <contact@jookia.org>
---
This patch enables support for 32-bit audio in the sunxi I2S driver.

I have only tested this on the Allwinner T113 but I'm fairly
certain it will work on older boards.
---
Changes in v2:
- Specify PCM formats for each variant instead of failing in hw_params
- Link to v1: https://lore.kernel.org/r/20240326-sunxi_s32-v1-1-899f71dcb1e6@jookia.org
---
 sound/soc/sunxi/sun4i-i2s.c | 33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index a736f632bf0b..59830f2a0d30 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -156,6 +156,7 @@ struct sun4i_i2s;
 /**
  * struct sun4i_i2s_quirks - Differences between SoC variants.
  * @has_reset: SoC needs reset deasserted.
+ * @pcm_formats: available PCM formats
  * @reg_offset_txdata: offset of the tx fifo.
  * @sun4i_i2s_regmap: regmap config to use.
  * @field_clkdiv_mclk_en: regmap field to enable mclk output.
@@ -175,6 +176,7 @@ struct sun4i_i2s;
  */
 struct sun4i_i2s_quirks {
 	bool				has_reset;
+	snd_pcm_format_t		pcm_formats;
 	unsigned int			reg_offset_txdata;	/* TX FIFO */
 	const struct regmap_config	*sun4i_i2s_regmap;
 
@@ -1092,8 +1094,18 @@ static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
 	return 0;
 }
 
+static int sun4i_i2s_dai_startup(struct snd_pcm_substream *sub, struct snd_soc_dai *dai)
+{
+	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+	struct snd_pcm_runtime *runtime = sub->runtime;
+
+	return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
+					    i2s->variant->pcm_formats);
+}
+
 static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
 	.probe		= sun4i_i2s_dai_probe,
+	.startup	= sun4i_i2s_dai_startup,
 	.hw_params	= sun4i_i2s_hw_params,
 	.set_fmt	= sun4i_i2s_set_fmt,
 	.set_sysclk	= sun4i_i2s_set_sysclk,
@@ -1101,9 +1113,10 @@ static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
 	.trigger	= sun4i_i2s_trigger,
 };
 
-#define SUN4I_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | \
-			 SNDRV_PCM_FMTBIT_S20_LE | \
-			 SNDRV_PCM_FMTBIT_S24_LE)
+#define SUN4I_FORMATS_ALL (SNDRV_PCM_FMTBIT_S16_LE | \
+			   SNDRV_PCM_FMTBIT_S20_LE | \
+			   SNDRV_PCM_FMTBIT_S24_LE | \
+			   SNDRV_PCM_FMTBIT_S32_LE)
 
 static struct snd_soc_dai_driver sun4i_i2s_dai = {
 	.capture = {
@@ -1111,14 +1124,14 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
 		.channels_min = 1,
 		.channels_max = 8,
 		.rates = SNDRV_PCM_RATE_8000_192000,
-		.formats = SUN4I_FORMATS,
+		.formats = SUN4I_FORMATS_ALL,
 	},
 	.playback = {
 		.stream_name = "Playback",
 		.channels_min = 1,
 		.channels_max = 8,
 		.rates = SNDRV_PCM_RATE_8000_192000,
-		.formats = SUN4I_FORMATS,
+		.formats = SUN4I_FORMATS_ALL,
 	},
 	.ops = &sun4i_i2s_dai_ops,
 	.symmetric_rate = 1,
@@ -1340,8 +1353,12 @@ static int sun4i_i2s_runtime_suspend(struct device *dev)
 	return 0;
 }
 
+#define SUN4I_FORMATS_A10 (SUN4I_FORMATS_ALL & ~SNDRV_PCM_FMTBIT_S32_LE)
+#define SUN4I_FORMATS_H3 SUN4I_FORMATS_ALL
+
 static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
 	.has_reset		= false,
+	.pcm_formats		= SUN4I_FORMATS_A10,
 	.reg_offset_txdata	= SUN4I_I2S_FIFO_TX_REG,
 	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
 	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
@@ -1360,6 +1377,7 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
 
 static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
 	.has_reset		= true,
+	.pcm_formats		= SUN4I_FORMATS_A10,
 	.reg_offset_txdata	= SUN4I_I2S_FIFO_TX_REG,
 	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
 	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
@@ -1383,6 +1401,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
  */
 static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
 	.has_reset		= true,
+	.pcm_formats		= SUN4I_FORMATS_A10,
 	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
 	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
 	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
@@ -1401,6 +1420,7 @@ static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
 
 static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
 	.has_reset		= true,
+	.pcm_formats		= SUN4I_FORMATS_H3,
 	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
 	.sun4i_i2s_regmap	= &sun8i_i2s_regmap_config,
 	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
@@ -1419,6 +1439,7 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
 
 static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
 	.has_reset		= true,
+	.pcm_formats		= SUN4I_FORMATS_H3,
 	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
 	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
 	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
@@ -1437,6 +1458,7 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
 
 static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
 	.has_reset		= true,
+	.pcm_formats		= SUN4I_FORMATS_H3,
 	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
 	.sun4i_i2s_regmap	= &sun50i_h6_i2s_regmap_config,
 	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
@@ -1455,6 +1477,7 @@ static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
 
 static const struct sun4i_i2s_quirks sun50i_r329_i2s_quirks = {
 	.has_reset		= true,
+	.pcm_formats		= SUN4I_FORMATS_H3,
 	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
 	.sun4i_i2s_regmap	= &sun50i_h6_i2s_regmap_config,
 	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),

---
base-commit: 13227c2baa6b345451128828c9c2b0ec3868bd0d
change-id: 20240326-sunxi_s32-f2ab25b8e688

Best regards,
-- 
John Watts <contact@jookia.org>


_______________________________________________
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/7] arm64: mm: cleanup __do_page_fault()
From: Suren Baghdasaryan @ 2024-04-03  5:11 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: akpm, Russell King, Catalin Marinas, Will Deacon,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexander Gordeev,
	Gerald Schaefer, Dave Hansen, Andy Lutomirski, Peter Zijlstra,
	x86, linux-arm-kernel, linuxppc-dev, linux-riscv, linux-s390
In-Reply-To: <20240402075142.196265-2-wangkefeng.wang@huawei.com>

On Tue, Apr 2, 2024 at 12:53 AM Kefeng Wang <wangkefeng.wang@huawei.com> wrote:
>
> The __do_page_fault() only check vma->flags and call handle_mm_fault(),
> and only called by do_page_fault(), let's squash it into do_page_fault()
> to cleanup code.
>
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>

Reviewed-by: Suren Baghdasaryan <surenb@google.com>

> ---
>  arch/arm64/mm/fault.c | 27 +++++++--------------------
>  1 file changed, 7 insertions(+), 20 deletions(-)
>
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index 8251e2fea9c7..9bb9f395351a 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -486,25 +486,6 @@ static void do_bad_area(unsigned long far, unsigned long esr,
>         }
>  }
>
> -#define VM_FAULT_BADMAP                ((__force vm_fault_t)0x010000)
> -#define VM_FAULT_BADACCESS     ((__force vm_fault_t)0x020000)
> -
> -static vm_fault_t __do_page_fault(struct mm_struct *mm,
> -                                 struct vm_area_struct *vma, unsigned long addr,
> -                                 unsigned int mm_flags, unsigned long vm_flags,
> -                                 struct pt_regs *regs)
> -{
> -       /*
> -        * Ok, we have a good vm_area for this memory access, so we can handle
> -        * it.
> -        * Check that the permissions on the VMA allow for the fault which
> -        * occurred.
> -        */
> -       if (!(vma->vm_flags & vm_flags))
> -               return VM_FAULT_BADACCESS;
> -       return handle_mm_fault(vma, addr, mm_flags, regs);
> -}
> -
>  static bool is_el0_instruction_abort(unsigned long esr)
>  {
>         return ESR_ELx_EC(esr) == ESR_ELx_EC_IABT_LOW;
> @@ -519,6 +500,9 @@ static bool is_write_abort(unsigned long esr)
>         return (esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM);
>  }
>
> +#define VM_FAULT_BADMAP                ((__force vm_fault_t)0x010000)
> +#define VM_FAULT_BADACCESS     ((__force vm_fault_t)0x020000)
> +
>  static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
>                                    struct pt_regs *regs)
>  {
> @@ -617,7 +601,10 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
>                 goto done;
>         }
>
> -       fault = __do_page_fault(mm, vma, addr, mm_flags, vm_flags, regs);
> +       if (!(vma->vm_flags & vm_flags))
> +               fault = VM_FAULT_BADACCESS;
> +       else
> +               fault = handle_mm_fault(vma, addr, mm_flags, regs);
>
>         /* Quick path to respond to signals */
>         if (fault_signal_pending(fault, regs)) {
> --
> 2.27.0
>

_______________________________________________
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 2/3] dt-bindings: phy: Add i.MX8Q HSIO SerDes PHY binding
From: Hongxing Zhu @ 2024-04-03  5:16 UTC (permalink / raw)
  To: Conor Dooley, Frank Li
  Cc: vkoul@kernel.org, kishon@kernel.org, robh+dt@kernel.org,
	krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org,
	linux-phy@lists.infradead.org, devicetree@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, kernel@pengutronix.de,
	imx@lists.linux.dev
In-Reply-To: <20240402-anemic-aerospace-bc428fff280c@spud>


> -----Original Message-----
> From: Conor Dooley <conor@kernel.org>
> Sent: 2024年4月3日 2:17
> To: Frank Li <frank.li@nxp.com>
> Cc: Hongxing Zhu <hongxing.zhu@nxp.com>; vkoul@kernel.org;
> kishon@kernel.org; robh+dt@kernel.org; krzysztof.kozlowski+dt@linaro.org;
> conor+dt@kernel.org; linux-phy@lists.infradead.org; devicetree@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org;
> kernel@pengutronix.de; imx@lists.linux.dev
> Subject: Re: [PATCH v2 2/3] dt-bindings: phy: Add i.MX8Q HSIO SerDes PHY
> binding
> 
> On Tue, Apr 02, 2024 at 10:23:45AM -0400, Frank Li wrote:
> > On Tue, Apr 02, 2024 at 01:45:03PM +0800, Richard Zhu wrote:
> > > Add i.MX8QM and i.MX8QXP HSIO SerDes PHY binding.
> > > - Use the controller ID to specify which controller is binded to the
> > > PHY.
> > > - Introduce one HSIO configuration, mandatory required to set
> > > "PCIE_AB_SELECT" and "PHY_X1_EPCS_SEL" during the initialization.
> > >
> > > Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> >
> > You missed all conor's comments.
> > Please double check v1's comments.
> 
Hi Frank:
Thanks a lot for your reminder.
It's my fault that I missed this email.

> > > +  fsl,refclk-pad-mode:
> > > +    description: |
> > > +      Specifies the mode of the refclk pad used. It can be UNUSED(PHY
> > > +      refclock is derived from SoC internal source), INPUT(PHY refclock
> > > +      is provided externally via the refclk pad) or OUTPUT(PHY refclock
> > > +      is derived from SoC internal source and provided on the refclk pad).
> > > +      Refer include/dt-bindings/phy/phy-imx8-pcie.h for the constants
> > > +      to be used.
> > > +    $ref: /schemas/types.yaml#/definitions/uint32
> > > +    enum: [ 0, 1, 2 ]
> >
> > I remember needn't enum because there are header file.
> 
> Yah, specifically my comments about this property were missed and were
> probably the most meaningful comments I left.
Hi Conor:
I'm so sorry about it.
I made the mistake missing your last review email.
Would follow your comments in next review cycle.

Best Regards
Richard Zhu
> 
> Thanks for the reminder Frank.
_______________________________________________
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/7] arm64: mm: accelerate pagefault when VM_FAULT_BADACCESS
From: Suren Baghdasaryan @ 2024-04-03  5:19 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: akpm, Russell King, Catalin Marinas, Will Deacon,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexander Gordeev,
	Gerald Schaefer, Dave Hansen, Andy Lutomirski, Peter Zijlstra,
	x86, linux-arm-kernel, linuxppc-dev, linux-riscv, linux-s390
In-Reply-To: <20240402075142.196265-3-wangkefeng.wang@huawei.com>

On Tue, Apr 2, 2024 at 12:53 AM Kefeng Wang <wangkefeng.wang@huawei.com> wrote:
>
> The vm_flags of vma already checked under per-VMA lock, if it is a
> bad access, directly set fault to VM_FAULT_BADACCESS and handle error,
> no need to lock_mm_and_find_vma() and check vm_flags again, the latency
> time reduce 34% in lmbench 'lat_sig -P 1 prot lat_sig'.

The change makes sense to me. Per-VMA lock is enough to keep
vma->vm_flags stable, so no need to retry with mmap_lock.

>
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>

Reviewed-by: Suren Baghdasaryan <surenb@google.com>

> ---
>  arch/arm64/mm/fault.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index 9bb9f395351a..405f9aa831bd 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -572,7 +572,9 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
>
>         if (!(vma->vm_flags & vm_flags)) {
>                 vma_end_read(vma);
> -               goto lock_mmap;
> +               fault = VM_FAULT_BADACCESS;
> +               count_vm_vma_lock_event(VMA_LOCK_SUCCESS);

nit: VMA_LOCK_SUCCESS accounting here seems correct to me but
unrelated to the main change. Either splitting into a separate patch
or mentioning this additional fixup in the changelog would be helpful.

> +               goto done;
>         }
>         fault = handle_mm_fault(vma, addr, mm_flags | FAULT_FLAG_VMA_LOCK, regs);
>         if (!(fault & (VM_FAULT_RETRY | VM_FAULT_COMPLETED)))
> --
> 2.27.0
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* RE:  [RESEND PATCH v3] perf/marvell: Marvell PEM performance monitor support
From: Gowthami Thiagarajan @ 2024-04-03  5:22 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: will@kernel.org, mark.rutland@arm.com,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, Sunil Kovvuri Goutham,
	George Cherian, Linu Cherian
In-Reply-To: <695199ba-c71d-43ec-8305-8f52488b8c5d@lunn.ch>

Hi Andrew,

Please find the responses inline.

Thanks,
Gowthami

> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Wednesday, March 27, 2024 6:41 PM
> To: Gowthami Thiagarajan <gthiagarajan@marvell.com>
> Cc: will@kernel.org; mark.rutland@arm.com; linux-arm-kernel@lists.infradead.org; linux-
> kernel@vger.kernel.org; Sunil Kovvuri Goutham <sgoutham@marvell.com>; George Cherian
> <gcherian@marvell.com>; Linu Cherian <lcherian@marvell.com>
> Subject: [EXTERNAL] Re: [RESEND PATCH v3] perf/marvell: Marvell PEM performance monitor support
> 
> On Wed, Mar 27, 2024 at 12:51:17PM +0530, Gowthami Thiagarajan wrote:
> > PCI Express Interface PMU includes various performance counters
> > to monitor the data that is transmitted over the PCIe link. The
> > counters track various inbound and outbound transactions which
> > includes separate counters for posted/non-posted/completion TLPs.
> > Also, inbound and outbound memory read requests along with their
> > latencies can also be monitored. Address Translation Services(ATS)events
> > such as ATS Translation, ATS Page Request, ATS Invalidation along with
> > their corresponding latencies are also supported.
> >
> > The performance counters are 64 bits wide.
> >
> > For instance,
> > perf stat -e ib_tlp_pr <workload>
> > tracks the inbound posted TLPs for the workload.
> >
> > Signed-off-by: Gowthami Thiagarajan <gthiagarajan@marvell.com>
> > ---
> > v2->v3 changes:
> > - Dropped device tree support as the acpi table based probing is used.
> 
> So people using DT cannot use this driver? Can they use the PCIe
> interface?
> 
> There does not appear to be any ACPI binding, it is not reading any
> properties from ACPI tables etc. So the DT binding should be
> trivial...

The ACPI bindings are present in the driver. Have the ACPI ID MRVL000E tied here
and the resources are fetched from the ACPI table.

static const struct acpi_device_id pem_pmu_acpi_match[] = {
	{"MRVL000E", 0},
	{},
};
MODULE_DEVICE_TABLE(acpi, pem_pmu_acpi_match);

base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);

> 
> > index 000000000000..d4175483b982
> > --- /dev/null
> > +++ b/drivers/perf/marvell_pem_pmu.c
> > @@ -0,0 +1,428 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Marvell PEM(PCIe RC) Performance Monitor Driver
> > + *
> > + * Copyright (C) 2024 Marvell.
> > + */
> > +
> > +#include <linux/acpi.h>
> > +#include <linux/init.h>
> > +#include <linux/io.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_device.h>
> 
> Why do you need these header files? I don't see any calls to of_
> functions.
> 
 These header files are not needed. I will remove them in the next version.

> > +static int pem_perf_probe(struct platform_device *pdev)
> > +{
> > +	struct pem_pmu *pem_pmu;
> > +	struct resource *res;
> > +	void __iomem *base;
> > +	char *name;
> > +	int ret;
> > +
> > +	pem_pmu = devm_kzalloc(&pdev->dev, sizeof(*pem_pmu), GFP_KERNEL);
> > +	if (!pem_pmu)
> > +		return -ENOMEM;
> > +
> > +	pem_pmu->dev = &pdev->dev;
> > +	platform_set_drvdata(pdev, pem_pmu);
> > +
> > +	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
> > +	if (IS_ERR(base))
> > +		return PTR_ERR(base);
> > +
> > +	pem_pmu->base = base;
> > +
> > +	pem_pmu->pmu = (struct pmu) {
> > +		.module	      = THIS_MODULE,
> > +		.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
> > +		.task_ctx_nr = perf_invalid_context,
> > +		.attr_groups = pem_perf_attr_groups,
> > +		.event_init  = pem_perf_event_init,
> > +		.add	     = pem_perf_event_add,
> > +		.del	     = pem_perf_event_del,
> > +		.start	     = pem_perf_event_start,
> > +		.stop	     = pem_perf_event_stop,
> > +		.read	     = pem_perf_event_update,
> > +	};
> > +
> > +	/* Choose this cpu to collect perf data */
> > +	pem_pmu->cpu = raw_smp_processor_id();
> > +
> > +	name = devm_kasprintf(pem_pmu->dev, GFP_KERNEL, "mrvl_pcie_rc_pmu_%llx",
> > +			      res->start);
> > +	if (!name)
> > +		return -ENOMEM;
> > +
> > +	cpuhp_state_add_instance_nocalls
> > +			(CPUHP_AP_PERF_ARM_MARVELL_PEM_ONLINE,
> > +			 &pem_pmu->node);
> > +
> > +	ret = perf_pmu_register(&pem_pmu->pmu, name, -1);
> > +	if (ret)
> > +		goto error;
> > +
> > +	pr_info("Marvell PEM(PCIe RC) PMU Driver for pem@%llx\n", res->start);
> 
> Please don't spam the kernel log like this.

Will get this message removed.
> 
>        Andrew

_______________________________________________
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/7] arm64: mm: accelerate pagefault when VM_FAULT_BADACCESS
From: Suren Baghdasaryan @ 2024-04-03  5:30 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: akpm, Russell King, Catalin Marinas, Will Deacon,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexander Gordeev,
	Gerald Schaefer, Dave Hansen, Andy Lutomirski, Peter Zijlstra,
	x86, linux-arm-kernel, linuxppc-dev, linux-riscv, linux-s390
In-Reply-To: <CAJuCfpGpKup6AOPY08p35S2S+D4ch5XjEB=FM-n9-kU8dZXS5Q@mail.gmail.com>

On Tue, Apr 2, 2024 at 10:19 PM Suren Baghdasaryan <surenb@google.com> wrote:
>
> On Tue, Apr 2, 2024 at 12:53 AM Kefeng Wang <wangkefeng.wang@huawei.com> wrote:
> >
> > The vm_flags of vma already checked under per-VMA lock, if it is a
> > bad access, directly set fault to VM_FAULT_BADACCESS and handle error,
> > no need to lock_mm_and_find_vma() and check vm_flags again, the latency
> > time reduce 34% in lmbench 'lat_sig -P 1 prot lat_sig'.
>
> The change makes sense to me. Per-VMA lock is enough to keep
> vma->vm_flags stable, so no need to retry with mmap_lock.
>
> >
> > Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
>
> Reviewed-by: Suren Baghdasaryan <surenb@google.com>
>
> > ---
> >  arch/arm64/mm/fault.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> > index 9bb9f395351a..405f9aa831bd 100644
> > --- a/arch/arm64/mm/fault.c
> > +++ b/arch/arm64/mm/fault.c
> > @@ -572,7 +572,9 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
> >
> >         if (!(vma->vm_flags & vm_flags)) {
> >                 vma_end_read(vma);
> > -               goto lock_mmap;
> > +               fault = VM_FAULT_BADACCESS;
> > +               count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
>
> nit: VMA_LOCK_SUCCESS accounting here seems correct to me but
> unrelated to the main change. Either splitting into a separate patch
> or mentioning this additional fixup in the changelog would be helpful.

The above nit applies to all the patches after this one, so I won't
comment on each one separately. If you decide to split or adjust the
changelog please do that for each patch.

>
> > +               goto done;
> >         }
> >         fault = handle_mm_fault(vma, addr, mm_flags | FAULT_FLAG_VMA_LOCK, regs);
> >         if (!(fault & (VM_FAULT_RETRY | VM_FAULT_COMPLETED)))
> > --
> > 2.27.0
> >

_______________________________________________
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 3/7] arm: mm: accelerate pagefault when VM_FAULT_BADACCESS
From: Suren Baghdasaryan @ 2024-04-03  5:30 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: akpm, Russell King, Catalin Marinas, Will Deacon,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexander Gordeev,
	Gerald Schaefer, Dave Hansen, Andy Lutomirski, Peter Zijlstra,
	x86, linux-arm-kernel, linuxppc-dev, linux-riscv, linux-s390
In-Reply-To: <20240402075142.196265-4-wangkefeng.wang@huawei.com>

On Tue, Apr 2, 2024 at 12:53 AM Kefeng Wang <wangkefeng.wang@huawei.com> wrote:
>
> The vm_flags of vma already checked under per-VMA lock, if it is a
> bad access, directly set fault to VM_FAULT_BADACCESS and handle error,
> so no need to lock_mm_and_find_vma() and check vm_flags again.
>
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>

Reviewed-by: Suren Baghdasaryan <surenb@google.com>



> ---
>  arch/arm/mm/fault.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
> index 439dc6a26bb9..5c4b417e24f9 100644
> --- a/arch/arm/mm/fault.c
> +++ b/arch/arm/mm/fault.c
> @@ -294,7 +294,9 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
>
>         if (!(vma->vm_flags & vm_flags)) {
>                 vma_end_read(vma);
> -               goto lock_mmap;
> +               count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
> +               fault = VM_FAULT_BADACCESS;
> +               goto bad_area;
>         }
>         fault = handle_mm_fault(vma, addr, flags | FAULT_FLAG_VMA_LOCK, regs);
>         if (!(fault & (VM_FAULT_RETRY | VM_FAULT_COMPLETED)))
> --
> 2.27.0
>

_______________________________________________
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 4/7] powerpc: mm: accelerate pagefault when badaccess
From: Suren Baghdasaryan @ 2024-04-03  5:34 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: akpm, Russell King, Catalin Marinas, Will Deacon,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexander Gordeev,
	Gerald Schaefer, Dave Hansen, Andy Lutomirski, Peter Zijlstra,
	x86, linux-arm-kernel, linuxppc-dev, linux-riscv, linux-s390
In-Reply-To: <20240402075142.196265-5-wangkefeng.wang@huawei.com>

On Tue, Apr 2, 2024 at 12:53 AM Kefeng Wang <wangkefeng.wang@huawei.com> wrote:
>
> The vm_flags of vma already checked under per-VMA lock, if it is a
> bad access, directly handle error and return, there is no need to
> lock_mm_and_find_vma() and check vm_flags again.
>
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>

Code-wise looks correct to me and almost identical to x86 change but
someone with more experience with this architecture should review.

> ---
>  arch/powerpc/mm/fault.c | 33 ++++++++++++++++++++-------------
>  1 file changed, 20 insertions(+), 13 deletions(-)
>
> diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
> index 53335ae21a40..215690452495 100644
> --- a/arch/powerpc/mm/fault.c
> +++ b/arch/powerpc/mm/fault.c
> @@ -71,23 +71,26 @@ static noinline int bad_area_nosemaphore(struct pt_regs *regs, unsigned long add
>         return __bad_area_nosemaphore(regs, address, SEGV_MAPERR);
>  }
>
> -static int __bad_area(struct pt_regs *regs, unsigned long address, int si_code)
> +static int __bad_area(struct pt_regs *regs, unsigned long address, int si_code,
> +                     struct mm_struct *mm, struct vm_area_struct *vma)
>  {
> -       struct mm_struct *mm = current->mm;
>
>         /*
>          * Something tried to access memory that isn't in our memory map..
>          * Fix it, but check if it's kernel or user first..
>          */
> -       mmap_read_unlock(mm);
> +       if (mm)
> +               mmap_read_unlock(mm);
> +       else
> +               vma_end_read(vma);
>
>         return __bad_area_nosemaphore(regs, address, si_code);
>  }
>
>  static noinline int bad_access_pkey(struct pt_regs *regs, unsigned long address,
> +                                   struct mm_struct *mm,
>                                     struct vm_area_struct *vma)
>  {
> -       struct mm_struct *mm = current->mm;
>         int pkey;
>
>         /*
> @@ -109,7 +112,10 @@ static noinline int bad_access_pkey(struct pt_regs *regs, unsigned long address,
>          */
>         pkey = vma_pkey(vma);
>
> -       mmap_read_unlock(mm);
> +       if (mm)
> +               mmap_read_unlock(mm);
> +       else
> +               vma_end_read(vma);
>
>         /*
>          * If we are in kernel mode, bail out with a SEGV, this will
> @@ -124,9 +130,10 @@ static noinline int bad_access_pkey(struct pt_regs *regs, unsigned long address,
>         return 0;
>  }
>
> -static noinline int bad_access(struct pt_regs *regs, unsigned long address)
> +static noinline int bad_access(struct pt_regs *regs, unsigned long address,
> +                              struct mm_struct *mm, struct vm_area_struct *vma)
>  {
> -       return __bad_area(regs, address, SEGV_ACCERR);
> +       return __bad_area(regs, address, SEGV_ACCERR, mm, vma);
>  }
>
>  static int do_sigbus(struct pt_regs *regs, unsigned long address,
> @@ -479,13 +486,13 @@ static int ___do_page_fault(struct pt_regs *regs, unsigned long address,
>
>         if (unlikely(access_pkey_error(is_write, is_exec,
>                                        (error_code & DSISR_KEYFAULT), vma))) {
> -               vma_end_read(vma);
> -               goto lock_mmap;
> +               count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
> +               return bad_access_pkey(regs, address, NULL, vma);
>         }
>
>         if (unlikely(access_error(is_write, is_exec, vma))) {
> -               vma_end_read(vma);
> -               goto lock_mmap;
> +               count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
> +               return bad_access(regs, address, NULL, vma);
>         }
>
>         fault = handle_mm_fault(vma, address, flags | FAULT_FLAG_VMA_LOCK, regs);
> @@ -521,10 +528,10 @@ static int ___do_page_fault(struct pt_regs *regs, unsigned long address,
>
>         if (unlikely(access_pkey_error(is_write, is_exec,
>                                        (error_code & DSISR_KEYFAULT), vma)))
> -               return bad_access_pkey(regs, address, vma);
> +               return bad_access_pkey(regs, address, mm, vma);
>
>         if (unlikely(access_error(is_write, is_exec, vma)))
> -               return bad_access(regs, address);
> +               return bad_access(regs, address, mm, vma);
>
>         /*
>          * If for any reason at all we couldn't handle the fault,
> --
> 2.27.0
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox