1 /* 2 * Carsten Langgaard, carstenl@mips.com 3 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. 4 * Copyright (C) 2008 Dmitri Vorobiev 5 * 6 * This program is free software; you can distribute it and/or modify it 7 * under the terms of the GNU General Public License (Version 2) as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 18 */ 19 #include <linux/cpu.h> 20 #include <linux/init.h> 21 #include <linux/sched.h> 22 #include <linux/ioport.h> 23 #include <linux/irq.h> 24 #include <linux/of_fdt.h> 25 #include <linux/pci.h> 26 #include <linux/screen_info.h> 27 #include <linux/time.h> 28 29 #include <asm/fw/fw.h> 30 #include <asm/mips-cm.h> 31 #include <asm/mips-boards/generic.h> 32 #include <asm/mips-boards/malta.h> 33 #include <asm/mips-boards/maltaint.h> 34 #include <asm/dma.h> 35 #include <asm/prom.h> 36 #include <asm/traps.h> 37 #ifdef CONFIG_VT 38 #include <linux/console.h> 39 #endif 40 41 extern void malta_be_init(void); 42 extern int malta_be_handler(struct pt_regs *regs, int is_fixup); 43 44 static struct resource standard_io_resources[] = { 45 { 46 .name = "dma1", 47 .start = 0x00, 48 .end = 0x1f, 49 .flags = IORESOURCE_BUSY 50 }, 51 { 52 .name = "timer", 53 .start = 0x40, 54 .end = 0x5f, 55 .flags = IORESOURCE_BUSY 56 }, 57 { 58 .name = "keyboard", 59 .start = 0x60, 60 .end = 0x6f, 61 .flags = IORESOURCE_BUSY 62 }, 63 { 64 .name = "dma page reg", 65 .start = 0x80, 66 .end = 0x8f, 67 .flags = IORESOURCE_BUSY 68 }, 69 { 70 .name = "dma2", 71 .start = 0xc0, 72 .end = 0xdf, 73 .flags = IORESOURCE_BUSY 74 }, 75 }; 76 77 const char *get_system_type(void) 78 { 79 return "MIPS Malta"; 80 } 81 82 const char display_string[] = " LINUX ON MALTA "; 83 84 #ifdef CONFIG_BLK_DEV_FD 85 static void __init fd_activate(void) 86 { 87 /* 88 * Activate Floppy Controller in the SMSC FDC37M817 Super I/O 89 * Controller. 90 * Done by YAMON 2.00 onwards 91 */ 92 /* Entering config state. */ 93 SMSC_WRITE(SMSC_CONFIG_ENTER, SMSC_CONFIG_REG); 94 95 /* Activate floppy controller. */ 96 SMSC_WRITE(SMSC_CONFIG_DEVNUM, SMSC_CONFIG_REG); 97 SMSC_WRITE(SMSC_CONFIG_DEVNUM_FLOPPY, SMSC_DATA_REG); 98 SMSC_WRITE(SMSC_CONFIG_ACTIVATE, SMSC_CONFIG_REG); 99 SMSC_WRITE(SMSC_CONFIG_ACTIVATE_ENABLE, SMSC_DATA_REG); 100 101 /* Exit config state. */ 102 SMSC_WRITE(SMSC_CONFIG_EXIT, SMSC_CONFIG_REG); 103 } 104 #endif 105 106 static int __init plat_enable_iocoherency(void) 107 { 108 int supported = 0; 109 if (mips_revision_sconid == MIPS_REVISION_SCON_BONITO) { 110 if (BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES) { 111 BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_CPUCOH_EN; 112 pr_info("Enabled Bonito CPU coherency\n"); 113 supported = 1; 114 } 115 if (strstr(fw_getcmdline(), "iobcuncached")) { 116 BONITO_PCICACHECTRL &= ~BONITO_PCICACHECTRL_IOBCCOH_EN; 117 BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & 118 ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | 119 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); 120 pr_info("Disabled Bonito IOBC coherency\n"); 121 } else { 122 BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_IOBCCOH_EN; 123 BONITO_PCIMEMBASECFG |= 124 (BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | 125 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); 126 pr_info("Enabled Bonito IOBC coherency\n"); 127 } 128 } else if (mips_cm_numiocu() != 0) { 129 /* Nothing special needs to be done to enable coherency */ 130 pr_info("CMP IOCU detected\n"); 131 if ((*(unsigned int *)0xbf403000 & 0x81) != 0x81) { 132 pr_crit("IOCU OPERATION DISABLED BY SWITCH - DEFAULTING TO SW IO COHERENCY\n"); 133 return 0; 134 } 135 supported = 1; 136 } 137 hw_coherentio = supported; 138 return supported; 139 } 140 141 static void __init plat_setup_iocoherency(void) 142 { 143 #ifdef CONFIG_DMA_NONCOHERENT 144 /* 145 * Kernel has been configured with software coherency 146 * but we might choose to turn it off and use hardware 147 * coherency instead. 148 */ 149 if (plat_enable_iocoherency()) { 150 if (coherentio == 0) 151 pr_info("Hardware DMA cache coherency disabled\n"); 152 else 153 pr_info("Hardware DMA cache coherency enabled\n"); 154 } else { 155 if (coherentio == 1) 156 pr_info("Hardware DMA cache coherency unsupported, but enabled from command line!\n"); 157 else 158 pr_info("Software DMA cache coherency enabled\n"); 159 } 160 #else 161 if (!plat_enable_iocoherency()) 162 panic("Hardware DMA cache coherency not supported!"); 163 #endif 164 } 165 166 static void __init pci_clock_check(void) 167 { 168 unsigned int __iomem *jmpr_p = 169 (unsigned int *) ioremap(MALTA_JMPRS_REG, sizeof(unsigned int)); 170 int jmpr = (__raw_readl(jmpr_p) >> 2) & 0x07; 171 static const int pciclocks[] __initconst = { 172 33, 20, 25, 30, 12, 16, 37, 10 173 }; 174 int pciclock = pciclocks[jmpr]; 175 char *optptr, *argptr = fw_getcmdline(); 176 177 /* 178 * If user passed a pci_clock= option, don't tack on another one 179 */ 180 optptr = strstr(argptr, "pci_clock="); 181 if (optptr && (optptr == argptr || optptr[-1] == ' ')) 182 return; 183 184 if (pciclock != 33) { 185 pr_warn("WARNING: PCI clock is %dMHz, setting pci_clock\n", 186 pciclock); 187 argptr += strlen(argptr); 188 sprintf(argptr, " pci_clock=%d", pciclock); 189 if (pciclock < 20 || pciclock > 66) 190 pr_warn("WARNING: IDE timing calculations will be " 191 "incorrect\n"); 192 } 193 } 194 195 #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) 196 static void __init screen_info_setup(void) 197 { 198 screen_info = (struct screen_info) { 199 .orig_x = 0, 200 .orig_y = 25, 201 .ext_mem_k = 0, 202 .orig_video_page = 0, 203 .orig_video_mode = 0, 204 .orig_video_cols = 80, 205 .unused2 = 0, 206 .orig_video_ega_bx = 0, 207 .unused3 = 0, 208 .orig_video_lines = 25, 209 .orig_video_isVGA = VIDEO_TYPE_VGAC, 210 .orig_video_points = 16 211 }; 212 } 213 #endif 214 215 static void __init bonito_quirks_setup(void) 216 { 217 char *argptr; 218 219 argptr = fw_getcmdline(); 220 if (strstr(argptr, "debug")) { 221 BONITO_BONGENCFG |= BONITO_BONGENCFG_DEBUGMODE; 222 pr_info("Enabled Bonito debug mode\n"); 223 } else 224 BONITO_BONGENCFG &= ~BONITO_BONGENCFG_DEBUGMODE; 225 226 #ifdef CONFIG_DMA_COHERENT 227 if (BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES) { 228 BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_CPUCOH_EN; 229 pr_info("Enabled Bonito CPU coherency\n"); 230 231 argptr = fw_getcmdline(); 232 if (strstr(argptr, "iobcuncached")) { 233 BONITO_PCICACHECTRL &= ~BONITO_PCICACHECTRL_IOBCCOH_EN; 234 BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & 235 ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | 236 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); 237 pr_info("Disabled Bonito IOBC coherency\n"); 238 } else { 239 BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_IOBCCOH_EN; 240 BONITO_PCIMEMBASECFG |= 241 (BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | 242 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); 243 pr_info("Enabled Bonito IOBC coherency\n"); 244 } 245 } else 246 panic("Hardware DMA cache coherency not supported"); 247 #endif 248 } 249 250 void __init plat_mem_setup(void) 251 { 252 unsigned int i; 253 254 __dt_setup_arch(__dtb_start); 255 256 if (config_enabled(CONFIG_EVA)) 257 /* EVA has already been configured in mach-malta/kernel-init.h */ 258 pr_info("Enhanced Virtual Addressing (EVA) activated\n"); 259 260 mips_pcibios_init(); 261 262 /* Request I/O space for devices used on the Malta board. */ 263 for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) 264 request_resource(&ioport_resource, standard_io_resources+i); 265 266 /* 267 * Enable DMA channel 4 (cascade channel) in the PIIX4 south bridge. 268 */ 269 enable_dma(4); 270 271 #ifdef CONFIG_DMA_COHERENT 272 if (mips_revision_sconid != MIPS_REVISION_SCON_BONITO) 273 panic("Hardware DMA cache coherency not supported"); 274 #endif 275 276 if (mips_revision_sconid == MIPS_REVISION_SCON_BONITO) 277 bonito_quirks_setup(); 278 279 plat_setup_iocoherency(); 280 281 pci_clock_check(); 282 283 #ifdef CONFIG_BLK_DEV_FD 284 fd_activate(); 285 #endif 286 287 #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) 288 screen_info_setup(); 289 #endif 290 291 board_be_init = malta_be_init; 292 board_be_handler = malta_be_handler; 293 } 294