lkml.org 
[lkml]   [2014]   [Jul]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH v2 1/3] usb: dwc3: add ST dwc3 glue layer to manage dwc3 HC
    Hi,

    On Tue, Jul 22, 2014 at 10:18:00AM +0100, Peter Griffin wrote:
    > > > +static inline u32 st_dwc3_readl(void __iomem *base, u32 offset)
    > > > +{
    > > > + return readl_relaxed(base + offset);
    > > > +}
    > > > +
    > > > +static inline void st_dwc3_writel(void __iomem *base, u32 offset, u32 value)
    > > > +{
    > > > + writel_relaxed(value, base + offset);
    > > > +}
    > >
    > > Why are these being abstracted?
    > >
    > > Just use {read,write}l_relaxed() directly.
    >
    > Ok, unabstracted in v3

    no, no... all other glues add their own local helpers for register
    access. This is good for tracing, it's very easy to add a tracepoint to
    this sort of function and get very low overhead tracing of every
    register access.

    > > > + if (dwc3_data->drd_device_conf)
    > > > + val |= USB_SET_PORT_DEVICE;
    > > > + else
    > > > + val &= USB_HOST_DEFAULT_MASK;
    > > > +
    > > > + return regmap_write(dwc3_data->regmap, dwc3_data->syscfg_reg_off, val);
    > > > +}
    > > > +
    > > > +/**
    > > > + * st_dwc3_init: init the controller via glue logic
    > > > + * @dwc3_data: driver private structure
    > > > + */
    > > > +static void st_dwc3_init(struct st_dwc3 *dwc3_data)
    > > > +{
    > > > + u32 reg = st_dwc3_readl(dwc3_data->glue_base, USB2_CLKRST_CTRL);
    > > > +
    > > > + reg |= aux_clk_en(1) | ext_cfg_reset_n(1) | xhci_revision(1);
    > > > + reg &= ~sw_pipew_reset_n(1);
    > >
    > > 1? Better to add defines for these magic numbers. What is 1 anyway?
    >
    > They are just bit setting macros, I've converted them over to use BIT macro now,
    > so it no longer takes a parameter.

    the macros are better, but make them upper case as everybody else.

    > > > + st_dwc3_writel(dwc3_data->glue_base, USB2_CLKRST_CTRL, reg);
    > > > +
    > > > + reg = st_dwc3_readl(dwc3_data->glue_base, USB2_VBUS_MNGMNT_SEL1);
    > > > + reg |= SEL_OVERRIDE_VBUSVALID(1) | SEL_OVERRIDE_POWERPRESENT(1) |
    > > > + SEL_OVERRIDE_BVALID(1);
    > > > + st_dwc3_writel(dwc3_data->glue_base, USB2_VBUS_MNGMNT_SEL1, reg);
    > > > + udelay(100);
    > >
    > > Why 100?
    >
    > I've asked ST how this value was derirved and why. It came from validation.
    > The docs don't mention that it is necessary, and removing it
    > seems to have no ill effects. So I've removed this udelay in v3.

    make sure to test with many, many iterations just to make sure.

    > > > + reg = st_dwc3_readl(dwc3_data->glue_base, USB2_CLKRST_CTRL);
    > > > + reg |= sw_pipew_reset_n(1);
    > > > + st_dwc3_writel(dwc3_data->glue_base, USB2_CLKRST_CTRL, reg);
    > > > +}
    > > > +
    > > > +static void st_dwc3_dt_get_pdata(struct platform_device *pdev,
    > > > + struct st_dwc3 *dwc3_data)
    > > > +{
    > > > + struct device_node *np = pdev->dev.of_node;
    > > > +
    > > > + dwc3_data->drd_device_conf =
    > > > + of_property_read_bool(np, "st,dwc3-drd-device");
    > >
    > > This requires a DT Ack.
    >
    > Ok. Do the DT folks have any comment on this?

    look at the child's dr-mode property instead of adding your own.

    > > > + dwc3_data->glue_base = devm_request_and_ioremap(dev, res);

    use devm_ioremap_resource()

    > > > + regmap = syscon_regmap_lookup_by_phandle(node, "st,syscfg");
    > > > + if (IS_ERR(regmap))
    > > > + return PTR_ERR(regmap);
    > > > +
    > > > + dwc3 = platform_device_alloc("st-dwc3", PLATFORM_DEVID_AUTO);
    > > > + if (!dwc3) {
    > > > + dev_err(&pdev->dev, "couldn't allocate dwc3 device\n");
    > > > + return -ENOMEM;
    > > > + }
    > >
    > > I'm confused. What is this doing? Isn't this the DWC3 driver, which
    > > already had a platform device structure associated to it? Perhaps a
    > > small ASCII diagram describing the layers might be useful.
    >
    > Your right, this was wrong. It was some legacy code which is
    > unnecessary and I've removed this in v3.

    if you're going for DT, why don't you create the parent and the child
    from DT as omap/exynos/qcom are doing ?

    > > > + dma_set_coherent_mask(&dwc3->dev, dev->coherent_dma_mask);
    > > > +
    > > > + dwc3->dev.parent = &pdev->dev;
    > > > + dwc3->dev.dma_mask = pdev->dev.dma_mask;
    > > > + dwc3->dev.dma_parms = pdev->dev.dma_parms;

    stick to DT device creation. Look into dwc3-omap.c

    > > > +static int st_dwc3_remove(struct platform_device *pdev)
    > > > +{
    > > > + struct st_dwc3 *dwc3_data = platform_get_drvdata(pdev);
    > > > +
    > > > + platform_device_unregister(dwc3_data->dwc3);
    > > > +
    > > > + return 0;
    > > > +}
    > > > +
    > > > +#ifdef CONFIG_PM_SLEEP
    > > > +static int st_dwc3_suspend(struct device *dev)
    > > > +{
    > > > + struct st_dwc3 *dwc3_data = dev_get_drvdata(dev);
    > > > +
    > > > + reset_control_assert(dwc3_data->rstc_pwrdn);
    > > > +
    > > > + pinctrl_pm_select_sleep_state(dev);

    pinctrl will select sleep and default states automatically for you.

    --
    balbi
    [unhandled content-type:application/pgp-signature]
    \
     
     \ /
      Last update: 2014-07-22 17:41    [W:2.525 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site