1/* $NetBSD: mainbus.c,v 1.28 2012/01/27 18:53:00 para 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.28 2012/01/27 18:53:00 para Exp $"); 35 36#include "opt_pci.h" 37#include "pci.h" 38 39#include <sys/param.h> 40#include <sys/extent.h> 41#include <sys/device.h> 42#include <sys/malloc.h> 43#include <sys/systm.h> 44 45#include <machine/autoconf.h> 46#include <machine/bootinfo.h> 47#include <machine/isa_machdep.h> 48 49#include <powerpc/oea/spr.h> 50 51#include <dev/pci/pcivar.h> 52#include <dev/pci/pciconf.h> 53 54int mainbus_match(device_t, cfdata_t, void *); 55void mainbus_attach(device_t, device_t, void *); 56int mainbus_print(void *, const char *); 57 58CFATTACH_DECL_NEW(mainbus, 0, 59 mainbus_match, mainbus_attach, NULL, NULL); 60 61struct powerpc_isa_chipset genppc_ict; 62 63/* 64 * Probe for the mainbus; always succeeds. 65 */ 66int 67mainbus_match(device_t parent, cfdata_t match, void *aux) 68{ 69 70 return 1; 71} 72 73/* 74 * Attach the mainbus. 75 */ 76void 77mainbus_attach(device_t parent, device_t self, void *aux) 78{ 79 struct mainbus_attach_args mba; 80 struct pcibus_attach_args pba; 81 struct btinfo_prodfamily *pfam; 82#if defined(PCI_NETBSD_CONFIGURE) 83 struct extent *ioext, *memext; 84#endif 85 86 aprint_naive("\n"); 87 aprint_normal("\n"); 88 89 mba.ma_name = "cpu"; 90 config_found_ia(self, "mainbus", &mba, mainbus_print); 91 92 mba.ma_name = "eumb"; 93 mba.ma_bst = &sandpoint_eumb_space_tag; 94 config_found_ia(self, "mainbus", &mba, mainbus_print); 95 96 pfam = lookup_bootinfo(BTINFO_PRODFAMILY); 97 if (pfam != NULL && strcmp(pfam->name, "nhnas") == 0) { 98 /* attach nhpow(4) for NH230/231 only */ 99 mba.ma_name = "nhpow"; 100 mba.ma_bst = &sandpoint_nhgpio_space_tag; 101 config_found_ia(self, "mainbus", &mba, mainbus_print); 102 } 103 104 mba.ma_name = "cfi"; 105 mba.ma_bst = &sandpoint_flash_space_tag; 106 mba.ma_addr = 0xffe00000; /* smallest flash is 2 MiB */ 107 config_found_ia(self, "mainbus", &mba, mainbus_print); 108 109 /* 110 * XXX Note also that the presence of a PCI bus should 111 * XXX _always_ be checked, and if present the bus should be 112 * XXX 'found'. However, because of the structure of the code, 113 * XXX that's not currently possible. 114 */ 115#if NPCI > 0 116#if defined(PCI_NETBSD_CONFIGURE) 117 ioext = extent_create("pciio", 0x00001000, 0x0000ffff, 118 NULL, 0, EX_NOWAIT); 119 memext = extent_create("pcimem", 0x80000000, 0x8fffffff, 120 NULL, 0, EX_NOWAIT); 121 122 pci_configure_bus(0, ioext, memext, NULL, 0, 32); 123 124 extent_destroy(ioext); 125 extent_destroy(memext); 126#endif 127 128 pba.pba_iot = &sandpoint_io_space_tag; 129 pba.pba_memt = &sandpoint_mem_space_tag; 130 pba.pba_dmat = &pci_bus_dma_tag; 131 pba.pba_dmat64 = NULL; 132 pba.pba_bus = 0; 133 pba.pba_pc = 0; 134 pba.pba_bridgetag = NULL; 135 pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY; 136 137 config_found_ia(self, "pcibus", &pba, pcibusprint); 138#endif 139} 140 141static int cpu_match(device_t, cfdata_t, void *); 142static void cpu_attach(device_t, device_t, void *); 143 144CFATTACH_DECL_NEW(cpu, 0, cpu_match, cpu_attach, NULL, NULL); 145 146extern struct cfdriver cpu_cd; 147 148int 149cpu_match(device_t parent, cfdata_t cf, void *aux) 150{ 151 struct mainbus_attach_args *mba = aux; 152 153 if (strcmp(mba->ma_name, cpu_cd.cd_name) != 0) 154 return 0; 155 156 if (cpu_info[0].ci_dev != NULL) 157 return 0; 158 159 return 1; 160} 161 162void 163cpu_attach(device_t parent, device_t self, void *aux) 164{ 165 static uint8_t mem_to_cpuclk[] = { 166 25, 30, 45, 20, 20, 00, 10, 30, 167 30, 20, 45, 30, 25, 35, 30, 35, 168 20, 25, 20, 30, 35, 40, 40, 20, 169 30, 25, 40, 30, 30, 25, 35, 00 170 }; 171 extern u_long ticks_per_sec; 172 struct cpu_info *ci; 173 u_int hid1, vers; 174 175 ci = cpu_attach_common(self, 0); 176 if (ci == NULL) 177 return; 178 179 vers = (mfpvr() >> 16) & 0xffff; 180 if (ci->ci_khz == 0 && vers == MPC8245) { 181 /* calculate speed from bus clock and PLL ratio */ 182 asm volatile ("mfspr %0,1009" : "=r"(hid1)); 183 ci->ci_khz = ((uint64_t)ticks_per_sec * 4 * 184 mem_to_cpuclk[hid1 >> 27] + 10) / 10000; 185 aprint_normal_dev(self, "%u.%02u MHz\n", 186 ci->ci_khz / 1000, (ci->ci_khz / 10) % 100); 187 } 188} 189 190int 191mainbus_print(void *aux, const char *pnp) 192{ 193 struct mainbus_attach_args *mba = aux; 194 195 if (pnp) 196 aprint_normal("%s at %s", mba->ma_name, pnp); 197 return UNCONF; 198} 199