aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/drivers/pci
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-08-20 07:39:22 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-08-20 07:39:22 -0400
commit144c7494239f12d554806439a17ad8203c7b2d3a (patch)
treedef630d167f5e25ca926faf462653075a69c7566 /arch/sh/drivers/pci
parentd2d5bc58d79321bd29ed1c8c61e806ec0541e3bf (diff)
parent65c23f54c01fabae171d54c0e78df354b3709b93 (diff)
Merge branch 'sh/pci-express-integration'
Diffstat (limited to 'arch/sh/drivers/pci')
-rw-r--r--arch/sh/drivers/pci/ops-sh7786.c27
-rw-r--r--arch/sh/drivers/pci/pcie-sh7786.c30
2 files changed, 36 insertions, 21 deletions
diff --git a/arch/sh/drivers/pci/ops-sh7786.c b/arch/sh/drivers/pci/ops-sh7786.c
index 48f594b9582b..79a5ddae733d 100644
--- a/arch/sh/drivers/pci/ops-sh7786.c
+++ b/arch/sh/drivers/pci/ops-sh7786.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Generic SH7786 PCI-Express operations. 2 * Generic SH7786 PCI-Express operations.
3 * 3 *
4 * Copyright (C) 2009 Paul Mundt 4 * Copyright (C) 2009 - 2010 Paul Mundt
5 * 5 *
6 * This file is subject to the terms and conditions of the GNU General Public 6 * This file is subject to the terms and conditions of the GNU General Public
7 * License v2. See the file "COPYING" in the main directory of this archive 7 * License v2. See the file "COPYING" in the main directory of this archive
@@ -25,32 +25,39 @@ static int sh7786_pcie_config_access(unsigned char access_type,
25 struct pci_bus *bus, unsigned int devfn, int where, u32 *data) 25 struct pci_bus *bus, unsigned int devfn, int where, u32 *data)
26{ 26{
27 struct pci_channel *chan = bus->sysdata; 27 struct pci_channel *chan = bus->sysdata;
28 int dev, func; 28 int dev, func, type;
29 29
30 dev = PCI_SLOT(devfn); 30 dev = PCI_SLOT(devfn);
31 func = PCI_FUNC(devfn); 31 func = PCI_FUNC(devfn);
32 type = !!bus->parent;
32 33
33 if (bus->number > 255 || dev > 31 || func > 7) 34 if (bus->number > 255 || dev > 31 || func > 7)
34 return PCIBIOS_FUNC_NOT_SUPPORTED; 35 return PCIBIOS_FUNC_NOT_SUPPORTED;
35 if (devfn) 36 if (bus->parent == NULL && dev)
36 return PCIBIOS_DEVICE_NOT_FOUND; 37 return PCIBIOS_DEVICE_NOT_FOUND;
37 38
39 /* Clear errors */
40 pci_write_reg(chan, pci_read_reg(chan, SH4A_PCIEERRFR), SH4A_PCIEERRFR);
41
38 /* Set the PIO address */ 42 /* Set the PIO address */
39 pci_write_reg(chan, (bus->number << 24) | (dev << 19) | 43 pci_write_reg(chan, (bus->number << 24) | (dev << 19) |
40 (func << 16) | (where & ~3), SH4A_PCIEPAR); 44 (func << 16) | (where & ~3), SH4A_PCIEPAR);
41 45
42 /* Enable the configuration access */ 46 /* Enable the configuration access */
43 pci_write_reg(chan, (1 << 31), SH4A_PCIEPCTLR); 47 pci_write_reg(chan, (1 << 31) | (type << 8), SH4A_PCIEPCTLR);
48
49 /* Check for errors */
50 if (pci_read_reg(chan, SH4A_PCIEERRFR) & 0x10)
51 return PCIBIOS_DEVICE_NOT_FOUND;
52 /* Check for master and target aborts */
53 if (pci_read_reg(chan, SH4A_PCIEPCICONF1) & ((1 << 29) | (1 << 28)))
54 return PCIBIOS_DEVICE_NOT_FOUND;
44 55
45 if (access_type == PCI_ACCESS_READ) 56 if (access_type == PCI_ACCESS_READ)
46 *data = pci_read_reg(chan, SH4A_PCIEPDR); 57 *data = pci_read_reg(chan, SH4A_PCIEPDR);
47 else 58 else
48 pci_write_reg(chan, *data, SH4A_PCIEPDR); 59 pci_write_reg(chan, *data, SH4A_PCIEPDR);
49 60
50 /* Check for master and target aborts */
51 if (pci_read_reg(chan, SH4A_PCIEPCICONF1) & ((1 << 29) | (1 << 28)))
52 return PCIBIOS_DEVICE_NOT_FOUND;
53
54 return PCIBIOS_SUCCESSFUL; 61 return PCIBIOS_SUCCESSFUL;
55} 62}
56 63
@@ -69,8 +76,10 @@ static int sh7786_pcie_read(struct pci_bus *bus, unsigned int devfn,
69 spin_lock_irqsave(&sh7786_pcie_lock, flags); 76 spin_lock_irqsave(&sh7786_pcie_lock, flags);
70 ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus, 77 ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus,
71 devfn, where, &data); 78 devfn, where, &data);
72 if (ret != PCIBIOS_SUCCESSFUL) 79 if (ret != PCIBIOS_SUCCESSFUL) {
80 *val = 0xffffffff;
73 goto out; 81 goto out;
82 }
74 83
75 if (size == 1) 84 if (size == 1)
76 *val = (data >> ((where & 3) << 3)) & 0xff; 85 *val = (data >> ((where & 3) << 3)) & 0xff;
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c
index 78f378731858..d053ffca8196 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.c
+++ b/arch/sh/drivers/pci/pcie-sh7786.c
@@ -148,16 +148,11 @@ static int pci_wait_for_irq(struct pci_channel *chan, unsigned int mask)
148static void phy_write_reg(struct pci_channel *chan, unsigned int addr, 148static void phy_write_reg(struct pci_channel *chan, unsigned int addr,
149 unsigned int lane, unsigned int data) 149 unsigned int lane, unsigned int data)
150{ 150{
151 unsigned long phyaddr, ctrl; 151 unsigned long phyaddr;
152 152
153 phyaddr = (1 << BITS_CMD) + ((lane & 0xf) << BITS_LANE) + 153 phyaddr = (1 << BITS_CMD) + ((lane & 0xf) << BITS_LANE) +
154 ((addr & 0xff) << BITS_ADR); 154 ((addr & 0xff) << BITS_ADR);
155 155
156 /* Enable clock */
157 ctrl = pci_read_reg(chan, SH4A_PCIEPHYCTLR);
158 ctrl |= (1 << BITS_CKE);
159 pci_write_reg(chan, ctrl, SH4A_PCIEPHYCTLR);
160
161 /* Set write data */ 156 /* Set write data */
162 pci_write_reg(chan, data, SH4A_PCIEPHYDOUTR); 157 pci_write_reg(chan, data, SH4A_PCIEPHYDOUTR);
163 pci_write_reg(chan, phyaddr, SH4A_PCIEPHYADRR); 158 pci_write_reg(chan, phyaddr, SH4A_PCIEPHYADRR);
@@ -165,20 +160,22 @@ static void phy_write_reg(struct pci_channel *chan, unsigned int addr,
165 phy_wait_for_ack(chan); 160 phy_wait_for_ack(chan);
166 161
167 /* Clear command */ 162 /* Clear command */
163 pci_write_reg(chan, 0, SH4A_PCIEPHYDOUTR);
168 pci_write_reg(chan, 0, SH4A_PCIEPHYADRR); 164 pci_write_reg(chan, 0, SH4A_PCIEPHYADRR);
169 165
170 phy_wait_for_ack(chan); 166 phy_wait_for_ack(chan);
171
172 /* Disable clock */
173 ctrl = pci_read_reg(chan, SH4A_PCIEPHYCTLR);
174 ctrl &= ~(1 << BITS_CKE);
175 pci_write_reg(chan, ctrl, SH4A_PCIEPHYCTLR);
176} 167}
177 168
178static int phy_init(struct pci_channel *chan) 169static int phy_init(struct pci_channel *chan)
179{ 170{
171 unsigned long ctrl;
180 unsigned int timeout = 100; 172 unsigned int timeout = 100;
181 173
174 /* Enable clock */
175 ctrl = pci_read_reg(chan, SH4A_PCIEPHYCTLR);
176 ctrl |= (1 << BITS_CKE);
177 pci_write_reg(chan, ctrl, SH4A_PCIEPHYCTLR);
178
182 /* Initialize the phy */ 179 /* Initialize the phy */
183 phy_write_reg(chan, 0x60, 0xf, 0x004b008b); 180 phy_write_reg(chan, 0x60, 0xf, 0x004b008b);
184 phy_write_reg(chan, 0x61, 0xf, 0x00007b41); 181 phy_write_reg(chan, 0x61, 0xf, 0x00007b41);
@@ -187,9 +184,15 @@ static int phy_init(struct pci_channel *chan)
187 phy_write_reg(chan, 0x66, 0xf, 0x00000010); 184 phy_write_reg(chan, 0x66, 0xf, 0x00000010);
188 phy_write_reg(chan, 0x74, 0xf, 0x0007001c); 185 phy_write_reg(chan, 0x74, 0xf, 0x0007001c);
189 phy_write_reg(chan, 0x79, 0xf, 0x01fc000d); 186 phy_write_reg(chan, 0x79, 0xf, 0x01fc000d);
187 phy_write_reg(chan, 0xb0, 0xf, 0x00000610);
190 188
191 /* Deassert Standby */ 189 /* Deassert Standby */
192 phy_write_reg(chan, 0x67, 0xf, 0x00000400); 190 phy_write_reg(chan, 0x67, 0x1, 0x00000400);
191
192 /* Disable clock */
193 ctrl = pci_read_reg(chan, SH4A_PCIEPHYCTLR);
194 ctrl &= ~(1 << BITS_CKE);
195 pci_write_reg(chan, ctrl, SH4A_PCIEPHYCTLR);
193 196
194 while (timeout--) { 197 while (timeout--) {
195 if (pci_read_reg(chan, SH4A_PCIEPHYSR)) 198 if (pci_read_reg(chan, SH4A_PCIEPHYSR))
@@ -287,6 +290,9 @@ static int pcie_init(struct sh7786_pcie_port *port)
287 __raw_writel(memphys, chan->reg_base + SH4A_PCIELAR0); 290 __raw_writel(memphys, chan->reg_base + SH4A_PCIELAR0);
288 __raw_writel((memsize - SZ_256) | 1, chan->reg_base + SH4A_PCIELAMR0); 291 __raw_writel((memsize - SZ_256) | 1, chan->reg_base + SH4A_PCIELAMR0);
289 292
293 __raw_writel(memphys, chan->reg_base + SH4A_PCIEPCICONF4);
294 __raw_writel(0, chan->reg_base + SH4A_PCIEPCICONF5);
295
290 /* Finish initialization */ 296 /* Finish initialization */
291 data = pci_read_reg(chan, SH4A_PCIETCTLR); 297 data = pci_read_reg(chan, SH4A_PCIETCTLR);
292 data |= 0x1; 298 data |= 0x1;