/** * Copyright (C) 2006-2014 Ikanos Communications. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(CONFIG_FUSIV_VX185) #include struct clock_values fusiv_718x_clks; #endif /* CONFIG_FUSIV_VX185 */ #if defined(CONFIG_FUSIV_VX585) #include struct fusiv_clock_values fusiv_75xx_clks; #define HMIPS_VX585_HP_CLK 1200000000 #define HMIPS_VX585_CLK 1000000000 #define HMIPS_VX583_CLK 800000000 #define SYS_VX585_HP_CLK 500000000 #define SYS_VX585_CLK 400000000 #define SYS_VX583_CLK 300000000 #define AP_VX585_HP_CLK 1000000000 #define AP_VX585_CLK 800000000 #define AP_VX583_CLK 600000000 #define IO(_x) *(volatile unsigned int *) (_x) #define GPIO_INPUT_VALUE (*(volatile unsigned long *) 0xB9030000) #define GPIO_OUT_SET_REG (*(volatile unsigned long *) 0xB9030004) #define GPIO_OUT_CLEAR_REG (*(volatile unsigned long *) 0xB9030008) #define GPIO_MODE1 (*(volatile unsigned long *) 0xB903000C) #define GPIO_MODE2 (*(volatile unsigned long *) 0xB9030010) #define GPIO_ALT_FUNC_SEL (*(volatile unsigned long *) 0xB9030014) #define GPIO_ALT_DEF (*(volatile unsigned long *) 0xB9030018) #endif /* CONFIG_FUSIV_VX585 */ extern void (*_machine_restart) (char *); extern void (*_machine_halt) (void); extern void (*pm_power_off) (void); extern void fusiv_init_IRQ(void); static void fusiv_mips32_configure(void); void serial_setup(void); extern unsigned int avm_nmi_taken; char *reboot_cause_written = NULL; static void set_reboot_status(char *); #define UPDATE_REBOOT_STATUS_TEXT "(c) AVM 2013, Reboot Status is: Firmware-Update" \ "(c) AVM 2013, Reboot Status is: Firmware-Update" \ "(c) AVM 2013, Reboot Status is: Firmware-Update" #define SOFT_REBOOT_STATUS_TEXT "(c) AVM 2013, Reboot Status is: Software-Reboot" \ "(c) AVM 2013, Reboot Status is: Software-Reboot" \ "(c) AVM 2013, Reboot Status is: Software-Reboot" #define NMI_REBOOT_STATUS_TEXT "(c) AVM 2013, Reboot Status is: Software-NMI-Watchdog" \ "(c) AVM 2013, Reboot Status is: Software-NMI-Watchdog" \ "(c) AVM 2013, Reboot Status is: Software-NMI-Watchdog" #define POWERON_REBOOT_STATUS_TEXT "(c) AVM 2013, Reboot Status is: Power-On-Reboot" \ "(c) AVM 2013, Reboot Status is: Power-On-Reboot" \ "(c) AVM 2013, Reboot Status is: Power-On-Reboot" #define PCI_RST_CONTROL *(volatile unsigned long *)(KSEG1ADDR(0x19050700)) #define REBOOT_CTRL *(volatile unsigned long *)(KSEG1ADDR(0x19000000)) // AVM/TKL: MERGE prom_printf for all machines #if 1 //defined(CONFIG_FUSIV_VX585) /* Add for Debug UART */ static char buf[1024]; /* End for Debug UART */ #endif /* CONFIG_FUSIV_VX585 */ static void fusiv_restart(char *command) { printk("System reset for Chip\n"); sys_sync(); sys_sync(); mdelay(1); if (avm_nmi_taken == ~0xdeadbabe) { pr_err("[IKS] double NMI and Oops\n"); } #if defined(CONFIG_FUSIV_VX185) /* Send Reset Command to flash */ *(volatile unsigned char *)0xbfc00000 = 0xF0; mdelay(1); /* Unmask the reset the bit for system reset */ scu_regs->rst_mask = 0x0; scu_regs->rst_vec = 0x0; #endif #if defined(CONFIG_FUSIV_VX585) /* Issuing Self Reset and Reset to peripherals */ scu_regs->reset_control_2_mask = ~(1 << RSTN_OUT | 1 << SELF_RSTN); scu_regs->reset_control_2 = ~(1 << RSTN_OUT | 1 << SELF_RSTN); #endif while (1) ; } static void fusiv_halt(void) { printk("\n>>> Fusiv Halted <<<\n"); #ifdef CONFIG_FUSIV_VX185 sys_sync(); sys_sync(); mdelay(1); *(volatile unsigned char *)0xbfc00000 = 0xF0; mdelay(1); scu_regs->rst_mask = 0x0; scu_regs->clk_gate_ctl = 0x0; #endif #if defined(CONFIG_FUSIV_VX585) sys_sync(); sys_sync(); mdelay(1); /* Halt the System by gating all the clocks */ /* Disable write protection to Clock Gate control registers */ scu_regs->clock_gate_control_0_mask = 0x0; scu_regs->clock_gate_control_1_mask = 0x0; scu_regs->clock_gate_control_2_mask = 0x0; /* Disable all the clocks */ scu_regs->clock_gate_control_2 = 0x0; scu_regs->clock_gate_control_1 = 0x0; scu_regs->clock_gate_control_0 = 0x0; //Gating HMIPS at the last #endif while (1) ; } unsigned int iks_reboot_status; int get_reboot_status(void) { static char Buffer[512]; volatile unsigned char *mailbox = (volatile unsigned char *)(0xA1000000 - 512); memcpy(Buffer, (void *)mailbox, 512); Buffer[511] = '\0'; /*--- printk("Reboot Status: %s\n", Buffer); ---*/ if(!strcmp(Buffer, UPDATE_REBOOT_STATUS_TEXT)) { printk("Reboot Status is: FW-Update\n"); iks_reboot_status = 3; set_reboot_status(POWERON_REBOOT_STATUS_TEXT); reboot_cause_written = NULL; return 0; } if(!strcmp(Buffer, NMI_REBOOT_STATUS_TEXT)) { printk("Reboot Status is: NMI-Watchdog-Reboot\n"); iks_reboot_status = 2; set_reboot_status(POWERON_REBOOT_STATUS_TEXT); reboot_cause_written = NULL; return 0; } if(!strcmp(Buffer, SOFT_REBOOT_STATUS_TEXT)) { printk("Reboot Status is: Soft-Reboot\n"); set_reboot_status(POWERON_REBOOT_STATUS_TEXT); reboot_cause_written = NULL; iks_reboot_status = 1; return 0; } if(!strcmp(Buffer, POWERON_REBOOT_STATUS_TEXT)) { printk("Reboot Status is: Short-PowerOff-Reboot\n"); set_reboot_status(POWERON_REBOOT_STATUS_TEXT); reboot_cause_written = NULL; iks_reboot_status = 0; return 0; } printk("Reboot Status is: Power-On\n"); set_reboot_status(POWERON_REBOOT_STATUS_TEXT); reboot_cause_written = NULL; iks_reboot_status = 0; return 0; } static void set_reboot_status(char *text) { volatile unsigned char *mailbox = (volatile unsigned char *)(0xA1000000 - 512); int len; if((reboot_cause_written != NULL) && (reboot_cause_written != text)) { return; } reboot_cause_written = text; len = strlen(text); memcpy((char *)mailbox, text, len); mailbox += len; *mailbox = '\0'; } arch_initcall(get_reboot_status); /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ void set_reboot_status_to_NMI(void) { set_reboot_status(NMI_REBOOT_STATUS_TEXT); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ void set_reboot_status_to_Update(void) { set_reboot_status(UPDATE_REBOOT_STATUS_TEXT); } /* Do fusiv-specific initialization in here */ int plat_setup(void) { #if defined(CONFIG_FUSIV_VX585) struct uart_port up; fusiv_mips_75xx_get_clocks(); #endif #if defined(CONFIG_FUSIV_VX185) fusiv_mips_718x_get_clocks(); #endif /* Serial Setup */ serial_setup(); _machine_restart = fusiv_restart; _machine_halt = fusiv_halt; pm_power_off = fusiv_halt; #ifdef CONFIG_PCI set_io_port_base(0); #endif #if defined (CONFIG_FUSIV_VX585) /* Initialize the GPIO alternate functions for UART0 RTS/CTS */ GPIO_ALT_FUNC_SEL |= 0x00000300; GPIO_MODE1 |= 0x00010000; memset(&up, 0, sizeof(up)); up.iotype = UPIO_MEM32; up.mapbase = (unsigned long)(UART1_BASE_ADDR); up.membase = (unsigned char *)(UART1_BASE_ADDR); up.irq = 34; /* Updating the System clock frequency 300 MHz for CatShark - CRS */ #if defined(CONFIG_FUSIV_VX585_PALLADIUM) up.uartclk = (MIPS_CORE_CLK_FREQ) / (16 * UART_DIVISOR); #else up.uartclk = fusiv_75xx_clks.sys_clk_val; #endif up.regshift = 2; up.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; up.type = PORT_8250; up.line = 0; up.regshift = 2; /* TODO: early_serial_setup is also called from serial_setup() -- VB */ if (early_serial_setup(&up)) { pr_err("Early serial init of port 0 failed\n"); } /* Configure the GPIOs used for LEDs in output mode and drive them low by default. Required drivers/applications will/can initialize and drive the GPIOs for LEDs at a later stage. GPIOs 2, 3, 4, 6, 15, 17, 18, 19, 22, 31 are used for LEDs as per DO-444726-TC-F */ printk("Seting LED GPIOs to low... \r\n"); /* Set the above listed GPIOs in Normal output mode */ GPIO_MODE1 |= 0x40001150; GPIO_MODE2 |= 0x40001054; /* Drive the above listed GPIOs to logical high */ GPIO_OUT_SET_REG = 0x804e805c; mdelay(1000); /* Drive the above listed GPIOs to logical low */ GPIO_OUT_CLEAR_REG = 0x804e805c; #endif /* CONFIG_FUSIV_VX585 */ /* Core specific tunings */ fusiv_mips32_configure(); #ifdef CONFIG_MIPS_MT_SMP /* TODO: CONFIG_MIPS_MT_SMP is defined but following print is not seen during boot -- VB */ printk("Registering SMP OPS \n\r"); #if defined(CONFIG_FUSIV_VX185) if (register_vsmp_smp_ops()) { printk("Error in registering smp ops..\n\r"); return -1; } #endif #if defined (CONFIG_FUSIV_VX585) if (!register_cps_smp_ops()) return -1; #endif #endif return 0; } #if 0 /* The below piece of code is commented to resolve Bug# 24334 & 24551 */ /* * If the port was already initialised (eg, by a boot loader), * try to determine the current setup. */ void fusiv_uart_get_options(struct uart_port *uart, int *baud, int *parity, int *bits) { unsigned short status; unsigned int uart_base_addr; #ifdef CONFIG_FUSIV_MIPS_DUALCORE /* Dual core image */ #ifdef CONFIG_FUSIV_MIPS_CMIPS_CORE uart_base_addr = UART2_BASE_ADDR; #else uart_base_addr = UART1_BASE_ADDR; #endif #else /* Single Core image */ uart_base_addr = UART1_BASE_ADDR; #endif struct uart_8250_port *up = (struct uart_8250_port *)uart; /* ok, the port was enabled */ unsigned short lcr, dl; lcr = *(volatile unsigned char *)(uart_base_addr + (UART_LCR << 2)); *parity = 'n'; if (lcr & UART_LCR_PARITY) { if (lcr & UART_LCR_EPAR) *parity = 'e'; else *parity = 'o'; } switch (lcr & 0x03) { case 0: *bits = 5; break; case 1: *bits = 6; break; case 2: *bits = 7; break; case 3: *bits = 8; break; } /* Set DLAB in LCR to Access DLL and DLH */ *(volatile unsigned long *)(uart_base_addr + (UART_LCR << 2)) |= UART_LCR_DLAB; dl = *(volatile unsigned long *)(uart_base_addr + (UART_DLL << 2)) | (*(volatile unsigned long *)(uart_base_addr + (UART_DLM << 2)) << 8); /* Clear DLAB in LCR to Access THR RBR IER */ lcr &= 0x7F; *(volatile unsigned long *)(uart_base_addr + (UART_LCR << 2)) = lcr; /* * The serial core only rounds down when matching this to a * supported baud rate. Make sure we don't end up slightly * lower than one of those, as it would make us fall through * to a much lower baud rate than we really want. */ #ifdef CONFIG_FUSIV_VX185 *baud = fusiv_718x_clks.sys_clk_val / (16 * (dl - 1)); #endif //printk("%s:baud = %d, parity = %c, bits= %d\n", __func__, *baud, *parity, *bits); } #endif #if defined(CONFIG_FUSIV_VX185) void fusiv_mips_718x_get_clocks(void) { unsigned int pll_freq; unsigned int bme_pll_freq; unsigned int gw_div; unsigned int bme_div; unsigned int post_div1, spare_post_div1; unsigned int post_div2; unsigned int bmips_post_div1; unsigned int bmips_post_div2; unsigned int host_post_div2, spare_host_post_div2; unsigned int sys_post_div2; volatile unsigned int chip_type; /* Clock = ( Board Crystal Clock * GW PLL Divisor)/(PD1 * PD2); */ /* Get the GW PLL Post divider value */ /* Register SCU:B900002C[7:0] -- GW PLL DIV value */ gw_div = (scu_regs->pll_pd1_ctl & HOST_GW_PLL_DIV_MASK); pll_freq = (gw_div * BOARD_CRYSTAL_FREQ); bme_div = (scu_regs->pll_pd1_ctl & BME_PLL_DIV_MASK) >> 8; bme_pll_freq = (bme_div * BOARD_CRYSTAL_FREQ); chip_type = (scu_regs->cpu_ctl >> 4) & 0x7; /* Get the H_MIPS Clk and AP/SYS Clk Post divider (PD1) Values */ /* Register SCU:B9000030[3:0] -- H MIPS PD1 [7:4] -- SYS/AP PD1 [9:8] -- H MIPS PD2 [11:10]-- SYS/AP PD2 */ post_div1 = (scu_regs->pll_pd2_ctl & HOST_SYS_AP_PD1_MASK); bmips_post_div1 = (scu_regs->pll_pd2_ctl & BME_FD_PD1_MASK); fusiv_718x_clks.cpu_clk_val = (pll_freq / (post_div1 & HOST_PD1_MASK)); fusiv_718x_clks.sys_clk_val = (pll_freq / ((post_div1 & SYS_AP_PD1_MASK) >> 4)); fusiv_718x_clks.cmips_cpu_clk_val = (bme_pll_freq / (bmips_post_div1 >> 12)); post_div2 = ((scu_regs->pll_pd2_ctl & HOST_SYS_AP_PD2_MASK) >> 8); bmips_post_div2 = ((scu_regs->pll_pd2_ctl & BME_FD_PD2_MASK) >> 16); host_post_div2 = post_div2 & HOST_PD2_MASK; sys_post_div2 = ((post_div2 & SYS_AP_PD2_MASK) >> 2); bmips_post_div2 = bmips_post_div2 & HOST_PD2_MASK; if (host_post_div2 == 0x3 || sys_post_div2 == 0x3) panic("VX185: Invalid PLL Divisor settings!"); fusiv_718x_clks.cpu_clk_val = fusiv_718x_clks.cpu_clk_val / (host_post_div2 ? (4 * host_post_div2) : 2); fusiv_718x_clks.sys_clk_val = fusiv_718x_clks.sys_clk_val / (sys_post_div2 ? (4 * sys_post_div2) : 2); fusiv_718x_clks.sys_clk_val = fusiv_718x_clks.sys_clk_val / 2; fusiv_718x_clks.ap_clk_val = fusiv_718x_clks.sys_clk_val * 2; fusiv_718x_clks.cmips_cpu_clk_val = fusiv_718x_clks.cmips_cpu_clk_val / (bmips_post_div2 ? (4 * bmips_post_div2) : 2); fusiv_718x_clks.uart_div_factor = fusiv_718x_clks.sys_clk_val / (16 * UART_BAUD_RATE); if (chip_type == CHIP_7175) { /* Indicates Vx175 */ scu_regs->spare0 = 0x4009; /*Changing MIPS clock source to to BME PLL for 600MHz */ spare_post_div1 = ((scu_regs->spare0 & HOST_SPARE_PD1_MASK) >> 2); fusiv_718x_clks.cpu_clk_val = (bme_pll_freq / spare_post_div1); spare_host_post_div2 = ((scu_regs->spare0 & HOST_SPARE_PD2_MASK) >> 10); if (spare_host_post_div2 == 0x3) panic("VX175: Invalid PLL Divisor settings!"); fusiv_718x_clks.cpu_clk_val = fusiv_718x_clks.cpu_clk_val / (spare_host_post_div2 ? (4 * spare_host_post_div2) : 2); } #ifdef CONFIG_FUSIV_MIPS_DUALCORE /* Dual core image */ #ifdef CONFIG_FUSIV_MIPS_CMIPS_CORE printk("Fusiv MIPS Clock = %d System Clock = %d\n", fusiv_718x_clks.cmips_cpu_clk_val, fusiv_718x_clks.sys_clk_val); #else printk("Fusiv MIPS Clock = %d System Clock = %d\n", fusiv_718x_clks.cpu_clk_val, fusiv_718x_clks.sys_clk_val); #endif #else /* Single core image */ printk("Fusiv MIPS Clock = %d System Clock = %d\n", fusiv_718x_clks.cpu_clk_val, fusiv_718x_clks.sys_clk_val); #endif } #endif #if defined(CONFIG_FUSIV_VX585) void fusiv_mips_75xx_get_clocks(void) { unsigned int chip_id = 0; volatile unsigned int BondPad_Val; /*Configuring chip types as per DO-444782-TC-1A */ enum chip_type { CHIP_VX585 = 0x3, CHIP_VX585_HP = 0x4, CHIP_VX585_LT = 0x5, CHIP_VX583 = 0x9, CHIP_VX582 = 0xc, CHIP_VX575 = 0x13, CHIP_VX575_HP = 0x14, CHIP_VX573 = 0x19, CHIP_VX572 = 0x1c }; BondPad_Val = IO(0xb9000318); BondPad_Val = ((BondPad_Val >> 8) & 0x1f); switch (BondPad_Val) { case CHIP_VX585: chip_id = CHIP_VX585; break; case CHIP_VX585_HP: chip_id = CHIP_VX585_HP; break; case CHIP_VX585_LT: chip_id = CHIP_VX585_LT; break; case CHIP_VX583: chip_id = CHIP_VX583; break; case CHIP_VX582: chip_id = CHIP_VX582; break; case CHIP_VX575: chip_id = CHIP_VX575; break; case CHIP_VX575_HP: chip_id = CHIP_VX575_HP; break; case CHIP_VX573: chip_id = CHIP_VX573; break; case CHIP_VX572: chip_id = CHIP_VX572; break; default: chip_id = CHIP_VX585; break; } if ((chip_id == CHIP_VX585_HP) || (chip_id == CHIP_VX575_HP)) { fusiv_75xx_clks.cpu_clk_val = HMIPS_VX585_HP_CLK; fusiv_75xx_clks.sys_clk_val = SYS_VX585_HP_CLK; fusiv_75xx_clks.ap_clk_val = AP_VX585_HP_CLK; } else if ((chip_id == CHIP_VX585) || (chip_id == CHIP_VX575)) { fusiv_75xx_clks.cpu_clk_val = HMIPS_VX585_CLK; fusiv_75xx_clks.sys_clk_val = SYS_VX585_CLK; fusiv_75xx_clks.ap_clk_val = AP_VX585_CLK; } else { /*CHIP_VX583, CHIP_VX582, CHIP_VX573, CHIP_VX572 */ fusiv_75xx_clks.cpu_clk_val = HMIPS_VX583_CLK; fusiv_75xx_clks.sys_clk_val = SYS_VX583_CLK; fusiv_75xx_clks.ap_clk_val = AP_VX583_CLK; } } #endif void __init plat_mem_setup(void) { } /* MIPS32 Core configuration and tuning */ static void fusiv_mips32_configure(void) { /* * Configure Cache Coherency policy for KSEG0: * Cacheable, non-coherent, write-back, read and write allocate */ #if defined(CONFIG_FUSIV_VX185) change_c0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT); #endif } const char *get_system_type(void) { return "Ikanos Fusiv Core"; } void serial_setup(void) { struct uart_port req; unsigned int uart_int_source; unsigned int uart_base_addr; #ifdef CONFIG_FUSIV_MIPS_DUALCORE /* Dual Core */ #ifdef CONFIG_FUSIV_MIPS_CMIPS_CORE uart_int_source = UART2_INT; uart_base_addr = UART2_BASE_ADDR; #else uart_int_source = UART1_INT; uart_base_addr = UART1_BASE_ADDR; #endif #else /*Single Core */ uart_int_source = UART1_INT; uart_base_addr = UART1_BASE_ADDR; #endif /* Setup serial port */ memset(&req, 0, sizeof(req)); req.line = 0; #if defined(CONFIG_FUSIV_VX185) req.type = PORT_16450; #endif #if defined(CONFIG_FUSIV_VX185) req.type = PORT_16550; #endif #if defined (CONFIG_CPU_MIPSR2_IRQ_VI) if (cpu_has_vint) req.irq = FUSIV_MIPS_INT_SERIAL; #else req.irq = uart_int_source; #endif req.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; #if defined(CONFIG_FUSIV_VX185) req.uartclk = fusiv_718x_clks.sys_clk_val; #endif #if defined(CONFIG_FUSIV_VX585) req.uartclk = fusiv_75xx_clks.sys_clk_val; #endif #if defined(CONFIG_FUSIV_VX185) req.iotype = SERIAL_IO_MEM; #endif #if defined(CONFIG_FUSIV_VX585) req.iotype = UPIO_MEM32; #endif req.membase = (unsigned char *)((uart_base_addr)); req.mapbase = (unsigned long)(uart_base_addr); req.regshift = 2; req.fifosize = 1; early_serial_setup(&req); return; } void __init arch_init_irq(void) { fusiv_init_IRQ(); } //static int echoOn = 1; static int rxBuffer[16]; static int rxWrPtr = 0; //static int rxRdPtr = 0; static int rxChars = 0; int prom_putchar(char c) { #if 1 /* While !THRE, loop */ while (0 == (*((volatile int *)(UART1_BASE_ADDR + LSR)) & LSR_THRE)) { // check for input, buffer any chars if (1 == (*((volatile int *)(UART1_BASE_ADDR + LSR)) & 0x01)) { rxBuffer[rxWrPtr++] = (char)(*((volatile int *)(UART1_BASE_ADDR + THR)) & 0xFF); if (rxWrPtr == 16) { rxWrPtr = 0; } rxChars++; } } *((volatile int *)(UART1_BASE_ADDR + THR)) = (int)c; #endif return 0; } static int __init fusiv185_spi_init(void) { struct spi_board_info spidev_info = { .modalias = "spidev", .max_speed_hz = 24000000, .bus_num = 1, .chip_select = 2, /* Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS */ .mode = SPI_MODE_1 | SPI_CS_HIGH, }; spi_register_board_info(&spidev_info, 1); return 0; } static int __init _fusiv_arch_init(void) { fusiv185_spi_init(); return 0; } arch_initcall(_fusiv_arch_init); #ifdef CONFIG_FUSIV_KERNEL_PROFILER_MODULE int (*loggerFunction) (unsigned long event) = NULL; int loggerProfile(unsigned long event) { if (loggerFunction != NULL) return loggerFunction(event); return -1; } void loggerRegFunction(int (*func) (unsigned long event)) { loggerFunction = func; } EXPORT_SYMBOL(loggerRegFunction); EXPORT_SYMBOL(loggerProfile); #endif // AVM/TKL: MERGE prom_printf for all machines #if 1 //defined(CONFIG_FUSIV_VX585) /* Add for Debugging UART - CRS*/ void prom_puts(char *p) { while (p && *p){ prom_putchar(*p); if(*p == '\n'){ prom_putchar('\r'); } ++p; } } // AVM/TKL: MERGE //int prom_printf(const char *fmt, ...) void prom_printf(const char *fmt, ...) { va_list args; int l; char *p, *buf_end; /* Low level, brute force, not SMP safe... */ va_start(args, fmt); l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */ va_end(args); buf_end = buf + l; *buf_end = '\0'; for (p = buf; p < buf_end; p++) { /* Wait for FIFO to empty */ prom_putchar(*p); if(*p == '\n'){ prom_putchar('\r'); } } // return 0; } void printascii(const char *string) { char *buf = "%s"; prom_printf(buf, string); } //device_initcall(fusiv_add_devices); EXPORT_SYMBOL(prom_printf); EXPORT_SYMBOL(prom_puts); EXPORT_SYMBOL(printascii); /* End Add for Debugging UART - CRS */ #endif /* CONFIG_FUSIV_VX585 */ #if defined(CONFIG_FUSIV_VX185) EXPORT_SYMBOL(fusiv_718x_clks); #endif #if defined(CONFIG_FUSIV_VX585) EXPORT_SYMBOL(fusiv_75xx_clks); #endif void __init plat_device_tree_setup(void) { struct boot_param_header *dtb; if (IS_ENABLED(CONFIG_AVM_ENHANCED)) { char *subrev_str; int subrev = 0; subrev_str = prom_getenv("HWSubRevision"); if (subrev_str) { if (sscanf(subrev_str, "%u", &subrev) != 1) subrev_str = NULL; } if (!subrev_str) { prom_printf("%s: Unable to read AVM hardware " "subrevision! Identity crisis... who am I?\n", __func__); } prom_printf("%s: AVM hardware subrevision %d\n", __func__, subrev); if (subrev > avm_subrev_max) { prom_printf("%s: Too many hardware subrevisions!\n", __func__); panic("%s: Too many hardware subrevisions!\n", __func__); } dtb = (struct boot_param_header *)avm_kernel_config_device_tree[subrev]; if (!dtb) { /* fallback auf subrev == 0 */ dtb = (struct boot_param_header *)avm_kernel_config_device_tree[0]; prom_printf("%s: Fallback device-tree for AVM hardware " "subrevision %d\n", __func__, subrev); } if (!dtb) { prom_printf("%s: Missing device-tree for AVM hardware " "subrevision %d\n", __func__, subrev); panic("%s: Missing device-tree for AVM hardware " "subrevision %d\n", __func__, subrev); } else { extern struct boot_param_header *initial_boot_params; initial_boot_params = dtb; prom_printf("DT: %02x %02x %02x %02x %02x %02x %02x %02x\n", ((unsigned char *)dtb)[0], ((unsigned char *)dtb)[1], ((unsigned char *)dtb)[2], ((unsigned char *)dtb)[3], ((unsigned char *)dtb)[4], ((unsigned char *)dtb)[5], ((unsigned char *)dtb)[6], ((unsigned char *)dtb)[7]); } } __dt_setup_arch(dtb); } void __init device_tree_init(void) { unsigned long base, size; if (!initial_boot_params) return; base = virt_to_phys((void *)initial_boot_params); size = be32_to_cpu(initial_boot_params->totalsize); /* Before we do anything, lets reserve the dt blob */ reserve_bootmem(base, size, BOOTMEM_DEFAULT); unflatten_device_tree(); } unsigned int avm_reset_status(void) { return iks_reboot_status; } EXPORT_SYMBOL(avm_reset_status); /*--- Kernel-Schnittstellen-Funktion für das LED-Modul ---*/ enum _led_event { /* DUMMY DEFINITION */ LastEvent = 0 }; int (*led_event_action)(int, enum _led_event , unsigned int ) = NULL; EXPORT_SYMBOL(led_event_action);