1 /* $NetBSD: mainbus.c,v 1.35 2023/12/20 15:29:07 thorpej Exp $ */
2
3 /*
4 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Christopher G. Demetriou
17 * for the NetBSD Project.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.35 2023/12/20 15:29:07 thorpej Exp $");
35
36 #include "opt_pci.h"
37 #include "pci.h"
38
39 #include <sys/param.h>
40 #include <sys/device.h>
41 #include <sys/systm.h>
42
43 #include <machine/autoconf.h>
44 #include <machine/bootinfo.h>
45 #include <machine/isa_machdep.h>
46
47 #include <powerpc/oea/spr.h>
48
49 #include <dev/pci/pcivar.h>
50 #include <dev/pci/pciconf.h>
51
52 int mainbus_match(device_t, cfdata_t, void *);
53 void mainbus_attach(device_t, device_t, void *);
54 int mainbus_print(void *, const char *);
55
56 CFATTACH_DECL_NEW(mainbus, 0,
57 mainbus_match, mainbus_attach, NULL, NULL);
58
59 struct powerpc_isa_chipset genppc_ict;
60
61 #define PCI_IO_START 0x00001000
62 #define PCI_IO_END 0x0000ffff
63 #define PCI_IO_SIZE ((PCI_IO_END - PCI_IO_START) + 1)
64
65 #define PCI_MEM_START 0x80000000U
66 #define PCI_MEM_END 0x8fffffffU
67 #define PCI_MEM_SIZE ((PCI_MEM_END - PCI_MEM_START) + 1)
68
69 /*
70 * Probe for the mainbus; always succeeds.
71 */
72 int
mainbus_match(device_t parent,cfdata_t match,void * aux)73 mainbus_match(device_t parent, cfdata_t match, void *aux)
74 {
75
76 return 1;
77 }
78
79 /*
80 * Attach the mainbus.
81 */
82 void
mainbus_attach(device_t parent,device_t self,void * aux)83 mainbus_attach(device_t parent, device_t self, void *aux)
84 {
85 struct mainbus_attach_args mba;
86 struct pcibus_attach_args pba;
87 struct btinfo_prodfamily *pfam;
88
89 aprint_naive("\n");
90 aprint_normal("\n");
91
92 mba.ma_name = "cpu";
93 config_found(self, &mba, mainbus_print,
94 CFARGS(.iattr = "mainbus"));
95
96 mba.ma_name = "eumb";
97 mba.ma_bst = &sandpoint_eumb_space_tag;
98 config_found(self, &mba, mainbus_print,
99 CFARGS(.iattr = "mainbus"));
100
101 pfam = lookup_bootinfo(BTINFO_PRODFAMILY);
102 if (pfam != NULL && strcmp(pfam->name, "nhnas") == 0) {
103 /* attach nhpow(4) for NH230/231 only */
104 mba.ma_name = "nhpow";
105 mba.ma_bst = &sandpoint_nhgpio_space_tag;
106 config_found(self, &mba, mainbus_print,
107 CFARGS(.iattr = "mainbus"));
108 }
109
110 mba.ma_name = "cfi";
111 mba.ma_bst = &sandpoint_flash_space_tag;
112 config_found(self, &mba, mainbus_print,
113 CFARGS(.iattr = "mainbus"));
114
115 /*
116 * XXX Note also that the presence of a PCI bus should
117 * XXX _always_ be checked, and if present the bus should be
118 * XXX 'found'. However, because of the structure of the code,
119 * XXX that's not currently possible.
120 */
121 #if NPCI > 0
122 #if defined(PCI_NETBSD_CONFIGURE)
123 struct pciconf_resources *pcires = pciconf_resource_init();
124
125 pciconf_resource_add(pcires, PCICONF_RESOURCE_IO,
126 PCI_IO_START, PCI_IO_SIZE);
127 pciconf_resource_add(pcires, PCICONF_RESOURCE_MEM,
128 PCI_MEM_START, PCI_MEM_SIZE);
129
130 pci_configure_bus(0, pcires, 0, 32);
131
132 pciconf_resource_fini(pcires);
133 #endif
134
135 pba.pba_iot = &sandpoint_io_space_tag;
136 pba.pba_memt = &sandpoint_mem_space_tag;
137 pba.pba_dmat = &pci_bus_dma_tag;
138 pba.pba_dmat64 = NULL;
139 pba.pba_bus = 0;
140 pba.pba_pc = 0;
141 pba.pba_bridgetag = NULL;
142 pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;
143
144 config_found(self, &pba, pcibusprint,
145 CFARGS(.iattr = "pcibus"));
146 #endif
147 }
148
149 static int cpu_match(device_t, cfdata_t, void *);
150 static void cpu_attach(device_t, device_t, void *);
151
152 CFATTACH_DECL_NEW(cpu, 0, cpu_match, cpu_attach, NULL, NULL);
153
154 extern struct cfdriver cpu_cd;
155
156 int
cpu_match(device_t parent,cfdata_t cf,void * aux)157 cpu_match(device_t parent, cfdata_t cf, void *aux)
158 {
159 struct mainbus_attach_args *mba = aux;
160
161 if (strcmp(mba->ma_name, cpu_cd.cd_name) != 0)
162 return 0;
163
164 if (cpu_info[0].ci_dev != NULL)
165 return 0;
166
167 return 1;
168 }
169
170 void
cpu_attach(device_t parent,device_t self,void * aux)171 cpu_attach(device_t parent, device_t self, void *aux)
172 {
173 static uint8_t mem_to_cpuclk[] = {
174 25, 30, 45, 20, 20, 00, 10, 30,
175 30, 20, 45, 30, 25, 35, 30, 35,
176 20, 25, 20, 30, 35, 40, 40, 20,
177 30, 25, 40, 30, 30, 25, 35, 00
178 };
179 extern u_long ticks_per_sec;
180 struct cpu_info *ci;
181 u_int hid1, vers;
182
183 ci = cpu_attach_common(self, 0);
184 if (ci == NULL)
185 return;
186
187 vers = (mfpvr() >> 16) & 0xffff;
188 if (ci->ci_khz == 0 && vers == MPC8245) {
189 /* calculate speed from bus clock and PLL ratio */
190 asm volatile ("mfspr %0,1009" : "=r"(hid1));
191 ci->ci_khz = ((uint64_t)ticks_per_sec * 4 *
192 mem_to_cpuclk[hid1 >> 27] + 10) / 10000;
193 aprint_normal_dev(self, "%u.%02u MHz\n",
194 ci->ci_khz / 1000, (ci->ci_khz / 10) % 100);
195 }
196 }
197
198 int
mainbus_print(void * aux,const char * pnp)199 mainbus_print(void *aux, const char *pnp)
200 {
201 struct mainbus_attach_args *mba = aux;
202
203 if (pnp)
204 aprint_normal("%s at %s", mba->ma_name, pnp);
205 return UNCONF;
206 }
207