0001
0002
0003
0004
0005
0006
0007 #include <linux/init.h>
0008 #include <linux/ioport.h>
0009 #include <linux/irq.h>
0010 #include <linux/memblock.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/platform_data/simplefb.h>
0013 #include <linux/string.h>
0014
0015 #include <asm/bootinfo.h>
0016 #include <asm/fw/fw.h>
0017 #include <asm/time.h>
0018
0019 #define IO_MEM_RESOURCE_START 0UL
0020 #define IO_MEM_RESOURCE_END 0x1fffffffUL
0021
0022
0023
0024
0025 #define MIPS_CPU_IRQ(x) (MIPS_CPU_IRQ_BASE + (x))
0026 #define MIPS_SOFTINT0_IRQ MIPS_CPU_IRQ(0)
0027 #define MIPS_SOFTINT1_IRQ MIPS_CPU_IRQ(1)
0028 #define RCP_IRQ MIPS_CPU_IRQ(2)
0029 #define CART_IRQ MIPS_CPU_IRQ(3)
0030 #define PRENMI_IRQ MIPS_CPU_IRQ(4)
0031 #define RDBR_IRQ MIPS_CPU_IRQ(5)
0032 #define RDBW_IRQ MIPS_CPU_IRQ(6)
0033 #define TIMER_IRQ MIPS_CPU_IRQ(7)
0034
0035 static void __init iomem_resource_init(void)
0036 {
0037 iomem_resource.start = IO_MEM_RESOURCE_START;
0038 iomem_resource.end = IO_MEM_RESOURCE_END;
0039 }
0040
0041 const char *get_system_type(void)
0042 {
0043 return "Nintendo 64";
0044 }
0045
0046 void __init prom_init(void)
0047 {
0048 fw_init_cmdline();
0049 }
0050
0051 #define W 320
0052 #define H 240
0053 #define REG_BASE ((u32 *) CKSEG1ADDR(0x4400000))
0054
0055 static void __init n64rdp_write_reg(const u8 reg, const u32 value)
0056 {
0057 __raw_writel(value, REG_BASE + reg);
0058 }
0059
0060 #undef REG_BASE
0061
0062 static const u32 ntsc_320[] __initconst = {
0063 0x00013212, 0x00000000, 0x00000140, 0x00000200,
0064 0x00000000, 0x03e52239, 0x0000020d, 0x00000c15,
0065 0x0c150c15, 0x006c02ec, 0x002501ff, 0x000e0204,
0066 0x00000200, 0x00000400
0067 };
0068
0069 #define MI_REG_BASE 0x4300000
0070 #define NUM_MI_REGS 4
0071 #define AI_REG_BASE 0x4500000
0072 #define NUM_AI_REGS 6
0073 #define PI_REG_BASE 0x4600000
0074 #define NUM_PI_REGS 5
0075 #define SI_REG_BASE 0x4800000
0076 #define NUM_SI_REGS 7
0077
0078 static int __init n64_platform_init(void)
0079 {
0080 static const char simplefb_resname[] = "FB";
0081 static const struct simplefb_platform_data mode = {
0082 .width = W,
0083 .height = H,
0084 .stride = W * 2,
0085 .format = "r5g5b5a1"
0086 };
0087 struct resource res[3];
0088 void *orig;
0089 unsigned long phys;
0090 unsigned i;
0091
0092 memset(res, 0, sizeof(struct resource) * 3);
0093 res[0].flags = IORESOURCE_MEM;
0094 res[0].start = MI_REG_BASE;
0095 res[0].end = MI_REG_BASE + NUM_MI_REGS * 4 - 1;
0096
0097 res[1].flags = IORESOURCE_MEM;
0098 res[1].start = AI_REG_BASE;
0099 res[1].end = AI_REG_BASE + NUM_AI_REGS * 4 - 1;
0100
0101 res[2].flags = IORESOURCE_IRQ;
0102 res[2].start = RCP_IRQ;
0103 res[2].end = RCP_IRQ;
0104
0105 platform_device_register_simple("n64audio", -1, res, 3);
0106
0107 memset(&res[0], 0, sizeof(res[0]));
0108 res[0].flags = IORESOURCE_MEM;
0109 res[0].start = PI_REG_BASE;
0110 res[0].end = PI_REG_BASE + NUM_PI_REGS * 4 - 1;
0111
0112 platform_device_register_simple("n64cart", -1, res, 1);
0113
0114 memset(&res[0], 0, sizeof(res[0]));
0115 res[0].flags = IORESOURCE_MEM;
0116 res[0].start = SI_REG_BASE;
0117 res[0].end = SI_REG_BASE + NUM_SI_REGS * 4 - 1;
0118
0119 platform_device_register_simple("n64joy", -1, res, 1);
0120
0121
0122 orig = kzalloc(W * H * 2 + 63, GFP_DMA | GFP_KERNEL);
0123 if (!orig)
0124 return -ENOMEM;
0125 phys = virt_to_phys(orig);
0126 phys += 63;
0127 phys &= ~63;
0128
0129 for (i = 0; i < ARRAY_SIZE(ntsc_320); i++) {
0130 if (i == 1)
0131 n64rdp_write_reg(i, phys);
0132 else
0133 n64rdp_write_reg(i, ntsc_320[i]);
0134 }
0135
0136
0137 memset(&res[0], 0, sizeof(res[0]));
0138 res[0].flags = IORESOURCE_MEM;
0139 res[0].name = simplefb_resname;
0140 res[0].start = phys;
0141 res[0].end = phys + W * H * 2 - 1;
0142
0143 platform_device_register_resndata(NULL, "simple-framebuffer", 0,
0144 &res[0], 1, &mode, sizeof(mode));
0145
0146 return 0;
0147 }
0148
0149 #undef W
0150 #undef H
0151
0152 arch_initcall(n64_platform_init);
0153
0154 void __init plat_mem_setup(void)
0155 {
0156 iomem_resource_init();
0157 memblock_add(0x0, 8 * 1024 * 1024);
0158 }
0159
0160 void __init plat_time_init(void)
0161 {
0162
0163 mips_hpt_frequency = 93750000 / 2;
0164 }