* [RFC PATCH 2/3] dt: bindings: Add SD tap value properties details
From: Manish Narani @ 2018-06-21 12:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607124743.fqo7f7nxonn2k3b5@lakrids.cambridge.arm.com>
Hi Mark,
> -----Original Message-----
> From: Mark Rutland [mailto:mark.rutland at arm.com]
> Sent: Thursday, June 7, 2018 6:18 PM
> To: Manish Narani <MNARANI@xilinx.com>
> Cc: robh+dt at kernel.org; catalin.marinas at arm.com; will.deacon at arm.com;
> mdf at kernel.org; stefan.krsmanovic at aggios.com; linux-arm-
> kernel at lists.infradead.org; linux-kernel at vger.kernel.org; linux-
> mmc at vger.kernel.org; devicetree at vger.kernel.org; adrian.hunter at intel.com;
> michal.simek at xilinx.com; ulf.hansson at linaro.org
> Subject: Re: [RFC PATCH 2/3] dt: bindings: Add SD tap value properties details
>
> On Thu, Jun 07, 2018 at 05:41:39PM +0530, Manish Narani wrote:
> > This patch adds details of SD tap value properties in device tree.
> >
> > Signed-off-by: Manish Narani <manish.narani@xilinx.com>
> > ---
> > .../devicetree/bindings/mmc/arasan,sdhci.txt | 26
> ++++++++++++++++++++++
> > 1 file changed, 26 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
> > b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
> > index 60481bf..0e08877 100644
> > --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
> > +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
> > @@ -15,6 +15,8 @@ Required Properties:
> > - "arasan,sdhci-5.1": generic Arasan SDHCI 5.1 PHY
> > - "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1": rk3399 eMMC PHY
> > For this device it is strongly suggested to include arasan,soc-ctl-syscon.
> > + - "xlnx,zynqmp-8.9a": Xilinx ZynqMP Arasan SDHCI 8.9a PHY
> > + For this device it is strongly suggested to include arasan,soc-ctl-syscon.
> > - reg: From mmc bindings: Register location and length.
> > - clocks: From clock bindings: Handles to clock inputs.
> > - clock-names: From clock bindings: Tuple including "clk_xin" and "clk_ahb"
> > @@ -26,6 +28,30 @@ Required Properties for "arasan,sdhci-5.1":
> > - phys: From PHY bindings: Phandle for the Generic PHY for arasan.
> > - phy-names: MUST be "phy_arasan".
> >
> > +Required Properties for "xlnx,zynqmp-8.9a":
> > + - xlnx,mio_bank: The value will be 0/1/2 depending on MIO bank selection.
>
> For all of these properties, please s/_/-/, folowing the usual property name
> conventions.
I will correct this in the next version.
>
> It's not clear to me why you need this property. The code in patch 3 only seems
> to use this to determine which properties to read, choosing between <prop>_b0
> or <prop>_b2. I don't see why you dont have the base <prop> alone...
The property 'xlnx,mio_bank' will be different for various ZynqMP varients. So different ZynqMP dts files may have different values for 'xlnx,mio_bank'. That's why I am maintaining _b0 and _b2 as different values
>
> Is this a HW detail, or configuration that you prefer?
These are SD tap values which are generally used for configuring taps in SD. Keeping it in device tree makes it User Configurable without changing the driver code.
>
> > + - xlnx,device_id: Unique Id of the device, value will be 0/1.
>
> What's this used for?
This used to identify the controller ID between two SD controllers present on ZynqMP.
>
> > + - xlnx,itap_delay_sd_hsd: Input Tap Delay for SD HS.
>
> What unit at hese delays in?
The tap values don't have specific units. They are generally a fraction of the clock cycle.
For the SD frequency of -
200 MHz: 30 Input taps are available
100 MHz: 60 Input taps are available
50 MHz: 120 Input taps are available
200 MHz: 8 Output taps are available
100 MHz: 15 Output taps are available
50 MHz: 30 Output taps are available
Thanks,
Manish
>
> Please follow the conventions in
> Documentation/devicetree/bindings/property-units.txt.
>
> > + - xlnx,itap_delay_sdr25: Input Tap Delay for SDR25.
> > + - xlnx,itap_delay_sdr50: Input Tap Delay for SDR50.
> > + - xlnx,itap_delay_sdr104_b0: Input Tap Delay for SDR104.
> > + - xlnx,itap_delay_sdr104_b2: Input Tap Delay for SDR104.
>
> As above, Given you have to specify the bank, I don't see why you need multiple
> properties.
>
> Thanks,
> Mark.
>
> > + - xlnx,itap_delay_sd_ddr50: Input Tap Delay for SD DDR50.
> > + - xlnx,itap_delay_mmc_hsd: Input Tap Delay for MMC HS.
> > + - xlnx,itap_delay_mmc_ddr50: Input Tap Delay for MMC DDR50.
> > + - xlnx,itap_delay_mmc_hs200_b0: Input Tap Delay for MMC HS200.
> > + - xlnx,itap_delay_mmc_hs200_b2: Input Tap Delay for MMC HS200.
> > + - xlnx,otap_delay_sd_hsd: Output Tap Delay for SD HS.
> > + - xlnx,otap_delay_sdr25: Output Tap Delay for SDR25.
> > + - xlnx,otap_delay_sdr50: Output Tap Delay for SDR50.
> > + - xlnx,otap_delay_sdr104_b0: Output Tap Delay for SDR104.
> > + - xlnx,otap_delay_sdr104_b2: Output Tap Delay for SDR104.
> > + - xlnx,otap_delay_sd_ddr50: Output Tap Delay for DDR50.
> > + - xlnx,otap_delay_mmc_hsd: Output Tap Delay for MMC HS.
> > + - xlnx,otap_delay_mmc_ddr50: Output Tap Delay for MMC DDR50.
> > + - xlnx,otap_delay_mmc_hs200_b0: Output Tap Delay for MMC HS200.
> > + - xlnx,otap_delay_mmc_hs200_b2: Output Tap Delay for MMC HS200.
> > +
> > Optional Properties:
> > - arasan,soc-ctl-syscon: A phandle to a syscon device (see ../mfd/syscon.txt)
> > used to access core corecfg registers. Offsets of registers in
> > this
> > --
> > 2.7.4
^ permalink raw reply
* [PATCH] usb: chipidea: Fix ULPI on imx51
From: Andrey Smirnov @ 2018-06-21 12:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOMZO5DJj=oQfsB-vNP=81HCiy-69j-5U+Km9P6LxGpnLx9xzg@mail.gmail.com>
On Wed, Jun 20, 2018 at 3:22 PM Fabio Estevam <festevam@gmail.com> wrote:
>
> On Wed, Jun 20, 2018 at 7:07 PM, Fabio Estevam <festevam@gmail.com> wrote:
>
> > This patches causes a regression on a imx51-babbage running 4.18-rc1:
> > I get a kernel hang.
> >
> > If I revert it on top of 4.18-rc1, then it boots fine and USB host is
> > functional.
> >
> > I understand this patch fixes a kernel hang for you, so which commit
> > is responsible for the hang you observe?
> >
I never assumed it was a regression and that USB worked on RDU1 board
before, so I never tried to see if this was a regression. I can only
tell you that it hangs as soon as any PORTSC registers are accessed.
> > It seems this commit fixes a hang for you and causes another hang for me :-)
> >
> > Any ideas?
>
RDU1 design is based heavily on Babbage board, moreso USB1/ULPI
portion of it is an exact copy (it does use different GPIO for PHY
reset, but that's irrelevant), so I am surprised that it breaks in
your case.
However looking at imx51-babbage.dts, I am suspicious of it's USB1
setup. There we have usbh1phy node that references <&gpio2 5
GPIO_ACTIVE_LOW> as reset, but corresponding pinmux, pinctrl_usbh1reg,
is not being used anywhere. Cold that be that the problem you are
seeing is due to USB PHY not being properly reset?
> I am able to boot again if I skip passing the CI_HDRC_OVERRIDE_PHY_CONTROL flag:
>
Yeah, IMHO if you are dropping that flag, you may as well revert the
whole patch :-). The path that make the kernel hang in my case would
be taken if that flag is dropped.
Thanks,
Andrey Smirnov
^ permalink raw reply
* [RFC PATCH 3/3] sdhci: arasan: Add support to read Tap Delay values from DT
From: Manish Narani @ 2018-06-21 12:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <6d3b2f29-fe8d-b084-3e1f-631cf20796b9@intel.com>
Hi Adrian,
> -----Original Message-----
> From: Adrian Hunter [mailto:adrian.hunter at intel.com]
> Sent: Tuesday, June 19, 2018 5:08 PM
> To: Manish Narani <MNARANI@xilinx.com>; robh+dt at kernel.org;
> catalin.marinas at arm.com; will.deacon at arm.com; mdf at kernel.org;
> stefan.krsmanovic at aggios.com; linux-arm-kernel at lists.infradead.org; linux-
> kernel at vger.kernel.org; linux-mmc at vger.kernel.org;
> devicetree at vger.kernel.org; Michal Simek <michals@xilinx.com>;
> ulf.hansson at linaro.org
> Cc: Srinivas Goud <sgoud@xilinx.com>; Anirudha Sarangi
> <anirudh@xilinx.com>
> Subject: Re: [RFC PATCH 3/3] sdhci: arasan: Add support to read Tap Delay
> values from DT
>
> On 14/06/18 08:38, Manish Narani wrote:
> > Ping for RFC
>
> What is eemi? Why aren't there patches for that?
Eemi(Extensible Energy Management Interface) is a power management interface for ZynqMP core. The patches for the same are already in process of mainlining.
https://lkml.org/lkml/2018/6/20/823
Thanks,
Manish
>
> >
> >> -----Original Message-----
> >> From: Manish Narani [mailto:manish.narani at xilinx.com]
> >> Sent: Thursday, June 7, 2018 5:42 PM
> >> To: robh+dt at kernel.org; mark.rutland at arm.com;
> >> catalin.marinas at arm.com; will.deacon at arm.com; mdf at kernel.org;
> >> stefan.krsmanovic at aggios.com; linux-arm-kernel at lists.infradead.org;
> >> linux-kernel at vger.kernel.org; linux- mmc at vger.kernel.org;
> >> devicetree at vger.kernel.org; adrian.hunter at intel.com;
> >> michal.simek at xilinx.com; ulf.hansson at linaro.org
> >> Cc: Manish Narani <MNARANI@xilinx.com>
> >> Subject: [RFC PATCH 3/3] sdhci: arasan: Add support to read Tap Delay
> >> values from DT
> >>
> >> This patch adds support for reading Tap Delay values from Device Tree
> >> and write them via eemi calls. The macros containing these tap delay
> >> values are removed from the driver.
> >>
> >> Signed-off-by: Manish Narani <manish.narani@xilinx.com>
> >> ---
> >> drivers/mmc/host/sdhci-of-arasan.c | 131
> >> +++++++++++++++++++++++++++++++++++++
> >> 1 file changed, 131 insertions(+)
> >>
> >> diff --git a/drivers/mmc/host/sdhci-of-arasan.c
> >> b/drivers/mmc/host/sdhci- of-arasan.c index e3332a5..fc0fd01 100644
> >> --- a/drivers/mmc/host/sdhci-of-arasan.c
> >> +++ b/drivers/mmc/host/sdhci-of-arasan.c
> >> @@ -36,6 +36,8 @@
> >>
> >> #define PHY_CLK_TOO_SLOW_HZ 400000
> >>
> >> +#define MMC_BANK2 0x2
> >> +
> >> /*
> >> * On some SoCs the syscon area has a feature where the upper 16-bits of
> >> * each 32-bit register act as a write mask for the lower 16-bits.
> >> This allows @@ -90,6 +92,10 @@ struct sdhci_arasan_data {
> >> struct sdhci_host *host;
> >> struct clk *clk_ahb;
> >> struct phy *phy;
> >> + u32 mio_bank;
> >> + u32 device_id;
> >> + u32 itapdly[MMC_TIMING_MMC_HS400 + 1];
> >> + u32 otapdly[MMC_TIMING_MMC_HS400 + 1];
> >> bool is_phy_on;
> >>
> >> bool has_cqe;
> >> @@ -160,11 +166,36 @@ static int sdhci_arasan_syscon_write(struct
> >> sdhci_host *host,
> >> return ret;
> >> }
> >>
> >> +/**
> >> + * arasan_zynqmp_set_tap_delay - Program the tap delays.
> >> + * @deviceid: Unique Id of device
> >> + * @itap_delay: Input Tap Delay
> >> + * @oitap_delay: Output Tap Delay
> >> + */
> >> +static void arasan_zynqmp_set_tap_delay(u8 deviceid, u8 itap_delay,
> >> +u8
> >> +otap_delay) {
> >> + const struct zynqmp_eemi_ops *eemi_ops =
> >> zynqmp_pm_get_eemi_ops();
> >> + u32 node_id = (deviceid == 0) ? NODE_SD_0 : NODE_SD_1;
> >> +
> >> + if (!eemi_ops || !eemi_ops->ioctl)
> >> + return;
> >> +
> >> + if (itap_delay)
> >> + eemi_ops->ioctl(node_id, IOCTL_SET_SD_TAPDELAY,
> >> + PM_TAPDELAY_INPUT, itap_delay, NULL);
> >> +
> >> + if (otap_delay)
> >> + eemi_ops->ioctl(node_id, IOCTL_SET_SD_TAPDELAY,
> >> + PM_TAPDELAY_OUTPUT, otap_delay, NULL);
> >> }
> >> +
> >> static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned
> >> int
> >> clock) {
> >> struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> >> struct sdhci_arasan_data *sdhci_arasan =
> >> sdhci_pltfm_priv(pltfm_host);
> >> bool ctrl_phy = false;
> >> + u8 itap_delay;
> >> + u8 otap_delay;
> >>
> >> if (!IS_ERR(sdhci_arasan->phy)) {
> >> if (!sdhci_arasan->is_phy_on && clock <=
> >> PHY_CLK_TOO_SLOW_HZ) { @@ -200,6 +231,16 @@ static void
> >> sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock)
> >> }
> >> }
> >>
> >> + if (host->version >= SDHCI_SPEC_300) {
> >> + if ((host->timing != MMC_TIMING_LEGACY) &&
> >> + (host->timing != MMC_TIMING_UHS_SDR12)) {
> >> + itap_delay = sdhci_arasan->itapdly[host->timing];
> >> + otap_delay = sdhci_arasan->otapdly[host->timing];
> >> + arasan_zynqmp_set_tap_delay(sdhci_arasan-
> >>> device_id,
> >> + itap_delay, otap_delay);
> >> + }
> >> + }
> >> +
> >> if (ctrl_phy && sdhci_arasan->is_phy_on) {
> >> phy_power_off(sdhci_arasan->phy);
> >> sdhci_arasan->is_phy_on = false;
> >> @@ -456,6 +497,7 @@ static const struct of_device_id
> >> sdhci_arasan_of_match[] = {
> >> { .compatible = "arasan,sdhci-8.9a" },
> >> { .compatible = "arasan,sdhci-5.1" },
> >> { .compatible = "arasan,sdhci-4.9a" },
> >> + { .compatible = "xlnx,zynqmp-8.9a" },
> >>
> >> { /* sentinel */ }
> >> };
> >> @@ -641,6 +683,74 @@ static void sdhci_arasan_unregister_sdclk(struct
> >> device *dev)
> >> of_clk_del_provider(dev->of_node);
> >> }
> >>
> >> +/**
> >> + * arasan_zynqmp_dt_parse_tap_delays - Read Tap Delay values from DT
> >> + *
> >> + * Called at initialization to parse the values of Tap Delays.
> >> + *
> >> + * @dev: Pointer to our struct device.
> >> + */
> >> +static void arasan_zynqmp_dt_parse_tap_delays(struct device *dev) {
> >> + struct platform_device *pdev = to_platform_device(dev);
> >> + struct sdhci_host *host = platform_get_drvdata(pdev);
> >> + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> >> + struct sdhci_arasan_data *sdhci_arasan =
> >> sdhci_pltfm_priv(pltfm_host);
> >> + struct device_node *np = dev->of_node;
> >> +
> >> + of_property_read_u32(np, "xlnx,itap_delay_sd_hsd",
> >> + &sdhci_arasan->itapdly[MMC_TIMING_SD_HS]);
> >> + of_property_read_u32(np, "xlnx,otap_delay_sd_hsd",
> >> + &sdhci_arasan->otapdly[MMC_TIMING_SD_HS]);
> >> + of_property_read_u32(np, "xlnx,itap_delay_sdr25",
> >> + &sdhci_arasan-
> >>> itapdly[MMC_TIMING_UHS_SDR25]);
> >> + of_property_read_u32(np, "xlnx,otap_delay_sdr25",
> >> + &sdhci_arasan-
> >>> otapdly[MMC_TIMING_UHS_SDR25]);
> >> + of_property_read_u32(np, "xlnx,itap_delay_sdr50",
> >> + &sdhci_arasan-
> >>> itapdly[MMC_TIMING_UHS_SDR50]);
> >> + of_property_read_u32(np, "xlnx,otap_delay_sdr50",
> >> + &sdhci_arasan-
> >>> otapdly[MMC_TIMING_UHS_SDR50]);
> >> + of_property_read_u32(np, "xlnx,itap_delay_sd_ddr50",
> >> + &sdhci_arasan-
> >>> itapdly[MMC_TIMING_UHS_DDR50]);
> >> + of_property_read_u32(np, "xlnx,otap_delay_sd_ddr50",
> >> + &sdhci_arasan-
> >>> otapdly[MMC_TIMING_UHS_DDR50]);
> >> + of_property_read_u32(np, "xlnx,itap_delay_mmc_hsd",
> >> + &sdhci_arasan-
> >>> itapdly[MMC_TIMING_MMC_HS]);
> >> + of_property_read_u32(np, "xlnx,otap_delay_mmc_hsd",
> >> + &sdhci_arasan-
> >>> otapdly[MMC_TIMING_MMC_HS]);
> >> + of_property_read_u32(np, "xlnx,itap_delay_mmc_ddr50",
> >> + &sdhci_arasan-
> >>> itapdly[MMC_TIMING_MMC_DDR52]);
> >> + of_property_read_u32(np, "xlnx,otap_delay_mmc_ddr50",
> >> + &sdhci_arasan-
> >>> otapdly[MMC_TIMING_MMC_DDR52]);
> >> + if (sdhci_arasan->mio_bank == MMC_BANK2) {
> >> + of_property_read_u32(np,
> >> + "xlnx,itap_delay_sdr104_b2",
> >> + &sdhci_arasan-
> >>> itapdly[MMC_TIMING_UHS_SDR104]);
> >> + of_property_read_u32(np,
> >> + "xlnx,otap_delay_sdr104_b2",
> >> + &sdhci_arasan-
> >>> otapdly[MMC_TIMING_UHS_SDR104]);
> >> + of_property_read_u32(np,
> >> + "xlnx,itap_delay_mmc_hs200_b2",
> >> + &sdhci_arasan-
> >>> itapdly[MMC_TIMING_MMC_HS200]);
> >> + of_property_read_u32(np,
> >> + "xlnx,otap_delay_mmc_hs200_b2",
> >> + &sdhci_arasan-
> >>> otapdly[MMC_TIMING_MMC_HS200]);
> >> + } else {
> >> + of_property_read_u32(np,
> >> + "xlnx,itap_delay_sdr104_b0",
> >> + &sdhci_arasan-
> >>> itapdly[MMC_TIMING_UHS_SDR104]);
> >> + of_property_read_u32(np,
> >> + "xlnx,otap_delay_sdr104_b0",
> >> + &sdhci_arasan-
> >>> otapdly[MMC_TIMING_UHS_SDR104]);
> >> + of_property_read_u32(np,
> >> + "xlnx,itap_delay_mmc_hs200_b0",
> >> + &sdhci_arasan-
> >>> itapdly[MMC_TIMING_MMC_HS200]);
> >> + of_property_read_u32(np,
> >> + "xlnx,otap_delay_mmc_hs200_b0",
> >> + &sdhci_arasan-
> >>> otapdly[MMC_TIMING_MMC_HS200]);
> >> + }
> >> +}
> >> +
> >> static int sdhci_arasan_add_host(struct sdhci_arasan_data *sdhci_arasan) {
> >> struct sdhci_host *host = sdhci_arasan->host; @@ -776,6 +886,27 @@
> >> static int sdhci_arasan_probe(struct platform_device *pdev)
> >> goto unreg_clk;
> >> }
> >>
> >> + if (of_device_is_compatible(pdev->dev.of_node,
> >> + "xlnx,zynqmp-8.9a")) {
> >> + ret = of_property_read_u32(pdev->dev.of_node,
> >> + "xlnx,mio_bank",
> >> + &sdhci_arasan->mio_bank);
> >> + if (ret < 0) {
> >> + dev_err(&pdev->dev,
> >> + "\"xlnx,mio_bank \" property is missing.\n");
> >> + goto clk_disable_all;
> >> + }
> >> + ret = of_property_read_u32(pdev->dev.of_node,
> >> + "xlnx,device_id",
> >> + &sdhci_arasan->device_id);
> >> + if (ret < 0) {
> >> + dev_err(&pdev->dev,
> >> + "\"xlnx,device_id \" property is missing.\n");
> >> + goto clk_disable_all;
> >> + }
> >> + arasan_zynqmp_dt_parse_tap_delays(&pdev->dev);
> >> + }
> >> +
> >> sdhci_arasan->phy = ERR_PTR(-ENODEV);
> >> if (of_device_is_compatible(pdev->dev.of_node,
> >> "arasan,sdhci-5.1")) {
> >> --
> >> 2.7.4
> >
> >
^ permalink raw reply
* [PATCH 0/5] RFC: Mezzanine handling for 96boards
From: Frank Rowand @ 2018-06-21 12:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180618074556.6944-1-linus.walleij@linaro.org>
On 06/18/18 00:45, Linus Walleij wrote:
> This is a proposal for how to handle the non-discoverable
> 96boards plug-in expansion boards called "mezzanines" in the
> Linux kernel. It is a working RFC series meant for discussion
> at the moment.
< snip >
> So for that reason, or other predictable statements such
> as "you're reinventing board files", I'd like to have an
> open discussion on how to actually support these boards
> with the mainline kernel and work on device drivers common
> with other systems now, and not in 2020 when they are already
> obsolete.
>
> Yeah it is a bit controversial, but what we are doing right
> now for non-discoverable expansion boards isn't working
> in my opinion, so I have to throw something out there,
> and this is it.
< snip >
why can't a devicetree description of the devices on the
mezzanine board be used?
I do understand the desire to describe interchangeable mezzanine
boards separately from the base devicetree, such as in an
overlay. Overlays can be applied today by U-boot before the
Linux kernel is booted, so lack of being able to apply an
overlay after Linux boot completes is not a blocker.
-Frank
^ permalink raw reply
* [PATCH 0/5] RFC: Mezzanine handling for 96boards
From: Frank Rowand @ 2018-06-21 13:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAL_JsqK2DKPbaFvUPSU2E7oh1_pryrRXPMg8OASmK722jmznwA@mail.gmail.com>
On 06/19/18 08:52, Rob Herring wrote:
> On Mon, Jun 18, 2018 at 1:45 AM, Linus Walleij <linus.walleij@linaro.org> wrote:
>> This is a proposal for how to handle the non-discoverable
>> 96boards plug-in expansion boards called "mezzanines" in the
>> Linux kernel. It is a working RFC series meant for discussion
>> at the moment.
>>
>> The RFC was done on the brand new Ultra96 board from Xilinx
>> with a Secure96 mezzanine expansion board. The main part
>> is in patch 4, the rest is enabling and examples.
>>
>> The code can be obtained from here:
>> https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=ultra96
>>
>> You can for example probably augment the DTS file for any
>> upstream-supported 96board and get the Secure96 going with
>> it with minor efforts.
>>
>> TODO:
>>
>> - Proper device tree bindings for the connector, for now
>> look at the example.
>>
>> - Discuss whether to actually do this or just take it all and
>> flush it down the drain because the community doesn't like
>> it. I'm not one of those especially infatuated with my own code,
>> I always stay by the old programming project management mantra
>> to calculate to make one version and throw it away as stepping
>> stone to a good final design.
>>
>> - Placement: putting this in drivers/bus is just an example.
>> drivers/platform/96boards-mezzanines is fine too, maybe better?
>>
>> - I am especially curious about input from Andy and Mika from
>> the Intel/ACPI camp on what they have seen for non-discoverable
>> plug-in boards. Does this problem even exist in the Intel
>> world, or not...
>>
>> Background:
>>
>> - These boards connect on a custom connector on this family
>> of boards. The relationship is many-to-many with the connector
>> as nexus. The electronic standard for the connector is specified:
>> https://github.com/96boards/documentation/blob/master/Specifications/96Boards-CE-Specification.pdf
>> Example mezzanines:
>> https://www.96boards.org/documentation/mezzanine/
>>
>> - These boards have siblings on other platforms, the problem
>> scope is similar with BeagleBone "capes":
>> https://beagleboard.org/capes
>> Raspberry Pi expansion boards:
>> https://www.abelectronics.co.uk/products/18/raspberry-pi-expansion-boards
>> Intel Edison, Galileo, Joule also have expansion boards.
>>
>> Idea: add a driver for the connector itself and tie it in to
>> the device tree with a compatible string. Since the boards
>> are non-discoverable two mechanisms are provided to discover
>> them:
>>
>> - Add a very simple device tree node with just a compatible
>> string for the board in the node. This will be simple to
>> add from e.g. a boot loader or as an overlay from userspace.
>>
>> board {
>> compatible = "96boards,secure96";
>> };
>>
>>
>> - Echo 1 > boardname into a sysfs file to populate the
>> board and echo 0 > boardname to depopulate it. This
>> makes it easy to even switch out expansion boards at
>> runtime, if allowed by the electronics.
>>
>> > cd /sys/devices/platform/connector
>> > echo 1 > secure96
>> lscon connector: called mezzanine_store on secure96
>> lscon connector: populate secure96
>> at24 1-0050: 2048 byte 24c128 EEPROM, writable, 128 bytes/write
>> atmel-ecc 1-0060: configuration zone is unlocked
>> tpm_tis_spi spi0.0: 2.0 TPM (device-id 0x1B, rev-id 16)
>> (...)
>>
>> What this patch set does not do:
>>
>> - It does not use device tree or ACPI DSDT or any other
>> hardware decription language to model the contents of the
>> board per se. Instead the boards buses are populated
>> directly with platform devices.
>>
>> Predictable complaints about this design:
>>
>> Q: This is not device tree overlays. Why is it not device
>> tree overlays?
>>
>> A1: Right tool for the job, overlays are complex and the
>> plan to get it in place seems to be spanning years, this
>> is a few devices on simple busses and it works today.
>> Using this approach I can already work on shaping up
>> drivers for the mezzanine board devices as proved by:
>> https://marc.info/?l=linux-crypto-vger&m=152820660120590&w=2
>> https://marc.info/?l=linux-crypto-vger&m=152820662820595&w=2
>> (...)
>>
>> I can work on drivers for the chips on the
>> Secure96 mezzanine board. It's just an example of
>> what the mezzanine community can do.
>> Now they are hacking around in userspace instead of
>> doing/reusing kernel drivers for their stuff:
>> https://github.com/jbech-linaro/secure96
>>
>> This way we can bring developers for these components
>> into the kernel community instead of telling them to
>> wait for some big infrastructure that comes later
>> before they can contribute their stuff.
>>
>> A2: Overlays does not solve the problem if the system runs
>> ACPI, and what about if the same connector[s] appear
>> on a server board, servers use ACPI. Also notice
>> that Intel have development boards with non-discoverable
>> expansion boards as well. They just will not use
>> device tree.
>>
>> A3: Overlays is Big Upfront Design.
>> https://en.wikipedia.org/wiki/Big_Design_Up_Front
>> This way of designing things is associated with the
>> (pejorative term) "waterfall model" which is out of
>> fashion as a way of doing development. I think I am not
>> the only one slightly annoyed by the fact that device
>> tree overlays is now starting to look like a very
>> big very upfront design. It's just not possible to get
>> something up and running in small iterative steps with
>> device tree overlays. Instead huge efforts are
>> required and it involves major possible showstoppers
>> and uncertain outcome as indicated by Frank's TODO:
>> https://elinux.org/Frank's_Evolving_Overlay_Thoughts
>
> I don't agree. This can be broken down into various smaller mostly
> independent problems. Overlay handling is mostly an orthogonal
> problem. The exception is that we need to ensure bindings allow a
> decoupling of upstream of the connector and downstream of the
> connector so the downstream part can be a reusable overlay. Defining
> anything while ignoring this known criteria would be a mistake.
>
> The list is roughly like this:
>
> - Connector node binding and probing infrastructure
> - GPIO (already done w/ gpio-map binding)
> - I2C
> - SPI
> - Pinmux
> - clocks
> - OF graph (displays, cameras, etc.)
> - USB (re-use the USB connector binding for non-standard connectors)
> - Userspace interface
>
> We don't have to support every interface from the start. The bindings
> and corresponding kernel support can be designed 1-by-1 for the most
> part. Start with something simple like a GPIO LED on a mezzanine. Once
> the base is functionality is there, the other parts can be worked on
> incrementally. We can punt any overlay handling to the bootloader
> initially. That punts all the issues around overlays like designing a
> userspace interface, where overlays are located (filesystem, passed
> from bootloader, built into the kernel), when they are loaded, and how
> to specify which overlays to load. Most of Frank's list is related to
> these issues.
>
> Rob
>
Agreeing with Rob (despite my other reply asking why the current
devicetree mechanisms can't be used) that we do have a desire to
have the ability to create bindings for connectors - this has been
discussed before.
-Frank
^ permalink raw reply
* [PATCH v2 1/5] dmaengine: xilinx_dma: in axidma slave_sg and dma_cyclic mode align split descriptors
From: Radhey Shyam Pandey @ 2018-06-21 13:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180621115822.20058-1-andrea.merello@gmail.com>
> -----Original Message-----
> From: dmaengine-owner at vger.kernel.org [mailto:dmaengine-
> owner at vger.kernel.org] On Behalf Of Andrea Merello
> Sent: Thursday, June 21, 2018 5:28 PM
> To: vkoul at kernel.org; dan.j.williams at intel.com; Michal Simek
> <michals@xilinx.com>; Appana Durga Kedareswara Rao
> <appanad@xilinx.com>; dmaengine at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
> Andrea Merello <andrea.merello@gmail.com>
> Subject: [PATCH v2 1/5] dmaengine: xilinx_dma: in axidma slave_sg and
> dma_cyclic mode align split descriptors
>
> Whenever a single or cyclic transaction is prepared, the driver
> could eventually split it over several SG descriptors in order
> to deal with the HW maximum transfer length.
>
> This could end up in DMA operations starting from a misaligned
> address. This seems fatal for the HW if DRE is not enabled.
>
> This patch eventually adjusts the transfer size in order to make sure
> all operations start from an aligned address.
>
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> ---
> Changes in v2:
> - don't introduce copy_mask field, rather rely on already-esistent
> copy_align field. Suggested by Radhey Shyam Pandey
> - reword title
> ---
> drivers/dma/xilinx/xilinx_dma.c | 22 ++++++++++++++++------
> 1 file changed, 16 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
> index 27b523530c4a..22d7a6b85e65 100644
> --- a/drivers/dma/xilinx/xilinx_dma.c
> +++ b/drivers/dma/xilinx/xilinx_dma.c
> @@ -1789,10 +1789,15 @@ static struct dma_async_tx_descriptor
> *xilinx_dma_prep_slave_sg(
>
> /*
> * Calculate the maximum number of bytes to transfer,
> - * making sure it is less than the hw limit
> + * making sure it is less than the hw limit and that
> + * the next chunck start address is aligned
/s/chunck/chunk . Same for later occurrence.
> */
> - copy = min_t(size_t, sg_dma_len(sg) - sg_used,
> - XILINX_DMA_MAX_TRANS_LEN);
> + copy = sg_dma_len(sg) - sg_used;
> + if (copy > XILINX_DMA_MAX_TRANS_LEN &&
> + chan->xdev->common.copy_align)
> + copy =
> rounddown(XILINX_DMA_MAX_TRANS_LEN,
> + (1 << chan->xdev-
> >common.copy_align));
> +
If DRE is not enabled (copy_align=0) we are copying entire sg_dma_len
which is not correct i.e more than XILINX_DMA_MAX_TRANS_LEN.
> hw = &segment->hw;
>
> /* Fill in the descriptor */
> @@ -1894,10 +1899,15 @@ static struct dma_async_tx_descriptor
> *xilinx_dma_prep_dma_cyclic(
>
> /*
> * Calculate the maximum number of bytes to transfer,
> - * making sure it is less than the hw limit
> + * making sure it is less than the hw limit and that
> + * the next chunck start address is aligned
> */
> - copy = min_t(size_t, period_len - sg_used,
> - XILINX_DMA_MAX_TRANS_LEN);
> + copy = period_len - sg_used;
> + if (copy > XILINX_DMA_MAX_TRANS_LEN &&
> + chan->xdev->common.copy_align)
> + copy =
> rounddown(XILINX_DMA_MAX_TRANS_LEN,
> + (1 << chan->xdev-
> >common.copy_align));
> +
> hw = &segment->hw;
> xilinx_axidma_buf(chan, hw, buf_addr, sg_used,
> period_len * i);
> --
> 2.17.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v2] mtd: atmel-quadspi: add suspend/resume hooks
From: Claudiu Beznea @ 2018-06-21 13:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5b66cafe-782e-43a9-c221-cf0a1528f382@gmail.com>
Hi Marek,
On 19.06.2018 04:28, Marek Vasut wrote:
> On 06/18/2018 02:00 PM, Claudiu Beznea wrote:
>>
>>
>> On 18.06.2018 12:53, Marek Vasut wrote:
>>> On 06/18/2018 11:49 AM, Boris Brezillon wrote:
>>>> Hi Claudiu,
>>>>
>>>> The subject prefix should be "mtd: spi-nor: atmel-quadspi: ". No need
>>>> to send a new version just for that, I'll fix it when applying the
>>>> patch.
>>>>
>> Hi Boris,
>>
>> Thank you!
>>
>>>> Looks good otherwise. Marek, any objection? If not, can you add your
>>>> Acked-by?
>>>
>>> Will this work if you have ie. ubifs mounted on that QSPI NOR and you
>>> suspect and resume during IO ? I think it would, but just curious if
>>> there could be some problem.
>>
>> Hi Marek,
>>
>> I tested only with read/writes while suspending, simple scripts, but not
>> having ubifs mounted on QSPI NOR. I will double check also with ubifs
>> mounted on QSPI NOR and come back with the results.
>
> Thanks. I think it's gonna be OK, but let's just be sure.
> Make sure to disable 4K sector support when fiddling with UBI/UBIFS on
> QSPI NOR.
I did the following to test this patch with ubifs:
1. disabled CONFIG_MTD_SPI_NOR_USE_4K_SECTORS and build kernel
2. create a ubifs image:
mkfs.ubifs -r /mnt/ubifs-sama5d2-rootfs -m 1 -e 65408 -c 3739 \
-o /mnt/sama5d2-xplained-ubifs.img
3. boot the board and check partitions:
cat /proc/mtd
dev: size erasesize name
mtd0: 00010000 00010000 "at91bootstrap"
mtd1: 00010000 00010000 "bootloader env"
mtd2: 00050000 00010000 "bootloader"
mtd3: 00010000 00010000 "device tree"
mtd4: 00380000 00010000 "kernel"
mtd5: 01c00000 00010000 "rootfs"
mtd6: 00400000 00010000 "spi32766.0"
4. ubiformat /dev/mtd5
5. ubiattach -p /dev/mtd5
6. ubimkvol /dev/ubi0 -N test -s 28910336
7. ubiupdatevol /dev/ubi0_0 /sama5d2-xplained-buildroot-ubifs.img
8. mount -t ubifs ubi0:test /mnt
9. cd /mnt/; ls /mnt/
bin lib media proc sbin usr
dev lib32 mnt root sys var
etc linuxrc opt run tmp
10. Create a file with dd on ubifs partition:
dd if=/dev/urandom of=test.bin bs=1024 count=8K
11. compute md5sum on this file:
md5sum test.bin > test.md5
12. Measure how much will take to copy that file (to be sure the copy
operation is not done before suspending):
date; cp test.bin test-pm.bin; date
Wed Jun 20 13:20:34 UTC 2018
Wed Jun 20 13:21:14 UTC 2018
13. Copy, sync, and switch to suspend-to-mem:
cp test.bin test-pm.bin &
sync &
echo mem > /sys/power/state
14. Check md5sum of test-pm.bin and compare it with md5sum of test.bin:
md5sum test-pm.bin > test-pm.md5
cat test.md5
b5338647572b9665f24c61db98601522 test.bin
cat test-pm.md5
b5338647572b9665f24c61db98601522 test-pm.bin
Please let me know if this is enough!
Thank you,
Claudiu Beznea
^ permalink raw reply
* [PATCH] arm64: dts: rockchip: add 96boards RK3399 Ficus board
From: Heiko Stuebner @ 2018-06-21 13:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180618220804.18468-1-ezequiel@collabora.com>
Hi Ezequiel,
Am Dienstag, 19. Juni 2018, 00:08:04 CEST schrieb Ezequiel Garcia:
> The RK3399 Ficus board is an Enterprise Edition board
> manufactured by Vamrs Ltd., based on the Rockchip RK3399 SoC.
>
> The board exposes a bunch of nice peripherals, including
> SATA, HDMI, MIPI CSI, Ethernet, WiFi, USB 2.0, USB 3.0
> and PCIe.
>
> Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
> ---
> I am not including USB support because I cannot seem
> to make it work.
>
> [ 1.677293] dwc3 fe800000.dwc3: Failed to get clk 'ref': -2
> [ 1.677937] dwc3 fe800000.dwc3: Configuration mismatch. dr_mode forced to host
> [ 1.678602] dwc3 fe800000.dwc3: failed to initialize core
> [ 1.679409] dwc3 fe900000.dwc3: Failed to get clk 'ref': -2
> [ 1.679988] dwc3 fe900000.dwc3: failed to initialize core
>
> I am under the impression it is related to:
>
> commit fe8abf332b8f66868013cfcd6bfe727136a2ab5f
> Author: Masahiro Yamada <yamada.masahiro@socionext.com>
> Date: Wed May 16 11:41:07 2018 +0900
>
> usb: dwc3: support clocks and resets for DWC3 core
>
> Any ideas? Would like to sort out the USB issue before
> merging.
>From what I remember, we had an issue with usb ports not providing
an extcon to the typc-c phys, making the dwc3 fail to probe.
Enric did a nice patch adding support for extcon-less type-c phys in
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ec1fcd7b7e6f50dd6e259ca76c6e41e2346b3afe
So maybe the kernel you were working on was just to old?
> Also, I should probably split the rk3399.dtsi change.
correct :-D
> arch/arm64/boot/dts/rockchip/Makefile | 1 +
> arch/arm64/boot/dts/rockchip/rk3399-ficus.dts | 564 ++++++++++++++++++
> arch/arm64/boot/dts/rockchip/rk3399.dtsi | 9 +
> 3 files changed, 574 insertions(+)
> create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-ficus.dts
Please also add an entry to Documentation/devicetree/bindings/arm/rockchip.txt
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-ficus.dts b/arch/arm64/boot/dts/rockchip/rk3399-ficus.dts
> new file mode 100644
> index 000000000000..17471b4b7a14
> --- /dev/null
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-ficus.dts
> @@ -0,0 +1,564 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2018 Collabora Ltd.
> + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd.
> + */
> +
> +/dts-v1/;
> +#include "rk3399.dtsi"
> +#include "rk3399-opp.dtsi"
> +
> +/ {
> + model = "96boards RK3399 Ficus";
> + compatible = "vamrs,ficus", "rockchip,rk3399";
> +
> + chosen {
> + stdout-path = "serial2:1500000n8";
> + };
> +
> + clkin_gmac: external-gmac-clock {
> + compatible = "fixed-clock";
> + clock-frequency = <125000000>;
> + clock-output-names = "clkin_gmac";
> + #clock-cells = <0>;
> + };
> +
> + usb_typec_vbus: usb-typec-vbus {
> + compatible = "regulator-fixed";
> + regulator-name = "typec-vbus";
> + regulator-min-microvolt = <5000000>;
> + regulator-max-microvolt = <5000000>;
> + gpio = <&gpio1 3 GPIO_ACTIVE_HIGH>;
> + };
> +
> + vcc1v8_s0: vcc1v8-s0 {
> + compatible = "regulator-fixed";
> + regulator-name = "vcc1v8_s0";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-always-on;
> + };
> +
> + vcc_sys: vcc-sys {
> + compatible = "regulator-fixed";
> + regulator-name = "vcc_sys";
> + regulator-min-microvolt = <5000000>;
> + regulator-max-microvolt = <5000000>;
> + regulator-always-on;
> + };
> +
> + vcc_phy: vcc-phy-regulator {
> + compatible = "regulator-fixed";
> + regulator-name = "vcc_phy";
> + regulator-always-on;
> + regulator-boot-on;
> + };
please try to double-check the regulator setup with the schematics.
Like this completely unconnected vcc_phy regulator is normally copy-pasted
from Rockchip's default board-dt and never matches the actual power-tree.
Schematics seem to a at
https://www.96boards.org/documentation/consumer/rock960/hardware-docs/
and there doesn't even seem to be network interface on the board?
Also please use regulator names as defined in the schematics.
This applies to all regulators defined here. I'd really like to see a real
supply-tree with regulators connected to their supplies.
See for example the rk3399-gru boards for an example :-)
And you can also check $DEBUGFS/regulator/regulator_summary
which should form a nice tree structure if everything is correct.
> +&gmac {
> + assigned-clocks = <&cru SCLK_RMII_SRC>;
> + assigned-clock-parents = <&clkin_gmac>;
> + clock_in_out = "input";
> + phy-supply = <&vcc_phy>;
> + phy-mode = "rgmii";
> + pinctrl-names = "default";
> + pinctrl-0 = <&rgmii_pins>;
> + snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
> + snps,reset-active-low;
> + snps,reset-delays-us = <0 10000 50000>;
> + tx_delay = <0x28>;
> + rx_delay = <0x11>;
> + status = "okay";
> +};
Looking at the 96boards page, there is no gmac on the board at all?
> + fusb0: fusb30x at 22 {
node name should be generic ... typec at 22 or something like that
> + vbus-supply = <&usb_typec_vbus>;
> + compatible = "fairchild,fusb302";
> + reg = <0x22>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&fusb0_int>;
> + int-n-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
> + status = "okay";
Please do
- compatible
- reg
- interrupts
[alphabetical]
- status
for properties.
Again applies to everything.
> + };
> +
> +&pinctrl {
> + gmac {
> + rgmii_sleep_pins: rgmii-sleep-pins {
> + rockchip,pins =
> + <3 15 RK_FUNC_GPIO &pcfg_output_low>;
> + };
> + };
again, no gmac that I can see ;-)
Heiko
^ permalink raw reply
* [PATCH v2] ARM64: dts: rockchip: add some pins to rk3399
From: Randy Li @ 2018-06-21 13:32 UTC (permalink / raw)
To: linux-arm-kernel
Those pins would be used by many boards.
Signed-off-by: Randy Li <ayaka@soulik.info>
---
arch/arm64/boot/dts/rockchip/rk3399.dtsi | 87 +++++++++++++++++++++++++++-----
1 file changed, 73 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index e0040b648f43..f32d1a049550 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1936,19 +1936,49 @@
drive-strength = <12>;
};
+ pcfg_pull_none_13ma: pcfg-pull-none-13ma {
+ bias-disable;
+ drive-strength = <13>;
+ };
+
+ pcfg_pull_none_18ma: pcfg-pull-none-18ma {
+ bias-disable;
+ drive-strength = <18>;
+ };
+
+ pcfg_pull_none_20ma: pcfg-pull-none-20ma {
+ bias-disable;
+ drive-strength = <20>;
+ };
+
+ pcfg_pull_up_2ma: pcfg-pull-up-2ma {
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+
pcfg_pull_up_8ma: pcfg-pull-up-8ma {
bias-pull-up;
drive-strength = <8>;
};
+ pcfg_pull_up_18ma: pcfg-pull-up-18ma {
+ bias-pull-up;
+ drive-strength = <18>;
+ };
+
+ pcfg_pull_up_20ma: pcfg-pull-up-20ma {
+ bias-pull-up;
+ drive-strength = <20>;
+ };
+
pcfg_pull_down_4ma: pcfg-pull-down-4ma {
bias-pull-down;
drive-strength = <4>;
};
- pcfg_pull_up_2ma: pcfg-pull-up-2ma {
- bias-pull-up;
- drive-strength = <2>;
+ pcfg_pull_down_8ma: pcfg-pull-down-8ma {
+ bias-pull-down;
+ drive-strength = <8>;
};
pcfg_pull_down_12ma: pcfg-pull-down-12ma {
@@ -1956,9 +1986,22 @@
drive-strength = <12>;
};
- pcfg_pull_none_13ma: pcfg-pull-none-13ma {
- bias-disable;
- drive-strength = <13>;
+ pcfg_pull_down_18ma: pcfg-pull-down-18ma {
+ bias-pull-down;
+ drive-strength = <18>;
+ };
+
+ pcfg_pull_down_20ma: pcfg-pull-down-20ma {
+ bias-pull-down;
+ drive-strength = <20>;
+ };
+
+ pcfg_output_high: pcfg-output-high {
+ output-high;
+ };
+
+ pcfg_output_low: pcfg-output-low {
+ output-low;
};
clock {
@@ -2481,45 +2524,61 @@
pwm0 {
pwm0_pin: pwm0-pin {
rockchip,pins =
- <4 18 RK_FUNC_1 &pcfg_pull_none>;
+ <4 RK_PC2 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ pwm0_pin_pull_down: pwm0-pin-pull-down {
+ rockchip,pins =
+ <4 RK_PC2 RK_FUNC_1 &pcfg_pull_down>;
};
vop0_pwm_pin: vop0-pwm-pin {
rockchip,pins =
- <4 18 RK_FUNC_2 &pcfg_pull_none>;
+ <4 RK_PC2 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ vop1_pwm_pin: vop1-pwm-pin {
+ rockchip,pins =
+ <4 RK_PC2 RK_FUNC_3 &pcfg_pull_none>;
};
+
};
pwm1 {
pwm1_pin: pwm1-pin {
rockchip,pins =
- <4 22 RK_FUNC_1 &pcfg_pull_none>;
+ <4 RK_PC6 RK_FUNC_1 &pcfg_pull_none>;
};
- vop1_pwm_pin: vop1-pwm-pin {
+ pwm1_pin_pull_down: pwm1-pin-pull-down {
rockchip,pins =
- <4 18 RK_FUNC_3 &pcfg_pull_none>;
+ <4 RK_PC6 RK_FUNC_1 &pcfg_pull_down>;
};
};
pwm2 {
pwm2_pin: pwm2-pin {
rockchip,pins =
- <1 19 RK_FUNC_1 &pcfg_pull_none>;
+ <1 RK_PC3 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ pwm2_pin_pull_down: pwm2-pin-pull-down {
+ rockchip,pins =
+ <1 RK_PC3 RK_FUNC_1 &pcfg_pull_down>;
};
};
pwm3a {
pwm3a_pin: pwm3a-pin {
rockchip,pins =
- <0 6 RK_FUNC_1 &pcfg_pull_none>;
+ <0 RK_PA6 RK_FUNC_1 &pcfg_pull_none>;
};
};
pwm3b {
pwm3b_pin: pwm3b-pin {
rockchip,pins =
- <1 14 RK_FUNC_1 &pcfg_pull_none>;
+ <1 RK_PB6 RK_FUNC_1 &pcfg_pull_none>;
};
};
--
2.14.4
^ permalink raw reply related
* [PATCH v2 0/2] Add support for a YUV 10bits pixel format
From: Randy Li @ 2018-06-21 13:42 UTC (permalink / raw)
To: linux-arm-kernel
In the last time, I got some feedback and not a clear guide on what
I should do. So just give more comment on describing this 10bits format.
Whether I should add bpp instead cpp in drm_format_info and update a
numbers of functions is up to you guys.
And I don't any other driver would request 10bits yuv format support,
so I can't add the pixel format they don't use as I did a year ago.
You would ignore those patches.
Randy Li (2):
drm/fourcc: add a 10bits fully packed variant of NV12
drm/rockchip: Support 10 bits yuv format in vop
drivers/gpu/drm/drm_fourcc.c | 1 +
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 27 +++++++++++++++++++++++++--
drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 +
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 2 ++
include/uapi/drm/drm_fourcc.h | 7 +++++++
5 files changed, 36 insertions(+), 2 deletions(-)
--
2.14.4
^ permalink raw reply
* [PATCH v2 1/2] drm/fourcc: add a 10bits fully packed variant of NV12
From: Randy Li @ 2018-06-21 13:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180621134243.9557-1-ayaka@soulik.info>
This pixel format is a fully packed and 10bits variant of NV12.
A luma pixel would take 10bits in memory, without any
filled bits between pixels in a stride. The color gamut
follows the BT.2020 standard.
Signed-off-by: Randy Li <ayaka@soulik.info>
---
drivers/gpu/drm/drm_fourcc.c | 1 +
include/uapi/drm/drm_fourcc.h | 3 +++
2 files changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 5ca6395cd4d3..1f43967c4013 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -173,6 +173,7 @@ const struct drm_format_info *__drm_format_info(u32 format)
{ .format = DRM_FORMAT_UYVY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 },
{ .format = DRM_FORMAT_VYUY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 },
{ .format = DRM_FORMAT_AYUV, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_NV12_10LE40, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2 },
};
unsigned int i;
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index e04613d30a13..8eabf01e966f 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -140,6 +140,9 @@ extern "C" {
#define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */
#define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */
#define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */
+/* A fully packed variant of NV12_10LE32 */
+#define DRM_FORMAT_NV12_10LE40 fourcc_code('R', 'K', '2', '0') /* 2x2 subsampled Cr:Cb plane */
+
/*
* 3 plane YCbCr
--
2.14.4
^ permalink raw reply related
* [PATCH v2 2/2] drm/rockchip: Support 10 bits yuv format in vop
From: Randy Li @ 2018-06-21 13:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180621134243.9557-1-ayaka@soulik.info>
The rockchip use fully packed pixel format variants
for YUV 10bits.
This patch only make the VOP accept this pixel format,
but it doesn't add the converting data path for
the color gamuts that the target display are supported.
Signed-off-by: Randy Li <ayaka@soulik.info>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 27 +++++++++++++++++++++++++--
drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 +
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 2 ++
include/uapi/drm/drm_fourcc.h | 6 +++++-
4 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 2121345a61af..6a54b20501ac 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -232,6 +232,7 @@ static enum vop_data_format vop_convert_format(uint32_t format)
case DRM_FORMAT_BGR565:
return VOP_FMT_RGB565;
case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV12_10LE40:
return VOP_FMT_YUV420SP;
case DRM_FORMAT_NV16:
return VOP_FMT_YUV422SP;
@@ -249,6 +250,17 @@ static bool is_yuv_support(uint32_t format)
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV16:
case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV12_10LE40:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool is_yuv_10bit(uint32_t format)
+{
+ switch (format) {
+ case DRM_FORMAT_NV12_10LE40:
return true;
default:
return false;
@@ -711,6 +723,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
dma_addr_t dma_addr;
uint32_t val;
bool rb_swap;
+ bool is_10_bits = false;
int win_index = VOP_WIN_TO_INDEX(vop_win);
int format;
@@ -728,6 +741,8 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
return;
}
+ is_10_bits = is_yuv_10bit(fb->format->format);
+
obj = rockchip_fb_get_gem_obj(fb, 0);
rk_obj = to_rockchip_obj(obj);
@@ -742,7 +757,11 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
- offset = (src->x1 >> 16) * fb->format->cpp[0];
+ if (is_10_bits)
+ offset = (src->x1 >> 16) * (fb->format->cpp[0] * 5 / 4);
+ else
+ offset = (src->x1 >> 16) * fb->format->cpp[0];
+
offset += (src->y1 >> 16) * fb->pitches[0];
dma_addr = rk_obj->dma_addr + offset + fb->offsets[0];
@@ -753,6 +772,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
VOP_WIN_SET(vop, win, format, format);
VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
+ VOP_WIN_SET(vop, win, fmt_10, is_10_bits);
if (is_yuv_support(fb->format->format)) {
int hsub = drm_format_horz_chroma_subsampling(fb->format->format);
int vsub = drm_format_vert_chroma_subsampling(fb->format->format);
@@ -761,7 +781,10 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
uv_obj = rockchip_fb_get_gem_obj(fb, 1);
rk_uv_obj = to_rockchip_obj(uv_obj);
- offset = (src->x1 >> 16) * bpp / hsub;
+ if (is_10_bits)
+ offset = (src->x1 >> 16) * (bpp * 5 / 4) / hsub;
+ else
+ offset = (src->x1 >> 16) * bpp / hsub;
offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 084acdd0019a..d9ec993f420a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -131,6 +131,7 @@ struct vop_win_phy {
struct vop_reg enable;
struct vop_reg gate;
struct vop_reg format;
+ struct vop_reg fmt_10;
struct vop_reg rb_swap;
struct vop_reg act_info;
struct vop_reg dsp_info;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 08023d3ecb76..5393886ddd95 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -50,6 +50,7 @@ static const uint32_t formats_win_full[] = {
DRM_FORMAT_NV12,
DRM_FORMAT_NV16,
DRM_FORMAT_NV24,
+ DRM_FORMAT_NV12_10LE40,
};
static const uint32_t formats_win_lite[] = {
@@ -215,6 +216,7 @@ static const struct vop_win_phy rk3288_win01_data = {
.nformats = ARRAY_SIZE(formats_win_full),
.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
+ .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 8eabf01e966f..fc4cc0a6c9c0 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -140,7 +140,11 @@ extern "C" {
#define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */
#define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */
#define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */
-/* A fully packed variant of NV12_10LE32 */
+/*
+ * A fully packed variant of NV12_10LE32
+ * Y1 0-9, Y2 10-19, Y3 20-29, Y4 20-39
+ * U1V1: 0-19, U2V2: 20-39
+ */
#define DRM_FORMAT_NV12_10LE40 fourcc_code('R', 'K', '2', '0') /* 2x2 subsampled Cr:Cb plane */
--
2.14.4
^ permalink raw reply related
* [PATCH 2/6] dmaengine: xilinx_dma: fix completion callback is not invoked for each DMA operation
From: Radhey Shyam Pandey @ 2018-06-21 13:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAN8YU5O35du2RpTV78sJMx+MpGdOKf2LCQu8FqO1og6FO-JBOQ@mail.gmail.com>
> -----Original Message-----
> From: Andrea Merello [mailto:andrea.merello at gmail.com]
> Sent: Wednesday, June 20, 2018 7:02 PM
> To: Radhey Shyam Pandey <radheys@xilinx.com>
> Cc: vkoul at kernel.org; dan.j.williams at intel.com; Michal Simek
> <michals@xilinx.com>; Appana Durga Kedareswara Rao
> <appanad@xilinx.com>; dmaengine at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-kernel at vger.kernel.org
> Subject: Re: [PATCH 2/6] dmaengine: xilinx_dma: fix completion callback is not
> invoked for each DMA operation
>
> On Wed, Jun 20, 2018 at 2:36 PM, Radhey Shyam Pandey
> <radheys@xilinx.com> wrote:
> >> -----Original Message-----
> >> From: dmaengine-owner at vger.kernel.org [mailto:dmaengine-
> >> owner at vger.kernel.org] On Behalf Of Andrea Merello
> >> Sent: Wednesday, June 20, 2018 2:07 PM
> >> To: vkoul at kernel.org; dan.j.williams at intel.com; Michal Simek
> >> <michals@xilinx.com>; Appana Durga Kedareswara Rao
> >> <appanad@xilinx.com>; dmaengine at vger.kernel.org
> >> Cc: linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
> >> Andrea Merello <andrea.merello@gmail.com>
> >> Subject: [PATCH 2/6] dmaengine: xilinx_dma: fix completion callback is not
> >> invoked for each DMA operation
> >>
> >> API specification says: "On completion of each DMA operation, the next in
> >> queue is started and a tasklet triggered. The tasklet will then call the
> >> client driver completion callback routine for notification, if set."
> >>
> >> Currently the driver keeps a "desc_pendingcount" counter of the total
> >> descriptor pending, and it uses as IRQ coalesce threshold, as result it
> >> only calls the CBs after ALL pending operations are completed, which is
> >> wrong.
> > I think IRQ coalescing enable/disable should be configurable.
> > Performance related usecases will need this support.
>
> I didn't intend this (only) wrt performances; my concern was mostly
> wrt correctness. If my point of view is wrong then I'll drop this
> patch from the series.
>
If coalescing is enabled driver will know DMA completion when
all packet counts are processed. So I think it's correct implementation.
Making interrupt coalescing configurable will address all usecases.
> (.. I might respin it again in future: I had a patch wrt an old driver
> version that allowed submitting new descriptors to the HW while the
> DMA is running, and in this case disabling coalesce is needed i.e. in
> order to submit a new empty buffer whenever the DMA finishes a
> transfer without waiting the DMA to stop).
>
> BTW, is there any dmaengine API suitable for setting interrupt coalesce?
>
> >>
> >> This patch uses disable IRQ coalesce and checks for the completion flag
> >> for the descriptors (which is further divided in segments).
> >>
> >> Possibly a better optimization could be using proper IRQ coalesce
> >> threshold to get an IRQ after all segments of the descriptors are done.
> >> But we don't do that yet..
> >>
> >> NOTE: for now we do this only for AXI DMA, other DMA flavors are
> >> untested/untouched.
> >> This is loosely based on
> >> commit 65df81a6dc74 ("xilinx_dma: IrqThreshold set incorrectly,
> unreliable.")
> >> in my linux-4.6-zynq tree
> > NOTE description doesn't help much.
> >
> >>
> >> From: Jeremy Trimble [original patch]
> >> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> >> ---
> >> drivers/dma/xilinx/xilinx_dma.c | 39 +++++++++++++++++++++------------
> >> 1 file changed, 25 insertions(+), 14 deletions(-)
> >>
> >> diff --git a/drivers/dma/xilinx/xilinx_dma.c
> b/drivers/dma/xilinx/xilinx_dma.c
> >> index a516e7ffef21..cf12f7147f07 100644
> >> --- a/drivers/dma/xilinx/xilinx_dma.c
> >> +++ b/drivers/dma/xilinx/xilinx_dma.c
> >> @@ -164,6 +164,7 @@
> >> #define XILINX_DMA_CR_COALESCE_SHIFT 16
> >> #define XILINX_DMA_BD_SOP BIT(27)
> >> #define XILINX_DMA_BD_EOP BIT(26)
> >> +#define XILINX_DMA_BD_CMPLT BIT(31)
> >> #define XILINX_DMA_COALESCE_MAX 255
> >> #define XILINX_DMA_NUM_DESCS 255
> >> #define XILINX_DMA_NUM_APP_WORDS 5
> >> @@ -1274,12 +1275,9 @@ static void xilinx_dma_start_transfer(struct
> >> xilinx_dma_chan *chan)
> >>
> >> reg = dma_ctrl_read(chan, XILINX_DMA_REG_DMACR);
> >>
> >> - if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX) {
> >> - reg &= ~XILINX_DMA_CR_COALESCE_MAX;
> >> - reg |= chan->desc_pendingcount <<
> >> - XILINX_DMA_CR_COALESCE_SHIFT;
> >> - dma_ctrl_write(chan, XILINX_DMA_REG_DMACR, reg);
> >> - }
> >> + reg &= ~XILINX_DMA_CR_COALESCE_MAX;
> >> + reg |= 1 << XILINX_DMA_CR_COALESCE_SHIFT;
> >> + dma_ctrl_write(chan, XILINX_DMA_REG_DMACR, reg);
> >>
> >> if (chan->has_sg && !chan->xdev->mcdma)
> >> xilinx_write(chan, XILINX_DMA_REG_CURDESC,
> >> @@ -1378,6 +1376,20 @@ static void
> xilinx_dma_complete_descriptor(struct
> >> xilinx_dma_chan *chan)
> >> return;
> >>
> >> list_for_each_entry_safe(desc, next, &chan->active_list, node) {
> >> + if (chan->xdev->dma_config->dmatype ==
> >> XDMA_TYPE_AXIDMA) {
> >> + /*
> >> + * Check whether the last segment in this descriptor
> >> + * has been completed.
> >> + */
> >> + const struct xilinx_axidma_tx_segment *const tail_seg
> >> =
> >> + list_last_entry(&desc->segments,
> >> + struct
> >> xilinx_axidma_tx_segment,
> >> + node);
> >> +
> >> + /* we've processed all the completed descriptors */
> >> + if (!(tail_seg->hw.status & XILINX_DMA_BD_CMPLT))
> >> + break;
> >> + }
> >> list_del(&desc->node);
> >> if (!desc->cyclic)
> >> dma_cookie_complete(&desc->async_tx);
> >> @@ -1826,14 +1838,13 @@ static struct dma_async_tx_descriptor
> >> *xilinx_dma_prep_slave_sg(
> >> struct xilinx_axidma_tx_segment, node);
> >> desc->async_tx.phys = segment->phys;
> >>
> >> - /* For the last DMA_MEM_TO_DEV transfer, set EOP */
> >> - if (chan->direction == DMA_MEM_TO_DEV) {
> >> - segment->hw.control |= XILINX_DMA_BD_SOP;
> >> - segment = list_last_entry(&desc->segments,
> >> - struct xilinx_axidma_tx_segment,
> >> - node);
> >> - segment->hw.control |= XILINX_DMA_BD_EOP;
> >> - }
> >> + /* For the first transfer, set SOP */
> >> + segment->hw.control |= XILINX_DMA_BD_SOP;
> >> + /* For the last transfer, set EOP */
> >> + segment = list_last_entry(&desc->segments,
> >> + struct xilinx_axidma_tx_segment,
> >> + node);
> >> + segment->hw.control |= XILINX_DMA_BD_EOP;
> >>
> >> return &desc->async_tx;
> >>
> >> --
> >> 2.17.1
> >>
> >> --
> >> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
> >> the body of a message to majordomo at vger.kernel.org
> >> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Dynamic ftrace self test broken on ARM
From: Steven Rostedt @ 2018-06-21 13:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <daf9cea94b0baf23563c575fbab1a4da@agner.ch>
On Thu, 21 Jun 2018 09:25:48 +0200
Stefan Agner <stefan@agner.ch> wrote:
> This aligns nicely with how this has been solved with commit
> 162396309745 ("ftrace, x86: make kernel text writable only for
> conversions") a while ago.
> Reviewed-by: Stefan Agner <stefan@agner.ch>
>
> Compiled and tested here, selftest as well as ftrace at runtime seems to
> work fine.
> Tested-by: Stefan Agner <stefan@agner.ch>
>
> Thanks Steven! Can you send a patch or should I do it?
I'll resend a proper patch. Thanks for looking into it!
-- Steve
^ permalink raw reply
* [PATCH] usb: chipidea: Fix ULPI on imx51
From: Fabio Estevam @ 2018-06-21 14:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAHQ1cqHxq+RM1nNHECY75Cojd_kxu1ERLe6+MhMLUa5kb10r8w@mail.gmail.com>
Hi Andrey,
On Thu, Jun 21, 2018 at 9:47 AM, Andrey Smirnov
<andrew.smirnov@gmail.com> wrote:
> I never assumed it was a regression and that USB worked on RDU1 board
> before, so I never tried to see if this was a regression. I can only
> tell you that it hangs as soon as any PORTSC registers are accessed.
I think we need to investigate this portsc register hang further.
> RDU1 design is based heavily on Babbage board, moreso USB1/ULPI
> portion of it is an exact copy (it does use different GPIO for PHY
> reset, but that's irrelevant), so I am surprised that it breaks in
> your case.
>
> However looking at imx51-babbage.dts, I am suspicious of it's USB1
> setup. There we have usbh1phy node that references <&gpio2 5
> GPIO_ACTIVE_LOW> as reset, but corresponding pinmux, pinctrl_usbh1reg,
> is not being used anywhere. Cold that be that the problem you are
> seeing is due to USB PHY not being properly reset?
Yes, this can be improved, but this is not the cause of the issue .
gpio2 5 is passed as the USB PHY reset:
reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>;
The default IOMUX setting after power on reset is GPIO, so not an issue.
> Yeah, IMHO if you are dropping that flag, you may as well revert the
> whole patch :-). The path that make the kernel hang in my case would
> be taken if that flag is dropped.
Yes, it seems we need to revert the full patch and have a proper fix
in place that works for imx51 RDU, imx53-ppd and imx51 babbage.
The USB host 1 on imx51-babbage has been working since kernel 3.19 :-)
Thanks
^ permalink raw reply
* [PATCH] usb: chipidea: Fix ULPI on imx51
From: Nikita Yushchenko @ 2018-06-21 14:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAHQ1cqHxq+RM1nNHECY75Cojd_kxu1ERLe6+MhMLUa5kb10r8w@mail.gmail.com>
>>> This patches causes a regression on a imx51-babbage running 4.18-rc1:
>>> I get a kernel hang.
>>>
>>> If I revert it on top of 4.18-rc1, then it boots fine and USB host is
>>> functional.
>>>
>>> I understand this patch fixes a kernel hang for you, so which commit
>>> is responsible for the hang you observe?
>>>
>
> I never assumed it was a regression and that USB worked on RDU1 board
> before, so I never tried to see if this was a regression. I can only
> tell you that it hangs as soon as any PORTSC registers are accessed.
Hang at register access usually means that module that owns the register
is not clocked.
^ permalink raw reply
* [PATCH] usb: chipidea: Fix ULPI on imx51
From: Nikita Yushchenko @ 2018-06-21 14:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <0f31d801-528e-54ee-f385-b7aa3eef414f@cogentembedded.com>
21.06.2018 17:12, Nikita Yushchenko wrote:
>>>> This patches causes a regression on a imx51-babbage running 4.18-rc1:
>>>> I get a kernel hang.
>>>>
>>>> If I revert it on top of 4.18-rc1, then it boots fine and USB host is
>>>> functional.
>>>>
>>>> I understand this patch fixes a kernel hang for you, so which commit
>>>> is responsible for the hang you observe?
>>>>
>>
>> I never assumed it was a regression and that USB worked on RDU1 board
>> before, so I never tried to see if this was a regression. I can only
>> tell you that it hangs as soon as any PORTSC registers are accessed.
>
> Hang at register access usually means that module that owns the register
> is not clocked.
On RDU1, call to usb_phy_init() actually calls usb_gen_phy_init() that
does regulator_enable() for &vusb_reg and clk_prepare_enable() for
&clk_26M_usb. I thing some of these two is actually needed to avoid
hang on register access.
^ permalink raw reply
* [RFC PATCH 00/16] KVM: arm64: Initial support for SVE guests
From: Dave Martin @ 2018-06-21 14:57 UTC (permalink / raw)
To: linux-arm-kernel
This series implements basic support for allowing KVM guests to use the
Arm Scalable Vector Extension (SVE).
The patches is based on torvalds/master f5b7769e (Revert "debugfs:
inode: debugfs_create_dir uses mode permission from parent") plus the
patches from [1].
Issues / missing features:
* No way for userspace to determine or control the set of vector
lengths exposed to the guest. This needs to be fixed for
snapshotting/migration of guests to work reliably.
An ioctl needs to be added for this (dropped from this series
because I consider it lower-priority than the core support).
* No documentation update yet (I'd like to get the interfaces
finalised before I put too much effort into writing that...)
* Patch 14 (SVE register ioctl() access core) may be too complicated
in its handling of backwards compatibility for the FPSIMD regs:
It might be simpler to use nvcpu->arch.ctxt.gp_regs.fp_regs.vregs[]
as a bounce buffer rather than trying to redirect uaccess directly
to the appropriate locations in vcpu->sve_state.
I'd be interested in people's comments on this.
* kvmtool/qemu updates are needed to enable creation of SVE-enabled
guests (to be discussed separately).
Brief notes on the patches:
* Patches 1-4 are miscellaneous preliminary cleanups.
* Patch 5 adds new arch vcpu init/teardown hooks due to the lack of
an obvious place to free a vcpu's SVE state buffer. This may want
a rethink, because the allocation part has now ended up in
kvm_reset_vcpu() instead of the new init hook.
* Patches 6-12 implement the core SVE support for guests (of which
patch 8-9 refactor the sysregs code to support conditional hiding
of the SVE-related registers).
* Patches 13-15 implement ioctl() access for the new SVE registers.
* Patch 16 exposes the new functionality to userspace, allowing
SVE-enabled vcpus to be created.
This series is somewhat tested on Arm Juno r0 and the Arm Fast Model
(with/without SVE support). arch/arm builds, but I've not booted
it -- only some trivial refactoring in this series affects arch/arm.
Cheers
---Dave
[1] [PATCH v2 0/4] KVM: arm64: FPSIMD/SVE fixes for 4.17 [sic]
http://lists.infradead.org/pipermail/linux-arm-kernel/2018-June/584281.html
Dave Martin (16):
arm64: fpsimd: Always set TIF_FOREIGN_FPSTATE on task state flush
KVM: arm64: Delete orphaned declaration for __fpsimd_enabled()
KVM: arm64: Refactor kvm_arm_num_regs() for easier maintenance
KVM: arm64: Add missing #include of <linux/bitmap.h> to kvm_host.h
KVM: arm: Add arch init/uninit hooks
arm64/sve: Determine virtualisation-friendly vector lengths
arm64/sve: Enable SVE state tracking for non-task contexts
KVM: arm64: Support dynamically hideable system registers
KVM: arm64: Allow ID registers to by dynamically read-as-zero
KVM: arm64: Add a vcpu flag to control SVE visibility for the guest
KVM: arm64/sve: System register context switch and access support
KVM: arm64/sve: Context switch the SVE registers
KVM: Allow 2048-bit register access via KVM_{GET,SET}_ONE_REG
KVM: arm64/sve: Add SVE support to register access ioctl interface
KVM: arm64: Enumerate SVE register indices for KVM_GET_REG_LIST
KVM: arm64/sve: Report and enable SVE API extensions for userspace
arch/arm/include/asm/kvm_host.h | 4 +-
arch/arm64/include/asm/fpsimd.h | 4 +-
arch/arm64/include/asm/kvm_host.h | 18 ++-
arch/arm64/include/asm/kvm_hyp.h | 1 -
arch/arm64/include/asm/sysreg.h | 3 +
arch/arm64/include/uapi/asm/kvm.h | 11 ++
arch/arm64/kernel/cpufeature.c | 2 +-
arch/arm64/kernel/fpsimd.c | 131 +++++++++++++---
arch/arm64/kernel/signal.c | 5 -
arch/arm64/kvm/fpsimd.c | 7 +-
arch/arm64/kvm/guest.c | 321 +++++++++++++++++++++++++++++++++++---
arch/arm64/kvm/hyp/switch.c | 43 +++--
arch/arm64/kvm/hyp/sysreg-sr.c | 5 +
arch/arm64/kvm/reset.c | 14 ++
arch/arm64/kvm/sys_regs.c | 73 ++++++---
arch/arm64/kvm/sys_regs.h | 22 +++
include/uapi/linux/kvm.h | 1 +
virt/kvm/arm/arm.c | 13 +-
18 files changed, 587 insertions(+), 91 deletions(-)
--
2.1.4
^ permalink raw reply
* [RFC PATCH 01/16] arm64: fpsimd: Always set TIF_FOREIGN_FPSTATE on task state flush
From: Dave Martin @ 2018-06-21 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529593060-542-1-git-send-email-Dave.Martin@arm.com>
This patch updates fpsimd_flush_task_state() to mirror the new
semantics of fpsimd_flush_cpu_state(): both functions now
implicitly set TIF_FOREIGN_FPSTATE to indicate that the task's
FPSIMD state is not loaded into the cpu.
As a side-effect, fpsimd_flush_task_state() now sets
TIF_FOREIGN_FPSTATE even for non-running tasks. In the case of
non-running tasks this is not useful but also harmless, because the
flag is live only while the corresponding task is running. This
function is not called from fast paths, so special-casing this for
the task == current case is not really worth it.
Compiler barriers previously present in restore_sve_fpsimd_context()
are pulled into fpsimd_flush_task_state() so that it can be safely
called with preemption enabled if necessary.
Explicit calls to set TIF_FOREIGN_FPSTATE that accompany
fpsimd_flush_task_state() calls and are now redundant are removed
as appropriate.
fpsimd_flush_task_state() is used to get exclusive access to the
representation of the task's state via task_struct, for the purpose
of replacing the state. Thus, the call to this function should
happen before manipulating fpsimd_state or sve_state etc. in
task_struct. Anomalous cases are reordered appropriately in order
to make the code more consistent, although there should be no
functional difference since these cases are protected by
local_bh_disable() anyway.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
arch/arm64/kernel/fpsimd.c | 25 +++++++++++++++++++------
arch/arm64/kernel/signal.c | 5 -----
2 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 84c68b1..6b1ddae 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -569,7 +569,6 @@ int sve_set_vector_length(struct task_struct *task,
local_bh_disable();
fpsimd_save();
- set_thread_flag(TIF_FOREIGN_FPSTATE);
}
fpsimd_flush_task_state(task);
@@ -835,12 +834,11 @@ asmlinkage void do_sve_acc(unsigned int esr, struct pt_regs *regs)
local_bh_disable();
fpsimd_save();
- fpsimd_to_sve(current);
/* Force ret_to_user to reload the registers: */
fpsimd_flush_task_state(current);
- set_thread_flag(TIF_FOREIGN_FPSTATE);
+ fpsimd_to_sve(current);
if (test_and_set_thread_flag(TIF_SVE))
WARN_ON(1); /* SVE access shouldn't have trapped */
@@ -917,9 +915,9 @@ void fpsimd_flush_thread(void)
local_bh_disable();
+ fpsimd_flush_task_state(current);
memset(¤t->thread.uw.fpsimd_state, 0,
sizeof(current->thread.uw.fpsimd_state));
- fpsimd_flush_task_state(current);
if (system_supports_sve()) {
clear_thread_flag(TIF_SVE);
@@ -956,8 +954,6 @@ void fpsimd_flush_thread(void)
current->thread.sve_vl_onexec = 0;
}
- set_thread_flag(TIF_FOREIGN_FPSTATE);
-
local_bh_enable();
}
@@ -1066,12 +1062,29 @@ void fpsimd_update_current_state(struct user_fpsimd_state const *state)
/*
* Invalidate live CPU copies of task t's FPSIMD state
+ *
+ * This function may be called with preemption enabled. The barrier()
+ * ensures that the assignment to fpsimd_cpu is visible to any
+ * preemption/softirq that could race with set_tsk_thread_flag(), so
+ * that TIF_FOREIGN_FPSTATE cannot be spuriously re-cleared.
+ *
+ * The final barrier ensures that TIF_FOREIGN_FPSTATE is seen set by any
+ * subsequent code.
*/
void fpsimd_flush_task_state(struct task_struct *t)
{
t->thread.fpsimd_cpu = NR_CPUS;
+
+ barrier();
+ set_tsk_thread_flag(t, TIF_FOREIGN_FPSTATE);
+
+ barrier();
}
+/*
+ * Invalidate any task's FPSIMD state that is present on this cpu.
+ * This function must be called with softirqs disabled.
+ */
void fpsimd_flush_cpu_state(void)
{
__this_cpu_write(fpsimd_last_state.st, NULL);
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 511af13..7636965 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -296,11 +296,6 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
*/
fpsimd_flush_task_state(current);
- barrier();
- /* From now, fpsimd_thread_switch() won't clear TIF_FOREIGN_FPSTATE */
-
- set_thread_flag(TIF_FOREIGN_FPSTATE);
- barrier();
/* From now, fpsimd_thread_switch() won't touch thread.sve_state */
sve_alloc(current);
--
2.1.4
^ permalink raw reply related
* [RFC PATCH 02/16] KVM: arm64: Delete orphaned declaration for __fpsimd_enabled()
From: Dave Martin @ 2018-06-21 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529593060-542-1-git-send-email-Dave.Martin@arm.com>
__fpsimd_enabled() no longer exists, but a dangling declaration has
survived in kvm_hyp.h.
This patch gets rid of it.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
arch/arm64/include/asm/kvm_hyp.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 384c343..9cbbd03 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -147,7 +147,6 @@ void __debug_switch_to_host(struct kvm_vcpu *vcpu);
void __fpsimd_save_state(struct user_fpsimd_state *fp_regs);
void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs);
-bool __fpsimd_enabled(void);
void activate_traps_vhe_load(struct kvm_vcpu *vcpu);
void deactivate_traps_vhe_put(void);
--
2.1.4
^ permalink raw reply related
* [RFC PATCH 03/16] KVM: arm64: Refactor kvm_arm_num_regs() for easier maintenance
From: Dave Martin @ 2018-06-21 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529593060-542-1-git-send-email-Dave.Martin@arm.com>
kvm_arm_num_regs() adds together various partial register counts in
a freeform sum expression, which makes it harder than necessary to
read diffs that add, modify or remove a single term in the sum
(which is expected to the common case under maintenance).
This patch refactors the code to add the term one per line, for
maximum readability.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
arch/arm64/kvm/guest.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 56a0260..4a9d77c 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -205,8 +205,14 @@ static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
*/
unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu)
{
- return num_core_regs() + kvm_arm_num_sys_reg_descs(vcpu)
- + kvm_arm_get_fw_num_regs(vcpu) + NUM_TIMER_REGS;
+ unsigned long res = 0;
+
+ res += num_core_regs();
+ res += kvm_arm_num_sys_reg_descs(vcpu);
+ res += kvm_arm_get_fw_num_regs(vcpu);
+ res += NUM_TIMER_REGS;
+
+ return res;
}
/**
--
2.1.4
^ permalink raw reply related
* [RFC PATCH 04/16] KVM: arm64: Add missing #include of <linux/bitmap.h> to kvm_host.h
From: Dave Martin @ 2018-06-21 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529593060-542-1-git-send-email-Dave.Martin@arm.com>
kvm_host.h uses DECLARE_BITMAP() to declare the features member of
struct vcpu_arch, but the corresponding #include for this is
missing.
This patch adds a suitable #include for <linux/bitmap.h>. Although
the header builds without it today, this should help to avoid
future surprises.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
arch/arm64/include/asm/kvm_host.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index fe8777b..92d6e88 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -22,6 +22,7 @@
#ifndef __ARM64_KVM_HOST_H__
#define __ARM64_KVM_HOST_H__
+#include <linux/bitmap.h>
#include <linux/types.h>
#include <linux/kvm_types.h>
#include <asm/cpufeature.h>
--
2.1.4
^ permalink raw reply related
* [RFC PATCH 05/16] KVM: arm: Add arch init/uninit hooks
From: Dave Martin @ 2018-06-21 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529593060-542-1-git-send-email-Dave.Martin@arm.com>
In preparation for adding support for SVE in guests on arm64, hooks
for allocating and freeing additional per-vcpu memory are needed.
kvm_arch_vcpu_setup() could be used for allocation, but this
function is not clearly balanced by un "unsetup" function, making
it unclear where memory allocated in this function should be freed.
To keep things simple, this patch defines backend hooks
kvm_arm_arch_vcpu_{,un}unint(), and plumbs them in appropriately.
The exusting kvm_arch_vcpu_init() function now calls
kvm_arm_arch_vcpu_init(), while an explicit kvm_arch_vcpu_uninit()
is added which current does nothing except to call
kvm_arm_arch_vcpu_uninit().
The backend functions are currently defined to do nothing.
No functional change.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
arch/arm/include/asm/kvm_host.h | 4 +++-
arch/arm64/include/asm/kvm_host.h | 4 +++-
virt/kvm/arm/arm.c | 13 ++++++++++++-
3 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 1f1fe410..9b902b8 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -284,10 +284,12 @@ struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
static inline bool kvm_arch_check_sve_has_vhe(void) { return true; }
static inline void kvm_arch_hardware_unsetup(void) {}
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
-static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
static inline void kvm_arch_vcpu_block_finish(struct kvm_vcpu *vcpu) {}
+static inline int kvm_arm_arch_vcpu_init(struct kvm_vcpu *vcpu) { return 0; }
+static inline void kvm_arm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
+
static inline void kvm_arm_init_debug(void) {}
static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 92d6e88..9671ddd 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -425,10 +425,12 @@ static inline bool kvm_arch_check_sve_has_vhe(void)
static inline void kvm_arch_hardware_unsetup(void) {}
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
-static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
static inline void kvm_arch_vcpu_block_finish(struct kvm_vcpu *vcpu) {}
+static inline int kvm_arm_arch_vcpu_init(struct kvm_vcpu *vcpu) { return 0; }
+static inline void kvm_arm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
+
void kvm_arm_init_debug(void);
void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 04e554c..66f15cc 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -345,6 +345,8 @@ void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu)
int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
{
+ int ret;
+
/* Force users to call KVM_ARM_VCPU_INIT */
vcpu->arch.target = -1;
bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
@@ -354,7 +356,16 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
kvm_arm_reset_debug_ptr(vcpu);
- return kvm_vgic_vcpu_init(vcpu);
+ ret = kvm_vgic_vcpu_init(vcpu);
+ if (ret)
+ return ret;
+
+ return kvm_arm_arch_vcpu_init(vcpu);
+}
+
+void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
+{
+ kvm_arm_arch_vcpu_uninit(vcpu);
}
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
--
2.1.4
^ permalink raw reply related
* [RFC PATCH 06/16] arm64/sve: Determine virtualisation-friendly vector lengths
From: Dave Martin @ 2018-06-21 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529593060-542-1-git-send-email-Dave.Martin@arm.com>
Software at EL1 is permitted to assume that when programming
ZCR_EL1.LEN, the effective vector length is nonetheless a vector
length supported by the CPU. Thus, software may rely on the
effective vector length being different from that programmed via
ZCR_EL1.LEN in some situations.
However, KVM does not tightly bind vcpus to individual underlying
physical CPUs. As a result, vcpus can migrate from one CPU to
another. This means that in order to preserve the guarantee
described in the previous paragraph, the set of supported vector
lengths must appear to be the same for the vcpu at all times,
irrespective of which physical CPU the vcpu is currently running
on.
The Arm SVE architecture allows the maximum vector length visible
to EL1 to be restricted by programming ZCR_EL2.LEN. This provides
a means to hide from guests any vector lengths that are not
supported by every physical CPU in the system. However, there is
no way to hide a particular vector length while some greater vector
length is exposed to EL1.
This patch determines the maximum vector length
(sve_max_virtualisable_vl) for which the set of supported vector
lengths not exceeding it is identical for all CPUs. When KVM is
available, the set of vector lengths supported by each late
secondary CPU is verified to be consistent with those of the early
CPUs, in order to ensure that the value chosen for
sve_max_virtualisable_vl remains globally valid, and ensure that
all created vcpus continue to behave correctly.
sve_secondary_vq_map is used as scratch space for these
computations, rendering its name misleading. This patch renames
this bitmap to sve_tmp_vq_map in order to make its purpose clearer.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
arch/arm64/include/asm/fpsimd.h | 1 +
arch/arm64/kernel/cpufeature.c | 2 +-
arch/arm64/kernel/fpsimd.c | 86 ++++++++++++++++++++++++++++++++++-------
3 files changed, 75 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index fa92747..3ad4607 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -85,6 +85,7 @@ extern void sve_kernel_enable(const struct arm64_cpu_capabilities *__unused);
extern u64 read_zcr_features(void);
extern int __ro_after_init sve_max_vl;
+extern int __ro_after_init sve_max_virtualisable_vl;
#ifdef CONFIG_ARM64_SVE
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index d2856b1..f493a2f 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1511,7 +1511,7 @@ static void verify_sve_features(void)
unsigned int len = zcr & ZCR_ELx_LEN_MASK;
if (len < safe_len || sve_verify_vq_map()) {
- pr_crit("CPU%d: SVE: required vector length(s) missing\n",
+ pr_crit("CPU%d: SVE: vector length support mismatch\n",
smp_processor_id());
cpu_die_early();
}
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 6b1ddae..390afb4 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -18,6 +18,7 @@
*/
#include <linux/bitmap.h>
+#include <linux/bitops.h>
#include <linux/bottom_half.h>
#include <linux/bug.h>
#include <linux/cache.h>
@@ -48,6 +49,7 @@
#include <asm/sigcontext.h>
#include <asm/sysreg.h>
#include <asm/traps.h>
+#include <asm/virt.h>
#define FPEXC_IOF (1 << 0)
#define FPEXC_DZF (1 << 1)
@@ -130,14 +132,18 @@ static int sve_default_vl = -1;
/* Maximum supported vector length across all CPUs (initially poisoned) */
int __ro_after_init sve_max_vl = SVE_VL_MIN;
+int __ro_after_init sve_max_virtualisable_vl = SVE_VL_MIN;
/* Set of available vector lengths, as vq_to_bit(vq): */
static __ro_after_init DECLARE_BITMAP(sve_vq_map, SVE_VQ_MAX);
+/* Set of vector lengths present on@least one cpu: */
+static __ro_after_init DECLARE_BITMAP(sve_vq_partial_map, SVE_VQ_MAX);
static void __percpu *efi_sve_state;
#else /* ! CONFIG_ARM64_SVE */
/* Dummy declaration for code that will be optimised out: */
extern __ro_after_init DECLARE_BITMAP(sve_vq_map, SVE_VQ_MAX);
+extern __ro_after_init DECLARE_BITMAP(sve_vq_partial_map, SVE_VQ_MAX);
extern void __percpu *efi_sve_state;
#endif /* ! CONFIG_ARM64_SVE */
@@ -642,11 +648,8 @@ int sve_get_current_vl(void)
return sve_prctl_status(0);
}
-/*
- * Bitmap for temporary storage of the per-CPU set of supported vector lengths
- * during secondary boot.
- */
-static DECLARE_BITMAP(sve_secondary_vq_map, SVE_VQ_MAX);
+/* Bitmaps for temporary storage during manipulation of vector length sets */
+static DECLARE_BITMAP(sve_tmp_vq_map, SVE_VQ_MAX);
static void sve_probe_vqs(DECLARE_BITMAP(map, SVE_VQ_MAX))
{
@@ -669,6 +672,7 @@ static void sve_probe_vqs(DECLARE_BITMAP(map, SVE_VQ_MAX))
void __init sve_init_vq_map(void)
{
sve_probe_vqs(sve_vq_map);
+ bitmap_copy(sve_vq_partial_map, sve_vq_map, SVE_VQ_MAX);
}
/*
@@ -677,24 +681,60 @@ void __init sve_init_vq_map(void)
*/
void sve_update_vq_map(void)
{
- sve_probe_vqs(sve_secondary_vq_map);
- bitmap_and(sve_vq_map, sve_vq_map, sve_secondary_vq_map, SVE_VQ_MAX);
+ sve_probe_vqs(sve_tmp_vq_map);
+ bitmap_and(sve_vq_map, sve_vq_map, sve_tmp_vq_map,
+ SVE_VQ_MAX);
+ bitmap_or(sve_vq_partial_map, sve_vq_partial_map, sve_tmp_vq_map,
+ SVE_VQ_MAX);
}
/* Check whether the current CPU supports all VQs in the committed set */
int sve_verify_vq_map(void)
{
- int ret = 0;
+ int ret = -EINVAL;
+ unsigned long b;
- sve_probe_vqs(sve_secondary_vq_map);
- bitmap_andnot(sve_secondary_vq_map, sve_vq_map, sve_secondary_vq_map,
- SVE_VQ_MAX);
- if (!bitmap_empty(sve_secondary_vq_map, SVE_VQ_MAX)) {
+ sve_probe_vqs(sve_tmp_vq_map);
+
+ bitmap_complement(sve_tmp_vq_map, sve_tmp_vq_map, SVE_VQ_MAX);
+ if (bitmap_intersects(sve_tmp_vq_map, sve_vq_map, SVE_VQ_MAX)) {
pr_warn("SVE: cpu%d: Required vector length(s) missing\n",
smp_processor_id());
- ret = -EINVAL;
+ goto error;
}
+ if (!IS_ENABLED(CONFIG_KVM) || !is_hyp_mode_available())
+ goto ok;
+
+ /*
+ * For KVM, it is necessary to ensure that this CPU doesn't
+ * support any vector length that guests may have probed as
+ * unsupported.
+ */
+
+ /* Recover the set of supported VQs: */
+ bitmap_complement(sve_tmp_vq_map, sve_tmp_vq_map, SVE_VQ_MAX);
+ /* Find VQs supported that are not globally supported: */
+ bitmap_andnot(sve_tmp_vq_map, sve_tmp_vq_map, sve_vq_map, SVE_VQ_MAX);
+
+ /* Find the lowest such VQ, if any: */
+ b = find_last_bit(sve_tmp_vq_map, SVE_VQ_MAX);
+ if (b >= SVE_VQ_MAX)
+ goto ok; /* no mismatches */
+
+ /*
+ * Mismatches above sve_max_virtualisable_vl are fine, since
+ * no guest is allowed to configure ZCR_EL2.LEN to exceed this:
+ */
+ if (sve_vl_from_vq(bit_to_vq(b)) <= sve_max_virtualisable_vl) {
+ pr_warn("SVE: cpu%d: Unsupported vector length(s) present\n",
+ smp_processor_id());
+ goto error;
+ }
+
+ok:
+ ret = 0;
+error:
return ret;
}
@@ -762,6 +802,7 @@ u64 read_zcr_features(void)
void __init sve_setup(void)
{
u64 zcr;
+ unsigned long b;
if (!system_supports_sve())
return;
@@ -790,10 +831,29 @@ void __init sve_setup(void)
*/
sve_default_vl = find_supported_vector_length(64);
+ bitmap_andnot(sve_tmp_vq_map, sve_vq_partial_map, sve_vq_map,
+ SVE_VQ_MAX);
+
+ b = find_last_bit(sve_tmp_vq_map, SVE_VQ_MAX);
+ if (b >= SVE_VQ_MAX)
+ /* No non-virtualisable VLs found */
+ sve_max_virtualisable_vl = SVE_VQ_MAX;
+ else if (WARN_ON(b == SVE_VQ_MAX - 1))
+ /* No virtualisable VLs? This is architecturally forbidden. */
+ sve_max_virtualisable_vl = SVE_VQ_MIN;
+ else /* b + 1 < SVE_VQ_MAX */
+ sve_max_virtualisable_vl = sve_vl_from_vq(bit_to_vq(b + 1));
+
+ if (sve_max_virtualisable_vl > sve_max_vl)
+ sve_max_virtualisable_vl = sve_max_vl;
+
pr_info("SVE: maximum available vector length %u bytes per vector\n",
sve_max_vl);
pr_info("SVE: default vector length %u bytes per vector\n",
sve_default_vl);
+ if (sve_max_virtualisable_vl < sve_max_vl)
+ pr_info("SVE: vector lengths greater than %u bytes not virtualisable\n",
+ sve_max_virtualisable_vl);
sve_efi_setup();
}
--
2.1.4
^ permalink raw reply related
* [RFC PATCH 07/16] arm64/sve: Enable SVE state tracking for non-task contexts
From: Dave Martin @ 2018-06-21 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529593060-542-1-git-send-email-Dave.Martin@arm.com>
The current FPSIMD/SVE context handling support for non-task (i.e.,
KVM vcpu) contexts does not take SVE into account. This means that
only task contexts can safely use SVE at present.
In preparation for enabling KVM guests to use SVE, it is necessary
to keep track of SVE state for non-task contexts too.
This patch adds the necessary support, removing assumptions from
the context switch code about the location of the SVE context
storage.
When binding a vcpu context, its vector length is arbitrarily
specified as sve_max_vl for now. In any case, because TIF_SVE is
presently cleared at vcpu context bind time, the specified vector
length will not be used for anything yet. In later patches TIF_SVE
will be set here as appropriate, and the appropriate maximum vector
length for the vcpu will be passed when binding.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
arch/arm64/include/asm/fpsimd.h | 3 ++-
arch/arm64/kernel/fpsimd.c | 20 +++++++++++++++-----
arch/arm64/kvm/fpsimd.c | 4 +++-
3 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 3ad4607..d575e59 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -54,7 +54,8 @@ extern void fpsimd_restore_current_state(void);
extern void fpsimd_update_current_state(struct user_fpsimd_state const *state);
extern void fpsimd_bind_task_to_cpu(void);
-extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state);
+extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state,
+ void *sve_state, unsigned int sve_vl);
extern void fpsimd_flush_task_state(struct task_struct *target);
extern void fpsimd_flush_cpu_state(void);
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 390afb4..8afc518 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -121,6 +121,8 @@
*/
struct fpsimd_last_state_struct {
struct user_fpsimd_state *st;
+ void *sve_state;
+ unsigned int sve_vl;
};
static DEFINE_PER_CPU(struct fpsimd_last_state_struct, fpsimd_last_state);
@@ -260,14 +262,15 @@ static void task_fpsimd_load(void)
*/
void fpsimd_save(void)
{
- struct user_fpsimd_state *st = __this_cpu_read(fpsimd_last_state.st);
+ struct fpsimd_last_state_struct const *last =
+ this_cpu_ptr(&fpsimd_last_state);
/* set by fpsimd_bind_task_to_cpu() or fpsimd_bind_state_to_cpu() */
WARN_ON(!in_softirq() && !irqs_disabled());
if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
if (system_supports_sve() && test_thread_flag(TIF_SVE)) {
- if (WARN_ON(sve_get_vl() != current->thread.sve_vl)) {
+ if (WARN_ON(sve_get_vl() != last->sve_vl)) {
/*
* Can't save the user regs, so current would
* re-enter user with corrupt state.
@@ -277,9 +280,11 @@ void fpsimd_save(void)
return;
}
- sve_save_state(sve_pffr(¤t->thread), &st->fpsr);
+ sve_save_state((char *)last->sve_state +
+ sve_ffr_offset(last->sve_vl),
+ &last->st->fpsr);
} else
- fpsimd_save_state(st);
+ fpsimd_save_state(last->st);
}
}
@@ -1053,6 +1058,8 @@ void fpsimd_bind_task_to_cpu(void)
this_cpu_ptr(&fpsimd_last_state);
last->st = ¤t->thread.uw.fpsimd_state;
+ last->sve_state = current->thread.sve_state;
+ last->sve_vl = current->thread.sve_vl;
current->thread.fpsimd_cpu = smp_processor_id();
if (system_supports_sve()) {
@@ -1066,7 +1073,8 @@ void fpsimd_bind_task_to_cpu(void)
}
}
-void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st)
+void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
+ unsigned int sve_vl)
{
struct fpsimd_last_state_struct *last =
this_cpu_ptr(&fpsimd_last_state);
@@ -1074,6 +1082,8 @@ void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st)
WARN_ON(!in_softirq() && !irqs_disabled());
last->st = st;
+ last->sve_state = sve_state;
+ last->sve_vl = sve_vl;
}
/*
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 4aaf78e..872008c 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -85,7 +85,9 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
WARN_ON_ONCE(!irqs_disabled());
if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) {
- fpsimd_bind_state_to_cpu(&vcpu->arch.ctxt.gp_regs.fp_regs);
+ fpsimd_bind_state_to_cpu(&vcpu->arch.ctxt.gp_regs.fp_regs,
+ NULL, sve_max_vl);
+
clear_thread_flag(TIF_FOREIGN_FPSTATE);
clear_thread_flag(TIF_SVE);
}
--
2.1.4
^ 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