aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2015-01-20 17:55:59 -0500
committerFelipe Balbi <balbi@ti.com>2015-01-27 10:39:26 -0500
commit5171446a3aec607c4f94a32758f51a68bc627fe3 (patch)
treeef715105026ba279886ab33ef1a089a4606b11dc /drivers/usb/host
parent667c45c2f159d3c4e1d592df42ffbc7d4d73e07b (diff)
usb: isp1760: Initialize the bus interface in core code
Although the corresponding register is part of the HCD register space, processor bus initialization is not specific to the HCD. To prepare for device controller support, move bus interface initialization to core code. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/isp1760-core.c62
-rw-r--r--drivers/usb/host/isp1760-core.h31
-rw-r--r--drivers/usb/host/isp1760-hcd.c67
-rw-r--r--drivers/usb/host/isp1760-hcd.h20
4 files changed, 105 insertions, 75 deletions
diff --git a/drivers/usb/host/isp1760-core.c b/drivers/usb/host/isp1760-core.c
index 35278a8356b3..e840a1d3676b 100644
--- a/drivers/usb/host/isp1760-core.c
+++ b/drivers/usb/host/isp1760-core.c
@@ -13,7 +13,8 @@
13 * version 2 as published by the Free Software Foundation. 13 * version 2 as published by the Free Software Foundation.
14 */ 14 */
15 15
16#include <linux/gpio.h> 16#include <linux/delay.h>
17#include <linux/gpio/consumer.h>
17#include <linux/io.h> 18#include <linux/io.h>
18#include <linux/kernel.h> 19#include <linux/kernel.h>
19#include <linux/module.h> 20#include <linux/module.h>
@@ -22,6 +23,54 @@
22 23
23#include "isp1760-core.h" 24#include "isp1760-core.h"
24#include "isp1760-hcd.h" 25#include "isp1760-hcd.h"
26#include "isp1760-regs.h"
27
28static void isp1760_init_core(struct isp1760_device *isp)
29{
30 u32 hwmode;
31
32 /* Low-level chip reset */
33 if (isp->rst_gpio) {
34 gpiod_set_value_cansleep(isp->rst_gpio, 1);
35 mdelay(50);
36 gpiod_set_value_cansleep(isp->rst_gpio, 0);
37 }
38
39 /*
40 * Reset the host controller, including the CPU interface
41 * configuration.
42 */
43 isp1760_write32(isp->regs, HC_RESET_REG, SW_RESET_RESET_ALL);
44 msleep(100);
45
46 /* Setup HW Mode Control: This assumes a level active-low interrupt */
47 hwmode = HW_DATA_BUS_32BIT;
48
49 if (isp->devflags & ISP1760_FLAG_BUS_WIDTH_16)
50 hwmode &= ~HW_DATA_BUS_32BIT;
51 if (isp->devflags & ISP1760_FLAG_ANALOG_OC)
52 hwmode |= HW_ANA_DIGI_OC;
53 if (isp->devflags & ISP1760_FLAG_DACK_POL_HIGH)
54 hwmode |= HW_DACK_POL_HIGH;
55 if (isp->devflags & ISP1760_FLAG_DREQ_POL_HIGH)
56 hwmode |= HW_DREQ_POL_HIGH;
57 if (isp->devflags & ISP1760_FLAG_INTR_POL_HIGH)
58 hwmode |= HW_INTR_HIGH_ACT;
59 if (isp->devflags & ISP1760_FLAG_INTR_EDGE_TRIG)
60 hwmode |= HW_INTR_EDGE_TRIG;
61
62 /*
63 * We have to set this first in case we're in 16-bit mode.
64 * Write it twice to ensure correct upper bits if switching
65 * to 16-bit mode.
66 */
67 isp1760_write32(isp->regs, HC_HW_MODE_CTRL, hwmode);
68 isp1760_write32(isp->regs, HC_HW_MODE_CTRL, hwmode);
69
70 dev_info(isp->dev, "bus width: %u, oc: %s\n",
71 isp->devflags & ISP1760_FLAG_BUS_WIDTH_16 ? 16 : 32,
72 isp->devflags & ISP1760_FLAG_ANALOG_OC ? "analog" : "digital");
73}
25 74
26int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, 75int isp1760_register(struct resource *mem, int irq, unsigned long irqflags,
27 struct device *dev, unsigned int devflags) 76 struct device *dev, unsigned int devflags)
@@ -39,12 +88,21 @@ int isp1760_register(struct resource *mem, int irq, unsigned long irqflags,
39 if (!isp) 88 if (!isp)
40 return -ENOMEM; 89 return -ENOMEM;
41 90
91 isp->dev = dev;
92 isp->devflags = devflags;
93
94 isp->rst_gpio = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH);
95 if (IS_ERR(isp->rst_gpio))
96 return PTR_ERR(isp->rst_gpio);
97
42 isp->regs = devm_ioremap_resource(dev, mem); 98 isp->regs = devm_ioremap_resource(dev, mem);
43 if (IS_ERR(isp->regs)) 99 if (IS_ERR(isp->regs))
44 return PTR_ERR(isp->regs); 100 return PTR_ERR(isp->regs);
45 101
102 isp1760_init_core(isp);
103
46 ret = isp1760_hcd_register(&isp->hcd, isp->regs, mem, irq, 104 ret = isp1760_hcd_register(&isp->hcd, isp->regs, mem, irq,
47 irqflags | IRQF_SHARED, dev, devflags); 105 irqflags | IRQF_SHARED, dev);
48 if (ret < 0) 106 if (ret < 0)
49 return ret; 107 return ret;
50 108
diff --git a/drivers/usb/host/isp1760-core.h b/drivers/usb/host/isp1760-core.h
index 0caeb1135275..cd4a0f3981d9 100644
--- a/drivers/usb/host/isp1760-core.h
+++ b/drivers/usb/host/isp1760-core.h
@@ -20,8 +20,29 @@
20 20
21#include "isp1760-hcd.h" 21#include "isp1760-hcd.h"
22 22
23struct device;
24struct gpio_desc;
25
26/*
27 * Device flags that can vary from board to board. All of these
28 * indicate the most "atypical" case, so that a devflags of 0 is
29 * a sane default configuration.
30 */
31#define ISP1760_FLAG_BUS_WIDTH_16 0x00000002 /* 16-bit data bus width */
32#define ISP1760_FLAG_OTG_EN 0x00000004 /* Port 1 supports OTG */
33#define ISP1760_FLAG_ANALOG_OC 0x00000008 /* Analog overcurrent */
34#define ISP1760_FLAG_DACK_POL_HIGH 0x00000010 /* DACK active high */
35#define ISP1760_FLAG_DREQ_POL_HIGH 0x00000020 /* DREQ active high */
36#define ISP1760_FLAG_ISP1761 0x00000040 /* Chip is ISP1761 */
37#define ISP1760_FLAG_INTR_POL_HIGH 0x00000080 /* Interrupt polarity active high */
38#define ISP1760_FLAG_INTR_EDGE_TRIG 0x00000100 /* Interrupt edge triggered */
39
23struct isp1760_device { 40struct isp1760_device {
41 struct device *dev;
42
24 void __iomem *regs; 43 void __iomem *regs;
44 unsigned int devflags;
45 struct gpio_desc *rst_gpio;
25 46
26 struct isp1760_hcd hcd; 47 struct isp1760_hcd hcd;
27}; 48};
@@ -30,4 +51,14 @@ int isp1760_register(struct resource *mem, int irq, unsigned long irqflags,
30 struct device *dev, unsigned int devflags); 51 struct device *dev, unsigned int devflags);
31void isp1760_unregister(struct device *dev); 52void isp1760_unregister(struct device *dev);
32 53
54static inline u32 isp1760_read32(void __iomem *base, u32 reg)
55{
56 return readl(base + reg);
57}
58
59static inline void isp1760_write32(void __iomem *base, u32 reg, u32 val)
60{
61 writel(val, base + reg);
62}
63
33#endif 64#endif
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index 0cf620b1f6aa..5309d7324485 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -26,6 +26,7 @@
26#include <asm/unaligned.h> 26#include <asm/unaligned.h>
27#include <asm/cacheflush.h> 27#include <asm/cacheflush.h>
28 28
29#include "isp1760-core.h"
29#include "isp1760-hcd.h" 30#include "isp1760-hcd.h"
30#include "isp1760-regs.h" 31#include "isp1760-regs.h"
31 32
@@ -160,12 +161,12 @@ struct urb_listitem {
160 */ 161 */
161static u32 reg_read32(void __iomem *base, u32 reg) 162static u32 reg_read32(void __iomem *base, u32 reg)
162{ 163{
163 return readl(base + reg); 164 return isp1760_read32(base, reg);
164} 165}
165 166
166static void reg_write32(void __iomem *base, u32 reg, u32 val) 167static void reg_write32(void __iomem *base, u32 reg, u32 val)
167{ 168{
168 writel(val, base + reg); 169 isp1760_write32(base, reg, val);
169} 170}
170 171
171/* 172/*
@@ -466,37 +467,6 @@ static int isp1760_hc_setup(struct usb_hcd *hcd)
466 int result; 467 int result;
467 u32 scratch, hwmode; 468 u32 scratch, hwmode;
468 469
469 /* low-level chip reset */
470 if (priv->rst_gpio) {
471 gpiod_set_value_cansleep(priv->rst_gpio, 1);
472 mdelay(50);
473 gpiod_set_value_cansleep(priv->rst_gpio, 0);
474 }
475
476 /* Setup HW Mode Control: This assumes a level active-low interrupt */
477 hwmode = HW_DATA_BUS_32BIT;
478
479 if (priv->devflags & ISP1760_FLAG_BUS_WIDTH_16)
480 hwmode &= ~HW_DATA_BUS_32BIT;
481 if (priv->devflags & ISP1760_FLAG_ANALOG_OC)
482 hwmode |= HW_ANA_DIGI_OC;
483 if (priv->devflags & ISP1760_FLAG_DACK_POL_HIGH)
484 hwmode |= HW_DACK_POL_HIGH;
485 if (priv->devflags & ISP1760_FLAG_DREQ_POL_HIGH)
486 hwmode |= HW_DREQ_POL_HIGH;
487 if (priv->devflags & ISP1760_FLAG_INTR_POL_HIGH)
488 hwmode |= HW_INTR_HIGH_ACT;
489 if (priv->devflags & ISP1760_FLAG_INTR_EDGE_TRIG)
490 hwmode |= HW_INTR_EDGE_TRIG;
491
492 /*
493 * We have to set this first in case we're in 16-bit mode.
494 * Write it twice to ensure correct upper bits if switching
495 * to 16-bit mode.
496 */
497 reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode);
498 reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode);
499
500 reg_write32(hcd->regs, HC_SCRATCH_REG, 0xdeadbabe); 470 reg_write32(hcd->regs, HC_SCRATCH_REG, 0xdeadbabe);
501 /* Change bus pattern */ 471 /* Change bus pattern */
502 scratch = reg_read32(hcd->regs, HC_CHIP_ID_REG); 472 scratch = reg_read32(hcd->regs, HC_CHIP_ID_REG);
@@ -506,31 +476,27 @@ static int isp1760_hc_setup(struct usb_hcd *hcd)
506 return -ENODEV; 476 return -ENODEV;
507 } 477 }
508 478
509 /* pre reset */ 479 /*
480 * The RESET_HC bit in the SW_RESET register is supposed to reset the
481 * host controller without touching the CPU interface registers, but at
482 * least on the ISP1761 it seems to behave as the RESET_ALL bit and
483 * reset the whole device. We thus can't use it here, so let's reset
484 * the host controller through the EHCI USB Command register. The device
485 * has been reset in core code anyway, so this shouldn't matter.
486 */
510 reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, 0); 487 reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, 0);
511 reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE); 488 reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE);
512 reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE); 489 reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE);
513 reg_write32(hcd->regs, HC_ISO_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE); 490 reg_write32(hcd->regs, HC_ISO_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE);
514 491
515 /* reset */
516 reg_write32(hcd->regs, HC_RESET_REG, SW_RESET_RESET_ALL);
517 mdelay(100);
518
519 reg_write32(hcd->regs, HC_RESET_REG, SW_RESET_RESET_HC);
520 mdelay(100);
521
522 result = ehci_reset(hcd); 492 result = ehci_reset(hcd);
523 if (result) 493 if (result)
524 return result; 494 return result;
525 495
526 /* Step 11 passed */ 496 /* Step 11 passed */
527 497
528 dev_info(hcd->self.controller, "bus width: %d, oc: %s\n",
529 (priv->devflags & ISP1760_FLAG_BUS_WIDTH_16) ?
530 16 : 32, (priv->devflags & ISP1760_FLAG_ANALOG_OC) ?
531 "analog" : "digital");
532
533 /* ATL reset */ 498 /* ATL reset */
499 hwmode = reg_read32(hcd->regs, HC_HW_MODE_CTRL) & ~ALL_ATX_RESET;
534 reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode | ALL_ATX_RESET); 500 reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode | ALL_ATX_RESET);
535 mdelay(10); 501 mdelay(10);
536 reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode); 502 reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode);
@@ -2234,7 +2200,7 @@ void isp1760_deinit_kmem_cache(void)
2234 2200
2235int isp1760_hcd_register(struct isp1760_hcd *priv, void __iomem *regs, 2201int isp1760_hcd_register(struct isp1760_hcd *priv, void __iomem *regs,
2236 struct resource *mem, int irq, unsigned long irqflags, 2202 struct resource *mem, int irq, unsigned long irqflags,
2237 struct device *dev, unsigned int devflags) 2203 struct device *dev)
2238{ 2204{
2239 struct usb_hcd *hcd; 2205 struct usb_hcd *hcd;
2240 int ret; 2206 int ret;
@@ -2246,13 +2212,6 @@ int isp1760_hcd_register(struct isp1760_hcd *priv, void __iomem *regs,
2246 *(struct isp1760_hcd **)hcd->hcd_priv = priv; 2212 *(struct isp1760_hcd **)hcd->hcd_priv = priv;
2247 2213
2248 priv->hcd = hcd; 2214 priv->hcd = hcd;
2249 priv->devflags = devflags;
2250
2251 priv->rst_gpio = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH);
2252 if (IS_ERR(priv->rst_gpio)) {
2253 ret = PTR_ERR(priv->rst_gpio);
2254 goto error;
2255 }
2256 2215
2257 init_memory(priv); 2216 init_memory(priv);
2258 2217
diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h
index dcd2232848cd..df7ea3684b77 100644
--- a/drivers/usb/host/isp1760-hcd.h
+++ b/drivers/usb/host/isp1760-hcd.h
@@ -3,7 +3,6 @@
3 3
4#include <linux/spinlock.h> 4#include <linux/spinlock.h>
5 5
6struct gpio_desc;
7struct isp1760_qh; 6struct isp1760_qh;
8struct isp1760_qtd; 7struct isp1760_qtd;
9struct resource; 8struct resource;
@@ -27,20 +26,6 @@ struct usb_hcd;
27#define MAX_PAYLOAD_SIZE BLOCK_3_SIZE 26#define MAX_PAYLOAD_SIZE BLOCK_3_SIZE
28#define PAYLOAD_AREA_SIZE 0xf000 27#define PAYLOAD_AREA_SIZE 0xf000
29 28
30/*
31 * Device flags that can vary from board to board. All of these
32 * indicate the most "atypical" case, so that a devflags of 0 is
33 * a sane default configuration.
34 */
35#define ISP1760_FLAG_BUS_WIDTH_16 0x00000002 /* 16-bit data bus width */
36#define ISP1760_FLAG_OTG_EN 0x00000004 /* Port 1 supports OTG */
37#define ISP1760_FLAG_ANALOG_OC 0x00000008 /* Analog overcurrent */
38#define ISP1760_FLAG_DACK_POL_HIGH 0x00000010 /* DACK active high */
39#define ISP1760_FLAG_DREQ_POL_HIGH 0x00000020 /* DREQ active high */
40#define ISP1760_FLAG_ISP1761 0x00000040 /* Chip is ISP1761 */
41#define ISP1760_FLAG_INTR_POL_HIGH 0x00000080 /* Interrupt polarity active high */
42#define ISP1760_FLAG_INTR_EDGE_TRIG 0x00000100 /* Interrupt edge triggered */
43
44struct isp1760_slotinfo { 29struct isp1760_slotinfo {
45 struct isp1760_qh *qh; 30 struct isp1760_qh *qh;
46 struct isp1760_qtd *qtd; 31 struct isp1760_qtd *qtd;
@@ -79,14 +64,11 @@ struct isp1760_hcd {
79 unsigned i_thresh; 64 unsigned i_thresh;
80 unsigned long reset_done; 65 unsigned long reset_done;
81 unsigned long next_statechange; 66 unsigned long next_statechange;
82 unsigned int devflags;
83
84 struct gpio_desc *rst_gpio;
85}; 67};
86 68
87int isp1760_hcd_register(struct isp1760_hcd *priv, void __iomem *regs, 69int isp1760_hcd_register(struct isp1760_hcd *priv, void __iomem *regs,
88 struct resource *mem, int irq, unsigned long irqflags, 70 struct resource *mem, int irq, unsigned long irqflags,
89 struct device *dev, unsigned int devflags); 71 struct device *dev);
90void isp1760_hcd_unregister(struct isp1760_hcd *priv); 72void isp1760_hcd_unregister(struct isp1760_hcd *priv);
91 73
92int isp1760_init_kmem_once(void); 74int isp1760_init_kmem_once(void);