diff options
Diffstat (limited to 'arch/sparc/cpu/leon3')
-rw-r--r-- | arch/sparc/cpu/leon3/Makefile | 10 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/ambapp.c | 316 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/ambapp_low.S | 784 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/ambapp_low_c.S | 113 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/cpu.c | 113 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/cpu_init.c | 175 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/interrupts.c | 193 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/memcfg.c | 237 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/memcfg.h | 90 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/memcfg_low.S | 253 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/prom.c | 1067 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/serial.c | 189 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/start.S | 681 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/usb_uhci.c | 1195 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/usb_uhci.h | 167 |
15 files changed, 0 insertions, 5583 deletions
diff --git a/arch/sparc/cpu/leon3/Makefile b/arch/sparc/cpu/leon3/Makefile deleted file mode 100644 index f4cf43cfec..0000000000 --- a/arch/sparc/cpu/leon3/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# (C) Copyright 2003-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -extra-y = start.o -obj-y = cpu_init.o serial.o cpu.o ambapp.o ambapp_low.o ambapp_low_c.o \ - interrupts.o prom.o usb_uhci.o memcfg.o memcfg_low.o diff --git a/arch/sparc/cpu/leon3/ambapp.c b/arch/sparc/cpu/leon3/ambapp.c deleted file mode 100644 index 47769cffd7..0000000000 --- a/arch/sparc/cpu/leon3/ambapp.c +++ /dev/null @@ -1,316 +0,0 @@ -/* GRLIB AMBA Plug&Play information scanning, relies on assembler - * routines. - * - * (C) Copyright 2010, 2015 - * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* #define DEBUG */ - -#include <common.h> -#include <malloc.h> -#include <ambapp.h> -#include <config.h> - -/************ C INTERFACE OF ASSEMBLER SCAN ROUTINES ************/ -struct ambapp_find_apb_info { - /* Address of APB device Plug&Play information */ - struct ambapp_pnp_apb *pnp; - /* AHB Bus index of where the APB-Master Bridge device was found */ - int ahb_bus_index; - int dec_index; -}; - -struct ambapp_find_ahb_info { - /* Address of AHB device Plug&Play information */ - struct ambapp_pnp_ahb *pnp; - /* AHB Bus index of where the AHB device was found */ - int ahb_bus_index; - int dec_index; -}; - -extern void ambapp_find_buses(unsigned int ioarea, struct ambapp_bus *abus); - -extern int ambapp_find_apb(struct ambapp_bus *abus, unsigned int dev_vend, - int index, struct ambapp_find_apb_info *result); - -extern int ambapp_find_ahb(struct ambapp_bus *abus, unsigned int dev_vend, - int index, int type, struct ambapp_find_ahb_info *result); - -/************ C ROUTINES USED BY U-BOOT AMBA CORE DRIVERS ************/ -struct ambapp_bus ambapp_plb __section(.data); - -void ambapp_bus_init( - unsigned int ioarea, - unsigned int freq, - struct ambapp_bus *abus) -{ - int i; - - ambapp_find_buses(ioarea, abus); - for (i = 0; i < 6; i++) - if (abus->ioareas[i] == 0) - break; - abus->buses = i; - abus->freq = freq; -} - -/* Parse APB PnP Information */ -void ambapp_apb_parse(struct ambapp_find_apb_info *info, ambapp_apbdev *dev) -{ - struct ambapp_pnp_apb *apb = info->pnp; - unsigned int apbbase = (unsigned int)apb & 0xfff00000; - - dev->vendor = amba_vendor(apb->id); - dev->device = amba_device(apb->id); - dev->irq = amba_irq(apb->id); - dev->ver = amba_ver(apb->id); - dev->address = (apbbase | (((apb->iobar & 0xfff00000) >> 12))) & - (((apb->iobar & 0x0000fff0) << 4) | 0xfff00000); - dev->mask = amba_apb_mask(apb->iobar); - dev->ahb_bus_index = info->ahb_bus_index - 1; -} - -/* Parse AHB PnP information */ -void ambapp_ahb_parse(struct ambapp_find_ahb_info *info, ambapp_ahbdev *dev) -{ - struct ambapp_pnp_ahb *ahb = info->pnp; - unsigned int ahbbase = (unsigned int)ahb & 0xfff00000; - int i, type; - unsigned int addr, mask, mbar; - - dev->vendor = amba_vendor(ahb->id); - dev->device = amba_device(ahb->id); - dev->irq = amba_irq(ahb->id); - dev->ver = amba_ver(ahb->id); - dev->userdef[0] = ahb->custom[0]; - dev->userdef[1] = ahb->custom[1]; - dev->userdef[2] = ahb->custom[2]; - dev->ahb_bus_index = info->ahb_bus_index - 1; - for (i = 0; i < 4; i++) { - mbar = ahb->mbar[i]; - addr = amba_membar_start(mbar); - type = amba_membar_type(mbar); - if (type == AMBA_TYPE_AHBIO) { - addr = amba_ahbio_adr(addr, ahbbase); - mask = (((unsigned int) - (amba_membar_mask((~mbar))<<8)|0xff))+1; - } else { - /* AHB memory area, absolute address */ - mask = (~((unsigned int) - (amba_membar_mask(mbar)<<20)))+1; - } - dev->address[i] = addr; - dev->mask[i] = mask; - dev->type[i] = type; - } -} - -int ambapp_apb_find(struct ambapp_bus *abus, int vendor, int device, - int index, ambapp_apbdev *dev) -{ - unsigned int devid = AMBA_PNP_ID(vendor, device); - int found; - struct ambapp_find_apb_info apbdev; - - found = ambapp_find_apb(abus, devid, index, &apbdev); - if (found == 1) - ambapp_apb_parse(&apbdev, dev); - - return found; -} - -int ambapp_apb_count(struct ambapp_bus *abus, int vendor, int device) -{ - unsigned int devid = AMBA_PNP_ID(vendor, device); - int found; - struct ambapp_find_apb_info apbdev; - - found = ambapp_find_apb(abus, devid, 63, &apbdev); - if (found == 1) - return 64; - else - return 63 - apbdev.dec_index; -} - -int ambapp_ahb_find(struct ambapp_bus *abus, int vendor, int device, - int index, ambapp_ahbdev *dev, int type) -{ - int found; - struct ambapp_find_ahb_info ahbdev; - unsigned int devid = AMBA_PNP_ID(vendor, device); - - found = ambapp_find_ahb(abus, devid, index, type, &ahbdev); - if (found == 1) - ambapp_ahb_parse(&ahbdev, dev); - - return found; -} - -int ambapp_ahbmst_find(struct ambapp_bus *abus, int vendor, int device, - int index, ambapp_ahbdev *dev) -{ - return ambapp_ahb_find(abus, vendor, device, index, dev, DEV_AHB_MST); -} - -int ambapp_ahbslv_find(struct ambapp_bus *abus, int vendor, int device, - int index, ambapp_ahbdev *dev) -{ - return ambapp_ahb_find(abus, vendor, device, index, dev, DEV_AHB_SLV); -} - -int ambapp_ahb_count(struct ambapp_bus *abus, int vendor, int device, int type) -{ - int found; - struct ambapp_find_ahb_info ahbdev; - unsigned int devid = AMBA_PNP_ID(vendor, device); - - found = ambapp_find_ahb(abus, devid, 63, type, &ahbdev); - if (found == 1) - return 64; - else - return 63 - ahbdev.dec_index; -} - -int ambapp_ahbmst_count(struct ambapp_bus *abus, int vendor, int device) -{ - return ambapp_ahb_count(abus, vendor, device, DEV_AHB_MST); -} - -int ambapp_ahbslv_count(struct ambapp_bus *abus, int vendor, int device) -{ - return ambapp_ahb_count(abus, vendor, device, DEV_AHB_SLV); -} - -/* The define CONFIG_SYS_GRLIB_SINGLE_BUS may be defined on GRLIB systems - * where only one AHB Bus is available - no bridges are present. This option - * is available only to reduce the footprint. - * - * Defining this on a multi-bus GRLIB system may also work depending on the - * design. - */ - -#ifndef CONFIG_SYS_GRLIB_SINGLE_BUS - -/* GAISLER AHB2AHB Version 1 Bridge Definitions */ -#define AHB2AHB_V1_FLAG_FFACT 0x0f0 /* Frequency factor against top bus */ -#define AHB2AHB_V1_FLAG_FFACT_DIR 0x100 /* Factor direction, 0=down, 1=up */ -#define AHB2AHB_V1_FLAG_MBUS 0x00c /* Master bus number mask */ -#define AHB2AHB_V1_FLAG_SBUS 0x003 /* Slave bus number mask */ - -/* Get Parent bus frequency. Note that since we go from a "child" bus - * to a parent bus, the frequency factor direction is inverted. - */ -unsigned int gaisler_ahb2ahb_v1_freq(ambapp_ahbdev *ahb, unsigned int freq) -{ - int dir; - unsigned char ffact; - - /* Get division/multiple factor */ - ffact = (ahb->userdef[0] & AHB2AHB_V1_FLAG_FFACT) >> 4; - if (ffact != 0) { - dir = ahb->userdef[0] & AHB2AHB_V1_FLAG_FFACT_DIR; - - /* Calculate frequency by dividing or - * multiplying system frequency - */ - if (dir) - freq = freq * ffact; - else - freq = freq / ffact; - } - - return freq; -} - -/* AHB2AHB and L2CACHE ver 2 is not supported yet. */ -unsigned int gaisler_ahb2ahb_v2_freq(ambapp_ahbdev *ahb, unsigned int freq) -{ - panic("gaisler_ahb2ahb_v2_freq: AHB2AHB ver 2 not supported\n"); - return -1; -} -#endif - -/* Return the frequency of a AHB bus identified by index found - * note that this is not the AHB Bus number. - */ -unsigned int ambapp_bus_freq(struct ambapp_bus *abus, int ahb_bus_index) -{ - unsigned int freq = abus->freq; -#ifndef CONFIG_SYS_GRLIB_SINGLE_BUS - unsigned int ioarea, ioarea_parent, bridge_pnp_ofs; - struct ambapp_find_ahb_info ahbinfo; - ambapp_ahbdev ahb; - int parent; - - debug("ambapp_bus_freq: get freq on bus %d\n", ahb_bus_index); - - while (ahb_bus_index != 0) { - debug(" BUS[0]: 0x%08x\n", abus->ioareas[0]); - debug(" BUS[1]: 0x%08x\n", abus->ioareas[1]); - debug(" BUS[2]: 0x%08x\n", abus->ioareas[2]); - debug(" BUS[3]: 0x%08x\n", abus->ioareas[3]); - debug(" BUS[4]: 0x%08x\n", abus->ioareas[4]); - debug(" BUS[5]: 0x%08x\n", abus->ioareas[5]); - - /* Get I/O area of AHB bus */ - ioarea = abus->ioareas[ahb_bus_index]; - - debug(" IOAREA: 0x%08x\n", ioarea); - - /* Get parent bus */ - parent = (ioarea & 0x7); - if (parent == 0) { - panic("%s: parent=0 indicates no parent! Stopping.\n", - __func__); - return -1; - } - parent = parent - 1; - bridge_pnp_ofs = ioarea & 0x7e0; - - debug(" PARENT: %d\n", parent); - debug(" BRIDGE_OFS: 0x%08x\n", bridge_pnp_ofs); - - /* Get AHB/AHB bridge PnP address */ - ioarea_parent = (abus->ioareas[parent] & 0xfff00000) | - AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA; - ahbinfo.pnp = (struct ambapp_pnp_ahb *) - (ioarea_parent | bridge_pnp_ofs); - - debug(" IOAREA PARENT: 0x%08x\n", ioarea_parent); - debug(" BRIDGE PNP: 0x%p\n", ahbinfo.pnp); - - /* Parse the AHB information */ - ahbinfo.ahb_bus_index = parent; - ambapp_ahb_parse(&ahbinfo, &ahb); - - debug(" BRIDGE ID: VENDOR=%d(0x%x), DEVICE=%d(0x%x)\n", - ahb.vendor, ahb.vendor, ahb.device, ahb.device); - - /* Different bridges may convert frequency differently */ - if ((ahb.vendor == VENDOR_GAISLER) && - ((ahb.device == GAISLER_AHB2AHB) || - (ahb.device == GAISLER_L2CACHE))) { - /* Get new frequency */ - if (ahb.ver > 1) - freq = gaisler_ahb2ahb_v2_freq(&ahb, freq); - else - freq = gaisler_ahb2ahb_v1_freq(&ahb, freq); - - debug(" NEW FREQ: %dHz\n", freq); - } else { - panic("%s: unsupported AMBA bridge\n", __func__); - return -1; - } - - /* Step upwards towards system top bus */ - ahb_bus_index = parent; - } -#endif - - debug("ambapp_bus_freq: %dHz\n", freq); - - return freq; -} diff --git a/arch/sparc/cpu/leon3/ambapp_low.S b/arch/sparc/cpu/leon3/ambapp_low.S deleted file mode 100644 index 2863586dc1..0000000000 --- a/arch/sparc/cpu/leon3/ambapp_low.S +++ /dev/null @@ -1,784 +0,0 @@ -/* GRLIB AMBA Plug&Play information scanning implemented without - * using memory (stack) and one register window. The code scan - * the PnP info and inserts the AHB bridges/buses into register - * i0-i5. - * The code support - * - up to 6 AHB buses - * - multiple APB buses - * - support for AHB2AHB & L2CACHE bridges - * - * (C) Copyright 2010, 2015 - * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <ambapp.h> - - .seg "text" - .globl _nomem_amba_init - .globl _nomem_ambapp_find_buses - .globl _nomem_find_apb - .globl _nomem_find_ahb - -/* Overview - * ======== - * - * _nomem_amba_init - Init AMBA bus and calls _nomem_ambapp_find_buses - * _nomem_ambapp_find_buses - Scan AMBA PnP info for AHB buses/bridges and - * place them in i0-i5, see below - * _nomem_find_apb - Find one APB device identified by VENDOR:DEVICE - * ID and an index. - * _nomem_find_ahb - Find one AHB Master or Slave device identified - * by VENDOR:DEVICE ID and an index. - * init_ahb_bridges - Local function. Clears i0-i5 - * insert_ahb_bridge - Local function. Insert a new AHB bus into first - * free register in i0-i5. It also checks that the - * bus has not already been added. - * get_ahb_bridge - Local function. Get AHB bus from registers, - * return register iN, where N is defined by o0. - * - * The _nomem_find_apb and _nomem_find_ahb function requires that i0-i5 - * are populated with the AHB buses of the system. The registers are - * initialized by _nomem_ambapp_find_buses. - * - * AHB Bus result and requirements of i0-i5 - * ======================================== - * - * i0: AHB BUS0 IOAREA, no parent bus - * i1: AHB BUS1 IOAREA, parent bus is always i0 (AHB BUS0) and bridge address - * i2: AHB BUS2 IOAREA, 3-bit parent bus number and bridge address - * i3: AHB BUS3 IOAREA, 3-bit parent bus number and bridge address - * i4: AHB BUS4 IOAREA, 3-bit parent bus number and bridge address - * i5: AHB BUS5 IOAREA, 3-bit parent bus number and bridge address - * - * AHB BUS - * ------- - * Bits 31-20 (0xfff00000) contain the found bus I/O Area (AHB PnP area). - * - * 3-bit Parent bus - * ---------------- - * Bits 2-0 (0x00000007) contain parent bus number. Zero if no parent - * bus, 1 = parent is AHB BUS 0 (i0), 2 = parent is AHB BUS 1 (i1).. - * - * Bridge Address - * -------------- - * Bits 10-5 (0x000007e0) contain the index of the Bridge's PnP - * information on the parent. Since all bridges are found in the - * PnP information they all have a PnP entry. Together with the - * parent bus number the PnP entry can be found: - * PnPEntry = (BRIDGE_ADDRESS + (iN & 0xfff00000)) | 0x000ff800 - * where N is the parent bus minus one. - * - */ - -/* Function initializes the AHB Bridge I/O AREA storage. (Clears i0-i5) - * - * Arguments - * none - * - * Results - * none - * - * Clobbered - * none - */ - -init_ahb_bridges: - mov %g0, %i0 - mov %g0, %i1 - mov %g0, %i2 - mov %g0, %i3 - mov %g0, %i4 - retl - mov %g0, %i5 - -/* Function returns AHB Bridge I/O AREA for specified bus. - * - * Arguments - * - o0 = bus number - * - * Results - * - o0 = I/O AREA - * - * Clobbered - * none - */ -get_ahb_bridge: - cmp %o0, 1 - be,a L1 - mov %i0, %o0 - - cmp %o0, 2 - be,a L1 - mov %i1, %o0 - - cmp %o0, 3 - be,a L1 - mov %i2, %o0 - - cmp %o0, 4 - be,a L1 - mov %i3, %o0 - - cmp %o0, 5 - be,a L1 - mov %i4, %o0 - - cmp %o0, 6 - be,a L1 - mov %i5, %o0 - - /* o0 > 6: only 6 buses supported */ - mov %g0, %o0 -L1: - retl - nop - -/* Function adds a AHB Bridge I/O AREA to the i0-i5 registers if - * not already added. It stores the bus PnP start information. - * - * Arguments - * - o0 = AHB Bridge I/O area - * - * Results - * none - * - * Clobbered - * o2, o3 - */ -insert_ahb_bridge: - /* Check that bridge hasn't already been added */ - andn %o0, 0x7ff, %o2 - andn %i0, 0x7ff, %o3 - cmp %o3, %o2 - be L2 - andn %i1, 0x7ff, %o3 - cmp %o3, %o2 - be L2 - andn %i2, 0x7ff, %o3 - cmp %o3, %o2 - be L2 - andn %i3, 0x7ff, %o3 - cmp %o3, %o2 - be L2 - andn %i4, 0x7ff, %o3 - cmp %o3, %o2 - be L2 - andn %i5, 0x7ff, %o3 - cmp %o3, %o2 - be L2 - - /* Insert into first free posistion */ - cmp %i0, %g0 - be,a L2 - mov %o0, %i0 - - cmp %i1, %g0 - be,a L2 - mov %o0, %i1 - - cmp %i2, %g0 - be,a L2 - mov %o0, %i2 - - cmp %i3, %g0 - be,a L2 - mov %o0, %i3 - - cmp %i4, %g0 - be,a L2 - mov %o0, %i4 - - cmp %i5, %g0 - be,a L2 - mov %o0, %i5 -L2: - retl - nop - -/* FUNCTION int _nomem_find_ahb_bus( - * unsigned int bridge, - * int vendor_device, - * int index, - * void **pconf, - * int not_used, - * int option - * ) - * - * Scans the AHB Master or Slave area for a matching VENDOR:DEVICE, the - * index is decremented when a matching device is found but index is - * greater than zero. When index is zero and a matching DEVICE:VENDOR - * is found the AHB configuration address and AHB I/O area is returned. - * - * i0-i7,l0,l1,l2,l3,l4,g2,o6 is not available for use. - * o1,o5 Must be left untouched - * - * Results - * - o0 Number of found devices (1 or 0) - * - o2 is decremented for each matching VENDOR:DEVICE found, zero if found - * - o3 Address of the AHB PnP configuration entry (Only valid if o0=1) - * - * Clobbered - * - o3 (Clobbered when no device was found) - * - o4 (Number of Devices left to search) - * - o0 (Bus ID, PnP ID, Device) - */ -_nomem_find_ahb_bus: - - /* Get the number of Slaves/Masters. - * Only AHB Bus 0 has 64 AHB Masters/Slaves the - * other AHB buses has 16 slaves and 16 masters. - */ - add %g0, 16, %o4 /* Defaulting to 16 */ - andcc %o0, 0x7, %g0 /* 3-bit bus id */ - be,a .L_maxloops_detected - add %g0, 64, %o4 /* AHB Bus 0 has 64 AHB Masters/Slaves */ -.L_maxloops_detected: - - /* Get start address of AHB Slave or AHB Master area depending on what - * we are searching for. - */ - andn %o0, 0x7ff, %o0 /* Remove Bus ID and 5-bit AHB/AHB - * Bridge PnP Address to get I/O Area */ - set AMBA_CONF_AREA, %o3 - or %o3, %o0, %o3 /* Master area address */ - - cmp %o5, DEV_AHB_SLV - be,a .L_conf_area_calculated - or %o3, AMBA_AHB_SLAVE_CONF_AREA, %o3 /* Add 0x800 to get to slave area */ -.L_conf_area_calculated: - - /* Iterate over all AHB device and try to find matching DEVICE:VENDOR - * o1 - VENDOR|DEVICE - * o2 - Index - * o3 - Current AHB Device Configuration address - * o5 - Type (leave untouched) - * - * o4 - Number of AHB device left to process - * o0 - tmp - */ -.L_process_one_conf: - ld [%o3], %o0 - andn %o0, 0xfff, %o0 - cmp %o0, 0 /* No device if zero */ - beq .L_next_conf - cmp %o1, 0 /* If VENDOR:DEVICE==0, consider all matching */ - beq .L_process_ahb_dev_found - cmp %o0, %o1 /* Does VENDOR and DEVICE Match? */ - bne .L_next_conf - nop -.L_process_ahb_dev_found: - /* Found a Matching VENDOR:DEVICE, index must also match */ - cmp %o2, %g0 - bne .L_next_conf - dec %o2 - /* Index matches also, return happy with o3 set to AHB Conf Address */ - mov %g0, %o2 - retl - add %g0, 1, %o0 - -.L_next_conf: - subcc %o4, 1, %o4 /* One device has been processed, - * Are there more devices to process? */ - bne .L_process_one_conf - add %o3, AMBA_AHB_CONF_LENGH, %o3 /* Next Configuration entry */ - /* No Matching device found */ - retl - mov %g0, %o0 - -/* FUNCTION int _nomem_find_ahb( - * int unused, - * int vendor_device, - * int index, - * void **pconf, - * int *ahb_bus_index, - * int option, - * ) - * - * Find a AHB Master or AHB Slave device, it puts the address of the AHB PnP - * configuration in o3 (pconf), the I/O Area base address in o4 (pioarea). - * - * Calls _nomem_find_ahb_bus for every AHB bus. - * - * i0-i7, l0, l1, o6, g1, g4-g7 is not available for use. - * - * Arguments - * - o0 Unused - * - * Results - * - o0 Number of found devices (1 or 0) - * - o2 Decremented Index (Zero if found) - * - o3 Address of the AHB PnP configuration entry - * - o4 AHB Bus index the device was found on (if o0=1) - * - o5 Left untouched - * - * Clobbered - * - o0 (AHB Bridge and used by _nomem_find_ahb_bus) - * - o2 (index is decremented) - * - l2 (Current AHB Bus index) - * - g2 (return address) - */ -_nomem_find_ahb: - mov %o7, %g2 /* Save return address */ - /* Scan all AHB Buses found for the AHB Master/Slave matching VENDOR:DEVICE */ - clr %l2 -.L_search_next_ahb_bus: - add %l2, 1, %l2 - call get_ahb_bridge /* Get bus %l0 I/O Area */ - mov %l2, %o0 - cmp %o0, %g0 - be .L_no_device_found /* If no more AHB bus is left to be scanned, proceed */ - nop - call _nomem_find_ahb_bus /* Scan AHB bus %o0 for VENDOR:DEVICE. Index in o3 is decremented */ - nop - cmp %o0, %g0 /* If VENDOR:DEVICE was not found scan next AHB Bus */ - be .L_search_next_ahb_bus /* Do next bus is o0=0 (not found) */ - nop - /* The device was found, o0 is 1 */ - mov %g2, %o7 /* Restore return address */ - retl - mov %l2, %o4 /* The AHB bus index the device was found on */ - - /* No device found matching */ -.L_no_device_found: - mov %g2, %o7 /* Restore return address */ - retl - mov %g0, %o0 - - -/* FUNCTION int _nomem_find_apb_bus( - * int apbmst, - * int vendor_device, - * int index, - * void **pconf - * ) - * - * Find a APB Slave device, it puts the address of the APB PnP configuration - * in o3 (pconf). - * - * Calls _nomem_find_ahb_bus for every AHB bus searching for AHB/APB Bridges. - * The AHB/APB bridges are AHB Slaves with ID GAISLER_APBMST. - * - * Results - * - o0 Number of found devices (1 or 0) - * - o2 Decremented Index - * - o3 Address of the found APB device PnP configuration entry - * - * Clobbered - * - o5 PnP VENDOR:DEVICE ID - */ - -_nomem_find_apb_bus: - set AMBA_CONF_AREA, %o3 - or %o0, %o3, %o3 /* Calc start of APB device PnP info */ - add %g0, 16, %o0 /* o0, number of APB Slaves left to scan */ -.L_process_one_apb_conf: - ld [%o3], %o5 - andn %o5, 0xfff, %o5 - cmp %o5, 0 /* No device if zero */ - beq .L_process_apb_dev_not_found - cmp %o1, 0 /* If VENDOR:DEVICE == -1, consider all matching */ - beq .L_process_apb_dev_found - cmp %o1, %o5 /* Found VENDOR:DEVICE */ - bne .L_process_apb_dev_not_found - nop - -.L_process_apb_dev_found: - /* Found matching device, compare index */ - cmp %o2, %g0 - bne .L_process_apb_dev_not_found - dec %o2 - /* Matching index and VENDOR:DEVICE */ - retl - add %g0, 1, %o0 - -.L_process_apb_dev_not_found: - subcc %o0, 1, %o0 - bne .L_process_one_apb_conf - add %o3, 8, %o3 - retl - mov %g0, %o0 - -/* FUNCTION int _nomem_find_apb( - * int unused, - * int vendor_device, - * int index, - * void **pconf, - * int *ahb_bus_index - * ) - * - * Find a APB Slave device, it puts the address of the APB PnP configuration - * in o3 (pconf), the APB Master I/O Area base address in o4 (papbarea). - * - * Calls _nomem_find_ahb_bus for every AHB bus searching for AHB/APB Bridges. - * The AHB/APB bridges are AHB Slaves with ID GAISLER_APBMST. - * - * i0-i7, l0, l1, o6 is not available for use. - * - * Arguments - * - o0 Unused - * - * Results - * - o0 Number of found devices (1 or 0) - * - o2 Decremented Index if not found - * - o3 Address of the APB PnP configuration entry - * - o4 AHB Bus index of APB Bridge/APB Device - * - * Clobbered - * - o0 (AHB Bridge) - * - o2 (index is decremented) - * - l2 (APB DEV Index [7..4] : APBMST AHB Index [3..0]) - * - l3 (Current AHB Bus index) - * - l4 (temporary storage for APB VENDOR:DEVICE) - * - o5 (AHB Slave ID) - * - o0 (clobbered by _nomem_find_ahb_bus) - * - g2 (Return address) - */ -_nomem_find_apb: - /* Scan all AHB Buses found for AHB/APB Bridges */ - mov %o7, %g2 /* Save return address */ - mov %o1, %l4 /* Save APB VENDOR:DEVICE */ - sll %o2, 4, %l2 /* APB MST index = 0 */ - add %g0, 1, %l3 /* AHB Bus index = 0 */ -.L2_search_next_ahb_bus: - call get_ahb_bridge /* Get bus %l3 I/O Area */ - mov %l3, %o0 - cmp %o0, %g0 - be .L2_no_device_found /* If no more AHB bus is left to be scanned, proceed */ - add %g0, DEV_AHB_SLV, %o5 /* Search for AHB Slave */ - sethi %hi(AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_APBMST)), %o1 - call _nomem_find_ahb_bus /* Scan AHB bus %o0 for VENDOR:DEVICE. Index in o3 is decremented */ - and %l2, 0xf, %o2 /* Set APBMST index */ - cmp %o0, %g0 /* If no AHB/APB Bridge was not found, scan next AHB Bus */ - be .L_no_apb_bridge_found /* Do next bus */ - nop - - /* The AHB/APB Bridge was found. - * Search for the requested APB Device on the APB bus using - * find_apb_bus, it will decrement the index. - */ - ld [%o3 + AMBA_AHB_MBAR0_OFS], %o3 - sll %o3, 16, %o0 - and %o0, %o3, %o0 /* Address AND Address Mask */ - sethi %hi(0xfff00000), %o3 - and %o0, %o3, %o0 /* AHB/APB Bridge address */ - - srl %l2, 4, %o2 /* APB DEV Index */ - call _nomem_find_apb_bus - mov %l4, %o1 /* APB VENDOR:DEVICE */ - cmp %o0, %g0 - be .L_apb_dev_not_found - mov %g2, %o7 /* Restore return address */ - /* APB Device found - * o0 1 - * o2 Index is decremented to zero - * o3 APB configuration address, - * o4 APB Bridge Configuration address. - */ - mov %g0, %o2 - retl - mov %l3, %o4 - -.L_apb_dev_not_found: - /* Update APB DEV Index by saving output from find_apb_bus - * (index parameter) into bits [31..4] in L2. - */ - sll %o2, 4, %o2 - and %l2, 0xf, %l2 - or %o2, %l2, %l2 - /* Try finding the next AHB/APB Bridge on the same AHB bus - * to find more APB devices - */ - ba .L2_search_next_ahb_bus /* Find next AHB/APB bridge */ - inc %l2 - -.L_no_apb_bridge_found: - inc %l3 /* Next AHB Bus */ - ba .L2_search_next_ahb_bus /* Process next AHB bus */ - andn %l2, 0xf, %l2 /* Start at APB Bridge index 0 at every AHB Bus */ - /* No device found matching */ -.L2_no_device_found: - mov %g2, %o7 /* Restore return address */ - srl %l2, 4, %o2 /* APB DEV Index */ - retl - mov %g0, %o0 - - - -/* FUNCTION _nomem_amba_scan_gaisler_ahb2ahb_bridge(unsigned int bridge, int bus) - * - * Constraints: - * - o1 may not be used - * - o0, o2, o3 may be used. - * - * Arguments - * - o0 PnP Address of Bridge AHB device - * - o2 PnP ID of AHB device - * - * Results - * - o0 Address of new bus PnP area or a 1 if AHB device is no bridge - * - * Clobbered - * - o0, o2 - * - */ -_nomem_amba_scan_gaisler_ahb2ahb_bridge: - andn %o2, 0xfff, %o2 - sethi %hi(AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_AHB2AHB)), %o3 - cmp %o2, %o3 - beq .L_is_ahb2ahb_bridge - nop - - retl - add %g0, 1, %o0 - -.L_is_ahb2ahb_bridge: - /* Found a GAISLER AHB2AHB bridge */ - retl - ld [%o0 + AMBA_AHB_CUSTOM1_OFS], %o0 /* Get address of bridge PnP area */ - - -/* FUNCTION _nomem_amba_scan_gaisler_l2cache_bridge(unsigned int bridge, int bus) - * - * Constraints: - * - o1 may not be used - * - o0, o2, o3 may be used. - * - * Arguments - * - o0 PnP Address of Bridge AHB device - * - o2 PnP ID of AHB device - * - * Results - * - o0 Address of new bus PnP area or a 1 if AHB device is no bridge - * - * Clobbered - * - o0, o2 - * - */ -_nomem_amba_scan_gaisler_l2cache_bridge: - andn %o2, 0xfff, %o2 - sethi %hi(AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_L2CACHE)), %o3 - cmp %o2, %o3 - beq .L_is_l2cache_bridge - nop - - retl - add %g0, 1, %o0 - -.L_is_l2cache_bridge: - /* Found a GAISLER l2cache bridge */ - retl - ld [%o0 + AMBA_AHB_CUSTOM1_OFS], %o0 /* Get address of bridge PnP area */ - - -/* FUNCTION _nomem_amba_scan(unsigned int bridge, int bus) - * - * Constraints: - * i0-i7, l0 is used by caller - * o5-o7 may not be used. - * - * Arguments - * - o0 Bridge Information: I/O AREA and parent bus - * - o1 Bus - * - * Results - * - o0 Number of AHB bridges found - * - * Clobbered - * - o0 (Current AHB slave conf address) - * - o2 (Used by insert_bridge) - * - o3 (Used by insert_bridge) - * - l1 (Number of AHB Slaves left to process) - * - l2 (Current AHB slave conf address) - * - g2 (Return address) - */ -_nomem_amba_scan: - mov %o7, %g2 /* Save return address */ - set 16, %l1 - cmp %o1, 1 - be,a .L2_maxloops_detected - add %g0, 64, %l1 -.L2_maxloops_detected: - - /* Clear 3-bit parent bus from bridge to get I/O AREA, then or - * (AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA) to get first AHB slave - * conf address. - */ - andn %o0, 0x7ff, %o0 - set (AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA), %l2 - or %o0, %l2, %l2 - - /* Scan AHB Slave area for AHB<->AHB bridges. For each AHB device - * all "bridge drivers" are called, the driver function interface: - * - * Input: - * - o0 PnP Address of Bridge AHB device - * - o2 PnP ID of AHB device - * Return values: - * - o0 Address of new bus PnP area, returning a 1 in o2 means not found - * - * Constraints: - * - o1 may not be used - * - o0, o2, o3 may be used. - * - */ -.L_scan_one_ahb_slave: - ld [%l2], %o2 - - cmp %o2, %g0 - beq .L_scan_next_ahb_slave - nop - - /* Call the GAISLER AHB2AHB bridge driver */ - call _nomem_amba_scan_gaisler_ahb2ahb_bridge - mov %l2, %o0 - cmp %o0, 1 - bne .L_found_bridge - ld [%l2], %o2 - - /* Call the GAISLER L2CACHE bridge driver */ - call _nomem_amba_scan_gaisler_l2cache_bridge - mov %l2, %o0 - cmp %o0, 1 - bne .L_found_bridge - ld [%l2], %o2 - - /* Insert next bridge "driver" function here */ - - - /* The PnP ID did not match a bridge - a new bus was not found ==> - * step to next AHB device */ - ba .L_scan_next_ahb_slave - nop - - /* Add Found bus */ -.L_found_bridge: - and %l2, 0x7e0, %o2 - or %o2, %o0, %o0 /* Add AHB/AHB Bridge PnP address */ - call insert_ahb_bridge /* Insert Bridge into found buses storage */ - or %o1, %o0, %o0 /* Add parent bus LSB 3-bits */ - -.L_scan_next_ahb_slave: - /* More Slaves to process? */ - subcc %l1, 1, %l1 - bne .L_scan_one_ahb_slave - add %l2, AMBA_AHB_CONF_LENGH, %l2 - - /* No more AHB devices to process */ - mov %g2, %o7 /* Restore return address */ - retl - nop - -/* FUNCTION _nomem_ambapp_find_buses(unsigned int ioarea) - * - * Find AMBA AHB buses. - * - * Constraints: - * i6-i7, l7 is used by caller - * - * Arguments - * - o0 Bridge Information: I/O AREA and parent bus - * - * Results - * - o0 Number of AHB bridges found - * - i0-i5 initialized - * - * Clobbered - * - o0 (Current AHB slave conf address) - * - o2 (Used by insert_bridge) - * - o3 (Used by insert_bridge) - * - l0 (Current AHB Bus) - * - l1 (Used by nomem_amba_scan) - * - l2 (Used by nomem_amba_scan) - * - l3 (Used by nomem_amba_scan) - * - l4 (Used by nomem_amba_scan) - * - * - g1 (level 1 return address) - * - g2 (Used by nomem_amba_scan) - */ -_nomem_ambapp_find_buses: - mov %o7, %g1 /* Save return address */ - - /* Initialize AHB Bus storage */ - call init_ahb_bridges - nop - - /* Insert AHB Bus 0 */ - call insert_ahb_bridge - nop /* Argument already prepared by caller */ - - /* Scan AHB Bus 0 for AHB Bridges */ - call _nomem_amba_scan - add %g0, 1, %o1 - - /* Scan all AHB Buses found for more AHB Bridges */ - add %g0, 2, %l0 -.L100_search_next_ahb_bus: - call get_ahb_bridge /* Get bus %l0 I/O Area */ - mov %l0, %o0 - cmp %o0, %g0 - be .L100_return /* If no more AHB bus is left to be scanned, proceed */ - nop - call _nomem_amba_scan /* Scan bus %l0 for AHB Bridges. i0-i7,l0 is used */ - mov %l0, %o1 /* I/O AREA untouched in o0 */ - ba .L100_search_next_ahb_bus /* Do next bus */ - add %l0, 1, %l0 - -.L100_return: - mov %g1, %o7 - retl - nop - - -/* FUNCTION _nomem_amba_init(unsigned int ioarea) - * - * Find all AHB buses - * - * Constraints: - * i6, i7, o6, o7, l7, l6, g3, g4, g5, g6, g7 is used by caller - * - * Arguments - * - o0 Bridge Information: I/O AREA and parent bus - * - * Results - * - o0 Number of AHB bridges found - * - * Clobbered - * - l0, l1, l2, l3, l4, g1, g2 (used by _nomem_ambapp_find_buses) - * - o0, o1, o2, o3 (Used as arguments) - * - o5 (return address) - * - g1 (level 1 return address) - * - g2 (level 2 return address) - */ -_nomem_amba_init: - mov %o7, %o5 /* Save return address, o5 not used */ - - /* Scan for buses, it will init i0-i5 */ - call _nomem_ambapp_find_buses - nop - - mov %o5, %o7 - retl - nop - -/* Call tree and their return address register - * - *_nomem_amba_scan (g1) - * -> init_ahb_bridges (o7) - * -> insert_ahb_bridge (o7) - * -> _nomem_amba_scan (g2) - * -> insert_ahb_bridge (o7) - * -> get_ahb_bridge (o7) - * - * - * -> _nomem_find_apb (g2) - * -> get_ahb_bridge (o7) - * -> _nomem_find_ahb_bus (o7) - * -> _nomem_find_apb_bus (o7) - * -> _nomem_find_ahb (g2) - * -> get_ahb_bridge (o7) - * -> _nomem_find_ahb_bus (o7) - * -> mem_handler.func() (o7) - * - */ diff --git a/arch/sparc/cpu/leon3/ambapp_low_c.S b/arch/sparc/cpu/leon3/ambapp_low_c.S deleted file mode 100644 index 42288fac59..0000000000 --- a/arch/sparc/cpu/leon3/ambapp_low_c.S +++ /dev/null @@ -1,113 +0,0 @@ -/* C-interface for AMBA PnP scanning functions implemented in - * ambapp_low.S. At the point the memory and stack can be - * used. - * - * (C) Copyright 2010, 2015 - * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - - - .seg "text" - .extern _nomem_ambapp_find_buses - .extern _nomem_find_apb - .extern _nomem_find_ahb - - .globl ambapp_find_buses - .globl ambapp_find_apb - .globl ambapp_find_ahb - - -/* C-interface for _nomem_ambapp_find_buses used when memory is available. - */ -ambapp_find_buses: - save %sp, -104, %sp - mov %i1, %l7 /* Save second argument */ - call _nomem_ambapp_find_buses - mov %i0, %o0 - - /* Store result */ - st %g0, [%l7+0x00] - st %i0, [%l7+0x04] - st %i1, [%l7+0x08] - st %i2, [%l7+0x0c] - st %i3, [%l7+0x10] - st %i4, [%l7+0x14] - st %i5, [%l7+0x18] - - ret - restore - -/* C-interface for _nomem_find_apb used when memory is available. - * - * void ambapp_find_apb( - * struct ambapp_bus *abus, - * unsigned int dev_vend, - * int index, - * struct ambapp_find_apb_info *result - * ); - * - */ -ambapp_find_apb: - save %sp, -104, %sp - - mov %i3, %l7 /* Save second argument */ - mov %i1, %o1 - mov %i2, %o2 - - /* Initialize buses available in system */ - ld [%i0+0x08], %i1 - ld [%i0+0x0c], %i2 - ld [%i0+0x10], %i3 - ld [%i0+0x14], %i4 - ld [%i0+0x18], %i5 - - call _nomem_find_apb - ld [%i0+0x04], %i0 - - st %o2, [%l7+0x08] /* Decremented Index */ - st %o3, [%l7] /* PnP configuration address of APB Device */ - st %o4, [%l7+0x04] /* AHB Bus Index of AHB/APB bridge and APB Device */ - mov %o0, %i0 - ret - restore - -/* C-interface for _nomem_find_ahb used when memory is available. - * - * void ambapp_find_ahb( - * struct ambapp_bus *abus, - * unsigned int dev_vend, - * int index, - * int type, - * struct ambapp_find_ahb_info *result - * ); - * - */ -ambapp_find_ahb: - save %sp, -104, %sp - - mov %i4, %l7 /* Save second argument */ - clr %o0 - mov %i1, %o1 - mov %i2, %o2 - clr %o3 - clr %o4 - mov %i3, %o5 - - /* Initialize buses available in system */ - ld [%i0+0x08], %i1 - ld [%i0+0x0c], %i2 - ld [%i0+0x10], %i3 - ld [%i0+0x14], %i4 - ld [%i0+0x18], %i5 - - call _nomem_find_ahb - ld [%i0+0x04], %i0 - - st %o2, [%l7+0x08] /* Decremented Index */ - st %o3, [%l7] /* PnP configuration address of AHB Device */ - st %o4, [%l7+0x04] /* AHB Bus Index of AHB Device */ - mov %o0, %i0 - ret - restore diff --git a/arch/sparc/cpu/leon3/cpu.c b/arch/sparc/cpu/leon3/cpu.c deleted file mode 100644 index 149e5c69e6..0000000000 --- a/arch/sparc/cpu/leon3/cpu.c +++ /dev/null @@ -1,113 +0,0 @@ -/* CPU specific code for the LEON3 CPU - * - * (C) Copyright 2007, 2015 - * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <watchdog.h> -#include <command.h> -#include <netdev.h> - -#include <asm/io.h> -#include <asm/processor.h> -#include <ambapp.h> - -DECLARE_GLOBAL_DATA_PTR; - -extern void _reset_reloc(void); - -int leon_cpu_cnt = 1; -int leon_ver = 3; -unsigned int leon_cpu_freq = CONFIG_SYS_CLK_FREQ; - -int cpu_freq(void) -{ - ambapp_ahbdev dev; - - if (leon_ver == 3) { - ambapp_ahbmst_find(&ambapp_plb, VENDOR_GAISLER, - GAISLER_LEON3, 0, &dev); - } else { - ambapp_ahbmst_find(&ambapp_plb, VENDOR_GAISLER, - GAISLER_LEON4, 0, &dev); - } - - leon_cpu_freq = ambapp_bus_freq(&ambapp_plb, dev.ahb_bus_index); - - return 0; -} - -int checkcpu(void) -{ - int cnt; - char str[4]; - - /* check LEON version here */ - cnt = ambapp_ahbmst_count(&ambapp_plb, VENDOR_GAISLER, GAISLER_LEON3); - if (cnt <= 0) { - cnt = ambapp_ahbmst_count(&ambapp_plb, VENDOR_GAISLER, - GAISLER_LEON4); - if (cnt > 0) - leon_ver = 4; - } - - cpu_freq(); - - str[0] = '\0'; - if (cnt > 1) { - leon_cpu_cnt = cnt; - str[0] = '0' + cnt; - str[1] = 'x'; - str[2] = '\0'; - } - printf("CPU: %sLEON%d @ %dMHz\n", str, leon_ver, - leon_cpu_freq / 1000000); - - return 0; -} - -#ifdef CONFIG_DISPLAY_CPUINFO - -int print_cpuinfo(void) -{ - printf("CPU: LEON3\n"); - return 0; -} - -#endif - -/* ------------------------------------------------------------------------- */ - -void cpu_reset(void) -{ - /* Interrupts off */ - disable_interrupts(); - - /* jump to restart in flash */ - _reset_reloc(); -} - -int do_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) -{ - cpu_reset(); - - return 1; - -} - -u64 flash_read64(void *addr) -{ - return __raw_readq(addr); -} - -/* ------------------------------------------------------------------------- */ - -#ifdef CONFIG_GRETH -int cpu_eth_init(bd_t *bis) -{ - return greth_initialize(bis); -} -#endif diff --git a/arch/sparc/cpu/leon3/cpu_init.c b/arch/sparc/cpu/leon3/cpu_init.c deleted file mode 100644 index f25388cf84..0000000000 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ /dev/null @@ -1,175 +0,0 @@ -/* Initializes CPU and basic hardware such as memory - * controllers, IRQ controller and system timer 0. - * - * (C) Copyright 2007, 2015 - * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/asi.h> -#include <asm/leon.h> -#include <asm/io.h> -#include <ambapp.h> -#include <grlib/irqmp.h> -#include <grlib/gptimer.h> -#include <debug_uart.h> - -#include <config.h> - -/* Default Plug&Play I/O area */ -#ifndef CONFIG_AMBAPP_IOAREA -#define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA -#endif - -/* Select which TIMER that will become the time base */ -#ifndef CONFIG_SYS_GRLIB_GPTIMER_INDEX -#define CONFIG_SYS_GRLIB_GPTIMER_INDEX 0 -#endif - -DECLARE_GLOBAL_DATA_PTR; - -ambapp_dev_irqmp *irqmp = NULL; - -/* - * Breath some life into the CPU... - * - * Run from FLASH/PROM: - * - until memory controller is set up, only registers available - * - memory controller has already been setup up, stack can be used - * - no global variables available for writing - * - constants available - */ -void cpu_init_f(void) -{ -#ifdef CONFIG_DEBUG_UART - debug_uart_init(); -#endif -} - -/* If cache snooping is available in hardware the result will be set - * to 0x800000, otherwise 0. - */ -static unsigned int snoop_detect(void) -{ - unsigned int result; - asm("lda [%%g0] 2, %0" : "=r"(result)); - return result & 0x00800000; -} - -int arch_cpu_init(void) -{ - ambapp_apbdev apbdev; - int index; - - gd->cpu_clk = CONFIG_SYS_CLK_FREQ; - gd->bus_clk = CONFIG_SYS_CLK_FREQ; - gd->ram_size = CONFIG_SYS_SDRAM_SIZE; - - gd->arch.snooping_available = snoop_detect(); - - /* Initialize the AMBA Plug & Play bus structure, the bus - * structure represents the AMBA bus that the CPU is located at. - */ - ambapp_bus_init(CONFIG_AMBAPP_IOAREA, CONFIG_SYS_CLK_FREQ, &ambapp_plb); - - /* Initialize/clear all the timers in the system. - */ - for (index = 0; ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, - GAISLER_GPTIMER, index, &apbdev) == 1; index++) { - ambapp_dev_gptimer *timer; - unsigned int bus_freq; - int i, ntimers; - - timer = (ambapp_dev_gptimer *)apbdev.address; - - /* Different buses may have different frequency, the - * frequency of the bus tell in which frequency the timer - * prescaler operates. - */ - bus_freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index); - - /* Initialize prescaler common to all timers to 1MHz */ - timer->scalar = timer->scalar_reload = - (((bus_freq / 1000) + 500) / 1000) - 1; - - /* Clear all timers */ - ntimers = timer->config & 0x7; - for (i = 0; i < ntimers; i++) { - timer->e[i].ctrl = GPTIMER_CTRL_IP; - timer->e[i].rld = 0; - timer->e[i].ctrl = GPTIMER_CTRL_LD; - } - } - - return 0; -} - -/* - * initialize higher level parts of CPU like time base and timers - */ -int cpu_init_r(void) -{ - ambapp_apbdev apbdev; - int cpu; - - /* - * Find AMBA APB IRQMP Controller, - */ - if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, - GAISLER_IRQMP, 0, &apbdev) != 1) { - panic("%s: IRQ controller not found\n", __func__); - return -1; - } - irqmp = (ambapp_dev_irqmp *)apbdev.address; - - /* initialize the IRQMP */ - irqmp->ilevel = 0xf; /* all IRQ off */ - irqmp->iforce = 0; - irqmp->ipend = 0; - irqmp->iclear = 0xfffe; /* clear all old pending interrupts */ - for (cpu = 0; cpu < 16; cpu++) { - /* mask and clear force for all IRQs on CPU[N] */ - irqmp->cpu_mask[cpu] = 0; - irqmp->cpu_force[cpu] = 0; - } - - return 0; -} - - ; -int timer_init(void) -{ - ambapp_dev_gptimer_element *tmr; - ambapp_dev_gptimer *gptimer; - ambapp_apbdev apbdev; - unsigned bus_freq; - - if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_GPTIMER, - CONFIG_SYS_GRLIB_GPTIMER_INDEX, &apbdev) != 1) { - panic("%s: gptimer not found!\n", __func__); - return -1; - } - - gptimer = (ambapp_dev_gptimer *) apbdev.address; - - /* Different buses may have different frequency, the - * frequency of the bus tell in which frequency the timer - * prescaler operates. - */ - bus_freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index); - - /* initialize prescaler common to all timers to 1MHz */ - gptimer->scalar = gptimer->scalar_reload = - (((bus_freq / 1000) + 500) / 1000) - 1; - - tmr = (ambapp_dev_gptimer_element *)&gptimer->e[0]; - - tmr->val = 0; - tmr->rld = ~0; - tmr->ctrl = GPTIMER_CTRL_EN | GPTIMER_CTRL_RS | GPTIMER_CTRL_LD; - - CONFIG_SYS_TIMER_COUNTER = (void *)&tmr->val; - return 0; -} diff --git a/arch/sparc/cpu/leon3/interrupts.c b/arch/sparc/cpu/leon3/interrupts.c deleted file mode 100644 index 00c3288774..0000000000 --- a/arch/sparc/cpu/leon3/interrupts.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com - * - * (C) Copyright 2006 - * Detlev Zundel, DENX Software Engineering, dzu@denx.de - * - * (C) Copyright -2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * (C) Copyright 2001 - * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <asm/stack.h> -#include <common.h> -#include <asm/io.h> -#include <asm/processor.h> -#include <command.h> -#include <asm/irq.h> - -#include <asm/leon.h> -#include <ambapp.h> -#include <grlib/irqmp.h> -#include <grlib/gptimer.h> - -/* 15 normal irqs and a non maskable interrupt */ -#define NR_IRQS 15 - -struct irq_action { - interrupt_handler_t *handler; - void *arg; - unsigned int count; -}; - -extern ambapp_dev_irqmp *irqmp; -extern ambapp_dev_gptimer *gptimer; - -static struct irq_action irq_handlers[NR_IRQS] = { {0}, }; -static int spurious_irq_cnt = 0; -static int spurious_irq = 0; - -static inline unsigned int irqmp_get_irqmask(unsigned int irq) -{ - if ((irq < 0) || (irq >= NR_IRQS)) { - return 0; - } else { - return (1 << irq); - } - -} - -static void leon3_ic_disable(unsigned int irq) -{ - unsigned int mask, pil; - if (!irqmp) - return; - - pil = intLock(); - - /* get mask of interrupt */ - mask = irqmp_get_irqmask(irq); - - /* set int level */ - irqmp->cpu_mask[0] = SPARC_NOCACHE_READ(&irqmp->cpu_mask[0]) & (~mask); - - intUnlock(pil); -} - -static void leon3_ic_enable(unsigned int irq) -{ - unsigned int mask, pil; - if (!irqmp) - return; - - pil = intLock(); - - /* get mask of interrupt */ - mask = irqmp_get_irqmask(irq); - - /* set int level */ - irqmp->cpu_mask[0] = SPARC_NOCACHE_READ(&irqmp->cpu_mask[0]) | mask; - - intUnlock(pil); - -} - -void handler_irq(int irq, struct pt_regs *regs) -{ - if (irq_handlers[irq].handler) { - if (((unsigned int)irq_handlers[irq].handler > CONFIG_SYS_RAM_END) || - ((unsigned int)irq_handlers[irq].handler < CONFIG_SYS_RAM_BASE) - ) { - printf("handler_irq: bad handler: %x, irq number %d\n", - (unsigned int)irq_handlers[irq].handler, irq); - return; - } - irq_handlers[irq].handler(irq_handlers[irq].arg); - irq_handlers[irq].count++; - } else { - spurious_irq_cnt++; - spurious_irq = irq; - } -} - -void leon3_force_int(int irq) -{ - if (!irqmp || (irq >= NR_IRQS) || (irq < 0)) - return; - printf("Forcing interrupt %d\n", irq); - - irqmp->iforce = SPARC_NOCACHE_READ(&irqmp->iforce) | (1 << irq); -} - -/****************************************************************************/ - -int interrupt_init_cpu(void) -{ - - return (0); -} - -/****************************************************************************/ - -/* - * Install and free a interrupt handler. - */ - -void irq_install_handler(int irq, interrupt_handler_t * handler, void *arg) -{ - if (irq < 0 || irq >= NR_IRQS) { - printf("irq_install_handler: bad irq number %d\n", irq); - return; - } - - if (irq_handlers[irq].handler != NULL) - printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n", - (ulong) handler, (ulong) irq_handlers[irq].handler); - - if (((unsigned int)handler > CONFIG_SYS_RAM_END) || - ((unsigned int)handler < CONFIG_SYS_RAM_BASE) - ) { - printf("irq_install_handler: bad handler: %x, irq number %d\n", - (unsigned int)handler, irq); - return; - } - irq_handlers[irq].handler = handler; - irq_handlers[irq].arg = arg; - - /* enable irq on IRQMP hardware */ - leon3_ic_enable(irq); - -} - -void irq_free_handler(int irq) -{ - if (irq < 0 || irq >= NR_IRQS) { - printf("irq_free_handler: bad irq number %d\n", irq); - return; - } - - /* disable irq on IRQMP hardware */ - leon3_ic_disable(irq); - - irq_handlers[irq].handler = NULL; - irq_handlers[irq].arg = NULL; -} - -/****************************************************************************/ - -#if defined(CONFIG_CMD_IRQ) -void do_irqinfo(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const argv[]) -{ - int irq; - unsigned int pil = get_pil(); - printf("PIL level: %u\n\r", pil); - printf("Spurious IRQ: %u, last unknown IRQ: %d\n", - spurious_irq_cnt, spurious_irq); - - puts("\nInterrupt-Information:\n" "Nr Routine Arg Count\n"); - - for (irq = 0; irq < NR_IRQS; irq++) { - if (irq_handlers[irq].handler != NULL) { - printf("%02d %p %p %d\n", irq, - irq_handlers[irq].handler, - irq_handlers[irq].arg, - irq_handlers[irq].count); - } - } -} -#endif diff --git a/arch/sparc/cpu/leon3/memcfg.c b/arch/sparc/cpu/leon3/memcfg.c deleted file mode 100644 index b9eda440e2..0000000000 --- a/arch/sparc/cpu/leon3/memcfg.c +++ /dev/null @@ -1,237 +0,0 @@ -/* GRLIB Memory controller setup. The register values are used - * from the associated low level assembler routine implemented - * in memcfg_low.S. - * - * (C) Copyright 2010, 2015 - * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <ambapp.h> -#include "memcfg.h" -#include <config.h> - -#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL1 -struct mctrl_setup esa_mctrl1_cfg = { - .reg_mask = 0x7, - .regs = { - { - .mask = 0x00000300, - .value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1, - }, - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2, - }, - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3, - }, - } -}; -#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL2 -struct mctrl_setup esa_mctrl2_cfg = { - .reg_mask = 0x7, - .regs = { - { - .mask = 0x00000300, - .value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG1, - }, - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG2, - }, - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG3, - }, - } -}; -#endif -#endif - -#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1 -struct mctrl_setup gaisler_ftmctrl1_cfg = { - .reg_mask = 0x7, - .regs = { - { - .mask = 0x00000300, - .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1, - }, - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2, - }, - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3, - }, - } -}; -#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2 -struct mctrl_setup gaisler_ftmctrl2_cfg = { - .reg_mask = 0x7, - .regs = { - { - .mask = 0x00000300, - .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG1, - }, - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG2, - }, - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG3, - }, - } -}; -#endif -#endif - -#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1 -struct mctrl_setup gaisler_sdctrl1_cfg = { - .reg_mask = 0x1, - .regs = { - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_GAISLER_SDCTRL1_CTRL, - }, - } -}; -#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL2 -struct mctrl_setup gaisler_sdctrl2_cfg = { - .reg_mask = 0x1, - .regs = { - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_GAISLER_SDCTRL2_CTRL, - }, - } -}; -#endif -#endif - -#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 -struct ahbmctrl_setup gaisler_ddr2spa1_cfg = { - .ahb_mbar_no = 1, - .reg_mask = 0xd, - .regs = { - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG1, - }, - { 0x00000000, 0}, - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG3, - }, - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG4, - }, - } -}; -#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2 -struct ahbmctrl_setup gaisler_ddr2spa2_cfg = { - .ahb_mbar_no = 1, - .reg_mask = 0xd, - .regs = { - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG1, - }, - { 0x00000000, 0}, - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG3, - }, - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG4, - }, - } -}; -#endif -#endif - -#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1 -struct ahbmctrl_setup gaisler_ddrspa1_cfg = { - .ahb_mbar_no = 1, - .reg_mask = 0x1, - .regs = { - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_GAISLER_DDRSPA1_CTRL, - }, - } -}; -#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA2 -struct ahbmctrl_setup gaisler_ddrspa2_cfg = { - .ahb_mbar_no = 1, - .reg_mask = 0x1, - .regs = { - { - .mask = 0x00000000, - .value = CONFIG_SYS_GRLIB_GAISLER_DDRSPA2_CTRL, - }, - } -}; -#endif -#endif - -struct grlib_mctrl_handler grlib_mctrl_handlers[] = { -/* ESA MCTRL (PROM/FLASH/IO/SRAM/SDRAM) */ -#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL1 - {DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_ESA, ESA_MCTRL), - _nomem_mctrl_init, (void *)&esa_mctrl1_cfg}, -#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL2 - {DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_ESA, ESA_MCTRL), - _nomem_mctrl_init, (void *)&esa_mctrl2_cfg}, -#endif -#endif - -/* GAISLER Fault Tolerant Memory controller (PROM/FLASH/IO/SRAM/SDRAM) */ -#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1 - {DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_FTMCTRL), - _nomem_mctrl_init, (void *)&gaisler_ftmctrl1_cfg}, -#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2 - {DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_FTMCTRL), - _nomem_mctrl_init, (void *)&gaisler_ftmctrl2_cfg}, -#endif -#endif - -/* GAISLER SDRAM-only Memory controller (SDRAM) */ -#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1 - {DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_SDCTRL), - _nomem_mctrl_init, (void *)&gaisler_sdctrl1_cfg}, -#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL2 - {DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_SDCTRL), - _nomem_mctrl_init, (void *)&gaisler_sdctrl2_cfg}, -#endif -#endif - -/* GAISLER DDR Memory controller (DDR) */ -#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1 - {DEV_AHB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDRSP), - _nomem_ahbmctrl_init, (void *)&gaisler_ddrspa1_cfg}, -#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA2 - {DEV_AHB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDRSP), - _nomem_ahbmctrl_init, (void *)&gaisler_ddrspa2_cfg}, -#endif -#endif - -/* GAISLER DDR2 Memory controller (DDR2) */ -#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 - {DEV_AHB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDR2SP), - _nomem_ahbmctrl_init, (void *)&gaisler_ddr2spa1_cfg}, -#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2 - {DEV_AHB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDR2SP), - _nomem_ahbmctrl_init, (void *)&gaisler_ddr2spa2_cfg}, -#endif -#endif - - /* Mark end */ - MH_END -}; diff --git a/arch/sparc/cpu/leon3/memcfg.h b/arch/sparc/cpu/leon3/memcfg.h deleted file mode 100644 index a524896e5a..0000000000 --- a/arch/sparc/cpu/leon3/memcfg.h +++ /dev/null @@ -1,90 +0,0 @@ -/* GRLIB Memory controller setup structures - * - * (C) Copyright 2010, 2015 - * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __MEMCFG_H__ -#define __MEMCFG_H__ - -/*********** Low Level Memory Controller Initalization ***********/ - -#ifndef __ASSEMBLER__ - -struct grlib_mctrl_handler; - -typedef void (*mctrl_handler_t)( - struct grlib_mctrl_handler *dev, - void *conf, - unsigned int ioarea - ); - -/* Memory Controller Handler Structure */ -struct grlib_mctrl_handler { - unsigned char type; /* 0x00. MASK: AHB MST&SLV, APB SLV */ - char index; /* 0x01. Unit number, 0, 1, 2... */ - char unused[2]; /* 0x02 */ - unsigned int ven_dev; /* 0x04. Device and Vendor */ - mctrl_handler_t func; /* 0x08. Memory Controller Handler */ - void *priv; /* 0x0c. Optional private data, ptr to - * info how to set up controller */ -}; - -extern struct grlib_mctrl_handler grlib_mctrl_handlers[]; - -#endif - -#define MH_STRUCT_SIZE (4*4) -#define MH_TYPE 0x00 -#define MH_INDEX 0x01 -#define MH_VENDOR_DEVICE 0x04 -#define MH_FUNC 0x08 -#define MH_PRIV 0x0c - -#define MH_TYPE_NONE DEV_NONE -#define MH_TYPE_AHB_MST DEV_AHB_MST -#define MH_TYPE_AHB_SLV DEV_AHB_SLV -#define MH_TYPE_APB_SLV DEV_APB_SLV - -#define MH_UNUSED {0, 0} -#define MH_END {DEV_NONE, 0, MH_UNUSED, AMBA_PNP_ID(0, 0), 0, 0} - -/*********** Low Level Memory Controller Initalization Handlers ***********/ - -#ifndef __ASSEMBLER__ -extern void _nomem_mctrl_init( - struct grlib_mctrl_handler *dev, - void *conf, - unsigned int ioarea_apbmst); - -struct mctrl_setup { - unsigned int reg_mask; /* Which registers to write */ - struct { - unsigned int mask; /* Mask used keep reg bits unchanged */ - unsigned int value; /* Value written to register */ - } regs[8]; -}; - -extern void _nomem_ahbmctrl_init( - struct grlib_mctrl_handler *dev, - void *conf, - unsigned int ioarea_apbmst); - -struct ahbmctrl_setup { - int ahb_mbar_no; /* MBAR to get register address from */ - unsigned int reg_mask; /* Which registers to write */ - struct { - unsigned int mask; /* Mask used keep reg bits unchanged */ - unsigned int value; /* Value written to register */ - } regs[8]; -}; -#endif - -/* mctrl_setup data structure defines */ -#define NREGS_OFS 0 -#define REGS_OFS 0x4 -#define REGS_SIZE 8 - -#endif diff --git a/arch/sparc/cpu/leon3/memcfg_low.S b/arch/sparc/cpu/leon3/memcfg_low.S deleted file mode 100644 index 84a81a90a9..0000000000 --- a/arch/sparc/cpu/leon3/memcfg_low.S +++ /dev/null @@ -1,253 +0,0 @@ -/* This is the memory initialization functions, the function - * implemented below initializes each memory controller - * found and specified by the input grlib_mctrl_handler structure. - * - * After the memory controllers have been initialized the stack - * can be used. - * - * (C) Copyright 2010, 2015 - * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <ambapp.h> -#include "memcfg.h" -#include <config.h> - - .seg "text" - .globl _nomem_memory_ctrl_init - .globl _nomem_mctrl_init, _nomem_ahbmctrl_init - .extern _nomem_find_apb - .extern _nomem_find_ahb - - -/* FUNCTION - * _nomem_memory_controller_init(struct grlib_mctrl_handler *mem_handlers) - * - * Initialize AMBA devices, _nomem_amba_init() has prepared i0-i5 - * with the AHB buses on the system. - * - * For each entry in mem_handlers find the VENDOR:DEVICE and handle it - * by calling the handler function pointer. - * - * Constraints: - * i6, i7, o6, l7, l6, g3, g4, g5, g6, g7 is used by caller - * o7 is return address - * l5 reserved for this function for future use. - * - * Arguments - * - o0 Pointer to memory handler array - * - * Results - * - o0 Number of memory controllers found - * - * Clobbered - * - o0 (Current AHB slave conf address) - * - l0 (mem handler entry address) - * - l1 (Return value, number of memory controllers found) - * - o7 (function pointer) - * - l0, l1, l2, l3, l4, g1, g2 (used by _nomem_ambapp_find_buses) - * - o0, o1, o2, o3, o4, o5 (Used as arguments) - * - * - g1 ( level 1 return address) - * - g2 ( level 2 return address) - */ - -_nomem_memory_ctrl_init: - /* At this point all AHB buses has been found and the I/O Areas of - * all AHB buses is stored in the i0-i5 registers. Max 6 buses. Next, - * memory controllers are found by searching all buses for matching - * VENDOR:DEVICE. The VENDOR:DEVICE to search for are taken from the - * mem_handlers array. For each match the function pointer stored in - * the mem_handler entry is called to handle the hardware setup. - */ - mov %o7, %g1 /* Save return address */ - mov %o0, %l0 - mov %g0, %l1 /* The return value */ - -.L_do_one_mem_handler: - ld [%l0 + MH_FUNC], %o7 - cmp %o7, %g0 - be .L_all_mctrl_handled - nop - - /*** Scan for memory controller ***/ - - /* Set up argments, o5 not used by _nomem_find_apb */ - ldub [%l0 + MH_TYPE], %o5 - clr %o4 - clr %o3 - ldub [%l0 + MH_INDEX], %o2 - ld [%l0 + MH_VENDOR_DEVICE], %o1 - - /* An empty config? */ - cmp %o5, DEV_NONE - beq .L_all_mctrl_next - - /* Select function (APB or AHB) */ - cmp %o5, DEV_APB_SLV - bne .L_find_ahb_memctrl - clr %o0 -.L_find_apb_memctrl: - call _nomem_find_apb /* Scan for APB slave device */ - nop - - /* o3 = iobar address - * o4 = AHB Bus index - * - * REG ADR = ((iobar >> 12) & (iobar << 4) & 0xfff00) | "APB Base" - */ - ld [%o3 + AMBA_APB_IOBAR_OFS], %o5 - srl %o5, 12, %o2 - sll %o5, 4, %o5 - and %o2, %o5, %o5 - set 0xfff00, %o2 - and %o2, %o5, %o5 - sethi %hi(0xfff00000), %o2 - and %o3, %o2, %o2 - or %o5, %o2, %o5 /* Register base address */ - - ba .L_call_one_mem_handler - nop - -.L_find_ahb_memctrl: - call _nomem_find_ahb /* Scan for AHB Slave or Master. - * o5 determine type. */ - nop - clr %o5 - - /* Call the handler function if the hardware was found - * - * o0 = mem_handler - * o1 = Configuration address - * o2 = AHB Bus index - * o3 = APB Base register (if APB Slave) - * - * Constraints: - * i0-i7, l0, l1, l5, g1, g3-g7 may no be used. - */ -.L_call_one_mem_handler: - cmp %o0, %g0 - be .L_all_mctrl_next - mov %l0, %o0 /* Mem handler pointer */ - mov %o3, %o1 /* AMBA PnP Configuration address */ - mov %o4, %o2 /* AHB Bus index */ - ld [%l0 + MH_FUNC], %o7 /* Get Function pointer */ - call %o7 - mov %o5, %o3 /* APB Register Base Address */ - - inc %l1 /* Number of Memory controllers - * handled. */ - - /* Do next entry in mem_handlers */ -.L_all_mctrl_next: - ba .L_do_one_mem_handler - add %l0, MH_STRUCT_SIZE, %l0 - -.L_all_mctrl_handled: - mov %g1, %o7 /* Restore return address */ - retl - mov %l1, %o0 - - - -/* Generic Memory controller initialization routine (APB Registers) - * - * o0 = mem_handler structure pointer - * o1 = Configuration address - * o2 = AHB Bus index - * o3 = APB Base register - * - * Clobbered - * o0-o4 - */ -_nomem_mctrl_init: - ld [%o0 + MH_PRIV], %o0 /* Get Private structure */ - ld [%o0], %o1 /* Get Reg Mask */ - and %o1, 0xff, %o1 - add %o0, REGS_OFS, %o0 /* Point to first reg */ -.L_do_one_reg: - andcc %o1, 0x1, %g0 - beq .L_do_next_reg - ld [%o0], %o2 - ld [%o3], %o4 - and %o4, %o2, %o4 - ld [%o0 + 4], %o2 - or %o4, %o2, %o4 - st %o4, [%o3] - -.L_do_next_reg: - add %o0, REGS_SIZE, %o0 - add %o3, 4, %o3 - srl %o1, 1, %o1 - cmp %o1, 0 - bne .L_do_one_reg - nop - - /* No more registers to write */ - retl - nop - - - -/* Generic Memory controller initialization routine (AHB Registers) - * - * o0 = mem_handler structure pointer - * o1 = Configuration address of memory controller - * o2 = AHB Bus index - * - * Clobbered - * o0-o5 - */ -_nomem_ahbmctrl_init: - ld [%o0 + MH_PRIV], %o0 /* Get Private structure */ - - /* Get index of AHB MBAR to get registers from */ - ld [%o0], %o5 - add %o0, 4, %o0 - - /* Get Address of MBAR in PnP info */ - add %o5, 4, %o5 - sll %o5, 2, %o5 - add %o5, %o1, %o5 /* Address of MBAR */ - - /* Get Address of registers from PnP information - * Address is in AHB I/O format, i.e. relative to bus - * - * ADR = (iobar & (iobar << 16) & 0xfff00000) - * IOADR = (ADR >> 12) | "APB Base" - */ - ld [%o5], %o5 - sll %o5, 16, %o4 - and %o5, %o4, %o5 - sethi %hi(0xfff00000), %o4 - and %o5, %o4, %o5 /* ADR */ - and %o4, %o1, %o4 - srl %o5, 12, %o5 - or %o5, %o4, %o3 /* IOADR in o3 */ - - ld [%o0], %o1 /* Get Reg Mask */ - and %o1, 0xff, %o1 - add %o0, REGS_OFS, %o0 /* Point to first reg */ -.L_do_one_ahbreg: - andcc %o1, 0x1, %g0 - beq .L_do_next_reg - ld [%o0], %o2 - ld [%o3], %o4 - and %o4, %o2, %o4 - ld [%o0 + 4], %o2 - or %o4, %o2, %o4 - st %o4, [%o3] - -.L_do_next_ahbreg: - add %o0, REGS_SIZE, %o0 - add %o3, 4, %o3 - srl %o1, 1, %o1 - cmp %o1, 0 - bne .L_do_one_reg - nop - - /* No more registers to write */ - retl - nop diff --git a/arch/sparc/cpu/leon3/prom.c b/arch/sparc/cpu/leon3/prom.c deleted file mode 100644 index 1f185b776b..0000000000 --- a/arch/sparc/cpu/leon3/prom.c +++ /dev/null @@ -1,1067 +0,0 @@ -/* prom.c - emulates a sparc v0 PROM for the linux kernel. - * - * Copyright (C) 2003 Konrad Eisele <eiselekd@web.de> - * Copyright (C) 2004 Stefan Holst <mail@s-holst.de> - * Copyright (C) 2007 Daniel Hellstrom <daniel@gaisler.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/prom.h> -#include <asm/machines.h> -#include <asm/srmmu.h> -#include <asm/processor.h> -#include <asm/irq.h> -#include <asm/leon.h> -#include <ambapp.h> -#include <grlib/apbuart.h> -#include <grlib/irqmp.h> -#include <grlib/gptimer.h> - -#include <config.h> -/* -#define PRINT_ROM_VEC -*/ -extern struct linux_romvec *kernel_arg_promvec; - -DECLARE_GLOBAL_DATA_PTR; - -#define PROM_PGT __attribute__ ((__section__ (".prom.pgt"))) -#define PROM_TEXT __attribute__ ((__section__ (".prom.text"))) -#define PROM_DATA __attribute__ ((__section__ (".prom.data"))) - -ambapp_dev_gptimer *gptimer; - -void *__prom_start_reloc; /* relocated prom_start address */ - -/* for __va */ -extern int __prom_start; -#define PAGE_OFFSET 0xf0000000 -#define phys_base CONFIG_SYS_SDRAM_BASE -#define PROM_OFFS 8192 -#define PROM_SIZE_MASK (PROM_OFFS-1) -#define __va(x) ( \ - (void *)( ((unsigned long)(x))-PROM_OFFS+ \ - (CONFIG_SYS_PROM_OFFSET-phys_base)+PAGE_OFFSET-CONFIG_SYS_TEXT_BASE ) \ - ) -#define __phy(x) ((void *)(((unsigned long)(x))-PROM_OFFS+CONFIG_SYS_PROM_OFFSET-CONFIG_SYS_TEXT_BASE)) - -struct property { - char *name; - char *value; - int length; -}; - -struct node { - int level; - struct property *properties; -}; - -static void leon_reboot(char *bcommand); -static void leon_halt(void); -static int leon_nbputchar(int c); -static int leon_nbgetchar(void); - -static int no_nextnode(int node); -static int no_child(int node); -static int no_proplen(int node, char *name); -static int no_getprop(int node, char *name, char *value); -static int no_setprop(int node, char *name, char *value, int len); -static char *no_nextprop(int node, char *name); - -static struct property PROM_TEXT *find_property(int node, char *name); -static int PROM_TEXT leon_strcmp(const char *s1, const char *s2); -static void *PROM_TEXT leon_memcpy(void *dest, const void *src, size_t n); -static void PROM_TEXT leon_reboot_physical(char *bcommand); - -void __inline__ leon_flush_cache_all(void) -{ - __asm__ __volatile__(" flush "); - __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"::"i"(ASI_DFLUSH):"memory"); -} - -void __inline__ leon_flush_tlb_all(void) -{ - leon_flush_cache_all(); - __asm__ __volatile__("sta %%g0, [%0] %1\n\t"::"r"(0x400), - "i"(ASI_MMUFLUSH):"memory"); -} - -typedef struct { - unsigned int ctx_table[256]; - unsigned int pgd_table[256]; -} sparc_srmmu_setup; - -sparc_srmmu_setup srmmu_tables PROM_PGT = { - {0}, - {0x1e, - 0x10001e, - 0x20001e, - 0x30001e, - 0x40001e, - 0x50001e, - 0x60001e, - 0x70001e, - 0x80001e, - 0x90001e, - 0xa0001e, - 0xb0001e, - 0xc0001e, - 0xd0001e, - 0xe0001e, - 0xf0001e, - 0x100001e, - 0x110001e, - 0x120001e, - 0x130001e, - 0x140001e, - 0x150001e, - 0x160001e, - 0x170001e, - 0x180001e, - 0x190001e, - 0x1a0001e, - 0x1b0001e, - 0x1c0001e, - 0x1d0001e, - 0x1e0001e, - 0x1f0001e, - 0x200001e, - 0x210001e, - 0x220001e, - 0x230001e, - 0x240001e, - 0x250001e, - 0x260001e, - 0x270001e, - 0x280001e, - 0x290001e, - 0x2a0001e, - 0x2b0001e, - 0x2c0001e, - 0x2d0001e, - 0x2e0001e, - 0x2f0001e, - 0x300001e, - 0x310001e, - 0x320001e, - 0x330001e, - 0x340001e, - 0x350001e, - 0x360001e, - 0x370001e, - 0x380001e, - 0x390001e, - 0x3a0001e, - 0x3b0001e, - 0x3c0001e, - 0x3d0001e, - 0x3e0001e, - 0x3f0001e, - 0x400001e, - 0x410001e, - 0x420001e, - 0x430001e, - 0x440001e, - 0x450001e, - 0x460001e, - 0x470001e, - 0x480001e, - 0x490001e, - 0x4a0001e, - 0x4b0001e, - 0x4c0001e, - 0x4d0001e, - 0x4e0001e, - 0x4f0001e, - 0x500001e, - 0x510001e, - 0x520001e, - 0x530001e, - 0x540001e, - 0x550001e, - 0x560001e, - 0x570001e, - 0x580001e, - 0x590001e, - 0x5a0001e, - 0x5b0001e, - 0x5c0001e, - 0x5d0001e, - 0x5e0001e, - 0x5f0001e, - 0x600001e, - 0x610001e, - 0x620001e, - 0x630001e, - 0x640001e, - 0x650001e, - 0x660001e, - 0x670001e, - 0x680001e, - 0x690001e, - 0x6a0001e, - 0x6b0001e, - 0x6c0001e, - 0x6d0001e, - 0x6e0001e, - 0x6f0001e, - 0x700001e, - 0x710001e, - 0x720001e, - 0x730001e, - 0x740001e, - 0x750001e, - 0x760001e, - 0x770001e, - 0x780001e, - 0x790001e, - 0x7a0001e, - 0x7b0001e, - 0x7c0001e, - 0x7d0001e, - 0x7e0001e, - 0x7f0001e, - 0x800001e, - 0x810001e, - 0x820001e, - 0x830001e, - 0x840001e, - 0x850001e, - 0x860001e, - 0x870001e, - 0x880001e, - 0x890001e, - 0x8a0001e, - 0x8b0001e, - 0x8c0001e, - 0x8d0001e, - 0x8e0001e, - 0x8f0001e, - 0x900001e, - 0x910001e, - 0x920001e, - 0x930001e, - 0x940001e, - 0x950001e, - 0x960001e, - 0x970001e, - 0x980001e, - 0x990001e, - 0x9a0001e, - 0x9b0001e, - 0x9c0001e, - 0x9d0001e, - 0x9e0001e, - 0x9f0001e, - 0xa00001e, - 0xa10001e, - 0xa20001e, - 0xa30001e, - 0xa40001e, - 0xa50001e, - 0xa60001e, - 0xa70001e, - 0xa80001e, - 0xa90001e, - 0xaa0001e, - 0xab0001e, - 0xac0001e, - 0xad0001e, - 0xae0001e, - 0xaf0001e, - 0xb00001e, - 0xb10001e, - 0xb20001e, - 0xb30001e, - 0xb40001e, - 0xb50001e, - 0xb60001e, - 0xb70001e, - 0xb80001e, - 0xb90001e, - 0xba0001e, - 0xbb0001e, - 0xbc0001e, - 0xbd0001e, - 0xbe0001e, - 0xbf0001e, - 0xc00001e, - 0xc10001e, - 0xc20001e, - 0xc30001e, - 0xc40001e, - 0xc50001e, - 0xc60001e, - 0xc70001e, - 0xc80001e, - 0xc90001e, - 0xca0001e, - 0xcb0001e, - 0xcc0001e, - 0xcd0001e, - 0xce0001e, - 0xcf0001e, - 0xd00001e, - 0xd10001e, - 0xd20001e, - 0xd30001e, - 0xd40001e, - 0xd50001e, - 0xd60001e, - 0xd70001e, - 0xd80001e, - 0xd90001e, - 0xda0001e, - 0xdb0001e, - 0xdc0001e, - 0xdd0001e, - 0xde0001e, - 0xdf0001e, - 0xe00001e, - 0xe10001e, - 0xe20001e, - 0xe30001e, - 0xe40001e, - 0xe50001e, - 0xe60001e, - 0xe70001e, - 0xe80001e, - 0xe90001e, - 0xea0001e, - 0xeb0001e, - 0xec0001e, - 0xed0001e, - 0xee0001e, - 0xef0001e, - 0x400001e /* default */ - } -}; - -/* a self contained prom info structure */ -struct leon_reloc_func { - struct property *(*find_property) (int node, char *name); - int (*strcmp) (char *s1, char *s2); - void *(*memcpy) (void *dest, const void *src, size_t n); - void (*reboot_physical) (char *cmd); - ambapp_dev_apbuart *leon3_apbuart; -}; - -struct leon_prom_info { - int freq_khz; - int leon_nctx; - int mids[32]; - int baudrates[2]; - struct leon_reloc_func reloc_funcs; - struct property root_properties[4]; - struct property cpu_properties[7]; -#undef CPUENTRY -#define CPUENTRY(idx) struct property cpu_properties##idx[4] - CPUENTRY(1); - CPUENTRY(2); - CPUENTRY(3); - CPUENTRY(4); - CPUENTRY(5); - CPUENTRY(6); - CPUENTRY(7); - CPUENTRY(8); - CPUENTRY(9); - CPUENTRY(10); - CPUENTRY(11); - CPUENTRY(12); - CPUENTRY(13); - CPUENTRY(14); - CPUENTRY(15); - CPUENTRY(16); - CPUENTRY(17); - CPUENTRY(18); - CPUENTRY(19); - CPUENTRY(20); - CPUENTRY(21); - CPUENTRY(22); - CPUENTRY(23); - CPUENTRY(24); - CPUENTRY(25); - CPUENTRY(26); - CPUENTRY(27); - CPUENTRY(28); - CPUENTRY(29); - CPUENTRY(30); - CPUENTRY(31); - struct idprom idprom; - struct linux_nodeops nodeops; - struct linux_mlist_v0 *totphys_p; - struct linux_mlist_v0 totphys; - struct linux_mlist_v0 *avail_p; - struct linux_mlist_v0 avail; - struct linux_mlist_v0 *prommap_p; - void (*synchook) (void); - struct linux_arguments_v0 *bootargs_p; - struct linux_arguments_v0 bootargs; - struct linux_romvec romvec; - struct node nodes[35]; - char s_device_type[12]; - char s_cpu[4]; - char s_mid[4]; - char s_idprom[7]; - char s_compatability[14]; - char s_leon2[6]; - char s_mmu_nctx[9]; - char s_frequency[16]; - char s_uart1_baud[11]; - char s_uart2_baud[11]; - char arg[256]; -}; - -/* static prom info */ -static struct leon_prom_info PROM_DATA spi = { - CONFIG_SYS_CLK_FREQ / 1000, - 256, - { -#undef CPUENTRY -#define CPUENTRY(idx) idx - CPUENTRY(0), - CPUENTRY(1), - CPUENTRY(2), - CPUENTRY(3), - CPUENTRY(4), - CPUENTRY(5), - CPUENTRY(6), - CPUENTRY(7), - CPUENTRY(8), - CPUENTRY(9), - CPUENTRY(10), - CPUENTRY(11), - CPUENTRY(12), - CPUENTRY(13), - CPUENTRY(14), - CPUENTRY(15), - CPUENTRY(16), - CPUENTRY(17), - CPUENTRY(18), - CPUENTRY(19), - CPUENTRY(20), - CPUENTRY(21), - CPUENTRY(22), - CPUENTRY(23), - CPUENTRY(24), - CPUENTRY(25), - CPUENTRY(26), - CPUENTRY(27), - CPUENTRY(28), - CPUENTRY(29), - CPUENTRY(30), - 31}, - {38400, 38400}, - { - __va(find_property), - __va(leon_strcmp), - __va(leon_memcpy), - __phy(leon_reboot_physical), - }, - { - {__va(spi.s_device_type), __va(spi.s_idprom), 4}, - {__va(spi.s_idprom), (char *)__va(&spi.idprom), sizeof(struct idprom)}, - {__va(spi.s_compatability), __va(spi.s_leon2), 5}, - {NULL, NULL, -1} - }, - { - {__va(spi.s_device_type), __va(spi.s_cpu), 4}, - {__va(spi.s_mid), __va(&spi.mids[0]), 4}, - {__va(spi.s_mmu_nctx), (char *)__va(&spi.leon_nctx), 4}, - {__va(spi.s_frequency), (char *)__va(&spi.freq_khz), 4}, - {__va(spi.s_uart1_baud), (char *)__va(&spi.baudrates[0]), 4}, - {__va(spi.s_uart2_baud), (char *)__va(&spi.baudrates[1]), 4}, - {NULL, NULL, -1} - }, -#undef CPUENTRY -#define CPUENTRY(idx) \ - { /* cpu_properties */ \ - {__va(spi.s_device_type), __va(spi.s_cpu), 4}, \ - {__va(spi.s_mid), __va(&spi.mids[idx]), 4}, \ - {__va(spi.s_frequency), (char *)__va(&spi.freq_khz), 4}, \ - {NULL, NULL, -1} \ - } - CPUENTRY(1), - CPUENTRY(2), - CPUENTRY(3), - CPUENTRY(4), - CPUENTRY(5), - CPUENTRY(6), - CPUENTRY(7), - CPUENTRY(8), - CPUENTRY(9), - CPUENTRY(10), - CPUENTRY(11), - CPUENTRY(12), - CPUENTRY(13), - CPUENTRY(14), - CPUENTRY(15), - CPUENTRY(16), - CPUENTRY(17), - CPUENTRY(18), - CPUENTRY(19), - CPUENTRY(20), - CPUENTRY(21), - CPUENTRY(22), - CPUENTRY(23), - CPUENTRY(24), - CPUENTRY(25), - CPUENTRY(26), - CPUENTRY(27), - CPUENTRY(28), - CPUENTRY(29), - CPUENTRY(30), - CPUENTRY(31), - { - 0x01, /* format */ - M_LEON2 | M_LEON2_SOC, /* machine type */ - {0, 0, 0, 0, 0, 0}, /* eth */ - 0, /* date */ - 0, /* sernum */ - 0, /* checksum */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} /* reserved */ - }, - { - __va(no_nextnode), - __va(no_child), - __va(no_proplen), - __va(no_getprop), - __va(no_setprop), - __va(no_nextprop) - }, - __va(&spi.totphys), - { - NULL, - (char *)CONFIG_SYS_SDRAM_BASE, - 0, - }, - __va(&spi.avail), - { - NULL, - (char *)CONFIG_SYS_SDRAM_BASE, - 0, - }, - NULL, /* prommap_p */ - NULL, - __va(&spi.bootargs), - { - {NULL, __va(spi.arg), NULL /*... */ }, - /*... */ - }, - { - 0, - 0, /* sun4c v0 prom */ - 0, 0, - {__va(&spi.totphys_p), __va(&spi.prommap_p), __va(&spi.avail_p)}, - __va(&spi.nodeops), - NULL, {NULL /* ... */ }, - NULL, NULL, - NULL, NULL, /* pv_getchar, pv_putchar */ - __va(leon_nbgetchar), __va(leon_nbputchar), - NULL, - __va(leon_reboot), - NULL, - NULL, - NULL, - __va(leon_halt), - __va(&spi.synchook), - {NULL}, - __va(&spi.bootargs_p) - /*... */ - }, - { - {0, __va(spi.root_properties + 3) /* NULL, NULL, -1 */ }, - {0, __va(spi.root_properties)}, - /* cpu 0, must be spi.nodes[2] see leon_prom_init() */ - {1, __va(spi.cpu_properties)}, - -#undef CPUENTRY -#define CPUENTRY(idx) \ - {1, __va(spi.cpu_properties##idx) } /* cpu <idx> */ - CPUENTRY(1), - CPUENTRY(2), - CPUENTRY(3), - CPUENTRY(4), - CPUENTRY(5), - CPUENTRY(6), - CPUENTRY(7), - CPUENTRY(8), - CPUENTRY(9), - CPUENTRY(10), - CPUENTRY(11), - CPUENTRY(12), - CPUENTRY(13), - CPUENTRY(14), - CPUENTRY(15), - CPUENTRY(16), - CPUENTRY(17), - CPUENTRY(18), - CPUENTRY(19), - CPUENTRY(20), - CPUENTRY(21), - CPUENTRY(22), - CPUENTRY(23), - CPUENTRY(24), - CPUENTRY(25), - CPUENTRY(26), - CPUENTRY(27), - CPUENTRY(28), - CPUENTRY(29), - CPUENTRY(30), - CPUENTRY(31), - {-1, __va(spi.root_properties + 3) /* NULL, NULL, -1 */ } - }, - "device_type", - "cpu", - "mid", - "idprom", - "compatability", - "leon2", - "mmu-nctx", - "clock-frequency", - "uart1_baud", - "uart2_baud", - CONFIG_DEFAULT_KERNEL_COMMAND_LINE -}; - -/* from arch/sparc/kernel/setup.c */ -#define RAMDISK_LOAD_FLAG 0x4000 -extern unsigned short root_flags; -extern unsigned short root_dev; -extern unsigned short ram_flags; -extern unsigned int sparc_ramdisk_image; -extern unsigned int sparc_ramdisk_size; -extern int root_mountflags; - -extern char initrd_end, initrd_start; - -/* Reboot the CPU = jump to beginning of flash again. - * - * Make sure that all function are inlined here. - */ -static void PROM_TEXT leon_reboot(char *bcommand) -{ - register char *arg = bcommand; - void __attribute__ ((noreturn)) (*reboot_physical) (char *cmd); - - /* get physical address */ - struct leon_prom_info *pspi = - (void *)(CONFIG_SYS_PROM_OFFSET + sizeof(srmmu_tables)); - - unsigned int *srmmu_ctx_table; - - /* Turn of Interrupts */ - set_pil(0xf); - - /* Set kernel's context, context zero */ - srmmu_set_context(0); - - /* Get physical address of the MMU shutdown routine */ - reboot_physical = (void *) - SPARC_BYPASS_READ(&pspi->reloc_funcs.reboot_physical); - - /* Now that we know the physical address of the function - * we can make the MMU allow jumping to it. - */ - srmmu_ctx_table = (unsigned int *)srmmu_get_ctable_ptr(); - - srmmu_ctx_table = (unsigned int *)SPARC_BYPASS_READ(srmmu_ctx_table); - - /* get physical address of kernel's context table (assume ptd) */ - srmmu_ctx_table = (unsigned int *) - (((unsigned int)srmmu_ctx_table & 0xfffffffc) << 4); - - /* enable access to physical address of MMU shutdown function */ - SPARC_BYPASS_WRITE(&srmmu_ctx_table - [((unsigned int)reboot_physical) >> 24], - (((unsigned int)reboot_physical & 0xff000000) >> 4) | - 0x1e); - - /* flush TLB cache */ - leon_flush_tlb_all(); - - /* flash instruction & data cache */ - sparc_icache_flush_all(); - sparc_dcache_flush_all(); - - /* jump to physical address function - * so that when the MMU is disabled - * we can continue to execute - */ - reboot_physical(arg); -} - -static void PROM_TEXT leon_reboot_physical(char *bcommand) -{ - void __attribute__ ((noreturn)) (*reset) (void); - - /* Turn off MMU */ - srmmu_set_mmureg(0); - - /* Hardcoded start address */ - reset = CONFIG_SYS_MONITOR_BASE; - - /* flush data cache */ - sparc_dcache_flush_all(); - - /* flush instruction cache */ - sparc_icache_flush_all(); - - /* Jump to start in Flash */ - reset(); -} - -static void PROM_TEXT leon_halt(void) -{ - while (1) ; -} - -/* get single char, don't care for blocking*/ -static int PROM_TEXT leon_nbgetchar(void) -{ - return -1; -} - -/* put single char, don't care for blocking*/ -static int PROM_TEXT leon_nbputchar(int c) -{ - ambapp_dev_apbuart *uart; - - /* get physical address */ - struct leon_prom_info *pspi = - (void *)(CONFIG_SYS_PROM_OFFSET + sizeof(srmmu_tables)); - - uart = (ambapp_dev_apbuart *) - SPARC_BYPASS_READ(&pspi->reloc_funcs.leon3_apbuart); - - /* no UART? */ - if (!uart) - return 0; - - /***** put char in buffer... *********** - * Make sure all functions are inline! * - ***************************************/ - - /* Wait for last character to go. */ - while (!(SPARC_BYPASS_READ(&uart->status) - & APBUART_STATUS_THE)); - - /* Send data */ - SPARC_BYPASS_WRITE(&uart->data, c); - - /* Wait for data to be sent */ - while (!(SPARC_BYPASS_READ(&uart->status) - & APBUART_STATUS_TSE)); - - return 0; -} - -/* node ops */ - -/*#define nodes ((struct node *)__va(&pspi->nodes))*/ -#define nodes ((struct node *)(pspi->nodes)) - -static int PROM_TEXT no_nextnode(int node) -{ - /* get physical address */ - struct leon_prom_info *pspi = - (void *)(CONFIG_SYS_PROM_OFFSET + sizeof(srmmu_tables)); - - /* convert into virtual address */ - pspi = (struct leon_prom_info *) - (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET); - - if (nodes[node].level == nodes[node + 1].level) - return node + 1; - return -1; -} - -static int PROM_TEXT no_child(int node) -{ - /* get physical address */ - struct leon_prom_info *pspi = (struct leon_prom_info *) - (CONFIG_SYS_PROM_OFFSET + sizeof(srmmu_tables)); - - /* convert into virtual address */ - pspi = (struct leon_prom_info *) - (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET); - - if (nodes[node].level == nodes[node + 1].level - 1) - return node + 1; - return -1; -} - -static struct property PROM_TEXT *find_property(int node, char *name) -{ - /* get physical address */ - struct leon_prom_info *pspi = (struct leon_prom_info *) - (CONFIG_SYS_PROM_OFFSET + sizeof(srmmu_tables)); - - /* convert into virtual address */ - pspi = (struct leon_prom_info *) - (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET); - - struct property *prop = &nodes[node].properties[0]; - while (prop && prop->name) { - if (pspi->reloc_funcs.strcmp(prop->name, name) == 0) - return prop; - prop++; - } - return NULL; -} - -static int PROM_TEXT no_proplen(int node, char *name) -{ - /* get physical address */ - struct leon_prom_info *pspi = (struct leon_prom_info *) - (CONFIG_SYS_PROM_OFFSET + sizeof(srmmu_tables)); - - /* convert into virtual address */ - pspi = (struct leon_prom_info *) - (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET); - - struct property *prop = pspi->reloc_funcs.find_property(node, name); - if (prop) - return prop->length; - return -1; -} - -static int PROM_TEXT no_getprop(int node, char *name, char *value) -{ - /* get physical address */ - struct leon_prom_info *pspi = (struct leon_prom_info *) - (CONFIG_SYS_PROM_OFFSET + sizeof(srmmu_tables)); - - /* convert into virtual address */ - pspi = (struct leon_prom_info *) - (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET); - - struct property *prop = pspi->reloc_funcs.find_property(node, name); - if (prop) { - pspi->reloc_funcs.memcpy(value, prop->value, prop->length); - return 1; - } - return -1; -} - -static int PROM_TEXT no_setprop(int node, char *name, char *value, int len) -{ - return -1; -} - -static char PROM_TEXT *no_nextprop(int node, char *name) -{ - /* get physical address */ - struct leon_prom_info *pspi = (struct leon_prom_info *) - (CONFIG_SYS_PROM_OFFSET + sizeof(srmmu_tables)); - struct property *prop; - - /* convert into virtual address */ - pspi = (struct leon_prom_info *) - (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET); - - if (!name || !name[0]) - return nodes[node].properties[0].name; - - prop = pspi->reloc_funcs.find_property(node, name); - if (prop) - return prop[1].name; - return NULL; -} - -static int PROM_TEXT leon_strcmp(const char *s1, const char *s2) -{ - register char result; - - while (1) { - result = *s1 - *s2; - if (result || !*s1) - break; - s2++; - s1++; - } - - return result; -} - -static void *PROM_TEXT leon_memcpy(void *dest, const void *src, size_t n) -{ - char *dst = (char *)dest, *source = (char *)src; - - while (n--) { - *dst = *source; - dst++; - source++; - } - return dest; -} - -#define GETREGSP(sp) __asm__ __volatile__("mov %%sp, %0" : "=r" (sp)) - -void leon_prom_init(struct leon_prom_info *pspi) -{ - unsigned long i; - unsigned char cksum, *ptr; - char *addr_str, *end; - unsigned long sp; - GETREGSP(sp); - - pspi->freq_khz = CONFIG_SYS_CLK_FREQ / 1000; - - /* Set Available main memory size */ - pspi->totphys.num_bytes = CONFIG_SYS_PROM_OFFSET - CONFIG_SYS_SDRAM_BASE; - pspi->avail.num_bytes = pspi->totphys.num_bytes; - - /* Set the pointer to the Console UART in romvec */ - pspi->reloc_funcs.leon3_apbuart = gd->arch.uart; - - { - int j = 1; -#ifdef CONFIG_SMP - ambapp_dev_irqmp *b; - b = (ambapp_dev_irqmp *) leon3_getapbbase(VENDOR_GAISLER, - GAISLER_IRQMP); - if (b) { - j = 1 + ((LEON3_BYPASS_LOAD_PA(&(b->mpstatus)) - >> LEON3_IRQMPSTATUS_CPUNR) & 0xf); - } -#endif -#undef nodes - pspi->nodes[2 + j].level = -1; - pspi->nodes[2 + j].properties = __va(spi.root_properties + 3); - } - - /* Set Ethernet MAC address from environment */ - if ((addr_str = getenv("ethaddr")) != NULL) { - for (i = 0; i < 6; i++) { - pspi->idprom.id_ethaddr[i] = addr_str ? - simple_strtoul(addr_str, &end, 16) : 0; - if (addr_str) { - addr_str = (*end) ? end + 1 : end; - } - } - } else { - /* HW Address not found in environment, - * Set default HW address - */ - pspi->idprom.id_ethaddr[0] = 0; - pspi->idprom.id_ethaddr[1] = 0; - pspi->idprom.id_ethaddr[2] = 0; - pspi->idprom.id_ethaddr[3] = 0; - pspi->idprom.id_ethaddr[4] = 0; - pspi->idprom.id_ethaddr[5] = 0; - } - - ptr = (unsigned char *)&pspi->idprom; - for (i = cksum = 0; i <= 0x0E; i++) - cksum ^= *ptr++; - pspi->idprom.id_cksum = cksum; -} - -static inline void set_cache(unsigned long regval) -{ - asm volatile ("sta %0, [%%g0] %1\n\t":: "r" (regval), "i"(2):"memory"); -} - -extern unsigned short bss_start, bss_end; - -/* mark as section .img.main.text, to be referenced in linker script */ -int prom_init(void) -{ - struct leon_prom_info *pspi = (void *) - ((((unsigned int)&spi) & PROM_SIZE_MASK) + CONFIG_SYS_PROM_OFFSET); - - /* disable mmu */ - srmmu_set_mmureg(0x00000000); - __asm__ __volatile__("flush\n\t"); - - /* init prom info struct */ - leon_prom_init(pspi); - - kernel_arg_promvec = &pspi->romvec; -#ifdef PRINT_ROM_VEC - printf("Kernel rom vec: 0x%lx\n", (unsigned int)(&pspi->romvec)); -#endif - return 0; -} - -/* Copy current kernel boot argument to ROMvec */ -void prepare_bootargs(char *bootargs) -{ - struct leon_prom_info *pspi; - char *src, *dst; - int left; - - /* if no bootargs set, skip copying ==> default bootline */ - if (bootargs && (*bootargs != '\0')) { - pspi = (void *)((((unsigned int)&spi) & PROM_SIZE_MASK) + - CONFIG_SYS_PROM_OFFSET); - src = bootargs; - dst = &pspi->arg[0]; - left = 255; /* max len */ - while (*src && left > 0) { - *dst++ = *src++; - left--; - } - /* terminate kernel command line string */ - *dst = 0; - } -} - -void srmmu_init_cpu(unsigned int entry) -{ - sparc_srmmu_setup *psrmmu_tables = (void *) - ((((unsigned int)&srmmu_tables) & PROM_SIZE_MASK) + - CONFIG_SYS_PROM_OFFSET); - - /* Make context 0 (kernel's context) point - * to our prepared memory mapping - */ -#define PTD 1 - psrmmu_tables->ctx_table[0] = - ((unsigned int)&psrmmu_tables->pgd_table[0x00]) >> 4 | PTD; - - /* Set virtual kernel address 0xf0000000 - * to SRAM/SDRAM address. - * Make it READ/WRITE/EXEC to SuperUser - */ -#define PTE 2 -#define ACC_SU_ALL 0x1c - psrmmu_tables->pgd_table[0xf0] = - (CONFIG_SYS_SDRAM_BASE >> 4) | ACC_SU_ALL | PTE; - psrmmu_tables->pgd_table[0xf1] = - ((CONFIG_SYS_SDRAM_BASE + 0x1000000) >> 4) | ACC_SU_ALL | PTE; - psrmmu_tables->pgd_table[0xf2] = - ((CONFIG_SYS_SDRAM_BASE + 0x2000000) >> 4) | ACC_SU_ALL | PTE; - psrmmu_tables->pgd_table[0xf3] = - ((CONFIG_SYS_SDRAM_BASE + 0x3000000) >> 4) | ACC_SU_ALL | PTE; - psrmmu_tables->pgd_table[0xf4] = - ((CONFIG_SYS_SDRAM_BASE + 0x4000000) >> 4) | ACC_SU_ALL | PTE; - psrmmu_tables->pgd_table[0xf5] = - ((CONFIG_SYS_SDRAM_BASE + 0x5000000) >> 4) | ACC_SU_ALL | PTE; - psrmmu_tables->pgd_table[0xf6] = - ((CONFIG_SYS_SDRAM_BASE + 0x6000000) >> 4) | ACC_SU_ALL | PTE; - psrmmu_tables->pgd_table[0xf7] = - ((CONFIG_SYS_SDRAM_BASE + 0x7000000) >> 4) | ACC_SU_ALL | PTE; - - /* convert rom vec pointer to virtual address */ - kernel_arg_promvec = (struct linux_romvec *) - (((unsigned int)kernel_arg_promvec & 0x0fffffff) | 0xf0000000); - - /* Set Context pointer to point to context table - * 256 contexts supported. - */ - srmmu_set_ctable_ptr((unsigned int)&psrmmu_tables->ctx_table[0]); - - /* Set kernel's context, context zero */ - srmmu_set_context(0); - - /* Invalidate all Cache */ - __asm__ __volatile__("flush\n\t"); - - srmmu_set_mmureg(0x00000001); - leon_flush_tlb_all(); - leon_flush_cache_all(); -} diff --git a/arch/sparc/cpu/leon3/serial.c b/arch/sparc/cpu/leon3/serial.c deleted file mode 100644 index bc6e7a172e..0000000000 --- a/arch/sparc/cpu/leon3/serial.c +++ /dev/null @@ -1,189 +0,0 @@ -/* GRLIB APBUART Serial controller driver - * - * (C) Copyright 2007, 2015 - * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/io.h> -#include <ambapp.h> -#include <grlib/apbuart.h> -#include <serial.h> -#include <watchdog.h> - -DECLARE_GLOBAL_DATA_PTR; - -/* Select which UART that will become u-boot console */ -#ifndef CONFIG_SYS_GRLIB_APBUART_INDEX -/* Try to use CONFIG_CONS_INDEX, if available, it is numbered from 1 */ -#ifdef CONFIG_CONS_INDEX -#define CONFIG_SYS_GRLIB_APBUART_INDEX (CONFIG_CONS_INDEX - 1) -#else -#define CONFIG_SYS_GRLIB_APBUART_INDEX 0 -#endif -#endif - -static unsigned apbuart_calc_scaler(unsigned apbuart_freq, unsigned baud) -{ - return (((apbuart_freq * 10) / (baud * 8)) - 5) / 10; -} - -static int leon3_serial_init(void) -{ - ambapp_dev_apbuart *uart; - ambapp_apbdev apbdev; - unsigned int tmp; - - /* find UART */ - if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_APBUART, - CONFIG_SYS_GRLIB_APBUART_INDEX, &apbdev) != 1) { - gd->flags &= ~GD_FLG_SERIAL_READY; - panic("%s: apbuart not found!\n", __func__); - return -1; /* didn't find hardware */ - } - - /* found apbuart, let's init .. */ - uart = (ambapp_dev_apbuart *) apbdev.address; - - /* APBUART Frequency is equal to bus frequency */ - gd->arch.uart_freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index); - - /* Set scaler / baud rate */ - tmp = apbuart_calc_scaler(gd->arch.uart_freq, CONFIG_BAUDRATE); - writel(tmp, &uart->scaler); - - /* Let bit 11 be unchanged (debug bit for GRMON) */ - tmp = readl(&uart->ctrl) & APBUART_CTRL_DBG; - /* Receiver & transmitter enable */ - tmp |= APBUART_CTRL_RE | APBUART_CTRL_TE; - writel(tmp, &uart->ctrl); - - gd->arch.uart = uart; - return 0; -} - -static inline ambapp_dev_apbuart *leon3_get_uart_regs(void) -{ - ambapp_dev_apbuart *uart = gd->arch.uart; - return uart; -} - -static void leon3_serial_putc_raw(const char c) -{ - ambapp_dev_apbuart * const uart = leon3_get_uart_regs(); - - if (!uart) - return; - - /* Wait for last character to go. */ - while (!(readl(&uart->status) & APBUART_STATUS_THE)) - WATCHDOG_RESET(); - - /* Send data */ - writel(c, &uart->data); - -#ifdef LEON_DEBUG - /* Wait for data to be sent */ - while (!(readl(&uart->status) & APBUART_STATUS_TSE)) - WATCHDOG_RESET(); -#endif -} - -static void leon3_serial_putc(const char c) -{ - if (c == '\n') - leon3_serial_putc_raw('\r'); - - leon3_serial_putc_raw(c); -} - -static int leon3_serial_getc(void) -{ - ambapp_dev_apbuart * const uart = leon3_get_uart_regs(); - - if (!uart) - return 0; - - /* Wait for a character to arrive. */ - while (!(readl(&uart->status) & APBUART_STATUS_DR)) - WATCHDOG_RESET(); - - /* Read character data */ - return readl(&uart->data); -} - -static int leon3_serial_tstc(void) -{ - ambapp_dev_apbuart * const uart = leon3_get_uart_regs(); - - if (!uart) - return 0; - - return readl(&uart->status) & APBUART_STATUS_DR; -} - -/* set baud rate for uart */ -static void leon3_serial_setbrg(void) -{ - ambapp_dev_apbuart * const uart = leon3_get_uart_regs(); - unsigned int scaler; - - if (!uart) - return; - - if (!gd->baudrate) - gd->baudrate = CONFIG_BAUDRATE; - - if (!gd->arch.uart_freq) - gd->arch.uart_freq = CONFIG_SYS_CLK_FREQ; - - scaler = apbuart_calc_scaler(gd->arch.uart_freq, gd->baudrate); - - writel(scaler, &uart->scaler); -} - -static struct serial_device leon3_serial_drv = { - .name = "leon3_serial", - .start = leon3_serial_init, - .stop = NULL, - .setbrg = leon3_serial_setbrg, - .putc = leon3_serial_putc, - .puts = default_serial_puts, - .getc = leon3_serial_getc, - .tstc = leon3_serial_tstc, -}; - -void leon3_serial_initialize(void) -{ - serial_register(&leon3_serial_drv); -} - -__weak struct serial_device *default_serial_console(void) -{ - return &leon3_serial_drv; -} - -#ifdef CONFIG_DEBUG_UART_APBUART - -#include <debug_uart.h> - -static inline void _debug_uart_init(void) -{ - ambapp_dev_apbuart *uart = (ambapp_dev_apbuart *)CONFIG_DEBUG_UART_BASE; - uart->scaler = apbuart_calc_scaler(CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE); - uart->ctrl = APBUART_CTRL_RE | APBUART_CTRL_TE; -} - -static inline void _debug_uart_putc(int ch) -{ - ambapp_dev_apbuart *uart = (ambapp_dev_apbuart *)CONFIG_DEBUG_UART_BASE; - while (!(readl(&uart->status) & APBUART_STATUS_THE)) - WATCHDOG_RESET(); - writel(ch, &uart->data); -} - -DEBUG_UART_FUNCS - -#endif diff --git a/arch/sparc/cpu/leon3/start.S b/arch/sparc/cpu/leon3/start.S deleted file mode 100644 index 1527d72a6d..0000000000 --- a/arch/sparc/cpu/leon3/start.S +++ /dev/null @@ -1,681 +0,0 @@ -/* This is where the SPARC/LEON3 starts - * - * Copyright (C) 2007, 2015 - * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <asm-offsets.h> -#include <config.h> -#include <asm/asmmacro.h> -#include <asm/winmacro.h> -#include <asm/psr.h> -#include <asm/stack.h> -#include <asm/leon.h> -#include <ambapp.h> - -/* Default Plug&Play I/O area */ -#ifndef CONFIG_AMBAPP_IOAREA -#define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA -#endif - -/* Default number of SPARC register windows */ -#ifndef CONFIG_SYS_SPARC_NWINDOWS -#define CONFIG_SYS_SPARC_NWINDOWS 8 -#endif - -/* Entry for traps which jump to a programmer-specified trap handler. */ -#define TRAPR(H) \ - wr %g0, 0xfe0, %psr; \ - mov %g0, %tbr; \ - ba (H); \ - mov %g0, %wim; - -#define TRAP(H) \ - mov %psr, %l0; \ - ba (H); \ - nop; nop; - -#define TRAPI(ilevel) \ - mov ilevel, %l7; \ - mov %psr, %l0; \ - b _irq_entry; \ - mov %wim, %l3 - -/* Unexcpected trap will halt the processor by forcing it to error state */ -#undef BAD_TRAP -#define BAD_TRAP ta 0; nop; nop; nop; - -/* Software trap. Treat as BAD_TRAP for the time being... */ -#define SOFT_TRAP TRAP(_hwerr) - -#define PSR_INIT 0x1FC0 /* Disable traps, set s and ps */ -#define WIM_INIT 2 - -/* All traps low-level code here must end with this macro. */ -#define RESTORE_ALL b ret_trap_entry; clr %l6; - -#define WRITE_PAUSE nop;nop;nop - -WINDOWSIZE = (16 * 4) -ARGPUSHSIZE = (6 * 4) -ARGPUSH = (WINDOWSIZE + 4) -MINFRAME = (WINDOWSIZE + ARGPUSHSIZE + 4) - -/* Number of register windows */ -#ifndef CONFIG_SYS_SPARC_NWINDOWS -#error Must define number of SPARC register windows, default is 8 -#endif - -/* Macros to load address into a register. Uses GOT table for PIC */ -#ifdef __PIC__ - -#define SPARC_PIC_THUNK_CALL(reg) \ - sethi %pc22(_GLOBAL_OFFSET_TABLE_-4), %##reg; \ - call __sparc_get_pc_thunk.reg; \ - add %##reg, %pc10(_GLOBAL_OFFSET_TABLE_+4), %##reg; - -#define SPARC_LOAD_ADDRESS(sym, got, reg) \ - sethi %gdop_hix22(sym), %##reg; \ - xor %##reg, %gdop_lox10(sym), %##reg; \ - ld [%##got + %##reg], %##reg, %gdop(sym); - -#else - -#define SPARC_PIC_THUNK_CALL(reg) -#define SPARC_LOAD_ADDRESS(sym, got, tmp) \ - set sym, %##reg; - -#endif - -#define STACK_ALIGN 8 -#define SA(X) (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1)) - - .section ".start", "ax" - .globl _start, start, _trap_table - .globl _irq_entry, nmi_trap - .globl _reset_reloc - -/* at address 0 - * Hardware traps - */ -start: -_start: -_trap_table: - TRAPR(_hardreset); ! 00 reset trap - BAD_TRAP; ! 01 instruction_access_exception - BAD_TRAP; ! 02 illegal_instruction - BAD_TRAP; ! 03 priveleged_instruction - BAD_TRAP; ! 04 fp_disabled - TRAP(_window_overflow); ! 05 window_overflow - TRAP(_window_underflow); ! 06 window_underflow - BAD_TRAP; ! 07 Memory Address Not Aligned - BAD_TRAP; ! 08 Floating Point Exception - BAD_TRAP; ! 09 Data Miss Exception - BAD_TRAP; ! 0a Tagged Instruction Ovrflw - BAD_TRAP; ! 0b Watchpoint Detected - BAD_TRAP; ! 0c - BAD_TRAP; ! 0d - BAD_TRAP; ! 0e - BAD_TRAP; ! 0f - BAD_TRAP; ! 10 - TRAPI(1); ! 11 IRQ level 1 - TRAPI(2); ! 12 IRQ level 2 - TRAPI(3); ! 13 IRQ level 3 - TRAPI(4); ! 14 IRQ level 4 - TRAPI(5); ! 15 IRQ level 5 - TRAPI(6); ! 16 IRQ level 6 - TRAPI(7); ! 17 IRQ level 7 - TRAPI(8); ! 18 IRQ level 8 - TRAPI(9); ! 19 IRQ level 9 - TRAPI(10); ! 1a IRQ level 10 - TRAPI(11); ! 1b IRQ level 11 - TRAPI(12); ! 1c IRQ level 12 - TRAPI(13); ! 1d IRQ level 13 - TRAPI(14); ! 1e IRQ level 14 - TRAP(_nmi_trap); ! 1f IRQ level 15 / - ! NMI (non maskable interrupt) - BAD_TRAP; ! 20 r_register_access_error - BAD_TRAP; ! 21 instruction access error - BAD_TRAP; ! 22 - BAD_TRAP; ! 23 - BAD_TRAP; ! 24 co-processor disabled - BAD_TRAP; ! 25 uniplemented FLUSH - BAD_TRAP; ! 26 - BAD_TRAP; ! 27 - BAD_TRAP; ! 28 co-processor exception - BAD_TRAP; ! 29 data access error - BAD_TRAP; ! 2a division by zero - BAD_TRAP; ! 2b data store error - BAD_TRAP; ! 2c data access MMU miss - BAD_TRAP; ! 2d - BAD_TRAP; ! 2e - BAD_TRAP; ! 2f - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 30-33 - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 34-37 - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 38-3b - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 3c-3f - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 40-43 - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 44-47 - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 48-4b - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 4c-4f - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 50-53 - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 54-57 - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 58-5b - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 5c-5f - - /* implementaion dependent */ - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 60-63 - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 64-67 - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 68-6b - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 6c-6f - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 70-73 - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 74-77 - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 78-7b - BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 7c-7f - - /* Software traps, not handled */ - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 80-83 - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 84-87 - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 88-8b - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 8c-8f - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 90-93 - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 94-97 - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 98-9b - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 9c-9f - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! a0-a3 - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! a4-a7 - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! a8-ab - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! ac-af - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! b0-b3 - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! b4-b7 - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! b8-bb - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! bc-bf - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! c0-c3 - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! c4-c7 - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! c8-cb - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! cc-cf - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! d0-d3 - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! d4-d7 - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! d8-db - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! dc-df - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! e0-e3 - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! e4-e7 - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! e8-eb - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! ec-ef - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f0-f3 - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f4-f7 - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f8-fb - SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! fc-ff - - .section ".text" - .extern _nomem_amba_init, _nomem_memory_ctrl_init - .align 4 - -_hardreset: -1000: - flush - - /* Enable I/D-Cache and Snooping */ - set 0x0081000f, %g2 - sta %g2, [%g0] 2 - - mov %g0, %y - clr %g1 - clr %g2 - clr %g3 - clr %g4 - clr %g5 - clr %g6 - clr %g7 - - mov %asr17, %g3 - and %g3, 0x1f, %g3 -clear_window: - mov %g0, %l0 - mov %g0, %l1 - mov %g0, %l2 - mov %g0, %l3 - mov %g0, %l4 - mov %g0, %l5 - mov %g0, %l6 - mov %g0, %l7 - mov %g0, %o0 - mov %g0, %o1 - mov %g0, %o2 - mov %g0, %o3 - mov %g0, %o4 - mov %g0, %o5 - mov %g0, %o6 - mov %g0, %o7 - subcc %g3, 1, %g3 - bge clear_window - save - -wiminit: - set WIM_INIT, %g3 - mov %g3, %wim - -stackinit: - set CONFIG_SYS_INIT_SP_OFFSET, %fp - andn %fp, 0x0f, %fp - sub %fp, 64, %sp - -tbrinit: - set CONFIG_SYS_TEXT_BASE, %g2 - wr %g0, %g2, %tbr - nop - nop - nop - -/* Obtain the address of _GLOBAL_OFFSET_TABLE_ */ - SPARC_PIC_THUNK_CALL(l7) - -/* Scan AMBA Bus for AMBA buses using PnP information. All found - * AMBA buses I/O area will be located in i0-i5 upon return. - * The i0-i5 registers are later used by _nomem_amba_init2 - */ -ambainit: - call _nomem_amba_init - sethi %hi(CONFIG_AMBAPP_IOAREA), %o0 - -/* Scan AMBA Buses for memory controllers, then initialize the - * memory controllers. Note that before setting up the memory controller - * the stack can not be used. - */ -memory_ctrl_init: - SPARC_LOAD_ADDRESS(grlib_mctrl_handlers, l7, o0) - - call _nomem_memory_ctrl_init - nop - -/* The return valu indicate how many memory controllers where found and - * initialized, if no memory controller was initialized, we can not continue - * because from here on we expect memory to be working. - */ - cmp %o0, 0 -memory_ctrl_init_failed: - beq memory_ctrl_init_failed - nop - -/*** From now on the stack can be used. ***/ - -cpu_init_unreloc: - call cpu_init_f - nop - -board_init_unreloc: - call board_init_f - clr %o0 ! boot_flags - -dead_unreloc: - mov 1, %g1 ! For GRMON2 to exit normally. - ta 0 ! If board_init_f call returns.. (unlikely) - nop - nop - ba dead_unreloc ! infinte loop - nop - -!------------------------------------------------------------------------------- - -/* void relocate_code (addr_sp, gd, addr_moni) - * - * This "function" does not return, instead it continues in RAM after - * relocating the monitor code. - * - * %o0 = Relocated stack pointer - * %o1 = Relocated global data pointer - * %o2 = Relocated text pointer - * - * %l7 = _GLOBAL_OFFSET_TABLE_ address - */ - .globl relocate_code - .type relocate_code, #function - .align 4 -relocate_code: - !SPARC_PIC_THUNK_CALL(l7) -reloc: - SPARC_LOAD_ADDRESS(_text, l7, g2) ! start address of monitor - SPARC_LOAD_ADDRESS(__init_end, l7, g3) ! end address of monitor - mov %o2, %g4 ! relocation address - sub %g4, %g2, %g6 ! relocation offset - /* copy .text & .data to relocated address */ -10: ldd [%g2], %l0 - ldd [%g2+8], %l2 - std %l0, [%g4] - std %l2, [%g4+8] - inc 16, %g2 ! src += 16 - cmp %g2, %g3 - bcs 10b ! while (src < end) - inc 16, %g4 ! dst += 16 - - clr %l0 - clr %l1 - clr %l2 - clr %l3 - clr %g2 - -/* register g4 contain address to start - * This means that BSS must be directly after data and code segments - * - * g3 is length of bss = (__bss_end-__bss_start) - * - */ - - /* clear the relocated .bss area */ -clr_bss: - SPARC_LOAD_ADDRESS(__bss_start, l7, g2) - SPARC_LOAD_ADDRESS(__bss_end, l7, g3) - sub %g3,%g2,%g3 ! length of .bss area - add %g3,%g4,%g3 - /* clearing 16byte a time ==> linker script need to align to 16 byte offset */ - clr %g1 /* std %g0 uses g0 and g1 */ -20: - std %g0, [%g4] - std %g0, [%g4+8] - inc 16, %g4 ! ptr += 16 - cmp %g4, %g3 - bcs 20b ! while (ptr < end) - nop - - /* add offsets to GOT table */ -fixup_got: - SPARC_LOAD_ADDRESS(__got_start, l7, g4) - add %g4, %g6, %g4 - SPARC_LOAD_ADDRESS(__got_end, l7, g3) - add %g3, %g6, %g3 -30: ld [%g4], %l0 -#ifdef CONFIG_RELOC_GOT_SKIP_NULL - cmp %l0, 0 - be 32f -#endif - add %l0, %g6, %l0 ! relocate GOT pointer - st %l0, [%g4] -32: inc 4, %g4 ! ptr += 4 - cmp %g4, %g3 - bcs 30b ! while (ptr < end) - nop - -prom_relocate: - SPARC_LOAD_ADDRESS(__prom_start, l7, g2) - SPARC_LOAD_ADDRESS(__prom_end, l7, g3) - /* - * Calculated addres is stored in this variable by - * reserve_prom() function in common/board_f.c - */ - SPARC_LOAD_ADDRESS(__prom_start_reloc, l7, g4) - ld [%g4], %g4 - -40: ldd [%g2], %l0 - ldd [%g2+8], %l2 - std %l0, [%g4] - std %l2, [%g4+8] - inc 16, %g2 - cmp %g2, %g3 - bcs 40b - inc 16, %g4 - -! %o0 = stack pointer (relocated) -! %o1 = global data pointer (relocated) -! %o2 = text pointer (relocated) - -! %g6 = relocation offset -! %l7 = _GLOBAL_OFFSET_TABLE_ - -/* Trap table has been moved, lets tell CPU about - * the new trap table address - */ -update_trap_table_address: - wr %g0, %o2, %tbr - nop - nop - nop - -update_stack_pointers: - mov %o0, %fp - andn %fp, 0x0f, %fp ! align to 16 bytes - add %fp, -64, %fp ! make space for a window push - mov %fp, %sp ! setup stack pointer - -jump_board_init_r: - mov %o1, %o0 ! relocated global data pointer - mov %o2, %o1 ! relocated text pointer - SPARC_LOAD_ADDRESS(board_init_r, l7, o3) - add %o3, %g6, %o3 ! add relocation offset - call %o3 - nop - -dead: - mov 1, %g1 ! For GRMON2 to exit normally. - ta 0 ! if call returns.. (unlikely) - nop - b dead ! infinte loop - nop - -!------------------------------------------------------------------------------ - -/* Interrupt handler caller, - * reg L7: interrupt number - * reg L0: psr after interrupt - * reg L1: PC - * reg L2: next PC - * reg L3: wim - */ -_irq_entry: - SAVE_ALL - - or %l0, PSR_PIL, %g2 - wr %g2, 0x0, %psr - WRITE_PAUSE - wr %g2, PSR_ET, %psr - WRITE_PAUSE - mov %l7, %o0 ! irq level - set handler_irq, %o1 - set (CONFIG_SYS_RELOC_MONITOR_BASE-CONFIG_SYS_TEXT_BASE), %o2 - add %o1, %o2, %o1 - call %o1 - add %sp, SF_REGS_SZ, %o1 ! pt_regs ptr - or %l0, PSR_PIL, %g2 ! restore PIL after handler_irq - wr %g2, PSR_ET, %psr ! keep ET up - WRITE_PAUSE - - RESTORE_ALL - -!------------------------------------------------------------------------------ - -/* - * Window overflow trap handler - */ - .global _window_overflow - -_window_overflow: - - mov %wim, %l3 ! Calculate next WIM - mov %g1, %l7 - srl %l3, 1, %g1 - sll %l3, (CONFIG_SYS_SPARC_NWINDOWS-1), %l4 - or %g1, %l4, %g1 - save ! Get into window to be saved. - mov %g1, %wim - nop; nop; nop - st %l0, [%sp + 0] ! Save window to the stack - st %l1, [%sp + 4] - st %l2, [%sp + 8] - st %l3, [%sp + 12] - st %l4, [%sp + 16] - st %l5, [%sp + 20] - st %l6, [%sp + 24] - st %l7, [%sp + 28] - st %i0, [%sp + 32] - st %i1, [%sp + 36] - st %i2, [%sp + 40] - st %i3, [%sp + 44] - st %i4, [%sp + 48] - st %i5, [%sp + 52] - st %i6, [%sp + 56] - st %i7, [%sp + 60] - restore ! Go back to trap window. - mov %l7, %g1 - jmp %l1 ! Re-execute save. - rett %l2 - -/* - * Window underflow trap handler - */ - .global _window_underflow - -_window_underflow: - - mov %wim, %l3 ! Calculate next WIM - srl %l3, (CONFIG_SYS_SPARC_NWINDOWS-1), %l5 - sll %l3, 1, %l4 - or %l5, %l4, %l5 - mov %l5, %wim - nop; nop; nop - restore ! Two restores to get into the - restore ! window to restore - ld [%sp + 0], %l0; ! Restore window from the stack - ld [%sp + 4], %l1; - ld [%sp + 8], %l2; - ld [%sp + 12], %l3; - ld [%sp + 16], %l4; - ld [%sp + 20], %l5; - ld [%sp + 24], %l6; - ld [%sp + 28], %l7; - ld [%sp + 32], %i0; - ld [%sp + 36], %i1; - ld [%sp + 40], %i2; - ld [%sp + 44], %i3; - ld [%sp + 48], %i4; - ld [%sp + 52], %i5; - ld [%sp + 56], %i6; - ld [%sp + 60], %i7; - save ! Get back to the trap window. - save - jmp %l1 ! Re-execute restore. - rett %l2 - -!------------------------------------------------------------------------------ - -_nmi_trap: - nop - jmp %l1 - rett %l2 - -_hwerr: - ta 0 - nop - nop - b _hwerr ! loop infinite - nop - -/* Registers to not touch at all. */ -#define t_psr l0 /* Set by caller */ -#define t_pc l1 /* Set by caller */ -#define t_npc l2 /* Set by caller */ -#define t_wim l3 /* Set by caller */ -#define t_twinmask l4 /* Set at beginning of this entry routine. */ -#define t_kstack l5 /* Set right before pt_regs frame is built */ -#define t_retpc l6 /* If you change this, change winmacro.h header file */ -#define t_systable l7 /* Never touch this, could be the syscall table ptr. */ -#define curptr g6 /* Set after pt_regs frame is built */ - -trap_setup: -/* build a pt_regs trap frame. */ - sub %fp, (SF_REGS_SZ + PT_REGS_SZ), %t_kstack - PT_STORE_ALL(t_kstack, t_psr, t_pc, t_npc, g2) - - /* See if we are in the trap window. */ - mov 1, %t_twinmask - sll %t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr) - andcc %t_twinmask, %t_wim, %g0 - beq 1f ! in trap window, clean up - nop - - /*------------------------------------------------- - * Spill , adjust %wim and go. - */ - srl %t_wim, 0x1, %g2 ! begin computation of new %wim - - set (CONFIG_SYS_SPARC_NWINDOWS-1), %g3 !NWINDOWS-1 - - sll %t_wim, %g3, %t_wim ! NWINDOWS-1 - or %t_wim, %g2, %g2 - and %g2, 0xff, %g2 - - save %g0, %g0, %g0 ! get in window to be saved - - /* Set new %wim value */ - wr %g2, 0x0, %wim - - /* Save the kernel window onto the corresponding stack. */ - RW_STORE(sp) - - restore %g0, %g0, %g0 - /*-------------------------------------------------*/ - -1: - /* Trap from kernel with a window available. - * Just do it... - */ - jmpl %t_retpc + 0x8, %g0 ! return to caller - mov %t_kstack, %sp ! jump onto new stack - -#define twin_tmp1 l4 -#define glob_tmp g4 -#define curptr g6 -ret_trap_entry: - wr %t_psr, 0x0, %psr ! enable nesting again, clear ET - - /* Will the rett land us in the invalid window? */ - mov 2, %g1 - sll %g1, %t_psr, %g1 - - set CONFIG_SYS_SPARC_NWINDOWS, %g2 !NWINDOWS - - srl %g1, %g2, %g2 - or %g1, %g2, %g1 - rd %wim, %g2 - andcc %g2, %g1, %g0 - be 1f ! Nope, just return from the trap - sll %g2, 0x1, %g1 - - /* We have to grab a window before returning. */ - set (CONFIG_SYS_SPARC_NWINDOWS-1), %g3 !NWINDOWS-1 - - srl %g2, %g3, %g2 - or %g1, %g2, %g1 - and %g1, 0xff, %g1 - - wr %g1, 0x0, %wim - - /* Grrr, make sure we load from the right %sp... */ - PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1) - - restore %g0, %g0, %g0 - RW_LOAD(sp) - b 2f - save %g0, %g0, %g0 - - /* Reload the entire frame in case this is from a - * kernel system call or whatever... - */ -1: - PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1) -2: - wr %t_psr, 0x0, %psr - nop; - nop; - nop - - jmp %t_pc - rett %t_npc - -/* This is called from relocated C-code. - * It resets the system by jumping to _start - */ -_reset_reloc: - set start, %l0 - call %l0 - nop diff --git a/arch/sparc/cpu/leon3/usb_uhci.c b/arch/sparc/cpu/leon3/usb_uhci.c deleted file mode 100644 index 67bd1241bd..0000000000 --- a/arch/sparc/cpu/leon3/usb_uhci.c +++ /dev/null @@ -1,1195 +0,0 @@ -/* - * Part of this code has been derived from linux: - * Universal Host Controller Interface driver for USB (take II). - * - * (c) 1999-2001 Georg Acher, acher@in.tum.de (executive slave) (base guitar) - * Deti Fliegl, deti@fliegl.de (executive slave) (lead voice) - * Thomas Sailer, sailer@ife.ee.ethz.ch (chief consultant) (cheer leader) - * Roman Weissgaerber, weissg@vienna.at (virt root hub) (studio porter) - * (c) 2000 Yggdrasil Computing, Inc. (port of new PCI interface support - * from usb-ohci.c by Adam Richter, adam@yggdrasil.com). - * (C) 2000 David Brownell, david-b@pacbell.net (usb-ohci.c) - * - * HW-initalization based on material of - * - * (C) Copyright 1999 Linus Torvalds - * (C) Copyright 1999 Johannes Erdfelt - * (C) Copyright 1999 Randy Dunlap - * (C) Copyright 1999 Gregory P. Smith - * - * - * Adapted for U-Boot: - * (C) Copyright 2001 Denis Peter, MPL AG Switzerland - * (C) Copyright 2008, Daniel Hellström, daniel@gaisler.com - * Added AMBA Plug&Play detection of GRUSB, modified interrupt handler. - * Added cache flushes where needed. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/********************************************************************** - * How it works: - * ------------- - * The framelist / Transfer descriptor / Queue Heads are similar like - * in the linux usb_uhci.c. - * - * During initialization, the following skeleton is allocated in init_skel: - * - * framespecific | common chain - * - * framelist[] - * [ 0 ]-----> TD ---------\ - * [ 1 ]-----> TD ----------> TD ------> QH -------> QH -------> QH ---> NULL - * ... TD ---------/ - * [1023]-----> TD --------/ - * - * ^^ ^^ ^^ ^^ ^^ - * 7 TDs for 1 TD for Start of Start of End Chain - * INT (2-128ms) 1ms-INT CTRL Chain BULK Chain - * - * - * Since this is a bootloader, the isochronous transfer descriptor have been removed. - * - * Interrupt Transfers. - * -------------------- - * For Interrupt transfers USB_MAX_TEMP_INT_TD Transfer descriptor are available. They - * will be inserted after the appropriate (depending the interval setting) skeleton TD. - * If an interrupt has been detected the dev->irqhandler is called. The status and number - * of transferred bytes is stored in dev->irq_status resp. dev->irq_act_len. If the - * dev->irqhandler returns 0, the interrupt TD is removed and disabled. If an 1 is returned, - * the interrupt TD will be reactivated. - * - * Control Transfers - * ----------------- - * Control Transfers are issued by filling the tmp_td with the appropriate data and connect - * them to the qh_cntrl queue header. Before other control/bulk transfers can be issued, - * the programm has to wait for completion. This does not allows asynchronous data transfer. - * - * Bulk Transfers - * -------------- - * Bulk Transfers are issued by filling the tmp_td with the appropriate data and connect - * them to the qh_bulk queue header. Before other control/bulk transfers can be issued, - * the programm has to wait for completion. This does not allows asynchronous data transfer. - * - * - */ - -#include <common.h> -#include <ambapp.h> -#include <asm/leon.h> -#include <asm/leon3.h> -#include <asm/processor.h> - -#ifdef CONFIG_USB_UHCI - -#include <usb.h> -#include "usb_uhci.h" - -DECLARE_GLOBAL_DATA_PTR; - -#define USB_MAX_TEMP_TD 128 /* number of temporary TDs for bulk and control transfers */ -#define USB_MAX_TEMP_INT_TD 32 /* number of temporary TDs for Interrupt transfers */ - -/* -#define out16r(address,data) (*(unsigned short *)(address) = \ - (unsigned short)( \ - (((unsigned short)(data)&0xff)<<8) | \ - (((unsigned short)(data)&0xff00)>>8) \ - )) - */ -#define out16r(address,data) _out16r((unsigned int)(address), (unsigned short)(data)) -void _out16r(unsigned int address, unsigned short data) -{ - unsigned short val = (unsigned short)((((unsigned short)(data) & 0xff) - << 8) | (((unsigned short)(data) - & 0xff00) >> 8)); -#ifdef UHCI_DEBUG_REGS - printf("out16r(0x%lx,0x%04x = 0x%04x)\n", address, val, data); -#endif - *(unsigned short *)(address) = val; -} - -#define out32r(address,data) _out32r((unsigned int)(address), (unsigned int)(data)) -void _out32r(unsigned int address, unsigned int data) -{ - unsigned int val = (unsigned int)((((unsigned int)(data) & 0x000000ff) - << 24) | (((unsigned int)(data) & - 0x0000ff00) << 8) | - (((unsigned int)(data) & 0x00ff0000) - >> 8) | (((unsigned int)(data) & - 0xff000000) >> 24)); -#ifdef UHCI_DEBUG_REGS - printf("out32r(0x%lx,0x%lx = 0x%lx)\n", address, val, data); -#endif - *(unsigned int *)address = val; -} - -#define in16r(address) _in16r((unsigned int)(address)) -unsigned short _in16r(unsigned int address) -{ - unsigned short val = sparc_load_reg_cachemiss_word(address); - val = ((val << 8) & 0xff00) | ((val >> 8) & 0xff); -#ifdef UHCI_DEBUG_REGS - printf("in16r(0x%lx): 0x%04x\n", address, val); -#endif - return val; -} - -#define in32r(address) _in32r((unsigned int)(address)) -unsigned int _in32r(unsigned int address) -{ - unsigned int val = sparc_load_reg_cachemiss(address); - val = - ((val << 24) & 0xff000000) | ((val << 8) & 0xff0000) | ((val >> 8) & - 0xff00) | - ((val >> 24) & 0xff); -#ifdef UHCI_DEBUG_REGS - printf("in32r(0x%lx): 0x%08x\n", address, val); -#endif - return val; -} - -#define READ32(address) sparc_load_reg_cachemiss((unsigned int)(address)) - -/*#define USB_UHCI_DEBUG*/ -#undef USB_UHCI_DEBUG - -void usb_show_td(int max); -#ifdef USB_UHCI_DEBUG -void grusb_show_regs(void); -#define USB_UHCI_PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define USB_UHCI_PRINTF(fmt,args...) -#endif - -static int grusb_irq = -1; /* irq vector, if -1 uhci is stopped / reseted */ -unsigned int usb_base_addr; /* base address */ - -static uhci_td_t td_int[8] __attribute__ ((aligned(16))); /* Interrupt Transfer descriptors */ -static uhci_qh_t qh_cntrl __attribute__ ((aligned(16))); /* control Queue Head */ -static uhci_qh_t qh_bulk __attribute__ ((aligned(16))); /* bulk Queue Head */ -static uhci_qh_t qh_end __attribute__ ((aligned(16))); /* end Queue Head */ -static uhci_td_t td_last __attribute__ ((aligned(16))); /* last TD (linked with end chain) */ - -/* temporary tds */ -static uhci_td_t tmp_td[USB_MAX_TEMP_TD] __attribute__ ((aligned(16))); /* temporary bulk/control td's */ -static uhci_td_t tmp_int_td[USB_MAX_TEMP_INT_TD] __attribute__ ((aligned(16))); /* temporary interrupt td's */ - -static unsigned long framelist[1024] __attribute__ ((aligned(0x1000))); /* frame list */ - -static struct virt_root_hub rh; /* struct for root hub */ - -/********************************************************************** - * some forward decleration - */ -int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, - void *buffer, int transfer_len, - struct devrequest *setup); - -/* fill a td with the approproiate data. Link, status, info and buffer - * are used by the USB controller itselfes, dev is used to identify the - * "connected" device - */ -void usb_fill_td(uhci_td_t * td, unsigned long link, unsigned long status, - unsigned long info, unsigned long buffer, unsigned long dev) -{ - td->link = swap_32(link); - td->status = swap_32(status); - if ((info & UHCI_PID) == 0) - info |= USB_PID_OUT; - td->info = swap_32(info); - td->buffer = swap_32(buffer); - td->dev_ptr = dev; -} - -/* fill a qh with the approproiate data. Head and element are used by the USB controller - * itselfes. As soon as a valid dev_ptr is filled, a td chain is connected to the qh. - * Please note, that after completion of the td chain, the entry element is removed / - * marked invalid by the USB controller. - */ -void usb_fill_qh(uhci_qh_t * qh, unsigned long head, unsigned long element) -{ - qh->head = swap_32(head); - qh->element = swap_32(element); - qh->dev_ptr = 0L; -} - -/* get the status of a td->status - */ -unsigned long usb_uhci_td_stat(unsigned long status) -{ - unsigned long result = 0; - result |= (status & TD_CTRL_NAK) ? USB_ST_NAK_REC : 0; - result |= (status & TD_CTRL_STALLED) ? USB_ST_STALLED : 0; - result |= (status & TD_CTRL_DBUFERR) ? USB_ST_BUF_ERR : 0; - result |= (status & TD_CTRL_BABBLE) ? USB_ST_BABBLE_DET : 0; - result |= (status & TD_CTRL_CRCTIMEO) ? USB_ST_CRC_ERR : 0; - result |= (status & TD_CTRL_BITSTUFF) ? USB_ST_BIT_ERR : 0; - result |= (status & TD_CTRL_ACTIVE) ? USB_ST_NOT_PROC : 0; - return result; -} - -/* get the status and the transferred len of a td chain. - * called from the completion handler - */ -int usb_get_td_status(uhci_td_t * td, struct usb_device *dev) -{ - unsigned long temp, info; - unsigned long stat; - uhci_td_t *mytd = td; - - if (dev->devnum == rh.devnum) - return 0; - dev->act_len = 0; - stat = 0; - do { - temp = swap_32((unsigned long)READ32(&mytd->status)); - stat = usb_uhci_td_stat(temp); - info = swap_32((unsigned long)READ32(&mytd->info)); - if (((info & 0xff) != USB_PID_SETUP) && (((info >> 21) & 0x7ff) != 0x7ff) && (temp & 0x7FF) != 0x7ff) { /* if not setup and not null data pack */ - dev->act_len += (temp & 0x7FF) + 1; /* the transferred len is act_len + 1 */ - } - if (stat) { /* status no ok */ - dev->status = stat; - return -1; - } - temp = swap_32((unsigned long)READ32(&mytd->link)); - mytd = (uhci_td_t *) (temp & 0xfffffff0); - } while ((temp & 0x1) == 0); /* process all TDs */ - dev->status = stat; - return 0; /* Ok */ -} - -/*------------------------------------------------------------------- - * LOW LEVEL STUFF - * assembles QHs und TDs for control, bulk and iso - *-------------------------------------------------------------------*/ -int dummy(void) -{ - USB_UHCI_PRINTF("DUMMY\n"); - return 0; -} - -/* Submits a control message. That is a Setup, Data and Status transfer. - * Routine does not wait for completion. - */ -int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *setup) -{ - unsigned long destination, status; - int maxsze = usb_maxpacket(dev, pipe); - unsigned long dataptr; - int len; - int pktsze; - int i = 0; - - if (!maxsze) { - USB_UHCI_PRINTF - ("uhci_submit_control_urb: pipesize for pipe %lx is zero\n", - pipe); - return -1; - } - if (((pipe >> 8) & 0x7f) == rh.devnum) { - /* this is the root hub -> redirect it */ - return uhci_submit_rh_msg(dev, pipe, buffer, transfer_len, - setup); - } - USB_UHCI_PRINTF("uhci_submit_control start len %x, maxsize %x\n", - transfer_len, maxsze); - /* The "pipe" thing contains the destination in bits 8--18 */ - destination = (pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; /* Setup stage */ - /* 3 errors */ - status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27); - /* (urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD); */ - /* Build the TD for the control request, try forever, 8 bytes of data */ - usb_fill_td(&tmp_td[i], UHCI_PTR_TERM, status, destination | (7 << 21), - (unsigned long)setup, (unsigned long)dev); -#ifdef DEBUG_EXTRA - { - char *sp = (char *)setup; - printf("SETUP to pipe %lx: %x %x %x %x %x %x %x %x\n", pipe, - sp[0], sp[1], sp[2], sp[3], sp[4], sp[5], sp[6], sp[7]); - } -#endif - dataptr = (unsigned long)buffer; - len = transfer_len; - - /* If direction is "send", change the frame from SETUP (0x2D) - to OUT (0xE1). Else change it from SETUP to IN (0x69). */ - destination = - (pipe & PIPE_DEVEP_MASK) | ((pipe & USB_DIR_IN) == - 0 ? USB_PID_OUT : USB_PID_IN); - while (len > 0) { - /* data stage */ - pktsze = len; - i++; - if (pktsze > maxsze) - pktsze = maxsze; - destination ^= 1 << TD_TOKEN_TOGGLE; /* toggle DATA0/1 */ - usb_fill_td(&tmp_td[i], UHCI_PTR_TERM, status, destination | ((pktsze - 1) << 21), dataptr, (unsigned long)dev); /* Status, pktsze bytes of data */ - tmp_td[i - 1].link = swap_32((unsigned long)&tmp_td[i]); - - dataptr += pktsze; - len -= pktsze; - } - - /* Build the final TD for control status */ - /* It's only IN if the pipe is out AND we aren't expecting data */ - - destination &= ~UHCI_PID; - if (((pipe & USB_DIR_IN) == 0) || (transfer_len == 0)) - destination |= USB_PID_IN; - else - destination |= USB_PID_OUT; - destination |= 1 << TD_TOKEN_TOGGLE; /* End in Data1 */ - i++; - status &= ~TD_CTRL_SPD; - /* no limit on errors on final packet , 0 bytes of data */ - usb_fill_td(&tmp_td[i], UHCI_PTR_TERM, status | TD_CTRL_IOC, - destination | (UHCI_NULL_DATA_SIZE << 21), 0, - (unsigned long)dev); - tmp_td[i - 1].link = swap_32((unsigned long)&tmp_td[i]); /* queue status td */ - /* usb_show_td(i+1); */ - USB_UHCI_PRINTF("uhci_submit_control end (%d tmp_tds used)\n", i); - /* first mark the control QH element terminated */ - qh_cntrl.element = 0xffffffffL; - /* set qh active */ - qh_cntrl.dev_ptr = (unsigned long)dev; - /* fill in tmp_td_chain */ - dummy(); - qh_cntrl.element = swap_32((unsigned long)&tmp_td[0]); - return 0; -} - -/*------------------------------------------------------------------- - * Prepare TDs for bulk transfers. - */ -int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len) -{ - unsigned long destination, status, info; - unsigned long dataptr; - int maxsze = usb_maxpacket(dev, pipe); - int len; - int i = 0; - - if (transfer_len < 0) { - printf("Negative transfer length in submit_bulk\n"); - return -1; - } - if (!maxsze) - return -1; - /* The "pipe" thing contains the destination in bits 8--18. */ - destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid(pipe); - /* 3 errors */ - status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27); - /* ((urb->transfer_flags & USB_DISABLE_SPD) ? 0 : TD_CTRL_SPD) | (3 << 27); */ - /* Build the TDs for the bulk request */ - len = transfer_len; - dataptr = (unsigned long)buffer; - do { - int pktsze = len; - if (pktsze > maxsze) - pktsze = maxsze; - /* pktsze bytes of data */ - info = - destination | (((pktsze - 1) & UHCI_NULL_DATA_SIZE) << 21) | - (usb_gettoggle - (dev, usb_pipeendpoint(pipe), - usb_pipeout(pipe)) << TD_TOKEN_TOGGLE); - - if ((len - pktsze) == 0) - status |= TD_CTRL_IOC; /* last one generates INT */ - - usb_fill_td(&tmp_td[i], UHCI_PTR_TERM, status, info, dataptr, (unsigned long)dev); /* Status, pktsze bytes of data */ - if (i > 0) - tmp_td[i - 1].link = swap_32((unsigned long)&tmp_td[i]); - i++; - dataptr += pktsze; - len -= pktsze; - usb_dotoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)); - } while (len > 0); - /* first mark the bulk QH element terminated */ - qh_bulk.element = 0xffffffffL; - /* set qh active */ - qh_bulk.dev_ptr = (unsigned long)dev; - /* fill in tmp_td_chain */ - qh_bulk.element = swap_32((unsigned long)&tmp_td[0]); - return 0; -} - -/* search a free interrupt td - */ -uhci_td_t *uhci_alloc_int_td(void) -{ - int i; - for (i = 0; i < USB_MAX_TEMP_INT_TD; i++) { - if (tmp_int_td[i].dev_ptr == 0) /* no device assigned -> free TD */ - return &tmp_int_td[i]; - } - return NULL; -} - -/*------------------------------------------------------------------- - * submits USB interrupt (ie. polling ;-) - */ -int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, int interval) -{ - int nint, n; - unsigned long status, destination; - unsigned long info, tmp; - uhci_td_t *mytd; - if (interval < 0 || interval >= 256) - return -1; - - if (interval == 0) - nint = 0; - else { - for (nint = 0, n = 1; nint <= 8; nint++, n += n) { /* round interval down to 2^n */ - if (interval < n) { - interval = n / 2; - break; - } - } - nint--; - } - - USB_UHCI_PRINTF("Rounded interval to %i, chain %i\n", interval, nint); - mytd = uhci_alloc_int_td(); - if (mytd == NULL) { - printf("No free INT TDs found\n"); - return -1; - } - status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC | (3 << 27); -/* (urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27); -*/ - - destination = - (pipe & PIPE_DEVEP_MASK) | usb_packetid(pipe) | - (((transfer_len - 1) & 0x7ff) << 21); - - info = - destination | - (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << - TD_TOKEN_TOGGLE); - tmp = swap_32(td_int[nint].link); - usb_fill_td(mytd, tmp, status, info, (unsigned long)buffer, - (unsigned long)dev); - /* Link it */ - tmp = swap_32((unsigned long)mytd); - td_int[nint].link = tmp; - - usb_dotoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)); - - return 0; -} - -/********************************************************************** - * Low Level functions - */ - -void reset_hc(void) -{ - - /* Global reset for 100ms */ - out16r(usb_base_addr + USBPORTSC1, 0x0204); - out16r(usb_base_addr + USBPORTSC2, 0x0204); - out16r(usb_base_addr + USBCMD, USBCMD_GRESET | USBCMD_RS); - /* Turn off all interrupts */ - out16r(usb_base_addr + USBINTR, 0); - mdelay(50); - out16r(usb_base_addr + USBCMD, 0); - mdelay(10); -} - -void start_hc(void) -{ - int timeout = 1000; - - while (in16r(usb_base_addr + USBCMD) & USBCMD_HCRESET) { - if (!--timeout) { - printf("USBCMD_HCRESET timed out!\n"); - break; - } - } - /* Turn on all interrupts */ - out16r(usb_base_addr + USBINTR, - USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP); - /* Start at frame 0 */ - out16r(usb_base_addr + USBFRNUM, 0); - /* set Framebuffer base address */ - out32r(usb_base_addr + USBFLBASEADD, (unsigned long)&framelist); - /* Run and mark it configured with a 64-byte max packet */ - out16r(usb_base_addr + USBCMD, USBCMD_RS | USBCMD_CF | USBCMD_MAXP); -} - -/* Initialize the skeleton - */ -void usb_init_skel(void) -{ - unsigned long temp; - int n; - - for (n = 0; n < USB_MAX_TEMP_INT_TD; n++) - tmp_int_td[n].dev_ptr = 0L; /* no devices connected */ - /* last td */ - usb_fill_td(&td_last, UHCI_PTR_TERM, TD_CTRL_IOC, USB_PID_OUT, 0, 0L); - /* usb_fill_td(&td_last,UHCI_PTR_TERM,0,0,0); */ - /* End Queue Header */ - usb_fill_qh(&qh_end, UHCI_PTR_TERM, (unsigned long)&td_last); - /* Bulk Queue Header */ - temp = (unsigned long)&qh_end; - usb_fill_qh(&qh_bulk, temp | UHCI_PTR_QH, UHCI_PTR_TERM); - /* Control Queue Header */ - temp = (unsigned long)&qh_bulk; - usb_fill_qh(&qh_cntrl, temp | UHCI_PTR_QH, UHCI_PTR_TERM); - /* 1ms Interrupt td */ - temp = (unsigned long)&qh_cntrl; - usb_fill_td(&td_int[0], temp | UHCI_PTR_QH, 0, USB_PID_OUT, 0, 0L); - temp = (unsigned long)&td_int[0]; - for (n = 1; n < 8; n++) - usb_fill_td(&td_int[n], temp, 0, USB_PID_OUT, 0, 0L); - for (n = 0; n < 1024; n++) { - /* link all framelist pointers to one of the interrupts */ - int m, o; - if ((n & 127) == 127) - framelist[n] = swap_32((unsigned long)&td_int[0]); - else - for (o = 1, m = 2; m <= 128; o++, m += m) - if ((n & (m - 1)) == ((m - 1) / 2)) - framelist[n] = - swap_32((unsigned long)&td_int[o]); - - } -} - -/* check the common skeleton for completed transfers, and update the status - * of the "connected" device. Called from the IRQ routine. - */ -void usb_check_skel(void) -{ - struct usb_device *dev; - /* start with the control qh */ - if (qh_cntrl.dev_ptr != 0) { /* it's a device assigned check if this caused IRQ */ - dev = (struct usb_device *)qh_cntrl.dev_ptr; - /* Flush cache now that hardware updated DATA and TDs/QHs */ - if (!gd->arch.snooping_avail) - sparc_dcache_flush_all(); - usb_get_td_status(&tmp_td[0], dev); /* update status */ - if (!(dev->status & USB_ST_NOT_PROC)) { /* is not active anymore, disconnect devices */ - qh_cntrl.dev_ptr = 0; - } - } - /* now process the bulk */ - if (qh_bulk.dev_ptr != 0) { /* it's a device assigned check if this caused IRQ */ - dev = (struct usb_device *)qh_bulk.dev_ptr; - /* Flush cache now that hardware updated DATA and TDs/QHs */ - if (!gd->arch.snooping_avail) - sparc_dcache_flush_all(); - usb_get_td_status(&tmp_td[0], dev); /* update status */ - if (!(dev->status & USB_ST_NOT_PROC)) { /* is not active anymore, disconnect devices */ - qh_bulk.dev_ptr = 0; - } - } -} - -/* check the interrupt chain, ubdate the status of the appropriate device, - * call the appropriate irqhandler and reactivate the TD if the irqhandler - * returns with 1 - */ -void usb_check_int_chain(void) -{ - int i, res; - unsigned long link, status; - struct usb_device *dev; - uhci_td_t *td, *prevtd; - - for (i = 0; i < 8; i++) { - prevtd = &td_int[i]; /* the first previous td is the skeleton td */ - link = swap_32(READ32(&td_int[i].link)) & 0xfffffff0; /* next in chain */ - td = (uhci_td_t *) link; /* assign it */ - /* all interrupt TDs are finally linked to the td_int[0]. - * so we process all until we find the td_int[0]. - * if int0 chain points to a QH, we're also done - */ - while (((i > 0) && (link != (unsigned long)&td_int[0])) || - ((i == 0) - && !(swap_32(READ32(&td->link)) & UHCI_PTR_QH))) { - /* check if a device is assigned with this td */ - status = swap_32(READ32(&td->status)); - if ((td->dev_ptr != 0L) && !(status & TD_CTRL_ACTIVE)) { - /* td is not active and a device is assigned -> call irqhandler */ - dev = (struct usb_device *)td->dev_ptr; - dev->irq_act_len = ((status & 0x7FF) == 0x7FF) ? 0 : (status & 0x7FF) + 1; /* transferred length */ - dev->irq_status = usb_uhci_td_stat(status); /* get status */ - res = dev->irq_handle(dev); /* call irqhandler */ - if (res == 1) { - /* reactivate */ - status |= TD_CTRL_ACTIVE; - td->status = swap_32(status); - prevtd = td; /* previous td = this td */ - } else { - prevtd->link = READ32(&td->link); /* link previous td directly to the nex td -> unlinked */ - /* remove device pointer */ - td->dev_ptr = 0L; - } - } /* if we call the irq handler */ - link = swap_32(READ32(&td->link)) & 0xfffffff0; /* next in chain */ - td = (uhci_td_t *) link; /* assign it */ - } /* process all td in this int chain */ - } /* next interrupt chain */ -} - -/* usb interrupt service routine. - */ -void handle_usb_interrupt(void) -{ - unsigned short status; - static int error = 0; - - /* - * Read the interrupt status, and write it back to clear the - * interrupt cause - */ - - status = in16r(usb_base_addr + USBSTS); - - if (!status) /* shared interrupt, not mine */ - return; - if (status != 1) { - /* remove host controller halted state */ - if ((status & (USBSTS_HCPE | USBSTS_HCH)) == - (USBSTS_HCPE | USBSTS_HCH)) { - /* Stop due to bug in driver, or hardware */ - out16r(usb_base_addr + USBSTS, status); - out16r(usb_base_addr + USBCMD, - USBCMD_HCRESET | USBCMD_GRESET); - printf - ("GRUSB: HW detected error(s) in USB Descriptors (STS: 0x%x)\n", - status); - usb_show_td(8); - return; - } else if ((status & 0x20) - && ((in16r(usb_base_addr + USBCMD) & USBCMD_RS) == - 0)) { - if (error < 10) { - out16r(usb_base_addr + USBCMD, - USBCMD_RS | in16r(usb_base_addr + - USBCMD)); - error++; - } - } else - error = 0; - } - usb_check_int_chain(); /* call interrupt handlers for int tds */ - usb_check_skel(); /* call completion handler for common transfer routines */ - out16r(usb_base_addr + USBSTS, status); -} - -/* init uhci - */ -int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) -{ - ambapp_ahbdev ahbdev; - - /* Find GRUSB core using AMBA Plug&Play information */ - if (ambapp_ahbslv_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_UHCI, - CONFIG_SYS_GRLIB_GRUSB_INDEX, &ahbdev) != 1) { - printf("USB UHCI: Failed to find GRUSB controller\n"); - return -1; - } - usb_base_addr = ahbdev.address[0]; - grusb_irq = ahbdev.irq; - /* - usb_base_addr = 0xfffa0000; - grusb_irq = 10; - */ -#ifdef USB_UHCI_DEBUG - grusb_show_regs(); -#endif - memset(td_int, 0, sizeof(td_int)); - memset(tmp_td, 0, sizeof(tmp_td)); - memset(tmp_int_td, 0, sizeof(tmp_int_td)); - memset(&qh_cntrl, 0, sizeof(qh_cntrl)); - memset(&qh_end, 0, sizeof(qh_end)); - memset(&td_last, 0, sizeof(td_last)); - - irq_free_handler(grusb_irq); - USB_UHCI_PRINTF("GRUSB: at 0x%lx irq %d\n", usb_base_addr, grusb_irq); - rh.devnum = 0; - usb_init_skel(); - reset_hc(); - start_hc(); - irq_install_handler(grusb_irq, - (interrupt_handler_t *) handle_usb_interrupt, NULL); - return 0; -} - -/* stop uhci - */ -int usb_lowlevel_stop(int index) -{ - if (grusb_irq == -1) - return 1; - irq_free_handler(grusb_irq); - reset_hc(); - grusb_irq = -1; - return 0; -} - -/******************************************************************************************* - * Virtual Root Hub - * Since the uhci does not have a real HUB, we simulate one ;-) - */ -#undef USB_RH_DEBUG - -#ifdef USB_RH_DEBUG -#define USB_RH_PRINTF(fmt,args...) printf (fmt ,##args) -static void usb_display_wValue(unsigned short wValue, unsigned short wIndex); -static void usb_display_Req(unsigned short req); -#else -#define USB_RH_PRINTF(fmt,args...) -static void usb_display_wValue(unsigned short wValue, unsigned short wIndex) -{ -} -static void usb_display_Req(unsigned short req) -{ -} -#endif - -#define WANT_USB_ROOT_HUB_HUB_DES -#include <usbroothubdes.h> -#undef WANT_USB_ROOT_HUB_HUB_DES - -/* - * Root Hub Control Pipe (interrupt Pipes are not supported) - */ - -int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *cmd) -{ - void *data = buffer; - int leni = transfer_len; - int len = 0; - int status = 0; - int stat = 0; - int i; - - unsigned short cstatus; - - unsigned short bmRType_bReq; - unsigned short wValue; - unsigned short wIndex; - unsigned short wLength; - - if (usb_pipeint(pipe)) { - printf("Root-Hub submit IRQ: NOT implemented\n"); - return 0; - } - bmRType_bReq = cmd->requesttype | cmd->request << 8; - wValue = swap_16(cmd->value); - wIndex = swap_16(cmd->index); - wLength = swap_16(cmd->length); - usb_display_Req(bmRType_bReq); - for (i = 0; i < 8; i++) - rh.c_p_r[i] = 0; - USB_RH_PRINTF("Root-Hub: adr: %2x cmd(%1x): %02x%02x %04x %04x %04x\n", - dev->devnum, 8, cmd->requesttype, cmd->request, wValue, - wIndex, wLength); - - switch (bmRType_bReq) { - /* Request Destination: - without flags: Device, - RH_INTERFACE: interface, - RH_ENDPOINT: endpoint, - RH_CLASS means HUB here, - RH_OTHER | RH_CLASS almost ever means HUB_PORT here - */ - - case RH_GET_STATUS: - *(unsigned short *)data = swap_16(1); - len = 2; - break; - case RH_GET_STATUS | RH_INTERFACE: - *(unsigned short *)data = swap_16(0); - len = 2; - break; - case RH_GET_STATUS | RH_ENDPOINT: - *(unsigned short *)data = swap_16(0); - len = 2; - break; - case RH_GET_STATUS | RH_CLASS: - *(unsigned long *)data = swap_32(0); - len = 4; - break; /* hub power ** */ - case RH_GET_STATUS | RH_OTHER | RH_CLASS: - - status = in16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1)); - cstatus = ((status & USBPORTSC_CSC) >> (1 - 0)) | - ((status & USBPORTSC_PEC) >> (3 - 1)) | - (rh.c_p_r[wIndex - 1] << (0 + 4)); - status = (status & USBPORTSC_CCS) | ((status & USBPORTSC_PE) >> (2 - 1)) | ((status & USBPORTSC_SUSP) >> (12 - 2)) | ((status & USBPORTSC_PR) >> (9 - 4)) | (1 << 8) | /* power on ** */ - ((status & USBPORTSC_LSDA) << (-8 + 9)); - - *(unsigned short *)data = swap_16(status); - *(unsigned short *)(data + 2) = swap_16(cstatus); - len = 4; - break; - case RH_CLEAR_FEATURE | RH_ENDPOINT: - switch (wValue) { - case (RH_ENDPOINT_STALL): - len = 0; - break; - } - break; - - case RH_CLEAR_FEATURE | RH_CLASS: - switch (wValue) { - case (RH_C_HUB_OVER_CURRENT): - len = 0; /* hub power over current ** */ - break; - } - break; - - case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: - usb_display_wValue(wValue, wIndex); - switch (wValue) { - case (RH_PORT_ENABLE): - status = - in16r(usb_base_addr + USBPORTSC1 + - 2 * (wIndex - 1)); - status = (status & 0xfff5) & ~USBPORTSC_PE; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - len = 0; - break; - case (RH_PORT_SUSPEND): - status = - in16r(usb_base_addr + USBPORTSC1 + - 2 * (wIndex - 1)); - status = (status & 0xfff5) & ~USBPORTSC_SUSP; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - len = 0; - break; - case (RH_PORT_POWER): - len = 0; /* port power ** */ - break; - case (RH_C_PORT_CONNECTION): - status = - in16r(usb_base_addr + USBPORTSC1 + - 2 * (wIndex - 1)); - status = (status & 0xfff5) | USBPORTSC_CSC; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - len = 0; - break; - case (RH_C_PORT_ENABLE): - status = - in16r(usb_base_addr + USBPORTSC1 + - 2 * (wIndex - 1)); - status = (status & 0xfff5) | USBPORTSC_PEC; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - len = 0; - break; - case (RH_C_PORT_SUSPEND): -/*** WR_RH_PORTSTAT(RH_PS_PSSC); */ - len = 0; - break; - case (RH_C_PORT_OVER_CURRENT): - len = 0; - break; - case (RH_C_PORT_RESET): - rh.c_p_r[wIndex - 1] = 0; - len = 0; - break; - } - break; - case RH_SET_FEATURE | RH_OTHER | RH_CLASS: - usb_display_wValue(wValue, wIndex); - switch (wValue) { - case (RH_PORT_SUSPEND): - status = - in16r(usb_base_addr + USBPORTSC1 + - 2 * (wIndex - 1)); - status = (status & 0xfff5) | USBPORTSC_SUSP; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - len = 0; - break; - case (RH_PORT_RESET): - status = - in16r(usb_base_addr + USBPORTSC1 + - 2 * (wIndex - 1)); - status = (status & 0xfff5) | USBPORTSC_PR; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - mdelay(10); - status = (status & 0xfff5) & ~USBPORTSC_PR; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - udelay(10); - status = (status & 0xfff5) | USBPORTSC_PE; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - mdelay(10); - status = (status & 0xfff5) | 0xa; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - len = 0; - break; - case (RH_PORT_POWER): - len = 0; /* port power ** */ - break; - case (RH_PORT_ENABLE): - status = - in16r(usb_base_addr + USBPORTSC1 + - 2 * (wIndex - 1)); - status = (status & 0xfff5) | USBPORTSC_PE; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - len = 0; - break; - } - break; - - case RH_SET_ADDRESS: - rh.devnum = wValue; - len = 0; - break; - case RH_GET_DESCRIPTOR: - switch ((wValue & 0xff00) >> 8) { - case (0x01): /* device descriptor */ - i = sizeof(root_hub_config_des); - status = i > wLength ? wLength : i; - len = leni > status ? status : leni; - memcpy(data, root_hub_dev_des, len); - break; - case (0x02): /* configuration descriptor */ - i = sizeof(root_hub_config_des); - status = i > wLength ? wLength : i; - len = leni > status ? status : leni; - memcpy(data, root_hub_config_des, len); - break; - case (0x03): /*string descriptors */ - if (wValue == 0x0300) { - i = sizeof(root_hub_str_index0); - status = i > wLength ? wLength : i; - len = leni > status ? status : leni; - memcpy(data, root_hub_str_index0, len); - break; - } - if (wValue == 0x0301) { - i = sizeof(root_hub_str_index1); - status = i > wLength ? wLength : i; - len = leni > status ? status : leni; - memcpy(data, root_hub_str_index1, len); - break; - } - stat = USB_ST_STALLED; - } - break; - - case RH_GET_DESCRIPTOR | RH_CLASS: - root_hub_hub_des[2] = 2; - i = sizeof(root_hub_hub_des); - status = i > wLength ? wLength : i; - len = leni > status ? status : leni; - memcpy(data, root_hub_hub_des, len); - break; - case RH_GET_CONFIGURATION: - *(unsigned char *)data = 0x01; - len = 1; - break; - case RH_SET_CONFIGURATION: - len = 0; - break; - default: - stat = USB_ST_STALLED; - } - USB_RH_PRINTF("Root-Hub stat %lx port1: %x port2: %x\n\n", stat, - in16r(usb_base_addr + USBPORTSC1), - in16r(usb_base_addr + USBPORTSC2)); - dev->act_len = len; - dev->status = stat; - return stat; - -} - -/******************************************************************************** - * Some Debug Routines - */ - -#ifdef USB_RH_DEBUG - -static void usb_display_Req(unsigned short req) -{ - USB_RH_PRINTF("- Root-Hub Request: "); - switch (req) { - case RH_GET_STATUS: - USB_RH_PRINTF("Get Status "); - break; - case RH_GET_STATUS | RH_INTERFACE: - USB_RH_PRINTF("Get Status Interface "); - break; - case RH_GET_STATUS | RH_ENDPOINT: - USB_RH_PRINTF("Get Status Endpoint "); - break; - case RH_GET_STATUS | RH_CLASS: - USB_RH_PRINTF("Get Status Class"); - break; /* hub power ** */ - case RH_GET_STATUS | RH_OTHER | RH_CLASS: - USB_RH_PRINTF("Get Status Class Others"); - break; - case RH_CLEAR_FEATURE | RH_ENDPOINT: - USB_RH_PRINTF("Clear Feature Endpoint "); - break; - case RH_CLEAR_FEATURE | RH_CLASS: - USB_RH_PRINTF("Clear Feature Class "); - break; - case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: - USB_RH_PRINTF("Clear Feature Other Class "); - break; - case RH_SET_FEATURE | RH_OTHER | RH_CLASS: - USB_RH_PRINTF("Set Feature Other Class "); - break; - case RH_SET_ADDRESS: - USB_RH_PRINTF("Set Address "); - break; - case RH_GET_DESCRIPTOR: - USB_RH_PRINTF("Get Descriptor "); - break; - case RH_GET_DESCRIPTOR | RH_CLASS: - USB_RH_PRINTF("Get Descriptor Class "); - break; - case RH_GET_CONFIGURATION: - USB_RH_PRINTF("Get Configuration "); - break; - case RH_SET_CONFIGURATION: - USB_RH_PRINTF("Get Configuration "); - break; - default: - USB_RH_PRINTF("****UNKNOWN**** 0x%04X ", req); - } - USB_RH_PRINTF("\n"); - -} - -static void usb_display_wValue(unsigned short wValue, unsigned short wIndex) -{ - switch (wValue) { - case (RH_PORT_ENABLE): - USB_RH_PRINTF("Root-Hub: Enable Port %d\n", wIndex); - break; - case (RH_PORT_SUSPEND): - USB_RH_PRINTF("Root-Hub: Suspend Port %d\n", wIndex); - break; - case (RH_PORT_POWER): - USB_RH_PRINTF("Root-Hub: Port Power %d\n", wIndex); - break; - case (RH_C_PORT_CONNECTION): - USB_RH_PRINTF("Root-Hub: C Port Connection Port %d\n", wIndex); - break; - case (RH_C_PORT_ENABLE): - USB_RH_PRINTF("Root-Hub: C Port Enable Port %d\n", wIndex); - break; - case (RH_C_PORT_SUSPEND): - USB_RH_PRINTF("Root-Hub: C Port Suspend Port %d\n", wIndex); - break; - case (RH_C_PORT_OVER_CURRENT): - USB_RH_PRINTF("Root-Hub: C Port Over Current Port %d\n", - wIndex); - break; - case (RH_C_PORT_RESET): - USB_RH_PRINTF("Root-Hub: C Port reset Port %d\n", wIndex); - break; - default: - USB_RH_PRINTF("Root-Hub: unknown %x %x\n", wValue, wIndex); - break; - } -} - -#endif - -/*#ifdef USB_UHCI_DEBUG*/ - -static int usb_display_td(uhci_td_t * td) -{ - unsigned long tmp; - int valid; - - printf("TD at %p:\n", td); - - tmp = swap_32(READ32(&td->link)); - printf("Link points to 0x%08lX, %s first, %s, %s\n", tmp & 0xfffffff0, - ((tmp & 0x4) == 0x4) ? "Depth" : "Breath", - ((tmp & 0x2) == 0x2) ? "QH" : "TD", - ((tmp & 0x1) == 0x1) ? "invalid" : "valid"); - valid = ((tmp & 0x1) == 0x0); - tmp = swap_32(READ32(&td->status)); - printf - (" %s %ld Errors %s %s %s \n %s %s %s %s %s %s\n Len 0x%lX\n", - (((tmp >> 29) & 0x1) == 0x1) ? "SPD Enable" : "SPD Disable", - ((tmp >> 28) & 0x3), - (((tmp >> 26) & 0x1) == 0x1) ? "Low Speed" : "Full Speed", - (((tmp >> 25) & 0x1) == 0x1) ? "ISO " : "", - (((tmp >> 24) & 0x1) == 0x1) ? "IOC " : "", - (((tmp >> 23) & 0x1) == 0x1) ? "Active " : "Inactive ", - (((tmp >> 22) & 0x1) == 0x1) ? "Stalled" : "", - (((tmp >> 21) & 0x1) == 0x1) ? "Data Buffer Error" : "", - (((tmp >> 20) & 0x1) == 0x1) ? "Babble" : "", - (((tmp >> 19) & 0x1) == 0x1) ? "NAK" : "", - (((tmp >> 18) & 0x1) == 0x1) ? "Bitstuff Error" : "", - (tmp & 0x7ff)); - tmp = swap_32(READ32(&td->info)); - printf(" MaxLen 0x%lX\n", ((tmp >> 21) & 0x7FF)); - printf(" %sEndpoint 0x%lX Dev Addr 0x%lX PID 0x%lX\n", - ((tmp >> 19) & 0x1) == 0x1 ? "TOGGLE " : "", ((tmp >> 15) & 0xF), - ((tmp >> 8) & 0x7F), tmp & 0xFF); - tmp = swap_32(READ32(&td->buffer)); - printf(" Buffer 0x%08lX\n", tmp); - printf(" DEV %08lX\n", td->dev_ptr); - return valid; -} - -void usb_show_td(int max) -{ - int i; - if (max > 0) { - for (i = 0; i < max; i++) { - usb_display_td(&tmp_td[i]); - } - } else { - i = 0; - do { - printf("tmp_td[%d]\n", i); - } while (usb_display_td(&tmp_td[i++])); - } -} - -void grusb_show_regs(void) -{ - unsigned int tmp; - - tmp = in16r(usb_base_addr + USBCMD); - printf(" USBCMD: 0x%04x\n", tmp); - tmp = in16r(usb_base_addr + USBSTS); - printf(" USBSTS: 0x%04x\n", tmp); - tmp = in16r(usb_base_addr + USBINTR); - printf(" USBINTR: 0x%04x\n", tmp); - tmp = in16r(usb_base_addr + USBFRNUM); - printf(" FRNUM: 0x%04x\n", tmp); - tmp = in32r(usb_base_addr + USBFLBASEADD); - printf(" FLBASEADD: 0x%08x\n", tmp); - tmp = in16r(usb_base_addr + USBSOF); - printf(" SOFMOD: 0x%04x\n", tmp); - tmp = in16r(usb_base_addr + USBPORTSC1); - printf(" PORTSC1: 0x%04x\n", tmp); -} - -/*#endif*/ -#endif /* CONFIG_USB_UHCI */ - -/* EOF */ diff --git a/arch/sparc/cpu/leon3/usb_uhci.h b/arch/sparc/cpu/leon3/usb_uhci.h deleted file mode 100644 index 034814a482..0000000000 --- a/arch/sparc/cpu/leon3/usb_uhci.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * (C) Copyright 2001 - * Denis Peter, MPL AG Switzerland - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Note: Part of this code has been derived from linux - */ -#ifndef _USB_UHCI_H_ -#define _USB_UHCI_H_ - -/* Command register */ -#define USBCMD 0 -#define USBCMD_RS 0x0001 /* Run/Stop */ -#define USBCMD_HCRESET 0x0002 /* Host reset */ -#define USBCMD_GRESET 0x0004 /* Global reset */ -#define USBCMD_EGSM 0x0008 /* Global Suspend Mode */ -#define USBCMD_FGR 0x0010 /* Force Global Resume */ -#define USBCMD_SWDBG 0x0020 /* SW Debug mode */ -#define USBCMD_CF 0x0040 /* Config Flag (sw only) */ -#define USBCMD_MAXP 0x0080 /* Max Packet (0 = 32, 1 = 64) */ - -/* Status register */ -#define USBSTS 2 -#define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */ -#define USBSTS_ERROR 0x0002 /* Interrupt due to error */ -#define USBSTS_RD 0x0004 /* Resume Detect */ -#define USBSTS_HSE 0x0008 /* Host System Error - basically PCI problems */ -#define USBSTS_HCPE 0x0010 /* Host Controller Process Error - the scripts were buggy */ -#define USBSTS_HCH 0x0020 /* HC Halted */ - -/* Interrupt enable register */ -#define USBINTR 4 -#define USBINTR_TIMEOUT 0x0001 /* Timeout/CRC error enable */ -#define USBINTR_RESUME 0x0002 /* Resume interrupt enable */ -#define USBINTR_IOC 0x0004 /* Interrupt On Complete enable */ -#define USBINTR_SP 0x0008 /* Short packet interrupt enable */ - -#define USBFRNUM 6 -#define USBFLBASEADD 8 -#define USBSOF 12 - -/* USB port status and control registers */ -#define USBPORTSC1 16 -#define USBPORTSC2 18 -#define USBPORTSC_CCS 0x0001 /* Current Connect Status ("device present") */ -#define USBPORTSC_CSC 0x0002 /* Connect Status Change */ -#define USBPORTSC_PE 0x0004 /* Port Enable */ -#define USBPORTSC_PEC 0x0008 /* Port Enable Change */ -#define USBPORTSC_LS 0x0030 /* Line Status */ -#define USBPORTSC_RD 0x0040 /* Resume Detect */ -#define USBPORTSC_LSDA 0x0100 /* Low Speed Device Attached */ -#define USBPORTSC_PR 0x0200 /* Port Reset */ -#define USBPORTSC_SUSP 0x1000 /* Suspend */ - -/* Legacy support register */ -#define USBLEGSUP 0xc0 -#define USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */ - -#define UHCI_NULL_DATA_SIZE 0x7ff /* for UHCI controller TD */ -#define UHCI_PID 0xff /* PID MASK */ - -#define UHCI_PTR_BITS 0x000F -#define UHCI_PTR_TERM 0x0001 -#define UHCI_PTR_QH 0x0002 -#define UHCI_PTR_DEPTH 0x0004 - -/* for TD <status>: */ -#define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */ -#define TD_CTRL_C_ERR_MASK (3 << 27) /* Error Counter bits */ -#define TD_CTRL_LS (1 << 26) /* Low Speed Device */ -#define TD_CTRL_IOS (1 << 25) /* Isochronous Select */ -#define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */ -#define TD_CTRL_ACTIVE (1 << 23) /* TD Active */ -#define TD_CTRL_STALLED (1 << 22) /* TD Stalled */ -#define TD_CTRL_DBUFERR (1 << 21) /* Data Buffer Error */ -#define TD_CTRL_BABBLE (1 << 20) /* Babble Detected */ -#define TD_CTRL_NAK (1 << 19) /* NAK Received */ -#define TD_CTRL_CRCTIMEO (1 << 18) /* CRC/Time Out Error */ -#define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */ -#define TD_CTRL_ACTLEN_MASK 0x7ff /* actual length, encoded as n - 1 */ - -#define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \ - TD_CTRL_BABBLE | TD_CTRL_CRCTIME | TD_CTRL_BITSTUFF) - -#define TD_TOKEN_TOGGLE 19 - -/* ------------------------------------------------------------------------------------ - Virtual Root HUB - ------------------------------------------------------------------------------------ */ -/* destination of request */ -#define RH_INTERFACE 0x01 -#define RH_ENDPOINT 0x02 -#define RH_OTHER 0x03 - -#define RH_CLASS 0x20 -#define RH_VENDOR 0x40 - -/* Requests: bRequest << 8 | bmRequestType */ -#define RH_GET_STATUS 0x0080 -#define RH_CLEAR_FEATURE 0x0100 -#define RH_SET_FEATURE 0x0300 -#define RH_SET_ADDRESS 0x0500 -#define RH_GET_DESCRIPTOR 0x0680 -#define RH_SET_DESCRIPTOR 0x0700 -#define RH_GET_CONFIGURATION 0x0880 -#define RH_SET_CONFIGURATION 0x0900 -#define RH_GET_STATE 0x0280 -#define RH_GET_INTERFACE 0x0A80 -#define RH_SET_INTERFACE 0x0B00 -#define RH_SYNC_FRAME 0x0C80 -/* Our Vendor Specific Request */ -#define RH_SET_EP 0x2000 - -/* Hub port features */ -#define RH_PORT_CONNECTION 0x00 -#define RH_PORT_ENABLE 0x01 -#define RH_PORT_SUSPEND 0x02 -#define RH_PORT_OVER_CURRENT 0x03 -#define RH_PORT_RESET 0x04 -#define RH_PORT_POWER 0x08 -#define RH_PORT_LOW_SPEED 0x09 -#define RH_C_PORT_CONNECTION 0x10 -#define RH_C_PORT_ENABLE 0x11 -#define RH_C_PORT_SUSPEND 0x12 -#define RH_C_PORT_OVER_CURRENT 0x13 -#define RH_C_PORT_RESET 0x14 - -/* Hub features */ -#define RH_C_HUB_LOCAL_POWER 0x00 -#define RH_C_HUB_OVER_CURRENT 0x01 - -#define RH_DEVICE_REMOTE_WAKEUP 0x00 -#define RH_ENDPOINT_STALL 0x01 - -/* Our Vendor Specific feature */ -#define RH_REMOVE_EP 0x00 - -#define RH_ACK 0x01 -#define RH_REQ_ERR -1 -#define RH_NACK 0x00 - -/* Transfer descriptor structure */ -typedef struct { - unsigned long link; /* next td/qh (LE) */ - unsigned long status; /* status of the td */ - unsigned long info; /* Max Lenght / Endpoint / device address and PID */ - unsigned long buffer; /* pointer to data buffer (LE) */ - unsigned long dev_ptr; /* pointer to the assigned device (BE) */ - unsigned long res[3]; /* reserved (TDs must be 8Byte aligned) */ -} uhci_td_t, *puhci_td_t; - -/* Queue Header structure */ -typedef struct { - unsigned long head; /* Next QH (LE) */ - unsigned long element; /* Queue element pointer (LE) */ - unsigned long res[5]; /* reserved */ - unsigned long dev_ptr; /* if 0 no tds have been assigned to this qh */ -} uhci_qh_t, *puhci_qh_t; - -struct virt_root_hub { - int devnum; /* Address of Root Hub endpoint */ - int numports; /* number of ports */ - int c_p_r[8]; /* C_PORT_RESET */ -}; - -#endif /* _USB_UHCI_H_ */ |