* [PATCH V5 0/8] Add APSS clock controller support for IPQ6018
From: Sivaprakash Murugesan @ 2020-05-24 10:04 UTC (permalink / raw)
To: agross, bjorn.andersson, mturquette, sboyd, robh+dt,
jassisinghbrar, linux-arm-msm, linux-clk, devicetree,
linux-kernel
Cc: Sivaprakash Murugesan
The CPU on Qualcomm's IPQ6018 devices are primarily fed by APSS PLL and XO,
these are connected to a clock mux and enable block.
This patch series adds support for these clocks and inturn enables clocks
required for CPU freq.
[V5]
* Addressed Bjorn comments on apss clk and dt-bindings
* Patch 2 depends on a53 pll dt-bindings
https://www.spinics.net/lists/linux-clk/msg48358.html
[V4]
* Re-written PLL found on IPQ platforms as a separate driver
* Addressed stephen's comments on apss clock controller and pll
* Addressed Rob's review comments on bindings
* moved a53 pll binding from this series as it is not applicable, will send
it separately.
[V3]
* Fixed dt binding check error in patch2
dt-bindings: clock: Add YAML schemas for QCOM A53 PLL
[V2]
* Restructred the patch series as there are two different HW blocks,
the mux and enable belongs to the apcs block and PLL has a separate HW
block.
* Converted qcom mailbox and qcom a53 pll documentation to yaml.
* Addressed review comments from Stephen, Rob and Sibi where it is applicable.
* Changed this cover letter to state the purpose of this patch series
Sivaprakash Murugesan (8):
dt-bindings: mailbox: Add YAML schemas for QCOM APCS global block
dt-bindings: clock: add ipq6018 a53 pll compatible
clk: qcom: Add ipq apss pll driver
clk: qcom: Add DT bindings for ipq6018 apss clock controller
clk: qcom: Add ipq6018 apss clock controller
dt-bindings: mailbox: Add dt-bindings for ipq6018 apcs global block
mailbox: qcom: Add ipq6018 apcs compatible
arm64: dts: ipq6018: Add a53 pll and apcs clock
.../devicetree/bindings/clock/qcom,a53pll.yaml | 18 ++++
.../bindings/mailbox/qcom,apcs-kpss-global.txt | 88 -----------------
.../bindings/mailbox/qcom,apcs-kpss-global.yaml | 99 +++++++++++++++++++
arch/arm64/boot/dts/qcom/ipq6018.dtsi | 16 +++-
drivers/clk/qcom/Kconfig | 19 ++++
drivers/clk/qcom/Makefile | 2 +
drivers/clk/qcom/apss-ipq-pll.c | 97 +++++++++++++++++++
drivers/clk/qcom/apss-ipq6018.c | 106 +++++++++++++++++++++
drivers/mailbox/qcom-apcs-ipc-mailbox.c | 23 +++--
include/dt-bindings/clock/qcom,apss-ipq.h | 12 +++
10 files changed, 380 insertions(+), 100 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt
create mode 100644 Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml
create mode 100644 drivers/clk/qcom/apss-ipq-pll.c
create mode 100644 drivers/clk/qcom/apss-ipq6018.c
create mode 100644 include/dt-bindings/clock/qcom,apss-ipq.h
--
2.7.4
^ permalink raw reply
* Re: [PATCH V4 2/8] dt-bindings: clock: Add schema for QCOM IPQ apss pll
From: Sivaprakash Murugesan @ 2020-05-24 9:49 UTC (permalink / raw)
To: Bjorn Andersson
Cc: agross, mturquette, sboyd, robh+dt, jassisinghbrar, linux-arm-msm,
linux-clk, devicetree, linux-kernel
In-Reply-To: <20200512195608.GH2165@builder.lan>
On 5/13/2020 1:26 AM, Bjorn Andersson wrote:
> On Sun 03 May 23:20 PDT 2020, Sivaprakash Murugesan wrote:
>
>> Add dt-binding for apss pll found on QCOM IPQ platforms
>>
>> Signed-off-by: Sivaprakash Murugesan <sivaprak@codeaurora.org>
> This seems quite similar to the existing qcom,a53pll binding, can't you
> just describe both in the same binding?
ok.
^ permalink raw reply
* Re: [PATCH V4 5/8] clk: qcom: Add ipq apss clock controller
From: Sivaprakash Murugesan @ 2020-05-24 9:48 UTC (permalink / raw)
To: Bjorn Andersson
Cc: agross, mturquette, sboyd, robh+dt, jassisinghbrar, linux-arm-msm,
linux-clk, devicetree, linux-kernel
In-Reply-To: <20200512201233.GI2165@builder.lan>
On 5/13/2020 1:42 AM, Bjorn Andersson wrote:
> On Sun 03 May 23:20 PDT 2020, Sivaprakash Murugesan wrote:
>
>> The CPU on Qualcomm ipq platform is clocked primarily by a aplha PLL
>> and xo which are connected to a mux and enable block.
>>
>> Add support for the mux and enable block which feeds the CPU on ipq
>> based devices.
>>
> As with the A53 binding, I don't believe that this driver will support
> all past, present and future IPQ APSSs. Please make it more specific.
ok. Let me make the changes to be specific for ipq6018 devices.
> Regards,
> Bjorn
>
^ permalink raw reply
* Re: [PATCH V4 7/8] mailbox: qcom: Add ipq6018 apcs compatible
From: Sivaprakash Murugesan @ 2020-05-24 9:45 UTC (permalink / raw)
To: Bjorn Andersson
Cc: agross, mturquette, sboyd, robh+dt, jassisinghbrar, linux-arm-msm,
linux-clk, devicetree, linux-kernel
In-Reply-To: <20200512201931.GJ2165@builder.lan>
Hi Bjorn,
On 5/13/2020 1:49 AM, Bjorn Andersson wrote:
> On Sun 03 May 23:20 PDT 2020, Sivaprakash Murugesan wrote:
>
>> The Qualcomm ipq6018 has apcs block, add compatible for the same.
>> Also, the apcs provides a clock controller functionality similar
>> to msm8916 but the clock driver is different.
>>
>> Create a child platform device based on the apcs compatible for the
>> clock controller functionality.
>>
>> Signed-off-by: Sivaprakash Murugesan <sivaprak@codeaurora.org>
>> ---
>> drivers/mailbox/qcom-apcs-ipc-mailbox.c | 26 +++++++++++++++++---------
>> 1 file changed, 17 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/mailbox/qcom-apcs-ipc-mailbox.c b/drivers/mailbox/qcom-apcs-ipc-mailbox.c
>> index eeebafd..7c0c4b0 100644
>> --- a/drivers/mailbox/qcom-apcs-ipc-mailbox.c
>> +++ b/drivers/mailbox/qcom-apcs-ipc-mailbox.c
>> @@ -45,6 +45,16 @@ static const struct mbox_chan_ops qcom_apcs_ipc_ops = {
>> .send_data = qcom_apcs_ipc_send_data,
>> };
>>
>> +static const struct of_device_id apcs_clk_match_table[] = {
>> + { .compatible = "qcom,msm8916-apcs-kpss-global",
>> + .data = "qcom-apcs-msm8916-clk", },
> These are easier to read if you ignore the 80-char limit.
> Unless Jassi's object that is.
since Jassi has not objected your comment, I am making the change as per
your suggestion.
>
>> + { .compatible = "qcom,qcs404-apcs-apps-global",
>> + .data = "qcom-apcs-msm8916-clk", },
>> + { .compatible = "qcom,ipq6018-apcs-apps-global",
> Add your entry on top, to maintain sort order.
ok.
>
>> + .data = "qcom,apss-ipq-clk", },
>> + {}
>> +};
>> +
>> static int qcom_apcs_ipc_probe(struct platform_device *pdev)
>> {
>> struct qcom_apcs_ipc *apcs;
>> @@ -54,11 +64,7 @@ static int qcom_apcs_ipc_probe(struct platform_device *pdev)
>> void __iomem *base;
>> unsigned long i;
>> int ret;
>> - const struct of_device_id apcs_clk_match_table[] = {
>> - { .compatible = "qcom,msm8916-apcs-kpss-global", },
>> - { .compatible = "qcom,qcs404-apcs-apps-global", },
>> - {}
>> - };
>> + const struct of_device_id *clk_device;
>>
>> apcs = devm_kzalloc(&pdev->dev, sizeof(*apcs), GFP_KERNEL);
>> if (!apcs)
>> @@ -93,11 +99,12 @@ static int qcom_apcs_ipc_probe(struct platform_device *pdev)
>> return ret;
>> }
>>
>> - if (of_match_device(apcs_clk_match_table, &pdev->dev)) {
>> + clk_device = of_match_device(apcs_clk_match_table, &pdev->dev);
> Better use of_device_match_data() and get the string directly (or NULL).
As I checked there is no API called of_device_match_data(), the API
of_device_get_match_data()
returns the data associated with the device and it cannot be used here.
please correct me if wrong.
>
>> + if (clk_device) {
>> apcs->clk = platform_device_register_data(&pdev->dev,
>> - "qcom-apcs-msm8916-clk",
>> - PLATFORM_DEVID_NONE,
>> - NULL, 0);
>> + (const char *)clk_device->data,
>> + PLATFORM_DEVID_NONE,
>> + NULL, 0);
> I didn't apply the patch to look for myself, but please ensure to
> maintain indentation to follow the parenthesis on the line before.
ok.
>
>> if (IS_ERR(apcs->clk))
>> dev_err(&pdev->dev, "failed to register APCS clk\n");
>> }
>> @@ -127,6 +134,7 @@ static const struct of_device_id qcom_apcs_ipc_of_match[] = {
>> { .compatible = "qcom,sdm845-apss-shared", .data = (void *)12 },
>> { .compatible = "qcom,sm8150-apss-shared", .data = (void *)12 },
>> { .compatible = "qcom,ipq8074-apcs-apps-global", .data = (void *)8 },
>> + { .compatible = "qcom,ipq6018-apcs-apps-global", .data = (void *)8 },
> Add it one line up and you'll maintain partial sorting...
ok.
^ permalink raw reply
* Re: [PATCH V3 3/8] clk: qcom: Add A53 PLL support for ipq6018 devices
From: Sivaprakash Murugesan @ 2020-05-24 9:36 UTC (permalink / raw)
To: Stephen Boyd, agross, bjorn.andersson, devicetree, jassisinghbrar,
linux-arm-msm, linux-clk, linux-kernel, mturquette, robh+dt
In-Reply-To: <158948883904.215346.15910533287389644445@swboyd.mtv.corp.google.com>
On 5/15/2020 2:10 AM, Stephen Boyd wrote:
> Quoting Sivaprakash Murugesan (2020-04-22 03:44:33)
>> On 4/22/2020 2:30 PM, Stephen Boyd wrote:
>>> Quoting Sivaprakash Murugesan (2020-04-13 19:55:17)
>>>> diff --git a/drivers/clk/qcom/a53-pll.c b/drivers/clk/qcom/a53-pll.c
>>>> index 45cfc57..a95351c 100644
>>>> --- a/drivers/clk/qcom/a53-pll.c
>>>> +++ b/drivers/clk/qcom/a53-pll.c
>>>> @@ -57,30 +146,26 @@ static int qcom_a53pll_probe(struct platform_device *pdev)
>>>> if (IS_ERR(regmap))
>>>> return PTR_ERR(regmap);
>>>>
>>>> - pll->l_reg = 0x04;
>>>> - pll->m_reg = 0x08;
>>>> - pll->n_reg = 0x0c;
>>>> - pll->config_reg = 0x14;
>>>> - pll->mode_reg = 0x00;
>>>> - pll->status_reg = 0x1c;
>>>> - pll->status_bit = 16;
>>>> - pll->freq_tbl = a53pll_freq;
>>>> -
>>>> - init.name = "a53pll";
>>>> - init.parent_names = (const char *[]){ "xo" };
>>>> - init.num_parents = 1;
>>>> - init.ops = &clk_pll_sr2_ops;
>>>> - init.flags = CLK_IS_CRITICAL;
>>> Please document why a clk is critical.
>> ok
>>>> - pll->clkr.hw.init = &init;
>>>> -
>>>> - ret = devm_clk_register_regmap(dev, &pll->clkr);
>>>> + if (pll_data->flags & PLL_IS_ALPHA) {
>>>> + struct clk_alpha_pll *alpha_pll =
>>>> + pll_data->a53pll.alpha_pll.pll;
>>>> + struct alpha_pll_config *alpha_pll_config =
>>>> + pll_data->a53pll.alpha_pll.pll_config;
>>>> +
>>>> + clk_alpha_pll_configure(alpha_pll, regmap, alpha_pll_config);
>>>> + clkr = &pll_data->a53pll.alpha_pll.pll->clkr;
>>>> + } else {
>>>> + clkr = &pll_data->a53pll.pll->clkr;
>>>> + }
>>> Sorry, the design is confusing.
>> The basic idea is to add support for various PLLs available to clock the
>> A53 core.
>>
>> if this messing up the code, can the alpha pll support be moved to a
>> separate file?
>>
>> It would be very helpful if you provide your input on this.
> Isn't the alpha PLL support already in a different file? Is it sometimes
> an alpha pll and other times it is something else?
alpha pll for cpufreq is not yet available, and for ipq based devices it
is alpha pll, and I guess
for other mobile based devices it is something else.
I have raised a patch set keeping the alpha pll as a separate file,
could you please take a
look into it?
^ permalink raw reply
* Re: [PATCH v13 1/3] dt-bindings: i2c: npcm7xx: add NPCM I2C controller
From: Tali Perry @ 2020-05-24 8:35 UTC (permalink / raw)
To: Rob Herring
Cc: linux-kernel@vger.kernel.org, devicetree, kfting, Benjamin Fair,
Avi Fishman, Nancy Yuen, Andy Shevchenko, OpenBMC Maillist,
Tomer Maimon, Linux I2C,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Wolfram Sang, Brendan Higgins, Patrick Venture, Ofer Yehielli
In-Reply-To: <CAL_JsqLKaWkSs8vMB4+kBL+AzAU6A4KCVJRNFtvmYfATKR1H=w@mail.gmail.com>
Hi Rob,
On Sat, May 23, 2020 at 1:47 AM Rob Herring <robh+dt@kernel.org> wrote:
>
> On Fri, May 22, 2020 at 4:42 PM Rob Herring <robh@kernel.org> wrote:
> >
> > On Fri, 22 May 2020 14:33:10 +0300, Tali Perry wrote:
> > > Added device tree binding documentation for Nuvoton BMC
> > > NPCM I2C controller.
> > >
> > > Signed-off-by: Tali Perry <tali.perry1@gmail.com>
> > > ---
> > > .../bindings/i2c/nuvoton,npcm7xx-i2c.yaml | 60 +++++++++++++++++++
> > > 1 file changed, 60 insertions(+)
> > > create mode 100644 Documentation/devicetree/bindings/i2c/nuvoton,npcm7xx-i2c.yaml
> > >
> >
> >
> > My bot found errors running 'make dt_binding_check' on your patch:
> >
> > Error: Documentation/devicetree/bindings/i2c/nuvoton,npcm7xx-i2c.example.dts:22.28-29 syntax error
> > FATAL ERROR: Unable to parse input tree
> > scripts/Makefile.lib:312: recipe for target 'Documentation/devicetree/bindings/i2c/nuvoton,npcm7xx-i2c.example.dt.yaml' failed
> > make[1]: *** [Documentation/devicetree/bindings/i2c/nuvoton,npcm7xx-i2c.example.dt.yaml] Error 1
> > make[1]: *** Waiting for unfinished jobs....
> > Makefile:1300: recipe for target 'dt_binding_check' failed
> > make: *** [dt_binding_check] Error 2
> >
> > See https://patchwork.ozlabs.org/patch/1296162
> >
> > If you already ran 'make dt_binding_check' and didn't see the above
> > error(s), then make sure dt-schema is up to date:
> >
> > pip3 install git+https://github.com/devicetree-org/dt-schema.git@master --upgrade
> >
> > Please check and re-submit.
>
> Why do you keep sending new versions with the same problem? It won't
> get reviewed until this is fixed. This isn't a free automated service
> to throw things at to see if they work. I have to review the failures.
>
> Rob
Definitely not trying to use the Bot to check my yaml. On the first
version the dt-check was not updated on my side.
On the previous version I updated according to the bot explanations.
Found an error and fixed it. Now I don't see any errors. with latest
dt-check.
I did:
pip3 install git+https://github.com/devicetree-org/dt-schema.git@master
--upgrade
make dt_binding_check
And got a clean log, no warnings or errors. Was I suppose to check
anything else?
Thanks,
Tali
^ permalink raw reply
* [PATCH 0/6] arm64: dts: qcom: smmu/USB nodes and HDK855/HDK865 dts
From: Jonathan Marek @ 2020-05-24 2:38 UTC (permalink / raw)
To: linux-arm-msm
Cc: Andy Gross, Bjorn Andersson,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, Rob Herring
Add dts nodes for apps_smmu and USB for both sm8150 and sm8250.
Also add initial dts files for HDK855 and HDK865, based on mtp dts, with a
few changes. Notably, the HDK865 dts has regulator config changed a bit based
on downstream (I think sm8250-mtp.dts is wrong and copied too much from sm8150).
Jonathan Marek (6):
arm64: dts: qcom: sm8150: add apps_smmu node
arm64: dts: qcom: sm8250: add apps_smmu node
arm64: dts: qcom: sm8150: Add secondary USB and PHY nodes
arm64: dts: qcom: sm8250: Add USB and PHY device nodes
arm64: dts: qcom: add sm8150 hdk dts
arm64: dts: qcom: add sm8250 hdk dts
arch/arm64/boot/dts/qcom/Makefile | 2 +
arch/arm64/boot/dts/qcom/sm8150-hdk.dts | 461 ++++++++++++++++++++++++
arch/arm64/boot/dts/qcom/sm8150.dtsi | 180 +++++++++
arch/arm64/boot/dts/qcom/sm8250-hdk.dts | 454 +++++++++++++++++++++++
arch/arm64/boot/dts/qcom/sm8250.dtsi | 287 +++++++++++++++
5 files changed, 1384 insertions(+)
create mode 100644 arch/arm64/boot/dts/qcom/sm8150-hdk.dts
create mode 100644 arch/arm64/boot/dts/qcom/sm8250-hdk.dts
--
2.26.1
^ permalink raw reply
* [PATCH 3/6] arm64: dts: qcom: sm8150: Add secondary USB and PHY nodes
From: Jonathan Marek @ 2020-05-24 2:38 UTC (permalink / raw)
To: linux-arm-msm
Cc: Andy Gross, Bjorn Andersson, Rob Herring,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list
In-Reply-To: <20200524023815.21789-1-jonathan@marek.ca>
Add dts nodes for the secondary USB controller and related PHY nodes.
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
---
arch/arm64/boot/dts/qcom/sm8150.dtsi | 89 ++++++++++++++++++++++++++++
1 file changed, 89 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
index acb839427b12..903514fc299f 100644
--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -636,6 +636,19 @@ usb_1_hsphy: phy@88e2000 {
resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
};
+ usb_2_hsphy: phy@88e3000 {
+ compatible = "qcom,sm8150-usb-hs-phy",
+ "qcom,usb-snps-hs-7nm-phy";
+ reg = <0 0x088e3000 0 0x400>;
+ status = "disabled";
+ #phy-cells = <0>;
+
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "ref";
+
+ resets = <&gcc GCC_QUSB2PHY_SEC_BCR>;
+ };
+
usb_1_qmpphy: phy@88e9000 {
compatible = "qcom,sm8150-qmp-usb3-phy";
reg = <0 0x088e9000 0 0x18c>,
@@ -671,6 +684,37 @@ usb_1_ssphy: lanes@88e9200 {
};
};
+ usb_2_qmpphy: phy@88eb000 {
+ compatible = "qcom,sm8150-qmp-usb3-uni-phy";
+ reg = <0 0x088eb000 0 0x200>;
+ status = "disabled";
+ #clock-cells = <1>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ clocks = <&gcc GCC_USB3_SEC_PHY_AUX_CLK>,
+ <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_USB3_SEC_CLKREF_CLK>,
+ <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>;
+ clock-names = "aux", "ref_clk_src", "ref", "com_aux";
+
+ resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR>,
+ <&gcc GCC_USB3_PHY_SEC_BCR>;
+ reset-names = "phy", "common";
+
+ usb_2_ssphy: lane@88eb200 {
+ reg = <0 0x088eb200 0 0x200>,
+ <0 0x088eb400 0 0x200>,
+ <0 0x088eb800 0 0x800>,
+ <0 0x088eb600 0 0x200>;
+ #phy-cells = <0>;
+ clocks = <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>;
+ clock-names = "pipe0";
+ clock-output-names = "usb3_uni_phy_pipe_clk_src";
+ };
+ };
+
usb_1: usb@a6f8800 {
compatible = "qcom,sm8150-dwc3", "qcom,dwc3";
reg = <0 0x0a6f8800 0 0x400>;
@@ -716,6 +760,51 @@ usb_1_dwc3: dwc3@a600000 {
};
};
+ usb_2: usb@a8f8800 {
+ compatible = "qcom,sm8150-dwc3", "qcom,dwc3";
+ reg = <0 0x0a8f8800 0 0x400>;
+ status = "disabled";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ dma-ranges;
+
+ clocks = <&gcc GCC_CFG_NOC_USB3_SEC_AXI_CLK>,
+ <&gcc GCC_USB30_SEC_MASTER_CLK>,
+ <&gcc GCC_AGGRE_USB3_SEC_AXI_CLK>,
+ <&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>,
+ <&gcc GCC_USB30_SEC_SLEEP_CLK>,
+ <&gcc GCC_USB3_SEC_CLKREF_CLK>;
+ clock-names = "cfg_noc", "core", "iface", "mock_utmi",
+ "sleep", "xo";
+
+ assigned-clocks = <&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>,
+ <&gcc GCC_USB30_SEC_MASTER_CLK>;
+ assigned-clock-rates = <19200000>, <200000000>;
+
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 490 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 491 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hs_phy_irq", "ss_phy_irq",
+ "dm_hs_phy_irq", "dp_hs_phy_irq";
+
+ power-domains = <&gcc USB30_SEC_GDSC>;
+
+ resets = <&gcc GCC_USB30_SEC_BCR>;
+
+ usb_2_dwc3: dwc3@a800000 {
+ compatible = "snps,dwc3";
+ reg = <0 0x0a800000 0 0xcd00>;
+ interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ iommus = <&apps_smmu 0x160 0>;
+ snps,dis_u2_susphy_quirk;
+ snps,dis_enblslpm_quirk;
+ phys = <&usb_2_hsphy>, <&usb_2_ssphy>;
+ phy-names = "usb2-phy", "usb3-phy";
+ };
+ };
+
aoss_qmp: power-controller@c300000 {
compatible = "qcom,sm8150-aoss-qmp";
reg = <0x0 0x0c300000 0x0 0x100000>;
--
2.26.1
^ permalink raw reply related
* [PATCH 4/6] arm64: dts: qcom: sm8250: Add USB and PHY device nodes
From: Jonathan Marek @ 2020-05-24 2:38 UTC (permalink / raw)
To: linux-arm-msm
Cc: Andy Gross, Bjorn Andersson, Rob Herring,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list
In-Reply-To: <20200524023815.21789-1-jonathan@marek.ca>
Add device nodes for the USB3 controller, QMP SS PHY and
SNPS HS PHY.
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
---
arch/arm64/boot/dts/qcom/sm8250.dtsi | 180 +++++++++++++++++++++++++++
1 file changed, 180 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
index 43c5e48c15e2..3bdce658c08a 100644
--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
@@ -387,6 +387,186 @@ tcsr_mutex: hwlock@1f40000 {
#hwlock-cells = <1>;
};
+ usb_1_hsphy: phy@88e3000 {
+ compatible = "qcom,sm8250-usb-hs-phy",
+ "qcom,usb-snps-hs-7nm-phy";
+ reg = <0 0x088e3000 0 0x400>;
+ status = "disabled";
+ #phy-cells = <0>;
+
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "ref";
+
+ resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
+ };
+
+ usb_2_hsphy: phy@88e4000 {
+ compatible = "qcom,sm8250-usb-hs-phy",
+ "qcom,usb-snps-hs-7nm-phy";
+ reg = <0 0x088e4000 0 0x400>;
+ status = "disabled";
+ #phy-cells = <0>;
+
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "ref";
+
+ resets = <&gcc GCC_QUSB2PHY_SEC_BCR>;
+ };
+
+ usb_1_qmpphy: phy@88e9000 {
+ compatible = "qcom,sm8250-qmp-usb3-phy";
+ reg = <0 0x088e9000 0 0x200>,
+ <0 0x088e8000 0 0x20>;
+ reg-names = "reg-base", "dp_com";
+ status = "disabled";
+ #clock-cells = <1>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>,
+ <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>;
+ clock-names = "aux", "ref_clk_src", "com_aux";
+
+ resets = <&gcc GCC_USB3_DP_PHY_PRIM_BCR>,
+ <&gcc GCC_USB3_PHY_PRIM_BCR>;
+ reset-names = "phy", "common";
+
+ usb_1_ssphy: lanes@88e9200 {
+ reg = <0 0x088e9200 0 0x200>,
+ <0 0x088e9400 0 0x200>,
+ <0 0x088e9c00 0 0x400>,
+ <0 0x088e9600 0 0x200>,
+ <0 0x088e9800 0 0x200>,
+ <0 0x088e9a00 0 0x100>;
+ #phy-cells = <0>;
+ clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+ clock-names = "pipe0";
+ clock-output-names = "usb3_phy_pipe_clk_src";
+ };
+ };
+
+ usb_2_qmpphy: phy@88eb000 {
+ compatible = "qcom,sm8250-qmp-usb3-uni-phy";
+ reg = <0 0x088eb000 0 0x200>;
+ status = "disabled";
+ #clock-cells = <1>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ clocks = <&gcc GCC_USB3_SEC_PHY_AUX_CLK>,
+ <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_USB3_SEC_CLKREF_EN>,
+ <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>;
+ clock-names = "aux", "ref_clk_src", "ref", "com_aux";
+
+ resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR>,
+ <&gcc GCC_USB3_PHY_SEC_BCR>;
+ reset-names = "phy", "common";
+
+ usb_2_ssphy: lane@88eb200 {
+ reg = <0 0x088eb200 0 0x200>,
+ <0 0x088eb400 0 0x200>,
+ <0 0x088eb800 0 0x800>;
+ #phy-cells = <0>;
+ clocks = <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>;
+ clock-names = "pipe0";
+ clock-output-names = "usb3_uni_phy_pipe_clk_src";
+ };
+ };
+
+ usb_1: usb@a6f8800 {
+ compatible = "qcom,sm8250-dwc3", "qcom,dwc3";
+ reg = <0 0x0a6f8800 0 0x400>;
+ status = "disabled";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ dma-ranges;
+
+ clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>,
+ <&gcc GCC_USB30_PRIM_MASTER_CLK>,
+ <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>,
+ <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
+ <&gcc GCC_USB30_PRIM_SLEEP_CLK>,
+ <&gcc GCC_USB3_SEC_CLKREF_EN>;
+ clock-names = "cfg_noc", "core", "iface", "mock_utmi",
+ "sleep", "xo";
+
+ assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
+ <&gcc GCC_USB30_PRIM_MASTER_CLK>;
+ assigned-clock-rates = <19200000>, <200000000>;
+
+ interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 17 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hs_phy_irq", "dp_hs_phy_irq",
+ "dm_hs_phy_irq", "ss_phy_irq";
+
+ power-domains = <&gcc USB30_PRIM_GDSC>;
+
+ resets = <&gcc GCC_USB30_PRIM_BCR>;
+
+ usb_1_dwc3: dwc3@a600000 {
+ compatible = "snps,dwc3";
+ reg = <0 0x0a600000 0 0xcd00>;
+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ iommus = <&apps_smmu 0x0 0x0>;
+ snps,dis_u2_susphy_quirk;
+ snps,dis_enblslpm_quirk;
+ phys = <&usb_1_hsphy>, <&usb_1_ssphy>;
+ phy-names = "usb2-phy", "usb3-phy";
+ };
+ };
+
+ usb_2: usb@a8f8800 {
+ compatible = "qcom,sm8250-dwc3", "qcom,dwc3";
+ reg = <0 0x0a8f8800 0 0x400>;
+ status = "disabled";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ dma-ranges;
+
+ clocks = <&gcc GCC_CFG_NOC_USB3_SEC_AXI_CLK>,
+ <&gcc GCC_USB30_SEC_MASTER_CLK>,
+ <&gcc GCC_AGGRE_USB3_SEC_AXI_CLK>,
+ <&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>,
+ <&gcc GCC_USB30_SEC_SLEEP_CLK>,
+ <&gcc GCC_USB3_SEC_CLKREF_EN>;
+ clock-names = "cfg_noc", "core", "iface", "mock_utmi",
+ "sleep", "xo";
+
+ assigned-clocks = <&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>,
+ <&gcc GCC_USB30_SEC_MASTER_CLK>;
+ assigned-clock-rates = <19200000>, <200000000>;
+
+ interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 12 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 13 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 16 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hs_phy_irq", "dp_hs_phy_irq",
+ "dm_hs_phy_irq", "ss_phy_irq";
+
+ power-domains = <&gcc USB30_SEC_GDSC>;
+
+ resets = <&gcc GCC_USB30_SEC_BCR>;
+
+ usb_2_dwc3: dwc3@a800000 {
+ compatible = "snps,dwc3";
+ reg = <0 0x0a800000 0 0xcd00>;
+ interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ iommus = <&apps_smmu 0x20 0>;
+ snps,dis_u2_susphy_quirk;
+ snps,dis_enblslpm_quirk;
+ phys = <&usb_2_hsphy>, <&usb_2_ssphy>;
+ phy-names = "usb2-phy", "usb3-phy";
+ };
+ };
+
pdc: interrupt-controller@b220000 {
compatible = "qcom,sm8250-pdc", "qcom,pdc";
reg = <0 0x0b220000 0 0x30000>, <0 0x17c000f0 0 0x60>;
--
2.26.1
^ permalink raw reply related
* [PATCH 5/6] arm64: dts: qcom: add sm8150 hdk dts
From: Jonathan Marek @ 2020-05-24 2:38 UTC (permalink / raw)
To: linux-arm-msm
Cc: Andy Gross, Bjorn Andersson, Rob Herring,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list
In-Reply-To: <20200524023815.21789-1-jonathan@marek.ca>
Add initial HDK855 dts, based on sm8150-mtp, with a few changes.
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
---
arch/arm64/boot/dts/qcom/Makefile | 1 +
arch/arm64/boot/dts/qcom/sm8150-hdk.dts | 461 ++++++++++++++++++++++++
2 files changed, 462 insertions(+)
create mode 100644 arch/arm64/boot/dts/qcom/sm8150-hdk.dts
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index cc103f7020fd..e5dbd8b63951 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -22,6 +22,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sdm845-cheza-r3.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm845-db845c.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm845-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm850-lenovo-yoga-c630.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sm8150-hdk.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8150-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8250-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-1000.dtb
diff --git a/arch/arm64/boot/dts/qcom/sm8150-hdk.dts b/arch/arm64/boot/dts/qcom/sm8150-hdk.dts
new file mode 100644
index 000000000000..95b54fa8254a
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8150-hdk.dts
@@ -0,0 +1,461 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "sm8150.dtsi"
+#include "pm8150.dtsi"
+#include "pm8150b.dtsi"
+#include "pm8150l.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SM8150 HDK";
+ compatible = "qcom,sm8150-hdk";
+
+ aliases {
+ serial0 = &uart2;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ vph_pwr: vph-pwr-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vph_pwr";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+ };
+
+ /*
+ * Apparently RPMh does not provide support for PM8150 S4 because it
+ * is always-on; model it as a fixed regulator.
+ */
+ vreg_s4a_1p8: pm8150-s4 {
+ compatible = "regulator-fixed";
+ regulator-name = "vreg_s4a_1p8";
+
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-always-on;
+ regulator-boot-on;
+
+ vin-supply = <&vph_pwr>;
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ vol-up {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ gpios = <&pm8150_gpios 6 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&apps_rsc {
+ pm8150-rpmh-regulators {
+ compatible = "qcom,pm8150-rpmh-regulators";
+ qcom,pmic-id = "a";
+
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vph_pwr>;
+ vdd-s3-supply = <&vph_pwr>;
+ vdd-s4-supply = <&vph_pwr>;
+ vdd-s5-supply = <&vph_pwr>;
+ vdd-s6-supply = <&vph_pwr>;
+ vdd-s7-supply = <&vph_pwr>;
+ vdd-s8-supply = <&vph_pwr>;
+ vdd-s9-supply = <&vph_pwr>;
+ vdd-s10-supply = <&vph_pwr>;
+
+ vdd-l1-l8-l11-supply = <&vreg_s6a_0p9>;
+ vdd-l2-l10-supply = <&vreg_bob>;
+ vdd-l3-l4-l5-l18-supply = <&vreg_s6a_0p9>;
+ vdd-l6-l9-supply = <&vreg_s8c_1p3>;
+ vdd-l7-l12-l14-l15-supply = <&vreg_s5a_2p0>;
+ vdd-l13-l16-l17-supply = <&vreg_bob>;
+
+ vreg_s5a_2p0: smps5 {
+ regulator-min-microvolt = <1904000>;
+ regulator-max-microvolt = <2000000>;
+ };
+
+ vreg_s6a_0p9: smps6 {
+ regulator-min-microvolt = <920000>;
+ regulator-max-microvolt = <1128000>;
+ };
+
+ vdda_wcss_pll:
+ vreg_l1a_0p75: ldo1 {
+ regulator-min-microvolt = <752000>;
+ regulator-max-microvolt = <752000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdd_pdphy:
+ vdda_usb_hs_3p1:
+ vreg_l2a_3p1: ldo2 {
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3072000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3a_0p8: ldo3 {
+ regulator-min-microvolt = <480000>;
+ regulator-max-microvolt = <932000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdd_usb_hs_core:
+ vdda_csi_0_0p9:
+ vdda_csi_1_0p9:
+ vdda_csi_2_0p9:
+ vdda_csi_3_0p9:
+ vdda_dsi_0_0p9:
+ vdda_dsi_1_0p9:
+ vdda_dsi_0_pll_0p9:
+ vdda_dsi_1_pll_0p9:
+ vdda_pcie_1ln_core:
+ vdda_pcie_2ln_core:
+ vdda_pll_hv_cc_ebi01:
+ vdda_pll_hv_cc_ebi23:
+ vdda_qrefs_0p875_5:
+ vdda_sp_sensor:
+ vdda_ufs_2ln_core_1:
+ vdda_ufs_2ln_core_2:
+ vdda_usb_ss_dp_core_1:
+ vdda_usb_ss_dp_core_2:
+ vdda_qlink_lv:
+ vdda_qlink_lv_ck:
+ vreg_l5a_0p875: ldo5 {
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6a_1p2: ldo6 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7a_1p8: ldo7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vddpx_10:
+ vreg_l9a_1p2: ldo9 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l10a_2p5: ldo10 {
+ regulator-min-microvolt = <2504000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l11a_0p8: ldo11 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdd_qfprom:
+ vdd_qfprom_sp:
+ vdda_apc_cs_1p8:
+ vdda_gfx_cs_1p8:
+ vdda_usb_hs_1p8:
+ vdda_qrefs_vref_1p8:
+ vddpx_10_a:
+ vreg_l12a_1p8: ldo12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l13a_2p7: ldo13 {
+ regulator-min-microvolt = <2704000>;
+ regulator-max-microvolt = <2704000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l14a_1p8: ldo14 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l15a_1p7: ldo15 {
+ regulator-min-microvolt = <1704000>;
+ regulator-max-microvolt = <1704000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l16a_2p7: ldo16 {
+ regulator-min-microvolt = <2704000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l17a_3p0: ldo17 {
+ regulator-min-microvolt = <2856000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ pm8150l-rpmh-regulators {
+ compatible = "qcom,pm8150l-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vph_pwr>;
+ vdd-s3-supply = <&vph_pwr>;
+ vdd-s4-supply = <&vph_pwr>;
+ vdd-s5-supply = <&vph_pwr>;
+ vdd-s6-supply = <&vph_pwr>;
+ vdd-s7-supply = <&vph_pwr>;
+ vdd-s8-supply = <&vph_pwr>;
+
+ vdd-l1-l8-supply = <&vreg_s4a_1p8>;
+ vdd-l2-l3-supply = <&vreg_s8c_1p3>;
+ vdd-l4-l5-l6-supply = <&vreg_bob>;
+ vdd-l7-l11-supply = <&vreg_bob>;
+ vdd-l9-l10-supply = <&vreg_bob>;
+
+ vdd-bob-supply = <&vph_pwr>;
+ vdd-flash-supply = <&vreg_bob>;
+ vdd-rgb-supply = <&vreg_bob>;
+
+ vreg_bob: bob {
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <4000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+ regulator-allow-bypass;
+ };
+
+ vreg_s8c_1p3: smps8 {
+ regulator-min-microvolt = <1352000>;
+ regulator-max-microvolt = <1352000>;
+ };
+
+ vreg_l1c_1p8: ldo1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdda_wcss_adcdac_1:
+ vdda_wcss_adcdac_22:
+ vreg_l2c_1p3: ldo2 {
+ regulator-min-microvolt = <1304000>;
+ regulator-max-microvolt = <1304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdda_hv_ebi0:
+ vdda_hv_ebi1:
+ vdda_hv_ebi2:
+ vdda_hv_ebi3:
+ vdda_hv_refgen0:
+ vdda_qlink_hv_ck:
+ vreg_l3c_1p2: ldo3 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vddpx_5:
+ vreg_l4c_1p8: ldo4 {
+ regulator-min-microvolt = <1704000>;
+ regulator-max-microvolt = <2928000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vddpx_6:
+ vreg_l5c_1p8: ldo5 {
+ regulator-min-microvolt = <1704000>;
+ regulator-max-microvolt = <2928000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vddpx_2:
+ vreg_l6c_2p9: ldo6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7c_3p0: ldo7 {
+ regulator-min-microvolt = <2856000>;
+ regulator-max-microvolt = <3104000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8c_1p8: ldo8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9c_2p9: ldo9 {
+ regulator-min-microvolt = <2704000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l10c_3p3: ldo10 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3312000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l11c_3p3: ldo11 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3312000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ pm8009-rpmh-regulators {
+ compatible = "qcom,pm8009-rpmh-regulators";
+ qcom,pmic-id = "f";
+
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vreg_bob>;
+
+ vdd-l2-supply = <&vreg_s8c_1p3>;
+ vdd-l5-l6-supply = <&vreg_bob>;
+
+ vreg_l2f_1p2: ldo2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5f_2p85: ldo5 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6f_2p85: ldo6 {
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-min-microvolt = <2856000>;
+ regulator-max-microvolt = <2856000>;
+ };
+ };
+};
+
+&qupv3_id_1 {
+ status = "okay";
+};
+
+&pon {
+ pwrkey {
+ status = "okay";
+ };
+
+ resin {
+ compatible = "qcom,pm8941-resin";
+ interrupts = <0x0 0x8 0x1 IRQ_TYPE_EDGE_BOTH>;
+ debounce = <15625>;
+ bias-pull-up;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+};
+
+&remoteproc_adsp {
+ status = "okay";
+};
+
+&remoteproc_cdsp {
+ status = "okay";
+};
+
+&remoteproc_slpi {
+ status = "okay";
+};
+
+&tlmm {
+ gpio-reserved-ranges = <0 4>, <126 4>;
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&ufs_mem_hc {
+ status = "okay";
+
+ reset-gpios = <&tlmm 175 GPIO_ACTIVE_LOW>;
+
+ vcc-supply = <&vreg_l10a_2p5>;
+ vcc-max-microamp = <750000>;
+ vccq-supply = <&vreg_l9a_1p2>;
+ vccq-max-microamp = <700000>;
+ vccq2-supply = <&vreg_s4a_1p8>;
+ vccq2-max-microamp = <750000>;
+};
+
+&ufs_mem_phy {
+ status = "okay";
+
+ vdda-phy-supply = <&vdda_ufs_2ln_core_1>;
+ vdda-max-microamp = <90200>;
+ vdda-pll-supply = <&vreg_l3c_1p2>;
+ vdda-pll-max-microamp = <19000>;
+};
+
+&usb_1_hsphy {
+ status = "okay";
+ vdda-pll-supply = <&vdd_usb_hs_core>;
+ vdda33-supply = <&vdda_usb_hs_3p1>;
+ vdda18-supply = <&vdda_usb_hs_1p8>;
+};
+
+&usb_2_hsphy {
+ status = "okay";
+ vdda-pll-supply = <&vdd_usb_hs_core>;
+ vdda33-supply = <&vdda_usb_hs_3p1>;
+ vdda18-supply = <&vdda_usb_hs_1p8>;
+};
+
+&usb_1_qmpphy {
+ status = "okay";
+ vdda-phy-supply = <&vreg_l3c_1p2>;
+ vdda-pll-supply = <&vdda_usb_ss_dp_core_1>;
+};
+
+&usb_2_qmpphy {
+ status = "okay";
+ vdda-phy-supply = <&vreg_l3c_1p2>;
+ vdda-pll-supply = <&vdda_usb_ss_dp_core_1>;
+};
+
+&usb_1 {
+ status = "okay";
+};
+
+&usb_2 {
+ status = "okay";
+};
+
+&usb_1_dwc3 {
+ dr_mode = "peripheral";
+};
+
+&usb_2_dwc3 {
+ dr_mode = "host";
+};
--
2.26.1
^ permalink raw reply related
* [PATCH 6/6] arm64: dts: qcom: add sm8250 hdk dts
From: Jonathan Marek @ 2020-05-24 2:38 UTC (permalink / raw)
To: linux-arm-msm
Cc: Andy Gross, Bjorn Andersson, Rob Herring,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list
In-Reply-To: <20200524023815.21789-1-jonathan@marek.ca>
Add initial HDK865 dts, based on sm8250-mtp, with a few changes.
Notably, regulator configs are changed a bit.
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
---
arch/arm64/boot/dts/qcom/Makefile | 1 +
arch/arm64/boot/dts/qcom/sm8250-hdk.dts | 454 ++++++++++++++++++++++++
2 files changed, 455 insertions(+)
create mode 100644 arch/arm64/boot/dts/qcom/sm8250-hdk.dts
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index e5dbd8b63951..4649e8bc5034 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -24,6 +24,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sdm845-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm850-lenovo-yoga-c630.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8150-hdk.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8150-mtp.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sm8250-hdk.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8250-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-1000.dtb
dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-4000.dtb
diff --git a/arch/arm64/boot/dts/qcom/sm8250-hdk.dts b/arch/arm64/boot/dts/qcom/sm8250-hdk.dts
new file mode 100644
index 000000000000..d35014bf4f81
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8250-hdk.dts
@@ -0,0 +1,454 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "sm8250.dtsi"
+#include "pm8150.dtsi"
+#include "pm8150b.dtsi"
+#include "pm8150l.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SM8250 HDK";
+ compatible = "qcom,sm8250-hdk";
+
+ aliases {
+ serial0 = &uart2;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ vph_pwr: vph-pwr-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vph_pwr";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+ };
+
+ vreg_s4a_1p8: pm8150-s4 {
+ compatible = "regulator-fixed";
+ regulator-name = "vreg_s4a_1p8";
+
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-always-on;
+ regulator-boot-on;
+
+ vin-supply = <&vph_pwr>;
+ };
+
+ vreg_s6c_0p88: smpc6-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vreg_s6c_0p88";
+
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ regulator-always-on;
+ vin-supply = <&vph_pwr>;
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ vol-up {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ gpios = <&pm8150_gpios 6 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&apps_rsc {
+ pm8150-rpmh-regulators {
+ compatible = "qcom,pm8150-rpmh-regulators";
+ qcom,pmic-id = "a";
+
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vph_pwr>;
+ vdd-s3-supply = <&vph_pwr>;
+ vdd-s4-supply = <&vph_pwr>;
+ vdd-s5-supply = <&vph_pwr>;
+ vdd-s6-supply = <&vph_pwr>;
+ vdd-s7-supply = <&vph_pwr>;
+ vdd-s8-supply = <&vph_pwr>;
+ vdd-s9-supply = <&vph_pwr>;
+ vdd-s10-supply = <&vph_pwr>;
+ vdd-l1-l8-l11-supply = <&vreg_s6c_0p88>;
+ vdd-l2-l10-supply = <&vreg_bob>;
+ vdd-l3-l4-l5-l18-supply = <&vreg_s6a_0p95>;
+ vdd-l6-l9-supply = <&vreg_s8c_1p3>;
+ vdd-l7-l12-l14-l15-supply = <&vreg_s5a_1p9>;
+ vdd-l13-l16-l17-supply = <&vreg_bob>;
+
+ vreg_s5a_1p9: smps5 {
+ regulator-name = "vreg_s5a_1p9";
+ regulator-min-microvolt = <1824000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s6a_0p95: smps6 {
+ regulator-name = "vreg_s6a_0p95";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1128000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2a_3p1: ldo2 {
+ regulator-name = "vreg_l2a_3p1";
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3072000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3a_0p9: ldo3 {
+ regulator-name = "vreg_l3a_0p9";
+ regulator-min-microvolt = <928000>;
+ regulator-max-microvolt = <932000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5a_0p88: ldo5 {
+ regulator-name = "vreg_l5a_0p88";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6a_1p2: ldo6 {
+ regulator-name = "vreg_l6a_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7a_1p7: ldo7 {
+ regulator-name = "vreg_l7a_1p7";
+ regulator-min-microvolt = <1704000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9a_1p2: ldo9 {
+ regulator-name = "vreg_l9a_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l10a_1p8: ldo10 {
+ regulator-name = "vreg_l10a_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l12a_1p8: ldo12 {
+ regulator-name = "vreg_l12a_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l13a_ts_3p0: ldo13 {
+ regulator-name = "vreg_l13a_ts_3p0";
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l14a_1p8: ldo14 {
+ regulator-name = "vreg_l14a_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l15a_1p8: ldo15 {
+ regulator-name = "vreg_l15a_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l16a_3p3: ldo16 {
+ regulator-name = "vreg_l16a_3p3";
+ regulator-min-microvolt = <3024000>;
+ regulator-max-microvolt = <3304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l17a_2p96: ldo17 {
+ regulator-name = "vreg_l17a_2p96";
+ regulator-min-microvolt = <2496000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l18a_0p92: ldo18 {
+ regulator-name = "vreg_l18a_0p92";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ pm8150l-rpmh-regulators {
+ compatible = "qcom,pm8150l-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vph_pwr>;
+ vdd-s3-supply = <&vph_pwr>;
+ vdd-s4-supply = <&vph_pwr>;
+ vdd-s5-supply = <&vph_pwr>;
+ vdd-s6-supply = <&vph_pwr>;
+ vdd-s7-supply = <&vph_pwr>;
+ vdd-s8-supply = <&vph_pwr>;
+ vdd-l1-l8-supply = <&vreg_s4a_1p8>;
+ vdd-l2-l3-supply = <&vreg_s8c_1p3>;
+ vdd-l4-l5-l6-supply = <&vreg_bob>;
+ vdd-l7-l11-supply = <&vreg_bob>;
+ vdd-l9-l10-supply = <&vreg_bob>;
+ vdd-bob-supply = <&vph_pwr>;
+
+ vreg_bob: bob {
+ regulator-name = "vreg_bob";
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+ };
+
+ vreg_s8c_1p3: smps8 {
+ regulator-name = "vreg_s8c_1p3";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1c_1p8: ldo1 {
+ regulator-name = "vreg_l1c_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2c_1p2: ldo2 {
+ regulator-name = "vreg_l2c_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3c_0p8: ldo3 {
+ regulator-name = "vreg_l3c_0p8";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4c_1p8: ldo4 {
+ regulator-name = "vreg_l4c_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5c_1p8: ldo5 {
+ regulator-name = "vreg_l5c_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6c_2p96: ldo6 {
+ regulator-name = "vreg_l6c_2p96";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7c_cam_vcm0_2p85: ldo7 {
+ regulator-name = "vreg_l7c_cam_vcm0_2p85";
+ regulator-min-microvolt = <2856000>;
+ regulator-max-microvolt = <3104000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8c_1p8: ldo8 {
+ regulator-name = "vreg_l8c_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9c_2p96: ldo9 {
+ regulator-name = "vreg_l9c_2p96";
+ regulator-min-microvolt = <2704000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l10c_3p0: ldo10 {
+ regulator-name = "vreg_l10c_3p0";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3312000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l11c_3p3: ldo11 {
+ regulator-name = "vreg_l11c_3p3";
+ regulator-min-microvolt = <3104000>;
+ regulator-max-microvolt = <3312000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ pm8009-rpmh-regulators {
+ compatible = "qcom,pm8009-rpmh-regulators";
+ qcom,pmic-id = "f";
+
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vreg_bob>;
+ vdd-l2-supply = <&vreg_s8c_1p3>;
+ vdd-l5-l6-supply = <&vreg_bob>;
+ vdd-l7-supply = <&vreg_s4a_1p8>;
+
+ vreg_l1f_cam_dvdd1_1p1: ldo1 {
+ regulator-name = "vreg_l1f_cam_dvdd1_1p1";
+ regulator-min-microvolt = <1104000>;
+ regulator-max-microvolt = <1104000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2f_cam_dvdd0_1p2: ldo2 {
+ regulator-name = "vreg_l2f_cam_dvdd0_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3f_cam_dvdd2_1p05: ldo3 {
+ regulator-name = "vreg_l3f_cam_dvdd2_1p05";
+ regulator-min-microvolt = <1056000>;
+ regulator-max-microvolt = <1056000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5f_cam_avdd0_2p85: ldo5 {
+ regulator-name = "vreg_l5f_cam_avdd0_2p85";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6f_cam_avdd1_2p8: ldo6 {
+ regulator-name = "vreg_l6f_cam_avdd1_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7f_1p8: ldo7 {
+ regulator-name = "vreg_l7f_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+};
+
+&qupv3_id_1 {
+ status = "okay";
+};
+
+&pon {
+ pwrkey {
+ status = "okay";
+ };
+
+ resin {
+ compatible = "qcom,pm8941-resin";
+ interrupts = <0x0 0x8 0x1 IRQ_TYPE_EDGE_BOTH>;
+ debounce = <15625>;
+ bias-pull-up;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+};
+
+&tlmm {
+ gpio-reserved-ranges = <28 4>, <40 4>;
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&ufs_mem_hc {
+ status = "okay";
+
+ vcc-supply = <&vreg_l17a_2p96>;
+ vcc-max-microamp = <800000>;
+ vccq-supply = <&vreg_l6a_1p2>;
+ vccq-max-microamp = <800000>;
+ vccq2-supply = <&vreg_s4a_1p8>;
+ vccq2-max-microamp = <800000>;
+};
+
+&ufs_mem_phy {
+ status = "okay";
+
+ vdda-phy-supply = <&vreg_l5a_0p88>;
+ vdda-max-microamp = <89900>;
+ vdda-pll-supply = <&vreg_l9a_1p2>;
+ vdda-pll-max-microamp = <18800>;
+};
+
+&usb_1_hsphy {
+ status = "okay";
+ vdda-pll-supply = <&vreg_l5a_0p88>;
+ vdda33-supply = <&vreg_l2a_3p1>;
+ vdda18-supply = <&vreg_l12a_1p8>;
+};
+
+&usb_2_hsphy {
+ status = "okay";
+ vdda-pll-supply = <&vreg_l5a_0p88>;
+ vdda33-supply = <&vreg_l2a_3p1>;
+ vdda18-supply = <&vreg_l12a_1p8>;
+};
+
+&usb_1_qmpphy {
+ status = "okay";
+ vdda-phy-supply = <&vreg_l9a_1p2>;
+ vdda-pll-supply = <&vreg_l18a_0p92>;
+};
+
+&usb_2_qmpphy {
+ status = "okay";
+ vdda-phy-supply = <&vreg_l9a_1p2>;
+ vdda-pll-supply = <&vreg_l18a_0p92>;
+};
+
+&usb_1 {
+ status = "okay";
+};
+
+&usb_2 {
+ status = "okay";
+};
+
+&usb_1_dwc3 {
+ dr_mode = "peripheral";
+};
+
+&usb_2_dwc3 {
+ dr_mode = "host";
+};
--
2.26.1
^ permalink raw reply related
* [PATCH 2/6] arm64: dts: qcom: sm8250: add apps_smmu node
From: Jonathan Marek @ 2020-05-24 2:38 UTC (permalink / raw)
To: linux-arm-msm
Cc: Andy Gross, Bjorn Andersson, Rob Herring,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list
In-Reply-To: <20200524023815.21789-1-jonathan@marek.ca>
Add the apps_smmu node for sm8250. Note that adding the iommus field for
UFS is required because initializing the iommu removes the bypass mapping
that created by the bootloader.
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
---
arch/arm64/boot/dts/qcom/sm8250.dtsi | 107 +++++++++++++++++++++++++++
1 file changed, 107 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
index 2f99c350c287..43c5e48c15e2 100644
--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
@@ -323,6 +323,8 @@ ufs_mem_hc: ufshc@1d84000 {
power-domains = <&gcc UFS_PHY_GDSC>;
+ iommus = <&apps_smmu 0x0e0 0>, <&apps_smmu 0x4e0 0>;
+
clock-names =
"core_clk",
"bus_aggr_clk",
@@ -428,6 +430,111 @@ tlmm: pinctrl@f100000 {
wakeup-parent = <&pdc>;
};
+ apps_smmu: iommu@15000000 {
+ compatible = "qcom,sdm845-smmu-500", "arm,mmu-500";
+ reg = <0 0x15000000 0 0x100000>;
+ #iommu-cells = <2>;
+ #global-interrupts = <2>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 690 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 691 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 692 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 693 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 694 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 695 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 696 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 697 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 707 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
intc: interrupt-controller@17a00000 {
compatible = "arm,gic-v3";
#interrupt-cells = <3>;
--
2.26.1
^ permalink raw reply related
* [PATCH 1/6] arm64: dts: qcom: sm8150: add apps_smmu node
From: Jonathan Marek @ 2020-05-24 2:38 UTC (permalink / raw)
To: linux-arm-msm
Cc: Andy Gross, Bjorn Andersson, Rob Herring,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list
In-Reply-To: <20200524023815.21789-1-jonathan@marek.ca>
Add the apps_smmu node for sm8150. Note that adding the iommus field for
UFS is required because initializing the iommu removes the bypass mapping
that created by the bootloader.
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
---
arch/arm64/boot/dts/qcom/sm8150.dtsi | 91 ++++++++++++++++++++++++++++
1 file changed, 91 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
index a36512d1f6a1..acb839427b12 100644
--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -442,6 +442,8 @@ ufs_mem_hc: ufshc@1d84000 {
resets = <&gcc GCC_UFS_PHY_BCR>;
reset-names = "rst";
+ iommus = <&apps_smmu 0x300 0>;
+
clock-names =
"core_clk",
"bus_aggr_clk",
@@ -706,6 +708,7 @@ usb_1_dwc3: dwc3@a600000 {
compatible = "snps,dwc3";
reg = <0 0x0a600000 0 0xcd00>;
interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ iommus = <&apps_smmu 0x140 0>;
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
phys = <&usb_1_hsphy>, <&usb_1_ssphy>;
@@ -742,6 +745,94 @@ spmi_bus: spmi@c440000 {
cell-index = <0>;
};
+ apps_smmu: iommu@15000000 {
+ compatible = "qcom,sdm845-smmu-500", "arm,mmu-500";
+ reg = <0 0x15000000 0 0x100000>;
+ #iommu-cells = <2>;
+ #global-interrupts = <1>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
remoteproc_adsp: remoteproc@17300000 {
compatible = "qcom,sm8150-adsp-pas";
reg = <0x0 0x17300000 0x0 0x4040>;
--
2.26.1
^ permalink raw reply related
* Re: [PATCH v13 2/2] media: v4l: xilinx: Add Xilinx MIPI CSI-2 Rx Subsystem driver
From: Laurent Pinchart @ 2020-05-24 2:27 UTC (permalink / raw)
To: Vishal Sagar
Cc: Hyun Kwon, mchehab, robh+dt, mark.rutland, Michal Simek,
linux-media, devicetree, hans.verkuil, linux-arm-kernel,
linux-kernel, Dinesh Kumar, Sandip Kothari, Luca Ceresoli,
Jacopo Mondi, Hyun Kwon
In-Reply-To: <20200512151947.120348-3-vishal.sagar@xilinx.com>
Hi Vishal,
Thank you for the patch.
On Tue, May 12, 2020 at 08:49:47PM +0530, Vishal Sagar wrote:
> The Xilinx MIPI CSI-2 Rx Subsystem soft IP is used to capture images
> from MIPI CSI-2 camera sensors and output AXI4-Stream video data ready
> for image processing. Please refer to PG232 for details.
>
> The CSI2 Rx controller filters out all packets except for the packets
> with data type fixed in hardware. RAW8 packets are always allowed to
> pass through.
>
> It is also used to setup and handle interrupts and enable the core. It
> logs all the events in respective counters between streaming on and off.
>
> The driver supports only the video format bridge enabled configuration.
> Some data types like YUV 422 10bpc, RAW16, RAW20 are supported when the
> CSI v2.0 feature is enabled in design. When the VCX feature is enabled,
> the maximum number of virtual channels becomes 16 from 4.
>
> Signed-off-by: Vishal Sagar <vishal.sagar@xilinx.com>
> Reviewed-by: Hyun Kwon <hyun.kwon@xilinx.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> v13
> - Based on Laurent's suggestions
> - Removed unnecessary debug statement for vep
> - Added TODO for clock to enable disable at streamon/off
> - Fix for index to start from 0 for get_nth_mbus_format
> - Removed macro XCSI_TIMEOUT_VAL
> - Remove ndelay from hard reset
> - Remove hard reset from irq handler
> - Fix short packet fifo clear
> - Add TODO for v4l2_subdev_notify for SLBF error
> - Fix the enable condition in s_stream
> - Fix condition in xcsi2rxss_set_format
> - Fix enum_mbus_code for double enumeration of RAW8 Data type
> - Removed core struct
> - Added reviewed by Laurent
>
> v12
> - Changes done as suggested by Laurent Pinchart and Luca Ceresoli
> - Removed unused macros
> - No local storage of supported formats
> - Dropped init mbus fmts and removed xcsi2rxss_init_mbus_fmts()
> - XCSI_GET_BITSET_STR removed
> - Add data type and mbus LUT
> - Added xcsi2rxss_get_nth_mbus() and xcsi2rxss_get_dt()
> - Replaced all core->dev with dev in dev_dbg() and related debug prints
> - Replaced xcsi2rxss_log_ipconfig() with single line
> - Removed small functions to enable/disable interrupts and core
> - Now save remote subdev in state struct before streaming on
> - Made xcsi2rxss_reset as soft_reset()
> - Added hard reset using video-reset gpio
> - 2 modes one with delay and another sleep
> - Instead of reset-gpios it is not video-reset-gpios
> - In irq handler
> - Moved clearing of ISR up
> - Dump / empty short packet fifo
> - Irq handler is now threaded
> - Added init_cfg pad ops and removed open()
> - Updated xcsi2rxss_set_format(), xcsi2rxss_enum_mbus_code() to use the dt mbus lut
> - xcsi2rxss_set_default_format() updated
> - Moved mutex_init()
> - Updated graph handling
> - Removed unnecessary prints
> - Use devm_platform_ioremap_resource() and platform_get_irq()
> - Update KConfig description
>
> v11
> - Fixed changes as suggested by Sakari Ailus
> - Removed VIDEO_XILINX from KConfig
> - Minor formatting
> - Start / Stop upstream sub-device in xcsi2rxss_start_stream()
> and xcsi2rxss_stop_stream()
> - Added v4l2_subdev_link_validate_default() in v4l2_subdev_pad_ops()
> - Use fwnode_graph_get_endpoint_by_id() instead of parsing by self
> - Set bus type as V4L2_MBUS_CSI2_DPHY in struct v4l2_fwnode_endpoint
> - Remove num_clks from core. Instead use ARRAY_SIZE()
> - Fixed SPDX header to GPL-2.0
> - Update copyright year to 2020
>
> v10
> - Removed all V4L2 controls and events based on Sakari's comments.
> - Now stop_stream() before toggling rst_gpio
> - Updated init_mbus() to throw error on array out of bound access
> - Make events and vcx_events as counters instead of structures
> - Minor fixes in set_format() enum_mbus_code() as suggested by Sakari
>
> v9
> - Moved all controls and events to xilinx-csi2rxss.h
> - Updated name and description of controls and events
> - Get control base address from v4l2-controls.h (0x10c0)
> - Fix KConfig for dependency on VIDEO_XILINX
> - Added enum_mbus_code() support
> - Added default format to be returned on open()
> - Mark variables are const
> - Remove references to short packet in comments
> - Add check for streaming before setting active lanes control
> - strlcpy -> strscpy
> - Fix xcsi2rxss_set_format()
>
> v8
> - Use clk_bulk* APIs
> - Add gpio reset for asserting video_aresetn when stream line buffer occurs
> - Removed short packet related events and irq handling
> - V4L2_EVENT_XLNXCSIRX_SPKT and V4L2_EVENT_XLNXCSIRX_SPKT_OVF removed
> - Removed frame counter control V4L2_CID_XILINX_MIPICSISS_FRAME_COUNTER
> and xcsi2rxss_g_volatile_ctrl()
> - Minor formatting fixes
>
> v7
> - No change
>
> v6
> - No change
>
> v5
> - Removed bayer and updated related parts like set default format based
> on Luca Cersoli's comments.
> - Added correct YUV422 10bpc media bus format
>
> v4
> - Removed irq member from core structure
> - Consolidated IP config prints in xcsi2rxss_log_ipconfig()
> - Return -EINVAL in case of invalid ioctl
> - Code formatting
> - Added reviewed by Hyun Kwon
>
> v3
> - Fixed comments given by Hyun.
> - Removed DPHY 200 MHz clock. This will be controlled by DPHY driver
> - Minor code formatting
> - en_csi_v20 and vfb members removed from struct and made local to dt parsing
> - lock description updated
> - changed to ratelimited type for all dev prints in irq handler
> - Removed YUV 422 10bpc media format
>
> v2
> - Fixed comments given by Hyun and Sakari.
> - Made all bitmask using BIT() and GENMASK()
> - Removed unused definitions
> - Removed DPHY access. This will be done by separate DPHY PHY driver.
> - Added support for CSI v2.0 for YUV 422 10bpc, RAW16, RAW20 and extra
> virtual channels
> - Fixed the ports as sink and source
> - Now use the v4l2fwnode API to get number of data-lanes
> - Added clock framework support
> - Removed the close() function
> - updated the set format function
> - support only VFB enabled configuration
>
> drivers/media/platform/xilinx/Kconfig | 7 +
> drivers/media/platform/xilinx/Makefile | 1 +
> .../media/platform/xilinx/xilinx-csi2rxss.c | 1114 +++++++++++++++++
> 3 files changed, 1122 insertions(+)
> create mode 100644 drivers/media/platform/xilinx/xilinx-csi2rxss.c
>
> diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig
> index 01c96fb66414..44587dccacf1 100644
> --- a/drivers/media/platform/xilinx/Kconfig
> +++ b/drivers/media/platform/xilinx/Kconfig
> @@ -12,6 +12,13 @@ config VIDEO_XILINX
>
> if VIDEO_XILINX
>
> +config VIDEO_XILINX_CSI2RXSS
> + tristate "Xilinx CSI-2 Rx Subsystem"
> + help
> + Driver for Xilinx MIPI CSI-2 Rx Subsystem. This is a V4L sub-device
> + based driver that takes input from CSI-2 Tx source and converts
> + it into an AXI4-Stream.
> +
> config VIDEO_XILINX_TPG
> tristate "Xilinx Video Test Pattern Generator"
> depends on VIDEO_XILINX
> diff --git a/drivers/media/platform/xilinx/Makefile b/drivers/media/platform/xilinx/Makefile
> index 4cdc0b1ec7a5..6119a34f3043 100644
> --- a/drivers/media/platform/xilinx/Makefile
> +++ b/drivers/media/platform/xilinx/Makefile
> @@ -3,5 +3,6 @@
> xilinx-video-objs += xilinx-dma.o xilinx-vip.o xilinx-vipp.o
>
> obj-$(CONFIG_VIDEO_XILINX) += xilinx-video.o
> +obj-$(CONFIG_VIDEO_XILINX_CSI2RXSS) += xilinx-csi2rxss.o
> obj-$(CONFIG_VIDEO_XILINX_TPG) += xilinx-tpg.o
> obj-$(CONFIG_VIDEO_XILINX_VTC) += xilinx-vtc.o
> diff --git a/drivers/media/platform/xilinx/xilinx-csi2rxss.c b/drivers/media/platform/xilinx/xilinx-csi2rxss.c
> new file mode 100644
> index 000000000000..cac08149ae7a
> --- /dev/null
> +++ b/drivers/media/platform/xilinx/xilinx-csi2rxss.c
> @@ -0,0 +1,1114 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Driver for Xilinx MIPI CSI-2 Rx Subsystem
> + *
> + * Copyright (C) 2016 - 2020 Xilinx, Inc.
> + *
> + * Contacts: Vishal Sagar <vishal.sagar@xilinx.com>
> + *
> + */
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/v4l2-subdev.h>
> +#include <media/media-entity.h>
> +#include <media/v4l2-common.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-fwnode.h>
> +#include <media/v4l2-subdev.h>
> +#include "xilinx-vip.h"
> +
> +/* Register register map */
> +#define XCSI_CCR_OFFSET 0x00
> +#define XCSI_CCR_SOFTRESET BIT(1)
> +#define XCSI_CCR_ENABLE BIT(0)
> +
> +#define XCSI_PCR_OFFSET 0x04
> +#define XCSI_PCR_MAXLANES_MASK GENMASK(4, 3)
> +#define XCSI_PCR_ACTLANES_MASK GENMASK(1, 0)
> +
> +#define XCSI_CSR_OFFSET 0x10
> +#define XCSI_CSR_PKTCNT GENMASK(31, 16)
> +#define XCSI_CSR_SPFIFOFULL BIT(3)
> +#define XCSI_CSR_SPFIFONE BIT(2)
> +#define XCSI_CSR_SLBF BIT(1)
> +#define XCSI_CSR_RIPCD BIT(0)
> +
> +#define XCSI_GIER_OFFSET 0x20
> +#define XCSI_GIER_GIE BIT(0)
> +
> +#define XCSI_ISR_OFFSET 0x24
> +#define XCSI_IER_OFFSET 0x28
> +
> +#define XCSI_ISR_FR BIT(31)
> +#define XCSI_ISR_VCXFE BIT(30)
> +#define XCSI_ISR_WCC BIT(22)
> +#define XCSI_ISR_ILC BIT(21)
> +#define XCSI_ISR_SPFIFOF BIT(20)
> +#define XCSI_ISR_SPFIFONE BIT(19)
> +#define XCSI_ISR_SLBF BIT(18)
> +#define XCSI_ISR_STOP BIT(17)
> +#define XCSI_ISR_SOTERR BIT(13)
> +#define XCSI_ISR_SOTSYNCERR BIT(12)
> +#define XCSI_ISR_ECC2BERR BIT(11)
> +#define XCSI_ISR_ECC1BERR BIT(10)
> +#define XCSI_ISR_CRCERR BIT(9)
> +#define XCSI_ISR_DATAIDERR BIT(8)
> +#define XCSI_ISR_VC3FSYNCERR BIT(7)
> +#define XCSI_ISR_VC3FLVLERR BIT(6)
> +#define XCSI_ISR_VC2FSYNCERR BIT(5)
> +#define XCSI_ISR_VC2FLVLERR BIT(4)
> +#define XCSI_ISR_VC1FSYNCERR BIT(3)
> +#define XCSI_ISR_VC1FLVLERR BIT(2)
> +#define XCSI_ISR_VC0FSYNCERR BIT(1)
> +#define XCSI_ISR_VC0FLVLERR BIT(0)
> +
> +#define XCSI_ISR_ALLINTR_MASK (0xc07e3fff)
> +
> +/*
> + * Removed VCXFE mask as it doesn't exist in IER
> + * Removed STOP state irq as this will keep driver in irq handler only
> + */
> +#define XCSI_IER_INTR_MASK (XCSI_ISR_ALLINTR_MASK &\
> + ~(XCSI_ISR_STOP | XCSI_ISR_VCXFE))
> +
> +#define XCSI_SPKTR_OFFSET 0x30
> +#define XCSI_SPKTR_DATA GENMASK(23, 8)
> +#define XCSI_SPKTR_VC GENMASK(7, 6)
> +#define XCSI_SPKTR_DT GENMASK(5, 0)
> +#define XCSI_SPKT_FIFO_DEPTH 31
> +
> +#define XCSI_VCXR_OFFSET 0x34
> +#define XCSI_VCXR_VCERR GENMASK(23, 0)
> +#define XCSI_VCXR_FSYNCERR BIT(1)
> +#define XCSI_VCXR_FLVLERR BIT(0)
> +
> +#define XCSI_CLKINFR_OFFSET 0x3C
> +#define XCSI_CLKINFR_STOP BIT(1)
> +
> +#define XCSI_DLXINFR_OFFSET 0x40
> +#define XCSI_DLXINFR_STOP BIT(5)
> +#define XCSI_DLXINFR_SOTERR BIT(1)
> +#define XCSI_DLXINFR_SOTSYNCERR BIT(0)
> +#define XCSI_MAXDL_COUNT 0x4
> +
> +#define XCSI_VCXINF1R_OFFSET 0x60
> +#define XCSI_VCXINF1R_LINECOUNT GENMASK(31, 16)
> +#define XCSI_VCXINF1R_LINECOUNT_SHIFT 16
> +#define XCSI_VCXINF1R_BYTECOUNT GENMASK(15, 0)
> +
> +#define XCSI_VCXINF2R_OFFSET 0x64
> +#define XCSI_VCXINF2R_DT GENMASK(5, 0)
> +#define XCSI_MAXVCX_COUNT 16
> +
> +/*
> + * Sink pad connected to sensor source pad.
> + * Source pad connected to next module like demosaic.
> + */
> +#define XCSI_MEDIA_PADS 2
> +#define XCSI_DEFAULT_WIDTH 1920
> +#define XCSI_DEFAULT_HEIGHT 1080
> +
> +/* MIPI CSI-2 Data Types from spec */
> +#define XCSI_DT_YUV4228B 0x1e
> +#define XCSI_DT_YUV42210B 0x1f
> +#define XCSI_DT_RGB444 0x20
> +#define XCSI_DT_RGB555 0x21
> +#define XCSI_DT_RGB565 0x22
> +#define XCSI_DT_RGB666 0x23
> +#define XCSI_DT_RGB888 0x24
> +#define XCSI_DT_RAW6 0x28
> +#define XCSI_DT_RAW7 0x29
> +#define XCSI_DT_RAW8 0x2a
> +#define XCSI_DT_RAW10 0x2b
> +#define XCSI_DT_RAW12 0x2c
> +#define XCSI_DT_RAW14 0x2d
> +#define XCSI_DT_RAW16 0x2e
> +#define XCSI_DT_RAW20 0x2f
> +
> +#define XCSI_VCX_START 4
> +#define XCSI_MAX_VC 4
> +#define XCSI_MAX_VCX 16
> +
> +#define XCSI_NEXTREG_OFFSET 4
> +
> +/* There are 2 events frame sync and frame level error per VC */
> +#define XCSI_VCX_NUM_EVENTS ((XCSI_MAX_VCX - XCSI_MAX_VC) * 2)
> +
> +/**
> + * struct xcsi2rxss_event - Event log structure
> + * @mask: Event mask
> + * @name: Name of the event
> + */
> +struct xcsi2rxss_event {
> + u32 mask;
> + const char *name;
> +};
> +
> +static const struct xcsi2rxss_event xcsi2rxss_events[] = {
> + { XCSI_ISR_FR, "Frame Received" },
> + { XCSI_ISR_VCXFE, "VCX Frame Errors" },
> + { XCSI_ISR_WCC, "Word Count Errors" },
> + { XCSI_ISR_ILC, "Invalid Lane Count Error" },
> + { XCSI_ISR_SPFIFOF, "Short Packet FIFO OverFlow Error" },
> + { XCSI_ISR_SPFIFONE, "Short Packet FIFO Not Empty" },
> + { XCSI_ISR_SLBF, "Streamline Buffer Full Error" },
> + { XCSI_ISR_STOP, "Lane Stop State" },
> + { XCSI_ISR_SOTERR, "SOT Error" },
> + { XCSI_ISR_SOTSYNCERR, "SOT Sync Error" },
> + { XCSI_ISR_ECC2BERR, "2 Bit ECC Unrecoverable Error" },
> + { XCSI_ISR_ECC1BERR, "1 Bit ECC Recoverable Error" },
> + { XCSI_ISR_CRCERR, "CRC Error" },
> + { XCSI_ISR_DATAIDERR, "Data Id Error" },
> + { XCSI_ISR_VC3FSYNCERR, "Virtual Channel 3 Frame Sync Error" },
> + { XCSI_ISR_VC3FLVLERR, "Virtual Channel 3 Frame Level Error" },
> + { XCSI_ISR_VC2FSYNCERR, "Virtual Channel 2 Frame Sync Error" },
> + { XCSI_ISR_VC2FLVLERR, "Virtual Channel 2 Frame Level Error" },
> + { XCSI_ISR_VC1FSYNCERR, "Virtual Channel 1 Frame Sync Error" },
> + { XCSI_ISR_VC1FLVLERR, "Virtual Channel 1 Frame Level Error" },
> + { XCSI_ISR_VC0FSYNCERR, "Virtual Channel 0 Frame Sync Error" },
> + { XCSI_ISR_VC0FLVLERR, "Virtual Channel 0 Frame Level Error" }
> +};
> +
> +#define XCSI_NUM_EVENTS ARRAY_SIZE(xcsi2rxss_events)
> +
> +/*
> + * This table provides a mapping between CSI-2 Data type
> + * and media bus formats
> + */
> +static const u32 xcsi2dt_mbus_lut[][2] = {
> + { XCSI_DT_YUV4228B, MEDIA_BUS_FMT_UYVY8_1X16 },
> + { XCSI_DT_YUV42210B, MEDIA_BUS_FMT_UYVY10_1X20 },
> + { XCSI_DT_RGB444, 0 },
> + { XCSI_DT_RGB555, 0 },
> + { XCSI_DT_RGB565, 0 },
> + { XCSI_DT_RGB666, 0 },
> + { XCSI_DT_RGB888, MEDIA_BUS_FMT_RBG888_1X24 },
> + { XCSI_DT_RAW6, 0 },
> + { XCSI_DT_RAW7, 0 },
> + { XCSI_DT_RAW8, MEDIA_BUS_FMT_SRGGB8_1X8 },
> + { XCSI_DT_RAW8, MEDIA_BUS_FMT_SBGGR8_1X8 },
> + { XCSI_DT_RAW8, MEDIA_BUS_FMT_SGBRG8_1X8 },
> + { XCSI_DT_RAW8, MEDIA_BUS_FMT_SGRBG8_1X8 },
> + { XCSI_DT_RAW10, MEDIA_BUS_FMT_SRGGB10_1X10 },
> + { XCSI_DT_RAW10, MEDIA_BUS_FMT_SBGGR10_1X10 },
> + { XCSI_DT_RAW10, MEDIA_BUS_FMT_SGBRG10_1X10 },
> + { XCSI_DT_RAW10, MEDIA_BUS_FMT_SGRBG10_1X10 },
> + { XCSI_DT_RAW12, MEDIA_BUS_FMT_SRGGB12_1X12 },
> + { XCSI_DT_RAW12, MEDIA_BUS_FMT_SBGGR12_1X12 },
> + { XCSI_DT_RAW12, MEDIA_BUS_FMT_SGBRG12_1X12 },
> + { XCSI_DT_RAW12, MEDIA_BUS_FMT_SGRBG12_1X12 },
> + { XCSI_DT_RAW16, MEDIA_BUS_FMT_SRGGB16_1X16 },
> + { XCSI_DT_RAW16, MEDIA_BUS_FMT_SBGGR16_1X16 },
> + { XCSI_DT_RAW16, MEDIA_BUS_FMT_SGBRG16_1X16 },
> + { XCSI_DT_RAW16, MEDIA_BUS_FMT_SGRBG16_1X16 },
> + { XCSI_DT_RAW20, 0 },
> +};
> +
> +/**
> + * struct xcsi2rxss_state - CSI-2 Rx Subsystem device structure
> + * @subdev: The v4l2 subdev structure
> + * @format: Active V4L2 formats on each pad
> + * @default_format: Default V4L2 format
> + * @events: counter for events
> + * @vcx_events: counter for vcx_events
> + * @dev: Platform structure
> + * @rsubdev: Remote subdev connected to sink pad
> + * @rst_gpio: reset to video_aresetn
> + * @clks: array of clocks
> + * @iomem: Base address of subsystem
> + * @max_num_lanes: Maximum number of lanes present
> + * @datatype: Data type filter
> + * @lock: mutex for accessing this structure
> + * @pads: media pads
> + * @streaming: Flag for storing streaming state
> + * @enable_active_lanes: If number of active lanes can be modified
> + * @en_vcx: If more than 4 VC are enabled
> + *
> + * This structure contains the device driver related parameters
> + */
> +struct xcsi2rxss_state {
> + struct v4l2_subdev subdev;
> + struct v4l2_mbus_framefmt format;
> + struct v4l2_mbus_framefmt default_format;
> + u32 events[XCSI_NUM_EVENTS];
> + u32 vcx_events[XCSI_VCX_NUM_EVENTS];
> + struct device *dev;
> + struct v4l2_subdev *rsubdev;
> + struct gpio_desc *rst_gpio;
> + struct clk_bulk_data *clks;
> + void __iomem *iomem;
> + u32 max_num_lanes;
> + u32 datatype;
> + /* used to protect access to this struct */
> + struct mutex lock;
> + struct media_pad pads[XCSI_MEDIA_PADS];
> + bool streaming;
> + bool enable_active_lanes;
> + bool en_vcx;
> +};
> +
> +static const struct clk_bulk_data xcsi2rxss_clks[] = {
> + { .id = "lite_aclk" },
> + { .id = "video_aclk" },
> +};
> +
> +static inline struct xcsi2rxss_state *
> +to_xcsi2rxssstate(struct v4l2_subdev *subdev)
> +{
> + return container_of(subdev, struct xcsi2rxss_state, subdev);
> +}
> +
> +/*
> + * Register related operations
> + */
> +static inline u32 xcsi2rxss_read(struct xcsi2rxss_state *xcsi2rxss, u32 addr)
> +{
> + return ioread32(xcsi2rxss->iomem + addr);
> +}
> +
> +static inline void xcsi2rxss_write(struct xcsi2rxss_state *xcsi2rxss, u32 addr,
> + u32 value)
> +{
> + iowrite32(value, xcsi2rxss->iomem + addr);
> +}
> +
> +static inline void xcsi2rxss_clr(struct xcsi2rxss_state *xcsi2rxss, u32 addr,
> + u32 clr)
> +{
> + xcsi2rxss_write(xcsi2rxss, addr,
> + xcsi2rxss_read(xcsi2rxss, addr) & ~clr);
> +}
> +
> +static inline void xcsi2rxss_set(struct xcsi2rxss_state *xcsi2rxss, u32 addr,
> + u32 set)
> +{
> + xcsi2rxss_write(xcsi2rxss, addr, xcsi2rxss_read(xcsi2rxss, addr) | set);
> +}
> +
> +/*
> + * This function returns the nth mbus for a data type.
> + * In case of error, mbus code returned is 0.
> + */
> +static u32 xcsi2rxss_get_nth_mbus(u32 dt, u32 n)
> +{
> + unsigned int i;
> +
> + for (i = 0; i < ARRAY_SIZE(xcsi2dt_mbus_lut); i++) {
> + if (xcsi2dt_mbus_lut[i][0] == dt) {
> + if (n-- == 0)
> + return xcsi2dt_mbus_lut[i][1];
> + }
> + }
> +
> + return 0;
> +}
> +
> +/* This returns the data type for a media bus format else 0 */
> +static u32 xcsi2rxss_get_dt(u32 mbus)
> +{
> + unsigned int i;
> +
> + for (i = 0; i < ARRAY_SIZE(xcsi2dt_mbus_lut); i++) {
> + if (xcsi2dt_mbus_lut[i][1] == mbus)
> + return xcsi2dt_mbus_lut[i][0];
> + }
> +
> + return 0;
> +}
> +
> +/**
> + * xcsi2rxss_soft_reset - Does a soft reset of the MIPI CSI-2 Rx Subsystem
> + * @state: Xilinx CSI-2 Rx Subsystem structure pointer
> + *
> + * Core takes less than 100 video clock cycles to reset.
> + * So a larger timeout value is chosen for margin.
> + *
> + * Return: 0 - on success OR -ETIME if reset times out
> + */
> +static int xcsi2rxss_soft_reset(struct xcsi2rxss_state *state)
> +{
> + u32 timeout = 1000; /* us */
> +
> + xcsi2rxss_set(state, XCSI_CCR_OFFSET, XCSI_CCR_SOFTRESET);
> +
> + while (xcsi2rxss_read(state, XCSI_CSR_OFFSET) & XCSI_CSR_RIPCD) {
> + if (timeout == 0) {
> + dev_err(state->dev, "soft reset timed out!\n");
> + return -ETIME;
> + }
> +
> + timeout--;
> + udelay(1);
> + }
> +
> + xcsi2rxss_clr(state, XCSI_CCR_OFFSET, XCSI_CCR_SOFTRESET);
> + return 0;
> +}
> +
> +static void xcsi2rxss_hard_reset(struct xcsi2rxss_state *state)
> +{
> + if (!state->rst_gpio)
> + return;
> +
> + /* minimum of 40 dphy_clk_200M cycles */
> + gpiod_set_value_cansleep(state->rst_gpio, 1);
> + usleep_range(1, 2);
> + gpiod_set_value_cansleep(state->rst_gpio, 0);
> +}
> +
> +static void xcsi2rxss_reset_event_counters(struct xcsi2rxss_state *state)
> +{
> + unsigned int i;
> +
> + for (i = 0; i < XCSI_NUM_EVENTS; i++)
> + state->events[i] = 0;
> +
> + for (i = 0; i < XCSI_VCX_NUM_EVENTS; i++)
> + state->vcx_events[i] = 0;
> +}
> +
> +/* Print event counters */
> +static void xcsi2rxss_log_counters(struct xcsi2rxss_state *state)
> +{
> + struct device *dev = state->dev;
> + unsigned int i;
> +
> + for (i = 0; i < XCSI_NUM_EVENTS; i++) {
> + if (state->events[i] > 0) {
> + dev_info(dev, "%s events: %d\n",
> + xcsi2rxss_events[i].name,
> + state->events[i]);
> + }
> + }
> +
> + if (state->en_vcx) {
> + for (i = 0; i < XCSI_VCX_NUM_EVENTS; i++) {
> + if (state->vcx_events[i] > 0) {
> + dev_info(dev,
> + "VC %d Frame %s err vcx events: %d\n",
> + (i / 2) + XCSI_VCX_START,
> + i & 1 ? "Sync" : "Level",
> + state->vcx_events[i]);
> + }
> + }
> + }
> +}
> +
> +/**
> + * xcsi2rxss_log_status - Logs the status of the CSI-2 Receiver
> + * @sd: Pointer to V4L2 subdevice structure
> + *
> + * This function prints the current status of Xilinx MIPI CSI-2
> + *
> + * Return: 0 on success
> + */
> +static int xcsi2rxss_log_status(struct v4l2_subdev *sd)
> +{
> + struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> + struct device *dev = xcsi2rxss->dev;
> + const char *tr = "true";
> + const char *fa = "false";
I didn't notice this in the previous version, but you could just write
"true" and "false" below. The compiler should perform string
de-duplication automatically.
> + u32 reg, data;
> + unsigned int i, max_vc;
> +
> + mutex_lock(&xcsi2rxss->lock);
> +
> + xcsi2rxss_log_counters(xcsi2rxss);
> +
> + dev_info(dev, "***** Core Status *****\n");
> + data = xcsi2rxss_read(xcsi2rxss, XCSI_CSR_OFFSET);
> + dev_info(dev, "Short Packet FIFO Full = %s\n",
> + data & XCSI_CSR_SPFIFOFULL ? tr : fa);
> + dev_info(dev, "Short Packet FIFO Not Empty = %s\n",
> + data & XCSI_CSR_SPFIFONE ? tr : fa);
> + dev_info(dev, "Stream line buffer full = %s\n",
> + data & XCSI_CSR_SLBF ? tr : fa);
> + dev_info(dev, "Soft reset/Core disable in progress = %s\n",
> + data & XCSI_CSR_RIPCD ? tr : fa);
> +
> + /* Clk & Lane Info */
> + dev_info(dev, "******** Clock Lane Info *********\n");
> + data = xcsi2rxss_read(xcsi2rxss, XCSI_CLKINFR_OFFSET);
> + dev_info(dev, "Clock Lane in Stop State = %s\n",
> + data & XCSI_CLKINFR_STOP ? tr : fa);
> +
> + dev_info(dev, "******** Data Lane Info *********\n");
> + dev_info(dev, "Lane\tSoT Error\tSoT Sync Error\tStop State\n");
> + reg = XCSI_DLXINFR_OFFSET;
> + for (i = 0; i < XCSI_MAXDL_COUNT; i++) {
> + data = xcsi2rxss_read(xcsi2rxss, reg);
> +
> + dev_info(dev, "%d\t%s\t\t%s\t\t%s\n", i,
> + data & XCSI_DLXINFR_SOTERR ? tr : fa,
> + data & XCSI_DLXINFR_SOTSYNCERR ? tr : fa,
> + data & XCSI_DLXINFR_STOP ? tr : fa);
> +
> + reg += XCSI_NEXTREG_OFFSET;
> + }
> +
> + /* Virtual Channel Image Information */
> + dev_info(dev, "********** Virtual Channel Info ************\n");
> + dev_info(dev, "VC\tLine Count\tByte Count\tData Type\n");
> + if (xcsi2rxss->en_vcx)
> + max_vc = XCSI_MAX_VCX;
> + else
> + max_vc = XCSI_MAX_VC;
> +
> + reg = XCSI_VCXINF1R_OFFSET;
> + for (i = 0; i < max_vc; i++) {
> + u32 line_count, byte_count, data_type;
> +
> + /* Get line and byte count from VCXINFR1 Register */
> + data = xcsi2rxss_read(xcsi2rxss, reg);
> + byte_count = data & XCSI_VCXINF1R_BYTECOUNT;
> + line_count = data & XCSI_VCXINF1R_LINECOUNT;
> + line_count >>= XCSI_VCXINF1R_LINECOUNT_SHIFT;
> +
> + /* Get data type from VCXINFR2 Register */
> + reg += XCSI_NEXTREG_OFFSET;
> + data = xcsi2rxss_read(xcsi2rxss, reg);
> + data_type = data & XCSI_VCXINF2R_DT;
> +
> + dev_info(dev, "%d\t%d\t\t%d\t\t0x%x\n", i, line_count,
> + byte_count, data_type);
> +
> + /* Move to next pair of VC Info registers */
> + reg += XCSI_NEXTREG_OFFSET;
> + }
> +
> + mutex_unlock(&xcsi2rxss->lock);
> +
> + return 0;
> +}
> +
> +static struct v4l2_subdev *xcsi2rxss_get_remote_subdev(struct media_pad *local)
> +{
> + struct media_pad *remote;
> +
> + remote = media_entity_remote_pad(local);
> + if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
> + return NULL;
> +
> + return media_entity_to_v4l2_subdev(remote->entity);
> +}
> +
> +static int xcsi2rxss_start_stream(struct xcsi2rxss_state *state)
> +{
> + int ret = 0;
> +
> + /* enable core */
> + xcsi2rxss_set(state, XCSI_CCR_OFFSET, XCSI_CCR_ENABLE);
> +
> + ret = xcsi2rxss_soft_reset(state);
> + if (ret < 0) {
> + state->streaming = false;
> + return ret;
> + }
> +
> + /* enable interrupts */
> + xcsi2rxss_clr(state, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
> + xcsi2rxss_write(state, XCSI_IER_OFFSET, XCSI_IER_INTR_MASK);
> + xcsi2rxss_set(state, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
> +
> + state->streaming = true;
> +
> + state->rsubdev =
> + xcsi2rxss_get_remote_subdev(&state->pads[XVIP_PAD_SINK]);
> +
> + ret = v4l2_subdev_call(state->rsubdev, video, s_stream, 1);
> + if (ret) {
> + /* disable interrupts */
> + xcsi2rxss_clr(state, XCSI_IER_OFFSET, XCSI_IER_INTR_MASK);
> + xcsi2rxss_clr(state, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
> +
> + /* disable core */
> + xcsi2rxss_clr(state, XCSI_CCR_OFFSET, XCSI_CCR_ENABLE);
> + state->streaming = false;
> + }
> +
> + return ret;
> +}
> +
> +static void xcsi2rxss_stop_stream(struct xcsi2rxss_state *state)
> +{
> + v4l2_subdev_call(state->rsubdev, video, s_stream, 0);
> +
> + /* disable interrupts */
> + xcsi2rxss_clr(state, XCSI_IER_OFFSET, XCSI_IER_INTR_MASK);
> + xcsi2rxss_clr(state, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
> +
> + /* disable core */
> + xcsi2rxss_clr(state, XCSI_CCR_OFFSET, XCSI_CCR_ENABLE);
> + state->streaming = false;
> +}
> +
> +/**
> + * xcsi2rxss_irq_handler - Interrupt handler for CSI-2
> + * @irq: IRQ number
> + * @data: Pointer to device state
> + *
> + * In the interrupt handler, a list of event counters are updated for
> + * corresponding interrupts. This is useful to get status / debug.
> + *
> + * Return: IRQ_HANDLED after handling interrupts
> + */
> +static irqreturn_t xcsi2rxss_irq_handler(int irq, void *data)
> +{
> + struct xcsi2rxss_state *state = (struct xcsi2rxss_state *)data;
> + struct device *dev = state->dev;
> + u32 status;
> +
> + status = xcsi2rxss_read(state, XCSI_ISR_OFFSET) & XCSI_ISR_ALLINTR_MASK;
> + xcsi2rxss_write(state, XCSI_ISR_OFFSET, status);
> +
> + /* Received a short packet */
> + if (status & XCSI_ISR_SPFIFONE) {
> + u32 count = 0;
> +
> + /*
> + * Drain generic short packet FIFO by reading max 31
> + * (fifo depth) short packets from fifo or till fifo is empty.
> + */
> + for (count = 0; count < XCSI_SPKT_FIFO_DEPTH; ++count) {
> + u32 spfifostat, spkt;
> +
> + spkt = xcsi2rxss_read(state, XCSI_SPKTR_OFFSET);
> + dev_dbg(dev, "Short packet = 0x%08x\n", spkt);
> + spfifostat = xcsi2rxss_read(state, XCSI_ISR_OFFSET);
> + spfifostat &= XCSI_ISR_SPFIFONE;
> + if (!spfifostat)
> + break;
> + xcsi2rxss_write(state, XCSI_ISR_OFFSET, spfifostat);
> + }
> + }
> +
> + /* Short packet FIFO overflow */
> + if (status & XCSI_ISR_SPFIFOF)
> + dev_dbg_ratelimited(dev, "Short packet FIFO overflowed\n");
> +
> + /*
> + * Stream line buffer full
> + * This means there is a backpressure from downstream IP
> + */
> + if (status & XCSI_ISR_SLBF) {
> + dev_alert_ratelimited(dev, "Stream Line Buffer Full!\n");
> +
> + /* disable interrupts */
> + xcsi2rxss_clr(state, XCSI_IER_OFFSET, XCSI_IER_INTR_MASK);
> + xcsi2rxss_clr(state, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
> +
> + /* disable core */
> + xcsi2rxss_clr(state, XCSI_CCR_OFFSET, XCSI_CCR_ENABLE);
> + state->streaming = false;
If you set streaming to false, a later call to xcsi2rxss_s_stream(0)
will consider that the stream is already stopped, and skip calling
xcsi2rxss_stop_stream() and xcsi2rxss_hard_reset(). Now that you have
dropped the hard reset from the interrupt handler, we need to rely on it
being called at stream stop time. Should you just drop the line here ?
> +
> + /*
> + * The IP needs to be hard reset before it can be used now.
> + * This will be done in streamoff.
> + */
> +
> + /*
> + * TODO: Notify the whole pipeline with v4l2_subdev_notify() to
> + * inform userspace.
> + */
> + }
> +
> + /* Increment event counters */
> + if (status & XCSI_ISR_ALLINTR_MASK) {
> + unsigned int i;
> +
> + for (i = 0; i < XCSI_NUM_EVENTS; i++) {
> + if (!(status & xcsi2rxss_events[i].mask))
> + continue;
> + state->events[i]++;
> + dev_dbg_ratelimited(dev, "%s: %u\n",
> + xcsi2rxss_events[i].name,
> + state->events[i]);
> + }
> +
> + if (status & XCSI_ISR_VCXFE && state->en_vcx) {
> + u32 vcxstatus;
> +
> + vcxstatus = xcsi2rxss_read(state, XCSI_VCXR_OFFSET);
> + vcxstatus &= XCSI_VCXR_VCERR;
> + for (i = 0; i < XCSI_VCX_NUM_EVENTS; i++) {
> + if (!(vcxstatus & (1 << i)))
> + continue;
> + state->vcx_events[i]++;
> + }
> + xcsi2rxss_write(state, XCSI_VCXR_OFFSET, vcxstatus);
> + }
> + }
> +
> + return IRQ_HANDLED;
> +}
> +
> +/**
> + * xcsi2rxss_s_stream - It is used to start/stop the streaming.
> + * @sd: V4L2 Sub device
> + * @enable: Flag (True / False)
> + *
> + * This function controls the start or stop of streaming for the
> + * Xilinx MIPI CSI-2 Rx Subsystem.
> + *
> + * Return: 0 on success, errors otherwise
> + */
> +static int xcsi2rxss_s_stream(struct v4l2_subdev *sd, int enable)
> +{
> + struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> + int ret = 0;
> +
> + mutex_lock(&xcsi2rxss->lock);
> +
> + if (enable == xcsi2rxss->streaming)
> + goto stream_done;
> +
> + if (enable) {
> + xcsi2rxss_reset_event_counters(xcsi2rxss);
> + ret = xcsi2rxss_start_stream(xcsi2rxss);
> + } else {
> + xcsi2rxss_stop_stream(xcsi2rxss);
> + xcsi2rxss_hard_reset(xcsi2rxss);
> + }
> +
> +stream_done:
> + mutex_unlock(&xcsi2rxss->lock);
> + return ret;
> +}
> +
> +static struct v4l2_mbus_framefmt *
> +__xcsi2rxss_get_pad_format(struct xcsi2rxss_state *xcsi2rxss,
> + struct v4l2_subdev_pad_config *cfg,
> + unsigned int pad, u32 which)
> +{
> + switch (which) {
> + case V4L2_SUBDEV_FORMAT_TRY:
> + return v4l2_subdev_get_try_format(&xcsi2rxss->subdev, cfg, pad);
> + case V4L2_SUBDEV_FORMAT_ACTIVE:
> + return &xcsi2rxss->format;
> + default:
> + return NULL;
> + }
> +}
> +
> +/**
> + * xcsi2rxss_init_cfg - Initialise the pad format config to default
> + * @sd: Pointer to V4L2 Sub device structure
> + * @cfg: Pointer to sub device pad information structure
> + *
> + * This function is used to initialize the pad format with the default
> + * values.
> + *
> + * Return: 0 on success
> + */
> +static int xcsi2rxss_init_cfg(struct v4l2_subdev *sd,
> + struct v4l2_subdev_pad_config *cfg)
> +{
> + struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> + struct v4l2_mbus_framefmt *format;
> + unsigned int i;
> +
> + mutex_lock(&xcsi2rxss->lock);
> + for (i = 0; i < XCSI_MEDIA_PADS; i++) {
> + format = v4l2_subdev_get_try_format(sd, cfg, i);
> + *format = xcsi2rxss->default_format;
> + }
> + mutex_unlock(&xcsi2rxss->lock);
> +
> + return 0;
> +}
> +
> +/**
> + * xcsi2rxss_get_format - Get the pad format
> + * @sd: Pointer to V4L2 Sub device structure
> + * @cfg: Pointer to sub device pad information structure
> + * @fmt: Pointer to pad level media bus format
> + *
> + * This function is used to get the pad format information.
> + *
> + * Return: 0 on success
> + */
> +static int xcsi2rxss_get_format(struct v4l2_subdev *sd,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_format *fmt)
> +{
> + struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> +
> + mutex_lock(&xcsi2rxss->lock);
> + fmt->format = *__xcsi2rxss_get_pad_format(xcsi2rxss, cfg, fmt->pad,
> + fmt->which);
> + mutex_unlock(&xcsi2rxss->lock);
> +
> + return 0;
> +}
> +
> +/**
> + * xcsi2rxss_set_format - This is used to set the pad format
> + * @sd: Pointer to V4L2 Sub device structure
> + * @cfg: Pointer to sub device pad information structure
> + * @fmt: Pointer to pad level media bus format
> + *
> + * This function is used to set the pad format. Since the pad format is fixed
> + * in hardware, it can't be modified on run time. So when a format set is
> + * requested by application, all parameters except the format type is saved
> + * for the pad and the original pad format is sent back to the application.
> + *
> + * Return: 0 on success
> + */
> +static int xcsi2rxss_set_format(struct v4l2_subdev *sd,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_format *fmt)
> +{
> + struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> + struct v4l2_mbus_framefmt *__format;
> + u32 dt;
> +
> + /* only sink pad format can be updated */
> + mutex_lock(&xcsi2rxss->lock);
> +
> + /*
> + * Only the format->code parameter matters for CSI as the
> + * CSI format cannot be changed at runtime.
> + * Ensure that format to set is copied to over to CSI pad format
> + */
> + __format = __xcsi2rxss_get_pad_format(xcsi2rxss, cfg,
> + fmt->pad, fmt->which);
> +
> + if (fmt->pad == XVIP_PAD_SOURCE) {
> + fmt->format = *__format;
> + mutex_unlock(&xcsi2rxss->lock);
> + return 0;
> + }
> +
> + /*
> + * RAW8 is supported in all datatypes. So if requested media bus format
> + * is of RAW8 type, then allow to be set. In case core is configured to
> + * other RAW, YUV422 8/10 or RGB888, set appropriate media bus format.
> + */
> + dt = xcsi2rxss_get_dt(fmt->format.code);
> + if (dt != xcsi2rxss->datatype && dt != XCSI_DT_RAW8) {
> + dev_dbg(xcsi2rxss->dev, "Unsupported media bus format");
> + /* set the default format for the data type */
> + fmt->format.code = xcsi2rxss_get_nth_mbus(xcsi2rxss->datatype,
> + 0);
> + }
> +
> + *__format = fmt->format;
> + mutex_unlock(&xcsi2rxss->lock);
> +
> + return 0;
> +}
> +
> +/*
> + * xcsi2rxss_enum_mbus_code - Handle pixel format enumeration
> + * @sd : pointer to v4l2 subdev structure
> + * @cfg: V4L2 subdev pad configuration
> + * @code : pointer to v4l2_subdev_mbus_code_enum structure
> + *
> + * Return: -EINVAL or zero on success
> + */
> +int xcsi2rxss_enum_mbus_code(struct v4l2_subdev *sd,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_mbus_code_enum *code)
As commented by the kbuild bot, this function should be static.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Good to go :-)
> +{
> + struct xcsi2rxss_state *state = to_xcsi2rxssstate(sd);
> + u32 dt, n;
> + int ret = 0;
> +
> + /* RAW8 dt packets are available in all DT configurations */
> + if (code->index < 4) {
> + n = code->index;
> + dt = XCSI_DT_RAW8;
> + } else if (state->datatype != XCSI_DT_RAW8) {
> + n = code->index - 4;
> + dt = state->datatype;
> + } else {
> + return -EINVAL;
> + }
> +
> + code->code = xcsi2rxss_get_nth_mbus(dt, n);
> + if (!code->code)
> + ret = -EINVAL;
> +
> + return ret;
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * Media Operations
> + */
> +
> +static const struct media_entity_operations xcsi2rxss_media_ops = {
> + .link_validate = v4l2_subdev_link_validate
> +};
> +
> +static const struct v4l2_subdev_core_ops xcsi2rxss_core_ops = {
> + .log_status = xcsi2rxss_log_status,
> +};
> +
> +static const struct v4l2_subdev_video_ops xcsi2rxss_video_ops = {
> + .s_stream = xcsi2rxss_s_stream
> +};
> +
> +static const struct v4l2_subdev_pad_ops xcsi2rxss_pad_ops = {
> + .init_cfg = xcsi2rxss_init_cfg,
> + .get_fmt = xcsi2rxss_get_format,
> + .set_fmt = xcsi2rxss_set_format,
> + .enum_mbus_code = xcsi2rxss_enum_mbus_code,
> + .link_validate = v4l2_subdev_link_validate_default,
> +};
> +
> +static const struct v4l2_subdev_ops xcsi2rxss_ops = {
> + .core = &xcsi2rxss_core_ops,
> + .video = &xcsi2rxss_video_ops,
> + .pad = &xcsi2rxss_pad_ops
> +};
> +
> +static int xcsi2rxss_parse_of(struct xcsi2rxss_state *xcsi2rxss)
> +{
> + struct device *dev = xcsi2rxss->dev;
> + struct device_node *node = dev->of_node;
> +
> + struct fwnode_handle *ep;
> + struct v4l2_fwnode_endpoint vep = {
> + .bus_type = V4L2_MBUS_CSI2_DPHY
> + };
> + bool en_csi_v20, vfb;
> + int ret;
> +
> + en_csi_v20 = of_property_read_bool(node, "xlnx,en-csi-v2-0");
> + if (en_csi_v20)
> + xcsi2rxss->en_vcx = of_property_read_bool(node, "xlnx,en-vcx");
> +
> + xcsi2rxss->enable_active_lanes =
> + of_property_read_bool(node, "xlnx,en-active-lanes");
> +
> + ret = of_property_read_u32(node, "xlnx,csi-pxl-format",
> + &xcsi2rxss->datatype);
> + if (ret < 0) {
> + dev_err(dev, "missing xlnx,csi-pxl-format property\n");
> + return ret;
> + }
> +
> + switch (xcsi2rxss->datatype) {
> + case XCSI_DT_YUV4228B:
> + case XCSI_DT_RGB444:
> + case XCSI_DT_RGB555:
> + case XCSI_DT_RGB565:
> + case XCSI_DT_RGB666:
> + case XCSI_DT_RGB888:
> + case XCSI_DT_RAW6:
> + case XCSI_DT_RAW7:
> + case XCSI_DT_RAW8:
> + case XCSI_DT_RAW10:
> + case XCSI_DT_RAW12:
> + case XCSI_DT_RAW14:
> + break;
> + case XCSI_DT_YUV42210B:
> + case XCSI_DT_RAW16:
> + case XCSI_DT_RAW20:
> + if (!en_csi_v20) {
> + ret = -EINVAL;
> + dev_dbg(dev, "enable csi v2 for this pixel format");
> + }
> + break;
> + default:
> + ret = -EINVAL;
> + }
> + if (ret < 0) {
> + dev_err(dev, "invalid csi-pxl-format property!\n");
> + return ret;
> + }
> +
> + vfb = of_property_read_bool(node, "xlnx,vfb");
> + if (!vfb) {
> + dev_err(dev, "operation without VFB is not supported\n");
> + return -EINVAL;
> + }
> +
> + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
> + XVIP_PAD_SINK, 0,
> + FWNODE_GRAPH_ENDPOINT_NEXT);
> + if (!ep) {
> + dev_err(dev, "no sink port found");
> + return -EINVAL;
> + }
> +
> + ret = v4l2_fwnode_endpoint_parse(ep, &vep);
> + fwnode_handle_put(ep);
> + if (ret) {
> + dev_err(dev, "error parsing sink port");
> + return ret;
> + }
> +
> + dev_dbg(dev, "mipi number lanes = %d\n",
> + vep.bus.mipi_csi2.num_data_lanes);
> +
> + xcsi2rxss->max_num_lanes = vep.bus.mipi_csi2.num_data_lanes;
> +
> + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
> + XVIP_PAD_SOURCE, 0,
> + FWNODE_GRAPH_ENDPOINT_NEXT);
> + if (!ep) {
> + dev_err(dev, "no source port found");
> + return -EINVAL;
> + }
> +
> + fwnode_handle_put(ep);
> +
> + dev_dbg(dev, "vcx %s, %u data lanes (%s), data type 0x%02x\n",
> + xcsi2rxss->en_vcx ? "enabled" : "disabled",
> + xcsi2rxss->max_num_lanes,
> + xcsi2rxss->enable_active_lanes ? "dynamic" : "static",
> + xcsi2rxss->datatype);
> +
> + return 0;
> +}
> +
> +static int xcsi2rxss_probe(struct platform_device *pdev)
> +{
> + struct v4l2_subdev *subdev;
> + struct xcsi2rxss_state *xcsi2rxss;
> + int num_clks = ARRAY_SIZE(xcsi2rxss_clks);
> + struct device *dev = &pdev->dev;
> + int irq, ret;
> +
> + xcsi2rxss = devm_kzalloc(dev, sizeof(*xcsi2rxss), GFP_KERNEL);
> + if (!xcsi2rxss)
> + return -ENOMEM;
> +
> + xcsi2rxss->dev = dev;
> +
> + xcsi2rxss->clks = devm_kmemdup(dev, xcsi2rxss_clks,
> + sizeof(xcsi2rxss_clks), GFP_KERNEL);
> + if (!xcsi2rxss->clks)
> + return -ENOMEM;
> +
> + /* Reset GPIO */
> + xcsi2rxss->rst_gpio = devm_gpiod_get_optional(dev, "video-reset",
> + GPIOD_OUT_HIGH);
> + if (IS_ERR(xcsi2rxss->rst_gpio)) {
> + if (PTR_ERR(xcsi2rxss->rst_gpio) != -EPROBE_DEFER)
> + dev_err(dev, "Video Reset GPIO not setup in DT");
> + return PTR_ERR(xcsi2rxss->rst_gpio);
> + }
> +
> + ret = xcsi2rxss_parse_of(xcsi2rxss);
> + if (ret < 0)
> + return ret;
> +
> + xcsi2rxss->iomem = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(xcsi2rxss->iomem))
> + return PTR_ERR(xcsi2rxss->iomem);
> +
> + irq = platform_get_irq(pdev, 0);
> + if (irq < 0)
> + return irq;
> +
> + ret = devm_request_threaded_irq(dev, irq, NULL,
> + xcsi2rxss_irq_handler, IRQF_ONESHOT,
> + dev_name(dev), xcsi2rxss);
> + if (ret) {
> + dev_err(dev, "Err = %d Interrupt handler reg failed!\n", ret);
> + return ret;
> + }
> +
> + ret = clk_bulk_get(dev, num_clks, xcsi2rxss->clks);
> + if (ret)
> + return ret;
> +
> + /* TODO: Enable/disable clocks at stream on/off time. */
> + ret = clk_bulk_prepare_enable(num_clks, xcsi2rxss->clks);
> + if (ret)
> + goto err_clk_put;
> +
> + mutex_init(&xcsi2rxss->lock);
> +
> + xcsi2rxss_hard_reset(xcsi2rxss);
> + xcsi2rxss_soft_reset(xcsi2rxss);
> +
> + /* Initialize V4L2 subdevice and media entity */
> + xcsi2rxss->pads[XVIP_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
> + xcsi2rxss->pads[XVIP_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
> +
> + /* Initialize the default format */
> + xcsi2rxss->default_format.code =
> + xcsi2rxss_get_nth_mbus(xcsi2rxss->datatype, 0);
> + xcsi2rxss->default_format.field = V4L2_FIELD_NONE;
> + xcsi2rxss->default_format.colorspace = V4L2_COLORSPACE_SRGB;
> + xcsi2rxss->default_format.width = XCSI_DEFAULT_WIDTH;
> + xcsi2rxss->default_format.height = XCSI_DEFAULT_HEIGHT;
> + xcsi2rxss->format = xcsi2rxss->default_format;
> +
> + /* Initialize V4L2 subdevice and media entity */
> + subdev = &xcsi2rxss->subdev;
> + v4l2_subdev_init(subdev, &xcsi2rxss_ops);
> + subdev->dev = dev;
> + strscpy(subdev->name, dev_name(dev), sizeof(subdev->name));
> + subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
> + subdev->entity.ops = &xcsi2rxss_media_ops;
> + v4l2_set_subdevdata(subdev, xcsi2rxss);
> +
> + ret = media_entity_pads_init(&subdev->entity, XCSI_MEDIA_PADS,
> + xcsi2rxss->pads);
> + if (ret < 0)
> + goto error;
> +
> + platform_set_drvdata(pdev, xcsi2rxss);
> +
> + ret = v4l2_async_register_subdev(subdev);
> + if (ret < 0) {
> + dev_err(dev, "failed to register subdev\n");
> + goto error;
> + }
> +
> + return 0;
> +error:
> + media_entity_cleanup(&subdev->entity);
> + mutex_destroy(&xcsi2rxss->lock);
> + clk_bulk_disable_unprepare(num_clks, xcsi2rxss->clks);
> +err_clk_put:
> + clk_bulk_put(num_clks, xcsi2rxss->clks);
> + return ret;
> +}
> +
> +static int xcsi2rxss_remove(struct platform_device *pdev)
> +{
> + struct xcsi2rxss_state *xcsi2rxss = platform_get_drvdata(pdev);
> + struct v4l2_subdev *subdev = &xcsi2rxss->subdev;
> + int num_clks = ARRAY_SIZE(xcsi2rxss_clks);
> +
> + v4l2_async_unregister_subdev(subdev);
> + media_entity_cleanup(&subdev->entity);
> + mutex_destroy(&xcsi2rxss->lock);
> + clk_bulk_disable_unprepare(num_clks, xcsi2rxss->clks);
> + clk_bulk_put(num_clks, xcsi2rxss->clks);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id xcsi2rxss_of_id_table[] = {
> + { .compatible = "xlnx,mipi-csi2-rx-subsystem-5.0", },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, xcsi2rxss_of_id_table);
> +
> +static struct platform_driver xcsi2rxss_driver = {
> + .driver = {
> + .name = "xilinx-csi2rxss",
> + .of_match_table = xcsi2rxss_of_id_table,
> + },
> + .probe = xcsi2rxss_probe,
> + .remove = xcsi2rxss_remove,
> +};
> +
> +module_platform_driver(xcsi2rxss_driver);
> +
> +MODULE_AUTHOR("Vishal Sagar <vsagar@xilinx.com>");
> +MODULE_DESCRIPTION("Xilinx MIPI CSI-2 Rx Subsystem Driver");
> +MODULE_LICENSE("GPL v2");
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCH v13 1/2] media: dt-bindings: media: xilinx: Add Xilinx MIPI CSI-2 Rx Subsystem
From: Laurent Pinchart @ 2020-05-24 2:02 UTC (permalink / raw)
To: Vishal Sagar
Cc: Hyun Kwon, mchehab, robh+dt, mark.rutland, Michal Simek,
linux-media, devicetree, hans.verkuil, linux-arm-kernel,
linux-kernel, Dinesh Kumar, Sandip Kothari, Luca Ceresoli,
Jacopo Mondi, Hyun Kwon, Rob Herring
In-Reply-To: <20200512151947.120348-2-vishal.sagar@xilinx.com>
Hi Vishal,
Thank you for the patch.
On Tue, May 12, 2020 at 08:49:46PM +0530, Vishal Sagar wrote:
> Add bindings documentation for Xilinx MIPI CSI-2 Rx Subsystem.
>
> The Xilinx MIPI CSI-2 Rx Subsystem consists of a CSI-2 Rx controller, a
> D-PHY in Rx mode and a Video Format Bridge.
>
> Signed-off-by: Vishal Sagar <vishal.sagar@xilinx.com>
> Reviewed-by: Hyun Kwon <hyun.kwon@xilinx.com>
> Reviewed-by: Rob Herring <robh@kernel.org>
> Reviewed-by: Luca Ceresoli <luca@lucaceresoli.net>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> v13
> - Based on Laurent's suggestions
> - Fixed the datatypes values as minimum and maximum
> - condition added for en-vcx property
>
> v12
> - Moved to yaml format
> - Update CSI-2 and D-PHY
> - Mention that bindings for D-PHY not here
> - reset -> video-reset
>
> v11
> - Modify compatible string from 4.0 to 5.0
>
> v10
> - No changes
>
> v9
> - Fix xlnx,vfb description.
> - s/Optional/Required endpoint property.
> - Move data-lanes description from Ports to endpoint property section.
>
> v8
> - Added reset-gpios optional property to assert video_aresetn
>
> v7
> - Removed the control name from dt bindings
> - Updated the example dt node name to csi2rx
>
> v6
> - Added "control" after V4L2_CID_XILINX_MIPICSISS_ACT_LANES as suggested by Luca
> - Added reviewed by Rob Herring
>
> v5
> - Incorporated comments by Luca Cersoli
> - Removed DPHY clock from description and example
> - Removed bayer pattern from device tree MIPI CSI IP
> doesn't deal with bayer pattern.
>
> v4
> - Added reviewed by Hyun Kwon
>
> v3
> - removed interrupt parent as suggested by Rob
> - removed dphy clock
> - moved vfb to optional properties
> - Added required and optional port properties section
> - Added endpoint property section
>
> v2
> - updated the compatible string to latest version supported
> - removed DPHY related parameters
> - added CSI v2.0 related property (including VCX for supporting upto 16
> virtual channels).
> - modified csi-pxl-format from string to unsigned int type where the value
> is as per the CSI specification
> - Defined port 0 and port 1 as sink and source ports.
> - Removed max-lanes property as suggested by Rob and Sakari
> .../bindings/media/xilinx/xlnx,csi2rxss.yaml | 226 ++++++++++++++++++
> 1 file changed, 226 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml
>
> diff --git a/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml b/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml
> new file mode 100644
> index 000000000000..b0885f461785
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml
> @@ -0,0 +1,226 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/xilinx/xlnx,csi2rxss.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Xilinx MIPI CSI-2 Receiver Subsystem
> +
> +maintainers:
> + - Vishal Sagar <vishal.sagar@xilinx.com>
> +
> +description: |
> + The Xilinx MIPI CSI-2 Receiver Subsystem is used to capture MIPI CSI-2
> + traffic from compliant camera sensors and send the output as AXI4 Stream
> + video data for image processing.
> + The subsystem consists of a MIPI D-PHY in slave mode which captures the
> + data packets. This is passed along the MIPI CSI-2 Rx IP which extracts the
> + packet data. The optional Video Format Bridge (VFB) converts this data to
> + AXI4 Stream video data.
> + For more details, please refer to PG232 Xilinx MIPI CSI-2 Receiver Subsystem.
> + Please note that this bindings includes only the MIPI CSI-2 Rx controller
> + and Video Format Bridge and not D-PHY.
> +
> +properties:
> + compatible:
> + items:
> + - enum:
> + - xlnx,mipi-csi2-rx-subsystem-5.0
> +
> + reg:
> + maxItems: 1
> +
> + interrupts:
> + maxItems: 1
> +
> + clocks:
> + description: List of clock specifiers
> + items:
> + - description: AXI Lite clock
> + - description: Video clock
> +
> + clock-names:
> + items:
> + - const: lite_aclk
> + - const: video_aclk
> +
> + xlnx,csi-pxl-format:
> + description: |
> + This denotes the CSI Data type selected in hw design.
> + Packets other than this data type (except for RAW8 and
> + User defined data types) will be filtered out.
> + Possible values are as below -
> + 0x1e - YUV4228B
> + 0x1f - YUV42210B
> + 0x20 - RGB444
> + 0x21 - RGB555
> + 0x22 - RGB565
> + 0x23 - RGB666
> + 0x24 - RGB888
> + 0x28 - RAW6
> + 0x29 - RAW7
> + 0x2a - RAW8
> + 0x2b - RAW10
> + 0x2c - RAW12
> + 0x2d - RAW14
> + 0x2e - RAW16
> + 0x2f - RAW20
> + allOf:
> + - $ref: /schemas/types.yaml#/definitions/uint32
> + - anyOf:
> + - minimum: 0x1e
> + - maximum: 0x24
> + - minimum: 0x28
> + - maximum: 0x2f
> +
> + xlnx,vfb:
> + type: boolean
> + description: Present when Video Format Bridge is enabled in IP configuration
> +
> + xlnx,en-csi-v2-0:
> + type: boolean
> + description: Present if CSI v2 is enabled in IP configuration.
> +
> + xlnx,en-vcx:
> + type: boolean
> + description: |
> + When present, there are maximum 16 virtual channels, else only 4.
> +
> + xlnx,en-active-lanes:
> + type: boolean
> + description: |
> + Present if the number of active lanes can be re-configured at
> + runtime in the Protocol Configuration Register. Otherwise all lanes,
> + as set in IP configuration, are always active.
> +
> + video-reset-gpios:
> + description: Optional specifier for a GPIO that asserts video_aresetn.
> + maxItems: 1
> +
> + ports:
> + type: object
> +
> + properties:
> + port@0:
> + type: object
> + description: |
> + Input / sink port node, single endpoint describing the
> + CSI-2 transmitter.
> +
> + properties:
> + reg:
> + const: 0
> +
> + endpoint:
> + type: object
> +
> + properties:
> +
> + data-lanes:
> + description: |
> + This is required only in the sink port 0 endpoint which
> + connects to MIPI CSI-2 source like sensor.
> + The possible values are -
> + 1 - For 1 lane enabled in IP.
> + 1 2 - For 2 lanes enabled in IP.
> + 1 2 3 - For 3 lanes enabled in IP.
> + 1 2 3 4 - For 4 lanes enabled in IP.
> + items:
> + - const: 1
> + - const: 2
> + - const: 3
> + - const: 4
> +
> + remote-endpoint: true
> +
> + required:
> + - data-lanes
> + - remote-endpoint
> +
> + additionalProperties: false
> +
> + additionalProperties: false
> +
> + port@1:
> + type: object
> + description: |
> + Output / source port node, endpoint describing modules
> + connected the CSI-2 receiver.
> +
> + properties:
> +
> + reg:
> + const: 1
> +
> + endpoint:
> + type: object
> +
> + properties:
> +
> + remote-endpoint: true
> +
> + required:
> + - remote-endpoint
> +
> + additionalProperties: false
> +
> + additionalProperties: false
> +
> +required:
> + - compatible
> + - reg
> + - interrupts
> + - clocks
> + - clock-names
> + - xlnx,csi-pxl-format
> + - ports
> +
> +if:
> + not:
> + required:
> + - xlnx,en-csi-v2-0
> +then:
> + properties:
> + xlnx,en-vcx: false
As I've just commented on v12, I think we should condition the
xlnx,csi-pxl-format property to xlnx,vfb being set. xlnx,csi-pxl-format
should be removed from the required properties above, and the following
conditions added:
allOf:
- if:
required:
- xlnx,vfb
then:
required:
- xlnx,csi-pxl-format
else:
properties:
xlnx,csi-pxl-format: false
- if:
not:
required:
- xlnx,en-csi-v2-0
then:
properties:
xlnx,en-vcx: false
The 'allOf' is needed as you can't have two 'if' constructs at the top
level.
Please however let me know if my understanding is wrong and
xlnx,csi-pxl-format is needed even when xlnx,vfb is not set. In that
case please ignore this change (but please add the ... below).
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/gpio/gpio.h>
> + xcsi2rxss_1: csi2rx@a0020000 {
> + compatible = "xlnx,mipi-csi2-rx-subsystem-5.0";
> + reg = <0x0 0xa0020000 0x0 0x10000>;
> + interrupt-parent = <&gic>;
> + interrupts = <0 95 4>;
> + xlnx,csi-pxl-format = <0x2a>;
> + xlnx,vfb;
> + xlnx,en-active-lanes;
> + xlnx,en-csi-v2-0;
> + xlnx,en-vcx;
> + clock-names = "lite_aclk", "video_aclk";
> + clocks = <&misc_clk_0>, <&misc_clk_1>;
> + video-reset-gpios = <&gpio 86 GPIO_ACTIVE_LOW>;
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + /* Sink port */
> + reg = <0>;
> + csiss_in: endpoint {
> + data-lanes = <1 2 3 4>;
> + /* MIPI CSI-2 Camera handle */
> + remote-endpoint = <&camera_out>;
> + };
> + };
> + port@1 {
> + /* Source port */
> + reg = <1>;
> + csiss_out: endpoint {
> + remote-endpoint = <&vproc_in>;
> + };
> + };
> + };
> + };
YAML files usually end with
...
on the last line to mark the end of file.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCH v12 1/2] media: dt-bindings: media: xilinx: Add Xilinx MIPI CSI-2 Rx Subsystem
From: Laurent Pinchart @ 2020-05-24 1:45 UTC (permalink / raw)
To: Vishal Sagar
Cc: Hyun Kwon, mchehab@kernel.org, robh+dt@kernel.org,
mark.rutland@arm.com, hans.verkuil@cisco.com, Luca Ceresoli,
Jacopo Mondi, Michal Simek, linux-media@vger.kernel.org,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Dinesh Kumar, Sandip Kothari,
Rob Herring
In-Reply-To: <BY5PR02MB68679AA1B7CDDC16293EEC12A7A20@BY5PR02MB6867.namprd02.prod.outlook.com>
Hi Vishal,
On Fri, May 08, 2020 at 01:52:36PM +0000, Vishal Sagar wrote:
> On Tuesday, May 5, 2020 7:53 PM, Laurent Pinchart wrote:
> > On Thu, Apr 23, 2020 at 09:00:37PM +0530, Vishal Sagar wrote:
> > > Add bindings documentation for Xilinx MIPI CSI-2 Rx Subsystem.
> > >
> > > The Xilinx MIPI CSI-2 Rx Subsystem consists of a CSI-2 Rx controller,
> > > a D-PHY in Rx mode and a Video Format Bridge.
> > >
> > > Signed-off-by: Vishal Sagar <vishal.sagar@xilinx.com>
> > > Reviewed-by: Hyun Kwon <hyun.kwon@xilinx.com>
> > > Reviewed-by: Rob Herring <robh@kernel.org>
> > > Reviewed-by: Luca Ceresoli <luca@lucaceresoli.net>
> > > ---
> > > v12
> > > - Moved to yaml format
> > > - Update CSI-2 and D-PHY
> > > - Mention that bindings for D-PHY not here
> > > - reset -> video-reset
> > >
> > > v11
> > > - Modify compatible string from 4.0 to 5.0
> > >
> > > v10
> > > - No changes
> > >
> > > v9
> > > - Fix xlnx,vfb description.
> > > - s/Optional/Required endpoint property.
> > > - Move data-lanes description from Ports to endpoint property section.
> > >
> > > v8
> > > - Added reset-gpios optional property to assert video_aresetn
> > >
> > > v7
> > > - Removed the control name from dt bindings
> > > - Updated the example dt node name to csi2rx
> > >
> > > v6
> > > - Added "control" after V4L2_CID_XILINX_MIPICSISS_ACT_LANES as
> > > suggested by Luca
> > > - Added reviewed by Rob Herring
> > >
> > > v5
> > > - Incorporated comments by Luca Cersoli
> > > - Removed DPHY clock from description and example
> > > - Removed bayer pattern from device tree MIPI CSI IP
> > > doesn't deal with bayer pattern.
> > >
> > > v4
> > > - Added reviewed by Hyun Kwon
> > >
> > > v3
> > > - removed interrupt parent as suggested by Rob
> > > - removed dphy clock
> > > - moved vfb to optional properties
> > > - Added required and optional port properties section
> > > - Added endpoint property section
> > >
> > > v2
> > > - updated the compatible string to latest version supported
> > > - removed DPHY related parameters
> > > - added CSI v2.0 related property (including VCX for supporting upto 16
> > > virtual channels).
> > > - modified csi-pxl-format from string to unsigned int type where the value
> > > is as per the CSI specification
> > > - Defined port 0 and port 1 as sink and source ports.
> > > - Removed max-lanes property as suggested by Rob and Sakari
> > > .../bindings/media/xilinx/xlnx,csi2rxss.yaml | 215 ++++++++++++++++++
> > > 1 file changed, 215 insertions(+)
> > > create mode 100644
> > > Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml
> > >
> > > diff --git
> > > a/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml
> > > b/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml
> > > new file mode 100644
> > > index 000000000000..365084e27f7e
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yam
> > > +++ l
> > > @@ -0,0 +1,215 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/media/xilinx/xlnx,csi2rxss.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Xilinx MIPI CSI-2 Receiver Subsystem
> > > +
> > > +maintainers:
> > > + - Vishal Sagar <vishal.sagar@xilinx.com>
> > > +
> > > +description: |
> > > + The Xilinx MIPI CSI-2 Receiver Subsystem is used to capture MIPI CSI-2
> > > + traffic from compliant camera sensors and send the output as AXI4 Stream
> > > + video data for image processing.
> > > + The subsystem consists of a MIPI D-PHY in slave mode which captures the
> > > + data packets. This is passed along the MIPI CSI-2 Rx IP which extracts the
> > > + packet data. The optional Video Format Bridge (VFB) converts this data to
> > > + AXI4 Stream video data.
> > > + For more details, please refer to PG232 Xilinx MIPI CSI-2 Receiver Subsystem.
> > > + Please note that this bindings includes only the MIPI CSI-2 Rx controller
> > > + and Video Format Bridge and not D-PHY.
> >
> > How should the D-PHY be handled, when DPY_EN_REG_IF is set to true ?
>
> It was suggested in v3 to have a separate D-PHY phy driver which would be initialized / configured from MIPI CSI-2 Rx driver.
> Currently with the D-PHY register interface enabled, we don't have to really configure anything but the following parameters
> 1 - init
> 2 - hs_settle
> 3 - hs_timeout (High Speed mode timeout)
> 4 - esc_timeout (Escape mode timeout)
> 5 - idelay tap
>
> The D-PHY Rx can be enabled/disabled and has a soft reset bit.
> The HS and Escape mode timeout registers can be enabled with a default value via the Vivado IP GUI.
>
> The above parameters would have to be passed to D-PHY driver as custom control via MIPI CSI-2 Rx driver
> as these depend on the sensor connected.
> Probably these can be a new common control in V4L2 framework for CSI Rx controllers.
It seems that in that case, regardless of whether we go for a separate
PHY driver or not, we will be able to extend the DT bindings, either
with a phys property, or with an additional reg entry. That should be
backward-compatible, so I'm not concerned.
> > > +
> > > +properties:
> > > + compatible:
> > > + items:
> > > + - enum:
> > > + - xlnx,mipi-csi2-rx-subsystem-5.0
> > > +
> > > + reg:
> > > + maxItems: 1
> > > +
> > > + interrupts:
> > > + maxItems: 1
> > > +
> > > + clocks:
> > > + description: List of clock specifiers
> > > + items:
> > > + - description: AXI Lite clock
> > > + - description: Video clock
> > > +
> > > + clock-names:
> > > + items:
> > > + - const: lite_aclk
> > > + - const: video_aclk
> > > +
> > > + xlnx,csi-pxl-format:
> > > + description: |
> > > + This denotes the CSI Data type selected in hw design.
> > > + Packets other than this data type (except for RAW8 and
> > > + User defined data types) will be filtered out.
> > > + Possible values are as below -
> > > + 0x1e - YUV4228B
> > > + 0x1f - YUV42210B
> > > + 0x20 - RGB444
> > > + 0x21 - RGB555
> > > + 0x22 - RGB565
> > > + 0x23 - RGB666
> > > + 0x24 - RGB888
> > > + 0x28 - RAW6
> > > + 0x29 - RAW7
> > > + 0x2a - RAW8
> > > + 0x2b - RAW10
> > > + 0x2c - RAW12
> > > + 0x2d - RAW14
> > > + 0x2e - RAW16
> > > + 0x2f - RAW20
> > > + allOf:
> > > + - $ref: /schemas/types.yaml#/definitions/uint32
> > > + - enum: [0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x28, 0x29,
> > > + 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f]
> >
> > This could also be written
> >
> > allOf:
> > - $ref: /schemas/types.yaml#/definitions/uint32
> > - anyOf:
> > - minimum: 0x1e
> > maximum: 0x24
> > - minimum: 0x28
> > maximum: 0x2f
> >
> > if you want to make it a bit more compact (in the number of values, not the
> > number of lines obviously), up to you.
>
> Thanks for sharing this method. I will update this in next version.
>
> > I will also quote the question (and your answer) from the previous
> > version:
> >
> > > > Isn't this property required only when the VFB is present ?
> > >
> > > This will be present irrespective of VFB being enabled.
> > > With VFB, the data on the bus will be as per Xilinx UG934 which is similar to media bus formats.
> > >
> > > Without VFB, it will just be plain data as it comes in data packets.
> > > Refer to the Xilinx PG 232 "Pixel Packing When Video Format Bridge is Not Present"
> > >
> > > So the driver is currently made to load only in case VFB is enabled.
> >
> > I understand that the driver doesn't support the case where the VFB is
> > disabled, but the DT bindings shouldn't care about that. The document of
> > v4.1 of the subsystem states that the width of the video_out port is then
> > selected under "CSI-2 Options TDATA width" (page 11). I however don't such
> > such an option described on pages 55 or 56, but there's an
> > AXIS_TDATA_WIDTH parameter on page 61.
> >
> > Is the pixel format relevant when the VFB is disabled ?
>
> When the VFB is disabled, all supported data types will be allowed i.e. no filtering will occur.
> But the data output will be in 32/64 bit TDATA width (no dependence on pixels per clock) and
> will adhere to the "Recommended Memory Storage" section of the CSI spec.
> In this case data being sent on the bus won't compare to what media bus format documentation describes.
My understanding is that, in the case xlnx,vfb would be absent (not
supported in the driver yet), the xlnx,csi-pxl-format should not be set
? If that's correct, I'd like to capture that in the bindings already.
It could be expressed by dropping xlnx,csi-pxl-format from the required
section, and adding
if:
required:
- xlnx,vfb
then:
required:
- xlnx,csi-pxl-format
else:
properties:
xlnx,csi-pxl-format: false
As you will have two conditions defined, they should be grouped with
allOf:
- if:
required:
- xlnx,vfb
then:
required:
- xlnx,csi-pxl-format
else:
properties:
xlnx,csi-pxl-format: false
- if:
not:
required:
- xlnx,en-csi-v2-0
then:
properties:
xlnx,en-vcx: false
> > > +
> > > + xlnx,vfb:
> > > + type: boolean
> > > + description: Present when Video Format Bridge is enabled in IP
> > > + configuration
> > > +
> > > + xlnx,en-csi-v2-0:
> > > + type: boolean
> > > + description: Present if CSI v2 is enabled in IP configuration.
> > > +
> > > + xlnx,en-vcx:
> > > + type: boolean
> > > + description: |
> > > + When present, there are maximum 16 virtual channels, else
> > > + only 4. This is present only if xlnx,en-csi-v2-0 is present.
> >
> > The last sentence should be removed, and replaced with
> >
> > if:
> > not:
> > required:
> > - xlnx,en-csi-v2-0
> > then:
> > properties:
> > xlnx,en-vcx: false
> >
> > (to be placed after required: and before additionalProperties:).
>
> Got it. Thanks for the tips on YAML.
> I will update this in next version.
>
> > > +
> > > + xlnx,en-active-lanes:
> > > + type: boolean
> > > + description: |
> > > + Present if the number of active lanes can be re-configured at
> > > + runtime in the Protocol Configuration Register. Otherwise all lanes,
> > > + as set in IP configuration, are always active.
> > > +
> > > + video-reset-gpios:
> > > + description: Optional specifier for a GPIO that asserts video_aresetn.
> > > + maxItems: 1
> > > +
> > > + ports:
> > > + type: object
> > > +
> > > + properties:
> > > + port@0:
> > > + type: object
> > > + description: |
> > > + Input / sink port node, single endpoint describing the
> > > + CSI-2 transmitter.
> > > +
> > > + properties:
> > > + reg:
> > > + const: 0
> > > +
> > > + endpoint:
> > > + type: object
> > > +
> > > + properties:
> > > +
> > > + data-lanes:
> > > + description: |
> > > + This is required only in the sink port 0 endpoint which
> > > + connects to MIPI CSI-2 source like sensor.
> > > + The possible values are -
> > > + 1 - For 1 lane enabled in IP.
> > > + 1 2 - For 2 lanes enabled in IP.
> > > + 1 2 3 - For 3 lanes enabled in IP.
> > > + 1 2 3 4 - For 4 lanes enabled in IP.
> > > + items:
> > > + - const: 1
> > > + - const: 2
> > > + - const: 3
> > > + - const: 4
> > > +
> > > + remote-endpoint: true
> > > +
> > > + required:
> > > + - data-lanes
> > > + - remote-endpoint
> > > +
> > > + additionalProperties: false
> > > +
> > > + additionalProperties: false
> > > +
> > > + port@1:
> > > + type: object
> > > + description: |
> > > + Output / source port node, endpoint describing modules
> > > + connected the CSI-2 receiver.
> > > +
> > > + properties:
> > > +
> > > + reg:
> > > + const: 1
> > > +
> > > + endpoint:
> > > + type: object
> > > +
> > > + properties:
> > > +
> > > + remote-endpoint: true
> > > +
> > > + required:
> > > + - remote-endpoint
> > > +
> > > + additionalProperties: false
> > > +
> > > + additionalProperties: false
> > > +
> > > +required:
> > > + - compatible
> > > + - reg
> > > + - interrupts
> > > + - clocks
> > > + - clock-names
> > > + - xlnx,csi-pxl-format
> > > + - ports
> > > +
> > > +additionalProperties: false
> > > +
> > > +examples:
> > > + - |
> > > + #include <dt-bindings/gpio/gpio.h>
> > > + xcsi2rxss_1: csi2rx@a0020000 {
> > > + compatible = "xlnx,mipi-csi2-rx-subsystem-5.0";
> > > + reg = <0x0 0xa0020000 0x0 0x10000>;
> > > + interrupt-parent = <&gic>;
> > > + interrupts = <0 95 4>;
> > > + xlnx,csi-pxl-format = <0x2a>;
> > > + xlnx,vfb;
> > > + xlnx,en-active-lanes;
> > > + xlnx,en-csi-v2-0;
> > > + xlnx,en-vcx;
> > > + clock-names = "lite_aclk", "video_aclk";
> > > + clocks = <&misc_clk_0>, <&misc_clk_1>;
> > > + video-reset-gpios = <&gpio 86 GPIO_ACTIVE_LOW>;
> > > +
> > > + ports {
> > > + #address-cells = <1>;
> > > + #size-cells = <0>;
> > > +
> > > + port@0 {
> > > + /* Sink port */
> > > + reg = <0>;
> > > + csiss_in: endpoint {
> > > + data-lanes = <1 2 3 4>;
> > > + /* MIPI CSI-2 Camera handle */
> > > + remote-endpoint = <&camera_out>;
> > > + };
> > > + };
> > > + port@1 {
> > > + /* Source port */
> > > + reg = <1>;
> > > + csiss_out: endpoint {
> > > + remote-endpoint = <&vproc_in>;
> > > + };
> > > + };
> > > + };
> > > + };
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCH v2 0/5] net: provide a devres variant of register_netdev()
From: David Miller @ 2020-05-23 23:56 UTC (permalink / raw)
To: brgl
Cc: corbet, matthias.bgg, john, sean.wang, Mark-MC.Lee, kuba, arnd,
fparent, hkallweit1, edwin.peer, devicetree, linux-kernel, netdev,
linux-arm-kernel, linux-mediatek, stephane.leprovost, pedro.tsai,
andrew.perepech, bgolaszewski
In-Reply-To: <20200523132711.30617-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <brgl@bgdev.pl>
Date: Sat, 23 May 2020 15:27:06 +0200
> From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>
> Using devres helpers allows to shrink the probing code, avoid memory leaks in
> error paths make sure the order in which resources are freed is the exact
> opposite of their allocation. This series proposes to add a devres variant
> of register_netdev() that will only work with net_device structures whose
> memory is also managed.
>
> First we add the missing documentation entry for the only other networking
> devres helper: devm_alloc_etherdev().
>
> Next we move devm_alloc_etherdev() into a separate source file.
>
> We then use a proxy structure in devm_alloc_etherdev() to improve readability.
>
> Last: we implement devm_register_netdev() and use it in mtk-eth-mac driver.
>
> v1 -> v2:
> - rebase on top of net-next after driver rename, no functional changes
Series applied, thank you.
^ permalink raw reply
* Re: [PATCH net-next v2 4/4] net: dp83869: Add RGMII internal delay configuration
From: Andrew Lunn @ 2020-05-23 22:07 UTC (permalink / raw)
To: Dan Murphy
Cc: Florian Fainelli, hkallweit1, davem, robh, netdev, linux-kernel,
devicetree
In-Reply-To: <a59412a5-7cc6-dc70-b851-c7d65c1635b7@ti.com>
> > Any why is your PHY special, in that is does care about out of range
> > delays, when others using new the new core helper don't?
>
> We are not rounding to nearest here. Basically the helper works to find the
> best match
>
> If the delay passed in is less than or equal to the smallest delay then
> return the smallest delay index
>
> If the delay passed in is greater then the largest delay then return the max
> delay index
+ /* Find an approximate index by looking up the table */
+ if (delay > delay_values[i - 1] &&
+ delay < delay_values[i]) {
+ if (delay - delay_values[i - 1] < delay_values[i] - delay)
+ return i - 1;
+ else
+ return i;
This appears to round to the nearest value when it is not an exact
match.
The documentation is a hint to the DT developer what value to put in
DT. By saying it rounders, the developer does not need to go digging
through the source code to find an exact value, otherwise -EINVAL will
be returned. They can just use the value the HW engineer suggested,
and the PHY will pick whatever is nearest.
> Not sure what you mean about this PHY being special. This helper is
> not PHY specific.
As you said, if out of range, the helper returns the top/bottom
value. Your PHY is special, the top/bottom value is not good enough,
you throw an error.
The point of helpers is to give uniform behaviour. We have one line
helpers, simply because they give uniform behaviour, rather than have
each driver do it subtlety different. But it also means drivers should
try to not add additional constraints over what the helper already
has, unless it is actually required by the hardware.
> After I think about this more I am thinking a helper may be over kill here
> and the delay to setting should be done within the PHY driver itself
The helper is useful, it will result in uniform handling of rounding
between DT values and what the PHY can actually do. But please also
move your range check and error message inside the helper.
Andrew
^ permalink raw reply
* Re: [PATCH 2/3] pwm: Add PWM driver for Intel Keem Bay
From: Uwe Kleine-König @ 2020-05-23 21:40 UTC (permalink / raw)
To: vineetha.g.jaya.kumaran
Cc: thierry.reding, robh+dt, linux-pwm, devicetree,
wan.ahmad.zainie.wan.mohamad, andriy.shevchenko
In-Reply-To: <1589723560-5734-3-git-send-email-vineetha.g.jaya.kumaran@intel.com>
Hello,
On Sun, May 17, 2020 at 09:52:39PM +0800, vineetha.g.jaya.kumaran@intel.com wrote:
> From: "Lai, Poey Seng" <poey.seng.lai@intel.com>
>
> Enable PWM support for the Intel Keem Bay SoC.
>
> Signed-off-by: Lai, Poey Seng <poey.seng.lai@intel.com>
> Signed-off-by: Vineetha G. Jaya Kumaran <vineetha.g.jaya.kumaran@intel.com>
> ---
> drivers/pwm/Kconfig | 9 ++
> drivers/pwm/Makefile | 1 +
> drivers/pwm/pwm-keembay.c | 308 ++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 318 insertions(+)
> create mode 100644 drivers/pwm/pwm-keembay.c
>
> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> index c13d146..5311975 100644
> --- a/drivers/pwm/Kconfig
> +++ b/drivers/pwm/Kconfig
> @@ -569,4 +569,13 @@ config PWM_ZX
> To compile this driver as a module, choose M here: the module
> will be called pwm-zx.
>
> +config PWM_KEEMBAY
> + tristate "Intel Keem Bay PWM driver"
> + depends on ARM64
Support for COMPILE_TEST would be nice here.
> + help
> + The platform driver for Intel Keem Bay PWM controller.
> +
> + To compile this driver as a module, choose M here: the module
> + will be called pwm-keembay.
> +
> endif
> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> index a59c710..0c84ff2 100644
> --- a/drivers/pwm/Makefile
> +++ b/drivers/pwm/Makefile
> @@ -55,3 +55,4 @@ obj-$(CONFIG_PWM_TWL) += pwm-twl.o
> obj-$(CONFIG_PWM_TWL_LED) += pwm-twl-led.o
> obj-$(CONFIG_PWM_VT8500) += pwm-vt8500.o
> obj-$(CONFIG_PWM_ZX) += pwm-zx.o
> +obj-$(CONFIG_PWM_KEEMBAY) += pwm-keembay.o
> diff --git a/drivers/pwm/pwm-keembay.c b/drivers/pwm/pwm-keembay.c
> new file mode 100644
> index 0000000..39c7310
> --- /dev/null
> +++ b/drivers/pwm/pwm-keembay.c
> @@ -0,0 +1,308 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Intel Keem Bay PWM driver
> + *
> + * Copyright (C) 2020 Intel Corporation
> + * Authors: Lai Poey Seng <poey.seng.lai@intel.com>
> + * Vineetha G. Jaya Kumaran <vineetha.g.jaya.kumaran@intel.com>
Is there publically available documentation? If so, please add a link
here.
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pwm.h>
> +#include <linux/regmap.h>
> +
> +#define TOTAL_PWM_CHANNELS 6
> +#define LEAD_IN_DEFAULT 0
> +#define PWM_COUNT_MAX 65535
please use a unique prefix for all defines in your driver. The names as
they are are too generic.
> +
> +#define KEEMBAY_PWM_EN_BIT 31
> +
> +/* Mask */
> +#define KEEMBAY_PWM_RPT_CNT_MASK GENMASK(15, 0)
> +#define KEEMBAY_PWM_LEAD_IN_MASK GENMASK(30, 16)
> +#define KEEMBAY_PWM_HIGH_MASK GENMASK(31, 16)
> +#define KEEMBAY_PWM_LOW_MASK GENMASK(15, 0)
> +
> +/* PWM Register offset */
> +#define PWM_LEADIN0_OFFSET 0x00
> +#define PWM_LEADIN1_OFFSET 0x04
> +#define PWM_LEADIN2_OFFSET 0x08
> +#define PWM_LEADIN3_OFFSET 0x0c
> +#define PWM_LEADIN4_OFFSET 0x10
> +#define PWM_LEADIN5_OFFSET 0x14
> +
> +#define PWM_HIGHLOW0_OFFSET 0x20
> +#define PWM_HIGHLOW1_OFFSET 0x24
> +#define PWM_HIGHLOW2_OFFSET 0x28
> +#define PWM_HIGHLOW3_OFFSET 0x2c
> +#define PWM_HIGHLOW4_OFFSET 0x30
> +#define PWM_HIGHLOW5_OFFSET 0x34
> +
> +struct keembay_pwm {
> + struct pwm_chip chip;
> + struct device *dev;
> + struct clk *clk;
> + void __iomem *regmap;
I'd call this member "base" instead of "regmap" as the latter has a
different meaning in the kernel.
> +};
> +
> +static inline struct keembay_pwm *to_keembay_pwm_dev(struct pwm_chip *chip)
> +{
> + return container_of(chip, struct keembay_pwm, chip);
> +}
> +
> +static inline void keembay_pwm_enable_channel(struct keembay_pwm *priv, int ch)
> +{
> + u32 buff, offset;
> + void __iomem *address;
> +
> + offset = PWM_LEADIN0_OFFSET + ch * 4;
> + address = priv->regmap + offset;
> + buff = readl(address);
> + buff |= BIT(KEEMBAY_PWM_EN_BIT);
> + writel(buff, address);
> +}
> +
> +static inline void keembay_pwm_disable_channel(struct keembay_pwm *priv, int ch)
> +{
> + u32 buff, offset;
> + void __iomem *address;
> +
> + offset = PWM_LEADIN0_OFFSET + ch * 4;
> + address = priv->regmap + offset;
> + buff = readl(address);
> + buff &= ~BIT(KEEMBAY_PWM_EN_BIT);
> + writel(buff, address);
> +}
The two functions above could make use of keembay_pwm_update_bits().
> +
> +static inline void keembay_pwm_update_bits(struct keembay_pwm *priv, u32 mask,
> + u32 val, u32 reg, int ch)
> +{
> + u32 buff, offset, tmp;
> + void __iomem *address;
> +
> + offset = reg + ch * 4;
> + address = priv->regmap + offset;
> + buff = readl(address);
> + tmp = buff & ~mask;
> + tmp |= FIELD_PREP(mask, val);
> + writel(tmp, address);
> +}
> +
> +static inline u32 keembay_pwm_config_min(struct keembay_pwm *priv)
> +{
> + unsigned long long divd, divs;
> +
> + divd = NSEC_PER_SEC;
> + divs = clk_get_rate(priv->clk);
> + do_div(divd, divs);
Given that both NSEC_PER_SEC and the return value of clk_get_rate fit
into an unsigned long, this seems too much.
> + return (u32)divd;
> +}
> +
> +static inline u16 keembay_pwm_config_duty_cycle(struct keembay_pwm *priv,
> + int duty_ns, u32 ns_min)
> +{
> + unsigned long long divd;
> +
> + divd = duty_ns;
> + do_div(divd, ns_min);
> + if ((u16)divd == 0)
> + return 0;
> +
> + return (u16)divd - 1;
missing range checking.
> +}
> +
> +static inline u16 keembay_pwm_config_period(struct keembay_pwm *priv,
> + int period_ns,
> + int duty_ns,
> + u32 ns_min)
> +{
> + unsigned long long divd;
> +
> + divd = period_ns - duty_ns;
> + do_div(divd, ns_min);
> + if ((u16)divd == 0)
> + return 0;
> +
> + return (u16)divd - 1;
I wonder if both keembay_pwm_config_duty_cycle() and
keembay_pwm_config_period() would be easier to understand if they were not
separate functions but unrolled into their only user.
As above there is no range checking.
> +}
> +
> +/*
> + * For calculating "high time" register value:
> + * High time (quotient only) = duty_cycle / ns_min
> + *
> + * For calculating "low time" register value:
> + * Low time (quotient only) = (period - duty_cycle) / ns_min
> + *
> + * All values used are in nanoseconds for calculation.
> + */
> +static int keembay_pwm_config(struct keembay_pwm *priv, int ch,
> + int duty_ns, int period_ns, int count)
this function is only called once, I wonder if it can better be folded
into its only user.
> +{
> + u32 ns_min;
> + u16 pwm_h_count, pwm_l_count;
> +
> + /* Write to lead in */
> + keembay_pwm_update_bits(priv, KEEMBAY_PWM_LEAD_IN_MASK,
> + LEAD_IN_DEFAULT,
> + PWM_LEADIN0_OFFSET, ch);
What is the effect of this "lead in"?
> + /* Write the number of PWM pulse repetition */
> + keembay_pwm_update_bits(priv, KEEMBAY_PWM_RPT_CNT_MASK, count,
> + PWM_LEADIN0_OFFSET, ch);
Is this racy? E.g. if the PWM is already running and just after you
update the repetition count completes a period?
This writes to the same register as the lead in above. Can this be done
in a single register access?
> + /* Calculate min */
> + ns_min = keembay_pwm_config_min(priv);
What is "min"?
> + /* For duty cycle */
> + pwm_h_count = keembay_pwm_config_duty_cycle(priv, duty_ns, ns_min);
this is ineffective and less exact as possible. ns_min is the result of
a division and in keembay_pwm_config_duty_cycle you divide by it.
> + /* Write to high registers */
> + keembay_pwm_update_bits(priv, KEEMBAY_PWM_HIGH_MASK, pwm_h_count,
> + PWM_HIGHLOW0_OFFSET, ch);
> +
> + /* For period */
> + pwm_l_count = keembay_pwm_config_period(priv, period_ns, duty_ns,
> + ns_min);
> +
> + /* Write to low registers */
> + keembay_pwm_update_bits(priv, KEEMBAY_PWM_LOW_MASK, pwm_l_count,
> + PWM_HIGHLOW0_OFFSET, ch);
Can you please explain in a comment what's the resulting wave form for a
given value of this register?
Can writing h_count and l_count be combined in a single register access?
(And if not, what happens if a period completes between the two
updates?)
How does the hardware behave on a change here? Is the currently running
period completed before the new values take effect?
> +
> + return 0;
> +}
> +
> +static int keembay_pwm_enable(struct keembay_pwm *priv, int ch)
> +{
> + int ret;
> +
> + ret = clk_enable(priv->clk);
> + if (ret)
> + return ret;
> +
> + /* Enable channel */
> + keembay_pwm_enable_channel(priv, ch);
> +
> + return 0;
> +}
> +
> +static void keembay_pwm_disable(struct keembay_pwm *priv, int ch)
> +{
> + /* Disable channel */
> + keembay_pwm_disable_channel(priv, ch);
> +
> + clk_disable(priv->clk);
> +}
> +
> +static int keembay_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> + const struct pwm_state *state)
> +{
> + struct keembay_pwm *priv = to_keembay_pwm_dev(chip);
> +
> + if (!state->enabled && pwm_is_enabled(pwm)) {
Please don't call API functions in the driver.
> + keembay_pwm_disable(priv, pwm->hwpwm);
Is a currently running period completed here? How does the output behave
on disable? (i.e. does it go in its inactive state?)
> + return 0;
> + }
> +
> + if (state->count > PWM_COUNT_MAX)
> + return -EINVAL;
> +
> + if (state->polarity != pwm_get_polarity(pwm))
Using:
if (state->polarity != PWM_POLARITY_NORMAL)
seems both more robust and easier to understand.
> + return -ENOSYS;
> +
> + keembay_pwm_config(priv, pwm->hwpwm, state->duty_cycle,
> + state->period, state->count);
> +
> + if (state->enabled && !pwm_is_enabled(pwm))
> + return keembay_pwm_enable(priv, pwm->hwpwm);
> +
> + return 0;
> +}
> +
> +static const struct pwm_ops keembay_pwm_ops = {
> + .owner = THIS_MODULE,
> + .apply = keembay_pwm_apply,
Please implement .get_state().
> +};
> +
> +static int keembay_pwm_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct keembay_pwm *priv;
> + int ret;
> +
> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + priv->clk = devm_clk_get(&pdev->dev, NULL);
> + if (IS_ERR(priv->clk))
Error message please. (Something like:
int ret = PTR_ERR(ret);
if (ret != -EPROBE_DEFER)
dev_err(pdev->dev, "Failed to get clk: %pE\n", priv->clk);
return ret;
)
> + return PTR_ERR(priv->clk);
> +
> + /*
> + * Prepare clock here, and carry out clock enabling/disabling
> + * during channel enablement/disablement.
> + * The clock will not be unprepared due to shared usage with GPIO.
What has this clock to do with GPIO? If the GPIO drivers gets and
enables this clock itself there should be no problem.
> + */
> + ret = clk_prepare(priv->clk);
> + if (ret) {
> + dev_err(&pdev->dev, "Failed to prepare PWM clock\n");
Please include the error code in the message (preferably using %pE as
above).
> + return ret;
> + }
> +
> + priv->regmap = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(priv->regmap))
> + return PTR_ERR(priv->regmap);
> +
> + priv->chip.base = -1;
> + priv->chip.dev = dev;
> + priv->chip.ops = &keembay_pwm_ops;
> + priv->chip.npwm = TOTAL_PWM_CHANNELS;
> +
> + ret = pwmchip_add(&priv->chip);
> + if (ret < 0) {
> + dev_err(dev, "Failed to add PWM chip: %d\n", ret);
%pE please.
> + return ret;
> + }
> +
> + platform_set_drvdata(pdev, priv);
> +
> + return 0;
> +}
> +
> +static int keembay_pwm_remove(struct platform_device *pdev)
> +{
> + struct keembay_pwm *priv = platform_get_drvdata(pdev);
> + unsigned int i;
> +
> + for (i = 0; i < priv->chip.npwm; i++)
> + pwm_disable(&priv->chip.pwms[i]);
That's wrong. It's the responsibility of the consumer to disable the
clock.
> +
> + pwmchip_remove(&priv->chip);
clk_unprepare missing here.
> +
> + return 0;
> +}
> +
> +static const struct of_device_id keembay_pwm_of_match[] = {
> + { .compatible = "intel,keembay-pwm" },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, keembay_pwm_of_match);
> +
> +static struct platform_driver keembay_pwm_driver = {
> + .probe = keembay_pwm_probe,
> + .remove = keembay_pwm_remove,
> + .driver = {
> + .name = "pwm-keembay",
> + .of_match_table = keembay_pwm_of_match,
> + },
> +};
> +module_platform_driver(keembay_pwm_driver);
> +
> +MODULE_ALIAS("platform:keembay");
> +MODULE_DESCRIPTION("Intel Keem Bay PWM driver");
> +MODULE_LICENSE("GPL v2");
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | https://www.pengutronix.de/ |
^ permalink raw reply
* Re: [PATCH net-next v2 4/4] net: dp83869: Add RGMII internal delay configuration
From: Dan Murphy @ 2020-05-23 21:40 UTC (permalink / raw)
To: Andrew Lunn
Cc: Florian Fainelli, hkallweit1, davem, robh, netdev, linux-kernel,
devicetree
In-Reply-To: <20200523150951.GK610998@lunn.ch>
Andrew
On 5/23/20 10:09 AM, Andrew Lunn wrote:
>>>> + dp83869->tx_id_delay = DP83869_RGMII_CLK_DELAY_INV;
>>>> + ret = of_property_read_u32(of_node, "tx-internal-delay-ps",
>>>> + &dp83869->tx_id_delay);
>>>> + if (!ret && dp83869->tx_id_delay > dp83869_internal_delay[delay_size]) {
>>>> + phydev_err(phydev,
>>>> + "tx-internal-delay value of %u out of range\n",
>>>> + dp83869->tx_id_delay);
>>>> + return -EINVAL;
>>>> + }
>>> This is the kind of validation that I would be expecting from the PHY
>>> library to do, in fact, since you use Device Tree standard property, I
>>> would expect you only need to pass the maximum delay value and some
>>> storage for your array of delays.
>> Actually the PHY library will return either the 0th index if the value is to
>> small or the max index if the value is to large
>>
>> based on the array passed in so maybe this check is unnecessary.
> Hi Dan
>
> I'm not sure the helper is implementing the best behaviour. Rounded to
> the nearest when within the supported range is O.K. But if the request
> is outside the range, i would report an error.
Hope this email does not bounce.
> Any why is your PHY special, in that is does care about out of range
> delays, when others using new the new core helper don't?
We are not rounding to nearest here. Basically the helper works to find
the best match
If the delay passed in is less than or equal to the smallest delay then
return the smallest delay index
If the delay passed in is greater then the largest delay then return the
max delay index
Not sure what you mean about this PHY being special. This helper is not
PHY specific.
After I think about this more I am thinking a helper may be over kill
here and the delay to setting should be done within the PHY driver itself
Dan
> Andrew
^ permalink raw reply
* Re: [PATCH 1/3] pwm: Add count attribute in sysfs for Intel Keem Bay
From: Uwe Kleine-König @ 2020-05-23 21:05 UTC (permalink / raw)
To: vineetha.g.jaya.kumaran
Cc: thierry.reding, robh+dt, linux-pwm, devicetree,
wan.ahmad.zainie.wan.mohamad, andriy.shevchenko
In-Reply-To: <1589723560-5734-2-git-send-email-vineetha.g.jaya.kumaran@intel.com>
On Sun, May 17, 2020 at 09:52:38PM +0800, vineetha.g.jaya.kumaran@intel.com wrote:
> From: "Lai, Poey Seng" <poey.seng.lai@intel.com>
>
> In Keem Bay, the number of repetitions for the period/waveform
> can be configured from userspace. This requires addition of a sysfs
> attribute to get/set the repetition count. Setting this value to 0
> will result in continuous repetition of the waveform until the
> channel is disabled or reconfigured.
There is nothing specific for Keem Bay in this patch, the only special
thing here is that this driver is the first implementor.
IMHO all drivers that don't support count should be changed to fail if
a count > 0 is passed and introducing support in the sysfs interface
should be a separate change.
Having said that I'm not convinced this is a good idea given that only
very few driver can support this interface. Also this needs
documentation, e.g. what is expected from .get_state().
You should also motivate what this functionality is used for in the
commit log and I'd prefer to see an in-tree user (apart from sysfs which
I don't count as such).
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | https://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH] dt-bindings: dma: uart: mtk: fix example
From: matthias.bgg @ 2020-05-23 20:15 UTC (permalink / raw)
To: sean.wang, vkoul, robh+dt
Cc: matthias.bgg, dmaengine, linux-arm-kernel, linux-mediatek,
devicetree, linux-kernel, Matthias Brugger
From: Matthias Brugger <mbrugger@suse.com>
The binding example is missing the fallback compatible.
This is needed as the driver only matches against mt6577.
Signed-off-by: Matthias Brugger <mbrugger@suse.com>
---
Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt b/Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt
index 5d6f98c43e3d..2117db0ce4f2 100644
--- a/Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt
+++ b/Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt
@@ -21,7 +21,8 @@ Required properties:
Examples:
apdma: dma-controller@11000400 {
- compatible = "mediatek,mt2712-uart-dma";
+ compatible = "mediatek,mt2712-uart-dma",
+ "mediatek,mt6577-uart-dma";
reg = <0 0x11000400 0 0x80>,
<0 0x11000480 0 0x80>,
<0 0x11000500 0 0x80>,
--
2.26.2
^ permalink raw reply related
* Re: [PATCH V3] arm64: dts: mediatek: add cpufreq and cci devfreq nodes for mt8183
From: Matthias Brugger @ 2020-05-23 19:04 UTC (permalink / raw)
To: Andrew-sh.Cheng, Rob Herring, Mark Rutland, devicetree
Cc: linux-arm-kernel, linux-mediatek, linux-kernel, srv_heupstream
In-Reply-To: <1576826785-3867-1-git-send-email-andrew-sh.cheng@mediatek.com>
On 20/12/2019 08:26, Andrew-sh.Cheng wrote:
> From: "Andrew-sh.Cheng" <andrew-sh.cheng@mediatek.com>
>
> add cpufreq and cci devfreq nodes for mt8183
>
> Depend on regulator node patch:
> https://patchwork.kernel.org/patch/11284617/
>
> Signed-off-by: Andrew-sh.Cheng <andrew-sh.cheng@mediatek.com>
> ---
> arch/arm64/boot/dts/mediatek/mt8183-evb.dts | 36 ++++
> arch/arm64/boot/dts/mediatek/mt8183.dtsi | 245 ++++++++++++++++++++++++++++
> 2 files changed, 281 insertions(+)
>
[...]
> +
> + cci: cci {
> + compatible = "mediatek,mt8183-cci";
I wasn't able to find anyprovider for this compatible.
I'll drop this patch from my queue.
Regards,
Matthias
^ permalink raw reply
* Re: [PATCH V6 7/7] arm64: dts: sc7180: Add interconnect for QUP and QSPI
From: kbuild test robot @ 2020-05-23 14:05 UTC (permalink / raw)
To: Akash Asthana, gregkh, agross, bjorn.andersson, wsa, broonie,
mark.rutland, robh+dt
Cc: kbuild-all, clang-built-linux, linux-i2c, linux-spi, devicetree,
swboyd, mgautam, linux-arm-msm, linux-serial, mka, dianders
In-Reply-To: <1590049764-20912-8-git-send-email-akashast@codeaurora.org>
[-- Attachment #1: Type: text/plain, Size: 1711 bytes --]
Hi Akash,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on tty/tty-testing]
[also build test ERROR on spi/for-next wsa/i2c/for-next usb/usb-testing driver-core/driver-core-testing linus/master v5.7-rc6]
[cannot apply to next-20200522]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Akash-Asthana/Add-interconnect-support-to-QSPI-and-QUP-drivers/20200521-163523
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
config: arm64-randconfig-r026-20200521 (attached as .config)
compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project 3393cc4cebf9969db94dc424b7a2b6195589c33b)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install arm64 cross compiling tool for clang build
# apt-get install binutils-aarch64-linux-gnu
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>
All errors (new ones prefixed by >>, old ones prefixed by <<):
>> Error: arch/arm64/boot/dts/qcom/sc7180.dtsi:430.31-32 syntax error
>> FATAL ERROR: Unable to parse input tree
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 42362 bytes --]
^ permalink raw reply
* [PATCH] arm64: dts: qcom: sm8250: change ufs node name to ufshc
From: Jonathan Marek @ 2020-05-23 17:52 UTC (permalink / raw)
To: linux-arm-msm
Cc: Andy Gross, Bjorn Andersson, Rob Herring,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list
The ufs-qcom driver checks that the name matches the androidboot.bootdevice
parameter provided by the bootloader, which uses the name ufshc. Without
this change UFS fails to probe.
I think this is broken behavior from the ufs-qcom driver, but using the
name ufshc is consistent with dts for sdm845/sm8150/etc.
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
---
arch/arm64/boot/dts/qcom/sm8250.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
index e0344d3ba159..3bdce658c08a 100644
--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
@@ -309,7 +309,7 @@ uart2: serial@a90000 {
};
};
- ufs_mem_hc: ufs@1d84000 {
+ ufs_mem_hc: ufshc@1d84000 {
compatible = "qcom,sm8250-ufshc", "qcom,ufshc",
"jedec,ufs-2.0";
reg = <0 0x01d84000 0 0x3000>;
--
2.26.1
^ 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