public inbox for linux-tegra@vger.kernel.org
 help / color / mirror / Atom feed
From: rmorell-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org
To: Benoit Goby <benoit-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>
Cc: David Brownell
	<dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>,
	Greg Kroah-Hartman <gregkh-l3A5Bk7waGM@public.gmane.org>,
	"linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org"
	<linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>,
	Erik Gilling <konkers-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>,
	"linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org"
	<linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Subject: Re: [PATCH 1/4] [ARM] tegra: Add support for Tegra USB PHYs
Date: Tue, 8 Feb 2011 23:05:40 -0800	[thread overview]
Message-ID: <20110209070540.GA17627@morell.nvidia.com> (raw)
In-Reply-To: <1297228927-23497-2-git-send-email-benoit-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>

On Tue, Feb 08, 2011 at 09:22:04PM -0800, Benoit Goby wrote:
> Interface used by Tegra's gadget driver and ehci driver
> to power on and configure the USB PHYs.
> 
> Signed-off-by: Benoit Goby <benoit-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>
> ---

For some reason this patch (along with patch 3) appears to contain
spaces as indentation (no hard tabs), although patches 2 and 4 in this
series have the correct tabs.

[...]

> +#define USB_USBSTS             0x144
> +#define   USB_USBSTS_PCI       (1 << 2)

This doesn't appear to be used?

[...]

> +static DEFINE_SPINLOCK(utmip_pad_lock);
> +static int utmip_pad_count;
> +
> +static const int udc_freq_table[] = {
> +       12000000,
> +       13000000,
> +       19200000,
> +       26000000,
> +};
> +
> +static const u8 udc_delay_table[][4] = {
> +       /* ENABLE_DLY, STABLE_CNT, ACTIVE_DLY, XTAL_FREQ_CNT */
> +       {0x02,         0x2F,       0x04,       0x76}, /* 12 MHz */
> +       {0x02,         0x33,       0x05,       0x7F}, /* 13 MHz */
> +       {0x03,         0x4B,       0x06,       0xBB}, /* 19.2 MHz */
> +       {0x04,         0x66,       0x09,       0xFE}, /* 26 Mhz */
> +};

Use an array of structs here?  Writing
"UTMIP_PLL_ACTIVE_DLY_COUNT(udc_delay_table[phy->freq_sel][2])" below is a
lot less clear and more prone to bugs than, say,
"UTMIP_PLL_ACTIVE_DLY_COUNT(udc_delay_table[phy->freq_sel].active_dly)".

It'd be even better to combine all three tables into one; something
like:
static const struct udc_... udc_table[] = {
        { .freq = 12000000,
          .delay = {
            .enable = 0x02,
            .stable = 0x2f,
            .active = 0x04
          },
          .xtal_freq_cnt = 0x76,
          .debounce = 0x7530,
        },
        [... etc]
};

[...]

> +static int utmip_pad_open(struct tegra_usb_phy *phy)
> +{
> +       phy->pad_clk = clk_get_sys("utmip-pad", NULL);
> +       if (IS_ERR(phy->pad_clk)) {
> +               pr_err("%s: can't get utmip pad clock\n", __func__);
> +               return -1;

return PTR_ERR(phy->pad_clk);

> +       }
> +
> +       if (phy->instance == 0) {
> +               phy->pad_regs = phy->regs;
> +       } else {
> +               phy->pad_regs = ioremap(TEGRA_USB_BASE, TEGRA_USB_SIZE);
> +               if (!phy->pad_regs) {
> +                       pr_err("%s: can't remap usb registers\n", __func__);
> +                       clk_put(phy->pad_clk);
> +                       return -ENOMEM;
> +               }
> +       }
> +       return 0;
> +}

[...]

> +static int utmip_pad_power_off(struct tegra_usb_phy *phy)
> +{
> +       unsigned long val, flags;
> +       void __iomem *base = phy->pad_regs;
> +
> +       if (!utmip_pad_count) {
> +               pr_err("%s: utmip pad already powered off\n", __func__);
> +               return -1;

return -EINVAL?

> +       }
> +
> +       clk_enable(phy->pad_clk);
> +
> +       spin_lock_irqsave(&utmip_pad_lock, flags);
> +
> +       if (--utmip_pad_count == 0) {
> +               val = readl(base + UTMIP_BIAS_CFG0);
> +               val |= UTMIP_OTGPD | UTMIP_BIASPD;
> +               writel(val, base + UTMIP_BIAS_CFG0);
> +       }
> +
> +       spin_unlock_irqrestore(&utmip_pad_lock, flags);
> +
> +       clk_disable(phy->pad_clk);
> +
> +       return 0;
> +}
> +

[...]

> +static void ulpi_phy_power_on(struct tegra_usb_phy *phy)
> +{
> +       unsigned long val;
> +       void __iomem *base = phy->regs;
> +       struct tegra_ulpi_config *config = phy->config;
> +
> +       gpio_direction_output(config->reset_gpio, 0);
> +       msleep(5);
> +       gpio_direction_output(config->reset_gpio, 1);
> +
> +       clk_enable(phy->clk);
> +       msleep(1);

This msleep seems excessive.  Does it take that long for the clock to
settle?

> +
> +       val = readl(base + USB_SUSP_CTRL);
> +       val |= UHSIC_RESET;
> +       writel(val, base + USB_SUSP_CTRL);
> +
> +       val = readl(base + ULPI_TIMING_CTRL_0);
> +       val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP;
> +       writel(val, base + ULPI_TIMING_CTRL_0);
> +
> +       val = readl(base + USB_SUSP_CTRL);
> +       val |= ULPI_PHY_ENABLE;
> +       writel(val, base + USB_SUSP_CTRL);
> +
> +       val = 0;
> +       writel(val, base + ULPI_TIMING_CTRL_1);
> +
> +       val |= ULPI_DATA_TRIMMER_SEL(4);
> +       val |= ULPI_STPDIRNXT_TRIMMER_SEL(4);
> +       val |= ULPI_DIR_TRIMMER_SEL(4);
> +       writel(val, base + ULPI_TIMING_CTRL_1);
> +       udelay(10);
> +
> +       val |= ULPI_DATA_TRIMMER_LOAD;
> +       val |= ULPI_STPDIRNXT_TRIMMER_LOAD;
> +       val |= ULPI_DIR_TRIMMER_LOAD;
> +       writel(val, base + ULPI_TIMING_CTRL_1);
> +
> +       val = ULPI_WAKEUP | ULPI_RD_RW_WRITE | ULPI_PORT(0);
> +       writel(val, base + ULPI_VIEWPORT);
> +
> +       if (utmi_wait_register(base + ULPI_VIEWPORT, ULPI_WAKEUP, 0)) {
> +               pr_err("%s: timeout waiting for ulpi phy wakeup\n", __func__);
> +               return;

Why does this function return void if it can fail?
tegra_usb_phy_power_on() can propagate the error.

> +       }
> +
> +       /* Fix VbusInvalid due to floating VBUS */
> +       ulpi_viewport_write(phy, 0x08, 0x40);
> +       ulpi_viewport_write(phy, 0x0B, 0x80);
> +
> +       val = readl(base + USB_PORTSC1);
> +       val |= USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN;
> +       writel(val, base + USB_PORTSC1);
> +
> +       val = readl(base + USB_SUSP_CTRL);
> +       val |= USB_SUSP_CLR;
> +       writel(val, base + USB_SUSP_CTRL);
> +       udelay(100);
> +
> +       val = readl(base + USB_SUSP_CTRL);
> +       val &= ~USB_SUSP_CLR;
> +       writel(val, base + USB_SUSP_CTRL);
> +}

[...]

> +struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs,
> +                       void *config, enum tegra_usb_phy_mode phy_mode)
> +{
> +       struct tegra_usb_phy *phy;
> +       struct tegra_ulpi_config *ulpi_config;
> +       unsigned long parent_rate;
> +       int freq_sel;
> +       int err;
> +
> +       phy = kmalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL);
> +       if (!phy)
> +               return ERR_PTR(-ENOMEM);
> +
> +       phy->instance = instance;
> +       phy->regs = regs;
> +       phy->config = config;
> +       phy->mode = phy_mode;
> +
> +       if (!phy->config) {
> +               if (instance == 1) {

Instead of all of the (instance == 1) checks here and below (I count
eleven separate places this is checked), it might be more readable to
have a macro or static inline function such as bool phy_is_ulpi(phy).

> +                       pr_err("%s: ulpi phy configuration missing", __func__);
> +                       err = -EINVAL;
> +                       goto err0;
> +               } else {
> +                       phy->config = &utmip_default[instance];
> +               }
> +       }
> +
> +       phy->pll_u = clk_get_sys(NULL, "pll_u");
> +       if (IS_ERR(phy->pll_u)) {
> +               pr_err("Can't get pll_u clock\n");
> +               err = PTR_ERR(phy->pll_u);
> +               goto err0;
> +       }
> +       clk_enable(phy->pll_u);
> +
> +       parent_rate = clk_get_rate(clk_get_parent(phy->pll_u));
> +       for (freq_sel = 0; freq_sel < ARRAY_SIZE(udc_freq_table); freq_sel++) {
> +               if (udc_freq_table[freq_sel] == parent_rate)
> +                       break;
> +       }
> +       if (freq_sel == ARRAY_SIZE(udc_freq_table)) {
> +               pr_err("invalid pll_u parent rate %ld\n", parent_rate);
> +               err = -EINVAL;
> +               goto err1;
> +       }
> +       phy->freq_sel = freq_sel;
> +
> +       if (phy->instance == 1) {
> +               ulpi_config = config;
> +               phy->clk = clk_get_sys(NULL, ulpi_config->clk);
> +               if (IS_ERR(phy->clk)) {
> +                       pr_err("%s: can't get ulpi clock\n", __func__);
> +                       err = -ENXIO;
> +                       goto err1;
> +               }
> +               tegra_gpio_enable(ulpi_config->reset_gpio);
> +               gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b");
> +               gpio_direction_output(ulpi_config->reset_gpio, 0);
> +       } else {
> +               err = utmip_pad_open(phy);
> +               if (err < 0)
> +                       goto err1;
> +       }
> +
> +       return phy;
> +
> +err1:
> +       clk_disable(phy->pll_u);
> +       clk_put(phy->pll_u);
> +err0:
> +       kfree(phy);
> +       return ERR_PTR(err);
> +}

[...]

The rest seems okay.

> --
> 1.7.3.1
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2011-02-09  7:05 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-09  5:22 [PATCH 0/4] Tegra EHCI driver Benoit Goby
     [not found] ` <1297228927-23497-1-git-send-email-benoit-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>
2011-02-09  5:22   ` [PATCH 1/4] [ARM] tegra: Add support for Tegra USB PHYs Benoit Goby
     [not found]     ` <1297228927-23497-2-git-send-email-benoit-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>
2011-02-09  7:05       ` rmorell-DDmLM1+adcrQT0dZR+AlfA [this message]
     [not found]         ` <20110209070540.GA17627-f3YH7lVHJt/FT5IIyIEb6QC/G2K4zDHf@public.gmane.org>
2011-02-12  3:01           ` Benoit Goby
2011-02-09  8:44       ` Matthieu CASTET
2011-02-09  5:22   ` [PATCH 2/4] usb: host: ehci-hcd: Add controller_resets_phy quirk Benoit Goby
     [not found]     ` <1297228927-23497-3-git-send-email-benoit-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>
2011-02-09 16:01       ` Matthieu CASTET
     [not found]         ` <4D52BA75.5010409-ITF29qwbsa/QT0dZR+AlfA@public.gmane.org>
2011-02-10  2:46           ` Pavan Kondeti
2011-02-09  5:22   ` [PATCH 3/4] usb: host: Add EHCI driver for NVIDIA Tegra SoCs Benoit Goby
     [not found]     ` <1297228927-23497-4-git-send-email-benoit-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>
2011-02-09  9:01       ` Matthieu CASTET
     [not found]         ` <4D5257FA.1030605-ITF29qwbsa/QT0dZR+AlfA@public.gmane.org>
2011-02-12  0:59           ` Benoit Goby
2011-02-09 19:43       ` David Daney
2011-02-09  5:22   ` [PATCH 4/4] USB: ehci: tegra: Align DMA transfers to 32 bytes Benoit Goby

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110209070540.GA17627@morell.nvidia.com \
    --to=rmorell-ddmlm1+adcrqt0dzr+alfa@public.gmane.org \
    --cc=benoit-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org \
    --cc=dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    --cc=gregkh-l3A5Bk7waGM@public.gmane.org \
    --cc=konkers-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org \
    --cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox