1/* 2 * Copyright 2002 Momentum Computer Inc. 3 * Author: Matthew Dharm <mdharm@momenco.com> 4 * 5 * Based on Ocelot Linux port, which is 6 * Copyright 2001 MontaVista Software Inc. 7 * Author: jsun@mvista.com or jsun@junsun.net 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License as published by the 11 * Free Software Foundation; either version 2 of the License, or (at your 12 * option) any later version. 13 */ 14#include <linux/config.h> 15#include <linux/init.h> 16#include <linux/mm.h> 17#include <linux/sched.h> 18#include <linux/bootmem.h> 19 20#include <asm/addrspace.h> 21#include <asm/bootinfo.h> 22#include <asm/mv64340.h> 23 24#include "ocelot_c_fpga.h" 25 26struct callvectors { 27 int (*open) (char*, int, int); 28 int (*close) (int); 29 int (*read) (int, void*, int); 30 int (*write) (int, void*, int); 31 off_t (*lseek) (int, off_t, int); 32 int (*printf) (const char*, ...); 33 void (*cacheflush) (void); 34 char* (*gets) (char*); 35}; 36 37struct callvectors* debug_vectors; 38char arcs_cmdline[CL_SIZE]; 39 40extern unsigned long mv64340_base; 41extern unsigned long cpu_clock; 42 43#ifdef CONFIG_MV64340_ETH 44extern unsigned char prom_mac_addr_base[6]; 45#endif 46 47const char *get_system_type(void) 48{ 49#ifdef CONFIG_CPU_SR71000 50 return "Momentum Ocelot-CS"; 51#else 52 return "Momentum Ocelot-C"; 53#endif 54} 55 56#ifdef CONFIG_MV64340_ETH 57static void burn_clocks(void) 58{ 59 int i; 60 61 /* this loop should burn at least 1us -- this should be plenty */ 62 for (i = 0; i < 0x10000; i++) 63 ; 64} 65 66static u8 exchange_bit(u8 val, u8 cs) 67{ 68 /* place the data */ 69 OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); 70 burn_clocks(); 71 72 /* turn the clock on */ 73 OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); 74 burn_clocks(); 75 76 /* turn the clock off and read-strobe */ 77 OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); 78 79 /* return the data */ 80 return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1); 81} 82 83void get_mac(char dest[6]) 84{ 85 u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 86 int i,j; 87 88 for (i = 0; i < 12; i++) 89 exchange_bit(read_opcode[i], 1); 90 91 for (j = 0; j < 6; j++) { 92 dest[j] = 0; 93 for (i = 0; i < 8; i++) { 94 dest[j] <<= 1; 95 dest[j] |= exchange_bit(0, 1); 96 } 97 } 98 99 /* turn off CS */ 100 exchange_bit(0,0); 101} 102#endif 103 104/* [jsun@junsun.net] PMON passes arguments in C main() style */ 105void __init prom_init(int argc, char **arg, char** env, struct callvectors *cv) 106{ 107 int i; 108 109 /* save the PROM vectors for debugging use */ 110 debug_vectors = cv; 111 112 /* arg[0] is "g", the rest is boot parameters */ 113 arcs_cmdline[0] = '\0'; 114 for (i = 1; i < argc; i++) { 115 if (strlen(arcs_cmdline) + strlen(arg[i] + 1) 116 >= sizeof(arcs_cmdline)) 117 break; 118 strcat(arcs_cmdline, arg[i]); 119 strcat(arcs_cmdline, " "); 120 } 121 122 mips_machgroup = MACH_GROUP_MOMENCO; 123 mips_machtype = MACH_MOMENCO_OCELOT_C; 124 125 while (*env) { 126 if (strncmp("gtbase", *env, strlen("gtbase")) == 0) { 127 mv64340_base = simple_strtol(*env + strlen("gtbase="), 128 NULL, 16); 129 } 130 if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) { 131 cpu_clock = simple_strtol(*env + strlen("cpuclock="), 132 NULL, 10); 133 } 134 env++; 135 } 136 137#ifdef CONFIG_MV64340_ETH 138 /* get the base MAC address for on-board ethernet ports */ 139 get_mac(prom_mac_addr_base); 140#endif 141 142 debug_vectors->printf("Booting Linux kernel...\n"); 143} 144 145void __init prom_free_prom_memory(void) 146{ 147} 148 149void __init prom_fixup_mem_map(unsigned long start, unsigned long end) 150{ 151} 152