aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/isp1760-hcd.c67
-rw-r--r--drivers/usb/host/isp1760-hcd.h20
-rw-r--r--drivers/usb/host/isp1760-if.c35
3 files changed, 104 insertions, 18 deletions
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index d318af39c27f..c858f2adb929 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -38,6 +38,7 @@ struct isp1760_hcd {
38 unsigned i_thresh; 38 unsigned i_thresh;
39 unsigned long reset_done; 39 unsigned long reset_done;
40 unsigned long next_statechange; 40 unsigned long next_statechange;
41 unsigned int devflags;
41}; 42};
42 43
43static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) 44static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd)
@@ -378,9 +379,31 @@ static int isp1760_hc_setup(struct usb_hcd *hcd)
378{ 379{
379 struct isp1760_hcd *priv = hcd_to_priv(hcd); 380 struct isp1760_hcd *priv = hcd_to_priv(hcd);
380 int result; 381 int result;
381 u32 scratch; 382 u32 scratch, hwmode;
383
384 /* Setup HW Mode Control: This assumes a level active-low interrupt */
385 hwmode = HW_DATA_BUS_32BIT;
386
387 if (priv->devflags & ISP1760_FLAG_BUS_WIDTH_16)
388 hwmode &= ~HW_DATA_BUS_32BIT;
389 if (priv->devflags & ISP1760_FLAG_ANALOG_OC)
390 hwmode |= HW_ANA_DIGI_OC;
391 if (priv->devflags & ISP1760_FLAG_DACK_POL_HIGH)
392 hwmode |= HW_DACK_POL_HIGH;
393 if (priv->devflags & ISP1760_FLAG_DREQ_POL_HIGH)
394 hwmode |= HW_DREQ_POL_HIGH;
395
396 /*
397 * We have to set this first in case we're in 16-bit mode.
398 * Write it twice to ensure correct upper bits if switching
399 * to 16-bit mode.
400 */
401 isp1760_writel(hwmode, hcd->regs + HC_HW_MODE_CTRL);
402 isp1760_writel(hwmode, hcd->regs + HC_HW_MODE_CTRL);
382 403
383 isp1760_writel(0xdeadbabe, hcd->regs + HC_SCRATCH_REG); 404 isp1760_writel(0xdeadbabe, hcd->regs + HC_SCRATCH_REG);
405 /* Change bus pattern */
406 scratch = isp1760_readl(hcd->regs + HC_CHIP_ID_REG);
384 scratch = isp1760_readl(hcd->regs + HC_SCRATCH_REG); 407 scratch = isp1760_readl(hcd->regs + HC_SCRATCH_REG);
385 if (scratch != 0xdeadbabe) { 408 if (scratch != 0xdeadbabe) {
386 printk(KERN_ERR "ISP1760: Scratch test failed.\n"); 409 printk(KERN_ERR "ISP1760: Scratch test failed.\n");
@@ -403,17 +426,29 @@ static int isp1760_hc_setup(struct usb_hcd *hcd)
403 426
404 /* Step 11 passed */ 427 /* Step 11 passed */
405 428
406 isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_REG); 429 isp1760_info(priv, "bus width: %d, oc: %s\n",
407 isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_ENABLE); 430 (priv->devflags & ISP1760_FLAG_BUS_WIDTH_16) ?
431 16 : 32, (priv->devflags & ISP1760_FLAG_ANALOG_OC) ?
432 "analog" : "digital");
408 433
409 /* ATL reset */ 434 /* ATL reset */
410 scratch = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL); 435 isp1760_writel(hwmode | ALL_ATX_RESET, hcd->regs + HC_HW_MODE_CTRL);
411 isp1760_writel(scratch | ALL_ATX_RESET, hcd->regs + HC_HW_MODE_CTRL);
412 mdelay(10); 436 mdelay(10);
413 isp1760_writel(scratch, hcd->regs + HC_HW_MODE_CTRL); 437 isp1760_writel(hwmode, hcd->regs + HC_HW_MODE_CTRL);
414 438
415 isp1760_writel(PORT1_POWER | PORT1_INIT2, hcd->regs + HC_PORT1_CTRL); 439 isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_REG);
416 mdelay(10); 440 isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_ENABLE);
441
442 /*
443 * PORT 1 Control register of the ISP1760 is the OTG control
444 * register on ISP1761.
445 */
446 if (!(priv->devflags & ISP1760_FLAG_ISP1761) &&
447 !(priv->devflags & ISP1760_FLAG_PORT1_DIS)) {
448 isp1760_writel(PORT1_POWER | PORT1_INIT2,
449 hcd->regs + HC_PORT1_CTRL);
450 mdelay(10);
451 }
417 452
418 priv->hcs_params = isp1760_readl(hcd->regs + HC_HCSPARAMS); 453 priv->hcs_params = isp1760_readl(hcd->regs + HC_HCSPARAMS);
419 454
@@ -453,8 +488,7 @@ static int isp1760_run(struct usb_hcd *hcd)
453 hcd->state = HC_STATE_RUNNING; 488 hcd->state = HC_STATE_RUNNING;
454 isp1760_enable_interrupts(hcd); 489 isp1760_enable_interrupts(hcd);
455 temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL); 490 temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL);
456 temp |= FINAL_HW_CONFIG; 491 isp1760_writel(temp | HW_GLOBAL_INTR_EN, hcd->regs + HC_HW_MODE_CTRL);
457 isp1760_writel(temp, hcd->regs + HC_HW_MODE_CTRL);
458 492
459 command = isp1760_readl(hcd->regs + HC_USBCMD); 493 command = isp1760_readl(hcd->regs + HC_USBCMD);
460 command &= ~(CMD_LRESET|CMD_RESET); 494 command &= ~(CMD_LRESET|CMD_RESET);
@@ -2112,6 +2146,7 @@ static int isp1760_get_frame(struct usb_hcd *hcd)
2112static void isp1760_stop(struct usb_hcd *hcd) 2146static void isp1760_stop(struct usb_hcd *hcd)
2113{ 2147{
2114 struct isp1760_hcd *priv = hcd_to_priv(hcd); 2148 struct isp1760_hcd *priv = hcd_to_priv(hcd);
2149 u32 temp;
2115 2150
2116 isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1, 2151 isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1,
2117 NULL, 0); 2152 NULL, 0);
@@ -2120,7 +2155,8 @@ static void isp1760_stop(struct usb_hcd *hcd)
2120 spin_lock_irq(&priv->lock); 2155 spin_lock_irq(&priv->lock);
2121 ehci_reset(priv); 2156 ehci_reset(priv);
2122 /* Disable IRQ */ 2157 /* Disable IRQ */
2123 isp1760_writel(HW_DATA_BUS_32BIT, hcd->regs + HC_HW_MODE_CTRL); 2158 temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL);
2159 isp1760_writel(temp &= ~HW_GLOBAL_INTR_EN, hcd->regs + HC_HW_MODE_CTRL);
2124 spin_unlock_irq(&priv->lock); 2160 spin_unlock_irq(&priv->lock);
2125 2161
2126 isp1760_writel(0, hcd->regs + HC_CONFIGFLAG); 2162 isp1760_writel(0, hcd->regs + HC_CONFIGFLAG);
@@ -2128,10 +2164,11 @@ static void isp1760_stop(struct usb_hcd *hcd)
2128 2164
2129static void isp1760_shutdown(struct usb_hcd *hcd) 2165static void isp1760_shutdown(struct usb_hcd *hcd)
2130{ 2166{
2131 u32 command; 2167 u32 command, temp;
2132 2168
2133 isp1760_stop(hcd); 2169 isp1760_stop(hcd);
2134 isp1760_writel(HW_DATA_BUS_32BIT, hcd->regs + HC_HW_MODE_CTRL); 2170 temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL);
2171 isp1760_writel(temp &= ~HW_GLOBAL_INTR_EN, hcd->regs + HC_HW_MODE_CTRL);
2135 2172
2136 command = isp1760_readl(hcd->regs + HC_USBCMD); 2173 command = isp1760_readl(hcd->regs + HC_USBCMD);
2137 command &= ~CMD_RUN; 2174 command &= ~CMD_RUN;
@@ -2183,7 +2220,8 @@ void deinit_kmem_cache(void)
2183} 2220}
2184 2221
2185struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, 2222struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq,
2186 u64 irqflags, struct device *dev, const char *busname) 2223 u64 irqflags, struct device *dev, const char *busname,
2224 unsigned int devflags)
2187{ 2225{
2188 struct usb_hcd *hcd; 2226 struct usb_hcd *hcd;
2189 struct isp1760_hcd *priv; 2227 struct isp1760_hcd *priv;
@@ -2200,6 +2238,7 @@ struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq,
2200 return ERR_PTR(-ENOMEM); 2238 return ERR_PTR(-ENOMEM);
2201 2239
2202 priv = hcd_to_priv(hcd); 2240 priv = hcd_to_priv(hcd);
2241 priv->devflags = devflags;
2203 init_memory(priv); 2242 init_memory(priv);
2204 hcd->regs = ioremap(res_start, res_len); 2243 hcd->regs = ioremap(res_start, res_len);
2205 if (!hcd->regs) { 2244 if (!hcd->regs) {
diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h
index 3d86d0f6b147..6473dd86993c 100644
--- a/drivers/usb/host/isp1760-hcd.h
+++ b/drivers/usb/host/isp1760-hcd.h
@@ -3,7 +3,8 @@
3 3
4/* exports for if */ 4/* exports for if */
5struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, 5struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq,
6 u64 irqflags, struct device *dev, const char *busname); 6 u64 irqflags, struct device *dev, const char *busname,
7 unsigned int devflags);
7int init_kmem_once(void); 8int init_kmem_once(void);
8void deinit_kmem_cache(void); 9void deinit_kmem_cache(void);
9 10
@@ -31,6 +32,7 @@ void deinit_kmem_cache(void);
31/* Configuration Register */ 32/* Configuration Register */
32#define HC_HW_MODE_CTRL 0x300 33#define HC_HW_MODE_CTRL 0x300
33#define ALL_ATX_RESET (1 << 31) 34#define ALL_ATX_RESET (1 << 31)
35#define HW_ANA_DIGI_OC (1 << 15)
34#define HW_DATA_BUS_32BIT (1 << 8) 36#define HW_DATA_BUS_32BIT (1 << 8)
35#define HW_DACK_POL_HIGH (1 << 6) 37#define HW_DACK_POL_HIGH (1 << 6)
36#define HW_DREQ_POL_HIGH (1 << 5) 38#define HW_DREQ_POL_HIGH (1 << 5)
@@ -56,13 +58,14 @@ void deinit_kmem_cache(void);
56#define PORT1_POWER (3 << 3) 58#define PORT1_POWER (3 << 3)
57#define PORT1_INIT1 (1 << 7) 59#define PORT1_INIT1 (1 << 7)
58#define PORT1_INIT2 (1 << 23) 60#define PORT1_INIT2 (1 << 23)
61#define HW_OTG_CTRL_SET 0x374
62#define HW_OTG_CTRL_CLR 0x376
59 63
60/* Interrupt Register */ 64/* Interrupt Register */
61#define HC_INTERRUPT_REG 0x310 65#define HC_INTERRUPT_REG 0x310
62 66
63#define HC_INTERRUPT_ENABLE 0x314 67#define HC_INTERRUPT_ENABLE 0x314
64#define INTERRUPT_ENABLE_MASK (HC_INTL_INT | HC_ATL_INT | HC_EOT_INT) 68#define INTERRUPT_ENABLE_MASK (HC_INTL_INT | HC_ATL_INT | HC_EOT_INT)
65#define FINAL_HW_CONFIG (HW_GLOBAL_INTR_EN | HW_DATA_BUS_32BIT)
66 69
67#define HC_ISO_INT (1 << 9) 70#define HC_ISO_INT (1 << 9)
68#define HC_ATL_INT (1 << 8) 71#define HC_ATL_INT (1 << 8)
@@ -122,6 +125,19 @@ typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh,
122#define isp1760_err(priv, fmt, args...) \ 125#define isp1760_err(priv, fmt, args...) \
123 dev_err(priv_to_hcd(priv)->self.controller, fmt, ##args) 126 dev_err(priv_to_hcd(priv)->self.controller, fmt, ##args)
124 127
128/*
129 * Device flags that can vary from board to board. All of these
130 * indicate the most "atypical" case, so that a devflags of 0 is
131 * a sane default configuration.
132 */
133#define ISP1760_FLAG_PORT1_DIS 0x00000001 /* Port 1 disabled */
134#define ISP1760_FLAG_BUS_WIDTH_16 0x00000002 /* 16-bit data bus width */
135#define ISP1760_FLAG_OTG_EN 0x00000004 /* Port 1 supports OTG */
136#define ISP1760_FLAG_ANALOG_OC 0x00000008 /* Analog overcurrent */
137#define ISP1760_FLAG_DACK_POL_HIGH 0x00000010 /* DACK active high */
138#define ISP1760_FLAG_DREQ_POL_HIGH 0x00000020 /* DREQ active high */
139#define ISP1760_FLAG_ISP1761 0x00000040 /* Chip is ISP1761 */
140
125/* chip memory management */ 141/* chip memory management */
126struct memory_chunk { 142struct memory_chunk {
127 unsigned int start; 143 unsigned int start;
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
index ad833661ff34..051ef7b6bdc6 100644
--- a/drivers/usb/host/isp1760-if.c
+++ b/drivers/usb/host/isp1760-if.c
@@ -35,6 +35,8 @@ static int of_isp1760_probe(struct of_device *dev,
35 int virq; 35 int virq;
36 u64 res_len; 36 u64 res_len;
37 int ret; 37 int ret;
38 const unsigned int *prop;
39 unsigned int devflags = 0;
38 40
39 ret = of_address_to_resource(dp, 0, &memory); 41 ret = of_address_to_resource(dp, 0, &memory);
40 if (ret) 42 if (ret)
@@ -55,8 +57,32 @@ static int of_isp1760_probe(struct of_device *dev,
55 virq = irq_create_of_mapping(oirq.controller, oirq.specifier, 57 virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
56 oirq.size); 58 oirq.size);
57 59
60 if (of_device_is_compatible(dp, "nxp,usb-isp1761"))
61 devflags |= ISP1760_FLAG_ISP1761;
62
63 if (of_get_property(dp, "port1-disable", NULL) != NULL)
64 devflags |= ISP1760_FLAG_PORT1_DIS;
65
66 /* Some systems wire up only 16 of the 32 data lines */
67 prop = of_get_property(dp, "bus-width", NULL);
68 if (prop && *prop == 16)
69 devflags |= ISP1760_FLAG_BUS_WIDTH_16;
70
71 if (of_get_property(dp, "port1-otg", NULL) != NULL)
72 devflags |= ISP1760_FLAG_OTG_EN;
73
74 if (of_get_property(dp, "analog-oc", NULL) != NULL)
75 devflags |= ISP1760_FLAG_ANALOG_OC;
76
77 if (of_get_property(dp, "dack-polarity", NULL) != NULL)
78 devflags |= ISP1760_FLAG_DACK_POL_HIGH;
79
80 if (of_get_property(dp, "dreq-polarity", NULL) != NULL)
81 devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
82
58 hcd = isp1760_register(memory.start, res_len, virq, 83 hcd = isp1760_register(memory.start, res_len, virq,
59 IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev)); 84 IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev),
85 devflags);
60 if (IS_ERR(hcd)) { 86 if (IS_ERR(hcd)) {
61 ret = PTR_ERR(hcd); 87 ret = PTR_ERR(hcd);
62 goto release_reg; 88 goto release_reg;
@@ -87,6 +113,9 @@ static struct of_device_id of_isp1760_match[] = {
87 { 113 {
88 .compatible = "nxp,usb-isp1760", 114 .compatible = "nxp,usb-isp1760",
89 }, 115 },
116 {
117 .compatible = "nxp,usb-isp1761",
118 },
90 { }, 119 { },
91}; 120};
92MODULE_DEVICE_TABLE(of, of_isp1760_match); 121MODULE_DEVICE_TABLE(of, of_isp1760_match);
@@ -116,6 +145,7 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev,
116 int length; 145 int length;
117 int status = 1; 146 int status = 1;
118 struct usb_hcd *hcd; 147 struct usb_hcd *hcd;
148 unsigned int devflags = 0;
119 149
120 if (usb_disabled()) 150 if (usb_disabled())
121 return -ENODEV; 151 return -ENODEV;
@@ -200,7 +230,8 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev,
200 230
201 dev->dev.dma_mask = NULL; 231 dev->dev.dma_mask = NULL;
202 hcd = isp1760_register(pci_mem_phy0, length, dev->irq, 232 hcd = isp1760_register(pci_mem_phy0, length, dev->irq,
203 IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev)); 233 IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev),
234 devflags);
204 pci_set_drvdata(dev, hcd); 235 pci_set_drvdata(dev, hcd);
205 if (!hcd) 236 if (!hcd)
206 return 0; 237 return 0;