xref: /OK3568_Linux_fs/kernel/arch/sh/drivers/pci/fixups-se7751.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun #include <linux/kernel.h>
3*4882a593Smuzhiyun #include <linux/types.h>
4*4882a593Smuzhiyun #include <linux/init.h>
5*4882a593Smuzhiyun #include <linux/delay.h>
6*4882a593Smuzhiyun #include <linux/pci.h>
7*4882a593Smuzhiyun #include <linux/io.h>
8*4882a593Smuzhiyun #include <linux/sh_intc.h>
9*4882a593Smuzhiyun #include "pci-sh4.h"
10*4882a593Smuzhiyun 
pcibios_map_platform_irq(const struct pci_dev *,u8 slot,u8 pin)11*4882a593Smuzhiyun int pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin)
12*4882a593Smuzhiyun {
13*4882a593Smuzhiyun         switch (slot) {
14*4882a593Smuzhiyun         case 0: return evt2irq(0x3a0);
15*4882a593Smuzhiyun         case 1: return evt2irq(0x3a0);	/* AMD Ethernet controller */
16*4882a593Smuzhiyun         case 2: return -1;
17*4882a593Smuzhiyun         case 3: return -1;
18*4882a593Smuzhiyun         case 4: return -1;
19*4882a593Smuzhiyun         default:
20*4882a593Smuzhiyun                 printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
21*4882a593Smuzhiyun                 return -1;
22*4882a593Smuzhiyun         }
23*4882a593Smuzhiyun }
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #define PCIMCR_MRSET_OFF	0xBFFFFFFF
26*4882a593Smuzhiyun #define PCIMCR_RFSH_OFF		0xFFFFFFFB
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun /*
29*4882a593Smuzhiyun  * Only long word accesses of the PCIC's internal local registers and the
30*4882a593Smuzhiyun  * configuration registers from the CPU is supported.
31*4882a593Smuzhiyun  */
32*4882a593Smuzhiyun #define PCIC_WRITE(x,v) writel((v), PCI_REG(x))
33*4882a593Smuzhiyun #define PCIC_READ(x) readl(PCI_REG(x))
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun /*
36*4882a593Smuzhiyun  * Description:  This function sets up and initializes the pcic, sets
37*4882a593Smuzhiyun  * up the BARS, maps the DRAM into the address space etc, etc.
38*4882a593Smuzhiyun  */
pci_fixup_pcic(struct pci_channel * chan)39*4882a593Smuzhiyun int pci_fixup_pcic(struct pci_channel *chan)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun 	unsigned long bcr1, wcr1, wcr2, wcr3, mcr;
42*4882a593Smuzhiyun 	unsigned short bcr2;
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun 	/*
45*4882a593Smuzhiyun 	* Initialize the slave bus controller on the pcic.  The values used
46*4882a593Smuzhiyun 	* here should not be hardcoded, but they should be taken from the bsc
47*4882a593Smuzhiyun 	* on the processor, to make this function as generic as possible.
48*4882a593Smuzhiyun 	* (i.e. Another sbc may usr different SDRAM timing settings -- in order
49*4882a593Smuzhiyun 	* for the pcic to work, its settings need to be exactly the same.)
50*4882a593Smuzhiyun 	*/
51*4882a593Smuzhiyun 	bcr1 = (*(volatile unsigned long*)(SH7751_BCR1));
52*4882a593Smuzhiyun 	bcr2 = (*(volatile unsigned short*)(SH7751_BCR2));
53*4882a593Smuzhiyun 	wcr1 = (*(volatile unsigned long*)(SH7751_WCR1));
54*4882a593Smuzhiyun 	wcr2 = (*(volatile unsigned long*)(SH7751_WCR2));
55*4882a593Smuzhiyun 	wcr3 = (*(volatile unsigned long*)(SH7751_WCR3));
56*4882a593Smuzhiyun 	mcr = (*(volatile unsigned long*)(SH7751_MCR));
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 	bcr1 = bcr1 | 0x00080000;  /* Enable Bit 19, BREQEN */
59*4882a593Smuzhiyun 	(*(volatile unsigned long*)(SH7751_BCR1)) = bcr1;
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	bcr1 = bcr1 | 0x40080000;  /* Enable Bit 19 BREQEN, set PCIC to slave */
62*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCIBCR1, bcr1);	 /* PCIC BCR1 */
63*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCIBCR2, bcr2);     /* PCIC BCR2 */
64*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCIWCR1, wcr1);     /* PCIC WCR1 */
65*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCIWCR2, wcr2);     /* PCIC WCR2 */
66*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCIWCR3, wcr3);     /* PCIC WCR3 */
67*4882a593Smuzhiyun 	mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
68*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCIMCR, mcr);      /* PCIC MCR */
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun 	/* Enable all interrupts, so we know what to fix */
72*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCIINTM, 0x0000c3ff);
73*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCIAINTM, 0x0000380f);
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	/* Set up standard PCI config registers */
76*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCICONF1,	0xF39000C7); /* Bus Master, Mem & I/O access */
77*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCICONF2,	0x00000000); /* PCI Class code & Revision ID */
78*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCICONF4,	0xab000001); /* PCI I/O address (local regs) */
79*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCICONF5,	0x0c000000); /* PCI MEM address (local RAM)  */
80*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCICONF6,	0xd0000000); /* PCI MEM address (unused)     */
81*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Subsystem ID & Vendor ID */
82*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCILSR0, 0x03f00000);   /* MEM (full 64M exposed)       */
83*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCILSR1, 0x00000000);   /* MEM (unused)                 */
84*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCILAR0, 0x0c000000);   /* MEM (direct map from PCI)    */
85*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCILAR1, 0x00000000);   /* MEM (unused)                 */
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	/* Now turn it on... */
88*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCICR, 0xa5000001);
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	/*
91*4882a593Smuzhiyun 	* Set PCIMBR and PCIIOBR here, assuming a single window
92*4882a593Smuzhiyun 	* (16M MEM, 256K IO) is enough.  If a larger space is
93*4882a593Smuzhiyun 	* needed, the readx/writex and inx/outx functions will
94*4882a593Smuzhiyun 	* have to do more (e.g. setting registers for each call).
95*4882a593Smuzhiyun 	*/
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 	/*
98*4882a593Smuzhiyun 	* Set the MBR so PCI address is one-to-one with window,
99*4882a593Smuzhiyun 	* meaning all calls go straight through... use BUG_ON to
100*4882a593Smuzhiyun 	* catch erroneous assumption.
101*4882a593Smuzhiyun 	*/
102*4882a593Smuzhiyun 	BUG_ON(chan->resources[1].start != SH7751_PCI_MEMORY_BASE);
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCIMBR, chan->resources[1].start);
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	/* Set IOBR for window containing area specified in pci.h */
107*4882a593Smuzhiyun 	PCIC_WRITE(SH7751_PCIIOBR, (chan->resources[0].start & SH7751_PCIIOBR_MASK));
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	/* All done, may as well say so... */
110*4882a593Smuzhiyun 	printk("SH7751 PCI: Finished initialization of the PCI controller\n");
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	return 1;
113*4882a593Smuzhiyun }
114