1*35fb26f9SCaleb James DeLisle // SPDX-License-Identifier: GPL-2.0-only 2*35fb26f9SCaleb James DeLisle /* 3*35fb26f9SCaleb James DeLisle * EcoNet setup code 4*35fb26f9SCaleb James DeLisle * 5*35fb26f9SCaleb James DeLisle * Copyright (C) 2025 Caleb James DeLisle <cjd@cjdns.fr> 6*35fb26f9SCaleb James DeLisle */ 7*35fb26f9SCaleb James DeLisle 8*35fb26f9SCaleb James DeLisle #include <linux/init.h> 9*35fb26f9SCaleb James DeLisle #include <linux/of_clk.h> 10*35fb26f9SCaleb James DeLisle #include <linux/irqchip.h> 11*35fb26f9SCaleb James DeLisle 12*35fb26f9SCaleb James DeLisle #include <asm/addrspace.h> 13*35fb26f9SCaleb James DeLisle #include <asm/io.h> 14*35fb26f9SCaleb James DeLisle #include <asm/bootinfo.h> 15*35fb26f9SCaleb James DeLisle #include <asm/time.h> 16*35fb26f9SCaleb James DeLisle #include <asm/prom.h> 17*35fb26f9SCaleb James DeLisle #include <asm/smp-ops.h> 18*35fb26f9SCaleb James DeLisle #include <asm/reboot.h> 19*35fb26f9SCaleb James DeLisle 20*35fb26f9SCaleb James DeLisle #define CR_AHB_RSTCR ((void __iomem *)CKSEG1ADDR(0x1fb00040)) 21*35fb26f9SCaleb James DeLisle #define RESET BIT(31) 22*35fb26f9SCaleb James DeLisle 23*35fb26f9SCaleb James DeLisle #define UART_BASE CKSEG1ADDR(0x1fbf0003) 24*35fb26f9SCaleb James DeLisle #define UART_REG_SHIFT 2 25*35fb26f9SCaleb James DeLisle hw_reset(char * command)26*35fb26f9SCaleb James DeLislestatic void hw_reset(char *command) 27*35fb26f9SCaleb James DeLisle { 28*35fb26f9SCaleb James DeLisle iowrite32(RESET, CR_AHB_RSTCR); 29*35fb26f9SCaleb James DeLisle } 30*35fb26f9SCaleb James DeLisle 31*35fb26f9SCaleb James DeLisle /* 1. Bring up early printk. */ prom_init(void)32*35fb26f9SCaleb James DeLislevoid __init prom_init(void) 33*35fb26f9SCaleb James DeLisle { 34*35fb26f9SCaleb James DeLisle setup_8250_early_printk_port(UART_BASE, UART_REG_SHIFT, 0); 35*35fb26f9SCaleb James DeLisle _machine_restart = hw_reset; 36*35fb26f9SCaleb James DeLisle } 37*35fb26f9SCaleb James DeLisle 38*35fb26f9SCaleb James DeLisle /* 2. Parse the DT and find memory */ plat_mem_setup(void)39*35fb26f9SCaleb James DeLislevoid __init plat_mem_setup(void) 40*35fb26f9SCaleb James DeLisle { 41*35fb26f9SCaleb James DeLisle void *dtb; 42*35fb26f9SCaleb James DeLisle 43*35fb26f9SCaleb James DeLisle set_io_port_base(KSEG1); 44*35fb26f9SCaleb James DeLisle 45*35fb26f9SCaleb James DeLisle dtb = get_fdt(); 46*35fb26f9SCaleb James DeLisle if (!dtb) 47*35fb26f9SCaleb James DeLisle panic("no dtb found"); 48*35fb26f9SCaleb James DeLisle 49*35fb26f9SCaleb James DeLisle __dt_setup_arch(dtb); 50*35fb26f9SCaleb James DeLisle 51*35fb26f9SCaleb James DeLisle early_init_dt_scan_memory(); 52*35fb26f9SCaleb James DeLisle } 53*35fb26f9SCaleb James DeLisle 54*35fb26f9SCaleb James DeLisle /* 3. Overload __weak device_tree_init(), add SMP_UP ops */ device_tree_init(void)55*35fb26f9SCaleb James DeLislevoid __init device_tree_init(void) 56*35fb26f9SCaleb James DeLisle { 57*35fb26f9SCaleb James DeLisle unflatten_and_copy_device_tree(); 58*35fb26f9SCaleb James DeLisle 59*35fb26f9SCaleb James DeLisle register_up_smp_ops(); 60*35fb26f9SCaleb James DeLisle } 61*35fb26f9SCaleb James DeLisle get_system_type(void)62*35fb26f9SCaleb James DeLisleconst char *get_system_type(void) 63*35fb26f9SCaleb James DeLisle { 64*35fb26f9SCaleb James DeLisle return "EcoNet-EN75xx"; 65*35fb26f9SCaleb James DeLisle } 66*35fb26f9SCaleb James DeLisle 67*35fb26f9SCaleb James DeLisle /* 4. Initialize the IRQ subsystem */ arch_init_irq(void)68*35fb26f9SCaleb James DeLislevoid __init arch_init_irq(void) 69*35fb26f9SCaleb James DeLisle { 70*35fb26f9SCaleb James DeLisle irqchip_init(); 71*35fb26f9SCaleb James DeLisle } 72*35fb26f9SCaleb James DeLisle 73*35fb26f9SCaleb James DeLisle /* 5. Timers */ plat_time_init(void)74*35fb26f9SCaleb James DeLislevoid __init plat_time_init(void) 75*35fb26f9SCaleb James DeLisle { 76*35fb26f9SCaleb James DeLisle of_clk_init(NULL); 77*35fb26f9SCaleb James DeLisle timer_probe(); 78*35fb26f9SCaleb James DeLisle } 79