]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/dave/common/pci.c
ARM: highbank: use default prompt
[karo-tx-uboot.git] / board / dave / common / pci.c
1 /*
2  * (C) Copyright 2001
3  * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <asm/ppc4xx.h>
10 #include <asm/processor.h>
11 #include <pci.h>
12
13
14 u_long pci9054_iobase;
15
16
17 #define PCI_PRIMARY_CAR (0x500000dc) /* PCI config address reg */
18 #define PCI_PRIMARY_CDR (0x80000000) /* PCI config data    reg */
19
20
21 /*-----------------------------------------------------------------------------+
22 |  Subroutine:  pci9054_read_config_dword
23 |  Description: Read a PCI configuration register
24 |  Inputs:
25 |               hose            PCI Controller
26 |               dev             PCI Bus+Device+Function number
27 |               offset          Configuration register number
28 |               value           Address of the configuration register value
29 |  Return value:
30 |               0               Successful
31 +-----------------------------------------------------------------------------*/
32 int pci9054_read_config_dword(struct pci_controller *hose,
33                               pci_dev_t dev, int offset, u32* value)
34 {
35   unsigned long      conAdrVal;
36   unsigned long      val;
37
38   /* generate coded value for CON_ADR register */
39   conAdrVal = dev | (offset & 0xfc) | 0x80000000;
40
41   /* Load the CON_ADR (CAR) value first, then read from CON_DATA (CDR) */
42   *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal;
43
44   /* Note: *pResult comes back as -1 if machine check happened */
45   val = in32r(PCI_PRIMARY_CDR);
46
47   *value = (unsigned long) val;
48
49   out32r(PCI_PRIMARY_CAR, 0);
50
51   if ((*(unsigned long *)0x50000304) & 0x60000000)
52     {
53       /* clear pci master/target abort bits */
54       *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304;
55     }
56
57   return 0;
58 }
59
60 /*-----------------------------------------------------------------------------+
61 |  Subroutine:  pci9054_write_config_dword
62 |  Description: Write a PCI configuration register.
63 |  Inputs:
64 |               hose            PCI Controller
65 |               dev             PCI Bus+Device+Function number
66 |               offset          Configuration register number
67 |               Value           Configuration register value
68 |  Return value:
69 |               0               Successful
70 | Updated for pass2 errata #6. Need to disable interrupts and clear the
71 | PCICFGADR reg after writing the PCICFGDATA reg.
72 +-----------------------------------------------------------------------------*/
73 int pci9054_write_config_dword(struct pci_controller *hose,
74                                pci_dev_t dev, int offset, u32 value)
75 {
76   unsigned long      conAdrVal;
77
78   conAdrVal = dev | (offset & 0xfc) | 0x80000000;
79
80   *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal;
81
82   out32r(PCI_PRIMARY_CDR, value);
83
84   out32r(PCI_PRIMARY_CAR, 0);
85
86   /* clear pci master/target abort bits */
87   *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304;
88
89   return (0);
90 }
91
92 /*-----------------------------------------------------------------------
93  */
94
95 #ifdef CONFIG_DASA_SIM
96 static void pci_dasa_sim_config_pci9054(struct pci_controller *hose, pci_dev_t dev,
97                                         struct pci_config_table *_)
98 {
99   unsigned int iobase;
100   unsigned short status = 0;
101   unsigned char timer;
102
103   /*
104    * Configure PLX PCI9054
105    */
106   pci_read_config_word(CONFIG_SYS_PCI9054_DEV_FN, PCI_COMMAND, &status);
107   status |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
108   pci_write_config_word(CONFIG_SYS_PCI9054_DEV_FN, PCI_COMMAND, status);
109
110   /* Check the latency timer for values >= 0x60.
111    */
112   pci_read_config_byte(CONFIG_SYS_PCI9054_DEV_FN, PCI_LATENCY_TIMER, &timer);
113   if (timer < 0x60)
114     {
115       pci_write_config_byte(CONFIG_SYS_PCI9054_DEV_FN, PCI_LATENCY_TIMER, 0x60);
116     }
117
118   /* Set I/O base register.
119    */
120   pci_write_config_dword(CONFIG_SYS_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, CONFIG_SYS_PCI9054_IOBASE);
121   pci_read_config_dword(CONFIG_SYS_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, &iobase);
122
123   pci9054_iobase = pci_mem_to_phys(CONFIG_SYS_PCI9054_DEV_FN, iobase & PCI_BASE_ADDRESS_MEM_MASK);
124
125   if (pci9054_iobase == 0xffffffff)
126     {
127       printf("Error: Can not set I/O base register.\n");
128       return;
129     }
130 }
131 #endif
132
133 static struct pci_config_table pci9054_config_table[] = {
134 #ifndef CONFIG_PCI_PNP
135   { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
136     PCI_BUS(CONFIG_SYS_ETH_DEV_FN), PCI_DEV(CONFIG_SYS_ETH_DEV_FN), PCI_FUNC(CONFIG_SYS_ETH_DEV_FN),
137     pci_cfgfunc_config_device, { CONFIG_SYS_ETH_IOBASE,
138                                  CONFIG_SYS_ETH_IOBASE,
139                                  PCI_COMMAND_IO | PCI_COMMAND_MASTER }},
140 #ifdef CONFIG_DASA_SIM
141   { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
142     PCI_BUS(CONFIG_SYS_PCI9054_DEV_FN), PCI_DEV(CONFIG_SYS_PCI9054_DEV_FN), PCI_FUNC(CONFIG_SYS_PCI9054_DEV_FN),
143     pci_dasa_sim_config_pci9054 },
144 #endif
145 #endif
146   { }
147 };
148
149 static struct pci_controller pci9054_hose = {
150   config_table: pci9054_config_table,
151 };
152
153 void pci_init(void)
154 {
155   struct pci_controller *hose = &pci9054_hose;
156
157   /*
158    * Register the hose
159    */
160   hose->first_busno = 0;
161   hose->last_busno = 0xff;
162
163   /* System memory space */
164   pci_set_region(hose->regions + 0,
165                  0x00000000, 0x00000000, 0x01000000,
166                  PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
167
168   /* PCI Memory space */
169   pci_set_region(hose->regions + 1,
170                  0x00000000, 0xc0000000, 0x10000000,
171                  PCI_REGION_MEM);
172
173   pci_set_ops(hose,
174               pci_hose_read_config_byte_via_dword,
175               pci_hose_read_config_word_via_dword,
176               pci9054_read_config_dword,
177               pci_hose_write_config_byte_via_dword,
178               pci_hose_write_config_word_via_dword,
179               pci9054_write_config_dword);
180
181   hose->region_count = 2;
182
183   pci_register_hose(hose);
184
185   hose->last_busno = pci_hose_scan(hose);
186 }