diff options
Diffstat (limited to 'arch/sh')
-rw-r--r-- | arch/sh/drivers/pci/pcie-sh7786.c | 89 | ||||
-rw-r--r-- | arch/sh/drivers/pci/pcie-sh7786.h | 36 |
2 files changed, 82 insertions, 43 deletions
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index 95d095f26d6..ae91a2dd918 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c | |||
@@ -204,7 +204,9 @@ static int pcie_init(struct sh7786_pcie_port *port) | |||
204 | { | 204 | { |
205 | struct pci_channel *chan = port->hose; | 205 | struct pci_channel *chan = port->hose; |
206 | unsigned int data; | 206 | unsigned int data; |
207 | int ret; | 207 | phys_addr_t memphys; |
208 | size_t memsize; | ||
209 | int ret, i; | ||
208 | 210 | ||
209 | /* Begin initialization */ | 211 | /* Begin initialization */ |
210 | pci_write_reg(chan, 0, SH4A_PCIETCTLR); | 212 | pci_write_reg(chan, 0, SH4A_PCIETCTLR); |
@@ -227,15 +229,24 @@ static int pcie_init(struct sh7786_pcie_port *port) | |||
227 | data |= PCI_CAP_ID_EXP; | 229 | data |= PCI_CAP_ID_EXP; |
228 | pci_write_reg(chan, data, SH4A_PCIEEXPCAP0); | 230 | pci_write_reg(chan, data, SH4A_PCIEEXPCAP0); |
229 | 231 | ||
230 | /* Enable x4 link width and extended sync. */ | 232 | /* Enable data link layer active state reporting */ |
233 | pci_write_reg(chan, PCI_EXP_LNKCAP_DLLLARC, SH4A_PCIEEXPCAP3); | ||
234 | |||
235 | /* Enable extended sync and ASPM L0s support */ | ||
231 | data = pci_read_reg(chan, SH4A_PCIEEXPCAP4); | 236 | data = pci_read_reg(chan, SH4A_PCIEEXPCAP4); |
232 | data &= ~(PCI_EXP_LNKSTA_NLW << 16); | 237 | data &= ~PCI_EXP_LNKCTL_ASPMC; |
233 | data |= (1 << 22) | PCI_EXP_LNKCTL_ES; | 238 | data |= PCI_EXP_LNKCTL_ES | 1; |
234 | pci_write_reg(chan, data, SH4A_PCIEEXPCAP4); | 239 | pci_write_reg(chan, data, SH4A_PCIEEXPCAP4); |
235 | 240 | ||
241 | /* Write out the physical slot number */ | ||
242 | data = pci_read_reg(chan, SH4A_PCIEEXPCAP5); | ||
243 | data &= ~PCI_EXP_SLTCAP_PSN; | ||
244 | data |= (port->index + 1) << 19; | ||
245 | pci_write_reg(chan, data, SH4A_PCIEEXPCAP5); | ||
246 | |||
236 | /* Set the completion timer timeout to the maximum 32ms. */ | 247 | /* Set the completion timer timeout to the maximum 32ms. */ |
237 | data = pci_read_reg(chan, SH4A_PCIETLCTLR); | 248 | data = pci_read_reg(chan, SH4A_PCIETLCTLR); |
238 | data &= ~0xffff; | 249 | data &= ~0x3f00; |
239 | data |= 0x32 << 8; | 250 | data |= 0x32 << 8; |
240 | pci_write_reg(chan, data, SH4A_PCIETLCTLR); | 251 | pci_write_reg(chan, data, SH4A_PCIETLCTLR); |
241 | 252 | ||
@@ -248,6 +259,33 @@ static int pcie_init(struct sh7786_pcie_port *port) | |||
248 | data |= (0xff << 16); | 259 | data |= (0xff << 16); |
249 | pci_write_reg(chan, data, SH4A_PCIEMACCTLR); | 260 | pci_write_reg(chan, data, SH4A_PCIEMACCTLR); |
250 | 261 | ||
262 | memphys = __pa(memory_start); | ||
263 | memsize = roundup_pow_of_two(memory_end - memory_start); | ||
264 | |||
265 | /* | ||
266 | * If there's more than 512MB of memory, we need to roll over to | ||
267 | * LAR1/LAMR1. | ||
268 | */ | ||
269 | if (memsize > SZ_512M) { | ||
270 | __raw_writel(memphys + SZ_512M, chan->reg_base + SH4A_PCIELAR1); | ||
271 | __raw_writel(((memsize - SZ_512M) - SZ_256) | 1, | ||
272 | chan->reg_base + SH4A_PCIELAMR1); | ||
273 | memsize = SZ_512M; | ||
274 | } else { | ||
275 | /* | ||
276 | * Otherwise just zero it out and disable it. | ||
277 | */ | ||
278 | __raw_writel(0, chan->reg_base + SH4A_PCIELAR1); | ||
279 | __raw_writel(0, chan->reg_base + SH4A_PCIELAMR1); | ||
280 | } | ||
281 | |||
282 | /* | ||
283 | * LAR0/LAMR0 covers up to the first 512MB, which is enough to | ||
284 | * cover all of lowmem on most platforms. | ||
285 | */ | ||
286 | __raw_writel(memphys, chan->reg_base + SH4A_PCIELAR0); | ||
287 | __raw_writel((memsize - SZ_256) | 1, chan->reg_base + SH4A_PCIELAMR0); | ||
288 | |||
251 | /* Finish initialization */ | 289 | /* Finish initialization */ |
252 | data = pci_read_reg(chan, SH4A_PCIETCTLR); | 290 | data = pci_read_reg(chan, SH4A_PCIETCTLR); |
253 | data |= 0x1; | 291 | data |= 0x1; |
@@ -267,10 +305,14 @@ static int pcie_init(struct sh7786_pcie_port *port) | |||
267 | if (unlikely(ret != 0)) | 305 | if (unlikely(ret != 0)) |
268 | return -ENODEV; | 306 | return -ENODEV; |
269 | 307 | ||
270 | pci_write_reg(chan, 0x00100007, SH4A_PCIEPCICONF1); | 308 | data = pci_read_reg(chan, SH4A_PCIEPCICONF1); |
309 | data &= ~(PCI_STATUS_DEVSEL_MASK << 16); | ||
310 | data |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | | ||
311 | (PCI_STATUS_CAP_LIST | PCI_STATUS_DEVSEL_FAST) << 16; | ||
312 | pci_write_reg(chan, data, SH4A_PCIEPCICONF1); | ||
313 | |||
271 | pci_write_reg(chan, 0x80888000, SH4A_PCIETXVC0DCTLR); | 314 | pci_write_reg(chan, 0x80888000, SH4A_PCIETXVC0DCTLR); |
272 | pci_write_reg(chan, 0x00222000, SH4A_PCIERXVC0DCTLR); | 315 | pci_write_reg(chan, 0x00222000, SH4A_PCIERXVC0DCTLR); |
273 | pci_write_reg(chan, 0x000050A0, SH4A_PCIEEXPCAP2); | ||
274 | 316 | ||
275 | wmb(); | 317 | wmb(); |
276 | 318 | ||
@@ -278,15 +320,32 @@ static int pcie_init(struct sh7786_pcie_port *port) | |||
278 | printk(KERN_NOTICE "PCI: PCIe#%d link width %d\n", | 320 | printk(KERN_NOTICE "PCI: PCIe#%d link width %d\n", |
279 | port->index, (data >> 20) & 0x3f); | 321 | port->index, (data >> 20) & 0x3f); |
280 | 322 | ||
281 | pci_write_reg(chan, 0x007c0000, SH4A_PCIEPAMR0); | ||
282 | pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH0); | ||
283 | pci_write_reg(chan, 0x00000000, SH4A_PCIEPARL0); | ||
284 | pci_write_reg(chan, 0x80000100, SH4A_PCIEPTCTLR0); | ||
285 | 323 | ||
286 | pci_write_reg(chan, 0x03fc0000, SH4A_PCIEPAMR2); | 324 | for (i = 0; i < chan->nr_resources; i++) { |
287 | pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH2); | 325 | struct resource *res = chan->resources + i; |
288 | pci_write_reg(chan, 0x00000000, SH4A_PCIEPARL2); | 326 | resource_size_t size; |
289 | pci_write_reg(chan, 0x80000000, SH4A_PCIEPTCTLR2); | 327 | u32 enable_mask; |
328 | |||
329 | pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(i)); | ||
330 | |||
331 | size = resource_size(res); | ||
332 | |||
333 | /* | ||
334 | * The PAMR mask is calculated in units of 256kB, which | ||
335 | * keeps things pretty simple. | ||
336 | */ | ||
337 | __raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18, | ||
338 | chan->reg_base + SH4A_PCIEPAMR(i)); | ||
339 | |||
340 | pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH(i)); | ||
341 | pci_write_reg(chan, 0x00000000, SH4A_PCIEPARL(i)); | ||
342 | |||
343 | enable_mask = MASK_PARE; | ||
344 | if (res->flags & IORESOURCE_IO) | ||
345 | enable_mask |= MASK_SPC; | ||
346 | |||
347 | pci_write_reg(chan, enable_mask, SH4A_PCIEPTCTLR(i)); | ||
348 | } | ||
290 | 349 | ||
291 | return 0; | 350 | return 0; |
292 | } | 351 | } |
diff --git a/arch/sh/drivers/pci/pcie-sh7786.h b/arch/sh/drivers/pci/pcie-sh7786.h index 6666ea29cba..90a6992576b 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.h +++ b/arch/sh/drivers/pci/pcie-sh7786.h | |||
@@ -312,23 +312,23 @@ | |||
312 | #define SH4A_PCIECSAR5 (0x0202B4) /* R/W R/W 0x0000 0000 32 */ | 312 | #define SH4A_PCIECSAR5 (0x0202B4) /* R/W R/W 0x0000 0000 32 */ |
313 | #define SH4A_PCIESTCTLR5 (0x0202B8) /* R/W R/W 0x0000 0000 32 */ | 313 | #define SH4A_PCIESTCTLR5 (0x0202B8) /* R/W R/W 0x0000 0000 32 */ |
314 | 314 | ||
315 | /* PCIEPARL0 */ | 315 | /* PCIEPARL */ |
316 | #define SH4A_PCIEPARL0 (0x020400) /* R/W R/W 0x0000 0000 32 */ | 316 | #define SH4A_PCIEPARL(x) (0x020400 + ((x) * 0x20)) /* R/W R/W 0x0000 0000 32 */ |
317 | #define BITS_PAL (18) | 317 | #define BITS_PAL (18) |
318 | #define MASK_PAL (0x3fff<<BITS_PAL) | 318 | #define MASK_PAL (0x3fff<<BITS_PAL) |
319 | 319 | ||
320 | /* PCIEPARH0 */ | 320 | /* PCIEPARH */ |
321 | #define SH4A_PCIEPARH0 (0x020404) /* R/W R/W 0x0000 0000 32 */ | 321 | #define SH4A_PCIEPARH(x) (0x020404 + ((x) * 0x20)) /* R/W R/W 0x0000 0000 32 */ |
322 | #define BITS_PAH (0) | 322 | #define BITS_PAH (0) |
323 | #define MASK_PAH (0xffffffff<<BITS_PAH) | 323 | #define MASK_PAH (0xffffffff<<BITS_PAH) |
324 | 324 | ||
325 | /* PCIEPAMR0 */ | 325 | /* PCIEPAMR */ |
326 | #define SH4A_PCIEPAMR0 (0x020408) /* R/W R/W 0x0000 0000 32 */ | 326 | #define SH4A_PCIEPAMR(x) (0x020408 + ((x) * 0x20)) /* R/W R/W 0x0000 0000 32 */ |
327 | #define BITS_PAM (18) | 327 | #define BITS_PAM (18) |
328 | #define MASK_PAM (0x3fff<<BITS_PAM) | 328 | #define MASK_PAM (0x3fff<<BITS_PAM) |
329 | 329 | ||
330 | /* PCIEPTCTLR0 */ | 330 | /* PCIEPTCTLR */ |
331 | #define SH4A_PCIEPTCTLR0 (0x02040C) /* R/W R/W 0x0000 0000 32 */ | 331 | #define SH4A_PCIEPTCTLR(x) (0x02040C + ((x) * 0x20)) |
332 | #define BITS_PARE (31) | 332 | #define BITS_PARE (31) |
333 | #define MASK_PARE (0x1<<BITS_PARE) | 333 | #define MASK_PARE (0x1<<BITS_PARE) |
334 | #define BITS_TC (20) | 334 | #define BITS_TC (20) |
@@ -340,26 +340,6 @@ | |||
340 | #define BITS_SPC (8) | 340 | #define BITS_SPC (8) |
341 | #define MASK_SPC (0x1<<BITS_SPC) | 341 | #define MASK_SPC (0x1<<BITS_SPC) |
342 | 342 | ||
343 | #define SH4A_PCIEPARL1 (0x020420) /* R/W R/W 0x0000 0000 32 */ | ||
344 | #define SH4A_PCIEPARH1 (0x020424) /* R/W R/W 0x0000 0000 32 */ | ||
345 | #define SH4A_PCIEPAMR1 (0x020428) /* R/W R/W 0x0000 0000 32 */ | ||
346 | #define SH4A_PCIEPTCTLR1 (0x02042C) /* R/W R/W 0x0000 0000 32 */ | ||
347 | #define SH4A_PCIEPARL2 (0x020440) /* R/W R/W 0x0000 0000 32 */ | ||
348 | #define SH4A_PCIEPARH2 (0x020444) /* R/W R/W 0x0000 0000 32 */ | ||
349 | #define SH4A_PCIEPAMR2 (0x020448) /* R/W R/W 0x0000 0000 32 */ | ||
350 | #define SH4A_PCIEPTCTLR2 (0x02044C) /* R/W R/W 0x0000 0000 32 */ | ||
351 | #define SH4A_PCIEPARL3 (0x020460) /* R/W R/W 0x0000 0000 32 */ | ||
352 | #define SH4A_PCIEPARH3 (0x020464) /* R/W R/W 0x0000 0000 32 */ | ||
353 | #define SH4A_PCIEPAMR3 (0x020468) /* R/W R/W 0x0000 0000 32 */ | ||
354 | #define SH4A_PCIEPTCTLR3 (0x02046C) /* R/W R/W 0x0000 0000 32 */ | ||
355 | #define SH4A_PCIEPARL4 (0x020480) /* R/W R/W 0x0000 0000 32 */ | ||
356 | #define SH4A_PCIEPARH4 (0x020484) /* R/W R/W 0x0000 0000 32 */ | ||
357 | #define SH4A_PCIEPAMR4 (0x020488) /* R/W R/W 0x0000 0000 32 */ | ||
358 | #define SH4A_PCIEPTCTLR4 (0x02048C) /* R/W R/W 0x0000 0000 32 */ | ||
359 | #define SH4A_PCIEPARL5 (0x0204A0) /* R/W R/W 0x0000 0000 32 */ | ||
360 | #define SH4A_PCIEPARH5 (0x0204A4) /* R/W R/W 0x0000 0000 32 */ | ||
361 | #define SH4A_PCIEPAMR5 (0x0204A8) /* R/W R/W 0x0000 0000 32 */ | ||
362 | #define SH4A_PCIEPTCTLR5 (0x0204AC) /* R/W R/W 0x0000 0000 32 */ | ||
363 | #define SH4A_PCIEDMAOR (0x021000) /* R/W R/W 0x0000 0000 32 */ | 343 | #define SH4A_PCIEDMAOR (0x021000) /* R/W R/W 0x0000 0000 32 */ |
364 | #define SH4A_PCIEDMSAR0 (0x021100) /* R/W R/W 0x0000 0000 32 */ | 344 | #define SH4A_PCIEDMSAR0 (0x021100) /* R/W R/W 0x0000 0000 32 */ |
365 | #define SH4A_PCIEDMSAHR0 (0x021104) /* R/W R/W 0x0000 0000 32 */ | 345 | #define SH4A_PCIEDMSAHR0 (0x021104) /* R/W R/W 0x0000 0000 32 */ |