xref: /OK3568_Linux_fs/kernel/arch/mips/pci/fixup-fuloong2e.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2004 ICT CAS
4*4882a593Smuzhiyun  * Author: Li xiaoyu, ICT CAS
5*4882a593Smuzhiyun  *   lixy@ict.ac.cn
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
8*4882a593Smuzhiyun  * Author: Fuxin Zhang, zhangfx@lemote.com
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun #include <linux/init.h>
11*4882a593Smuzhiyun #include <linux/pci.h>
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include <loongson.h>
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun /* South bridge slot number is set by the pci probe process */
16*4882a593Smuzhiyun static u8 sb_slot = 5;
17*4882a593Smuzhiyun 
pcibios_map_irq(const struct pci_dev * dev,u8 slot,u8 pin)18*4882a593Smuzhiyun int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
19*4882a593Smuzhiyun {
20*4882a593Smuzhiyun 	int irq = 0;
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun 	if (slot == sb_slot) {
23*4882a593Smuzhiyun 		switch (PCI_FUNC(dev->devfn)) {
24*4882a593Smuzhiyun 		case 2:
25*4882a593Smuzhiyun 			irq = 10;
26*4882a593Smuzhiyun 			break;
27*4882a593Smuzhiyun 		case 3:
28*4882a593Smuzhiyun 			irq = 11;
29*4882a593Smuzhiyun 			break;
30*4882a593Smuzhiyun 		case 5:
31*4882a593Smuzhiyun 			irq = 9;
32*4882a593Smuzhiyun 			break;
33*4882a593Smuzhiyun 		}
34*4882a593Smuzhiyun 	} else {
35*4882a593Smuzhiyun 		irq = LOONGSON_IRQ_BASE + 25 + pin;
36*4882a593Smuzhiyun 	}
37*4882a593Smuzhiyun 	return irq;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun }
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /* Do platform specific device initialization at pci_enable_device() time */
pcibios_plat_dev_init(struct pci_dev * dev)42*4882a593Smuzhiyun int pcibios_plat_dev_init(struct pci_dev *dev)
43*4882a593Smuzhiyun {
44*4882a593Smuzhiyun 	return 0;
45*4882a593Smuzhiyun }
46*4882a593Smuzhiyun 
loongson2e_nec_fixup(struct pci_dev * pdev)47*4882a593Smuzhiyun static void loongson2e_nec_fixup(struct pci_dev *pdev)
48*4882a593Smuzhiyun {
49*4882a593Smuzhiyun 	unsigned int val;
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	/* Configures port 1, 2, 3, 4 to be validate*/
52*4882a593Smuzhiyun 	pci_read_config_dword(pdev, 0xe0, &val);
53*4882a593Smuzhiyun 	pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x4);
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	/* System clock is 48-MHz Oscillator. */
56*4882a593Smuzhiyun 	pci_write_config_dword(pdev, 0xe4, 1 << 5);
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun 
loongson2e_686b_func0_fixup(struct pci_dev * pdev)59*4882a593Smuzhiyun static void loongson2e_686b_func0_fixup(struct pci_dev *pdev)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun 	unsigned char c;
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun 	sb_slot = PCI_SLOT(pdev->devfn);
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 	printk(KERN_INFO "via686b fix: ISA bridge\n");
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	/*  Enable I/O Recovery time */
68*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x40, 0x08);
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun 	/*  Enable ISA refresh */
71*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x41, 0x01);
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	/*  disable ISA line buffer */
74*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x45, 0x00);
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	/*  Gate INTR, and flush line buffer */
77*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x46, 0xe0);
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	/*  Disable PCI Delay Transaction, Enable EISA ports 4D0/4D1. */
80*4882a593Smuzhiyun 	/* pci_write_config_byte(pdev, 0x47, 0x20); */
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	/*
83*4882a593Smuzhiyun 	 *  enable PCI Delay Transaction, Enable EISA ports 4D0/4D1.
84*4882a593Smuzhiyun 	 *  enable time-out timer
85*4882a593Smuzhiyun 	 */
86*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x47, 0xe6);
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	/*
89*4882a593Smuzhiyun 	 * enable level trigger on pci irqs: 9,10,11,13
90*4882a593Smuzhiyun 	 * important! without this PCI interrupts won't work
91*4882a593Smuzhiyun 	 */
92*4882a593Smuzhiyun 	outb(0x2e, 0x4d1);
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	/*  512 K PCI Decode */
95*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x48, 0x01);
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 	/*  Wait for PGNT before grant to ISA Master/DMA */
98*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x4a, 0x84);
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	/*
101*4882a593Smuzhiyun 	 * Plug'n'Play
102*4882a593Smuzhiyun 	 *
103*4882a593Smuzhiyun 	 *  Parallel DRQ 3, Floppy DRQ 2 (default)
104*4882a593Smuzhiyun 	 */
105*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x50, 0x0e);
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	/*
108*4882a593Smuzhiyun 	 * IRQ Routing for Floppy and Parallel port
109*4882a593Smuzhiyun 	 *
110*4882a593Smuzhiyun 	 *  IRQ 6 for floppy, IRQ 7 for parallel port
111*4882a593Smuzhiyun 	 */
112*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x51, 0x76);
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	/* IRQ Routing for serial ports (take IRQ 3 and 4) */
115*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x52, 0x34);
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 	/*  All IRQ's level triggered. */
118*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x54, 0x00);
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	/* route PIRQA-D irq */
121*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x55, 0x90);	/* bit 7-4, PIRQA */
122*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x56, 0xba);	/* bit 7-4, PIRQC; */
123*4882a593Smuzhiyun 							/* 3-0, PIRQB */
124*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x57, 0xd0);	/* bit 7-4, PIRQD */
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	/* enable function 5/6, audio/modem */
127*4882a593Smuzhiyun 	pci_read_config_byte(pdev, 0x85, &c);
128*4882a593Smuzhiyun 	c &= ~(0x3 << 2);
129*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x85, c);
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	printk(KERN_INFO"via686b fix: ISA bridge done\n");
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun 
loongson2e_686b_func1_fixup(struct pci_dev * pdev)134*4882a593Smuzhiyun static void loongson2e_686b_func1_fixup(struct pci_dev *pdev)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun 	printk(KERN_INFO"via686b fix: IDE\n");
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	/* Modify IDE controller setup */
139*4882a593Smuzhiyun 	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 48);
140*4882a593Smuzhiyun 	pci_write_config_byte(pdev, PCI_COMMAND,
141*4882a593Smuzhiyun 			      PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
142*4882a593Smuzhiyun 			      PCI_COMMAND_MASTER);
143*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x40, 0x0b);
144*4882a593Smuzhiyun 	/* legacy mode */
145*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x42, 0x09);
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun #if 1/* play safe, otherwise we may see notebook's usb keyboard lockup */
148*4882a593Smuzhiyun 	/* disable read prefetch/write post buffers */
149*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x41, 0x02);
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	/* use 3/4 as fifo thresh hold	*/
152*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x43, 0x0a);
153*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x44, 0x00);
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x45, 0x00);
156*4882a593Smuzhiyun #else
157*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x41, 0xc2);
158*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x43, 0x35);
159*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x44, 0x1c);
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x45, 0x10);
162*4882a593Smuzhiyun #endif
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	printk(KERN_INFO"via686b fix: IDE done\n");
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun 
loongson2e_686b_func2_fixup(struct pci_dev * pdev)167*4882a593Smuzhiyun static void loongson2e_686b_func2_fixup(struct pci_dev *pdev)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun 	/* irq routing */
170*4882a593Smuzhiyun 	pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 10);
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun 
loongson2e_686b_func3_fixup(struct pci_dev * pdev)173*4882a593Smuzhiyun static void loongson2e_686b_func3_fixup(struct pci_dev *pdev)
174*4882a593Smuzhiyun {
175*4882a593Smuzhiyun 	/* irq routing */
176*4882a593Smuzhiyun 	pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 11);
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun 
loongson2e_686b_func5_fixup(struct pci_dev * pdev)179*4882a593Smuzhiyun static void loongson2e_686b_func5_fixup(struct pci_dev *pdev)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun 	unsigned int val;
182*4882a593Smuzhiyun 	unsigned char c;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	/* enable IO */
185*4882a593Smuzhiyun 	pci_write_config_byte(pdev, PCI_COMMAND,
186*4882a593Smuzhiyun 			      PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
187*4882a593Smuzhiyun 			      PCI_COMMAND_MASTER);
188*4882a593Smuzhiyun 	pci_read_config_dword(pdev, 0x4, &val);
189*4882a593Smuzhiyun 	pci_write_config_dword(pdev, 0x4, val | 1);
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	/* route ac97 IRQ */
192*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x3c, 9);
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	pci_read_config_byte(pdev, 0x8, &c);
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	/* link control: enable link & SGD PCM output */
197*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x41, 0xcc);
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	/* disable game port, FM, midi, sb, enable write to reg2c-2f */
200*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x42, 0x20);
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	/* we are using Avance logic codec */
203*4882a593Smuzhiyun 	pci_write_config_word(pdev, 0x2c, 0x1005);
204*4882a593Smuzhiyun 	pci_write_config_word(pdev, 0x2e, 0x4710);
205*4882a593Smuzhiyun 	pci_read_config_dword(pdev, 0x2c, &val);
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	pci_write_config_byte(pdev, 0x42, 0x0);
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686,
211*4882a593Smuzhiyun 			 loongson2e_686b_func0_fixup);
212*4882a593Smuzhiyun DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
213*4882a593Smuzhiyun 			 loongson2e_686b_func1_fixup);
214*4882a593Smuzhiyun DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2,
215*4882a593Smuzhiyun 			 loongson2e_686b_func2_fixup);
216*4882a593Smuzhiyun DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3,
217*4882a593Smuzhiyun 			 loongson2e_686b_func3_fixup);
218*4882a593Smuzhiyun DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5,
219*4882a593Smuzhiyun 			 loongson2e_686b_func5_fixup);
220*4882a593Smuzhiyun DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
221*4882a593Smuzhiyun 			 loongson2e_nec_fixup);
222