* Re: [PATCH] iommu/arm-smmu: Report USF more clearly
From: Russell King - ARM Linux admin @ 2019-09-13 22:59 UTC (permalink / raw)
To: Robin Murphy; +Cc: joro, will, iommu, linux-arm-kernel, Douglas Anderson
In-Reply-To: <2762ffd4c196dc91d62e10eb8b753f256ea9b629.1568375317.git.robin.murphy@arm.com>
On Fri, Sep 13, 2019 at 12:48:37PM +0100, Robin Murphy wrote:
> Although CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT is a welcome tool
> for smoking out inadequate firmware, the failure mode is non-obvious
> and can be confusing for end users. Add some special-case reporting of
> Unidentified Stream Faults to help clarify this particular symptom.
Having encountered this on a board that turned up this week, it may
be better to use the hex representation of the stream ID, especially
as it seems normal for the stream ID to be made up of implementation
defined bitfields.
If we want to stick with decimal, maybe masking the stream ID with
the number of allowable bits would be a good idea, so that the
decimal value remains meaningful should other bits be non-zero?
> CC: Douglas Anderson <dianders@chromium.org>
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
> drivers/iommu/arm-smmu.c | 5 +++++
> drivers/iommu/arm-smmu.h | 2 ++
> 2 files changed, 7 insertions(+)
>
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index b7cf24402a94..76ac8c180695 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -499,6 +499,11 @@ static irqreturn_t arm_smmu_global_fault(int irq, void *dev)
> dev_err_ratelimited(smmu->dev,
> "\tGFSR 0x%08x, GFSYNR0 0x%08x, GFSYNR1 0x%08x, GFSYNR2 0x%08x\n",
> gfsr, gfsynr0, gfsynr1, gfsynr2);
> + if (IS_ENABLED(CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT) &&
> + (gfsr & sGFSR_USF))
> + dev_err_ratelimited(smmu->dev,
> + "Stream ID %hu may not be described by firmware, try booting with \"arm-smmu.disable_bypass=0\"\n",
> + (u16)gfsynr1);
>
> arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sGFSR, gfsr);
> return IRQ_HANDLED;
> diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
> index c9c13b5785f2..46f7e161e83e 100644
> --- a/drivers/iommu/arm-smmu.h
> +++ b/drivers/iommu/arm-smmu.h
> @@ -79,6 +79,8 @@
> #define ID7_MINOR GENMASK(3, 0)
>
> #define ARM_SMMU_GR0_sGFSR 0x48
> +#define sGFSR_USF BIT(2)
I do wonder if this is another instance where writing "(1 << 1)"
would have resulted in less chance of a mistake being made...
wrapping stuff up into macros is not always better!
9.6.15 SMMU_sGFSR, Global Fault Status Register
The SMMU_sGFSR bit assignments are:
USF, bit[1] Unidentified stream fault. The possible values of this
bit are:
0 No Unidentified stream fault.
1 Unidentified stream fault.
So this wants to be:
#define sGFSR_USF BIT(1)
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
_______________________________________________
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 05/13] clk: bcm2835: Add BCM2711_CLOCK_EMMC2 support
From: Florian Fainelli @ 2019-09-13 23:02 UTC (permalink / raw)
To: Matthias Brugger, Stefan Wahren, Eric Anholt, Ray Jui,
Scott Branden, Wolfram Sang, Rob Herring, Mark Rutland,
Michael Turquette, Stephen Boyd
Cc: devicetree, bcm-kernel-feedback-list, linux-i2c, linux-clk,
linux-arm-kernel, linux-rpi-kernel
In-Reply-To: <218baa70-9849-63db-4989-c6d658b11c6d@gmail.com>
On 9/13/19 12:13 AM, Matthias Brugger wrote:
>
>
> On 13/09/2019 03:20, Stefan Wahren wrote:
>> Am 12.09.19 um 20:52 schrieb Eric Anholt:
>>> Matthias Brugger <matthias.bgg@gmail.com> writes:
>>>
>>>> On 13/08/2019 18:20, Stefan Wahren wrote:
>>>>> The new BCM2711 supports an additional clock for the emmc2 block.
>>>>> So add a new compatible and register this clock only for BCM2711.
>>>>>
>>>>> Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
>>>>> Reviewed-by: Matthias Brugger <mbrugger@suse.com>
>>>>> Acked-by: Eric Anholt <eric@anholt.net>
>>>>> ---
>>>>> drivers/clk/bcm/clk-bcm2835.c | 20 +++++++++++++++++++-
>>>>> 1 file changed, 19 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
>>>>> index 21cd952..fdf672a 100644
>>>>> --- a/drivers/clk/bcm/clk-bcm2835.c
>>>>> +++ b/drivers/clk/bcm/clk-bcm2835.c
>>>>> @@ -114,6 +114,8 @@
>>>>> #define CM_AVEODIV 0x1bc
>>>>> #define CM_EMMCCTL 0x1c0
>>>>> #define CM_EMMCDIV 0x1c4
>>>>> +#define CM_EMMC2CTL 0x1d0
>>>>> +#define CM_EMMC2DIV 0x1d4
>>>>>
>>>>> /* General bits for the CM_*CTL regs */
>>>>> # define CM_ENABLE BIT(4)
>>>>> @@ -290,7 +292,8 @@
>>>>> #define BCM2835_MAX_FB_RATE 1750000000u
>>>>>
>>>>> #define SOC_BCM2835 BIT(0)
>>>>> -#define SOC_ALL (SOC_BCM2835)
>>>>> +#define SOC_BCM2711 BIT(1)
>>>>> +#define SOC_ALL (SOC_BCM2835 | SOC_BCM2711)
>>>>>
>>>>> /*
>>>>> * Names of clocks used within the driver that need to be replaced
>>>>> @@ -2003,6 +2006,16 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
>>>>> .frac_bits = 8,
>>>>> .tcnt_mux = 39),
>>>>>
>>>>> + /* EMMC2 clock (only available for BCM2711) */
>>>>> + [BCM2711_CLOCK_EMMC2] = REGISTER_PER_CLK(
>>>>> + SOC_BCM2711,
>>>>> + .name = "emmc2",
>>>>> + .ctl_reg = CM_EMMC2CTL,
>>>>> + .div_reg = CM_EMMC2DIV,
>>>>> + .int_bits = 4,
>>>>> + .frac_bits = 8,
>>>>> + .tcnt_mux = 42),
>>>>> +
>>>>> /* General purpose (GPIO) clocks */
>>>>> [BCM2835_CLOCK_GP0] = REGISTER_PER_CLK(
>>>>> SOC_ALL,
>>>>> @@ -2238,8 +2251,13 @@ static const struct cprman_plat_data cprman_bcm2835_plat_data = {
>>>>> .soc = SOC_BCM2835,
>>>>> };
>>>>>
>>>>> +static const struct cprman_plat_data cprman_bcm2711_plat_data = {
>>>>> + .soc = SOC_BCM2711,
>>>>> +};
>>>>> +
>>>>> static const struct of_device_id bcm2835_clk_of_match[] = {
>>>>> { .compatible = "brcm,bcm2835-cprman", .data = &cprman_bcm2835_plat_data },
>>>>> + { .compatible = "brcm,bcm2711-cprman", .data = &cprman_bcm2711_plat_data },
>>>> Because the RPi4 FW uses bcm2838-cprman as compatible, we will need to add this
>>>> here as well.
>>> Upstream has not committed to backwards compat with Pi's firmware. That
>>> makes the ABI requirement we get held to for upstream's DT absurd, but
>>> that's the state of things.
>>
>> We also learned from past, that's not possible to keep things downstream
>> compatible. As soon as a binding is not accepted, this wont work
>> anymore. A lot of the downstream stuff is hacky.
>>
>> For example yesterday, i learned that the thermal node is broken
>> (register is part of ring oscillator block). So do we really want to be
>> compatible with a hack? I would say: No
>>
>
> There is always the possibility to fix this in the FW, which in many cases will
> be trivial.
In many cases, the firmware can certainly be changed to support both
downstream and upstream properties, as long as the layout is not
fundamentally incompatible obviously. If this is just a game of
compatible strings, both can be provided and it should not cause any
issues as long as you are not mixing downstream and upstream drivers for
the same purpose.
--
Florian
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [arm:cex7 11/20] drivers/net/ethernet/freescale/dpaa2/dpmac.c:67:30: sparse: sparse: incorrect type in assignment (different base types)
From: kbuild test robot @ 2019-09-13 23:14 UTC (permalink / raw)
To: Russell King; +Cc: kbuild-all, linux-arm-kernel
tree: git://git.armlinux.org.uk/~rmk/linux-arm.git cex7
head: 5b0bee16ea663db4aefd0cc1d0dc5e41acabb5e8
commit: 3b1e790b01fd2e3f28840734f5ced7e2083f1209 [11/20] dpaa2-mac: add PHY layer
reproduce:
# apt-get install sparse
# sparse version: v0.6.1-rc1-7-g2b96cd8-dirty
git checkout 3b1e790b01fd2e3f28840734f5ced7e2083f1209
make ARCH=x86_64 allmodconfig
make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:67:30: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int [usertype] dpmac_id @@ got restrunsigned int [usertype] dpmac_id @@
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:67:30: sparse: expected unsigned int [usertype] dpmac_id
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:67:30: sparse: got restricted __le32 [usertype]
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:139:28: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int [usertype] mac_id @@ got restrunsigned int [usertype] mac_id @@
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:139:28: sparse: expected unsigned int [usertype] mac_id
drivers/net/ethernet/freescale/dpaa2/dpmac.c:139:28: sparse: got restricted __le32 [usertype]
drivers/net/ethernet/freescale/dpaa2/dpmac.c:180:30: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int [usertype] dpmac_id @@ got restrunsigned int [usertype] dpmac_id @@
drivers/net/ethernet/freescale/dpaa2/dpmac.c:180:30: sparse: expected unsigned int [usertype] dpmac_id
drivers/net/ethernet/freescale/dpaa2/dpmac.c:180:30: sparse: got restricted __le32 [usertype]
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:292:26: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int [usertype] mask @@ got restrunsigned int [usertype] mask @@
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:292:26: sparse: expected unsigned int [usertype] mask
drivers/net/ethernet/freescale/dpaa2/dpmac.c:292:26: sparse: got restricted __le32 [usertype]
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:337:17: sparse: sparse: cast to restricted __le32
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:371:28: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int [usertype] status @@ got restrunsigned int [usertype] status @@
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:371:28: sparse: expected unsigned int [usertype] status
drivers/net/ethernet/freescale/dpaa2/dpmac.c:371:28: sparse: got restricted __le32 [usertype]
drivers/net/ethernet/freescale/dpaa2/dpmac.c:381:19: sparse: sparse: cast to restricted __le32
drivers/net/ethernet/freescale/dpaa2/dpmac.c:413:28: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int [usertype] status @@ got restrunsigned int [usertype] status @@
drivers/net/ethernet/freescale/dpaa2/dpmac.c:413:28: sparse: expected unsigned int [usertype] status
drivers/net/ethernet/freescale/dpaa2/dpmac.c:413:28: sparse: got restricted __le32 [usertype]
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:453:20: sparse: sparse: cast to restricted __le16
drivers/net/ethernet/freescale/dpaa2/dpmac.c:454:26: sparse: sparse: cast to restricted __le32
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:488:24: sparse: sparse: cast to restricted __le64
drivers/net/ethernet/freescale/dpaa2/dpmac.c:489:21: sparse: sparse: cast to restricted __le32
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:516:29: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned long long [usertype] options @@ got nsigned long long [usertype] options @@
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:516:29: sparse: expected unsigned long long [usertype] options
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:516:29: sparse: got restricted __le64 [usertype]
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:517:26: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int [usertype] rate @@ got restrunsigned int [usertype] rate @@
>> drivers/net/ethernet/freescale/dpaa2/dpmac.c:517:26: sparse: expected unsigned int [usertype] rate
drivers/net/ethernet/freescale/dpaa2/dpmac.c:517:26: sparse: got restricted __le32 [usertype]
drivers/net/ethernet/freescale/dpaa2/dpmac.c:558:20: sparse: sparse: cast to restricted __le64
drivers/net/ethernet/freescale/dpaa2/dpmac.c:615:22: sparse: sparse: cast to restricted __le16
drivers/net/ethernet/freescale/dpaa2/dpmac.c:616:22: sparse: sparse: cast to restricted __le16
vim +67 drivers/net/ethernet/freescale/dpaa2/dpmac.c
35
36 /**
37 * dpmac_open() - Open a control session for the specified object.
38 * @mc_io: Pointer to MC portal's I/O object
39 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
40 * @dpmac_id: DPMAC unique ID
41 * @token: Returned token; use in subsequent API calls
42 *
43 * This function can be used to open a control session for an
44 * already created object; an object may have been declared in
45 * the DPL or by calling the dpmac_create function.
46 * This function returns a unique authentication token,
47 * associated with the specific object ID and the specific MC
48 * portal; this token must be used in all subsequent commands for
49 * this specific object
50 *
51 * Return: '0' on Success; Error code otherwise.
52 */
53 int dpmac_open(struct fsl_mc_io *mc_io,
54 u32 cmd_flags,
55 int dpmac_id,
56 u16 *token)
57 {
58 struct dpmac_cmd_open *cmd_params;
59 struct fsl_mc_command cmd = { 0 };
60 int err;
61
62 /* prepare command */
63 cmd.header = mc_encode_cmd_header(DPMAC_CMDID_OPEN,
64 cmd_flags,
65 0);
66 cmd_params = (struct dpmac_cmd_open *)cmd.params;
> 67 cmd_params->dpmac_id = cpu_to_le32(dpmac_id);
68
69 /* send command to mc*/
70 err = mc_send_command(mc_io, &cmd);
71 if (err)
72 return err;
73
74 /* retrieve response parameters */
75 *token = mc_cmd_hdr_read_token(&cmd);
76
77 return err;
78 }
79
80 /**
81 * dpmac_close() - Close the control session of the object
82 * @mc_io: Pointer to MC portal's I/O object
83 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
84 * @token: Token of DPMAC object
85 *
86 * After this function is called, no further operations are
87 * allowed on the object without opening a new control session.
88 *
89 * Return: '0' on Success; Error code otherwise.
90 */
91 int dpmac_close(struct fsl_mc_io *mc_io,
92 u32 cmd_flags,
93 u16 token)
94 {
95 struct fsl_mc_command cmd = { 0 };
96
97 /* prepare command */
98 cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CLOSE, cmd_flags,
99 token);
100
101 /* send command to mc*/
102 return mc_send_command(mc_io, &cmd);
103 }
104
105 /**
106 * dpmac_create() - Create the DPMAC object.
107 * @mc_io: Pointer to MC portal's I/O object
108 * @dprc_token: Parent container token; '0' for default container
109 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
110 * @cfg: Configuration structure
111 * @obj_id: Returned object id
112 *
113 * Create the DPMAC object, allocate required resources and
114 * perform required initialization.
115 *
116 * The function accepts an authentication token of a parent
117 * container that this object should be assigned to. The token
118 * can be '0' so the object will be assigned to the default container.
119 * The newly created object can be opened with the returned
120 * object id and using the container's associated tokens and MC portals.
121 *
122 * Return: '0' on Success; Error code otherwise.
123 */
124 int dpmac_create(struct fsl_mc_io *mc_io,
125 u16 dprc_token,
126 u32 cmd_flags,
127 const struct dpmac_cfg *cfg,
128 u32 *obj_id)
129 {
130 struct dpmac_cmd_create *cmd_params;
131 struct fsl_mc_command cmd = { 0 };
132 int err;
133
134 /* prepare command */
135 cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CREATE,
136 cmd_flags,
137 dprc_token);
138 cmd_params = (struct dpmac_cmd_create *)cmd.params;
> 139 cmd_params->mac_id = cpu_to_le32(cfg->mac_id);
140
141 /* send command to mc*/
142 err = mc_send_command(mc_io, &cmd);
143 if (err)
144 return err;
145
146 /* retrieve response parameters */
147 *obj_id = mc_cmd_read_object_id(&cmd);
148
149 return 0;
150 }
151
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
_______________________________________________
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 v5 00/13] Common patches from downstream development
From: Shawn Guo @ 2019-09-14 2:30 UTC (permalink / raw)
To: Philippe Schenker
Cc: Mark Rutland, devicetree @ vger . kernel . org,
Michal Vokáč, Pengutronix Kernel Team, Marcel Ziswiler,
Sascha Hauer, linux-kernel@vger.kernel.org, stefan @ agner . ch,
Rob Herring, NXP Linux Team, Max Krummenacher, Fabio Estevam,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20190827131806.6816-1-philippe.schenker@toradex.com>
On Tue, Aug 27, 2019 at 01:18:16PM +0000, Philippe Schenker wrote:
>
> This patchset holds some common changes that were never upstreamed.
> With latest downstream kernel upgrade, I took the aproach to select
> mainline devicetrees and atomically add missing stuff for downstream.
>
> These patches I send here are separated out with changes that also
> have a benefit for mainline.
>
> --------------------- Update version 4 and later -----------------------
> Patches that got pulled in an earlier patchset version got dropped in
> this patchset.
> ------------------------------------------------------------------------
>
> Philippe
>
> Changes in v5:
> - changed legacy gpio-key,wakeup to wakeup-source
> - Add note in commit message about disabled status
> - Added Olek's reviewed-by
> - change group name
> - Add pinmux to iomuxc
> - Adjusted commit message
> - Switched to consistent naming: pinctrl_xxx: xxxgrp
> - Added Olek's Reviewed-by
> - Added Olek's Reviewed-by
> - Added Olek's Reviewed-by
> - Added Olek's Reviewd-by
> - Added Olek's Reviewed-by
> - Add Olek's Reviewed-by
> - Added note to commit message about disabled status
> - Add Olek's Reviewed-by
>
> Changes in v4:
> - Add Marcel Ziswiler's Ack
> - Add Marcel Ziswiler's Ack
> - Add Marcel Ziswiler's Ack
> - Add Marcel Ziswiler's Ack
> - Add Marcel Ziswiler's Ack
> - Add Marcel Ziswiler's Ack
> - Add Marcel Ziswiler's Ack
> - Add Marcel Ziswiler's Ack
> - Add Marcel Ziswiler's Ack
> - Add Marcel Ziswiler's Ack
> - Move can nodes to module deviceteree include imx6ull-colibri.dtsi
> - Add Marcel Ziswiler's Ack
>
> Changes in v3:
> - Add new commit message from Stefan's proposal on ML
> - Fix commit message
> - Fix commit title to "...imx6-apalis:..."
>
> Changes in v2:
> - Deleted touchrevolution downstream stuff
> - Use generic node name
> - Better comment
> - Changed commit title to '...imx6qdl-apalis:...'
> - Deleted touchrevolution downstream stuff
> - Use generic node name
> - Put a better comment in there
> - Commit title
> - Removed f0710a
> that is downstream only
> - Changed to generic node name
> - Better comment
>
> Max Krummenacher (2):
> ARM: dts: imx6ull-colibri: reduce v_batt current in power off
> ARM: dts: imx6ull: improve can templates
>
> Philippe Schenker (9):
> ARM: dts: imx7-colibri: Add touch controllers
> ARM: dts: imx6qdl-colibri: Add missing pin declaration in iomuxc
> ARM: dts: imx6qdl-apalis: Add sleep state to can interfaces
> ARM: dts: imx6-apalis: Add touchscreens used on Toradex eval boards
> ARM: dts: imx6-colibri: Add missing pinmuxing to Toradex eval board
> ARM: dts: imx6ull-colibri: Add sleep mode to fec
> ARM: dts: imx6ull-colibri: Add watchdog
> ARM: dts: imx6ull-colibri: Add general wakeup key used on Colibri
> ARM: dts: imx6ull-colibri: Add touchscreen used with Eval Board
Applied all, but except this one which uses base64
Content-Transfer-Encoding.
Shawn
>
> Stefan Agner (2):
> ARM: dts: imx7-colibri: add GPIO wakeup key
> ARM: dts: imx7-colibri: fix 1.8V/UHS support
>
> arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts | 39 +++++++++++
> arch/arm/boot/dts/imx6q-apalis-eval.dts | 13 ++++
> arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts | 13 ++++
> arch/arm/boot/dts/imx6q-apalis-ixora.dts | 13 ++++
> arch/arm/boot/dts/imx6qdl-apalis.dtsi | 27 ++++++--
> arch/arm/boot/dts/imx6qdl-colibri.dtsi | 17 +++++
> .../arm/boot/dts/imx6ull-colibri-eval-v3.dtsi | 38 +++++++++++
> .../arm/boot/dts/imx6ull-colibri-nonwifi.dtsi | 2 +-
> arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi | 2 +-
> arch/arm/boot/dts/imx6ull-colibri.dtsi | 64 +++++++++++++++++--
> arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi | 38 +++++++++++
> arch/arm/boot/dts/imx7-colibri.dtsi | 30 ++++++++-
> 12 files changed, 280 insertions(+), 16 deletions(-)
>
> --
> 2.23.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] arm64: dts: ls1028a: fix a compatible issue
From: Shawn Guo @ 2019-09-14 2:42 UTC (permalink / raw)
To: Yuantian Tang
Cc: mark.rutland, devicetree, robh+dt, linux-arm-kernel, leoyang.li
In-Reply-To: <20190829073439.13069-1-andy.tang@nxp.com>
On Thu, Aug 29, 2019 at 03:34:39PM +0800, Yuantian Tang wrote:
> The I2C multiplexer used on ls1028aqds is PCA9547, not PCA9847.
> So correct it.
Can elaborate the fix a little bit, saying what's the issue exactly
with using that incorrect compatible?
>
> Signed-off-by: Yuantian Tang <andy.tang@nxp.com>
Do we need a fix tag?
Shawn
> ---
> arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
> index 5e14e5a19744..f5da9e8b0d9d 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
> @@ -107,7 +107,7 @@
> status = "okay";
>
> i2c-mux@77 {
> - compatible = "nxp,pca9847";
> + compatible = "nxp,pca9547";
> reg = <0x77>;
> #address-cells = <1>;
> #size-cells = <0>;
> --
> 2.17.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] arm64: dts: meson: Add capacity-dmips-mhz attributes to G12B
From: Christian Hewitt @ 2019-09-14 2:49 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Kevin Hilman, devicetree,
linux-arm-kernel, linux-amlogic, linux-kernel
Cc: Frank Hartung, Christian Hewitt
From: Frank Hartung <supervisedthinking@gmail.com>
From: Frank Hartung <supervisedthinking@gmail.com>
Meson G12B SoCs (S922X and A311D) are a big-little design where not all CPUs
are equal; the A53s cores are weaker than the A72s.
Include capacity-dmips-mhz properties to tell the OS there is a difference
in processing capacity. The dmips values are based on similar submissions for
other A53/A72 SoCs: HiSilicon 3660 [1] and Rockchip RK3399 [2].
This change is particularly beneficial for use-cases like retro gaming where
emulators often run on a single core. The OS now chooses an A72 core instead
of an A53 core.
[1] https://lore.kernel.org/patchwork/patch/862742/
[2] https://patchwork.kernel.org/patch/10836577/
Signed-off-by: Frank Hartung <supervisedthinking@gmail.com>
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
---
arch/arm64/boot/dts/amlogic/meson-g12b.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
index 5628ccd..7f78d88 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
@@ -49,6 +49,7 @@
compatible = "arm,cortex-a53";
reg = <0x0 0x0>;
enable-method = "psci";
+ capacity-dmips-mhz = <592>;
next-level-cache = <&l2>;
};
@@ -57,6 +58,7 @@
compatible = "arm,cortex-a53";
reg = <0x0 0x1>;
enable-method = "psci";
+ capacity-dmips-mhz = <592>;
next-level-cache = <&l2>;
};
@@ -65,6 +67,7 @@
compatible = "arm,cortex-a73";
reg = <0x0 0x100>;
enable-method = "psci";
+ capacity-dmips-mhz = <1024>;
next-level-cache = <&l2>;
};
@@ -73,6 +76,7 @@
compatible = "arm,cortex-a73";
reg = <0x0 0x101>;
enable-method = "psci";
+ capacity-dmips-mhz = <1024>;
next-level-cache = <&l2>;
};
@@ -81,6 +85,7 @@
compatible = "arm,cortex-a73";
reg = <0x0 0x102>;
enable-method = "psci";
+ capacity-dmips-mhz = <1024>;
next-level-cache = <&l2>;
};
@@ -89,6 +94,7 @@
compatible = "arm,cortex-a73";
reg = <0x0 0x103>;
enable-method = "psci";
+ capacity-dmips-mhz = <1024>;
next-level-cache = <&l2>;
};
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [arm:cex7 20/20] make[4]: *** No rule to make target 'drivers/bus/fsl-mc/fsl-mc-uapi.o', needed by 'drivers/bus/fsl-mc/built-in.a'.
From: kbuild test robot @ 2019-09-14 2:58 UTC (permalink / raw)
To: Russell King; +Cc: kbuild-all, linux-arm-kernel
[-- Attachment #1: Type: text/plain, Size: 921 bytes --]
tree: git://git.armlinux.org.uk/~rmk/linux-arm.git cex7
head: 5b0bee16ea663db4aefd0cc1d0dc5e41acabb5e8
commit: 5b0bee16ea663db4aefd0cc1d0dc5e41acabb5e8 [20/20] fsl-mc: add uapi interface for restool
config: x86_64-allmodconfig (attached as .config)
compiler: gcc-7 (Debian 7.4.0-11) 7.4.0
reproduce:
git checkout 5b0bee16ea663db4aefd0cc1d0dc5e41acabb5e8
# save the attached .config to linux build tree
make ARCH=x86_64
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
>> make[4]: *** No rule to make target 'drivers/bus/fsl-mc/fsl-mc-uapi.o', needed by 'drivers/bus/fsl-mc/built-in.a'.
make[4]: Target '__build' not remade because of errors.
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 69515 bytes --]
[-- Attachment #3: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* RE: [PATCH v3 09/11] PCI: layerscape: Add EP mode support for ls1088a and ls2088a
From: Xiaowei Bao @ 2019-09-14 4:10 UTC (permalink / raw)
To: Andrew Murray
Cc: mark.rutland@arm.com, Roy Zang, lorenzo.pieralisi@arm.com,
arnd@arndb.de, devicetree@vger.kernel.org, jingoohan1@gmail.com,
Z.q. Hou, linuxppc-dev@lists.ozlabs.org,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
kishon@ti.com, M.h. Lian, robh+dt@kernel.org,
gregkh@linuxfoundation.org, linux-arm-kernel@lists.infradead.org,
gustavo.pimentel@synopsys.com, Leo Li, shawnguo@kernel.org,
Mingkai Hu
In-Reply-To: <20190912124943.GD9720@e119886-lin.cambridge.arm.com>
> -----Original Message-----
> From: Andrew Murray <andrew.murray@arm.com>
> Sent: 2019年9月12日 20:50
> To: Xiaowei Bao <xiaowei.bao@nxp.com>
> Cc: robh+dt@kernel.org; mark.rutland@arm.com; shawnguo@kernel.org; Leo
> Li <leoyang.li@nxp.com>; kishon@ti.com; lorenzo.pieralisi@arm.com; M.h.
> Lian <minghuan.lian@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>; Roy
> Zang <roy.zang@nxp.com>; jingoohan1@gmail.com;
> gustavo.pimentel@synopsys.com; linux-pci@vger.kernel.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linuxppc-dev@lists.ozlabs.org;
> arnd@arndb.de; gregkh@linuxfoundation.org; Z.q. Hou
> <zhiqiang.hou@nxp.com>
> Subject: Re: [PATCH v3 09/11] PCI: layerscape: Add EP mode support for
> ls1088a and ls2088a
>
> On Tue, Sep 03, 2019 at 01:47:36AM +0000, Xiaowei Bao wrote:
> >
> >
> > > -----Original Message-----
> > > From: Andrew Murray <andrew.murray@arm.com>
> > > Sent: 2019年9月2日 20:46
> > > To: Xiaowei Bao <xiaowei.bao@nxp.com>
> > > Cc: robh+dt@kernel.org; mark.rutland@arm.com; shawnguo@kernel.org;
> > > Leo Li <leoyang.li@nxp.com>; kishon@ti.com; lorenzo.pieralisi@arm.com;
> M.h.
> > > Lian <minghuan.lian@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>; Roy
> > > Zang <roy.zang@nxp.com>; jingoohan1@gmail.com;
> > > gustavo.pimentel@synopsys.com; linux-pci@vger.kernel.org;
> > > devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> > > linux-arm-kernel@lists.infradead.org; linuxppc-dev@lists.ozlabs.org;
> > > arnd@arndb.de; gregkh@linuxfoundation.org; Z.q. Hou
> > > <zhiqiang.hou@nxp.com>
> > > Subject: Re: [PATCH v3 09/11] PCI: layerscape: Add EP mode support
> > > for ls1088a and ls2088a
> > >
> > > On Mon, Sep 02, 2019 at 11:17:14AM +0800, Xiaowei Bao wrote:
> > > > Add PCIe EP mode support for ls1088a and ls2088a, there are some
> > > > difference between LS1 and LS2 platform, so refactor the code of
> > > > the EP driver.
> > > >
> > > > Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> > > > ---
> > > > v2:
> > > > - This is a new patch for supporting the ls1088a and ls2088a platform.
> > > > v3:
> > > > - Adjust the some struct assignment order in probe function.
> > > >
> > > > drivers/pci/controller/dwc/pci-layerscape-ep.c | 72
> > > > +++++++++++++++++++-------
> > > > 1 file changed, 53 insertions(+), 19 deletions(-)
> > > >
> > > > diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > > b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > > index 5f0cb99..723bbe5 100644
> > > > --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > > +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > > @@ -20,27 +20,29 @@
> > > >
> > > > #define PCIE_DBI2_OFFSET 0x1000 /* DBI2 base address*/
> > > >
> > > > -struct ls_pcie_ep {
> > > > - struct dw_pcie *pci;
> > > > - struct pci_epc_features *ls_epc;
> > > > +#define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
> > > > +
> > > > +struct ls_pcie_ep_drvdata {
> > > > + u32 func_offset;
> > > > + const struct dw_pcie_ep_ops *ops;
> > > > + const struct dw_pcie_ops *dw_pcie_ops;
> > > > };
> > > >
> > > > -#define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
> > > > +struct ls_pcie_ep {
> > > > + struct dw_pcie *pci;
> > > > + struct pci_epc_features *ls_epc;
> > > > + const struct ls_pcie_ep_drvdata *drvdata; };
> > > >
> > > > static int ls_pcie_establish_link(struct dw_pcie *pci) {
> > > > return 0;
> > > > }
> > > >
> > > > -static const struct dw_pcie_ops ls_pcie_ep_ops = {
> > > > +static const struct dw_pcie_ops dw_ls_pcie_ep_ops = {
> > > > .start_link = ls_pcie_establish_link, };
> > > >
> > > > -static const struct of_device_id ls_pcie_ep_of_match[] = {
> > > > - { .compatible = "fsl,ls-pcie-ep",},
> > > > - { },
> > > > -};
> > > > -
> > > > static const struct pci_epc_features*
> > > > ls_pcie_ep_get_features(struct dw_pcie_ep *ep) { @@ -87,10 +89,39
> > > > @@ static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
> > > > }
> > > > }
> > > >
> > > > -static const struct dw_pcie_ep_ops pcie_ep_ops = {
> > > > +static unsigned int ls_pcie_ep_func_conf_select(struct dw_pcie_ep
> *ep,
> > > > + u8 func_no)
> > > > +{
> > > > + struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> > > > + struct ls_pcie_ep *pcie = to_ls_pcie_ep(pci);
> > > > +
> > > > + WARN_ON(func_no && !pcie->drvdata->func_offset);
> > > > + return pcie->drvdata->func_offset * func_no; }
> > > > +
> > > > +static const struct dw_pcie_ep_ops ls_pcie_ep_ops = {
> > > > .ep_init = ls_pcie_ep_init,
> > > > .raise_irq = ls_pcie_ep_raise_irq,
> > > > .get_features = ls_pcie_ep_get_features,
> > > > + .func_conf_select = ls_pcie_ep_func_conf_select, };
> > > > +
> > > > +static const struct ls_pcie_ep_drvdata ls1_ep_drvdata = {
> > > > + .ops = &ls_pcie_ep_ops,
> > > > + .dw_pcie_ops = &dw_ls_pcie_ep_ops, };
> > > > +
> > > > +static const struct ls_pcie_ep_drvdata ls2_ep_drvdata = {
> > > > + .func_offset = 0x20000,
> > > > + .ops = &ls_pcie_ep_ops,
> > > > + .dw_pcie_ops = &dw_ls_pcie_ep_ops, };
> > > > +
> > > > +static const struct of_device_id ls_pcie_ep_of_match[] = {
> > > > + { .compatible = "fsl,ls1046a-pcie-ep", .data = &ls1_ep_drvdata },
> > > > + { .compatible = "fsl,ls1088a-pcie-ep", .data = &ls2_ep_drvdata },
> > > > + { .compatible = "fsl,ls2088a-pcie-ep", .data = &ls2_ep_drvdata },
> > > > + { },
> > >
> > > This removes support for "fsl,ls-pcie-ep" - was that intentional? If
> > > you do plan to drop it please make sure you explain why in the
> > > commit message. See also my comments in your dt-binding patch.
> >
> > In fact, the u-boot will fixup the status property to 'status =
> > enabled' in PCI node of the DTS base on "fsl,ls-pcie-ep" compatible,
> > so "fsl,ls-pcie-ep" is used, I used this compatible before, because
> > the driver only support the LS1046a, but this time, I add the LS1088a
> > and LS2088a support, and these two boards have some difference form
> LS1046a, so I changed the compatible. I am not sure whether need to add
> "fsl,ls-pcie-ep"
> > in there, could you give some advice, thanks a lot.
>
> It sounds like "fsl,ls-pcie-ep" can be a fallback for "fsl,ls1046a-pcie-ep".
This is not a fallback, the compatible "fsl,ls1046a-pcie-ep" is used by bootloader,
the bootloader will modify the status property, the bootloader code get the
PCI_HEADER_TYPE(0xe) of config space to decide enable which node(EP or RC)
status property. At the beginning, we plan to use one compatible "fsl,ls1046a-pcie-ep"
support all NXP's platform, but actually, due to the difference of each platform,
it is difficult.
>
> I'm assuming that if someone used "fsl,ls1046a-pcie-ep" on ls1088a or
> ls2088a hardware it would still work, but without the multiple PF support.
>
I think the EP driver will not work if use current code, due to the current driver
need driver data.
> I.e. if "fsl,ls-pcie-ep" is given, treat it as ls1046a.
>
> Thanks,
>
> Andrew Murray
>
> >
> > Thanks
> > Xiaowei
> >
> > >
> > > Thanks,
> > >
> > > Andrew Murray
> > >
> > > > };
> > > >
> > > > static int __init ls_add_pcie_ep(struct ls_pcie_ep *pcie, @@
> > > > -103,7
> > > > +134,7 @@ static int __init ls_add_pcie_ep(struct ls_pcie_ep
> > > > +*pcie,
> > > > int ret;
> > > >
> > > > ep = &pci->ep;
> > > > - ep->ops = &pcie_ep_ops;
> > > > + ep->ops = pcie->drvdata->ops;
> > > >
> > > > res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> > > "addr_space");
> > > > if (!res)
> > > > @@ -142,20 +173,23 @@ static int __init ls_pcie_ep_probe(struct
> > > platform_device *pdev)
> > > > if (!ls_epc)
> > > > return -ENOMEM;
> > > >
> > > > - dbi_base = platform_get_resource_byname(pdev,
> IORESOURCE_MEM,
> > > "regs");
> > > > - pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base);
> > > > - if (IS_ERR(pci->dbi_base))
> > > > - return PTR_ERR(pci->dbi_base);
> > > > + pcie->drvdata = of_device_get_match_data(dev);
> > > >
> > > > - pci->dbi_base2 = pci->dbi_base + PCIE_DBI2_OFFSET;
> > > > pci->dev = dev;
> > > > - pci->ops = &ls_pcie_ep_ops;
> > > > - pcie->pci = pci;
> > > > + pci->ops = pcie->drvdata->dw_pcie_ops;
> > > >
> > > > ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
> > > >
> > > > + pcie->pci = pci;
> > > > pcie->ls_epc = ls_epc;
> > > >
> > > > + dbi_base = platform_get_resource_byname(pdev,
> IORESOURCE_MEM,
> > > "regs");
> > > > + pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base);
> > > > + if (IS_ERR(pci->dbi_base))
> > > > + return PTR_ERR(pci->dbi_base);
> > > > +
> > > > + pci->dbi_base2 = pci->dbi_base + PCIE_DBI2_OFFSET;
> > > > +
> > > > platform_set_drvdata(pdev, pcie);
> > > >
> > > > ret = ls_add_pcie_ep(pcie, pdev);
> > > > --
> > > > 2.9.5
> > > >
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* RE: [PATCH v3 11/11] misc: pci_endpoint_test: Add LS1088a in pci_device_id table
From: Xiaowei Bao @ 2019-09-14 4:13 UTC (permalink / raw)
To: Andrew Murray, helgaas@kernel.org
Cc: mark.rutland@arm.com, Roy Zang, lorenzo.pieralisi@arm.com,
arnd@arndb.de, devicetree@vger.kernel.org, jingoohan1@gmail.com,
Z.q. Hou, linuxppc-dev@lists.ozlabs.org,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
kishon@ti.com, M.h. Lian, robh+dt@kernel.org,
gregkh@linuxfoundation.org, linux-arm-kernel@lists.infradead.org,
gustavo.pimentel@synopsys.com, Leo Li, shawnguo@kernel.org,
Mingkai Hu
In-Reply-To: <20190912125939.GE9720@e119886-lin.cambridge.arm.com>
> -----Original Message-----
> From: Andrew Murray <andrew.murray@arm.com>
> Sent: 2019年9月12日 21:00
> To: Xiaowei Bao <xiaowei.bao@nxp.com>; helgaas@kernel.org
> Cc: robh+dt@kernel.org; mark.rutland@arm.com; shawnguo@kernel.org; Leo
> Li <leoyang.li@nxp.com>; kishon@ti.com; lorenzo.pieralisi@arm.com; M.h.
> Lian <minghuan.lian@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>; Roy
> Zang <roy.zang@nxp.com>; jingoohan1@gmail.com;
> gustavo.pimentel@synopsys.com; linux-pci@vger.kernel.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linuxppc-dev@lists.ozlabs.org;
> arnd@arndb.de; gregkh@linuxfoundation.org; Z.q. Hou
> <zhiqiang.hou@nxp.com>
> Subject: Re: [PATCH v3 11/11] misc: pci_endpoint_test: Add LS1088a in
> pci_device_id table
>
> On Tue, Sep 03, 2019 at 01:52:30AM +0000, Xiaowei Bao wrote:
> >
> >
> > > -----Original Message-----
> > > From: Andrew Murray <andrew.murray@arm.com>
> > > Sent: 2019年9月2日 20:55
> > > To: Xiaowei Bao <xiaowei.bao@nxp.com>
> > > Cc: robh+dt@kernel.org; mark.rutland@arm.com; shawnguo@kernel.org;
> > > Leo Li <leoyang.li@nxp.com>; kishon@ti.com; lorenzo.pieralisi@arm.com;
> M.h.
> > > Lian <minghuan.lian@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>; Roy
> > > Zang <roy.zang@nxp.com>; jingoohan1@gmail.com;
> > > gustavo.pimentel@synopsys.com; linux-pci@vger.kernel.org;
> > > devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> > > linux-arm-kernel@lists.infradead.org; linuxppc-dev@lists.ozlabs.org;
> > > arnd@arndb.de; gregkh@linuxfoundation.org; Z.q. Hou
> > > <zhiqiang.hou@nxp.com>
> > > Subject: Re: [PATCH v3 11/11] misc: pci_endpoint_test: Add LS1088a
> > > in pci_device_id table
> > >
> > > On Mon, Sep 02, 2019 at 11:17:16AM +0800, Xiaowei Bao wrote:
> > > > Add LS1088a in pci_device_id table so that pci-epf-test can be
> > > > used for testing PCIe EP in LS1088a.
> > > >
> > > > Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> > > > ---
> > > > v2:
> > > > - No change.
> > > > v3:
> > > > - No change.
> > > >
> > > > drivers/misc/pci_endpoint_test.c | 1 +
> > > > 1 file changed, 1 insertion(+)
> > > >
> > > > diff --git a/drivers/misc/pci_endpoint_test.c
> > > > b/drivers/misc/pci_endpoint_test.c
> > > > index 6e208a0..d531951 100644
> > > > --- a/drivers/misc/pci_endpoint_test.c
> > > > +++ b/drivers/misc/pci_endpoint_test.c
> > > > @@ -793,6 +793,7 @@ static const struct pci_device_id
> > > pci_endpoint_test_tbl[] = {
> > > > { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x) },
> > > > { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x) },
> > > > { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x81c0) },
> > > > + { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x80c0) },
> > >
> > > The Freescale PCI devices are the only devices in this table that
> > > don't have a define for their device ID. I think a define should be
> > > created for both of the device IDs above.
> >
> > OK, but I only define in this file, I am not sure this can define in
> > include/linux/pci_ids.h file
>
> This file seems a little inconsistent...
>
> - Two of the TI device IDs are defined in pci_ids.h and only used in
> pci_endpoint_test.c
> - One of the TI device IDs are defined in pci_endpoint_test.c and only used
> there
> - The Freescale device ID is hardcoded and only used in pci_endpoint_test.c
>
> The header in pci_ids.h has a comment suggestion definitions are only added
> where used in multiple files - yet I don't think this holds true.
Thanks Andrew.
>
> Bjorn - do you have a suggestion?
>
> Thanks,
>
> Andrew Murray
>
> >
> > Thanks
> > Xiaowei
> >
> > >
> > > Thanks,
> > >
> > > Andrew Murray
> > >
> > > > { PCI_DEVICE_DATA(SYNOPSYS, EDDA, NULL) },
> > > > { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654),
> > > > .driver_data = (kernel_ulong_t)&am654_data
> > > > --
> > > > 2.9.5
> > > >
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* RE: [PATCH v3 10/11] arm64: dts: layerscape: Add PCIe EP node for ls1088a
From: Xiaowei Bao @ 2019-09-14 4:15 UTC (permalink / raw)
To: Andrew Murray
Cc: mark.rutland@arm.com, Roy Zang, lorenzo.pieralisi@arm.com,
arnd@arndb.de, devicetree@vger.kernel.org, jingoohan1@gmail.com,
Z.q. Hou, linuxppc-dev@lists.ozlabs.org,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
kishon@ti.com, M.h. Lian, robh+dt@kernel.org,
gregkh@linuxfoundation.org, linux-arm-kernel@lists.infradead.org,
gustavo.pimentel@synopsys.com, Leo Li, shawnguo@kernel.org,
Mingkai Hu
In-Reply-To: <20190912130159.GF9720@e119886-lin.cambridge.arm.com>
> -----Original Message-----
> From: Andrew Murray <andrew.murray@arm.com>
> Sent: 2019年9月12日 21:02
> To: Xiaowei Bao <xiaowei.bao@nxp.com>
> Cc: robh+dt@kernel.org; mark.rutland@arm.com; shawnguo@kernel.org; Leo
> Li <leoyang.li@nxp.com>; kishon@ti.com; lorenzo.pieralisi@arm.com; M.h.
> Lian <minghuan.lian@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>; Roy
> Zang <roy.zang@nxp.com>; jingoohan1@gmail.com;
> gustavo.pimentel@synopsys.com; linux-pci@vger.kernel.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linuxppc-dev@lists.ozlabs.org;
> arnd@arndb.de; gregkh@linuxfoundation.org; Z.q. Hou
> <zhiqiang.hou@nxp.com>
> Subject: Re: [PATCH v3 10/11] arm64: dts: layerscape: Add PCIe EP node for
> ls1088a
>
> On Tue, Sep 03, 2019 at 02:01:32AM +0000, Xiaowei Bao wrote:
> >
> >
> > > -----Original Message-----
> > > From: Andrew Murray <andrew.murray@arm.com>
> > > Sent: 2019年9月2日 21:06
> > > To: Xiaowei Bao <xiaowei.bao@nxp.com>
> > > Cc: robh+dt@kernel.org; mark.rutland@arm.com; shawnguo@kernel.org;
> > > Leo Li <leoyang.li@nxp.com>; kishon@ti.com; lorenzo.pieralisi@arm.com;
> M.h.
> > > Lian <minghuan.lian@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>; Roy
> > > Zang <roy.zang@nxp.com>; jingoohan1@gmail.com;
> > > gustavo.pimentel@synopsys.com; linux-pci@vger.kernel.org;
> > > devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> > > linux-arm-kernel@lists.infradead.org; linuxppc-dev@lists.ozlabs.org;
> > > arnd@arndb.de; gregkh@linuxfoundation.org; Z.q. Hou
> > > <zhiqiang.hou@nxp.com>
> > > Subject: Re: [PATCH v3 10/11] arm64: dts: layerscape: Add PCIe EP
> > > node for ls1088a
> > >
> > > On Mon, Sep 02, 2019 at 11:17:15AM +0800, Xiaowei Bao wrote:
> > > > Add PCIe EP node for ls1088a to support EP mode.
> > > >
> > > > Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> > > > ---
> > > > v2:
> > > > - Remove the pf-offset proparty.
> > > > v3:
> > > > - No change.
> > > >
> > > > arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 31
> > > ++++++++++++++++++++++++++
> > > > 1 file changed, 31 insertions(+)
> > > >
> > > > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
> > > b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
> > > > index c676d07..da246ab 100644
> > > > --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
> > > > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
> > > > @@ -483,6 +483,17 @@
> > > > status = "disabled";
> > > > };
> > > >
> > > > + pcie_ep@3400000 {
> > > > + compatible = "fsl,ls1088a-pcie-ep","fsl,ls-pcie-ep";
> > >
> > > Here you specify a fallback "fsl,ls-pcie-ep" that is removed by this series.
> > >
> > > Besides that, this looks OK.
> >
> > As explained, the "fsl,ls-pcie-ep" is needed, due to the u-boot will
> > fixup the status property base on this compatible, I think we reserve
> > this compatible is helpfully, if delate this compatible, I have to modify the
> code of bootloader.
>
> I assume you mean that u-boot fixes up "fsl,ls-pcie-ep" *only* for ls1046a
> devices?
No, all Layerscape platform of NXP.
>
> Thanks,
>
> Andrew Murray
>
> >
> > Thanks
> > XIaowei
> >
> > >
> > > Thanks,
> > >
> > > Andrew Murray
> > >
> > > > + reg = <0x00 0x03400000 0x0 0x00100000
> > > > + 0x20 0x00000000 0x8 0x00000000>;
> > > > + reg-names = "regs", "addr_space";
> > > > + num-ib-windows = <24>;
> > > > + num-ob-windows = <128>;
> > > > + max-functions = /bits/ 8 <2>;
> > > > + status = "disabled";
> > > > + };
> > > > +
> > > > pcie@3500000 {
> > > > compatible = "fsl,ls1088a-pcie";
> > > > reg = <0x00 0x03500000 0x0 0x00100000 /* controller
> > > registers */
> > > > @@ -508,6 +519,16 @@
> > > > status = "disabled";
> > > > };
> > > >
> > > > + pcie_ep@3500000 {
> > > > + compatible = "fsl,ls1088a-pcie-ep","fsl,ls-pcie-ep";
> > > > + reg = <0x00 0x03500000 0x0 0x00100000
> > > > + 0x28 0x00000000 0x8 0x00000000>;
> > > > + reg-names = "regs", "addr_space";
> > > > + num-ib-windows = <6>;
> > > > + num-ob-windows = <8>;
> > > > + status = "disabled";
> > > > + };
> > > > +
> > > > pcie@3600000 {
> > > > compatible = "fsl,ls1088a-pcie";
> > > > reg = <0x00 0x03600000 0x0 0x00100000 /* controller
> > > registers */
> > > > @@ -533,6 +554,16 @@
> > > > status = "disabled";
> > > > };
> > > >
> > > > + pcie_ep@3600000 {
> > > > + compatible = "fsl,ls1088a-pcie-ep","fsl,ls-pcie-ep";
> > > > + reg = <0x00 0x03600000 0x0 0x00100000
> > > > + 0x30 0x00000000 0x8 0x00000000>;
> > > > + reg-names = "regs", "addr_space";
> > > > + num-ib-windows = <6>;
> > > > + num-ob-windows = <8>;
> > > > + status = "disabled";
> > > > + };
> > > > +
> > > > smmu: iommu@5000000 {
> > > > compatible = "arm,mmu-500";
> > > > reg = <0 0x5000000 0 0x800000>;
> > > > --
> > > > 2.9.5
> > > >
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* RE: [PATCH v3 08/11] PCI: layerscape: Modify the MSIX to the doorbell mode
From: Xiaowei Bao @ 2019-09-14 6:37 UTC (permalink / raw)
To: Gustavo Pimentel, Andrew Murray
Cc: mark.rutland@arm.com, Roy Zang, lorenzo.pieralisi@arm.com,
arnd@arndb.de, devicetree@vger.kernel.org, jingoohan1@gmail.com,
Z.q. Hou, linuxppc-dev@lists.ozlabs.org,
linux-kernel@vger.kernel.org, kishon@ti.com, M.h. Lian,
robh+dt@kernel.org, gregkh@linuxfoundation.org,
linux-arm-kernel@lists.infradead.org, linux-pci@vger.kernel.org,
Leo Li, shawnguo@kernel.org, Mingkai Hu
In-Reply-To: <DM6PR12MB40100CC1C0E64040652C3BFBDAB00@DM6PR12MB4010.namprd12.prod.outlook.com>
> -----Original Message-----
> From: Gustavo Pimentel <Gustavo.Pimentel@synopsys.com>
> Sent: 2019年9月12日 19:24
> To: Andrew Murray <andrew.murray@arm.com>; Xiaowei Bao
> <xiaowei.bao@nxp.com>
> Cc: robh+dt@kernel.org; mark.rutland@arm.com; shawnguo@kernel.org; Leo
> Li <leoyang.li@nxp.com>; kishon@ti.com; lorenzo.pieralisi@arm.com; M.h.
> Lian <minghuan.lian@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>; Roy
> Zang <roy.zang@nxp.com>; jingoohan1@gmail.com;
> gustavo.pimentel@synopsys.com; linux-pci@vger.kernel.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linuxppc-dev@lists.ozlabs.org;
> arnd@arndb.de; gregkh@linuxfoundation.org; Z.q. Hou
> <zhiqiang.hou@nxp.com>
> Subject: RE: [PATCH v3 08/11] PCI: layerscape: Modify the MSIX to the
> doorbell mode
>
> Hi,
>
> Sorry for the delay I was in parental leave and I'm still trying not to drown in
> the mailing list emails... 😊
>
> On Mon, Sep 2, 2019 at 13:1:47, Andrew Murray <andrew.murray@arm.com>
> wrote:
>
> > On Mon, Sep 02, 2019 at 11:17:13AM +0800, Xiaowei Bao wrote:
> > > dw_pcie_ep_raise_msix_irq was never called in the exisitng driver
> > > before, because the ls1046a platform don't support the MSIX feature
> > > and msix_capable was always set to false.
> > > Now that add the ls1088a platform with MSIX support, but the
> > > existing dw_pcie_ep_raise_msix_irq doesn't work, so use the doorbell
> > > method to support the MSIX feature.
>
> Hum... the implementation of msix implementation did work on my use case,
> however, at the time the setup used for developing and testing the
> implementation only had one PF (by default 0). Perhaps this could was is
> causing the different behavior between our setups.
>
> You have more than one PF, right?
Yes, I have two PFs.
Thanks
Xiaowei
>
> If I remember correctly, msix feature support entered on kernel 4.19 version
> and it worked quite well at the time, but I didn't test since there (I've to
> manage time to be able to retest it again), I'm didn't seen any patch that
> could interfere with this.
>
> Regards,
> Gustavo
>
>
> > >
> > > Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> >
> > Reviewed-by: Andrew Murray <andrew.murray@arm.com>
> >
> > > ---
> > > v2:
> > > - No change
> > > v3:
> > > - Modify the commit message make it clearly.
> > >
> > > drivers/pci/controller/dwc/pci-layerscape-ep.c | 3 ++-
> > > 1 file changed, 2 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > index 1e07287..5f0cb99 100644
> > > --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > @@ -79,7 +79,8 @@ static int ls_pcie_ep_raise_irq(struct dw_pcie_ep
> *ep, u8 func_no,
> > > case PCI_EPC_IRQ_MSI:
> > > return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
> > > case PCI_EPC_IRQ_MSIX:
> > > - return dw_pcie_ep_raise_msix_irq(ep, func_no, interrupt_num);
> > > + return dw_pcie_ep_raise_msix_irq_doorbell(ep, func_no,
> > > + interrupt_num);
> > > default:
> > > dev_err(pci->dev, "UNKNOWN IRQ type\n");
> > > return -EINVAL;
> > > --
> > > 2.9.5
> > >
>
_______________________________________________
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 5/6] media: sun4i: Add H3 deinterlace driver
From: Jernej Škrabec @ 2019-09-14 6:42 UTC (permalink / raw)
To: Maxime Ripard
Cc: mark.rutland, devicetree, linux-sunxi, linux-kernel, hverkuil,
wens, robh+dt, mchehab, linux-arm-kernel, linux-media
In-Reply-To: <20190912202647.wfcjur7yxhlelvd6@localhost.localdomain>
Hi!
Dne četrtek, 12. september 2019 ob 22:26:47 CEST je Maxime Ripard napisal(a):
> Hi,
>
> On Thu, Sep 12, 2019 at 07:51:31PM +0200, Jernej Skrabec wrote:
> > + dev->regmap = devm_regmap_init_mmio(dev->dev, dev->base,
> > +
&deinterlace_regmap_config);
> > + if (IS_ERR(dev->regmap)) {
> > + dev_err(dev->dev, "Couldn't create deinterlace
regmap\n");
> > +
> > + return PTR_ERR(dev->regmap);
> > + }
> > +
> > + ret = clk_prepare_enable(dev->bus_clk);
> > + if (ret) {
> > + dev_err(dev->dev, "Failed to enable bus clock\n");
> > +
> > + return ret;
> > + }
>
> Do you need to keep the bus clock enabled all the time? Usually, for
> the SoCs that have a reset line, you only need it to read / write to
> the registers, not to have the controller actually running.
>
> If you don't, then regmap_init_mmio_clk will take care of that for
> you.
>
> > + clk_set_rate(dev->mod_clk, 300000000);
> > +
> > + ret = clk_prepare_enable(dev->mod_clk);
> > + if (ret) {
> > + dev_err(dev->dev, "Failed to enable mod clock\n");
> > +
> > + goto err_bus_clk;
> > + }
> > +
> > + ret = clk_prepare_enable(dev->ram_clk);
> > + if (ret) {
> > + dev_err(dev->dev, "Failed to enable ram clock\n");
> > +
> > + goto err_mod_clk;
> > + }
> > +
> > + ret = reset_control_reset(dev->rstc);
> > + if (ret) {
> > + dev_err(dev->dev, "Failed to apply reset\n");
> > +
> > + goto err_ram_clk;
> > + }
>
> This could be moved to a runtime_pm hook, with get_sync called in the
> open. That way you won't leave the device powered on if it's unused.
Currently I'm looking at sun4i_csi.c as an example of runtime ops, but it
seems a bit wrong to have suspend and resume function marked with
__maybe_unused because they are the only functions which enable needed clocks.
If CONFIG_PM is not enabled, then this driver simply won't work, because
clocks will never get enabled. I guess I can implement runtime pm ops in the
same way and add additional handling when CONFIG_PM is not enabled, right?
BTW, which callback is get_sync? I don't see it in dev_pm_ops. I suppose I
need only runtime_suspend and runtime_resume.
Off topic: sun6i_csi.c includes linux/pm_runtime.h but it doesn't have any kind
of power management as far as I can see.
Best regards,
Jernej
>
> > +struct deinterlace_dev {
> > + struct v4l2_device v4l2_dev;
> > + struct video_device vfd;
> > + struct device *dev;
> > + struct v4l2_m2m_dev *m2m_dev;
> > +
> > + /* Device file mutex */
> > + struct mutex dev_mutex;
> > +
> > + void __iomem *base;
> > + struct regmap *regmap;
>
> Do you need to store the base address in that structure if you're
> using the regmap?
>
> Maxime
_______________________________________________
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 RFC 11/14] arm64: Move the ASID allocator code in a separate file
From: Guo Ren @ 2019-09-14 8:49 UTC (permalink / raw)
To: Will Deacon
Cc: julien.thierry, Catalin Marinas, Palmer Dabbelt, Will Deacon,
christoffer.dall, Atish Patra, Julien Grall, gary, linux-riscv,
kvmarm, Mike Rapoport, Christoph Hellwig, aou, Arnd Bergmann,
suzuki.poulose, Marc Zyngier, Paul Walmsley, linux-arm-kernel,
Anup Patel, Linux Kernel Mailing List, iommu, james.morse
In-Reply-To: <CAJF2gTTsHCsSpf1ncVb=ZJS2d=r+AdDi2=5z-REVS=uUg9138A@mail.gmail.com>
Here is the presentation, any comments is welcome.
https://docs.google.com/presentation/d/1sc295JznVAfDIPieAqzjcyUkcHnNFQsK8FFqdoCY854/edit?usp=sharing
On Fri, Sep 13, 2019 at 3:13 PM Guo Ren <guoren@kernel.org> wrote:
>
> Another idea is seperate remote TLB invalidate into two instructions:
>
> - sfence.vma.b.asyc
> - sfence.vma.b.barrier // wait all async TLB invalidate operations finished for all harts.
>
> (I remember who mentioned me separate them into two instructions after session. Anup? Is the idea right ?)
>
> Actually, I never consider asyc TLB invalidate before, because current our light iommu did not need it.
>
> Thx all people attend the session :) Let's continue the talk.
>
>
> Guo Ren <guoren@kernel.org> 于 2019年9月12日周四 22:59写道:
>>
>> Thx Will for reply.
>>
>> On Thu, Sep 12, 2019 at 3:03 PM Will Deacon <will@kernel.org> wrote:
>> >
>> > On Sun, Sep 08, 2019 at 07:52:55AM +0800, Guo Ren wrote:
>> > > On Mon, Jun 24, 2019 at 6:40 PM Will Deacon <will@kernel.org> wrote:
>> > > > > I'll keep my system use the same ASID for SMP + IOMMU :P
>> > > >
>> > > > You will want a separate allocator for that:
>> > > >
>> > > > https://lkml.kernel.org/r/20190610184714.6786-2-jean-philippe.brucker@arm.com
>> > >
>> > > Yes, it is hard to maintain ASID between IOMMU and CPUMMU or different
>> > > system, because it's difficult to synchronize the IO_ASID when the CPU
>> > > ASID is rollover.
>> > > But we could still use hardware broadcast TLB invalidation instruction
>> > > to uniformly manage the ASID and IO_ASID, or OTHER_ASID in our IOMMU.
>> >
>> > That's probably a bad idea, because you'll likely stall execution on the
>> > CPU until the IOTLB has completed invalidation. In the case of ATS, I think
>> > an endpoint ATC is permitted to take over a minute to respond. In reality, I
>> > suspect the worst you'll ever see would be in the msec range, but that's
>> > still an unacceptable period of time to hold a CPU.
>> Just as I've said in the session that IOTLB invalidate delay is
>> another topic, My main proposal is to introduce stage1.pgd and
>> stage2.pgd as address space identifiers between different TLB systems
>> based on vmid, asid. My last part of sildes will show you how to
>> translate stage1/2.pgd to as/vmid in PCI ATS system and the method
>> could work with SMMU-v3 and intel Vt-d. (It's regret for me there is
>> no time to show you the whole slides.)
>>
>> In our light IOMMU implementation, there's no IOTLB invalidate delay
>> problem. Becasue IOMMU is very close to CPU MMU and interconnect's
>> delay is the same with SMP CPUs MMU (no PCI, VM supported).
>>
>> To solve the problem, we could define a async mode in sfence.vma.b to
>> slove the problem and finished with per_cpu_irq/exception.
>>
>> --
>> Best Regards
>> Guo Ren
>>
>> ML: https://lore.kernel.org/linux-csky/
--
Best Regards
Guo Ren
ML: https://lore.kernel.org/linux-csky/
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 6/8] ARM: dts: omap36xx: using OPP1G needs to control the abb_ldo
From: H. Nikolaus Schaller @ 2019-09-14 9:30 UTC (permalink / raw)
To: Adam Ford
Cc: Mark Rutland, devicetree, Discussions about the Letux Kernel,
linux-pm, Tony Lindgren, Viresh Kumar, Rafael J. Wysocki,
Linux Kernel Mailing List, Enric Balletbo i Serra, Rob Herring,
André Roth, Benoît Cousson, kernel, Teresa Remmet,
Javier Martinez Canillas, Linux-OMAP, arm-soc, Roger Quadros
In-Reply-To: <CAHCN7x+RTSHg7jKys=Jv6Urz0PsHNTM8EnFT1dwAZOtsjxpEAw@mail.gmail.com>
> Am 13.09.2019 um 23:13 schrieb Adam Ford <aford173@gmail.com>:
>
> On Wed, Sep 11, 2019 at 12:47 PM H. Nikolaus Schaller <hns@goldelico.com> wrote:
>>
>> See DM3730,DM275 data sheet (SPRS685B) footnote (6) in Table 4-19
>> which says that ABB must be switched to FBB mode when using the
>> OPP1G.
>>
>> The LOD definition abb_mpu_iva already exists so that we need
>> to add plumbing for vbb-supply = <&abb_mpu_iva>
>> and define two voltage vectors for each OPP so that the abb LDO
>> is also updated by the ti-cpufreq driver.
>>
>> We also must switch the ti_cpufreq_soc_data to multi_regulator.
>>
>> Note: reading out the abb reglator voltage to verify that
>> it does do transitions can be done by
>>
>> cat /sys/devices/platform/68000000.ocp/483072f0.regulator-abb-mpu/regulator/regulator.*/microvolts
>>
>> Likewise, read the twl4030 provided VDD voltage by
>>
>> cat /sys/devices/platform/68000000.ocp/48070000.i2c/i2c-0/0-0048/48070000.i2c:twl@48:regulator-vdd1/regulator/regulator.*/microvolts
>>
>> Note: to check if the ABB FBB is enabled/disabled, check
>> registers
>>
>> PRM_LDO_ABB_CTRL 0x483072F4 bit 3:0 1=bypass 5=FBB
>> PRM_LDO_ABB_SETUP 0x483072F0 0x00=bypass 0x11=FBB
>>
>> e.g.
>>
>> /dev/mem opened.
>> Memory mapped at address 0xb6fe4000.
>> Value at address 0x483072F4 (0xb6fe42f4): 0x3205
>> /dev/mem opened.
>> Memory mapped at address 0xb6f89000.
>> Value at address 0x483072F4 (0xb6f892f4): 0x3201
>>
>> Note: omap34xx and am3517 have/need no comparable LDO
>> or mechanism.
>>
>> Suggested-by: Adam Ford <aford173@gmail.com>
>> Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
>> ---
>> arch/arm/boot/dts/omap36xx.dtsi | 21 ++++++++++++++++-----
>> drivers/cpufreq/ti-cpufreq.c | 2 +-
>> 2 files changed, 17 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/omap36xx.dtsi b/arch/arm/boot/dts/omap36xx.dtsi
>> index cb5bd0969124..4bb4f534afe2 100644
>> --- a/arch/arm/boot/dts/omap36xx.dtsi
>> +++ b/arch/arm/boot/dts/omap36xx.dtsi
>> @@ -23,6 +23,7 @@
>> cpu: cpu@0 {
>> operating-points-v2 = <&cpu0_opp_table>;
>>
>> + vbb-supply = <&abb_mpu_iva>;
>> clock-latency = <300000>; /* From omap-cpufreq driver */
>> };
>> };
>> @@ -37,9 +38,11 @@
>> /*
>> * we currently only select the max voltage from table
>> * Table 4-19 of the DM3730 Data sheet (SPRS685B)
>> - * Format is: <target min max>
>> + * Format is: cpu0-supply: <target min max>
>> + * vbb-supply: <target min max>
>> */
>> - opp-microvolt = <1012500 1012500 1012500>;
>> + opp-microvolt = <1012500 1012500 1012500>,
>> + <1012500 1012500 1012500>;
>> /*
>> * first value is silicon revision bit mask
>> * second one is "speed binned" bit mask
>> @@ -50,25 +53,33 @@
>>
>> opp100-600000000 {
>> opp-hz = /bits/ 64 <600000000>;
>> - opp-microvolt = <1200000 1200000 1200000>;
>> + opp-microvolt = <1200000 1200000 1200000>,
>> + <1200000 1200000 1200000>;
>> opp-supported-hw = <0xffffffff 3>;
>> };
>>
>> opp130-800000000 {
>> opp-hz = /bits/ 64 <800000000>;
>> - opp-microvolt = <1325000 1325000 1325000>;
>> + opp-microvolt = <1325000 1325000 1325000>,
>> + <1325000 1325000 1325000>;
>> opp-supported-hw = <0xffffffff 3>;
>> };
>>
>> opp1g-1000000000 {
>> opp-hz = /bits/ 64 <1000000000>;
>> - opp-microvolt = <1375000 1375000 1375000>;
>> + opp-microvolt = <1375000 1375000 1375000>,
>> + <1375000 1375000 1375000>;
>> /* only on am/dm37x with speed-binned bit set */
>> opp-supported-hw = <0xffffffff 2>;
>> turbo-mode;
>
> If / when the thermal changes I submitted get approved, would you
> entertain dropping this turbo-mode flag so it's enabled by default?
Yes, that makes sense.
To keep patches clearly grouped into two series (better for bisect or
partial revert or apply in any order), I would suggest that we do
1. add OPP1G logic (with turbo-mode; specified)
2. add thermal throttling
3. remove turbo-mode again as soon as both are merged
A patch for 2b is waiting for 1 and 2a to be confirmed :)
BR,
Nikolaus
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] clk: sunxi-ng: h6: Use sigma-delta modulation for audio PLL
From: Jernej Skrabec @ 2019-09-14 13:51 UTC (permalink / raw)
To: mripard, wens
Cc: sboyd, mturquette, linux-kernel, linux-sunxi, linux-clk,
linux-arm-kernel
Audio devices needs exact clock rates in order to correctly reproduce
the sound. Until now, only integer factors were used to configure H6
audio PLL which resulted in inexact rates. Fix that by adding support
for fractional factors using sigma-delta modulation look-up table. It
contains values for two most commonly used audio base frequencies.
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
index d89353a3cdec..ed6338d74474 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
@@ -203,12 +203,21 @@ static struct ccu_nkmp pll_hsic_clk = {
* hardcode it to match with the clock names.
*/
#define SUN50I_H6_PLL_AUDIO_REG 0x078
+
+static struct ccu_sdm_setting pll_audio_sdm_table[] = {
+ { .rate = 541900800, .pattern = 0xc001288d, .m = 1, .n = 22 },
+ { .rate = 589824000, .pattern = 0xc00126e9, .m = 1, .n = 24 },
+};
+
static struct ccu_nm pll_audio_base_clk = {
.enable = BIT(31),
.lock = BIT(28),
.n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
.m = _SUNXI_CCU_DIV(1, 1), /* input divider */
+ .sdm = _SUNXI_CCU_SDM(pll_audio_sdm_table,
+ BIT(24), 0x178, BIT(31)),
.common = {
+ .features = CCU_FEATURE_SIGMA_DELTA_MOD,
.reg = 0x078,
.hw.init = CLK_HW_INIT("pll-audio-base", "osc24M",
&ccu_nm_ops,
@@ -753,12 +762,12 @@ static const struct clk_hw *clk_parent_pll_audio[] = {
};
/*
- * The divider of pll-audio is fixed to 8 now, as pll-audio-4x has a
- * fixed post-divider 2.
+ * The divider of pll-audio is fixed to 24 for now, so 24576000 and 22579200
+ * rates can be set exactly in conjunction with sigma-delta modulation.
*/
static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
clk_parent_pll_audio,
- 8, 1, CLK_SET_RATE_PARENT);
+ 24, 1, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
clk_parent_pll_audio,
4, 1, CLK_SET_RATE_PARENT);
@@ -1215,12 +1224,12 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev)
}
/*
- * Force the post-divider of pll-audio to 8 and the output divider
- * of it to 1, to make the clock name represents the real frequency.
+ * Force the post-divider of pll-audio to 12 and the output divider
+ * of it to 2, so 24576000 and 22579200 rates can be set exactly.
*/
val = readl(reg + SUN50I_H6_PLL_AUDIO_REG);
val &= ~(GENMASK(21, 16) | BIT(0));
- writel(val | (7 << 16), reg + SUN50I_H6_PLL_AUDIO_REG);
+ writel(val | (11 << 16) | BIT(0), reg + SUN50I_H6_PLL_AUDIO_REG);
/*
* First clock parent (osc32K) is unusable for CEC. But since there
--
2.23.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 RFC 11/14] arm64: Move the ASID allocator code in a separate file
From: Palmer Dabbelt @ 2019-09-14 14:01 UTC (permalink / raw)
To: will
Cc: julien.thierry, catalin.marinas, Will Deacon, christoffer.dall,
Atish Patra, julien.grall, guoren, gary, linux-riscv, kvmarm,
rppt, Christoph Hellwig, aou, Arnd Bergmann, suzuki.poulose,
marc.zyngier, Paul Walmsley, linux-arm-kernel, Anup Patel,
linux-kernel, iommu, james.morse
In-Reply-To: <20190912140256.fwbutgmadpjbjnab@willie-the-truck>
On Thu, 12 Sep 2019 07:02:56 PDT (-0700), will@kernel.org wrote:
> On Sun, Sep 08, 2019 at 07:52:55AM +0800, Guo Ren wrote:
>> On Mon, Jun 24, 2019 at 6:40 PM Will Deacon <will@kernel.org> wrote:
>> > > I'll keep my system use the same ASID for SMP + IOMMU :P
>> >
>> > You will want a separate allocator for that:
>> >
>> > https://lkml.kernel.org/r/20190610184714.6786-2-jean-philippe.brucker@arm.com
>>
>> Yes, it is hard to maintain ASID between IOMMU and CPUMMU or different
>> system, because it's difficult to synchronize the IO_ASID when the CPU
>> ASID is rollover.
>> But we could still use hardware broadcast TLB invalidation instruction
>> to uniformly manage the ASID and IO_ASID, or OTHER_ASID in our IOMMU.
>
> That's probably a bad idea, because you'll likely stall execution on the
> CPU until the IOTLB has completed invalidation. In the case of ATS, I think
> an endpoint ATC is permitted to take over a minute to respond. In reality, I
> suspect the worst you'll ever see would be in the msec range, but that's
> still an unacceptable period of time to hold a CPU.
>
>> Welcome to join our disscusion:
>> "Introduce an implementation of IOMMU in linux-riscv"
>> 9 Sep 2019, 10:45 Jade-room-I&II (Corinthia Hotel Lisbon) RISC-V MC
>
> I attended this session, but it unfortunately raised many more questions
> than it answered.
Ya, we're a long way from figuring this out.
_______________________________________________
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 0/6] ARM, arm64: Remove arm_pm_restart()
From: Guenter Roeck @ 2019-09-14 15:25 UTC (permalink / raw)
To: Thierry Reding; +Cc: linux-kernel, linux-arm-kernel
In-Reply-To: <20170130110512.6943-1-thierry.reding@gmail.com>
On Mon, Jan 30, 2017 at 12:05:06PM +0100, Thierry Reding wrote:
> From: Thierry Reding <treding@nvidia.com>
>
> Hi everyone,
>
> This small series is preparatory work for a series that I'm working on
> which attempts to establish a formal framework for system restart and
> power off.
>
> Guenter has done a lot of good work in this area, but it never got
> merged. I think this set is a valuable addition to the kernel because
> it converts all odd providers to the established mechanism for restart.
>
> Since this is stretched across both 32-bit and 64-bit ARM, as well as
> PSCI, and given the SoC/board level of functionality, I think it might
> make sense to take this through the ARM SoC tree in order to simplify
> the interdependencies. But it should also be possible to take patches
> 1-4 via their respective trees this cycle and patches 5-6 through the
> ARM and arm64 trees for the next cycle, if that's preferred.
>
We tried this twice now, and it seems to go nowhere. What does it take
to get it applied ?
Guenter
> Thanks,
> Thierry
>
> Guenter Roeck (6):
> ARM: prima2: Register with kernel restart handler
> ARM: xen: Register with kernel restart handler
> drivers: firmware: psci: Register with kernel restart handler
> ARM: Register with kernel restart handler
> ARM64: Remove arm_pm_restart()
> ARM: Remove arm_pm_restart()
>
> arch/arm/include/asm/system_misc.h | 1 -
> arch/arm/kernel/reboot.c | 6 +-----
> arch/arm/kernel/setup.c | 20 ++++++++++++++++++--
> arch/arm/mach-prima2/rstc.c | 11 +++++++++--
> arch/arm/xen/enlighten.c | 13 +++++++++++--
> arch/arm64/include/asm/system_misc.h | 2 --
> arch/arm64/kernel/process.c | 7 +------
> drivers/firmware/psci.c | 11 +++++++++--
> 8 files changed, 49 insertions(+), 22 deletions(-)
>
> --
> 2.11.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] arm64: dts: renesas: Add /soc dma-ranges
From: Marek Vasut @ 2019-09-14 15:50 UTC (permalink / raw)
To: Rob Herring
Cc: devicetree, Geert Uytterhoeven, Wolfram Sang,
open list:MEDIA DRIVERS FOR RENESAS - FCP,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Marek Vasut
In-Reply-To: <CAL_JsqL47dQT-P78j4Ph61fsgA45Ha0AJjDajiMk52yFj++s+g@mail.gmail.com>
On 9/13/19 5:14 PM, Rob Herring wrote:
> On Sat, Sep 7, 2019 at 5:16 PM <marek.vasut@gmail.com> wrote:
>>
>> From: Marek Vasut <marek.vasut+renesas@gmail.com>
>>
>> Add dma-ranges property into /soc node to describe the DMA capabilities
>> of the bus. This is currently needed to translate PCI DMA ranges, which
>> are limited to 32bit addresses.
>
> FYI, I've started working on this problem and issues around
> dma-ranges/dma_mask. Hopefully I'll get some patches out next week.
Thanks
>> ---
>> NOTE: This is needed for the following patches to work correctly:
>> https://patchwork.ozlabs.org/patch/1144870/
>> https://patchwork.ozlabs.org/patch/1144871/
>
> First I'm seeing those... Well, I do have v7 from 2+ years ago...
Right, this issue was dragging on for a very long time.
> Not sure if these take into account the new dma_bus_mask, but that
> should simplify solving the issue.
What's that about ?
>> ---
>> arch/arm64/boot/dts/renesas/r8a7795.dtsi | 1 +
>> arch/arm64/boot/dts/renesas/r8a7796.dtsi | 1 +
>> arch/arm64/boot/dts/renesas/r8a77965.dtsi | 1 +
>> 3 files changed, 3 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
>> index 95deff66eeb6..2102140a6723 100644
>> --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
>> +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
>> @@ -330,6 +330,7 @@
>> #address-cells = <2>;
>> #size-cells = <2>;
>> ranges;
>> + dma-ranges = <0 0x40000000 0 0x40000000 0 0xc0000000>;
>
> Is the limitation in the bus or the PCI bridge or both? The commit
> message sounds like it's the PCI bridge in which case this is wrong
> (or incomplete).
I believe it is the PCI bridge too.
> 'dma-ranges' should be on the bus node where the
> restriction/translation exists. For PCI devices, that's the PCI bridge
> node. So a 32-bit only PCI bridge should have a dma-ranges size of
> 4GB. If the SoC bus has more restrictions, then that should be in the
> PCI bridge parent assuming that restriction also applies to other
> devices.
Would that mean the dma-ranges for /soc/pcie@fe000000/ [1], which is
already present in the DTSi, is the one that should be used to determine
the controller limitations ?
[1]
https://elixir.bootlin.com/linux/v5.3-rc8/source/arch/arm64/boot/dts/renesas/r8a7795.dtsi#L2653
--
Best regards,
Marek Vasut
_______________________________________________
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 v5 2/2] drm/bridge: Add NWL MIPI DSI host controller support
From: Guido Günther @ 2019-09-14 16:11 UTC (permalink / raw)
To: Andrzej Hajda
Cc: Mark Rutland, devicetree, Jernej Skrabec, Pengutronix Kernel Team,
Sam Ravnborg, Neil Armstrong, David Airlie, Fabio Estevam,
Sascha Hauer, Jonas Karlman, linux-kernel, dri-devel, Rob Herring,
Arnd Bergmann, NXP Linux Team, Daniel Vetter, Robert Chiras,
Lee Jones, Shawn Guo, linux-arm-kernel, Laurent Pinchart
In-Reply-To: <d544c189-8428-d10e-a69b-5af9ce47a802@samsung.com>
Hi Andrzej,
thanks for having a look!
On Fri, Sep 13, 2019 at 11:31:43AM +0200, Andrzej Hajda wrote:
> On 09.09.2019 04:25, Guido Günther wrote:
> > This adds initial support for the NWL MIPI DSI Host controller found on
> > i.MX8 SoCs.
> >
> > It adds support for the i.MX8MQ but the same IP can be found on
> > e.g. the i.MX8QXP.
> >
> > It has been tested on the Librem 5 devkit using mxsfb.
> >
> > Signed-off-by: Guido Günther <agx@sigxcpu.org>
> > Co-developed-by: Robert Chiras <robert.chiras@nxp.com>
> > Signed-off-by: Robert Chiras <robert.chiras@nxp.com>
> > Tested-by: Robert Chiras <robert.chiras@nxp.com>
> > ---
> > drivers/gpu/drm/bridge/Kconfig | 2 +
> > drivers/gpu/drm/bridge/Makefile | 1 +
> > drivers/gpu/drm/bridge/nwl-dsi/Kconfig | 16 +
> > drivers/gpu/drm/bridge/nwl-dsi/Makefile | 4 +
> > drivers/gpu/drm/bridge/nwl-dsi/nwl-drv.c | 499 ++++++++++++++++
> > drivers/gpu/drm/bridge/nwl-dsi/nwl-drv.h | 65 +++
> > drivers/gpu/drm/bridge/nwl-dsi/nwl-dsi.c | 696 +++++++++++++++++++++++
> > drivers/gpu/drm/bridge/nwl-dsi/nwl-dsi.h | 112 ++++
>
>
> Why do you need separate files nwl-drv.[ch] and nwl-dsi.[ch] ? I guess
> you can merge all into one file, maybe with separate file for NWL
> register definitions.
Idea is to have driver setup, soc specific hooks and revision specific
quirks in one file and the dsi specific parts in another. If that
doesn't fly I can merge into one if that's a requirement.
> > 8 files changed, 1395 insertions(+)
> > create mode 100644 drivers/gpu/drm/bridge/nwl-dsi/Kconfig
> > create mode 100644 drivers/gpu/drm/bridge/nwl-dsi/Makefile
> > create mode 100644 drivers/gpu/drm/bridge/nwl-dsi/nwl-drv.c
> > create mode 100644 drivers/gpu/drm/bridge/nwl-dsi/nwl-drv.h
> > create mode 100644 drivers/gpu/drm/bridge/nwl-dsi/nwl-dsi.c
> > create mode 100644 drivers/gpu/drm/bridge/nwl-dsi/nwl-dsi.h
> >
> > diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> > index 1cc9f502c1f2..7980b5c2156f 100644
> > --- a/drivers/gpu/drm/bridge/Kconfig
> > +++ b/drivers/gpu/drm/bridge/Kconfig
> > @@ -154,6 +154,8 @@ source "drivers/gpu/drm/bridge/analogix/Kconfig"
> >
> > source "drivers/gpu/drm/bridge/adv7511/Kconfig"
> >
> > +source "drivers/gpu/drm/bridge/nwl-dsi/Kconfig"
> > +
> > source "drivers/gpu/drm/bridge/synopsys/Kconfig"
> >
> > endmenu
> > diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> > index 4934fcf5a6f8..d9f6c0f77592 100644
> > --- a/drivers/gpu/drm/bridge/Makefile
> > +++ b/drivers/gpu/drm/bridge/Makefile
> > @@ -16,4 +16,5 @@ obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
> > obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
> > obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o
> > obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
> > +obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-dsi/
> > obj-y += synopsys/
> > diff --git a/drivers/gpu/drm/bridge/nwl-dsi/Kconfig b/drivers/gpu/drm/bridge/nwl-dsi/Kconfig
> > new file mode 100644
> > index 000000000000..7fa678e3b5e2
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/nwl-dsi/Kconfig
> > @@ -0,0 +1,16 @@
> > +config DRM_NWL_MIPI_DSI
> > + tristate "Northwest Logic MIPI DSI Host controller"
> > + depends on DRM
> > + depends on COMMON_CLK
> > + depends on OF && HAS_IOMEM
> > + select DRM_KMS_HELPER
> > + select DRM_MIPI_DSI
> > + select DRM_PANEL_BRIDGE
> > + select GENERIC_PHY_MIPI_DPHY
> > + select MFD_SYSCON
> > + select MULTIPLEXER
> > + select REGMAP_MMIO
> > + help
> > + This enables the Northwest Logic MIPI DSI Host controller as
> > + for example found on NXP's i.MX8 Processors.
> > +
> > diff --git a/drivers/gpu/drm/bridge/nwl-dsi/Makefile b/drivers/gpu/drm/bridge/nwl-dsi/Makefile
> > new file mode 100644
> > index 000000000000..804baf2f1916
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/nwl-dsi/Makefile
> > @@ -0,0 +1,4 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +nwl-mipi-dsi-y := nwl-drv.o nwl-dsi.o
> > +obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-mipi-dsi.o
> > +header-test-y += nwl-drv.h nwl-dsi.h
> > diff --git a/drivers/gpu/drm/bridge/nwl-dsi/nwl-drv.c b/drivers/gpu/drm/bridge/nwl-dsi/nwl-drv.c
> > new file mode 100644
> > index 000000000000..9ff43d2de127
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/nwl-dsi/nwl-drv.c
> > @@ -0,0 +1,499 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * i.MX8 NWL MIPI DSI host driver
> > + *
> > + * Copyright (C) 2017 NXP
> > + * Copyright (C) 2019 Purism SPC
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/irq.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/module.h>
> > +#include <linux/mux/consumer.h>
> > +#include <linux/of.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/reset.h>
> > +#include <linux/regmap.h>
>
>
> Alphabetic order
Fixed for v6.
> > +#include <linux/sys_soc.h>
> > +
> > +#include <drm/drm_atomic_helper.h>
> > +#include <drm/drm_of.h>
> > +#include <drm/drm_print.h>
> > +#include <drm/drm_probe_helper.h>
> > +
> > +#include "nwl-drv.h"
> > +#include "nwl-dsi.h"
> > +
> > +#define DRV_NAME "nwl-dsi"
> > +
> > +/* Possible platform specific clocks */
> > +#define NWL_DSI_CLK_CORE "core"
> > +
> > +static const struct regmap_config nwl_dsi_regmap_config = {
> > + .reg_bits = 16,
> > + .val_bits = 32,
> > + .reg_stride = 4,
> > + .max_register = NWL_DSI_IRQ_MASK2,
> > + .name = DRV_NAME,
> > +};
>
>
> What is the point in using regmap here, why not simple writel/readl.
For me
cat /sys/kernel/debug/regmap/30a00000.mipi_dsi-imx-nwl-dsi/registers
justifies it's use to help debugging problems when e.g. having it
connected to panels I don't own, so I think it's worth keeping if
possible.
> > +
> > +struct nwl_dsi_platform_data {
> > + int (*poweron)(struct nwl_dsi *dsi);
> > + int (*poweroff)(struct nwl_dsi *dsi);
> > + int (*select_input)(struct nwl_dsi *dsi);
> > + int (*deselect_input)(struct nwl_dsi *dsi);
> > + struct nwl_dsi_plat_clk_config clk_config[NWL_DSI_MAX_PLATFORM_CLOCKS];
> > +};
>
>
> Another construct which do not have justification, at least for now.
> Please simplify the driver, remove callbacks/intermediate
> structs/quirks
>
> - for now they are useless.
>
> Unless there is a serious reason - in such case please describe it in
> comments.
They're needed for i.mx 8QM SoC support (the current driver only
supports the i.mx 8MQ). It will be relatively easy to add with
these so I expect these to show up quickly. I'll add a comment.
The quirks on the other hand only apply to some i.mx8MQ mask revisions
so they need to be conditionalized. (or maybe I misunderstood you).
> > +
> > +static inline struct nwl_dsi *bridge_to_dsi(struct drm_bridge *bridge)
> > +{
> > + return container_of(bridge, struct nwl_dsi, bridge);
> > +}
> > +
> > +static int nwl_dsi_set_platform_clocks(struct nwl_dsi *dsi, bool enable)
> > +{
> > + struct device *dev = dsi->dev;
> > + const char *id;
> > + struct clk *clk;
> > + size_t i;
> > + unsigned long rate;
> > + int ret, result = 0;
> > +
> > + DRM_DEV_DEBUG_DRIVER(dev, "%s platform clocks\n",
> > + enable ? "enabling" : "disabling");
> > + for (i = 0; i < ARRAY_SIZE(dsi->pdata->clk_config); i++) {
> > + if (!dsi->clk_config[i].present)
> > + continue;
> > + id = dsi->clk_config[i].id;
> > + clk = dsi->clk_config[i].clk;
> > +
> > + if (enable) {
> > + ret = clk_prepare_enable(clk);
> > + if (ret < 0) {
> > + DRM_DEV_ERROR(dev,
> > + "Failed to enable %s clk: %d\n",
> > + id, ret);
> > + result = result ?: ret;
> > + }
> > + rate = clk_get_rate(clk);
> > + DRM_DEV_DEBUG_DRIVER(dev, "Enabled %s clk @%lu Hz\n",
> > + id, rate);
> > + } else {
> > + clk_disable_unprepare(clk);
> > + DRM_DEV_DEBUG_DRIVER(dev, "Disabled %s clk\n", id);
> > + }
> > + }
> > +
> > + return result;
> > +}
> > +
> > +static int nwl_dsi_plat_enable(struct nwl_dsi *dsi)
> > +{
> > + struct device *dev = dsi->dev;
> > + int ret;
> > +
> > + if (dsi->pdata->select_input)
> > + dsi->pdata->select_input(dsi);
> > +
> > + ret = nwl_dsi_set_platform_clocks(dsi, true);
> > + if (ret < 0)
> > + return ret;
> > +
> > + ret = dsi->pdata->poweron(dsi);
> > + if (ret < 0)
> > + DRM_DEV_ERROR(dev, "Failed to power on DSI: %d\n", ret);
> > + return ret;
> > +}
> > +
> > +static void nwl_dsi_plat_disable(struct nwl_dsi *dsi)
> > +{
> > + dsi->pdata->poweroff(dsi);
> > + nwl_dsi_set_platform_clocks(dsi, false);
> > + if (dsi->pdata->deselect_input)
> > + dsi->pdata->deselect_input(dsi);
> > +}
> > +
> > +static void nwl_dsi_bridge_disable(struct drm_bridge *bridge)
> > +{
> > + struct nwl_dsi *dsi = bridge_to_dsi(bridge);
> > +
> > + nwl_dsi_disable(dsi);
> > + nwl_dsi_plat_disable(dsi);
> > + pm_runtime_put(dsi->dev);
> > +}
> > +
> > +static int nwl_dsi_get_dphy_params(struct nwl_dsi *dsi,
> > + const struct drm_display_mode *mode,
> > + union phy_configure_opts *phy_opts)
> > +{
> > + unsigned long rate;
> > + int ret;
> > +
> > + if (dsi->lanes < 1 || dsi->lanes > 4)
> > + return -EINVAL;
> > +
> > + /*
> > + * So far the DPHY spec minimal timings work for both mixel
> > + * dphy and nwl dsi host
> > + */
> > + ret = phy_mipi_dphy_get_default_config(
> > + mode->crtc_clock * 1000,
> > + mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes,
> > + &phy_opts->mipi_dphy);
> > + if (ret < 0)
> > + return ret;
> > +
> > + rate = clk_get_rate(dsi->tx_esc_clk);
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "LP clk is @%lu Hz\n", rate);
> > + phy_opts->mipi_dphy.lp_clk_rate = rate;
> > +
> > + return 0;
> > +}
> > +
> > +static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
> > + const struct drm_display_mode *mode,
> > + struct drm_display_mode *adjusted_mode)
> > +{
> > + /* At least LCDIF + NWL needs active high sync */
> > + adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
> > + adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
> > +
> > + return true;
> > +}
> > +
> > +static enum drm_mode_status
> > +nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge,
> > + const struct drm_display_mode *mode)
> > +{
> > + struct nwl_dsi *dsi = bridge_to_dsi(bridge);
> > + int bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> > +
> > + if (mode->clock * bpp > 15000000 * dsi->lanes)
> > + return MODE_CLOCK_HIGH;
> > +
> > + if (mode->clock * bpp < 80000 * dsi->lanes)
> > + return MODE_CLOCK_LOW;
> > +
> > + return MODE_OK;
> > +}
> > +
> > +static void
> > +nwl_dsi_bridge_mode_set(struct drm_bridge *bridge,
> > + const struct drm_display_mode *mode,
> > + const struct drm_display_mode *adjusted_mode)
> > +{
> > + struct nwl_dsi *dsi = bridge_to_dsi(bridge);
> > + struct device *dev = dsi->dev;
> > + union phy_configure_opts new_cfg;
> > + unsigned long phy_ref_rate;
> > + int ret;
> > +
> > + ret = nwl_dsi_get_dphy_params(dsi, adjusted_mode, &new_cfg);
> > + if (ret < 0)
> > + return;
> > +
> > + /*
> > + * If hs clock is unchanged, we're all good - all parameters are
> > + * derived from it atm.
> > + */
> > + if (new_cfg.mipi_dphy.hs_clk_rate == dsi->phy_cfg.mipi_dphy.hs_clk_rate)
> > + return;
> > +
> > + phy_ref_rate = clk_get_rate(dsi->phy_ref_clk);
> > + DRM_DEV_DEBUG_DRIVER(dev, "PHY at ref rate: %lu\n", phy_ref_rate);
> > + /* Save the new desired phy config */
> > + memcpy(&dsi->phy_cfg, &new_cfg, sizeof(new_cfg));
> > +
> > + memcpy(&dsi->mode, adjusted_mode, sizeof(dsi->mode));
> > + drm_mode_debug_printmodeline(adjusted_mode);
> > +}
> > +
> > +static void nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge)
> > +{
> > + struct nwl_dsi *dsi = bridge_to_dsi(bridge);
> > +
> > + pm_runtime_get_sync(dsi->dev);
> > + nwl_dsi_plat_enable(dsi);
> > + nwl_dsi_enable(dsi);
> > +}
> > +
> > +static int nwl_dsi_bridge_attach(struct drm_bridge *bridge)
> > +{
> > + struct nwl_dsi *dsi = bridge->driver_private;
> > +
> > + return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge);
> > +}
> > +
> > +static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = {
> > + .pre_enable = nwl_dsi_bridge_pre_enable,
> > + .disable = nwl_dsi_bridge_disable,
> > + .mode_fixup = nwl_dsi_bridge_mode_fixup,
> > + .mode_set = nwl_dsi_bridge_mode_set,
> > + .mode_valid = nwl_dsi_bridge_mode_valid,
> > + .attach = nwl_dsi_bridge_attach,
> > +};
> > +
> > +static int nwl_dsi_parse_dt(struct nwl_dsi *dsi)
> > +{
> > + struct platform_device *pdev = to_platform_device(dsi->dev);
> > + struct clk *clk;
> > + const char *clk_id;
> > + void __iomem *base;
> > + int i, ret;
> > +
> > + dsi->phy = devm_phy_get(dsi->dev, "dphy");
> > + if (IS_ERR(dsi->phy)) {
> > + ret = PTR_ERR(dsi->phy);
> > + if (ret != -EPROBE_DEFER)
> > + DRM_DEV_ERROR(dsi->dev, "Could not get PHY: %d\n", ret);
> > + return ret;
> > + }
> > +
> > + /* Platform dependent clocks */
> > + memcpy(dsi->clk_config, dsi->pdata->clk_config,
> > + sizeof(dsi->pdata->clk_config));
> > +
> > + for (i = 0; i < ARRAY_SIZE(dsi->pdata->clk_config); i++) {
> > + if (!dsi->clk_config[i].present)
> > + continue;
> > +
> > + clk_id = dsi->clk_config[i].id;
> > + clk = devm_clk_get(dsi->dev, clk_id);
> > + if (IS_ERR(clk)) {
> > + ret = PTR_ERR(clk);
> > + DRM_DEV_ERROR(dsi->dev, "Failed to get %s clock: %d\n",
> > + clk_id, ret);
> > + return ret;
> > + }
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "Setup clk %s (rate: %lu)\n",
> > + clk_id, clk_get_rate(clk));
> > + dsi->clk_config[i].clk = clk;
> > + }
> > +
> > + /* DSI clocks */
> > + clk = devm_clk_get(dsi->dev, "phy_ref");
> > + if (IS_ERR(clk)) {
> > + ret = PTR_ERR(clk);
> > + DRM_DEV_ERROR(dsi->dev, "Failed to get phy_ref clock: %d\n",
> > + ret);
> > + return ret;
> > + }
> > + dsi->phy_ref_clk = clk;
> > +
> > + clk = devm_clk_get(dsi->dev, "rx_esc");
> > + if (IS_ERR(clk)) {
> > + ret = PTR_ERR(clk);
> > + DRM_DEV_ERROR(dsi->dev, "Failed to get rx_esc clock: %d\n",
> > + ret);
> > + return ret;
> > + }
> > + dsi->rx_esc_clk = clk;
> > +
> > + clk = devm_clk_get(dsi->dev, "tx_esc");
> > + if (IS_ERR(clk)) {
> > + ret = PTR_ERR(clk);
> > + DRM_DEV_ERROR(dsi->dev, "Failed to get tx_esc clock: %d\n",
> > + ret);
> > + return ret;
> > + }
> > + dsi->tx_esc_clk = clk;
> > +
> > + dsi->mux = devm_mux_control_get(dsi->dev, NULL);
> > + if (IS_ERR(dsi->mux)) {
> > + ret = PTR_ERR(dsi->mux);
> > + if (ret != -EPROBE_DEFER)
> > + DRM_DEV_ERROR(dsi->dev, "Failed to get mux: %d\n", ret);
> > + return ret;
> > + }
> > +
> > + base = devm_platform_ioremap_resource(pdev, 0);
> > + if (IS_ERR(base))
> > + return PTR_ERR(base);
> > +
> > + dsi->regmap =
> > + devm_regmap_init_mmio(dsi->dev, base, &nwl_dsi_regmap_config);
> > + if (IS_ERR(dsi->regmap)) {
> > + ret = PTR_ERR(dsi->regmap);
> > + DRM_DEV_ERROR(dsi->dev, "Failed to create NWL DSI regmap: %d\n",
> > + ret);
> > + return ret;
> > + }
> > +
> > + dsi->irq = platform_get_irq(pdev, 0);
> > + if (dsi->irq < 0) {
> > + DRM_DEV_ERROR(dsi->dev, "Failed to get device IRQ: %d\n",
> > + dsi->irq);
> > + return dsi->irq;
> > + }
> > +
> > + dsi->rstc = devm_reset_control_array_get(dsi->dev, false, true);
> > + if (IS_ERR(dsi->rstc)) {
> > + DRM_DEV_ERROR(dsi->dev, "Failed to get resets: %ld\n",
> > + PTR_ERR(dsi->rstc));
> > + return PTR_ERR(dsi->rstc);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int imx8mq_dsi_select_input(struct nwl_dsi *dsi)
> > +{
> > + struct device_node *remote;
> > + u32 use_dcss = 1;
> > + int ret;
> > +
> > + remote = of_graph_get_remote_node(dsi->dev->of_node, 0, 0);
> > + if (strcmp(remote->name, "lcdif") == 0)
> > + use_dcss = 0;
>
>
> Relying on node name seems to me wrong. I am not sure if whole logic for
> input select should be here.
>
> My 1st impression is that selecting should be done rather in DCSS or
> LCDIF driver, why do you want to put it here?
Doing it in here keeps it at a single location where on the other hand
it would need to be done in mxsfb (which handles other SoCs as well) and
upcoming dcss. Also we can have in the dsi enable path which e.g. mxsfb
doesn't even know about at this point.
Cheers,
-- Guido
>
> Regards
>
> Andrzej
>
>
> > +
> > + DRM_DEV_INFO(dsi->dev, "Using %s as input source\n",
> > + (use_dcss) ? "DCSS" : "LCDIF");
> > +
> > + ret = mux_control_try_select(dsi->mux, use_dcss);
> > + if (ret < 0)
> > + DRM_DEV_ERROR(dsi->dev, "Failed to select input: %d\n", ret);
> > +
> > + of_node_put(remote);
> > + return ret;
> > +}
> > +
> > +
> > +static int imx8mq_dsi_deselect_input(struct nwl_dsi *dsi)
> > +{
> > + int ret;
> > +
> > + ret = mux_control_deselect(dsi->mux);
> > + if (ret < 0)
> > + DRM_DEV_ERROR(dsi->dev, "Failed to deselect input: %d\n", ret);
> > +
> > + return ret;
> > +}
> > +
> > +
> > +static int imx8mq_dsi_poweron(struct nwl_dsi *dsi)
> > +{
> > + int ret = 0;
> > +
> > + /* otherwise the display stays blank */
> > + usleep_range(200, 300);
> > +
> > + if (dsi->rstc)
> > + ret = reset_control_deassert(dsi->rstc);
> > +
> > + return ret;
> > +}
> > +
> > +static int imx8mq_dsi_poweroff(struct nwl_dsi *dsi)
> > +{
> > + int ret = 0;
> > +
> > + if (dsi->quirks & SRC_RESET_QUIRK)
> > + return 0;
> > +
> > + if (dsi->rstc)
> > + ret = reset_control_assert(dsi->rstc);
> > + return ret;
> > +}
> > +
> > +static const struct drm_bridge_timings nwl_dsi_timings = {
> > + .input_bus_flags = DRM_BUS_FLAG_DE_LOW,
> > +};
> > +
> > +static const struct nwl_dsi_platform_data imx8mq_dev = {
> > + .poweron = &imx8mq_dsi_poweron,
> > + .poweroff = &imx8mq_dsi_poweroff,
> > + .select_input = &imx8mq_dsi_select_input,
> > + .deselect_input = &imx8mq_dsi_deselect_input,
> > + .clk_config = {
> > + { .id = NWL_DSI_CLK_CORE, .present = true },
> > + },
> > +};
> > +
> > +static const struct of_device_id nwl_dsi_dt_ids[] = {
> > + { .compatible = "fsl,imx8mq-nwl-dsi", .data = &imx8mq_dev, },
> > + { /* sentinel */ }
> > +};
> > +MODULE_DEVICE_TABLE(of, nwl_dsi_dt_ids);
> > +
> > +static const struct soc_device_attribute nwl_dsi_quirks_match[] = {
> > + { .soc_id = "i.MX8MQ", .revision = "2.0",
> > + .data = (void *)(E11418_HS_MODE_QUIRK | SRC_RESET_QUIRK) },
> > + { /* sentinel. */ },
> > +};
> > +
> > +static int nwl_dsi_probe(struct platform_device *pdev)
> > +{
> > + struct device *dev = &pdev->dev;
> > + const struct of_device_id *of_id = of_match_device(nwl_dsi_dt_ids, dev);
> > + const struct nwl_dsi_platform_data *pdata = of_id->data;
> > + const struct soc_device_attribute *attr;
> > + struct nwl_dsi *dsi;
> > + int ret;
> > +
> > + dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
> > + if (!dsi)
> > + return -ENOMEM;
> > +
> > + dsi->dev = dev;
> > + dsi->pdata = pdata;
> > +
> > + ret = nwl_dsi_parse_dt(dsi);
> > + if (ret)
> > + return ret;
> > +
> > + ret = devm_request_irq(dev, dsi->irq, nwl_dsi_irq_handler, 0,
> > + dev_name(dev), dsi);
> > + if (ret < 0) {
> > + DRM_DEV_ERROR(dev, "Failed to request IRQ %d: %d\n", dsi->irq,
> > + ret);
> > + return ret;
> > + }
> > +
> > + dsi->dsi_host.ops = &nwl_dsi_host_ops;
> > + dsi->dsi_host.dev = dev;
> > + ret = mipi_dsi_host_register(&dsi->dsi_host);
> > + if (ret) {
> > + DRM_DEV_ERROR(dev, "Failed to register MIPI host: %d\n", ret);
> > + return ret;
> > + }
> > +
> > + attr = soc_device_match(nwl_dsi_quirks_match);
> > + if (attr)
> > + dsi->quirks = (uintptr_t)attr->data;
> > +
> > + dsi->bridge.driver_private = dsi;
> > + dsi->bridge.funcs = &nwl_dsi_bridge_funcs;
> > + dsi->bridge.of_node = dev->of_node;
> > + dsi->bridge.timings = &nwl_dsi_timings;
> > +
> > + dev_set_drvdata(dev, dsi);
> > + pm_runtime_enable(dev);
> > + return 0;
> > +}
> > +
> > +static int nwl_dsi_remove(struct platform_device *pdev)
> > +{
> > + struct nwl_dsi *dsi = platform_get_drvdata(pdev);
> > +
> > + mipi_dsi_host_unregister(&dsi->dsi_host);
> > + pm_runtime_disable(&pdev->dev);
> > + return 0;
> > +}
> > +
> > +static struct platform_driver nwl_dsi_driver = {
> > + .probe = nwl_dsi_probe,
> > + .remove = nwl_dsi_remove,
> > + .driver = {
> > + .of_match_table = nwl_dsi_dt_ids,
> > + .name = DRV_NAME,
> > + },
> > +};
> > +
> > +module_platform_driver(nwl_dsi_driver);
> > +
> > +MODULE_AUTHOR("NXP Semiconductor");
> > +MODULE_AUTHOR("Purism SPC");
> > +MODULE_DESCRIPTION("Northwest Logic MIPI-DSI driver");
> > +MODULE_LICENSE("GPL"); /* GPLv2 or later */
> > diff --git a/drivers/gpu/drm/bridge/nwl-dsi/nwl-drv.h b/drivers/gpu/drm/bridge/nwl-dsi/nwl-drv.h
> > new file mode 100644
> > index 000000000000..1e72a9221401
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/nwl-dsi/nwl-drv.h
> > @@ -0,0 +1,65 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/*
> > + * NWL MIPI DSI host driver
> > + *
> > + * Copyright (C) 2017 NXP
> > + * Copyright (C) 2019 Purism SPC
> > + */
> > +
> > +#ifndef __NWL_DRV_H__
> > +#define __NWL_DRV_H__
> > +
> > +#include <linux/mux/consumer.h>
> > +#include <linux/phy/phy.h>
> > +
> > +#include <drm/drm_bridge.h>
> > +#include <drm/drm_mipi_dsi.h>
> > +
> > +struct nwl_dsi_platform_data;
> > +
> > +/* i.MX8 NWL quirks */
> > +/* i.MX8MQ errata E11418 */
> > +#define E11418_HS_MODE_QUIRK BIT(0)
> > +/* Skip DSI bits in SRC on disable to avoid blank display on enable */
> > +#define SRC_RESET_QUIRK BIT(1)
> > +
> > +#define NWL_DSI_MAX_PLATFORM_CLOCKS 1
> > +struct nwl_dsi_plat_clk_config {
> > + const char *id;
> > + struct clk *clk;
> > + bool present;
> > +};
> > +
> > +struct nwl_dsi {
> > + struct drm_bridge bridge;
> > + struct mipi_dsi_host dsi_host;
> > + struct drm_bridge *panel_bridge;
> > + struct device *dev;
> > + struct phy *phy;
> > + union phy_configure_opts phy_cfg;
> > + unsigned int quirks;
> > +
> > + struct regmap *regmap;
> > + int irq;
> > + struct reset_control *rstc;
> > + struct mux_control *mux;
> > +
> > + /* DSI clocks */
> > + struct clk *phy_ref_clk;
> > + struct clk *rx_esc_clk;
> > + struct clk *tx_esc_clk;
> > + /* Platform dependent clocks */
> > + struct nwl_dsi_plat_clk_config clk_config[NWL_DSI_MAX_PLATFORM_CLOCKS];
> > +
> > + /* dsi lanes */
> > + u32 lanes;
> > + enum mipi_dsi_pixel_format format;
> > + struct drm_display_mode mode;
> > + unsigned long dsi_mode_flags;
> > +
> > + struct nwl_dsi_transfer *xfer;
> > +
> > + const struct nwl_dsi_platform_data *pdata;
> > +};
> > +
> > +#endif /* __NWL_DRV_H__ */
> > diff --git a/drivers/gpu/drm/bridge/nwl-dsi/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi/nwl-dsi.c
> > new file mode 100644
> > index 000000000000..e6038cb4e849
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/nwl-dsi/nwl-dsi.c
> > @@ -0,0 +1,696 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * NWL MIPI DSI host driver
> > + *
> > + * Copyright (C) 2017 NXP
> > + * Copyright (C) 2019 Purism SPC
> > + */
> > +
> > +#include <linux/bitfield.h>
> > +#include <linux/clk.h>
> > +#include <linux/irq.h>
> > +#include <linux/math64.h>
> > +#include <linux/regmap.h>
> > +#include <linux/time64.h>
> > +
> > +#include <video/mipi_display.h>
> > +#include <video/videomode.h>
> > +
> > +#include <drm/drm_atomic_helper.h>
> > +#include <drm/drm_crtc_helper.h>
> > +#include <drm/drm_of.h>
> > +#include <drm/drm_panel.h>
> > +#include <drm/drm_print.h>
> > +
> > +#include "nwl-drv.h"
> > +#include "nwl-dsi.h"
> > +
> > +#define NWL_DSI_MIPI_FIFO_TIMEOUT msecs_to_jiffies(500)
> > +
> > +/*
> > + * PKT_CONTROL format:
> > + * [15: 0] - word count
> > + * [17:16] - virtual channel
> > + * [23:18] - data type
> > + * [24] - LP or HS select (0 - LP, 1 - HS)
> > + * [25] - perform BTA after packet is sent
> > + * [26] - perform BTA only, no packet tx
> > + */
> > +#define NWL_DSI_WC(x) FIELD_PREP(GENMASK(15, 0), (x))
> > +#define NWL_DSI_TX_VC(x) FIELD_PREP(GENMASK(17, 16), (x))
> > +#define NWL_DSI_TX_DT(x) FIELD_PREP(GENMASK(23, 18), (x))
> > +#define NWL_DSI_HS_SEL(x) FIELD_PREP(GENMASK(24, 24), (x))
> > +#define NWL_DSI_BTA_TX(x) FIELD_PREP(GENMASK(25, 25), (x))
> > +#define NWL_DSI_BTA_NO_TX(x) FIELD_PREP(GENMASK(26, 26), (x))
> > +
> > +/*
> > + * RX_PKT_HEADER format:
> > + * [15: 0] - word count
> > + * [21:16] - data type
> > + * [23:22] - virtual channel
> > + */
> > +#define NWL_DSI_RX_DT(x) FIELD_GET(GENMASK(21, 16), (x))
> > +#define NWL_DSI_RX_VC(x) FIELD_GET(GENMASK(23, 22), (x))
> > +
> > +/* DSI Video mode */
> > +#define NWL_DSI_VM_BURST_MODE_WITH_SYNC_PULSES 0
> > +#define NWL_DSI_VM_NON_BURST_MODE_WITH_SYNC_EVENTS BIT(0)
> > +#define NWL_DSI_VM_BURST_MODE BIT(1)
> > +
> > +/* * DPI color coding */
> > +#define NWL_DSI_DPI_16_BIT_565_PACKED 0
> > +#define NWL_DSI_DPI_16_BIT_565_ALIGNED 1
> > +#define NWL_DSI_DPI_16_BIT_565_SHIFTED 2
> > +#define NWL_DSI_DPI_18_BIT_PACKED 3
> > +#define NWL_DSI_DPI_18_BIT_ALIGNED 4
> > +#define NWL_DSI_DPI_24_BIT 5
> > +
> > +/* * DPI Pixel format */
> > +#define NWL_DSI_PIXEL_FORMAT_16 0
> > +#define NWL_DSI_PIXEL_FORMAT_18 BIT(0)
> > +#define NWL_DSI_PIXEL_FORMAT_18L BIT(1)
> > +#define NWL_DSI_PIXEL_FORMAT_24 (BIT(0) | BIT(1))
> > +
> > +enum transfer_direction {
> > + DSI_PACKET_SEND,
> > + DSI_PACKET_RECEIVE,
> > +};
> > +
> > +struct nwl_dsi_transfer {
> > + const struct mipi_dsi_msg *msg;
> > + struct mipi_dsi_packet packet;
> > + struct completion completed;
> > +
> > + int status; /* status of transmission */
> > + enum transfer_direction direction;
> > + bool need_bta;
> > + u8 cmd;
> > + u16 rx_word_count;
> > + size_t tx_len; /* in bytes */
> > + size_t rx_len; /* in bytes */
> > +};
> > +
> > +static int nwl_dsi_write(struct nwl_dsi *dsi, unsigned int reg, u32 val)
> > +{
> > + int ret;
> > +
> > + ret = regmap_write(dsi->regmap, reg, val);
> > + if (ret < 0)
> > + DRM_DEV_ERROR(dsi->dev,
> > + "Failed to write NWL DSI reg 0x%x: %d\n", reg,
> > + ret);
> > + return ret;
> > +}
> > +
> > +static u32 nwl_dsi_read(struct nwl_dsi *dsi, u32 reg)
> > +{
> > + unsigned int val;
> > + int ret;
> > +
> > + ret = regmap_read(dsi->regmap, reg, &val);
> > + if (ret < 0)
> > + DRM_DEV_ERROR(dsi->dev, "Failed to read NWL DSI reg 0x%x: %d\n",
> > + reg, ret);
> > +
> > + return val;
> > +}
> > +
> > +static u32 nwl_dsi_get_dpi_pixel_format(enum mipi_dsi_pixel_format format)
> > +{
> > + switch (format) {
> > + case MIPI_DSI_FMT_RGB565:
> > + return NWL_DSI_PIXEL_FORMAT_16;
> > + case MIPI_DSI_FMT_RGB666:
> > + return NWL_DSI_PIXEL_FORMAT_18L;
> > + case MIPI_DSI_FMT_RGB666_PACKED:
> > + return NWL_DSI_PIXEL_FORMAT_18;
> > + case MIPI_DSI_FMT_RGB888:
> > + return NWL_DSI_PIXEL_FORMAT_24;
> > + default:
> > + return -EINVAL;
> > + }
> > +}
> > +
> > +/*
> > + * ps2bc - Picoseconds to byte clock cycles
> > + */
> > +static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
> > +{
> > + u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> > +
> > + return DIV64_U64_ROUND_UP(ps * dsi->mode.clock * bpp,
> > + dsi->lanes * 8 * NSEC_PER_SEC);
> > +}
> > +
> > +/*
> > + * ui2bc - UI time periods to byte clock cycles
> > + */
> > +static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
> > +{
> > + u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> > +
> > + return DIV64_U64_ROUND_UP(ui * dsi->lanes,
> > + dsi->mode.clock * 1000 * bpp);
> > +}
> > +
> > +/*
> > + * us2bc - micro seconds to lp clock cycles
> > + */
> > +static u32 us2lp(u32 lp_clk_rate, unsigned long us)
> > +{
> > + return DIV_ROUND_UP(us * lp_clk_rate, USEC_PER_SEC);
> > +}
> > +
> > +static int nwl_dsi_config_host(struct nwl_dsi *dsi)
> > +{
> > + u32 cycles;
> > + struct phy_configure_opts_mipi_dphy *cfg = &dsi->phy_cfg.mipi_dphy;
> > +
> > + if (dsi->lanes < 1 || dsi->lanes > 4)
> > + return -EINVAL;
> > +
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "DSI Lanes %d\n", dsi->lanes);
> > + nwl_dsi_write(dsi, NWL_DSI_CFG_NUM_LANES, dsi->lanes - 1);
> > +
> > + if (dsi->dsi_mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
> > + nwl_dsi_write(dsi, NWL_DSI_CFG_NONCONTINUOUS_CLK, 0x01);
> > + nwl_dsi_write(dsi, NWL_DSI_CFG_AUTOINSERT_EOTP, 0x01);
> > + } else {
> > + nwl_dsi_write(dsi, NWL_DSI_CFG_NONCONTINUOUS_CLK, 0x00);
> > + nwl_dsi_write(dsi, NWL_DSI_CFG_AUTOINSERT_EOTP, 0x00);
> > + }
> > +
> > + /* values in byte clock cycles */
> > + cycles = ui2bc(dsi, cfg->clk_pre);
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
> > + nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
> > + cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
> > + cycles += ui2bc(dsi, cfg->clk_pre);
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
> > + nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
> > + cycles = ps2bc(dsi, cfg->hs_exit);
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap: 0x%x\n", cycles);
> > + nwl_dsi_write(dsi, NWL_DSI_CFG_TX_GAP, cycles);
> > +
> > + nwl_dsi_write(dsi, NWL_DSI_CFG_EXTRA_CMDS_AFTER_EOTP, 0x01);
> > + nwl_dsi_write(dsi, NWL_DSI_CFG_HTX_TO_COUNT, 0x00);
> > + nwl_dsi_write(dsi, NWL_DSI_CFG_LRX_H_TO_COUNT, 0x00);
> > + nwl_dsi_write(dsi, NWL_DSI_CFG_BTA_H_TO_COUNT, 0x00);
> > + /* In LP clock cycles */
> > + cycles = us2lp(cfg->lp_clk_rate, cfg->wakeup);
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_twakeup: 0x%x\n", cycles);
> > + nwl_dsi_write(dsi, NWL_DSI_CFG_TWAKEUP, cycles);
> > +
> > + return 0;
> > +}
> > +
> > +static int nwl_dsi_config_dpi(struct nwl_dsi *dsi)
> > +{
> > + u32 color_format, mode;
> > + bool burst_mode;
> > + int hfront_porch, hback_porch, vfront_porch, vback_porch;
> > + int hsync_len, vsync_len;
> > +
> > + hfront_porch = dsi->mode.hsync_start - dsi->mode.hdisplay;
> > + hsync_len = dsi->mode.hsync_end - dsi->mode.hsync_start;
> > + hback_porch = dsi->mode.htotal - dsi->mode.hsync_end;
> > +
> > + vfront_porch = dsi->mode.vsync_start - dsi->mode.vdisplay;
> > + vsync_len = dsi->mode.vsync_end - dsi->mode.vsync_start;
> > + vback_porch = dsi->mode.vtotal - dsi->mode.vsync_end;
> > +
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "hfront_porch = %d\n", hfront_porch);
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "hback_porch = %d\n", hback_porch);
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "hsync_len = %d\n", hsync_len);
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "hdisplay = %d\n", dsi->mode.hdisplay);
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "vfront_porch = %d\n", vfront_porch);
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "vback_porch = %d\n", vback_porch);
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "vsync_len = %d\n", vsync_len);
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "vactive = %d\n", dsi->mode.vdisplay);
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "clock = %d kHz\n", dsi->mode.clock);
> > +
> > + color_format = nwl_dsi_get_dpi_pixel_format(dsi->format);
> > + if (color_format < 0) {
> > + DRM_DEV_ERROR(dsi->dev, "Invalid color format 0x%x\n",
> > + dsi->format);
> > + return color_format;
> > + }
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "pixel fmt = %d\n", dsi->format);
> > +
> > + nwl_dsi_write(dsi, NWL_DSI_INTERFACE_COLOR_CODING, NWL_DSI_DPI_24_BIT);
> > + nwl_dsi_write(dsi, NWL_DSI_PIXEL_FORMAT, color_format);
> > + /*
> > + * Adjusting input polarity based on the video mode results in
> > + * a black screen so always pick active low:
> > + */
> > + nwl_dsi_write(dsi, NWL_DSI_VSYNC_POLARITY,
> > + NWL_DSI_VSYNC_POLARITY_ACTIVE_LOW);
> > + nwl_dsi_write(dsi, NWL_DSI_HSYNC_POLARITY,
> > + NWL_DSI_HSYNC_POLARITY_ACTIVE_LOW);
> > +
> > + burst_mode = (dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_BURST) &&
> > + !(dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE);
> > +
> > + if (burst_mode) {
> > + nwl_dsi_write(dsi, NWL_DSI_VIDEO_MODE, NWL_DSI_VM_BURST_MODE);
> > + nwl_dsi_write(dsi, NWL_DSI_PIXEL_FIFO_SEND_LEVEL, 256);
> > + } else {
> > + mode = ((dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) ?
> > + NWL_DSI_VM_BURST_MODE_WITH_SYNC_PULSES :
> > + NWL_DSI_VM_NON_BURST_MODE_WITH_SYNC_EVENTS);
> > + nwl_dsi_write(dsi, NWL_DSI_VIDEO_MODE, mode);
> > + nwl_dsi_write(dsi, NWL_DSI_PIXEL_FIFO_SEND_LEVEL,
> > + dsi->mode.hdisplay);
> > + }
> > +
> > + nwl_dsi_write(dsi, NWL_DSI_HFP, hfront_porch);
> > + nwl_dsi_write(dsi, NWL_DSI_HBP, hback_porch);
> > + nwl_dsi_write(dsi, NWL_DSI_HSA, hsync_len);
> > +
> > + nwl_dsi_write(dsi, NWL_DSI_ENABLE_MULT_PKTS, 0x0);
> > + nwl_dsi_write(dsi, NWL_DSI_BLLP_MODE, 0x1);
> > + nwl_dsi_write(dsi, NWL_DSI_USE_NULL_PKT_BLLP, 0x0);
> > + nwl_dsi_write(dsi, NWL_DSI_VC, 0x0);
> > +
> > + nwl_dsi_write(dsi, NWL_DSI_PIXEL_PAYLOAD_SIZE, dsi->mode.hdisplay);
> > + nwl_dsi_write(dsi, NWL_DSI_VACTIVE, dsi->mode.vdisplay - 1);
> > + nwl_dsi_write(dsi, NWL_DSI_VBP, vback_porch);
> > + nwl_dsi_write(dsi, NWL_DSI_VFP, vfront_porch);
> > +
> > + return 0;
> > +}
> > +
> > +static void nwl_dsi_init_interrupts(struct nwl_dsi *dsi)
> > +{
> > + u32 irq_enable;
> > +
> > + nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK, 0xffffffff);
> > + nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK2, 0x7);
> > +
> > + irq_enable = ~(u32)(NWL_DSI_TX_PKT_DONE_MASK |
> > + NWL_DSI_RX_PKT_HDR_RCVD_MASK |
> > + NWL_DSI_TX_FIFO_OVFLW_MASK |
> > + NWL_DSI_HS_TX_TIMEOUT_MASK);
> > +
> > + nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK, irq_enable);
> > +}
> > +
> > +static int nwl_dsi_host_attach(struct mipi_dsi_host *dsi_host,
> > + struct mipi_dsi_device *device)
> > +{
> > + struct nwl_dsi *dsi = container_of(dsi_host, struct nwl_dsi, dsi_host);
> > + struct device *dev = dsi->dev;
> > + struct drm_bridge *bridge;
> > + struct drm_panel *panel;
> > + int ret;
> > +
> > + DRM_DEV_INFO(dev, "lanes=%u, format=0x%x flags=0x%lx\n", device->lanes,
> > + device->format, device->mode_flags);
> > +
> > + if (device->lanes < 1 || device->lanes > 4)
> > + return -EINVAL;
> > +
> > + dsi->lanes = device->lanes;
> > + dsi->format = device->format;
> > + dsi->dsi_mode_flags = device->mode_flags;
> > +
> > + ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 1, 0, &panel,
> > + &bridge);
> > + if (ret)
> > + return ret;
> > +
> > + if (panel) {
> > + bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DSI);
> > + if (IS_ERR(bridge))
> > + return PTR_ERR(bridge);
> > + }
> > +
> > + dsi->panel_bridge = bridge;
> > + drm_bridge_add(&dsi->bridge);
> > +
> > + return 0;
> > +}
> > +
> > +static int nwl_dsi_host_detach(struct mipi_dsi_host *dsi_host,
> > + struct mipi_dsi_device *device)
> > +{
> > + struct nwl_dsi *dsi = container_of(dsi_host, struct nwl_dsi, dsi_host);
> > +
> > + drm_of_panel_bridge_remove(dsi->dev->of_node, 1, 0);
> > + drm_bridge_remove(&dsi->bridge);
> > +
> > + return 0;
> > +}
> > +
> > +static bool nwl_dsi_read_packet(struct nwl_dsi *dsi, u32 status)
> > +{
> > + struct device *dev = dsi->dev;
> > + struct nwl_dsi_transfer *xfer = dsi->xfer;
> > + u8 *payload = xfer->msg->rx_buf;
> > + u32 val;
> > + u16 word_count;
> > + u8 channel;
> > + u8 data_type;
> > +
> > + xfer->status = 0;
> > +
> > + if (xfer->rx_word_count == 0) {
> > + if (!(status & NWL_DSI_RX_PKT_HDR_RCVD))
> > + return false;
> > + /* Get the RX header and parse it */
> > + val = nwl_dsi_read(dsi, NWL_DSI_RX_PKT_HEADER);
> > + word_count = NWL_DSI_WC(val);
> > + channel = NWL_DSI_RX_VC(val);
> > + data_type = NWL_DSI_RX_DT(val);
> > +
> > + if (channel != xfer->msg->channel) {
> > + DRM_DEV_ERROR(dev,
> > + "[%02X] Channel mismatch (%u != %u)\n",
> > + xfer->cmd, channel, xfer->msg->channel);
> > + return true;
> > + }
> > +
> > + switch (data_type) {
> > + case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
> > + /* Fall through */
> > + case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
> > + if (xfer->msg->rx_len > 1) {
> > + /* read second byte */
> > + payload[1] = word_count >> 8;
> > + ++xfer->rx_len;
> > + }
> > + /* Fall through */
> > + case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:
> > + /* Fall through */
> > + case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
> > + if (xfer->msg->rx_len > 0) {
> > + /* read first byte */
> > + payload[0] = word_count & 0xff;
> > + ++xfer->rx_len;
> > + }
> > + xfer->status = xfer->rx_len;
> > + return true;
> > + case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
> > + word_count &= 0xff;
> > + DRM_DEV_ERROR(dev, "[%02X] DSI error report: 0x%02x\n",
> > + xfer->cmd, word_count);
> > + xfer->status = -EPROTO;
> > + return true;
> > + }
> > +
> > + if (word_count > xfer->msg->rx_len) {
> > + DRM_DEV_ERROR(
> > + dev,
> > + "[%02X] Receive buffer too small: %zu (< %u)\n",
> > + xfer->cmd, xfer->msg->rx_len, word_count);
> > + return true;
> > + }
> > +
> > + xfer->rx_word_count = word_count;
> > + } else {
> > + /* Set word_count from previous header read */
> > + word_count = xfer->rx_word_count;
> > + }
> > +
> > + /* If RX payload is not yet received, wait for it */
> > + if (!(status & NWL_DSI_RX_PKT_PAYLOAD_DATA_RCVD))
> > + return false;
> > +
> > + /* Read the RX payload */
> > + while (word_count >= 4) {
> > + val = nwl_dsi_read(dsi, NWL_DSI_RX_PAYLOAD);
> > + payload[0] = (val >> 0) & 0xff;
> > + payload[1] = (val >> 8) & 0xff;
> > + payload[2] = (val >> 16) & 0xff;
> > + payload[3] = (val >> 24) & 0xff;
> > + payload += 4;
> > + xfer->rx_len += 4;
> > + word_count -= 4;
> > + }
> > +
> > + if (word_count > 0) {
> > + val = nwl_dsi_read(dsi, NWL_DSI_RX_PAYLOAD);
> > + switch (word_count) {
> > + case 3:
> > + payload[2] = (val >> 16) & 0xff;
> > + ++xfer->rx_len;
> > + /* Fall through */
> > + case 2:
> > + payload[1] = (val >> 8) & 0xff;
> > + ++xfer->rx_len;
> > + /* Fall through */
> > + case 1:
> > + payload[0] = (val >> 0) & 0xff;
> > + ++xfer->rx_len;
> > + break;
> > + }
> > + }
> > +
> > + xfer->status = xfer->rx_len;
> > +
> > + return true;
> > +}
> > +
> > +static void nwl_dsi_finish_transmission(struct nwl_dsi *dsi, u32 status)
> > +{
> > + struct nwl_dsi_transfer *xfer = dsi->xfer;
> > + bool end_packet = false;
> > +
> > + if (!xfer)
> > + return;
> > +
> > + if (xfer->direction == DSI_PACKET_SEND &&
> > + status & NWL_DSI_TX_PKT_DONE) {
> > + xfer->status = xfer->tx_len;
> > + end_packet = true;
> > + } else if (status & NWL_DSI_DPHY_DIRECTION &&
> > + ((status & (NWL_DSI_RX_PKT_HDR_RCVD |
> > + NWL_DSI_RX_PKT_PAYLOAD_DATA_RCVD)))) {
> > + end_packet = nwl_dsi_read_packet(dsi, status);
> > + }
> > +
> > + if (end_packet)
> > + complete(&xfer->completed);
> > +}
> > +
> > +static void nwl_dsi_begin_transmission(struct nwl_dsi *dsi)
> > +{
> > + struct nwl_dsi_transfer *xfer = dsi->xfer;
> > + struct mipi_dsi_packet *pkt = &xfer->packet;
> > + const u8 *payload;
> > + size_t length;
> > + u16 word_count;
> > + u8 hs_mode;
> > + u32 val;
> > + u32 hs_workaround = 0;
> > +
> > + /* Send the payload, if any */
> > + length = pkt->payload_length;
> > + payload = pkt->payload;
> > +
> > + while (length >= 4) {
> > + val = *(u32 *)payload;
> > + hs_workaround |= !(val & 0xFFFF00);
> > + nwl_dsi_write(dsi, NWL_DSI_TX_PAYLOAD, val);
> > + payload += 4;
> > + length -= 4;
> > + }
> > + /* Send the rest of the payload */
> > + val = 0;
> > + switch (length) {
> > + case 3:
> > + val |= payload[2] << 16;
> > + /* Fall through */
> > + case 2:
> > + val |= payload[1] << 8;
> > + hs_workaround |= !(val & 0xFFFF00);
> > + /* Fall through */
> > + case 1:
> > + val |= payload[0];
> > + nwl_dsi_write(dsi, NWL_DSI_TX_PAYLOAD, val);
> > + break;
> > + }
> > + xfer->tx_len = pkt->payload_length;
> > +
> > + /*
> > + * Send the header
> > + * header[0] = Virtual Channel + Data Type
> > + * header[1] = Word Count LSB (LP) or first param (SP)
> > + * header[2] = Word Count MSB (LP) or second param (SP)
> > + */
> > + word_count = pkt->header[1] | (pkt->header[2] << 8);
> > + if (hs_workaround && (dsi->quirks & E11418_HS_MODE_QUIRK)) {
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev,
> > + "Using hs mode workaround for cmd 0x%x\n",
> > + xfer->cmd);
> > + hs_mode = 1;
> > + } else {
> > + hs_mode = (xfer->msg->flags & MIPI_DSI_MSG_USE_LPM) ? 0 : 1;
> > + }
> > + val = NWL_DSI_WC(word_count) | NWL_DSI_TX_VC(xfer->msg->channel) |
> > + NWL_DSI_TX_DT(xfer->msg->type) | NWL_DSI_HS_SEL(hs_mode) |
> > + NWL_DSI_BTA_TX(xfer->need_bta);
> > + nwl_dsi_write(dsi, NWL_DSI_PKT_CONTROL, val);
> > +
> > + /* Send packet command */
> > + nwl_dsi_write(dsi, NWL_DSI_SEND_PACKET, 0x1);
> > +}
> > +
> > +static ssize_t nwl_dsi_host_transfer(struct mipi_dsi_host *dsi_host,
> > + const struct mipi_dsi_msg *msg)
> > +{
> > + struct nwl_dsi *dsi = container_of(dsi_host, struct nwl_dsi, dsi_host);
> > + struct nwl_dsi_transfer xfer;
> > + ssize_t ret = 0;
> > +
> > + /* Create packet to be sent */
> > + dsi->xfer = &xfer;
> > + ret = mipi_dsi_create_packet(&xfer.packet, msg);
> > + if (ret < 0) {
> > + dsi->xfer = NULL;
> > + return ret;
> > + }
> > +
> > + if ((msg->type & MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM ||
> > + msg->type & MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM ||
> > + msg->type & MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM ||
> > + msg->type & MIPI_DSI_DCS_READ) &&
> > + msg->rx_len > 0 && msg->rx_buf != NULL)
> > + xfer.direction = DSI_PACKET_RECEIVE;
> > + else
> > + xfer.direction = DSI_PACKET_SEND;
> > +
> > + xfer.need_bta = (xfer.direction == DSI_PACKET_RECEIVE);
> > + xfer.need_bta |= (msg->flags & MIPI_DSI_MSG_REQ_ACK) ? 1 : 0;
> > + xfer.msg = msg;
> > + xfer.status = -ETIMEDOUT;
> > + xfer.rx_word_count = 0;
> > + xfer.rx_len = 0;
> > + xfer.cmd = 0x00;
> > + if (msg->tx_len > 0)
> > + xfer.cmd = ((u8 *)(msg->tx_buf))[0];
> > + init_completion(&xfer.completed);
> > +
> > + ret = clk_prepare_enable(dsi->rx_esc_clk);
> > + if (ret < 0) {
> > + DRM_DEV_ERROR(dsi->dev, "Failed to enable rx_esc clk: %zd\n",
> > + ret);
> > + return ret;
> > + }
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "Enabled rx_esc clk @%lu Hz\n",
> > + clk_get_rate(dsi->rx_esc_clk));
> > +
> > + /* Initiate the DSI packet transmision */
> > + nwl_dsi_begin_transmission(dsi);
> > +
> > + if (!wait_for_completion_timeout(&xfer.completed,
> > + NWL_DSI_MIPI_FIFO_TIMEOUT)) {
> > + DRM_DEV_ERROR(dsi_host->dev, "[%02X] DSI transfer timed out\n",
> > + xfer.cmd);
> > + ret = -ETIMEDOUT;
> > + } else {
> > + ret = xfer.status;
> > + }
> > +
> > + clk_disable_unprepare(dsi->rx_esc_clk);
> > +
> > + return ret;
> > +}
> > +
> > +const struct mipi_dsi_host_ops nwl_dsi_host_ops = {
> > + .attach = nwl_dsi_host_attach,
> > + .detach = nwl_dsi_host_detach,
> > + .transfer = nwl_dsi_host_transfer,
> > +};
> > +
> > +irqreturn_t nwl_dsi_irq_handler(int irq, void *data)
> > +{
> > + u32 irq_status;
> > + struct nwl_dsi *dsi = data;
> > +
> > + irq_status = nwl_dsi_read(dsi, NWL_DSI_IRQ_STATUS);
> > +
> > + if (irq_status & NWL_DSI_TX_FIFO_OVFLW)
> > + DRM_DEV_ERROR_RATELIMITED(dsi->dev, "tx fifo overflow\n");
> > +
> > + if (irq_status & NWL_DSI_HS_TX_TIMEOUT)
> > + DRM_DEV_ERROR_RATELIMITED(dsi->dev, "HS tx timeout\n");
> > +
> > + if (irq_status & NWL_DSI_TX_PKT_DONE ||
> > + irq_status & NWL_DSI_RX_PKT_HDR_RCVD ||
> > + irq_status & NWL_DSI_RX_PKT_PAYLOAD_DATA_RCVD)
> > + nwl_dsi_finish_transmission(dsi, irq_status);
> > +
> > + return IRQ_HANDLED;
> > +}
> > +
> > +int nwl_dsi_enable(struct nwl_dsi *dsi)
> > +{
> > + struct device *dev = dsi->dev;
> > + union phy_configure_opts *phy_cfg = &dsi->phy_cfg;
> > + int ret;
> > +
> > + if (!dsi->lanes) {
> > + DRM_DEV_ERROR(dev, "Need DSI lanes: %d\n", dsi->lanes);
> > + return -EINVAL;
> > + }
> > +
> > + ret = phy_init(dsi->phy);
> > + if (ret < 0) {
> > + DRM_DEV_ERROR(dev, "Failed to init DSI phy: %d\n", ret);
> > + return ret;
> > + }
> > +
> > + ret = phy_configure(dsi->phy, phy_cfg);
> > + if (ret < 0) {
> > + DRM_DEV_ERROR(dev, "Failed to configure DSI phy: %d\n", ret);
> > + return ret;
> > + }
> > +
> > + ret = clk_prepare_enable(dsi->tx_esc_clk);
> > + if (ret < 0) {
> > + DRM_DEV_ERROR(dsi->dev, "Failed to enable tx_esc clk: %d\n",
> > + ret);
> > + return ret;
> > + }
> > + DRM_DEV_DEBUG_DRIVER(dsi->dev, "Enabled tx_esc clk @%lu Hz\n",
> > + clk_get_rate(dsi->tx_esc_clk));
> > +
> > + ret = nwl_dsi_config_host(dsi);
> > + if (ret < 0) {
> > + DRM_DEV_ERROR(dev, "Failed to set up DSI: %d", ret);
> > + return ret;
> > + }
> > +
> > + ret = nwl_dsi_config_dpi(dsi);
> > + if (ret < 0) {
> > + DRM_DEV_ERROR(dev, "Failed to set up DPI: %d", ret);
> > + return ret;
> > + }
> > +
> > + ret = phy_power_on(dsi->phy);
> > + if (ret < 0) {
> > + DRM_DEV_ERROR(dev, "Failed to power on DPHY (%d)\n", ret);
> > + return ret;
> > + }
> > +
> > + nwl_dsi_init_interrupts(dsi);
> > +
> > + return 0;
> > +}
> > +
> > +int nwl_dsi_disable(struct nwl_dsi *dsi)
> > +{
> > + struct device *dev = dsi->dev;
> > +
> > + DRM_DEV_DEBUG_DRIVER(dev, "Disabling clocks and phy\n");
> > +
> > + phy_power_off(dsi->phy);
> > + phy_exit(dsi->phy);
> > +
> > + /* Disabling the clock before the phy breaks enabling dsi again */
> > + clk_disable_unprepare(dsi->tx_esc_clk);
> > +
> > + return 0;
> > +}
> > diff --git a/drivers/gpu/drm/bridge/nwl-dsi/nwl-dsi.h b/drivers/gpu/drm/bridge/nwl-dsi/nwl-dsi.h
> > new file mode 100644
> > index 000000000000..579b366de652
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/nwl-dsi/nwl-dsi.h
> > @@ -0,0 +1,112 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/*
> > + * NWL MIPI DSI host driver
> > + *
> > + * Copyright (C) 2017 NXP
> > + * Copyright (C) 2019 Purism SPC
> > + */
> > +#ifndef __NWL_DSI_H__
> > +#define __NWL_DSI_H__
> > +
> > +#include <linux/irqreturn.h>
> > +
> > +#include <drm/drm_mipi_dsi.h>
> > +
> > +#include "nwl-drv.h"
> > +
> > +/* DSI HOST registers */
> > +#define NWL_DSI_CFG_NUM_LANES 0x0
> > +#define NWL_DSI_CFG_NONCONTINUOUS_CLK 0x4
> > +#define NWL_DSI_CFG_T_PRE 0x8
> > +#define NWL_DSI_CFG_T_POST 0xc
> > +#define NWL_DSI_CFG_TX_GAP 0x10
> > +#define NWL_DSI_CFG_AUTOINSERT_EOTP 0x14
> > +#define NWL_DSI_CFG_EXTRA_CMDS_AFTER_EOTP 0x18
> > +#define NWL_DSI_CFG_HTX_TO_COUNT 0x1c
> > +#define NWL_DSI_CFG_LRX_H_TO_COUNT 0x20
> > +#define NWL_DSI_CFG_BTA_H_TO_COUNT 0x24
> > +#define NWL_DSI_CFG_TWAKEUP 0x28
> > +#define NWL_DSI_CFG_STATUS_OUT 0x2c
> > +#define NWL_DSI_RX_ERROR_STATUS 0x30
> > +
> > +/* DSI DPI registers */
> > +#define NWL_DSI_PIXEL_PAYLOAD_SIZE 0x200
> > +#define NWL_DSI_PIXEL_FIFO_SEND_LEVEL 0x204
> > +#define NWL_DSI_INTERFACE_COLOR_CODING 0x208
> > +#define NWL_DSI_PIXEL_FORMAT 0x20c
> > +#define NWL_DSI_VSYNC_POLARITY 0x210
> > +#define NWL_DSI_VSYNC_POLARITY_ACTIVE_LOW 0
> > +#define NWL_DSI_VSYNC_POLARITY_ACTIVE_HIGH BIT(1)
> > +
> > +#define NWL_DSI_HSYNC_POLARITY 0x214
> > +#define NWL_DSI_HSYNC_POLARITY_ACTIVE_LOW 0
> > +#define NWL_DSI_HSYNC_POLARITY_ACTIVE_HIGH BIT(1)
> > +
> > +#define NWL_DSI_VIDEO_MODE 0x218
> > +#define NWL_DSI_HFP 0x21c
> > +#define NWL_DSI_HBP 0x220
> > +#define NWL_DSI_HSA 0x224
> > +#define NWL_DSI_ENABLE_MULT_PKTS 0x228
> > +#define NWL_DSI_VBP 0x22c
> > +#define NWL_DSI_VFP 0x230
> > +#define NWL_DSI_BLLP_MODE 0x234
> > +#define NWL_DSI_USE_NULL_PKT_BLLP 0x238
> > +#define NWL_DSI_VACTIVE 0x23c
> > +#define NWL_DSI_VC 0x240
> > +
> > +/* DSI APB PKT control */
> > +#define NWL_DSI_TX_PAYLOAD 0x280
> > +#define NWL_DSI_PKT_CONTROL 0x284
> > +#define NWL_DSI_SEND_PACKET 0x288
> > +#define NWL_DSI_PKT_STATUS 0x28c
> > +#define NWL_DSI_PKT_FIFO_WR_LEVEL 0x290
> > +#define NWL_DSI_PKT_FIFO_RD_LEVEL 0x294
> > +#define NWL_DSI_RX_PAYLOAD 0x298
> > +#define NWL_DSI_RX_PKT_HEADER 0x29c
> > +
> > +/* DSI IRQ handling */
> > +#define NWL_DSI_IRQ_STATUS 0x2a0
> > +#define NWL_DSI_SM_NOT_IDLE BIT(0)
> > +#define NWL_DSI_TX_PKT_DONE BIT(1)
> > +#define NWL_DSI_DPHY_DIRECTION BIT(2)
> > +#define NWL_DSI_TX_FIFO_OVFLW BIT(3)
> > +#define NWL_DSI_TX_FIFO_UDFLW BIT(4)
> > +#define NWL_DSI_RX_FIFO_OVFLW BIT(5)
> > +#define NWL_DSI_RX_FIFO_UDFLW BIT(6)
> > +#define NWL_DSI_RX_PKT_HDR_RCVD BIT(7)
> > +#define NWL_DSI_RX_PKT_PAYLOAD_DATA_RCVD BIT(8)
> > +#define NWL_DSI_BTA_TIMEOUT BIT(29)
> > +#define NWL_DSI_LP_RX_TIMEOUT BIT(30)
> > +#define NWL_DSI_HS_TX_TIMEOUT BIT(31)
> > +
> > +#define NWL_DSI_IRQ_STATUS2 0x2a4
> > +#define NWL_DSI_SINGLE_BIT_ECC_ERR BIT(0)
> > +#define NWL_DSI_MULTI_BIT_ECC_ERR BIT(1)
> > +#define NWL_DSI_CRC_ERR BIT(2)
> > +
> > +#define NWL_DSI_IRQ_MASK 0x2a8
> > +#define NWL_DSI_SM_NOT_IDLE_MASK BIT(0)
> > +#define NWL_DSI_TX_PKT_DONE_MASK BIT(1)
> > +#define NWL_DSI_DPHY_DIRECTION_MASK BIT(2)
> > +#define NWL_DSI_TX_FIFO_OVFLW_MASK BIT(3)
> > +#define NWL_DSI_TX_FIFO_UDFLW_MASK BIT(4)
> > +#define NWL_DSI_RX_FIFO_OVFLW_MASK BIT(5)
> > +#define NWL_DSI_RX_FIFO_UDFLW_MASK BIT(6)
> > +#define NWL_DSI_RX_PKT_HDR_RCVD_MASK BIT(7)
> > +#define NWL_DSI_RX_PKT_PAYLOAD_DATA_RCVD_MASK BIT(8)
> > +#define NWL_DSI_BTA_TIMEOUT_MASK BIT(29)
> > +#define NWL_DSI_LP_RX_TIMEOUT_MASK BIT(30)
> > +#define NWL_DSI_HS_TX_TIMEOUT_MASK BIT(31)
> > +
> > +#define NWL_DSI_IRQ_MASK2 0x2ac
> > +#define NWL_DSI_SINGLE_BIT_ECC_ERR_MASK BIT(0)
> > +#define NWL_DSI_MULTI_BIT_ECC_ERR_MASK BIT(1)
> > +#define NWL_DSI_CRC_ERR_MASK BIT(2)
> > +
> > +extern const struct mipi_dsi_host_ops nwl_dsi_host_ops;
> > +
> > +irqreturn_t nwl_dsi_irq_handler(int irq, void *data);
> > +int nwl_dsi_enable(struct nwl_dsi *dsi);
> > +int nwl_dsi_disable(struct nwl_dsi *dsi);
> > +
> > +#endif /* __NWL_DSI_H__ */
>
>
_______________________________________________
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 v4 0/4] arm64: Add basic support for Amlogic A1 SoC Family
From: Martin Blumenstingl @ 2019-09-14 17:28 UTC (permalink / raw)
To: Jianxin Pan
Cc: devicetree, Hanjie Lin, Victor Wan, Neil Armstrong, Kevin Hilman,
linux-kernel, Qiufang Dai, Rob Herring, Jian Hu, Xingyu Chen,
Tao Zeng, Carlo Caione, linux-amlogic, linux-arm-kernel,
Jerome Brunet
In-Reply-To: <1568276370-54181-1-git-send-email-jianxin.pan@amlogic.com>
Hi Jianxin,
On Thu, Sep 12, 2019 at 10:20 AM Jianxin Pan <jianxin.pan@amlogic.com> wrote:
>
> A1 is an application processor designed for smart audio and IoT applications,
> with Dual core ARM Cortex-A35 CPU. Unlike the previous GXL and G12 series,
> there is no Cortex-M3 AO CPU in it.
it will be interesting to see which devices will use this SoC
[...]
> Jianxin Pan (4):
> soc: amlogic: meson-gx-socinfo: Add A1 and A113L IDs
> dt-bindings: arm: amlogic: add A1 bindings
> dt-bindings: arm: amlogic: add Amlogic AD401 bindings
> arm64: dts: add support for A1 based Amlogic AD401
for the whole series:
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
_______________________________________________
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 3/3] arm64: dts: meson-g12b-ugoos-am6: add initial device-tree
From: Martin Blumenstingl @ 2019-09-14 17:40 UTC (permalink / raw)
To: Christian Hewitt
Cc: Mark Rutland, devicetree, Oleg Ivanov, Kevin Hilman, linux-kernel,
Rob Herring, linux-amlogic, linux-arm-kernel
In-Reply-To: <1567780354-59472-4-git-send-email-christianshewitt@gmail.com>
Hi Christian,
my nit-picks below
On Fri, Sep 6, 2019 at 4:34 PM Christian Hewitt
<christianshewitt@gmail.com> wrote:
[...]
> + spdif_dit: audio-codec-1 {
> + #sound-dai-cells = <0>;
> + compatible = "linux,spdif-dit";
> + status = "okay";
> + sound-name-prefix = "DIT";
> + };
please move it below sdio_pwrseq (or at least somewhere below the memory node)
[...]
> + vcc_3v3: regulator-vcc_3v3 {
> + compatible = "regulator-fixed";
> + regulator-name = "VCC_3V3";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + vin-supply = <&vddao_3v3>;
> + regulator-always-on;
> + /* FIXME: actually controlled by VDDCPU_B_EN */
can we add the enable GPIO here now that we know how to describe the
VDDCPU_B regulator?
[...]
> + usb1_pow: regulator-usb1_pow {
for consistency with the regulators above: regulator-usb1-pow
[...]
> + usb_pwr_en: regulator-usb_pwr_en {
for consistency with the regulators above: regulator-usb-pwr-en
[...]
> + vddao_1v8: regulator-vddao_1v8 {
for consistency with the regulators above: regulator-vddao-1v8
[...
> + vddao_3v3: regulator-vddao_3v3 {
for consistency with the regulators above: regulator-vddao-3v3
[...]
> +&cpu0 {
> + cpu-supply = <&vddcpu_b>;
> + operating-points-v2 = <&cpu_opp_table_0>;
> + clocks = <&clkc CLKID_CPU_CLK>;
> + clock-latency = <50000>;
> +};
> +
> +&cpu1 {
> + cpu-supply = <&vddcpu_b>;
> + operating-points-v2 = <&cpu_opp_table_0>;
> + clocks = <&clkc CLKID_CPU_CLK>;
> + clock-latency = <50000>;
> +};
> +
> +&cpu100 {
> + cpu-supply = <&vddcpu_a>;
> + operating-points-v2 = <&cpub_opp_table_1>;
> + clocks = <&clkc CLKID_CPUB_CLK>;
> + clock-latency = <50000>;
> +};
> +
> +&cpu101 {
> + cpu-supply = <&vddcpu_a>;
> + operating-points-v2 = <&cpub_opp_table_1>;
> + clocks = <&clkc CLKID_CPUB_CLK>;
> + clock-latency = <50000>;
> +};
> +
> +&cpu102 {
> + cpu-supply = <&vddcpu_a>;
> + operating-points-v2 = <&cpub_opp_table_1>;
> + clocks = <&clkc CLKID_CPUB_CLK>;
> + clock-latency = <50000>;
> +};
> +
> +&cpu103 {
> + cpu-supply = <&vddcpu_a>;
> + operating-points-v2 = <&cpub_opp_table_1>;
> + clocks = <&clkc CLKID_CPUB_CLK>;
> + clock-latency = <50000>;
> +};
(not limited to this patch: there's a lot of redundancy with the CPU
nodes across the G12B .dts)
[...]
> +&sd_emmc_a {
all nodes starting here should use alphabetical sorting
Martin
_______________________________________________
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] i2c: at91: Send bus clear command if SCL or SDA is down
From: Ludovic Desroches @ 2019-09-14 19:05 UTC (permalink / raw)
To: Codrin Ciubotariu
Cc: alexandre.belloni, wsa, linux-kernel, linux-i2c, linux-arm-kernel
In-Reply-To: <20190911095854.5141-1-codrin.ciubotariu@microchip.com>
On Wed, Sep 11, 2019 at 12:58:54PM +0300, Codrin Ciubotariu wrote:
> After a transfer timeout, some faulty I2C slave devices might hold down
> the SCL or the SDA pins. We can generate a bus clear command, hoping that
> the slave might release the pins.
>
> Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
Acked-by: Ludovic Desroches <ludovic.desroches@microchip.com>
I'll be off for three weeks so if there are minor changes, you can keep my
ack.
Thanks
Ludovic
> ---
> drivers/i2c/busses/i2c-at91-master.c | 20 ++++++++++++++++++++
> drivers/i2c/busses/i2c-at91.h | 6 +++++-
> 2 files changed, 25 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/i2c/busses/i2c-at91-master.c b/drivers/i2c/busses/i2c-at91-master.c
> index a3fcc35ffd3b..5f544a16db96 100644
> --- a/drivers/i2c/busses/i2c-at91-master.c
> +++ b/drivers/i2c/busses/i2c-at91-master.c
> @@ -599,6 +599,26 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
> at91_twi_write(dev, AT91_TWI_CR,
> AT91_TWI_THRCLR | AT91_TWI_LOCKCLR);
> }
> +
> + /*
> + * After timeout, some faulty I2C slave devices might hold SCL/SDA down;
> + * we can send a bus clear command, hoping that the pins will be
> + * released
> + */
> + if (!(dev->transfer_status & AT91_TWI_SDA) ||
> + !(dev->transfer_status & AT91_TWI_SCL)) {
> + dev_dbg(dev->dev,
> + "SDA/SCL are down; sending bus clear command\n");
> + if (dev->use_alt_cmd) {
> + unsigned int acr;
> +
> + acr = at91_twi_read(dev, AT91_TWI_ACR);
> + acr &= ~AT91_TWI_ACR_DATAL_MASK;
> + at91_twi_write(dev, AT91_TWI_ACR, acr);
> + }
> + at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_CLEAR);
> + }
> +
> return ret;
> }
>
> diff --git a/drivers/i2c/busses/i2c-at91.h b/drivers/i2c/busses/i2c-at91.h
> index 499b506f6128..ffb870f3ffc6 100644
> --- a/drivers/i2c/busses/i2c-at91.h
> +++ b/drivers/i2c/busses/i2c-at91.h
> @@ -36,6 +36,7 @@
> #define AT91_TWI_SVDIS BIT(5) /* Slave Transfer Disable */
> #define AT91_TWI_QUICK BIT(6) /* SMBus quick command */
> #define AT91_TWI_SWRST BIT(7) /* Software Reset */
> +#define AT91_TWI_CLEAR BIT(15) /* Bus clear command */
> #define AT91_TWI_ACMEN BIT(16) /* Alternative Command Mode Enable */
> #define AT91_TWI_ACMDIS BIT(17) /* Alternative Command Mode Disable */
> #define AT91_TWI_THRCLR BIT(24) /* Transmit Holding Register Clear */
> @@ -69,6 +70,8 @@
> #define AT91_TWI_NACK BIT(8) /* Not Acknowledged */
> #define AT91_TWI_EOSACC BIT(11) /* End Of Slave Access */
> #define AT91_TWI_LOCK BIT(23) /* TWI Lock due to Frame Errors */
> +#define AT91_TWI_SCL BIT(24) /* TWI SCL status */
> +#define AT91_TWI_SDA BIT(25) /* TWI SDA status */
>
> #define AT91_TWI_INT_MASK \
> (AT91_TWI_TXCOMP | AT91_TWI_RXRDY | AT91_TWI_TXRDY | AT91_TWI_NACK \
> @@ -81,7 +84,8 @@
> #define AT91_TWI_THR 0x0034 /* Transmit Holding Register */
>
> #define AT91_TWI_ACR 0x0040 /* Alternative Command Register */
> -#define AT91_TWI_ACR_DATAL(len) ((len) & 0xff)
> +#define AT91_TWI_ACR_DATAL_MASK GENMASK(15, 0)
> +#define AT91_TWI_ACR_DATAL(len) ((len) & AT91_TWI_ACR_DATAL_MASK)
> #define AT91_TWI_ACR_DIR BIT(8)
>
> #define AT91_TWI_FMR 0x0050 /* FIFO Mode Register */
> --
> 2.20.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v5 0/9] i2c: add support for filters
From: Ludovic Desroches @ 2019-09-14 19:32 UTC (permalink / raw)
To: Eugen Hristev - M18282
Cc: mark.rutland@arm.com, devicetree@vger.kernel.org,
alexandre.belloni@bootlin.com, wsa@the-dreams.de,
linux-kernel@vger.kernel.org, robh+dt@kernel.org,
linux-i2c@vger.kernel.org, peda@axentia.se,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <1568189911-31641-1-git-send-email-eugen.hristev@microchip.com>
On Wed, Sep 11, 2019 at 10:24:14AM +0200, Eugen Hristev - M18282 wrote:
> From: Eugen Hristev <eugen.hristev@microchip.com>
>
> Hello,
>
> This series adds support for analog and digital filters for i2c controllers
>
> This series is based on the series:
> [PATCH v2 0/9] i2c: at91: filters support for at91 SoCs
> and later
> [PATCH v4 0/9] i2c: add support for filters
> and enhanced to add the bindings for all controllers plus an extra bindings
> for the width of the spikes in nanoseconds (digital filters) and cut-off
> frequency (analog filters)
>
> First, bindings are created for
> 'i2c-analog-filter'
> 'i2c-digital-filter'
> 'i2c-digital-filter-width-ns'
> 'i2c-analog-filter-cutoff-frequency'
>
> The support is added in the i2c core to retrieve filter width/cutoff frequency
> and add it to the timings structure.
> Next, the at91 driver is enhanced for supporting digital filter, advanced
> digital filter (with selectable spike width) and the analog filter.
>
> Finally the device tree for two boards are modified to make use of the
> new properties.
>
> This series is the result of the comments on the ML in the direction
> requested: to make the bindings globally available for i2c drivers.
>
> Changes in v5:
> - renamed i2c-filter-width-ns to i2c-digital-filter-width-ns as this
> is applicable only to digital filter
> - created new binding i2c-digital-filter-width-ns for analog filters.
Acked-by: Ludovic Desroches <ludovic.desroches@microchip.com>
for at91 stuff. You can keep it for the future if needed as long as
changes mainly concerned the generic binding.
Regards
Ludovic
>
> Changes in v4:
> - renamed i2c-ana-filter to i2c-analog-filter
> - renamed i2c-dig-filter to i2c-digital-filter
>
> Changes in v3:
> - made bindings global for i2c controllers and modified accordingly
> - gave up PADFCDF bit because it's a lack in datasheet
> - the computation on the width of the spike is based on periph clock as it
> is done for hold time.
>
> Changes in v2:
> - added device tree bindings and support for enable-ana-filt and
> enable-dig-filt
> - added the new properties to the DT for sama5d4_xplained/sama5d2_xplained
>
> Eugen Hristev (9):
> dt-bindings: i2c: at91: add new compatible
> dt-bindings: i2c: add bindings for i2c analog and digital filter
> i2c: add support for filters optional properties
> i2c: at91: add new platform support for sam9x60
> i2c: at91: add support for digital filtering
> i2c: at91: add support for advanced digital filtering
> i2c: at91: add support for analog filtering
> ARM: dts: at91: sama5d2_xplained: add analog and digital filter for
> i2c
> ARM: dts: at91: sama5d4_xplained: add digital filter for i2c
>
> Documentation/devicetree/bindings/i2c/i2c-at91.txt | 3 +-
> Documentation/devicetree/bindings/i2c/i2c.txt | 18 ++++++++
> arch/arm/boot/dts/at91-sama5d2_xplained.dts | 6 +++
> arch/arm/boot/dts/at91-sama5d4_xplained.dts | 1 +
> drivers/i2c/busses/i2c-at91-core.c | 38 +++++++++++++++++
> drivers/i2c/busses/i2c-at91-master.c | 49 ++++++++++++++++++++--
> drivers/i2c/busses/i2c-at91.h | 13 ++++++
> drivers/i2c/i2c-core-base.c | 6 +++
> include/linux/i2c.h | 6 +++
> 9 files changed, 136 insertions(+), 4 deletions(-)
>
> --
> 2.7.4
>
_______________________________________________
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] pinctrl: at91-pio4: implement .get_multiple and .set_multiple
From: Ludovic Desroches @ 2019-09-14 19:36 UTC (permalink / raw)
To: Alexandre Belloni
Cc: linux-gpio, Linus Walleij, linux-arm-kernel, linux-kernel
In-Reply-To: <20190905141304.22005-1-alexandre.belloni@bootlin.com>
On Thu, Sep 05, 2019 at 04:13:04PM +0200, Alexandre Belloni wrote:
>
> Implement .get_multiple and .set_multiple to allow reading or setting
> multiple pins simultaneously. Pins in the same bank will all be switched at
> the same time, improving synchronization and performances.
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Acked-by: Ludovic Desroches <ludovic.desroches@microchip.com>
Thanks for this improvement. You can keep my ack for v3 as the changes
should be the commit message only. I'll be off for three weeks.
Regards
Ludovic
> ---
> drivers/pinctrl/pinctrl-at91-pio4.c | 60 +++++++++++++++++++++++++++++
> 1 file changed, 60 insertions(+)
>
> diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c
> index d6de4d360cd4..488a302a60d4 100644
> --- a/drivers/pinctrl/pinctrl-at91-pio4.c
> +++ b/drivers/pinctrl/pinctrl-at91-pio4.c
> @@ -328,6 +328,35 @@ static int atmel_gpio_get(struct gpio_chip *chip, unsigned offset)
> return !!(reg & BIT(pin->line));
> }
>
> +static int atmel_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
> + unsigned long *bits)
> +{
> + struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip);
> + unsigned int bank;
> +
> + bitmap_zero(bits, atmel_pioctrl->npins);
> +
> + for (bank = 0; bank < atmel_pioctrl->nbanks; bank++) {
> + unsigned int word = bank;
> + unsigned int offset = 0;
> + unsigned int reg;
> +
> +#if ATMEL_PIO_NPINS_PER_BANK != BITS_PER_LONG
> + word = BIT_WORD(bank * ATMEL_PIO_NPINS_PER_BANK);
> + offset = bank * ATMEL_PIO_NPINS_PER_BANK % BITS_PER_LONG;
> +#endif
> + if (!mask[word])
> + continue;
> +
> + reg = atmel_gpio_read(atmel_pioctrl, bank, ATMEL_PIO_PDSR);
> + bits[word] |= mask[word] & (reg << offset);
> +
> + pr_err("ABE: %d %08x\n", bank, bits[word]);
> + }
> +
> + return 0;
> +}
> +
> static int atmel_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
> int value)
> {
> @@ -358,11 +387,42 @@ static void atmel_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
> BIT(pin->line));
> }
>
> +static void atmel_gpio_set_multiple(struct gpio_chip *chip, unsigned long *mask,
> + unsigned long *bits)
> +{
> + struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip);
> + unsigned int bank;
> +
> + for (bank = 0; bank < atmel_pioctrl->nbanks; bank++) {
> + unsigned int bitmask;
> + unsigned int word = bank;
> +
> +#if ATMEL_PIO_NPINS_PER_BANK != BITS_PER_LONG
> + word = BIT_WORD(bank * ATMEL_PIO_NPINS_PER_BANK);
> +#endif
> + if (!mask[word])
> + continue;
> +
> + bitmask = mask[word] & bits[word];
> + atmel_gpio_write(atmel_pioctrl, bank, ATMEL_PIO_SODR, bitmask);
> +
> + bitmask = mask[word] & ~bits[word];
> + atmel_gpio_write(atmel_pioctrl, bank, ATMEL_PIO_CODR, bitmask);
> +
> +#if ATMEL_PIO_NPINS_PER_BANK != BITS_PER_LONG
> + mask[word] >>= ATMEL_PIO_NPINS_PER_BANK;
> + bits[word] >>= ATMEL_PIO_NPINS_PER_BANK;
> +#endif
> + }
> +}
> +
> static struct gpio_chip atmel_gpio_chip = {
> .direction_input = atmel_gpio_direction_input,
> .get = atmel_gpio_get,
> + .get_multiple = atmel_gpio_get_multiple,
> .direction_output = atmel_gpio_direction_output,
> .set = atmel_gpio_set,
> + .set_multiple = atmel_gpio_set_multiple,
> .to_irq = atmel_gpio_to_irq,
> .base = 0,
> };
> --
> 2.21.0
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] drm: sun8i-ui/vi: Fix layer zpos change/atomic modesetting
From: megous @ 2019-09-14 22:03 UTC (permalink / raw)
To: Maxime Ripard, David Airlie, Daniel Vetter, Chen-Yu Tsai
Cc: Ondrej Jirman, linux-arm-kernel, dri-devel, linux-kernel
From: Ondrej Jirman <megous@megous.com>
There are various issues that this re-work of sun8i_[uv]i_layer_enable
function fixes:
- Make sure that we re-initialize zpos on reset
- Minimize register updates by doing them only when state changes
- Fix issue where DE pipe might get disabled even if it is no longer
used by the layer that's currently calling sun8i_ui_layer_enable
- .atomic_disable callback is not really needed because .atomic_update
can do the disable too, so drop the duplicate code
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 112 ++++++++++++++++---------
drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 112 ++++++++++++++++---------
2 files changed, 142 insertions(+), 82 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
index dd2a1c851939..b88e8ac5ad1c 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
@@ -24,10 +24,11 @@
#include "sun8i_ui_scaler.h"
static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
- int overlay, bool enable, unsigned int zpos,
- unsigned int old_zpos)
+ int overlay, bool was_enabled, bool enable,
+ unsigned int zpos, unsigned int old_zpos)
{
u32 val, bld_base, ch_base;
+ unsigned int old_pipe_ch;
bld_base = sun8i_blender_base(mixer);
ch_base = sun8i_channel_base(mixer, channel);
@@ -35,28 +36,57 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
DRM_DEBUG_DRIVER("%sabling channel %d overlay %d\n",
enable ? "En" : "Dis", channel, overlay);
- if (enable)
- val = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN;
- else
- val = 0;
+ if (!was_enabled != !enable) {
+ val = enable ? SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN : 0;
- regmap_update_bits(mixer->engine.regs,
- SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay),
- SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val);
-
- if (!enable || zpos != old_zpos) {
regmap_update_bits(mixer->engine.regs,
- SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
- SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
- 0);
+ SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay),
+ SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val);
+ }
- regmap_update_bits(mixer->engine.regs,
+ /*
+ * If this layer was enabled and is being disabled or if it is
+ * enabled and just changing zpos, clear the old route, if it is
+ * still configured to this layer in HW.
+ */
+ if ((was_enabled && !enable) || (enable && zpos != old_zpos)) {
+ /* get channel the pipe for old_zpos is routed to from the HW */
+ regmap_read(mixer->engine.regs,
SUN8I_MIXER_BLEND_ROUTE(bld_base),
- SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
- 0);
+ &old_pipe_ch);
+ old_pipe_ch &= SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos);
+ old_pipe_ch >>= SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(old_zpos);
+
+ /*
+ * Check that pipe for old_zpos is still routed to our layer,
+ * and clear/disable it if it is.
+ */
+
+ if (old_pipe_ch == channel) {
+ DRM_DEBUG_DRIVER("chan=%d en=%d->%d zpos=%d->%d\n",
+ channel, was_enabled, enable, old_zpos, zpos);
+
+ DRM_DEBUG_DRIVER(" disable pipe %d\n", old_zpos);
+
+ regmap_update_bits(mixer->engine.regs,
+ SUN8I_MIXER_BLEND_ROUTE(bld_base),
+ SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
+ 0);
+
+ regmap_update_bits(mixer->engine.regs,
+ SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
+ SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
+ 0);
+ }
}
- if (enable) {
+ /*
+ * If enabling this layer or changin zpos, set route to this layer.
+ */
+ if ((enable && !was_enabled) || (enable && zpos != old_zpos)) {
+ DRM_DEBUG_DRIVER("chan=%d en=%d->%d zpos=%d->%d\n",
+ channel, was_enabled, enable, old_zpos, zpos);
+
val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
regmap_update_bits(mixer->engine.regs,
@@ -69,6 +99,8 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
SUN8I_MIXER_BLEND_ROUTE(bld_base),
SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos),
val);
+
+ DRM_DEBUG_DRIVER(" enable pipe %d <- ch %d\n", zpos, channel);
}
}
@@ -261,45 +293,43 @@ static int sun8i_ui_layer_atomic_check(struct drm_plane *plane,
true, true);
}
-static void sun8i_ui_layer_atomic_disable(struct drm_plane *plane,
- struct drm_plane_state *old_state)
+static void sun8i_ui_layer_atomic_update(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
{
struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
+ unsigned int zpos = plane->state->normalized_zpos;
unsigned int old_zpos = old_state->normalized_zpos;
struct sun8i_mixer *mixer = layer->mixer;
+ bool was_enabled = old_state->crtc && old_state->visible;
+ bool enable = plane->state->crtc && plane->state->visible;
- sun8i_ui_layer_enable(mixer, layer->channel, layer->overlay, false, 0,
- old_zpos);
+ if (enable) {
+ sun8i_ui_layer_update_coord(mixer, layer->channel,
+ layer->overlay, plane, zpos);
+ sun8i_ui_layer_update_formats(mixer, layer->channel,
+ layer->overlay, plane);
+ sun8i_ui_layer_update_buffer(mixer, layer->channel,
+ layer->overlay, plane);
+ }
+
+ sun8i_ui_layer_enable(mixer, layer->channel, layer->overlay,
+ was_enabled, enable, zpos, old_zpos);
}
-static void sun8i_ui_layer_atomic_update(struct drm_plane *plane,
- struct drm_plane_state *old_state)
+void sun8i_ui_layer_plane_reset(struct drm_plane *plane)
{
struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
- unsigned int zpos = plane->state->normalized_zpos;
- unsigned int old_zpos = old_state->normalized_zpos;
- struct sun8i_mixer *mixer = layer->mixer;
- if (!plane->state->visible) {
- sun8i_ui_layer_enable(mixer, layer->channel,
- layer->overlay, false, 0, old_zpos);
+ drm_atomic_helper_plane_reset(plane);
+ if (!plane->state)
return;
- }
- sun8i_ui_layer_update_coord(mixer, layer->channel,
- layer->overlay, plane, zpos);
- sun8i_ui_layer_update_formats(mixer, layer->channel,
- layer->overlay, plane);
- sun8i_ui_layer_update_buffer(mixer, layer->channel,
- layer->overlay, plane);
- sun8i_ui_layer_enable(mixer, layer->channel, layer->overlay,
- true, zpos, old_zpos);
+ plane->state->zpos = layer->channel;
}
static struct drm_plane_helper_funcs sun8i_ui_layer_helper_funcs = {
.prepare_fb = drm_gem_fb_prepare_fb,
.atomic_check = sun8i_ui_layer_atomic_check,
- .atomic_disable = sun8i_ui_layer_atomic_disable,
.atomic_update = sun8i_ui_layer_atomic_update,
};
@@ -308,7 +338,7 @@ static const struct drm_plane_funcs sun8i_ui_layer_funcs = {
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.destroy = drm_plane_cleanup,
.disable_plane = drm_atomic_helper_disable_plane,
- .reset = drm_atomic_helper_plane_reset,
+ .reset = sun8i_ui_layer_plane_reset,
.update_plane = drm_atomic_helper_update_plane,
};
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
index bd0e6a52d1d8..675ebcdac00b 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
@@ -18,10 +18,11 @@
#include "sun8i_vi_scaler.h"
static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel,
- int overlay, bool enable, unsigned int zpos,
- unsigned int old_zpos)
+ int overlay, bool was_enabled, bool enable,
+ unsigned int zpos, unsigned int old_zpos)
{
u32 val, bld_base, ch_base;
+ unsigned int old_pipe_ch;
bld_base = sun8i_blender_base(mixer);
ch_base = sun8i_channel_base(mixer, channel);
@@ -29,28 +30,57 @@ static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel,
DRM_DEBUG_DRIVER("%sabling VI channel %d overlay %d\n",
enable ? "En" : "Dis", channel, overlay);
- if (enable)
- val = SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN;
- else
- val = 0;
-
- regmap_update_bits(mixer->engine.regs,
- SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay),
- SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN, val);
+ if (!was_enabled != !enable) {
+ val = enable ? SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN : 0;
- if (!enable || zpos != old_zpos) {
regmap_update_bits(mixer->engine.regs,
- SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
- SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
- 0);
+ SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay),
+ SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN, val);
+ }
- regmap_update_bits(mixer->engine.regs,
+ /*
+ * If this layer was enabled and is being disabled or if it is
+ * enabled and just changing zpos, clear the old route, if it is
+ * still configured to this layer in HW.
+ */
+ if ((was_enabled && !enable) || (enable && zpos != old_zpos)) {
+ /* get channel the pipe for old_zpos is routed to from the HW */
+ regmap_read(mixer->engine.regs,
SUN8I_MIXER_BLEND_ROUTE(bld_base),
- SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
- 0);
+ &old_pipe_ch);
+ old_pipe_ch &= SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos);
+ old_pipe_ch >>= SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(old_zpos);
+
+ /*
+ * Check that pipe for old_zpos is still routed to our layer,
+ * and clear/disable it if it is.
+ */
+
+ if (old_pipe_ch == channel) {
+ DRM_DEBUG_DRIVER("chan=%d en=%d->%d zpos=%d->%d\n",
+ channel, was_enabled, enable, old_zpos, zpos);
+
+ DRM_DEBUG_DRIVER(" disable pipe %d\n", old_zpos);
+
+ regmap_update_bits(mixer->engine.regs,
+ SUN8I_MIXER_BLEND_ROUTE(bld_base),
+ SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
+ 0);
+
+ regmap_update_bits(mixer->engine.regs,
+ SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
+ SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
+ 0);
+ }
}
- if (enable) {
+ /*
+ * If enabling this layer or changin zpos, set route to this layer.
+ */
+ if ((enable && !was_enabled) || (enable && zpos != old_zpos)) {
+ DRM_DEBUG_DRIVER("chan=%d en=%d->%d zpos=%d->%d\n",
+ channel, was_enabled, enable, old_zpos, zpos);
+
val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
regmap_update_bits(mixer->engine.regs,
@@ -63,6 +93,8 @@ static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel,
SUN8I_MIXER_BLEND_ROUTE(bld_base),
SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos),
val);
+
+ DRM_DEBUG_DRIVER(" enable pipe %d <- ch %d\n", zpos, channel);
}
}
@@ -345,45 +377,43 @@ static int sun8i_vi_layer_atomic_check(struct drm_plane *plane,
true, true);
}
-static void sun8i_vi_layer_atomic_disable(struct drm_plane *plane,
- struct drm_plane_state *old_state)
+static void sun8i_vi_layer_atomic_update(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
{
struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
+ unsigned int zpos = plane->state->normalized_zpos;
unsigned int old_zpos = old_state->normalized_zpos;
struct sun8i_mixer *mixer = layer->mixer;
+ bool was_enabled = old_state->crtc && old_state->visible;
+ bool enable = plane->state->crtc && plane->state->visible;
- sun8i_vi_layer_enable(mixer, layer->channel, layer->overlay, false, 0,
- old_zpos);
+ if (enable) {
+ sun8i_vi_layer_update_coord(mixer, layer->channel,
+ layer->overlay, plane, zpos);
+ sun8i_vi_layer_update_formats(mixer, layer->channel,
+ layer->overlay, plane);
+ sun8i_vi_layer_update_buffer(mixer, layer->channel,
+ layer->overlay, plane);
+ }
+
+ sun8i_vi_layer_enable(mixer, layer->channel, layer->overlay,
+ was_enabled, enable, zpos, old_zpos);
}
-static void sun8i_vi_layer_atomic_update(struct drm_plane *plane,
- struct drm_plane_state *old_state)
+void sun8i_vi_layer_plane_reset(struct drm_plane *plane)
{
struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
- unsigned int zpos = plane->state->normalized_zpos;
- unsigned int old_zpos = old_state->normalized_zpos;
- struct sun8i_mixer *mixer = layer->mixer;
- if (!plane->state->visible) {
- sun8i_vi_layer_enable(mixer, layer->channel,
- layer->overlay, false, 0, old_zpos);
+ drm_atomic_helper_plane_reset(plane);
+ if (!plane->state)
return;
- }
- sun8i_vi_layer_update_coord(mixer, layer->channel,
- layer->overlay, plane, zpos);
- sun8i_vi_layer_update_formats(mixer, layer->channel,
- layer->overlay, plane);
- sun8i_vi_layer_update_buffer(mixer, layer->channel,
- layer->overlay, plane);
- sun8i_vi_layer_enable(mixer, layer->channel, layer->overlay,
- true, zpos, old_zpos);
+ plane->state->zpos = layer->channel;
}
static struct drm_plane_helper_funcs sun8i_vi_layer_helper_funcs = {
.prepare_fb = drm_gem_fb_prepare_fb,
.atomic_check = sun8i_vi_layer_atomic_check,
- .atomic_disable = sun8i_vi_layer_atomic_disable,
.atomic_update = sun8i_vi_layer_atomic_update,
};
@@ -392,7 +422,7 @@ static const struct drm_plane_funcs sun8i_vi_layer_funcs = {
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.destroy = drm_plane_cleanup,
.disable_plane = drm_atomic_helper_disable_plane,
- .reset = drm_atomic_helper_plane_reset,
+ .reset = sun8i_vi_layer_plane_reset,
.update_plane = drm_atomic_helper_update_plane,
};
--
2.23.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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox