1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * arch/sh64/mach-cayman/setup.c 7 * 8 * SH5 Cayman support 9 * 10 * This file handles the architecture-dependent parts of initialization 11 * 12 * Copyright David J. Mckay. 13 * Needs major work! 14 * 15 * benedict.gaster@superh.com: 3rd May 2002 16 * Added support for ramdisk, removing statically linked romfs at the same time. 17 * 18 * lethal@linux-sh.org: 15th May 2003 19 * Use the generic procfs cpuinfo interface, just return a valid board name. 20 */ 21 22#include <linux/stddef.h> 23#include <linux/init.h> 24#include <linux/mm.h> 25#include <linux/bootmem.h> 26#include <linux/delay.h> 27#include <linux/kernel.h> 28#include <linux/seq_file.h> 29#include <asm/processor.h> 30#include <asm/platform.h> 31#include <asm/io.h> 32#include <asm/irq.h> 33#include <asm/page.h> 34 35/* 36 * Platform Dependent Interrupt Priorities. 37 */ 38 39/* Using defaults defined in irq.h */ 40#define RES NO_PRIORITY /* Disabled */ 41#define IR0 IRL0_PRIORITY /* IRLs */ 42#define IR1 IRL1_PRIORITY 43#define IR2 IRL2_PRIORITY 44#define IR3 IRL3_PRIORITY 45#define PCA INTA_PRIORITY /* PCI Ints */ 46#define PCB INTB_PRIORITY 47#define PCC INTC_PRIORITY 48#define PCD INTD_PRIORITY 49#define SER TOP_PRIORITY 50#define ERR TOP_PRIORITY 51#define PW0 TOP_PRIORITY 52#define PW1 TOP_PRIORITY 53#define PW2 TOP_PRIORITY 54#define PW3 TOP_PRIORITY 55#define DM0 NO_PRIORITY /* DMA Ints */ 56#define DM1 NO_PRIORITY 57#define DM2 NO_PRIORITY 58#define DM3 NO_PRIORITY 59#define DAE NO_PRIORITY 60#define TU0 TIMER_PRIORITY /* TMU Ints */ 61#define TU1 NO_PRIORITY 62#define TU2 NO_PRIORITY 63#define TI2 NO_PRIORITY 64#define ATI NO_PRIORITY /* RTC Ints */ 65#define PRI NO_PRIORITY 66#define CUI RTC_PRIORITY 67#define ERI SCIF_PRIORITY /* SCIF Ints */ 68#define RXI SCIF_PRIORITY 69#define BRI SCIF_PRIORITY 70#define TXI SCIF_PRIORITY 71#define ITI TOP_PRIORITY /* WDT Ints */ 72 73/* Setup for the SMSC FDC37C935 */ 74#define SMSC_SUPERIO_BASE 0x04000000 75#define SMSC_CONFIG_PORT_ADDR 0x3f0 76#define SMSC_INDEX_PORT_ADDR SMSC_CONFIG_PORT_ADDR 77#define SMSC_DATA_PORT_ADDR 0x3f1 78 79#define SMSC_ENTER_CONFIG_KEY 0x55 80#define SMSC_EXIT_CONFIG_KEY 0xaa 81 82#define SMCS_LOGICAL_DEV_INDEX 0x07 83#define SMSC_DEVICE_ID_INDEX 0x20 84#define SMSC_DEVICE_REV_INDEX 0x21 85#define SMSC_ACTIVATE_INDEX 0x30 86#define SMSC_PRIMARY_BASE_INDEX 0x60 87#define SMSC_SECONDARY_BASE_INDEX 0x62 88#define SMSC_PRIMARY_INT_INDEX 0x70 89#define SMSC_SECONDARY_INT_INDEX 0x72 90 91#define SMSC_IDE1_DEVICE 1 92#define SMSC_KEYBOARD_DEVICE 7 93#define SMSC_CONFIG_REGISTERS 8 94 95#define SMSC_SUPERIO_READ_INDEXED(index) ({ \ 96 outb((index), SMSC_INDEX_PORT_ADDR); \ 97 inb(SMSC_DATA_PORT_ADDR); }) 98#define SMSC_SUPERIO_WRITE_INDEXED(val, index) ({ \ 99 outb((index), SMSC_INDEX_PORT_ADDR); \ 100 outb((val), SMSC_DATA_PORT_ADDR); }) 101 102#define IDE1_PRIMARY_BASE 0x01f0 103#define IDE1_SECONDARY_BASE 0x03f6 104 105unsigned long smsc_superio_virt; 106 107/* 108 * Platform dependent structures: maps and parms block. 109 */ 110struct resource io_resources[] = { 111 /* To be updated with external devices */ 112}; 113 114struct resource kram_resources[] = { 115 /* These must be last in the array */ 116 { .name = "Kernel code", .start = 0, .end = 0 }, 117 /* These must be last in the array */ 118 { .name = "Kernel data", .start = 0, .end = 0 } 119}; 120 121struct resource xram_resources[] = { 122 /* To be updated with external devices */ 123}; 124 125struct resource rom_resources[] = { 126 /* To be updated with external devices */ 127}; 128 129struct sh64_platform platform_parms = { 130 .readonly_rootfs = 1, 131 .initial_root_dev = 0x0100, 132 .loader_type = 1, 133 .io_res_p = io_resources, 134 .io_res_count = ARRAY_SIZE(io_resources), 135 .kram_res_p = kram_resources, 136 .kram_res_count = ARRAY_SIZE(kram_resources), 137 .xram_res_p = xram_resources, 138 .xram_res_count = ARRAY_SIZE(xram_resources), 139 .rom_res_p = rom_resources, 140 .rom_res_count = ARRAY_SIZE(rom_resources), 141}; 142 143int platform_int_priority[NR_INTC_IRQS] = { 144 IR0, IR1, IR2, IR3, PCA, PCB, PCC, PCD, /* IRQ 0- 7 */ 145 RES, RES, RES, RES, SER, ERR, PW3, PW2, /* IRQ 8-15 */ 146 PW1, PW0, DM0, DM1, DM2, DM3, DAE, RES, /* IRQ 16-23 */ 147 RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 24-31 */ 148 TU0, TU1, TU2, TI2, ATI, PRI, CUI, ERI, /* IRQ 32-39 */ 149 RXI, BRI, TXI, RES, RES, RES, RES, RES, /* IRQ 40-47 */ 150 RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 48-55 */ 151 RES, RES, RES, RES, RES, RES, RES, ITI, /* IRQ 56-63 */ 152}; 153 154static int __init smsc_superio_setup(void) 155{ 156 unsigned char devid, devrev; 157 158 smsc_superio_virt = onchip_remap(SMSC_SUPERIO_BASE, 1024, "SMSC SuperIO"); 159 if (!smsc_superio_virt) { 160 panic("Unable to remap SMSC SuperIO\n"); 161 } 162 163 /* Initially the chip is in run state */ 164 /* Put it into configuration state */ 165 outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR); 166 outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR); 167 168 /* Read device ID info */ 169 devid = SMSC_SUPERIO_READ_INDEXED(SMSC_DEVICE_ID_INDEX); 170 devrev = SMSC_SUPERIO_READ_INDEXED(SMSC_DEVICE_REV_INDEX); 171 printk("SMSC SuperIO devid %02x rev %02x\n", devid, devrev); 172 173 /* Select the keyboard device */ 174 SMSC_SUPERIO_WRITE_INDEXED(SMSC_KEYBOARD_DEVICE, SMCS_LOGICAL_DEV_INDEX); 175 176 /* enable it */ 177 SMSC_SUPERIO_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX); 178 179 /* Select the interrupts */ 180 /* On a PC keyboard is IRQ1, mouse is IRQ12 */ 181 SMSC_SUPERIO_WRITE_INDEXED(1, SMSC_PRIMARY_INT_INDEX); 182 SMSC_SUPERIO_WRITE_INDEXED(12, SMSC_SECONDARY_INT_INDEX); 183 184#ifdef CONFIG_IDE 185 /* 186 * Only IDE1 exists on the Cayman 187 */ 188 189 /* Power it on */ 190 SMSC_SUPERIO_WRITE_INDEXED(1 << SMSC_IDE1_DEVICE, 0x22); 191 192 SMSC_SUPERIO_WRITE_INDEXED(SMSC_IDE1_DEVICE, SMCS_LOGICAL_DEV_INDEX); 193 SMSC_SUPERIO_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX); 194 195 SMSC_SUPERIO_WRITE_INDEXED(IDE1_PRIMARY_BASE >> 8, 196 SMSC_PRIMARY_BASE_INDEX + 0); 197 SMSC_SUPERIO_WRITE_INDEXED(IDE1_PRIMARY_BASE & 0xff, 198 SMSC_PRIMARY_BASE_INDEX + 1); 199 200 SMSC_SUPERIO_WRITE_INDEXED(IDE1_SECONDARY_BASE >> 8, 201 SMSC_SECONDARY_BASE_INDEX + 0); 202 SMSC_SUPERIO_WRITE_INDEXED(IDE1_SECONDARY_BASE & 0xff, 203 SMSC_SECONDARY_BASE_INDEX + 1); 204 205 SMSC_SUPERIO_WRITE_INDEXED(14, SMSC_PRIMARY_INT_INDEX); 206 207 SMSC_SUPERIO_WRITE_INDEXED(SMSC_CONFIG_REGISTERS, 208 SMCS_LOGICAL_DEV_INDEX); 209 210 SMSC_SUPERIO_WRITE_INDEXED(0x00, 0xc2); /* GP42 = nIDE1_OE */ 211 SMSC_SUPERIO_WRITE_INDEXED(0x01, 0xc5); /* GP45 = IDE1_IRQ */ 212 SMSC_SUPERIO_WRITE_INDEXED(0x00, 0xc6); /* GP46 = nIOROP */ 213 SMSC_SUPERIO_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */ 214#endif 215 216 /* Exit the configuration state */ 217 outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR); 218 219 return 0; 220} 221 222/* This is grotty, but, because kernel is always referenced on the link line 223 * before any devices, this is safe. 224 */ 225__initcall(smsc_superio_setup); 226 227void __init platform_setup(void) 228{ 229 /* Cayman platform leaves the decision to head.S, for now */ 230 platform_parms.fpu_flags = fpu_in_use; 231} 232 233void __init platform_monitor(void) 234{ 235 /* Nothing yet .. */ 236} 237 238void __init platform_reserve(void) 239{ 240 /* Nothing yet .. */ 241} 242 243const char *get_system_type(void) 244{ 245 return "Hitachi Cayman"; 246} 247