[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20230125190805.l7yo5lls7gfhoo4b@synopsys.com>
Date: Wed, 25 Jan 2023 19:08:10 +0000
From: Thinh Nguyen <Thinh.Nguyen@...opsys.com>
To: Krishna Kurapati PSSNV <quic_kriskura@...cinc.com>
CC: Thinh Nguyen <Thinh.Nguyen@...opsys.com>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Philipp Zabel <p.zabel@...gutronix.de>,
Andy Gross <agross@...nel.org>,
Bjorn Andersson <andersson@...nel.org>,
Konrad Dybcio <konrad.dybcio@...aro.org>,
Rob Herring <robh+dt@...nel.org>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@...aro.org>,
Felipe Balbi <balbi@...nel.org>,
"linux-usb@...r.kernel.org" <linux-usb@...r.kernel.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
"linux-arm-msm@...r.kernel.org" <linux-arm-msm@...r.kernel.org>,
"devicetree@...r.kernel.org" <devicetree@...r.kernel.org>,
Pavan Kondeti <quic_pkondeti@...cinc.com>,
Pratham Pratap <quic_ppratap@...cinc.com>,
Harsh Agarwal <quic_harshq@...cinc.com>,
Jack Pham <quic_jackp@...cinc.com>,
Wesley Cheng <quic_wcheng@...cinc.com>,
"quic_shazhuss@...cinc.com" <quic_shazhuss@...cinc.com>
Subject: Re: [RFC v4 2/5] usb: dwc3: core: Refactor PHY logic to support
Multiport Controller
On Wed, Jan 25, 2023, Krishna Kurapati PSSNV wrote:
>
>
> On 1/21/2023 4:14 AM, Thinh Nguyen wrote:
> >
> > This becomes rather more complicated because the user can skip certain
> > port in the DT. We have access to the host registers. Can we just
> > temporarily map and access HCSPARAMS1 to get the MAXPORTS and each port
> > capability before handing control over to the xHCI driver. We would be
> > able to get the num_ports and num_ss_ports then.
> >
> > Similarly, the xhci driver doesn't care whether the user skips certain
> > port in the DT, it only checks and operates based on the capability
> > registers.
> >
> > If we have the exact num_ports and num_ss_ports, we can be sure the
> > setting to GUSB3PIPECTLn and GUSB2PHYCFGn are valid.
> >
>
> Hi Thinh,
>
> Thanks for the suggestion. Is the following diff / implementation good
> enough ? I Wanted to get it clarified from upstream as I am using
> *ioremap/iounmap* directly instead of *devm_* API's
>
> I tested it and it works fine on SA8295P. Will do some further testing on
> other devices as well.
>
>
> +static int dwc3_read_port_info(struct dwc3 *dwc, struct resource *res)
> +{
> + void __iomem *regs;
> + struct resource dwc_res;
> + unsigned int hw_mode;
> + u32 offset;
> + u32 temp;
> + u8 major_revision;
> + u8 minor_revision;
> +
> + /*
> + * Request memory region including xHCI regs,
> + * since it is needed to get port info
> + */
> + dwc_res = *res;
> + dwc_res.start += 0;
> +
> + regs = ioremap(dwc_res.start, resource_size(&dwc_res));
> + if (IS_ERR(regs)) {
> + return PTR_ERR(regs);
> + }
We don't need to ioremap the whole region. Just do it for
the xhci_resources[0]
> +
> + /*
> + * If the controller is not host-only, then it must be a
> + * single port controller.
> + */
> + temp = readl(regs + DWC3_GHWPARAMS0);
> + hw_mode = DWC3_GHWPARAMS0_MODE(temp);
> + if (hw_mode != DWC3_GHWPARAMS0_MODE_HOST) {
> + dwc->num_ports = 1;
> + dwc->num_ss_ports = 1;
> + return 0;
> + }
This check should be done before we get into this function.
> +
> + offset = xhci_find_next_ext_cap(regs, 0,
> + XHCI_EXT_CAPS_PROTOCOL);
> + while (offset) {
> + temp = readl(regs + offset);
> + major_revision = XHCI_EXT_PORT_MAJOR(temp);;
> + minor_revision = XHCI_EXT_PORT_MINOR(temp);
We probably don't need minor revision.
> +
> + temp = readl(regs + offset + 0x08);
> + if (major_revision == 0x03) {
> + dwc->num_ss_ports += XHCI_EXT_PORT_COUNT(temp);
> + } else if (major_revision <= 0x02) {
> + dwc->num_ports += XHCI_EXT_PORT_COUNT(temp);
> + } else {
> + dev_err(dwc->dev, "revision gone wrong\n");
> + return -EINVAL;
> + }
> +
> + offset = xhci_find_next_ext_cap(regs, offset,
> + XHCI_EXT_CAPS_PROTOCOL);
> + }
> +
> + temp = readl(regs + DWC3_XHCI_HCSPARAMS1_OFFSET);
> + if (HCS_MAX_PORTS(temp) != (dwc->num_ss_ports + dwc->num_ports)) {
> + dev_err(dwc->dev, "inconsistency in port info\n");
> + return -EINVAL;
> + }
> +
> + dev_info(dwc->dev, "num_ports: %d, num_ss_ports: %d\n",
> dwc->num_ports, dwc->num_ss_ports);
> + iounmap(regs);
Make sure to iounmap on all the early return/error cases.
> + return 0;
> +}
> +
> static int dwc3_probe(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
> @@ -1912,6 +1964,10 @@ static int dwc3_probe(struct platform_device *pdev)
> dwc->xhci_resources[0].flags = res->flags;
> dwc->xhci_resources[0].name = res->name;
>
> + ret = dwc3_read_port_info(dwc, res);
This should be called after some initializations to make sure some
clocks are enabled. Otherwise some devices may not able to access the
registers. Preferably after dwc3_cache_hwparams() but before
dwc3_core_init().
> + if (ret)
> + return ret;
> +
> /*
> * Request memory region but exclude xHCI regs,
> * since it will be requested by the xhci-plat driver.
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index 2f82eda9d44f..8535425b81d4 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -38,6 +38,9 @@
> /* Numer of ports supported by a multiport controller */
> #define MAX_PORTS_SUPPORTED 4
>
> +/* XHCI Reg constants */
> +#define DWC3_XHCI_HCSPARAMS1_OFFSET 0x04
Change to DWC3_XHCI_HCSPARAMS1
> +
> /* Global constants */
> #define DWC3_PULL_UP_TIMEOUT 500 /* ms */
> #define DWC3_BOUNCE_SIZE 1024 /* size of a superspeed bulk */
>
>
>
> Please let me know if this would be acceptable.
>
It looks fine to me. Please review the comments and remmove debug
prints and any other cleanup for a proper patch.
Thanks,
Thinh
Powered by blists - more mailing lists