diff options
author | Peter Tyser <ptyser@xes-inc.com> | 2010-04-12 22:28:09 -0500 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2010-04-13 09:13:16 +0200 |
commit | 8d1f268204b07e172f3cb5cee0a3974d605b0b98 (patch) | |
tree | c3359e920cc886e7060fb099bf933496aca37153 /cpu/mpc5xxx | |
parent | 819833af39a91fa1c1e8252862bbda6f5a602f7b (diff) | |
download | u-boot-imx-8d1f268204b07e172f3cb5cee0a3974d605b0b98.zip u-boot-imx-8d1f268204b07e172f3cb5cee0a3974d605b0b98.tar.gz u-boot-imx-8d1f268204b07e172f3cb5cee0a3974d605b0b98.tar.bz2 |
ppc: Move cpu/$CPU to arch/ppc/cpu/$CPU
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
Diffstat (limited to 'cpu/mpc5xxx')
-rw-r--r-- | cpu/mpc5xxx/Makefile | 49 | ||||
-rw-r--r-- | cpu/mpc5xxx/config.mk | 30 | ||||
-rw-r--r-- | cpu/mpc5xxx/cpu.c | 205 | ||||
-rw-r--r-- | cpu/mpc5xxx/cpu_init.c | 233 | ||||
-rw-r--r-- | cpu/mpc5xxx/firmware_sc_task_bestcomm.impl.S | 359 | ||||
-rw-r--r-- | cpu/mpc5xxx/i2c.c | 442 | ||||
-rw-r--r-- | cpu/mpc5xxx/ide.c | 99 | ||||
-rw-r--r-- | cpu/mpc5xxx/interrupts.c | 346 | ||||
-rw-r--r-- | cpu/mpc5xxx/io.S | 128 | ||||
-rw-r--r-- | cpu/mpc5xxx/loadtask.c | 76 | ||||
-rw-r--r-- | cpu/mpc5xxx/pci_mpc5200.c | 187 | ||||
-rw-r--r-- | cpu/mpc5xxx/serial.c | 363 | ||||
-rw-r--r-- | cpu/mpc5xxx/speed.c | 94 | ||||
-rw-r--r-- | cpu/mpc5xxx/start.S | 777 | ||||
-rw-r--r-- | cpu/mpc5xxx/traps.c | 245 | ||||
-rw-r--r-- | cpu/mpc5xxx/u-boot-customlayout.lds | 133 | ||||
-rw-r--r-- | cpu/mpc5xxx/u-boot.lds | 122 | ||||
-rw-r--r-- | cpu/mpc5xxx/usb.c | 58 | ||||
-rw-r--r-- | cpu/mpc5xxx/usb_ohci.c | 1646 | ||||
-rw-r--r-- | cpu/mpc5xxx/usb_ohci.h | 418 |
20 files changed, 0 insertions, 6010 deletions
diff --git a/cpu/mpc5xxx/Makefile b/cpu/mpc5xxx/Makefile deleted file mode 100644 index 0ee0611..0000000 --- a/cpu/mpc5xxx/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -# -# (C) Copyright 2003-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START = start.o -SOBJS = io.o firmware_sc_task_bestcomm.impl.o -COBJS = i2c.o traps.o cpu.o cpu_init.o ide.o interrupts.o \ - loadtask.o pci_mpc5200.o serial.o speed.o usb_ohci.o usb.o - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/mpc5xxx/config.mk b/cpu/mpc5xxx/config.mk deleted file mode 100644 index 5e82f67..0000000 --- a/cpu/mpc5xxx/config.mk +++ /dev/null @@ -1,30 +0,0 @@ -# -# (C) Copyright 2003 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -PLATFORM_RELFLAGS += -fPIC -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_MPC5xxx -ffixed-r2 \ - -mstring -mcpu=603e -mmultiple - -# Use default linker script. Board port can override in board/*/config.mk -LDSCRIPT := $(SRCTREE)/cpu/mpc5xxx/u-boot.lds diff --git a/cpu/mpc5xxx/cpu.c b/cpu/mpc5xxx/cpu.c deleted file mode 100644 index b20234d..0000000 --- a/cpu/mpc5xxx/cpu.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * (C) Copyright 2000-2010 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * CPU specific code for the MPC5xxx CPUs - */ - -#include <common.h> -#include <watchdog.h> -#include <command.h> -#include <net.h> -#include <mpc5xxx.h> -#include <netdev.h> -#include <asm/io.h> -#include <asm/processor.h> - -#if defined(CONFIG_OF_LIBFDT) -#include <libfdt.h> -#include <libfdt_env.h> -#include <fdt_support.h> -#endif - -#if defined(CONFIG_OF_IDE_FIXUP) -#include <ide.h> -#endif - -DECLARE_GLOBAL_DATA_PTR; - -int checkcpu (void) -{ - ulong clock = gd->cpu_clk; - char buf[32]; - uint svr, pvr; - - puts ("CPU: "); - - svr = get_svr(); - pvr = get_pvr(); - - switch (pvr) { - case PVR_5200: - printf("MPC5200"); - break; - case PVR_5200B: - printf("MPC5200B"); - break; - default: - printf("Unknown MPC5xxx"); - break; - } - - printf (" v%d.%d, Core v%d.%d", SVR_MJREV (svr), SVR_MNREV (svr), - PVR_MAJ(pvr), PVR_MIN(pvr)); - printf (" at %s MHz\n", strmhz (buf, clock)); - return 0; -} - -/* ------------------------------------------------------------------------- */ - -int -do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - ulong msr; - /* Interrupts and MMU off */ - __asm__ __volatile__ ("mfmsr %0":"=r" (msr):); - - msr &= ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR); - __asm__ __volatile__ ("mtmsr %0"::"r" (msr)); - - /* Charge the watchdog timer */ - *(vu_long *)(MPC5XXX_GPT0_COUNTER) = 0x0001000f; - *(vu_long *)(MPC5XXX_GPT0_ENABLE) = 0x9004; /* wden|ce|timer_ms */ - while(1); - - return 1; - -} - -/* ------------------------------------------------------------------------- */ - -/* - * Get timebase clock frequency (like cpu_clk in Hz) - * - */ -unsigned long get_tbclk (void) -{ - ulong tbclk; - - tbclk = (gd->bus_clk + 3L) / 4L; - - return (tbclk); -} - -/* ------------------------------------------------------------------------- */ - -#if defined(CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP) -void ft_cpu_setup(void *blob, bd_t *bd) -{ - int div = in_8((void*)CONFIG_SYS_MBAR + 0x204) & 0x0020 ? 8 : 4; - char * cpu_path = "/cpus/" OF_CPU; -#ifdef CONFIG_MPC5xxx_FEC - uchar enetaddr[6]; - char * eth_path = "/" OF_SOC "/ethernet@3000"; -#endif - - do_fixup_by_path_u32(blob, cpu_path, "timebase-frequency", OF_TBCLK, 1); - do_fixup_by_path_u32(blob, cpu_path, "bus-frequency", bd->bi_busfreq, 1); - do_fixup_by_path_u32(blob, cpu_path, "clock-frequency", bd->bi_intfreq, 1); - do_fixup_by_path_u32(blob, "/" OF_SOC, "bus-frequency", bd->bi_ipbfreq, 1); - do_fixup_by_path_u32(blob, "/" OF_SOC, "system-frequency", - bd->bi_busfreq*div, 1); -#ifdef CONFIG_MPC5xxx_FEC - eth_getenv_enetaddr("ethaddr", enetaddr); - do_fixup_by_path(blob, eth_path, "mac-address", enetaddr, 6, 0); - do_fixup_by_path(blob, eth_path, "local-mac-address", enetaddr, 6, 0); -#endif -#if defined(CONFIG_OF_IDE_FIXUP) - if (!ide_device_present(0)) { - /* NO CF card detected -> delete ata node in DTS */ - int nodeoffset = 0; - char nodename[] = "/soc5200@f0000000/ata@3a00"; - - nodeoffset = fdt_path_offset(blob, nodename); - if (nodeoffset >= 0) { - fdt_del_node(blob, nodeoffset); - } else { - printf("%s: cannot find %s node err:%s\n", - __func__, nodename, fdt_strerror(nodeoffset)); - } - } - -#endif - fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); -} -#endif - -#ifdef CONFIG_BOOTCOUNT_LIMIT - -void bootcount_store (ulong a) -{ - volatile ulong *save_addr = (volatile ulong *) (MPC5XXX_CDM_BRDCRMB); - - *save_addr = (BOOTCOUNT_MAGIC & 0xffff0000) | a; -} - -ulong bootcount_load (void) -{ - volatile ulong *save_addr = (volatile ulong *) (MPC5XXX_CDM_BRDCRMB); - - if ((*save_addr & 0xffff0000) != (BOOTCOUNT_MAGIC & 0xffff0000)) - return 0; - else - return (*save_addr & 0x0000ffff); -} -#endif /* CONFIG_BOOTCOUNT_LIMIT */ - -#ifdef CONFIG_MPC5xxx_FEC -/* Default initializations for FEC controllers. To override, - * create a board-specific function called: - * int board_eth_init(bd_t *bis) - */ - -int cpu_eth_init(bd_t *bis) -{ - return mpc5xxx_fec_initialize(bis); -} -#endif - -#if defined(CONFIG_WATCHDOG) -void watchdog_reset(void) -{ - int re_enable = disable_interrupts(); - reset_5xxx_watchdog(); - if (re_enable) enable_interrupts(); -} - -void reset_5xxx_watchdog(void) -{ - volatile struct mpc5xxx_gpt *gpt0 = - (struct mpc5xxx_gpt *) MPC5XXX_GPT; - - /* Trigger TIMER_0 by writing A5 to OCPW */ - clrsetbits_be32(&gpt0->emsr, 0xff000000, 0xa5000000); -} -#endif /* CONFIG_WATCHDOG */ diff --git a/cpu/mpc5xxx/cpu_init.c b/cpu/mpc5xxx/cpu_init.c deleted file mode 100644 index 9daf375..0000000 --- a/cpu/mpc5xxx/cpu_init.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * (C) Copyright 2000-2010 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <mpc5xxx.h> -#include <asm/io.h> -#include <watchdog.h> - -DECLARE_GLOBAL_DATA_PTR; - -/* - * Breath some life into the CPU... - * - * Set up the memory map, - * initialize a bunch of registers. - */ -void cpu_init_f (void) -{ - volatile struct mpc5xxx_mmap_ctl *mm = - (struct mpc5xxx_mmap_ctl *) CONFIG_SYS_MBAR; - volatile struct mpc5xxx_lpb *lpb = - (struct mpc5xxx_lpb *) MPC5XXX_LPB; - volatile struct mpc5xxx_gpio *gpio = - (struct mpc5xxx_gpio *) MPC5XXX_GPIO; - volatile struct mpc5xxx_xlb *xlb = - (struct mpc5xxx_xlb *) MPC5XXX_XLBARB; -#if defined(CONFIG_SYS_IPBCLK_EQUALS_XLBCLK) - volatile struct mpc5xxx_cdm *cdm = - (struct mpc5xxx_cdm *) MPC5XXX_CDM; -#endif /* CONFIG_SYS_IPBCLK_EQUALS_XLBCLK */ -#if defined(CONFIG_WATCHDOG) - volatile struct mpc5xxx_gpt *gpt0 = - (struct mpc5xxx_gpt *) MPC5XXX_GPT; -#endif /* CONFIG_WATCHDOG */ - unsigned long addecr = (1 << 25); /* Boot_CS */ - /* Pointer is writable since we allocated a register for it */ - gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); - - /* Clear initial global data */ - memset ((void *) gd, 0, sizeof (gd_t)); - - /* - * Memory Controller: configure chip selects and enable them - */ -#if defined(CONFIG_SYS_BOOTCS_START) && defined(CONFIG_SYS_BOOTCS_SIZE) - out_be32(&mm->boot_start, START_REG(CONFIG_SYS_BOOTCS_START)); - out_be32(&mm->boot_stop, STOP_REG(CONFIG_SYS_BOOTCS_START, - CONFIG_SYS_BOOTCS_SIZE)); -#endif -#if defined(CONFIG_SYS_BOOTCS_CFG) - out_be32(&lpb->cs0_cfg, CONFIG_SYS_BOOTCS_CFG); -#endif - -#if defined(CONFIG_SYS_CS0_START) && defined(CONFIG_SYS_CS0_SIZE) - out_be32(&mm->cs0_start, START_REG(CONFIG_SYS_CS0_START)); - out_be32(&mm->cs0_stop, STOP_REG(CONFIG_SYS_CS0_START, - CONFIG_SYS_CS0_SIZE)); - /* CS0 and BOOT_CS cannot be enabled at once. */ - /* addecr |= (1 << 16); */ -#endif -#if defined(CONFIG_SYS_CS0_CFG) - out_be32(&lpb->cs0_cfg, CONFIG_SYS_CS0_CFG); -#endif - -#if defined(CONFIG_SYS_CS1_START) && defined(CONFIG_SYS_CS1_SIZE) - out_be32(&mm->cs1_start, START_REG(CONFIG_SYS_CS1_START)); - out_be32(&mm->cs1_stop, STOP_REG(CONFIG_SYS_CS1_START, - CONFIG_SYS_CS1_SIZE)); - addecr |= (1 << 17); -#endif -#if defined(CONFIG_SYS_CS1_CFG) - out_be32(&lpb->cs1_cfg, CONFIG_SYS_CS1_CFG); -#endif - -#if defined(CONFIG_SYS_CS2_START) && defined(CONFIG_SYS_CS2_SIZE) - out_be32(&mm->cs2_start, START_REG(CONFIG_SYS_CS2_START)); - out_be32(&mm->cs2_stop, STOP_REG(CONFIG_SYS_CS2_START, - CONFIG_SYS_CS2_SIZE)); - addecr |= (1 << 18); -#endif -#if defined(CONFIG_SYS_CS2_CFG) - out_be32(&lpb->cs2_cfg, CONFIG_SYS_CS2_CFG); -#endif - -#if defined(CONFIG_SYS_CS3_START) && defined(CONFIG_SYS_CS3_SIZE) - out_be32(&mm->cs3_start, START_REG(CONFIG_SYS_CS3_START)); - out_be32(&mm->cs3_stop, STOP_REG(CONFIG_SYS_CS3_START, - CONFIG_SYS_CS3_SIZE)); - addecr |= (1 << 19); -#endif -#if defined(CONFIG_SYS_CS3_CFG) - out_be32(&lpb->cs3_cfg, CONFIG_SYS_CS3_CFG); -#endif - -#if defined(CONFIG_SYS_CS4_START) && defined(CONFIG_SYS_CS4_SIZE) - out_be32(&mm->cs4_start, START_REG(CONFIG_SYS_CS4_START)); - out_be32(&mm->cs4_stop, STOP_REG(CONFIG_SYS_CS4_START, - CONFIG_SYS_CS4_SIZE)); - addecr |= (1 << 20); -#endif -#if defined(CONFIG_SYS_CS4_CFG) - out_be32(&lpb->cs4_cfg, CONFIG_SYS_CS4_CFG); -#endif - -#if defined(CONFIG_SYS_CS5_START) && defined(CONFIG_SYS_CS5_SIZE) - out_be32(&mm->cs5_start, START_REG(CONFIG_SYS_CS5_START)); - out_be32(&mm->cs5_stop, STOP_REG(CONFIG_SYS_CS5_START, - CONFIG_SYS_CS5_SIZE)); - addecr |= (1 << 21); -#endif -#if defined(CONFIG_SYS_CS5_CFG) - out_be32(&lpb->cs5_cfg, CONFIG_SYS_CS5_CFG); -#endif - - addecr |= 1; -#if defined(CONFIG_SYS_CS6_START) && defined(CONFIG_SYS_CS6_SIZE) - out_be32(&mm->cs6_start, START_REG(CONFIG_SYS_CS6_START)); - out_be32(&mm->cs6_stop, STOP_REG(CONFIG_SYS_CS6_START, - CONFIG_SYS_CS6_SIZE)); - addecr |= (1 << 26); -#endif -#if defined(CONFIG_SYS_CS6_CFG) - out_be32(&lpb->cs6_cfg, CONFIG_SYS_CS6_CFG); -#endif - -#if defined(CONFIG_SYS_CS7_START) && defined(CONFIG_SYS_CS7_SIZE) - out_be32(&mm->cs7_start, START_REG(CONFIG_SYS_CS7_START)); - out_be32(&mm->cs7_stop, STOP_REG(CONFIG_SYS_CS7_START, - CONFIG_SYS_CS7_SIZE)); - addecr |= (1 << 27); -#endif -#if defined(CONFIG_SYS_CS7_CFG) - out_be32(&lpb->cs7_cfg, CONFIG_SYS_CS7_CFG); -#endif - -#if defined(CONFIG_SYS_CS_BURST) - out_be32(&lpb->cs_burst, CONFIG_SYS_CS_BURST); -#endif -#if defined(CONFIG_SYS_CS_DEADCYCLE) - out_be32(&lpb->cs_deadcycle, CONFIG_SYS_CS_DEADCYCLE); -#endif - - /* Enable chip selects */ - out_be32(&mm->ipbi_ws_ctrl, addecr); - out_be32(&lpb->cs_ctrl, (1 << 24)); - - /* Setup pin multiplexing */ -#if defined(CONFIG_SYS_GPS_PORT_CONFIG) - out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG); -#endif - - /* enable timebase */ - setbits_be32(&xlb->config, (1 << 13)); - - /* Enable snooping for RAM */ - setbits_be32(&xlb->config, (1 << 15)); - out_be32(&xlb->snoop_window, CONFIG_SYS_SDRAM_BASE | 0x1d); - -#if defined(CONFIG_SYS_IPBCLK_EQUALS_XLBCLK) - /* Motorola reports IPB should better run at 133 MHz. */ - setbits_be32(&mm->ipbi_ws_ctrl, 1); - /* pci_clk_sel = 0x02, ipb_clk_sel = 0x00; */ - addecr = in_be32(&cdm->cfg); - addecr &= ~0x103; -# if defined(CONFIG_SYS_PCICLK_EQUALS_IPBCLK_DIV2) - /* pci_clk_sel = 0x01 -> IPB_CLK/2 */ - addecr |= 0x01; -# else - /* pci_clk_sel = 0x02 -> XLB_CLK/4 = IPB_CLK/4 */ - addecr |= 0x02; -# endif /* CONFIG_SYS_PCICLK_EQUALS_IPBCLK_DIV2 */ - out_be32(&cdm->cfg, addecr); -#endif /* CONFIG_SYS_IPBCLK_EQUALS_XLBCLK */ - /* Configure the XLB Arbiter */ - out_be32(&xlb->master_pri_enable, 0xff); - out_be32(&xlb->master_priority, 0x11111111); - -#if defined(CONFIG_SYS_XLB_PIPELINING) - /* Enable piplining */ - clrbits_be32(&xlb->config, (1 << 31)); -#endif - -#if defined(CONFIG_WATCHDOG) - /* Charge the watchdog timer - prescaler = 64k, count = 64k*/ - out_be32(&gpt0->cir, 0x0000ffff); - out_be32(&gpt0->emsr, 0x9004); /* wden|ce|timer_ms */ - - reset_5xxx_watchdog(); -#endif /* CONFIG_WATCHDOG */ -} - -/* - * initialize higher level parts of CPU like time base and timers - */ -int cpu_init_r (void) -{ - volatile struct mpc5xxx_intr *intr = - (struct mpc5xxx_intr *) MPC5XXX_ICTL; - - /* mask all interrupts */ - out_be32(&intr->per_mask, 0xffffff00); - setbits_be32(&intr->main_mask, 0x0001ffff); - clrbits_be32(&intr->ctrl, 0x00000f00); - /* route critical ints to normal ints */ - setbits_be32(&intr->ctrl, 0x00000001); - -#if defined(CONFIG_CMD_NET) && defined(CONFIG_MPC5xxx_FEC) - /* load FEC microcode */ - loadtask(0, 2); -#endif - - return (0); -} diff --git a/cpu/mpc5xxx/firmware_sc_task_bestcomm.impl.S b/cpu/mpc5xxx/firmware_sc_task_bestcomm.impl.S deleted file mode 100644 index 00c2312..0000000 --- a/cpu/mpc5xxx/firmware_sc_task_bestcomm.impl.S +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright (C) 2001, Software Center, Motorola China. - * - * This file contains microcode for the FEC controller of the MPC5200 CPU. - */ - -#include <config.h> - -/* sas/sccg, gas target */ -.section smartdmaInitData,"aw",@progbits /* Initialized data for task variables */ -.section smartdmaTaskTable,"aw",@progbits /* Task tables */ -.align 9 -.globl taskTable -taskTable: -.globl scEthernetRecv_Entry -scEthernetRecv_Entry: /* Task 0 */ -.long scEthernetRecv_TDT - taskTable /* Task 0 Descriptor Table */ -.long scEthernetRecv_TDT - taskTable + 0x000000a4 -.long scEthernetRecv_VarTab - taskTable /* Task 0 Variable Table */ -.long scEthernetRecv_FDT - taskTable + 0x03 /* Task 0 Function Descriptor Table & Flags */ -.long 0x00000000 -.long 0x00000000 -.long scEthernetRecv_CSave - taskTable /* Task 0 context save space */ -.long CONFIG_SYS_MBAR -.globl scEthernetXmit_Entry -scEthernetXmit_Entry: /* Task 1 */ -.long scEthernetXmit_TDT - taskTable /* Task 1 Descriptor Table */ -.long scEthernetXmit_TDT - taskTable + 0x000000d0 -.long scEthernetXmit_VarTab - taskTable /* Task 1 Variable Table */ -.long scEthernetXmit_FDT - taskTable + 0x03 /* Task 1 Function Descriptor Table & Flags */ -.long 0x00000000 -.long 0x00000000 -.long scEthernetXmit_CSave - taskTable /* Task 1 context save space */ -.long CONFIG_SYS_MBAR - - -.globl scEthernetRecv_TDT -scEthernetRecv_TDT: /* Task 0 Descriptor Table */ -.long 0xc4c50000 /* 0000: LCDEXT: idx0 = var9 + var10; idx0 once var0; idx0 += inc0 */ -.long 0x84c5e000 /* 0004: LCD: idx1 = var9 + var11; ; idx1 += inc0 */ -.long 0x10001f08 /* 0008: DRD1A: var7 = idx1; FN=0 MORE init=0 WS=0 RS=0 */ -.long 0x10000380 /* 000C: DRD1A: var0 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */ -.long 0x00000f88 /* 0010: DRD1A: var3 = *idx1; FN=0 init=0 WS=0 RS=0 */ -.long 0x81980000 /* 0014: LCD: idx0 = var3; idx0 once var0; idx0 += inc0 */ -.long 0x10000780 /* 0018: DRD1A: var1 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */ -.long 0x60000000 /* 001C: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */ -.long 0x010cf04c /* 0020: DRD2B1: var4 = EU3(); EU3(var1,var12) */ -.long 0x82180349 /* 0024: LCD: idx0 = var4; idx0 != var13; idx0 += inc1 */ -.long 0x81c68004 /* 0028: LCD: idx1 = var3 + var13 + 4; idx1 once var0; idx1 += inc0 */ -.long 0x70000000 /* 002C: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */ -.long 0x018cf04e /* 0030: DRD2B1: var6 = EU3(); EU3(var1,var14) */ -.long 0x70000000 /* 0034: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */ -.long 0x020cf04f /* 0038: DRD2B1: var8 = EU3(); EU3(var1,var15) */ -.long 0x00000b88 /* 003C: DRD1A: var2 = *idx1; FN=0 init=0 WS=0 RS=0 */ -.long 0x8000d184 /* 0040: LCDEXT: idx1 = 0xf0003184; ; */ -.long 0xc6990452 /* 0044: LCDEXT: idx2 = var13; idx2 < var17; idx2 += inc2 */ -.long 0x81486010 /* 0048: LCD: idx3 = var2 + var16; ; idx3 += inc2 */ -.long 0x006acf88 /* 004C: DRD1A: *idx3 = *idx1; FN=0 init=3 WS=1 RS=1 */ -.long 0x8000d184 /* 0050: LCDEXT: idx1 = 0xf0003184; ; */ -.long 0x86810492 /* 0054: LCD: idx2 = var13, idx3 = var2; idx2 < var18; idx2 += inc2, idx3 += inc2 */ -.long 0x006acf88 /* 0058: DRD1A: *idx3 = *idx1; FN=0 init=3 WS=1 RS=1 */ -.long 0x8000d184 /* 005C: LCDEXT: idx1 = 0xf0003184; ; */ -.long 0x868184d2 /* 0060: LCD: idx2 = var13, idx3 = var3; idx2 < var19; idx2 += inc2, idx3 += inc2 */ -.long 0x000acf88 /* 0064: DRD1A: *idx3 = *idx1; FN=0 init=0 WS=1 RS=1 */ -.long 0xc318839b /* 0068: LCDEXT: idx1 = var6; idx1 == var14; idx1 += inc3 */ -.long 0x80190000 /* 006C: LCD: idx2 = var0; idx2 once var0; idx2 += inc0 */ -.long 0x04008468 /* 0070: DRD1A: idx1 = var13; FN=0 INT init=0 WS=0 RS=0 */ -.long 0xc4038358 /* 0074: LCDEXT: idx1 = var8, idx2 = var7; idx1 == var13; idx1 += inc3, idx2 += inc0 */ -.long 0x81c50000 /* 0078: LCD: idx3 = var3 + var10; idx3 once var0; idx3 += inc0 */ -.long 0x1000cb18 /* 007C: DRD1A: *idx2 = idx3; FN=0 MORE init=0 WS=0 RS=0 */ -.long 0x00000f18 /* 0080: DRD1A: var3 = idx3; FN=0 init=0 WS=0 RS=0 */ -.long 0xc4188364 /* 0084: LCDEXT: idx1 = var8; idx1 > var13; idx1 += inc4 */ -.long 0x83990000 /* 0088: LCD: idx2 = var7; idx2 once var0; idx2 += inc0 */ -.long 0x10000c00 /* 008C: DRD1A: var3 = var0; FN=0 MORE init=0 WS=0 RS=0 */ -.long 0x0000c800 /* 0090: DRD1A: *idx2 = var0; FN=0 init=0 WS=0 RS=0 */ -.long 0x81988000 /* 0094: LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */ -.long 0x10000788 /* 0098: DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */ -.long 0x60000000 /* 009C: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */ -.long 0x080cf04c /* 00A0: DRD2B1: idx0 = EU3(); EU3(var1,var12) */ -.long 0x000001f8 /* 00A4(:0): NOP */ - - -.globl scEthernetXmit_TDT -scEthernetXmit_TDT: /* Task 1 Descriptor Table */ -.long 0x80024800 /* 0000: LCDEXT: idx0 = 0xf0008800; ; */ -.long 0x85c60004 /* 0004: LCD: idx1 = var11 + var12 + 4; idx1 once var0; idx1 += inc0 */ -.long 0x10002308 /* 0008: DRD1A: var8 = idx1; FN=0 MORE init=0 WS=0 RS=0 */ -.long 0x10000f88 /* 000C: DRD1A: var3 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */ -.long 0x00000380 /* 0010: DRD1A: var0 = *idx0; FN=0 init=0 WS=0 RS=0 */ -.long 0x81980000 /* 0014: LCD: idx0 = var3; idx0 once var0; idx0 += inc0 */ -.long 0x10000780 /* 0018: DRD1A: var1 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */ -.long 0x60000000 /* 001C: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */ -.long 0x024cf04d /* 0020: DRD2B1: var9 = EU3(); EU3(var1,var13) */ -.long 0x84980309 /* 0024: LCD: idx0 = var9; idx0 != var12; idx0 += inc1 */ -.long 0xc0004003 /* 0028: LCDEXT: idx1 = 0x00000003; ; */ -.long 0x81c60004 /* 002C: LCD: idx2 = var3 + var12 + 4; idx2 once var0; idx2 += inc0 */ -.long 0x70000000 /* 0030: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */ -.long 0x010cf04e /* 0034: DRD2B1: var4 = EU3(); EU3(var1,var14) */ -.long 0x70000000 /* 0038: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */ -.long 0x014cf04f /* 003C: DRD2B1: var5 = EU3(); EU3(var1,var15) */ -.long 0x70000000 /* 0040: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */ -.long 0x028cf050 /* 0044: DRD2B1: var10 = EU3(); EU3(var1,var16) */ -.long 0x70000000 /* 0048: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */ -.long 0x018cf051 /* 004C: DRD2B1: var6 = EU3(); EU3(var1,var17) */ -.long 0x10000b90 /* 0050: DRD1A: var2 = *idx2; FN=0 MORE init=0 WS=0 RS=0 */ -.long 0x60000000 /* 0054: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */ -.long 0x01ccf0a1 /* 0058: DRD2B1: var7 = EU3(); EU3(var2,idx1) */ -.long 0xc2988312 /* 005C: LCDEXT: idx1 = var5; idx1 > var12; idx1 += inc2 */ -.long 0x83490000 /* 0060: LCD: idx2 = var6 + var18; idx2 once var0; idx2 += inc0 */ -.long 0x00001b10 /* 0064: DRD1A: var6 = idx2; FN=0 init=0 WS=0 RS=0 */ -.long 0x8000d1a4 /* 0068: LCDEXT: idx1 = 0xf00031a4; ; */ -.long 0x8301031c /* 006C: LCD: idx2 = var6, idx3 = var2; idx2 > var12; idx2 += inc3, idx3 += inc4 */ -.long 0x008ac798 /* 0070: DRD1A: *idx1 = *idx3; FN=0 init=4 WS=1 RS=1 */ -.long 0x8000d1a4 /* 0074: LCDEXT: idx1 = 0xf00031a4; ; */ -.long 0xc1430000 /* 0078: LCDEXT: idx2 = var2 + var6; idx2 once var0; idx2 += inc0 */ -.long 0x82998312 /* 007C: LCD: idx3 = var5; idx3 > var12; idx3 += inc2 */ -.long 0x088ac790 /* 0080: DRD1A: *idx1 = *idx2; FN=0 TFD init=4 WS=1 RS=1 */ -.long 0x81988000 /* 0084: LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */ -.long 0x60000001 /* 0088: DRD2A: EU0=0 EU1=0 EU2=0 EU3=1 EXT init=0 WS=0 RS=0 */ -.long 0x0c4cfc4d /* 008C: DRD2B1: *idx1 = EU3(); EU3(*idx1,var13) */ -.long 0xc21883ad /* 0090: LCDEXT: idx1 = var4; idx1 == var14; idx1 += inc5 */ -.long 0x80190000 /* 0094: LCD: idx2 = var0; idx2 once var0; idx2 += inc0 */ -.long 0x04008460 /* 0098: DRD1A: idx1 = var12; FN=0 INT init=0 WS=0 RS=0 */ -.long 0xc4052305 /* 009C: LCDEXT: idx1 = var8, idx2 = var10; idx2 == var12; idx1 += inc0, idx2 += inc5 */ -.long 0x81c98000 /* 00A0: LCD: idx3 = var3 + var19; idx3 once var0; idx3 += inc0 */ -.long 0x1000c718 /* 00A4: DRD1A: *idx1 = idx3; FN=0 MORE init=0 WS=0 RS=0 */ -.long 0x00000f18 /* 00A8: DRD1A: var3 = idx3; FN=0 init=0 WS=0 RS=0 */ -.long 0xc4188000 /* 00AC: LCDEXT: idx1 = var8; idx1 once var0; idx1 += inc0 */ -.long 0x85190312 /* 00B0: LCD: idx2 = var10; idx2 > var12; idx2 += inc2 */ -.long 0x10000c00 /* 00B4: DRD1A: var3 = var0; FN=0 MORE init=0 WS=0 RS=0 */ -.long 0x1000c400 /* 00B8: DRD1A: *idx1 = var0; FN=0 MORE init=0 WS=0 RS=0 */ -.long 0x00008860 /* 00BC: DRD1A: idx2 = var12; FN=0 init=0 WS=0 RS=0 */ -.long 0x81988000 /* 00C0: LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */ -.long 0x10000788 /* 00C4: DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */ -.long 0x60000000 /* 00C8: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */ -.long 0x080cf04d /* 00CC: DRD2B1: idx0 = EU3(); EU3(var1,var13) */ -.long 0x000001f8 /* 00D0(:0): NOP */ - -.align 8 - -.globl scEthernetRecv_VarTab -scEthernetRecv_VarTab: /* Task 0 Variable Table */ -.long 0x00000000 /* var[0] */ -.long 0x00000000 /* var[1] */ -.long 0x00000000 /* var[2] */ -.long 0x00000000 /* var[3] */ -.long 0x00000000 /* var[4] */ -.long 0x00000000 /* var[5] */ -.long 0x00000000 /* var[6] */ -.long 0x00000000 /* var[7] */ -.long 0x00000000 /* var[8] */ -.long (CONFIG_SYS_MBAR + 0x8800) /* var[9] */ -.long 0x00000008 /* var[10] */ -.long 0x0000000c /* var[11] */ -.long 0x80000000 /* var[12] */ -.long 0x00000000 /* var[13] */ -.long 0x10000000 /* var[14] */ -.long 0x20000000 /* var[15] */ -.long 0x000005e4 /* var[16] */ -.long 0x0000000e /* var[17] */ -.long 0x000005e0 /* var[18] */ -.long 0x00000004 /* var[19] */ -.long 0x00000000 /* var[20] */ -.long 0x00000000 /* var[21] */ -.long 0x00000000 /* var[22] */ -.long 0x00000000 /* var[23] */ -.long 0x00000000 /* inc[0] */ -.long 0x60000000 /* inc[1] */ -.long 0x20000001 /* inc[2] */ -.long 0x80000000 /* inc[3] */ -.long 0x40000000 /* inc[4] */ -.long 0x00000000 /* inc[5] */ -.long 0x00000000 /* inc[6] */ -.long 0x00000000 /* inc[7] */ - -.align 8 - -.globl scEthernetXmit_VarTab -scEthernetXmit_VarTab: /* Task 1 Variable Table */ -.long 0x00000000 /* var[0] */ -.long 0x00000000 /* var[1] */ -.long 0x00000000 /* var[2] */ -.long 0x00000000 /* var[3] */ -.long 0x00000000 /* var[4] */ -.long 0x00000000 /* var[5] */ -.long 0x00000000 /* var[6] */ -.long 0x00000000 /* var[7] */ -.long 0x00000000 /* var[8] */ -.long 0x00000000 /* var[9] */ -.long 0x00000000 /* var[10] */ -.long (CONFIG_SYS_MBAR + 0x8800) /* var[11] */ -.long 0x00000000 /* var[12] */ -.long 0x80000000 /* var[13] */ -.long 0x10000000 /* var[14] */ -.long 0x08000000 /* var[15] */ -.long 0x20000000 /* var[16] */ -.long 0x0000ffff /* var[17] */ -.long 0xffffffff /* var[18] */ -.long 0x00000008 /* var[19] */ -.long 0x00000000 /* var[20] */ -.long 0x00000000 /* var[21] */ -.long 0x00000000 /* var[22] */ -.long 0x00000000 /* var[23] */ -.long 0x00000000 /* inc[0] */ -.long 0x60000000 /* inc[1] */ -.long 0x40000000 /* inc[2] */ -.long 0x4000ffff /* inc[3] */ -.long 0xe0000001 /* inc[4] */ -.long 0x80000000 /* inc[5] */ -.long 0x00000000 /* inc[6] */ -.long 0x00000000 /* inc[7] */ - -.align 8 - -.globl scEthernetRecv_FDT -scEthernetRecv_FDT: /* Task 0 Function Descriptor Table */ -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x21800000 /* and(), EU# 3 */ -.long 0x21400000 /* andn(), EU# 3 */ -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 - -.align 8 - -.globl scEthernetXmit_FDT -scEthernetXmit_FDT: /* Task 1 Function Descriptor Table */ -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x21800000 /* and(), EU# 3 */ -.long 0x21400000 /* andn(), EU# 3 */ -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 -.long 0x00000000 - - -.globl scEthernetRecv_CSave -scEthernetRecv_CSave: /* Task 0 context save space */ -.space 128, 0x0 - - -.globl scEthernetXmit_CSave -scEthernetXmit_CSave: /* Task 1 context save space */ -.space 128, 0x0 diff --git a/cpu/mpc5xxx/i2c.c b/cpu/mpc5xxx/i2c.c deleted file mode 100644 index 4f7f716..0000000 --- a/cpu/mpc5xxx/i2c.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> - -DECLARE_GLOBAL_DATA_PTR; - -#ifdef CONFIG_HARD_I2C - -#include <mpc5xxx.h> -#include <i2c.h> - -#if (CONFIG_SYS_I2C_MODULE == 2) -#define I2C_BASE MPC5XXX_I2C2 -#elif (CONFIG_SYS_I2C_MODULE == 1) -#define I2C_BASE MPC5XXX_I2C1 -#else -#error CONFIG_SYS_I2C_MODULE is not properly configured -#endif - -#define I2C_TIMEOUT 6667 -#define I2C_RETRIES 3 - -struct mpc5xxx_i2c_tap { - int scl2tap; - int tap2tap; -}; - -static int mpc_reg_in (volatile u32 *reg); -static void mpc_reg_out (volatile u32 *reg, int val, int mask); -static int wait_for_bb (void); -static int wait_for_pin (int *status); -static int do_address (uchar chip, char rdwr_flag); -static int send_bytes (uchar chip, char *buf, int len); -static int receive_bytes (uchar chip, char *buf, int len); -static int mpc_get_fdr (int); - -static int mpc_reg_in(volatile u32 *reg) -{ - int ret = *reg >> 24; - __asm__ __volatile__ ("eieio"); - return ret; -} - -static void mpc_reg_out(volatile u32 *reg, int val, int mask) -{ - int tmp; - - if (!mask) { - *reg = val << 24; - } else { - tmp = mpc_reg_in(reg); - *reg = ((tmp & ~mask) | (val & mask)) << 24; - } - __asm__ __volatile__ ("eieio"); - - return; -} - -static int wait_for_bb(void) -{ - struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE; - int timeout = I2C_TIMEOUT; - int status; - - status = mpc_reg_in(®s->msr); - - while (timeout-- && (status & I2C_BB)) { -#if 1 - volatile int temp; - mpc_reg_out(®s->mcr, I2C_STA, I2C_STA); - temp = mpc_reg_in(®s->mdr); - mpc_reg_out(®s->mcr, 0, I2C_STA); - mpc_reg_out(®s->mcr, 0, 0); - mpc_reg_out(®s->mcr, I2C_EN, 0); -#endif - udelay(15); - status = mpc_reg_in(®s->msr); - } - - return (status & I2C_BB); -} - -static int wait_for_pin(int *status) -{ - struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE; - int timeout = I2C_TIMEOUT; - - *status = mpc_reg_in(®s->msr); - - while (timeout-- && !(*status & I2C_IF)) { - udelay(15); - *status = mpc_reg_in(®s->msr); - } - - if (!(*status & I2C_IF)) { - return -1; - } - - mpc_reg_out(®s->msr, 0, I2C_IF); - - return 0; -} - -static int do_address(uchar chip, char rdwr_flag) -{ - struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE; - int status; - - chip <<= 1; - - if (rdwr_flag) { - chip |= 1; - } - - mpc_reg_out(®s->mcr, I2C_TX, I2C_TX); - mpc_reg_out(®s->mdr, chip, 0); - - if (wait_for_pin(&status)) { - return -2; - } - - if (status & I2C_RXAK) { - return -3; - } - - return 0; -} - -static int send_bytes(uchar chip, char *buf, int len) -{ - struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE; - int wrcount; - int status; - - for (wrcount = 0; wrcount < len; ++wrcount) { - - mpc_reg_out(®s->mdr, buf[wrcount], 0); - - if (wait_for_pin(&status)) { - break; - } - - if (status & I2C_RXAK) { - break; - } - - } - - return !(wrcount == len); -} - -static int receive_bytes(uchar chip, char *buf, int len) -{ - struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE; - int dummy = 1; - int rdcount = 0; - int status; - int i; - - mpc_reg_out(®s->mcr, 0, I2C_TX); - - for (i = 0; i < len; ++i) { - buf[rdcount] = mpc_reg_in(®s->mdr); - - if (dummy) { - dummy = 0; - } else { - rdcount++; - } - - - if (wait_for_pin(&status)) { - return -4; - } - } - - mpc_reg_out(®s->mcr, I2C_TXAK, I2C_TXAK); - buf[rdcount++] = mpc_reg_in(®s->mdr); - - if (wait_for_pin(&status)) { - return -5; - } - - mpc_reg_out(®s->mcr, 0, I2C_TXAK); - - return 0; -} - -#if defined(CONFIG_SYS_I2C_INIT_MPC5XXX) - -#define FDR510(x) (u8) (((x & 0x20) >> 3) | (x & 0x3)) -#define FDR432(x) (u8) ((x & 0x1C) >> 2) -/* - * Reset any i2c devices that may have been interrupted during a system reset. - * Normally this would be accomplished by clocking the line until SCL and SDA - * are released and then sending a start condtiion (From an Atmel datasheet). - * There is no direct access to the i2c pins so instead create start commands - * through the i2c interface. Send a start command then delay for the SDA Hold - * time, repeat this by disabling/enabling the bus a total of 9 times. - */ -static void send_reset(void) -{ - struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE; - int i; - u32 delay; - u8 fdr; - int SDA_Tap[] = { 3, 3, 4, 4, 1, 1, 2, 2}; - struct mpc5xxx_i2c_tap scltap[] = { - {4, 1}, - {4, 2}, - {6, 4}, - {6, 8}, - {14, 16}, - {30, 32}, - {62, 64}, - {126, 128} - }; - - fdr = (u8)mpc_reg_in(®s->mfdr); - - delay = scltap[FDR432(fdr)].scl2tap + ((SDA_Tap[FDR510(fdr)] - 1) * \ - scltap[FDR432(fdr)].tap2tap) + 3; - - for (i = 0; i < 9; i++) { - mpc_reg_out(®s->mcr, I2C_EN|I2C_STA|I2C_TX, I2C_INIT_MASK); - udelay(delay); - mpc_reg_out(®s->mcr, 0, I2C_INIT_MASK); - udelay(delay); - } - - mpc_reg_out(®s->mcr, I2C_EN, I2C_INIT_MASK); -} -#endif /* CONFIG_SYS_I2c_INIT_MPC5XXX */ - -/**************** I2C API ****************/ - -void i2c_init(int speed, int saddr) -{ - struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE; - - mpc_reg_out(®s->mcr, 0, 0); - mpc_reg_out(®s->madr, saddr << 1, 0); - - /* Set clock - */ - mpc_reg_out(®s->mfdr, mpc_get_fdr(speed), 0); - - /* Enable module - */ - mpc_reg_out(®s->mcr, I2C_EN, I2C_INIT_MASK); - mpc_reg_out(®s->msr, 0, I2C_IF); - -#if defined(CONFIG_SYS_I2C_INIT_MPC5XXX) - send_reset(); -#endif - return; -} - -static int mpc_get_fdr(int speed) -{ - static int fdr = -1; - - if (fdr == -1) { - ulong best_speed = 0; - ulong divider; - ulong ipb, scl; - ulong bestmatch = 0xffffffffUL; - int best_i = 0, best_j = 0, i, j; - int SCL_Tap[] = { 9, 10, 12, 15, 5, 6, 7, 8}; - struct mpc5xxx_i2c_tap scltap[] = { - {4, 1}, - {4, 2}, - {6, 4}, - {6, 8}, - {14, 16}, - {30, 32}, - {62, 64}, - {126, 128} - }; - - ipb = gd->ipb_clk; - for (i = 7; i >= 0; i--) { - for (j = 7; j >= 0; j--) { - scl = 2 * (scltap[j].scl2tap + - (SCL_Tap[i] - 1) * scltap[j].tap2tap + 2); - if (ipb <= speed*scl) { - if ((speed*scl - ipb) < bestmatch) { - bestmatch = speed*scl - ipb; - best_i = i; - best_j = j; - best_speed = ipb/scl; - } - } - } - } - divider = (best_i & 3) | ((best_i & 4) << 3) | (best_j << 2); - if (gd->flags & GD_FLG_RELOC) { - fdr = divider; - } else { - if (gd->have_console) - printf("%ld kHz, ", best_speed / 1000); - return divider; - } - } - - return fdr; -} - -int i2c_probe(uchar chip) -{ - struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE; - int i; - - for (i = 0; i < I2C_RETRIES; i++) { - mpc_reg_out(®s->mcr, I2C_STA, I2C_STA); - - if (! do_address(chip, 0)) { - mpc_reg_out(®s->mcr, 0, I2C_STA); - udelay(500); - break; - } - - mpc_reg_out(®s->mcr, 0, I2C_STA); - udelay(500); - } - - return (i == I2C_RETRIES); -} - -int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) -{ - char xaddr[4]; - struct mpc5xxx_i2c * regs = (struct mpc5xxx_i2c *)I2C_BASE; - int ret = -1; - - xaddr[0] = (addr >> 24) & 0xFF; - xaddr[1] = (addr >> 16) & 0xFF; - xaddr[2] = (addr >> 8) & 0xFF; - xaddr[3] = addr & 0xFF; - - if (wait_for_bb()) { - if (gd->have_console) - printf("i2c_read: bus is busy\n"); - goto Done; - } - - mpc_reg_out(®s->mcr, I2C_STA, I2C_STA); - if (do_address(chip, 0)) { - if (gd->have_console) - printf("i2c_read: failed to address chip\n"); - goto Done; - } - - if (send_bytes(chip, &xaddr[4-alen], alen)) { - if (gd->have_console) - printf("i2c_read: send_bytes failed\n"); - goto Done; - } - - mpc_reg_out(®s->mcr, I2C_RSTA, I2C_RSTA); - if (do_address(chip, 1)) { - if (gd->have_console) - printf("i2c_read: failed to address chip\n"); - goto Done; - } - - if (receive_bytes(chip, (char *)buf, len)) { - if (gd->have_console) - printf("i2c_read: receive_bytes failed\n"); - goto Done; - } - - ret = 0; -Done: - mpc_reg_out(®s->mcr, 0, I2C_STA); - return ret; -} - -int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) -{ - char xaddr[4]; - struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE; - int ret = -1; - - xaddr[0] = (addr >> 24) & 0xFF; - xaddr[1] = (addr >> 16) & 0xFF; - xaddr[2] = (addr >> 8) & 0xFF; - xaddr[3] = addr & 0xFF; - - if (wait_for_bb()) { - if (gd->have_console) - printf("i2c_write: bus is busy\n"); - goto Done; - } - - mpc_reg_out(®s->mcr, I2C_STA, I2C_STA); - if (do_address(chip, 0)) { - if (gd->have_console) - printf("i2c_write: failed to address chip\n"); - goto Done; - } - - if (send_bytes(chip, &xaddr[4-alen], alen)) { - if (gd->have_console) - printf("i2c_write: send_bytes failed\n"); - goto Done; - } - - if (send_bytes(chip, (char *)buf, len)) { - if (gd->have_console) - printf("i2c_write: send_bytes failed\n"); - goto Done; - } - - ret = 0; -Done: - mpc_reg_out(®s->mcr, 0, I2C_STA); - return ret; -} - -#endif /* CONFIG_HARD_I2C */ diff --git a/cpu/mpc5xxx/ide.c b/cpu/mpc5xxx/ide.c deleted file mode 100644 index d337abb..0000000 --- a/cpu/mpc5xxx/ide.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * (C) Copyright 2004 - * Pierre AUBERT, Staubli Faverges, <p.aubert@staubli.com> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * Init is derived from Linux code. - */ -#include <common.h> - -#if defined(CONFIG_CMD_IDE) -#include <mpc5xxx.h> - -DECLARE_GLOBAL_DATA_PTR; - -#define CALC_TIMING(t) (t + period - 1) / period - -#ifdef CONFIG_IDE_RESET -extern void init_ide_reset (void); -#endif - -int ide_preinit (void) -{ - long period, t0, t1, t2_8, t2_16, t4, ta; - vu_long reg; - struct mpc5xxx_sdma *psdma = (struct mpc5xxx_sdma *) MPC5XXX_SDMA; - - reg = *(vu_long *) MPC5XXX_GPS_PORT_CONFIG; -#if defined(CONFIG_SYS_ATA_CS_ON_I2C2) - /* ATA cs0/1 on i2c2 clk/io */ - reg = (reg & ~0x03000000ul) | 0x02000000ul; -#elif defined(CONFIG_SYS_ATA_CS_ON_TIMER01) - /* ATA cs0/1 on Timer 0/1 */ - reg = (reg & ~0x03000000ul) | 0x03000000ul; -#else - /* ATA cs0/1 on Local Plus cs4/5 */ - reg = (reg & ~0x03000000ul) | 0x01000000ul; -#endif /* CONFIG_TOTAL5200 */ - *(vu_long *) MPC5XXX_GPS_PORT_CONFIG = reg; - - /* All sample codes do that... */ - *(vu_long *) MPC5XXX_ATA_SHARE_COUNT = 0; - -#if defined(CONFIG_UC101) - /* Configure and reset host */ - *(vu_long *) MPC5XXX_ATA_HOST_CONFIG = - MPC5xxx_ATA_HOSTCONF_SMR | MPC5xxx_ATA_HOSTCONF_FR; - udelay (10); - *(vu_long *) MPC5XXX_ATA_HOST_CONFIG = 0; -#else - /* Configure and reset host */ - *(vu_long *) MPC5XXX_ATA_HOST_CONFIG = MPC5xxx_ATA_HOSTCONF_IORDY | - MPC5xxx_ATA_HOSTCONF_SMR | MPC5xxx_ATA_HOSTCONF_FR; - udelay (10); - *(vu_long *) MPC5XXX_ATA_HOST_CONFIG = MPC5xxx_ATA_HOSTCONF_IORDY; -#endif - - /* Disable prefetch on Commbus */ - psdma->PtdCntrl |= 1; - - /* Init timings : we use PIO mode 0 timings */ - period = 1000000000 / gd->ipb_clk; /* period in ns */ - - t0 = CALC_TIMING (600); - t2_8 = CALC_TIMING (290); - t2_16 = CALC_TIMING (165); - reg = (t0 << 24) | (t2_8 << 16) | (t2_16 << 8); - *(vu_long *) MPC5XXX_ATA_PIO1 = reg; - - t4 = CALC_TIMING (30); - t1 = CALC_TIMING (70); - ta = CALC_TIMING (35); - reg = (t4 << 24) | (t1 << 16) | (ta << 8); - - *(vu_long *) MPC5XXX_ATA_PIO2 = reg; - -#ifdef CONFIG_IDE_RESET - init_ide_reset (); -#endif /* CONFIG_IDE_RESET */ - - return (0); -} -#endif diff --git a/cpu/mpc5xxx/interrupts.c b/cpu/mpc5xxx/interrupts.c deleted file mode 100644 index 6035771..0000000 --- a/cpu/mpc5xxx/interrupts.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * (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. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* this section was ripped out of arch/ppc/syslib/mpc52xx_pic.c in the - * Linux 2.6 source with the following copyright. - * - * Based on (well, mostly copied from) the code from the 2.4 kernel by - * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg. - * - * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com> - * Copyright (C) 2003 Montavista Software, Inc - */ - -#include <common.h> -#include <asm/processor.h> -#include <asm/io.h> -#include <command.h> - -struct irq_action { - interrupt_handler_t *handler; - void *arg; - ulong count; -}; - -static struct irq_action irq_handlers[NR_IRQS]; - -static struct mpc5xxx_intr *intr; -static struct mpc5xxx_sdma *sdma; - -static void mpc5xxx_ic_disable(unsigned int irq) -{ - u32 val; - - if (irq == MPC5XXX_IRQ0) { - val = in_be32(&intr->ctrl); - val &= ~(1 << 11); - out_be32(&intr->ctrl, val); - } else if (irq < MPC5XXX_IRQ1) { - BUG(); - } else if (irq <= MPC5XXX_IRQ3) { - val = in_be32(&intr->ctrl); - val &= ~(1 << (10 - (irq - MPC5XXX_IRQ1))); - out_be32(&intr->ctrl, val); - } else if (irq < MPC5XXX_SDMA_IRQ_BASE) { - val = in_be32(&intr->main_mask); - val |= 1 << (16 - (irq - MPC5XXX_MAIN_IRQ_BASE)); - out_be32(&intr->main_mask, val); - } else if (irq < MPC5XXX_PERP_IRQ_BASE) { - val = in_be32(&sdma->IntMask); - val |= 1 << (irq - MPC5XXX_SDMA_IRQ_BASE); - out_be32(&sdma->IntMask, val); - } else { - val = in_be32(&intr->per_mask); - val |= 1 << (31 - (irq - MPC5XXX_PERP_IRQ_BASE)); - out_be32(&intr->per_mask, val); - } -} - -static void mpc5xxx_ic_enable(unsigned int irq) -{ - u32 val; - - if (irq == MPC5XXX_IRQ0) { - val = in_be32(&intr->ctrl); - val |= 1 << 11; - out_be32(&intr->ctrl, val); - } else if (irq < MPC5XXX_IRQ1) { - BUG(); - } else if (irq <= MPC5XXX_IRQ3) { - val = in_be32(&intr->ctrl); - val |= 1 << (10 - (irq - MPC5XXX_IRQ1)); - out_be32(&intr->ctrl, val); - } else if (irq < MPC5XXX_SDMA_IRQ_BASE) { - val = in_be32(&intr->main_mask); - val &= ~(1 << (16 - (irq - MPC5XXX_MAIN_IRQ_BASE))); - out_be32(&intr->main_mask, val); - } else if (irq < MPC5XXX_PERP_IRQ_BASE) { - val = in_be32(&sdma->IntMask); - val &= ~(1 << (irq - MPC5XXX_SDMA_IRQ_BASE)); - out_be32(&sdma->IntMask, val); - } else { - val = in_be32(&intr->per_mask); - val &= ~(1 << (31 - (irq - MPC5XXX_PERP_IRQ_BASE))); - out_be32(&intr->per_mask, val); - } -} - -static void mpc5xxx_ic_ack(unsigned int irq) -{ - u32 val; - - /* - * Only some irqs are reset here, others in interrupting hardware. - */ - - switch (irq) { - case MPC5XXX_IRQ0: - val = in_be32(&intr->ctrl); - val |= 0x08000000; - out_be32(&intr->ctrl, val); - break; - case MPC5XXX_CCS_IRQ: - val = in_be32(&intr->enc_status); - val |= 0x00000400; - out_be32(&intr->enc_status, val); - break; - case MPC5XXX_IRQ1: - val = in_be32(&intr->ctrl); - val |= 0x04000000; - out_be32(&intr->ctrl, val); - break; - case MPC5XXX_IRQ2: - val = in_be32(&intr->ctrl); - val |= 0x02000000; - out_be32(&intr->ctrl, val); - break; - case MPC5XXX_IRQ3: - val = in_be32(&intr->ctrl); - val |= 0x01000000; - out_be32(&intr->ctrl, val); - break; - default: - if (irq >= MPC5XXX_SDMA_IRQ_BASE - && irq < (MPC5XXX_SDMA_IRQ_BASE + MPC5XXX_SDMA_IRQ_NUM)) { - out_be32(&sdma->IntPend, - 1 << (irq - MPC5XXX_SDMA_IRQ_BASE)); - } - break; - } -} - -static void mpc5xxx_ic_disable_and_ack(unsigned int irq) -{ - mpc5xxx_ic_disable(irq); - mpc5xxx_ic_ack(irq); -} - -static void mpc5xxx_ic_end(unsigned int irq) -{ - mpc5xxx_ic_enable(irq); -} - -void mpc5xxx_init_irq(void) -{ - u32 intr_ctrl; - - /* Remap the necessary zones */ - intr = (struct mpc5xxx_intr *)(MPC5XXX_ICTL); - sdma = (struct mpc5xxx_sdma *)(MPC5XXX_SDMA); - - /* Disable all interrupt sources. */ - out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */ - out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */ - out_be32(&intr->per_mask, 0x7ffffc00); /* 1 means disabled */ - out_be32(&intr->main_mask, 0x00010fff); /* 1 means disabled */ - intr_ctrl = in_be32(&intr->ctrl); - intr_ctrl |= 0x0f000000 | /* clear IRQ 0-3 */ - 0x00ff0000 | /* IRQ 0-3 level sensitive low active */ - 0x00001000 | /* MEE master external enable */ - 0x00000000 | /* 0 means disable IRQ 0-3 */ - 0x00000001; /* CEb route critical normally */ - out_be32(&intr->ctrl, intr_ctrl); - - /* Zero a bunch of the priority settings. */ - out_be32(&intr->per_pri1, 0); - out_be32(&intr->per_pri2, 0); - out_be32(&intr->per_pri3, 0); - out_be32(&intr->main_pri1, 0); - out_be32(&intr->main_pri2, 0); -} - -int mpc5xxx_get_irq(struct pt_regs *regs) -{ - u32 status; - int irq = -1; - - status = in_be32(&intr->enc_status); - - if (status & 0x00000400) { /* critical */ - irq = (status >> 8) & 0x3; - if (irq == 2) /* high priority peripheral */ - goto peripheral; - irq += MPC5XXX_CRIT_IRQ_BASE; - } else if (status & 0x00200000) { /* main */ - irq = (status >> 16) & 0x1f; - if (irq == 4) /* low priority peripheral */ - goto peripheral; - irq += MPC5XXX_MAIN_IRQ_BASE; - } else if (status & 0x20000000) { /* peripheral */ - peripheral: - irq = (status >> 24) & 0x1f; - if (irq == 0) { /* bestcomm */ - status = in_be32(&sdma->IntPend); - irq = ffs(status) + MPC5XXX_SDMA_IRQ_BASE - 1; - } else - irq += MPC5XXX_PERP_IRQ_BASE; - } - - return irq; -} - -/****************************************************************************/ - -int interrupt_init_cpu(ulong * decrementer_count) -{ - *decrementer_count = get_tbclk() / CONFIG_SYS_HZ; - - mpc5xxx_init_irq(); - - return (0); -} - -/****************************************************************************/ - -/* - * Handle external interrupts - */ -void external_interrupt(struct pt_regs *regs) -{ - int irq, unmask = 1; - - irq = mpc5xxx_get_irq(regs); - - mpc5xxx_ic_disable_and_ack(irq); - - enable_interrupts(); - - if (irq_handlers[irq].handler != NULL) - (*irq_handlers[irq].handler) (irq_handlers[irq].arg); - else { - printf("\nBogus External Interrupt IRQ %d\n", irq); - /* - * turn off the bogus interrupt, otherwise it - * might repeat forever - */ - unmask = 0; - } - - if (unmask) - mpc5xxx_ic_end(irq); -} - -void timer_interrupt_cpu(struct pt_regs *regs) -{ - /* nothing to do here */ - return; -} - -/****************************************************************************/ - -/* - * 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); - - irq_handlers[irq].handler = handler; - irq_handlers[irq].arg = arg; - - mpc5xxx_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; - } - - mpc5xxx_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 *argv[]) -{ - int irq, re_enable; - u32 intr_ctrl; - char *irq_config[] = { "level sensitive, active high", - "edge sensitive, rising active edge", - "edge sensitive, falling active edge", - "level sensitive, active low" - }; - - re_enable = disable_interrupts(); - - intr_ctrl = in_be32(&intr->ctrl); - printf("Interrupt configuration:\n"); - - for (irq = 0; irq <= 3; irq++) { - printf("IRQ%d: %s\n", irq, - irq_config[(intr_ctrl >> (22 - 2 * irq)) & 0x3]); - } - - puts("\nInterrupt-Information:\n" "Nr Routine Arg Count\n"); - - for (irq = 0; irq < NR_IRQS; irq++) - if (irq_handlers[irq].handler != NULL) - printf("%02d %08lx %08lx %ld\n", irq, - (ulong) irq_handlers[irq].handler, - (ulong) irq_handlers[irq].arg, - irq_handlers[irq].count); - - if (re_enable) - enable_interrupts(); -} -#endif diff --git a/cpu/mpc5xxx/io.S b/cpu/mpc5xxx/io.S deleted file mode 100644 index 2178a26..0000000 --- a/cpu/mpc5xxx/io.S +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 1998 Dan Malek <dmalek@jlc.net> - * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> - * Copyright (C) 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> - * Andreas Heppel <aheppel@sysgo.de> - * Copyright (C) 2003 Wolfgang Denk <wd@denx.de> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <config.h> -#include <ppc_asm.tmpl> - -/* ------------------------------------------------------------------------------- */ -/* Function: in8 */ -/* Description: Input 8 bits */ -/* ------------------------------------------------------------------------------- */ - .globl in8 -in8: - lbz r3,0(r3) - sync - blr - -/* ------------------------------------------------------------------------------- */ -/* Function: in16 */ -/* Description: Input 16 bits */ -/* ------------------------------------------------------------------------------- */ - .globl in16 -in16: - lhz r3,0(r3) - sync - blr - -/* ------------------------------------------------------------------------------- */ -/* Function: in16r */ -/* Description: Input 16 bits and byte reverse */ -/* ------------------------------------------------------------------------------- */ - .globl in16r -in16r: - lhbrx r3,0,r3 - sync - blr - -/* ------------------------------------------------------------------------------- */ -/* Function: in32 */ -/* Description: Input 32 bits */ -/* ------------------------------------------------------------------------------- */ - .globl in32 -in32: - lwz 3,0(3) - sync - blr - -/* ------------------------------------------------------------------------------- */ -/* Function: in32r */ -/* Description: Input 32 bits and byte reverse */ -/* ------------------------------------------------------------------------------- */ - .globl in32r -in32r: - lwbrx r3,0,r3 - sync - blr - -/* ------------------------------------------------------------------------------- */ -/* Function: out8 */ -/* Description: Output 8 bits */ -/* ------------------------------------------------------------------------------- */ - .globl out8 -out8: - stb r4,0(r3) - sync - blr - -/* ------------------------------------------------------------------------------- */ -/* Function: out16 */ -/* Description: Output 16 bits */ -/* ------------------------------------------------------------------------------- */ - .globl out16 -out16: - sth r4,0(r3) - sync - blr - -/* ------------------------------------------------------------------------------- */ -/* Function: out16r */ -/* Description: Byte reverse and output 16 bits */ -/* ------------------------------------------------------------------------------- */ - .globl out16r -out16r: - sthbrx r4,0,r3 - sync - blr - -/* ------------------------------------------------------------------------------- */ -/* Function: out32 */ -/* Description: Output 32 bits */ -/* ------------------------------------------------------------------------------- */ - .globl out32 -out32: - stw r4,0(r3) - sync - blr - -/* ------------------------------------------------------------------------------- */ -/* Function: out32r */ -/* Description: Byte reverse and output 32 bits */ -/* ------------------------------------------------------------------------------- */ - .globl out32r -out32r: - stwbrx r4,0,r3 - sync - blr diff --git a/cpu/mpc5xxx/loadtask.c b/cpu/mpc5xxx/loadtask.c deleted file mode 100644 index 47e7b59..0000000 --- a/cpu/mpc5xxx/loadtask.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * This file is based on code - * (C) Copyright Motorola, Inc., 2000 - */ - -#include <common.h> -#include <mpc5xxx.h> - -/* BestComm/SmartComm microcode */ -extern int taskTable; - -void loadtask(int basetask, int tasks) -{ - int *sram = (int *)MPC5XXX_SRAM; - int *task_org = &taskTable; - unsigned int start, offset, end; - int i; - -#ifdef DEBUG - printf("basetask = %d, tasks = %d\n", basetask, tasks); - printf("task_org = 0x%08x\n", (unsigned int)task_org); -#endif - - /* setup TaskBAR register */ - *(vu_long *)MPC5XXX_SDMA = MPC5XXX_SRAM; - - /* relocate task table entries */ - offset = (unsigned int)sram; - for (i = basetask; i < basetask + tasks; i++) { - sram[i * 8 + 0] = task_org[i * 8 + 0] + offset; - sram[i * 8 + 1] = task_org[i * 8 + 1] + offset; - sram[i * 8 + 2] = task_org[i * 8 + 2] + offset; - sram[i * 8 + 3] = task_org[i * 8 + 3] + offset; - sram[i * 8 + 4] = task_org[i * 8 + 4]; - sram[i * 8 + 5] = task_org[i * 8 + 5]; - sram[i * 8 + 6] = task_org[i * 8 + 6] + offset; - sram[i * 8 + 7] = task_org[i * 8 + 7]; - } - - /* relocate task descriptors */ - start = (sram[basetask * 8] - (unsigned int)sram); - end = (sram[(basetask + tasks - 1) * 8 + 1] - (unsigned int)sram); - -#ifdef DEBUG - printf ("TDT start = 0x%08x, end = 0x%08x\n", start, end); -#endif - - start /= 4; - end /= 4; - for (i = start; i <= end; i++) { - sram[i] = task_org[i]; - } - - /* relocate variables */ - start = (sram[basetask * 8 + 2] - (unsigned int)sram); - end = (sram[(basetask + tasks - 1) * 8 + 2] + 256 - (unsigned int)sram); - start /= 4; - end /= 4; - for (i = start; i < end; i++) { - sram[i] = task_org[i]; - } - - /* relocate function decriptors */ - start = ((sram[basetask * 8 + 3] & 0xfffffffc) - (unsigned int)sram); - end = ((sram[(basetask + tasks - 1) * 8 + 3] & 0xfffffffc) + 256 - (unsigned int)sram); - start /= 4; - end /= 4; - for (i = start; i < end; i++) { - sram[i] = task_org[i]; - } - - asm volatile ("sync"); -} diff --git a/cpu/mpc5xxx/pci_mpc5200.c b/cpu/mpc5xxx/pci_mpc5200.c deleted file mode 100644 index 8268f8a..0000000 --- a/cpu/mpc5xxx/pci_mpc5200.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * (C) Copyright 2000-2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> - -#if defined(CONFIG_PCI) - -#include <asm/processor.h> -#include <asm/io.h> -#include <pci.h> -#include <mpc5xxx.h> - -/* System RAM mapped over PCI */ -#define CONFIG_PCI_MEMORY_BUS CONFIG_SYS_SDRAM_BASE -#define CONFIG_PCI_MEMORY_PHYS CONFIG_SYS_SDRAM_BASE -#define CONFIG_PCI_MEMORY_SIZE (1024 * 1024 * 1024) - -/* PCIIWCR bit fields */ -#define IWCR_MEM (0 << 3) -#define IWCR_IO (1 << 3) -#define IWCR_READ (0 << 1) -#define IWCR_READLINE (1 << 1) -#define IWCR_READMULT (2 << 1) -#define IWCR_EN (1 << 0) - -static int mpc5200_read_config_dword(struct pci_controller *hose, - pci_dev_t dev, int offset, u32* value) -{ - *(volatile u32 *)MPC5XXX_PCI_CAR = (1 << 31) | dev | offset; - eieio(); - udelay(10); -#if (defined CONFIG_PF5200 || defined CONFIG_CPCI5200) - if (dev & 0x00ff0000) { - u32 val; - val = in_le16((volatile u16 *)(CONFIG_PCI_IO_PHYS+2)); - udelay(10); - val = val << 16; - val |= in_le16((volatile u16 *)(CONFIG_PCI_IO_PHYS+0)); - *value = val; - } else { - *value = in_le32((volatile u32 *)CONFIG_PCI_IO_PHYS); - } - udelay(10); -#else - *value = in_le32((volatile u32 *)CONFIG_PCI_IO_PHYS); -#endif - eieio(); - *(volatile u32 *)MPC5XXX_PCI_CAR = 0; - udelay(10); - return 0; -} - -static int mpc5200_write_config_dword(struct pci_controller *hose, - pci_dev_t dev, int offset, u32 value) -{ - *(volatile u32 *)MPC5XXX_PCI_CAR = (1 << 31) | dev | offset; - eieio(); - udelay(10); - out_le32((volatile u32 *)CONFIG_PCI_IO_PHYS, value); - eieio(); - *(volatile u32 *)MPC5XXX_PCI_CAR = 0; - udelay(10); - return 0; -} - -void pci_mpc5xxx_init (struct pci_controller *hose) -{ - hose->first_busno = 0; - hose->last_busno = 0xff; - - /* System space */ - pci_set_region(hose->regions + 0, - CONFIG_PCI_MEMORY_BUS, - CONFIG_PCI_MEMORY_PHYS, - CONFIG_PCI_MEMORY_SIZE, - PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); - - /* PCI memory space */ - pci_set_region(hose->regions + 1, - CONFIG_PCI_MEM_BUS, - CONFIG_PCI_MEM_PHYS, - CONFIG_PCI_MEM_SIZE, - PCI_REGION_MEM); - - /* PCI IO space */ - pci_set_region(hose->regions + 2, - CONFIG_PCI_IO_BUS, - CONFIG_PCI_IO_PHYS, - CONFIG_PCI_IO_SIZE, - PCI_REGION_IO); - - hose->region_count = 3; - - pci_register_hose(hose); - - /* GPIO Multiplexing - enable PCI */ - *(vu_long *)MPC5XXX_GPS_PORT_CONFIG &= ~(1 << 15); - - /* Set host bridge as pci master and enable memory decoding */ - *(vu_long *)MPC5XXX_PCI_CMD |= - PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; - - /* Set maximum latency timer */ - *(vu_long *)MPC5XXX_PCI_CFG |= (0xf800); - - /* Set cache line size */ - *(vu_long *)MPC5XXX_PCI_CFG = (*(vu_long *)MPC5XXX_PCI_CFG & ~0xff) | - (CONFIG_SYS_CACHELINE_SIZE / 4); - - /* Map MBAR to PCI space */ - *(vu_long *)MPC5XXX_PCI_BAR0 = CONFIG_SYS_MBAR; - *(vu_long *)MPC5XXX_PCI_TBATR0 = CONFIG_SYS_MBAR | 1; - - /* Map RAM to PCI space */ - *(vu_long *)MPC5XXX_PCI_BAR1 = CONFIG_PCI_MEMORY_BUS | (1 << 3); - *(vu_long *)MPC5XXX_PCI_TBATR1 = CONFIG_PCI_MEMORY_PHYS | 1; - - /* Park XLB on PCI */ - *(vu_long *)(MPC5XXX_XLBARB + 0x40) &= ~((7 << 8) | (3 << 5)); - *(vu_long *)(MPC5XXX_XLBARB + 0x40) |= (3 << 8) | (3 << 5); - - /* Disable interrupts from PCI controller */ - *(vu_long *)MPC5XXX_PCI_GSCR &= ~(7 << 12); - *(vu_long *)MPC5XXX_PCI_ICR &= ~(7 << 24); - - /* Set PCI retry counter to 0 = infinite retry. */ - /* The default of 255 is too short for slow devices. */ - *(vu_long *)MPC5XXX_PCI_ICR &= 0xFFFFFF00; - - /* Disable initiator windows */ - *(vu_long *)MPC5XXX_PCI_IWCR = 0; - - /* Map PCI memory to physical space */ - *(vu_long *)MPC5XXX_PCI_IW0BTAR = CONFIG_PCI_MEM_PHYS | - (((CONFIG_PCI_MEM_SIZE - 1) >> 8) & 0x00ff0000) | - (CONFIG_PCI_MEM_BUS >> 16); - *(vu_long *)MPC5XXX_PCI_IWCR |= (IWCR_MEM | IWCR_READ | IWCR_EN) << 24; - - /* Map PCI I/O to physical space */ - *(vu_long *)MPC5XXX_PCI_IW1BTAR = CONFIG_PCI_IO_PHYS | - (((CONFIG_PCI_IO_SIZE - 1) >> 8) & 0x00ff0000) | - (CONFIG_PCI_IO_BUS >> 16); - *(vu_long *)MPC5XXX_PCI_IWCR |= (IWCR_IO | IWCR_READ | IWCR_EN) << 16; - - /* Reset the PCI bus */ - *(vu_long *)MPC5XXX_PCI_GSCR |= 1; - udelay(1000); - *(vu_long *)MPC5XXX_PCI_GSCR &= ~1; - udelay(1000); - - pci_set_ops(hose, - pci_hose_read_config_byte_via_dword, - pci_hose_read_config_word_via_dword, - mpc5200_read_config_dword, - pci_hose_write_config_byte_via_dword, - pci_hose_write_config_word_via_dword, - mpc5200_write_config_dword); - - udelay(1000); - -#ifdef CONFIG_PCI_SCAN_SHOW - printf("PCI: Bus Dev VenId DevId Class Int\n"); -#endif - - hose->last_busno = pci_hose_scan(hose); -} -#endif /* CONFIG_PCI */ diff --git a/cpu/mpc5xxx/serial.c b/cpu/mpc5xxx/serial.c deleted file mode 100644 index 6675988..0000000 --- a/cpu/mpc5xxx/serial.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - * (C) Copyright 2000 - 2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 19-Oct-00, with - * changes based on the file arch/ppc/mbxboot/m8260_tty.c from the - * Linux/PPC sources (m8260_tty.c had no copyright info in it). - * - * Martin Krause, 8 Jun 2006 - * Added CONFIG_SERIAL_MULTI support - */ - -/* - * Minimal serial functions needed to use one of the PSC ports - * as serial console interface. - */ - -#include <common.h> -#include <mpc5xxx.h> - -#if defined (CONFIG_SERIAL_MULTI) -#include <serial.h> -#endif - -DECLARE_GLOBAL_DATA_PTR; - -#if defined(CONFIG_PSC_CONSOLE) - -#if CONFIG_PSC_CONSOLE == 1 -#define PSC_BASE MPC5XXX_PSC1 -#elif CONFIG_PSC_CONSOLE == 2 -#define PSC_BASE MPC5XXX_PSC2 -#elif CONFIG_PSC_CONSOLE == 3 -#define PSC_BASE MPC5XXX_PSC3 -#elif CONFIG_PSC_CONSOLE == 4 -#define PSC_BASE MPC5XXX_PSC4 -#elif CONFIG_PSC_CONSOLE == 5 -#define PSC_BASE MPC5XXX_PSC5 -#elif CONFIG_PSC_CONSOLE == 6 -#define PSC_BASE MPC5XXX_PSC6 -#else -#error CONFIG_PSC_CONSOLE must be in 1 ... 6 -#endif - -#if defined(CONFIG_SERIAL_MULTI) && !defined(CONFIG_PSC_CONSOLE2) -#error you must define CONFIG_PSC_CONSOLE2 if CONFIG_SERIAL_MULTI is set -#endif - -#if defined(CONFIG_SERIAL_MULTI) -#if CONFIG_PSC_CONSOLE2 == 1 -#define PSC_BASE2 MPC5XXX_PSC1 -#elif CONFIG_PSC_CONSOLE2 == 2 -#define PSC_BASE2 MPC5XXX_PSC2 -#elif CONFIG_PSC_CONSOLE2 == 3 -#define PSC_BASE2 MPC5XXX_PSC3 -#elif CONFIG_PSC_CONSOLE2 == 4 -#define PSC_BASE2 MPC5XXX_PSC4 -#elif CONFIG_PSC_CONSOLE2 == 5 -#define PSC_BASE2 MPC5XXX_PSC5 -#elif CONFIG_PSC_CONSOLE2 == 6 -#define PSC_BASE2 MPC5XXX_PSC6 -#else -#error CONFIG_PSC_CONSOLE2 must be in 1 ... 6 -#endif -#endif /* CONFIG_SERIAL_MULTI */ - -#if defined(CONFIG_SERIAL_MULTI) -int serial_init_dev (unsigned long dev_base) -#else -int serial_init (void) -#endif -{ -#if defined(CONFIG_SERIAL_MULTI) - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base; -#else - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; -#endif - unsigned long baseclk; - int div; - - /* reset PSC */ - psc->command = PSC_SEL_MODE_REG_1; - - /* select clock sources */ - psc->psc_clock_select = 0; - baseclk = (gd->ipb_clk + 16) / 32; - - /* switch to UART mode */ - psc->sicr = 0; - - /* configure parity, bit length and so on */ - psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE; - psc->mode = PSC_MODE_ONE_STOP; - - /* set up UART divisor */ - div = (baseclk + (gd->baudrate/2)) / gd->baudrate; - psc->ctur = (div >> 8) & 0xff; - psc->ctlr = div & 0xff; - - /* disable all interrupts */ - psc->psc_imr = 0; - - /* reset and enable Rx/Tx */ - psc->command = PSC_RST_RX; - psc->command = PSC_RST_TX; - psc->command = PSC_RX_ENABLE | PSC_TX_ENABLE; - - return (0); -} - -#if defined(CONFIG_SERIAL_MULTI) -void serial_putc_dev (unsigned long dev_base, const char c) -#else -void serial_putc(const char c) -#endif -{ -#if defined(CONFIG_SERIAL_MULTI) - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base; -#else - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; -#endif - - if (c == '\n') -#if defined(CONFIG_SERIAL_MULTI) - serial_putc_dev (dev_base, '\r'); -#else - serial_putc('\r'); -#endif - - /* Wait for last character to go. */ - while (!(psc->psc_status & PSC_SR_TXEMP)) - ; - - psc->psc_buffer_8 = c; -} - -#if defined(CONFIG_SERIAL_MULTI) -void serial_putc_raw_dev(unsigned long dev_base, const char c) -#else -void serial_putc_raw(const char c) -#endif -{ -#if defined(CONFIG_SERIAL_MULTI) - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base; -#else - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; -#endif - /* Wait for last character to go. */ - while (!(psc->psc_status & PSC_SR_TXEMP)) - ; - - psc->psc_buffer_8 = c; -} - - -#if defined(CONFIG_SERIAL_MULTI) -void serial_puts_dev (unsigned long dev_base, const char *s) -#else -void serial_puts (const char *s) -#endif -{ - while (*s) { -#if defined(CONFIG_SERIAL_MULTI) - serial_putc_dev (dev_base, *s++); -#else - serial_putc (*s++); -#endif - } -} - -#if defined(CONFIG_SERIAL_MULTI) -int serial_getc_dev (unsigned long dev_base) -#else -int serial_getc(void) -#endif -{ -#if defined(CONFIG_SERIAL_MULTI) - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base; -#else - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; -#endif - - /* Wait for a character to arrive. */ - while (!(psc->psc_status & PSC_SR_RXRDY)) - ; - - return psc->psc_buffer_8; -} - -#if defined(CONFIG_SERIAL_MULTI) -int serial_tstc_dev (unsigned long dev_base) -#else -int serial_tstc(void) -#endif -{ -#if defined(CONFIG_SERIAL_MULTI) - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base; -#else - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; -#endif - - return (psc->psc_status & PSC_SR_RXRDY); -} - -#if defined(CONFIG_SERIAL_MULTI) -void serial_setbrg_dev (unsigned long dev_base) -#else -void serial_setbrg(void) -#endif -{ -#if defined(CONFIG_SERIAL_MULTI) - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base; -#else - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; -#endif - unsigned long baseclk, div; - - baseclk = (gd->ipb_clk + 16) / 32; - - /* set up UART divisor */ - div = (baseclk + (gd->baudrate/2)) / gd->baudrate; - psc->ctur = (div >> 8) & 0xFF; - psc->ctlr = div & 0xff; -} - -#if defined(CONFIG_SERIAL_MULTI) -void serial_setrts_dev (unsigned long dev_base, int s) -#else -void serial_setrts(int s) -#endif -{ -#if defined(CONFIG_SERIAL_MULTI) - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base; -#else - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; -#endif - - if (s) { - /* Assert RTS (become LOW) */ - psc->op1 = 0x1; - } - else { - /* Negate RTS (become HIGH) */ - psc->op0 = 0x1; - } -} - -#if defined(CONFIG_SERIAL_MULTI) -int serial_getcts_dev (unsigned long dev_base) -#else -int serial_getcts(void) -#endif -{ -#if defined(CONFIG_SERIAL_MULTI) - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base; -#else - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; -#endif - - return (psc->ip & 0x1) ? 0 : 1; -} - -#if defined(CONFIG_SERIAL_MULTI) -int serial0_init(void) -{ - return (serial_init_dev(PSC_BASE)); -} - -int serial1_init(void) -{ - return (serial_init_dev(PSC_BASE2)); -} -void serial0_setbrg (void) -{ - serial_setbrg_dev(PSC_BASE); -} -void serial1_setbrg (void) -{ - serial_setbrg_dev(PSC_BASE2); -} - -void serial0_putc(const char c) -{ - serial_putc_dev(PSC_BASE,c); -} - -void serial1_putc(const char c) -{ - serial_putc_dev(PSC_BASE2, c); -} -void serial0_puts(const char *s) -{ - serial_puts_dev(PSC_BASE, s); -} - -void serial1_puts(const char *s) -{ - serial_puts_dev(PSC_BASE2, s); -} - -int serial0_getc(void) -{ - return(serial_getc_dev(PSC_BASE)); -} - -int serial1_getc(void) -{ - return(serial_getc_dev(PSC_BASE2)); -} -int serial0_tstc(void) -{ - return (serial_tstc_dev(PSC_BASE)); -} - -int serial1_tstc(void) -{ - return (serial_tstc_dev(PSC_BASE2)); -} - -struct serial_device serial0_device = -{ - "serial0", - "UART0", - serial0_init, - serial0_setbrg, - serial0_getc, - serial0_tstc, - serial0_putc, - serial0_puts, -}; - -struct serial_device serial1_device = -{ - "serial1", - "UART1", - serial1_init, - serial1_setbrg, - serial1_getc, - serial1_tstc, - serial1_putc, - serial1_puts, -}; -#endif /* CONFIG_SERIAL_MULTI */ - -#endif /* CONFIG_PSC_CONSOLE */ diff --git a/cpu/mpc5xxx/speed.c b/cpu/mpc5xxx/speed.c deleted file mode 100644 index 8027d3e..0000000 --- a/cpu/mpc5xxx/speed.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * (C) Copyright 2000-2002 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <mpc5xxx.h> -#include <asm/processor.h> - -DECLARE_GLOBAL_DATA_PTR; - -/* ------------------------------------------------------------------------- */ - -/* Bus-to-Core Multipliers */ - -static int bus2core[] = { - 3, 2, 2, 2, 4, 4, 5, 9, - 6, 11, 8, 10, 3, 12, 7, 0, - 6, 5, 13, 2, 14, 4, 15, 9, - 0, 11, 8, 10, 16, 12, 7, 0 -}; -/* ------------------------------------------------------------------------- */ - -/* - * - */ - -int get_clocks (void) -{ - ulong val, vco; - -#if !defined(CONFIG_SYS_MPC5XXX_CLKIN) -#error clock measuring not implemented yet - define CONFIG_SYS_MPC5XXX_CLKIN -#endif - - val = *(vu_long *)MPC5XXX_CDM_PORCFG; - if (val & (1 << 6)) { - vco = CONFIG_SYS_MPC5XXX_CLKIN * 12; - } else { - vco = CONFIG_SYS_MPC5XXX_CLKIN * 16; - } - if (val & (1 << 5)) { - gd->bus_clk = vco / 8; - } else { - gd->bus_clk = vco / 4; - } - gd->cpu_clk = gd->bus_clk * bus2core[val & 0x1f] / 2; - - val = *(vu_long *)MPC5XXX_CDM_CFG; - if (val & (1 << 8)) { - gd->ipb_clk = gd->bus_clk / 2; - } else { - gd->ipb_clk = gd->bus_clk; - } - switch (val & 3) { - case 0: gd->pci_clk = gd->ipb_clk; break; - case 1: gd->pci_clk = gd->ipb_clk / 2; break; - default: gd->pci_clk = gd->bus_clk / 4; break; - } - - return (0); -} - -int prt_mpc5xxx_clks (void) -{ - char buf1[32], buf2[32], buf3[32]; - - printf (" Bus %s MHz, IPB %s MHz, PCI %s MHz\n", - strmhz(buf1, gd->bus_clk), - strmhz(buf2, gd->ipb_clk), - strmhz(buf3, gd->pci_clk) - ); - return (0); -} - -/* ------------------------------------------------------------------------- */ diff --git a/cpu/mpc5xxx/start.S b/cpu/mpc5xxx/start.S deleted file mode 100644 index ba49944..0000000 --- a/cpu/mpc5xxx/start.S +++ /dev/null @@ -1,777 +0,0 @@ -/* - * Copyright (C) 1998 Dan Malek <dmalek@jlc.net> - * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> - * Copyright (C) 2000 - 2003 Wolfgang Denk <wd@denx.de> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * U-Boot - Startup Code for MPC5xxx CPUs - */ -#include <config.h> -#include <mpc5xxx.h> -#include <timestamp.h> -#include <version.h> - -#define CONFIG_MPC5xxx 1 /* needed for Linux kernel header files */ -#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ - -#include <ppc_asm.tmpl> -#include <ppc_defs.h> - -#include <asm/cache.h> -#include <asm/mmu.h> - -#ifndef CONFIG_IDENT_STRING -#define CONFIG_IDENT_STRING "" -#endif - -/* We don't want the MMU yet. -*/ -#undef MSR_KERNEL -/* Floating Point enable, Machine Check and Recoverable Interr. */ -#ifdef DEBUG -#define MSR_KERNEL (MSR_FP|MSR_RI) -#else -#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI) -#endif - -/* - * Set up GOT: Global Offset Table - * - * Use r12 to access the GOT - */ - START_GOT - GOT_ENTRY(_GOT2_TABLE_) - GOT_ENTRY(_FIXUP_TABLE_) - - GOT_ENTRY(_start) - GOT_ENTRY(_start_of_vectors) - GOT_ENTRY(_end_of_vectors) - GOT_ENTRY(transfer_to_handler) - - GOT_ENTRY(__init_end) - GOT_ENTRY(_end) - GOT_ENTRY(__bss_start) - END_GOT - -/* - * Version string - */ - .data - .globl version_string -version_string: - .ascii U_BOOT_VERSION - .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" - .ascii CONFIG_IDENT_STRING, "\0" - -/* - * Exception vectors - */ - .text - . = EXC_OFF_SYS_RESET - .globl _start -_start: - li r21, BOOTFLAG_COLD /* Normal Power-On */ - nop - b boot_cold - - . = EXC_OFF_SYS_RESET + 0x10 - - .globl _start_warm -_start_warm: - li r21, BOOTFLAG_WARM /* Software reboot */ - b boot_warm - -boot_cold: -boot_warm: - mfmsr r5 /* save msr contents */ - - /* Move CSBoot and adjust instruction pointer */ - /*--------------------------------------------------------------*/ - -#if defined(CONFIG_SYS_LOWBOOT) -# if defined(CONFIG_SYS_RAMBOOT) -# error CONFIG_SYS_LOWBOOT is incompatible with CONFIG_SYS_RAMBOOT -# endif /* CONFIG_SYS_RAMBOOT */ - lis r4, CONFIG_SYS_DEFAULT_MBAR@h - lis r3, START_REG(CONFIG_SYS_BOOTCS_START)@h - ori r3, r3, START_REG(CONFIG_SYS_BOOTCS_START)@l - stw r3, 0x4(r4) /* CS0 start */ - lis r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@h - ori r3, r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@l - stw r3, 0x8(r4) /* CS0 stop */ - lis r3, 0x02010000@h - ori r3, r3, 0x02010000@l - stw r3, 0x54(r4) /* CS0 and Boot enable */ - - lis r3, lowboot_reentry@h /* jump from bootlow address space (0x0000xxxx) */ - ori r3, r3, lowboot_reentry@l /* to the address space the linker used */ - mtlr r3 - blr - -lowboot_reentry: - lis r3, START_REG(CONFIG_SYS_BOOTCS_START)@h - ori r3, r3, START_REG(CONFIG_SYS_BOOTCS_START)@l - stw r3, 0x4c(r4) /* Boot start */ - lis r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@h - ori r3, r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@l - stw r3, 0x50(r4) /* Boot stop */ - lis r3, 0x02000001@h - ori r3, r3, 0x02000001@l - stw r3, 0x54(r4) /* Boot enable, CS0 disable */ -#endif /* CONFIG_SYS_LOWBOOT */ - -#if defined(CONFIG_SYS_DEFAULT_MBAR) && !defined(CONFIG_SYS_RAMBOOT) - lis r3, CONFIG_SYS_MBAR@h - ori r3, r3, CONFIG_SYS_MBAR@l - /* MBAR is mirrored into the MBAR SPR */ - mtspr MBAR,r3 - rlwinm r3, r3, 16, 16, 31 - lis r4, CONFIG_SYS_DEFAULT_MBAR@h - stw r3, 0(r4) -#endif /* CONFIG_SYS_DEFAULT_MBAR */ - - /* Initialise the MPC5xxx processor core */ - /*--------------------------------------------------------------*/ - - bl init_5xxx_core - - /* initialize some things that are hard to access from C */ - /*--------------------------------------------------------------*/ - - /* set up stack in on-chip SRAM */ - lis r3, CONFIG_SYS_INIT_RAM_ADDR@h - ori r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l - ori r1, r3, CONFIG_SYS_INIT_SP_OFFSET - li r0, 0 /* Make room for stack frame header and */ - stwu r0, -4(r1) /* clear final stack frame so that */ - stwu r0, -4(r1) /* stack backtraces terminate cleanly */ - - /* let the C-code set up the rest */ - /* */ - /* Be careful to keep code relocatable ! */ - /*--------------------------------------------------------------*/ - - GET_GOT /* initialize GOT access */ - - /* r3: IMMR */ - bl cpu_init_f /* run low-level CPU init code (in Flash)*/ - - mr r3, r21 - /* r3: BOOTFLAG */ - bl board_init_f /* run 1st part of board init code (in Flash)*/ - -/* - * Vector Table - */ - - .globl _start_of_vectors -_start_of_vectors: - -/* Machine check */ - STD_EXCEPTION(0x200, MachineCheck, MachineCheckException) - -/* Data Storage exception. */ - STD_EXCEPTION(0x300, DataStorage, UnknownException) - -/* Instruction Storage exception. */ - STD_EXCEPTION(0x400, InstStorage, UnknownException) - -/* External Interrupt exception. */ - STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt) - -/* Alignment exception. */ - . = 0x600 -Alignment: - EXCEPTION_PROLOG(SRR0, SRR1) - mfspr r4,DAR - stw r4,_DAR(r21) - mfspr r5,DSISR - stw r5,_DSISR(r21) - addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE) - -/* Program check exception */ - . = 0x700 -ProgramCheck: - EXCEPTION_PROLOG(SRR0, SRR1) - addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException, - MSR_KERNEL, COPY_EE) - - STD_EXCEPTION(0x800, FPUnavailable, UnknownException) - - /* I guess we could implement decrementer, and may have - * to someday for timekeeping. - */ - STD_EXCEPTION(0x900, Decrementer, timer_interrupt) - - STD_EXCEPTION(0xa00, Trap_0a, UnknownException) - STD_EXCEPTION(0xb00, Trap_0b, UnknownException) - STD_EXCEPTION(0xc00, SystemCall, UnknownException) - STD_EXCEPTION(0xd00, SingleStep, UnknownException) - - STD_EXCEPTION(0xe00, Trap_0e, UnknownException) - STD_EXCEPTION(0xf00, Trap_0f, UnknownException) - - STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException) - STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException) - STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException) -#ifdef DEBUG - . = 0x1300 - /* - * This exception occurs when the program counter matches the - * Instruction Address Breakpoint Register (IABR). - * - * I want the cpu to halt if this occurs so I can hunt around - * with the debugger and look at things. - * - * When DEBUG is defined, both machine check enable (in the MSR) - * and checkstop reset enable (in the reset mode register) are - * turned off and so a checkstop condition will result in the cpu - * halting. - * - * I force the cpu into a checkstop condition by putting an illegal - * instruction here (at least this is the theory). - * - * well - that didnt work, so just do an infinite loop! - */ -1: b 1b -#else - STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException) -#endif - STD_EXCEPTION(0x1400, SMI, UnknownException) - - STD_EXCEPTION(0x1500, Trap_15, UnknownException) - STD_EXCEPTION(0x1600, Trap_16, UnknownException) - STD_EXCEPTION(0x1700, Trap_17, UnknownException) - STD_EXCEPTION(0x1800, Trap_18, UnknownException) - STD_EXCEPTION(0x1900, Trap_19, UnknownException) - STD_EXCEPTION(0x1a00, Trap_1a, UnknownException) - STD_EXCEPTION(0x1b00, Trap_1b, UnknownException) - STD_EXCEPTION(0x1c00, Trap_1c, UnknownException) - STD_EXCEPTION(0x1d00, Trap_1d, UnknownException) - STD_EXCEPTION(0x1e00, Trap_1e, UnknownException) - STD_EXCEPTION(0x1f00, Trap_1f, UnknownException) - STD_EXCEPTION(0x2000, Trap_20, UnknownException) - STD_EXCEPTION(0x2100, Trap_21, UnknownException) - STD_EXCEPTION(0x2200, Trap_22, UnknownException) - STD_EXCEPTION(0x2300, Trap_23, UnknownException) - STD_EXCEPTION(0x2400, Trap_24, UnknownException) - STD_EXCEPTION(0x2500, Trap_25, UnknownException) - STD_EXCEPTION(0x2600, Trap_26, UnknownException) - STD_EXCEPTION(0x2700, Trap_27, UnknownException) - STD_EXCEPTION(0x2800, Trap_28, UnknownException) - STD_EXCEPTION(0x2900, Trap_29, UnknownException) - STD_EXCEPTION(0x2a00, Trap_2a, UnknownException) - STD_EXCEPTION(0x2b00, Trap_2b, UnknownException) - STD_EXCEPTION(0x2c00, Trap_2c, UnknownException) - STD_EXCEPTION(0x2d00, Trap_2d, UnknownException) - STD_EXCEPTION(0x2e00, Trap_2e, UnknownException) - STD_EXCEPTION(0x2f00, Trap_2f, UnknownException) - - - .globl _end_of_vectors -_end_of_vectors: - - . = 0x3000 - -/* - * This code finishes saving the registers to the exception frame - * and jumps to the appropriate handler for the exception. - * Register r21 is pointer into trap frame, r1 has new stack pointer. - */ - .globl transfer_to_handler -transfer_to_handler: - stw r22,_NIP(r21) - lis r22,MSR_POW@h - andc r23,r23,r22 - stw r23,_MSR(r21) - SAVE_GPR(7, r21) - SAVE_4GPRS(8, r21) - SAVE_8GPRS(12, r21) - SAVE_8GPRS(24, r21) - mflr r23 - andi. r24,r23,0x3f00 /* get vector offset */ - stw r24,TRAP(r21) - li r22,0 - stw r22,RESULT(r21) - lwz r24,0(r23) /* virtual address of handler */ - lwz r23,4(r23) /* where to go when done */ - mtspr SRR0,r24 - mtspr SRR1,r20 - mtlr r23 - SYNC - rfi /* jump to handler, enable MMU */ - -int_return: - mfmsr r28 /* Disable interrupts */ - li r4,0 - ori r4,r4,MSR_EE - andc r28,r28,r4 - SYNC /* Some chip revs need this... */ - mtmsr r28 - SYNC - lwz r2,_CTR(r1) - lwz r0,_LINK(r1) - mtctr r2 - mtlr r0 - lwz r2,_XER(r1) - lwz r0,_CCR(r1) - mtspr XER,r2 - mtcrf 0xFF,r0 - REST_10GPRS(3, r1) - REST_10GPRS(13, r1) - REST_8GPRS(23, r1) - REST_GPR(31, r1) - lwz r2,_NIP(r1) /* Restore environment */ - lwz r0,_MSR(r1) - mtspr SRR0,r2 - mtspr SRR1,r0 - lwz r0,GPR0(r1) - lwz r2,GPR2(r1) - lwz r1,GPR1(r1) - SYNC - rfi - -/* - * This code initialises the MPC5xxx processor core - * (conforms to PowerPC 603e spec) - * Note: expects original MSR contents to be in r5. - */ - - .globl init_5xx_core -init_5xxx_core: - - /* Initialize machine status; enable machine check interrupt */ - /*--------------------------------------------------------------*/ - - li r3, MSR_KERNEL /* Set ME and RI flags */ - rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */ -#ifdef DEBUG - rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */ -#endif - SYNC /* Some chip revs need this... */ - mtmsr r3 - SYNC - mtspr SRR1, r3 /* Make SRR1 match MSR */ - - /* Initialize the Hardware Implementation-dependent Registers */ - /* HID0 also contains cache control */ - /*--------------------------------------------------------------*/ - - lis r3, CONFIG_SYS_HID0_INIT@h - ori r3, r3, CONFIG_SYS_HID0_INIT@l - SYNC - mtspr HID0, r3 - - lis r3, CONFIG_SYS_HID0_FINAL@h - ori r3, r3, CONFIG_SYS_HID0_FINAL@l - SYNC - mtspr HID0, r3 - - /* clear all BAT's */ - /*--------------------------------------------------------------*/ - - li r0, 0 - mtspr DBAT0U, r0 - mtspr DBAT0L, r0 - mtspr DBAT1U, r0 - mtspr DBAT1L, r0 - mtspr DBAT2U, r0 - mtspr DBAT2L, r0 - mtspr DBAT3U, r0 - mtspr DBAT3L, r0 - mtspr DBAT4U, r0 - mtspr DBAT4L, r0 - mtspr DBAT5U, r0 - mtspr DBAT5L, r0 - mtspr DBAT6U, r0 - mtspr DBAT6L, r0 - mtspr DBAT7U, r0 - mtspr DBAT7L, r0 - mtspr IBAT0U, r0 - mtspr IBAT0L, r0 - mtspr IBAT1U, r0 - mtspr IBAT1L, r0 - mtspr IBAT2U, r0 - mtspr IBAT2L, r0 - mtspr IBAT3U, r0 - mtspr IBAT3L, r0 - mtspr IBAT4U, r0 - mtspr IBAT4L, r0 - mtspr IBAT5U, r0 - mtspr IBAT5L, r0 - mtspr IBAT6U, r0 - mtspr IBAT6L, r0 - mtspr IBAT7U, r0 - mtspr IBAT7L, r0 - SYNC - - /* invalidate all tlb's */ - /* */ - /* From the 603e User Manual: "The 603e provides the ability to */ - /* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */ - /* instruction invalidates the TLB entry indexed by the EA, and */ - /* operates on both the instruction and data TLBs simultaneously*/ - /* invalidating four TLB entries (both sets in each TLB). The */ - /* index corresponds to bits 15-19 of the EA. To invalidate all */ - /* entries within both TLBs, 32 tlbie instructions should be */ - /* issued, incrementing this field by one each time." */ - /* */ - /* "Note that the tlbia instruction is not implemented on the */ - /* 603e." */ - /* */ - /* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */ - /* incrementing by 0x1000 each time. The code below is sort of */ - /* based on code in "flush_tlbs" from arch/ppc/kernel/head.S */ - /* */ - /*--------------------------------------------------------------*/ - - li r3, 32 - mtctr r3 - li r3, 0 -1: tlbie r3 - addi r3, r3, 0x1000 - bdnz 1b - SYNC - - /* Done! */ - /*--------------------------------------------------------------*/ - - blr - -/* Cache functions. - * - * Note: requires that all cache bits in - * HID0 are in the low half word. - */ - .globl icache_enable -icache_enable: - mfspr r3, HID0 - ori r3, r3, HID0_ICE - lis r4, 0 - ori r4, r4, HID0_ILOCK - andc r3, r3, r4 - ori r4, r3, HID0_ICFI - isync - mtspr HID0, r4 /* sets enable and invalidate, clears lock */ - isync - mtspr HID0, r3 /* clears invalidate */ - blr - - .globl icache_disable -icache_disable: - mfspr r3, HID0 - lis r4, 0 - ori r4, r4, HID0_ICE|HID0_ILOCK - andc r3, r3, r4 - ori r4, r3, HID0_ICFI - isync - mtspr HID0, r4 /* sets invalidate, clears enable and lock */ - isync - mtspr HID0, r3 /* clears invalidate */ - blr - - .globl icache_status -icache_status: - mfspr r3, HID0 - rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31 - blr - - .globl dcache_enable -dcache_enable: - mfspr r3, HID0 - ori r3, r3, HID0_DCE - lis r4, 0 - ori r4, r4, HID0_DLOCK - andc r3, r3, r4 - ori r4, r3, HID0_DCI - sync - mtspr HID0, r4 /* sets enable and invalidate, clears lock */ - sync - mtspr HID0, r3 /* clears invalidate */ - blr - - .globl dcache_disable -dcache_disable: - mfspr r3, HID0 - lis r4, 0 - ori r4, r4, HID0_DCE|HID0_DLOCK - andc r3, r3, r4 - ori r4, r3, HID0_DCI - sync - mtspr HID0, r4 /* sets invalidate, clears enable and lock */ - sync - mtspr HID0, r3 /* clears invalidate */ - blr - - .globl dcache_status -dcache_status: - mfspr r3, HID0 - rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31 - blr - - .globl get_svr -get_svr: - mfspr r3, SVR - blr - - .globl get_pvr -get_pvr: - mfspr r3, PVR - blr - -/*------------------------------------------------------------------------------*/ - -/* - * void relocate_code (addr_sp, gd, addr_moni) - * - * This "function" does not return, instead it continues in RAM - * after relocating the monitor code. - * - * r3 = dest - * r4 = src - * r5 = length in bytes - * r6 = cachelinesize - */ - .globl relocate_code -relocate_code: - mr r1, r3 /* Set new stack pointer */ - mr r9, r4 /* Save copy of Global Data pointer */ - mr r10, r5 /* Save copy of Destination Address */ - - GET_GOT - mr r3, r5 /* Destination Address */ - lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */ - ori r4, r4, CONFIG_SYS_MONITOR_BASE@l - lwz r5, GOT(__init_end) - sub r5, r5, r4 - li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */ - - /* - * Fix GOT pointer: - * - * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address - * - * Offset: - */ - sub r15, r10, r4 - - /* First our own GOT */ - add r12, r12, r15 - /* then the one used by the C code */ - add r30, r30, r15 - - /* - * Now relocate code - */ - - cmplw cr1,r3,r4 - addi r0,r5,3 - srwi. r0,r0,2 - beq cr1,4f /* In place copy is not necessary */ - beq 7f /* Protect against 0 count */ - mtctr r0 - bge cr1,2f - - la r8,-4(r4) - la r7,-4(r3) -1: lwzu r0,4(r8) - stwu r0,4(r7) - bdnz 1b - b 4f - -2: slwi r0,r0,2 - add r8,r4,r0 - add r7,r3,r0 -3: lwzu r0,-4(r8) - stwu r0,-4(r7) - bdnz 3b - -/* - * Now flush the cache: note that we must start from a cache aligned - * address. Otherwise we might miss one cache line. - */ -4: cmpwi r6,0 - add r5,r3,r5 - beq 7f /* Always flush prefetch queue in any case */ - subi r0,r6,1 - andc r3,r3,r0 - mfspr r7,HID0 /* don't do dcbst if dcache is disabled */ - rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31 - cmpwi r7,0 - beq 9f - mr r4,r3 -5: dcbst 0,r4 - add r4,r4,r6 - cmplw r4,r5 - blt 5b - sync /* Wait for all dcbst to complete on bus */ -9: mfspr r7,HID0 /* don't do icbi if icache is disabled */ - rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31 - cmpwi r7,0 - beq 7f - mr r4,r3 -6: icbi 0,r4 - add r4,r4,r6 - cmplw r4,r5 - blt 6b -7: sync /* Wait for all icbi to complete on bus */ - isync - -/* - * We are done. Do not return, instead branch to second part of board - * initialization, now running from RAM. - */ - - addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET - mtlr r0 - blr - -in_ram: - - /* - * Relocation Function, r12 point to got2+0x8000 - * - * Adjust got2 pointers, no need to check for 0, this code - * already puts a few entries in the table. - */ - li r0,__got2_entries@sectoff@l - la r3,GOT(_GOT2_TABLE_) - lwz r11,GOT(_GOT2_TABLE_) - mtctr r0 - sub r11,r3,r11 - addi r3,r3,-4 -1: lwzu r0,4(r3) - cmpwi r0,0 - beq- 2f - add r0,r0,r11 - stw r0,0(r3) -2: bdnz 1b - - /* - * Now adjust the fixups and the pointers to the fixups - * in case we need to move ourselves again. - */ - li r0,__fixup_entries@sectoff@l - lwz r3,GOT(_FIXUP_TABLE_) - cmpwi r0,0 - mtctr r0 - addi r3,r3,-4 - beq 4f -3: lwzu r4,4(r3) - lwzux r0,r4,r11 - add r0,r0,r11 - stw r10,0(r3) - stw r0,0(r4) - bdnz 3b -4: -clear_bss: - /* - * Now clear BSS segment - */ - lwz r3,GOT(__bss_start) - lwz r4,GOT(_end) - - cmplw 0, r3, r4 - beq 6f - - li r0, 0 -5: - stw r0, 0(r3) - addi r3, r3, 4 - cmplw 0, r3, r4 - bne 5b -6: - - mr r3, r9 /* Global Data pointer */ - mr r4, r10 /* Destination Address */ - bl board_init_r - - /* - * Copy exception vector code to low memory - * - * r3: dest_addr - * r7: source address, r8: end address, r9: target address - */ - .globl trap_init -trap_init: - mflr r4 /* save link register */ - GET_GOT - lwz r7, GOT(_start) - lwz r8, GOT(_end_of_vectors) - - li r9, 0x100 /* reset vector always at 0x100 */ - - cmplw 0, r7, r8 - bgelr /* return if r7>=r8 - just in case */ -1: - lwz r0, 0(r7) - stw r0, 0(r9) - addi r7, r7, 4 - addi r9, r9, 4 - cmplw 0, r7, r8 - bne 1b - - /* - * relocate `hdlr' and `int_return' entries - */ - li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET - li r8, Alignment - _start + EXC_OFF_SYS_RESET -2: - bl trap_reloc - addi r7, r7, 0x100 /* next exception vector */ - cmplw 0, r7, r8 - blt 2b - - li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET - bl trap_reloc - - li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET - bl trap_reloc - - li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET - li r8, SystemCall - _start + EXC_OFF_SYS_RESET -3: - bl trap_reloc - addi r7, r7, 0x100 /* next exception vector */ - cmplw 0, r7, r8 - blt 3b - - li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET - li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET -4: - bl trap_reloc - addi r7, r7, 0x100 /* next exception vector */ - cmplw 0, r7, r8 - blt 4b - - mfmsr r3 /* now that the vectors have */ - lis r7, MSR_IP@h /* relocated into low memory */ - ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */ - andc r3, r3, r7 /* (if it was on) */ - SYNC /* Some chip revs need this... */ - mtmsr r3 - SYNC - - mtlr r4 /* restore link register */ - blr diff --git a/cpu/mpc5xxx/traps.c b/cpu/mpc5xxx/traps.c deleted file mode 100644 index 934a2f2..0000000 --- a/cpu/mpc5xxx/traps.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * linux/arch/ppc/kernel/traps.c - * - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * - * Modified by Cort Dougan (cort@cs.nmt.edu) - * and Paul Mackerras (paulus@cs.anu.edu.au) - * fixed Machine Check Reasons by Reinhard Meyer (r.meyer@emk-elektronik.de) - * - * (C) Copyright 2000-2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * This file handles the architecture-dependent parts of hardware exceptions - */ - -#include <common.h> -#include <command.h> -#include <kgdb.h> -#include <asm/processor.h> - -/* Returns 0 if exception not found and fixup otherwise. */ -extern unsigned long search_exception_table(unsigned long); - -/* THIS NEEDS CHANGING to use the board info structure. -*/ -#define END_OF_MEM 0x02000000 - -/* - * Trap & Exception support - */ - -void -print_backtrace(unsigned long *sp) -{ - int cnt = 0; - unsigned long i; - - printf("Call backtrace: "); - while (sp) { - if ((uint)sp > END_OF_MEM) - break; - - i = sp[1]; - if (cnt++ % 7 == 0) - printf("\n"); - printf("%08lX ", i); - if (cnt > 32) break; - sp = (unsigned long *)*sp; - } - printf("\n"); -} - -void show_regs(struct pt_regs * regs) -{ - int i; - - printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n", - regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar); - printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n", - regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0, - regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0, - regs->msr&MSR_IR ? 1 : 0, - regs->msr&MSR_DR ? 1 : 0); - - printf("\n"); - for (i = 0; i < 32; i++) { - if ((i % 8) == 0) - { - printf("GPR%02d: ", i); - } - - printf("%08lX ", regs->gpr[i]); - if ((i % 8) == 7) - { - printf("\n"); - } - } -} - - -void -_exception(int signr, struct pt_regs *regs) -{ - show_regs(regs); - print_backtrace((unsigned long *)regs->gpr[1]); - panic("Exception in kernel pc %lx signal %d",regs->nip,signr); -} - -void -MachineCheckException(struct pt_regs *regs) -{ - unsigned long fixup; - - /* Probing PCI using config cycles cause this exception - * when a device is not present. Catch it and return to - * the PCI exception handler. - */ - if ((fixup = search_exception_table(regs->nip)) != 0) { - regs->nip = fixup; - return; - } - -#if defined(CONFIG_CMD_KGDB) - if (debugger_exception_handler && (*debugger_exception_handler)(regs)) - return; -#endif - - printf("Machine check in kernel mode.\n"); - printf("Caused by (from msr): "); - printf("regs %p ",regs); - /* refer to 603e Manual (MPC603EUM/AD), chapter 4.5.2.1 */ - switch( regs->msr & 0x000F0000) - { - case (0x80000000>>12) : - printf("Machine check signal - probably due to mm fault\n" - "with mmu off\n"); - break; - case (0x80000000>>13) : - printf("Transfer error ack signal\n"); - break; - case (0x80000000>>14) : - printf("Data parity signal\n"); - break; - case (0x80000000>>15) : - printf("Address parity signal\n"); - break; - default: - printf("Unknown values in msr\n"); - } - show_regs(regs); - print_backtrace((unsigned long *)regs->gpr[1]); - panic("machine check"); -} - -void -AlignmentException(struct pt_regs *regs) -{ -#if defined(CONFIG_CMD_KGDB) - if (debugger_exception_handler && (*debugger_exception_handler)(regs)) - return; -#endif - show_regs(regs); - print_backtrace((unsigned long *)regs->gpr[1]); - panic("Alignment Exception"); -} - -void -ProgramCheckException(struct pt_regs *regs) -{ -#if defined(CONFIG_CMD_KGDB) - if (debugger_exception_handler && (*debugger_exception_handler)(regs)) - return; -#endif - show_regs(regs); - print_backtrace((unsigned long *)regs->gpr[1]); - panic("Program Check Exception"); -} - -void -SoftEmuException(struct pt_regs *regs) -{ -#if defined(CONFIG_CMD_KGDB) - if (debugger_exception_handler && (*debugger_exception_handler)(regs)) - return; -#endif - show_regs(regs); - print_backtrace((unsigned long *)regs->gpr[1]); - panic("Software Emulation Exception"); -} - - -void -UnknownException(struct pt_regs *regs) -{ -#if defined(CONFIG_CMD_KGDB) - if (debugger_exception_handler && (*debugger_exception_handler)(regs)) - return; -#endif - printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", - regs->nip, regs->msr, regs->trap); - _exception(0, regs); -} - -#if defined(CONFIG_CMD_BEDBUG) -extern void do_bedbug_breakpoint(struct pt_regs *); -#endif - -void -DebugException(struct pt_regs *regs) -{ - - printf("Debugger trap at @ %lx\n", regs->nip ); - show_regs(regs); -#if defined(CONFIG_CMD_BEDBUG) - do_bedbug_breakpoint( regs ); -#endif -} - -/* Probe an address by reading. If not present, return -1, otherwise - * return 0. - */ -int -addr_probe(uint *addr) -{ -#if 0 - int retval; - - __asm__ __volatile__( \ - "1: lwz %0,0(%1)\n" \ - " eieio\n" \ - " li %0,0\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3: li %0,-1\n" \ - " b 2b\n" \ - ".section __ex_table,\"a\"\n" \ - " .align 2\n" \ - " .long 1b,3b\n" \ - ".text" \ - : "=r" (retval) : "r"(addr)); - - return (retval); -#endif - return 0; -} diff --git a/cpu/mpc5xxx/u-boot-customlayout.lds b/cpu/mpc5xxx/u-boot-customlayout.lds deleted file mode 100644 index 6c80139..0000000 --- a/cpu/mpc5xxx/u-boot-customlayout.lds +++ /dev/null @@ -1,133 +0,0 @@ -/* - * (C) Copyright 2003-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_ARCH(powerpc) -/* Do we need any of these for elf? - __DYNAMIC = 0; */ -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = + SIZEOF_HEADERS; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .rel.text : { *(.rel.text) } - .rela.text : { *(.rela.text) } - .rel.data : { *(.rel.data) } - .rela.data : { *(.rela.data) } - .rel.rodata : { *(.rel.rodata) } - .rela.rodata : { *(.rela.rodata) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.bss : { *(.rel.bss) } - .rela.bss : { *(.rela.bss) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : { *(.init) } - .plt : { *(.plt) } - .text : - { - /* WARNING - the following is hand-optimized to fit within */ - /* the sector layout of our flash chips! XXX FIXME XXX */ - - cpu/mpc5xxx/start.o (.text) - cpu/mpc5xxx/traps.o (.text) - lib/crc32.o (.text) - arch/ppc/lib/cache.o (.text) - arch/ppc/lib/time.o (.text) - - . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.ppcenv) - - *(.text) - *(.got1) - . = ALIGN(16); - *(.eh_frame) - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - .fini : { *(.fini) } =0 - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } - - /* Read-write section, merged into data segment: */ - . = (. + 0x0FFF) & 0xFFFFF000; - _erotext = .; - PROVIDE (erotext = .); - .reloc : - { - *(.got) - _GOT2_TABLE_ = .; - *(.got2) - _FIXUP_TABLE_ = .; - *(.fixup) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; - __fixup_entries = (. - _FIXUP_TABLE_) >> 2; - - .data : - { - *(.data) - *(.data1) - *(.sdata) - *(.sdata2) - *(.dynamic) - CONSTRUCTORS - } - _edata = .; - PROVIDE (edata = .); - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(4096); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(4096); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - *(.sbss) *(.scommon) - *(.dynbss) - *(.bss) - *(COMMON) - . = ALIGN(4); - } - _end = . ; - PROVIDE (end = .); -} diff --git a/cpu/mpc5xxx/u-boot.lds b/cpu/mpc5xxx/u-boot.lds deleted file mode 100644 index 7fe1e95..0000000 --- a/cpu/mpc5xxx/u-boot.lds +++ /dev/null @@ -1,122 +0,0 @@ -/* - * (C) Copyright 2003-2007 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_ARCH(powerpc) -/* Do we need any of these for elf? - __DYNAMIC = 0; */ -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = + SIZEOF_HEADERS; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .rel.text : { *(.rel.text) } - .rela.text : { *(.rela.text) } - .rel.data : { *(.rel.data) } - .rela.data : { *(.rela.data) } - .rel.rodata : { *(.rel.rodata) } - .rela.rodata : { *(.rela.rodata) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.bss : { *(.rel.bss) } - .rela.bss : { *(.rela.bss) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : { *(.init) } - .plt : { *(.plt) } - .text : - { - cpu/mpc5xxx/start.o (.text) - *(.text) - *(.got1) - . = ALIGN(16); - *(.eh_frame) - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - .fini : { *(.fini) } =0 - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } - - /* Read-write section, merged into data segment: */ - . = (. + 0x0FFF) & 0xFFFFF000; - _erotext = .; - PROVIDE (erotext = .); - .reloc : - { - *(.got) - _GOT2_TABLE_ = .; - *(.got2) - _FIXUP_TABLE_ = .; - *(.fixup) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; - __fixup_entries = (. - _FIXUP_TABLE_) >> 2; - - .data : - { - *(.data) - *(.data1) - *(.sdata) - *(.sdata2) - *(.dynamic) - CONSTRUCTORS - } - _edata = .; - PROVIDE (edata = .); - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(4096); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(4096); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - *(.sbss) *(.scommon) - *(.dynbss) - *(.bss) - *(COMMON) - . = ALIGN(4); - } - _end = . ; - PROVIDE (end = .); -} diff --git a/cpu/mpc5xxx/usb.c b/cpu/mpc5xxx/usb.c deleted file mode 100644 index bec7da3..0000000 --- a/cpu/mpc5xxx/usb.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * (C) Copyright 2007 - * Markus Klotzbuecher, DENX Software Engineering <mk@denx.de> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> - -#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) - -#include <mpc5xxx.h> - -int usb_cpu_init(void) -{ - /* Set the USB Clock */ - *(vu_long *)MPC5XXX_CDM_48_FDC = CONFIG_USB_CLOCK; - -#ifdef CONFIG_PSC3_USB /* USB is using the alternate configuration */ - /* remove all PSC3 USB bits first before ORing in ours */ - *(vu_long *)MPC5XXX_GPS_PORT_CONFIG &= ~0x00804f00; -#else - /* remove all USB bits first before ORing in ours */ - *(vu_long *)MPC5XXX_GPS_PORT_CONFIG &= ~0x00807000; -#endif - /* Activate USB port */ - *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= CONFIG_USB_CONFIG; - - return 0; -} - -int usb_cpu_stop(void) -{ - return 0; -} - -int usb_cpu_init_fail(void) -{ - return 0; -} - -#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) */ diff --git a/cpu/mpc5xxx/usb_ohci.c b/cpu/mpc5xxx/usb_ohci.c deleted file mode 100644 index 7976e4d..0000000 --- a/cpu/mpc5xxx/usb_ohci.c +++ /dev/null @@ -1,1646 +0,0 @@ -/* - * URB OHCI HCD (Host Controller Driver) for USB on the MPC5200. - * - * (C) Copyright 2003-2004 - * Gary Jennejohn, DENX Software Engineering <garyj@denx.de> - * - * (C) Copyright 2004 - * Pierre Aubert, Staubli Faverges <p.aubert@staubli.com> - * - * Note: Much of this code has been derived from Linux 2.4 - * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> - * (C) Copyright 2000-2002 David Brownell - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ -/* - * IMPORTANT NOTES - * 1 - this driver is intended for use with USB Mass Storage Devices - * (BBB) ONLY. There is NO support for Interrupt or Isochronous pipes! - */ - -#include <common.h> - -#ifdef CONFIG_USB_OHCI - -#include <malloc.h> -#include <usb.h> -#include "usb_ohci.h" - -#include <mpc5xxx.h> - -#define OHCI_USE_NPS /* force NoPowerSwitching mode */ -#undef OHCI_VERBOSE_DEBUG /* not always helpful */ -#undef DEBUG -#undef SHOW_INFO -#undef OHCI_FILL_TRACE - -/* For initializing controller (mask in an HCFS mode too) */ -#define OHCI_CONTROL_INIT \ - (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE - -#define readl(a) (*((volatile u32 *)(a))) -#define writel(a, b) (*((volatile u32 *)(b)) = ((volatile u32)a)) - -#define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) - -#ifdef DEBUG -#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg) -#else -#define dbg(format, arg...) do {} while(0) -#endif /* DEBUG */ -#define err(format, arg...) printf("ERROR: " format "\n", ## arg) -#ifdef SHOW_INFO -#define info(format, arg...) printf("INFO: " format "\n", ## arg) -#else -#define info(format, arg...) do {} while(0) -#endif - -#define m16_swap(x) swap_16(x) -#define m32_swap(x) swap_32(x) - -#define ohci_cpu_to_le16(x) (x) -#define ohci_cpu_to_le32(x) (x) - -/* global ohci_t */ -static ohci_t gohci; -/* this must be aligned to a 256 byte boundary */ -struct ohci_hcca ghcca[1]; -/* a pointer to the aligned storage */ -struct ohci_hcca *phcca; -/* this allocates EDs for all possible endpoints */ -struct ohci_device ohci_dev; -/* urb_priv */ -urb_priv_t urb_priv; -/* RHSC flag */ -int got_rhsc; -/* device which was disconnected */ -struct usb_device *devgone; -/* flag guarding URB transation */ -int urb_finished = 0; - -/*-------------------------------------------------------------------------*/ - -/* AMD-756 (D2 rev) reports corrupt register contents in some cases. - * The erratum (#4) description is incorrect. AMD's workaround waits - * till some bits (mostly reserved) are clear; ok for all revs. - */ -#define OHCI_QUIRK_AMD756 0xabcd -#define read_roothub(hc, register, mask) ({ \ - u32 temp = readl (&hc->regs->roothub.register); \ - if (hc->flags & OHCI_QUIRK_AMD756) \ - while (temp & mask) \ - temp = readl (&hc->regs->roothub.register); \ - temp; }) - -static u32 roothub_a (struct ohci *hc) - { return read_roothub (hc, a, 0xfc0fe000); } -static inline u32 roothub_b (struct ohci *hc) - { return readl (&hc->regs->roothub.b); } -static inline u32 roothub_status (struct ohci *hc) - { return readl (&hc->regs->roothub.status); } -static u32 roothub_portstatus (struct ohci *hc, int i) - { return read_roothub (hc, portstatus [i], 0xffe0fce0); } - - -/* forward declaration */ -static int hc_interrupt (void); -static void -td_submit_job (struct usb_device * dev, unsigned long pipe, void * buffer, - int transfer_len, struct devrequest * setup, urb_priv_t * urb, int interval); - -/*-------------------------------------------------------------------------* - * URB support functions - *-------------------------------------------------------------------------*/ - -/* free HCD-private data associated with this URB */ - -static void urb_free_priv (urb_priv_t * urb) -{ - int i; - int last; - struct td * td; - - last = urb->length - 1; - if (last >= 0) { - for (i = 0; i <= last; i++) { - td = urb->td[i]; - if (td) { - td->usb_dev = NULL; - urb->td[i] = NULL; - } - } - } -} - -/*-------------------------------------------------------------------------*/ - -#ifdef DEBUG -static int sohci_get_current_frame_number (struct usb_device * dev); - -/* debug| print the main components of an URB - * small: 0) header + data packets 1) just header */ - -static void pkt_print (struct usb_device * dev, unsigned long pipe, void * buffer, - int transfer_len, struct devrequest * setup, char * str, int small) -{ - urb_priv_t * purb = &urb_priv; - - dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx", - str, - sohci_get_current_frame_number (dev), - usb_pipedevice (pipe), - usb_pipeendpoint (pipe), - usb_pipeout (pipe)? 'O': 'I', - usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"): - (usb_pipecontrol (pipe)? "CTRL": "BULK"), - purb->actual_length, - transfer_len, dev->status); -#ifdef OHCI_VERBOSE_DEBUG - if (!small) { - int i, len; - - if (usb_pipecontrol (pipe)) { - printf (__FILE__ ": cmd(8):"); - for (i = 0; i < 8 ; i++) - printf (" %02x", ((__u8 *) setup) [i]); - printf ("\n"); - } - if (transfer_len > 0 && buffer) { - printf (__FILE__ ": data(%d/%d):", - purb->actual_length, - transfer_len); - len = usb_pipeout (pipe)? - transfer_len: purb->actual_length; - for (i = 0; i < 16 && i < len; i++) - printf (" %02x", ((__u8 *) buffer) [i]); - printf ("%s\n", i < len? "...": ""); - } - } -#endif -} - -/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/ -void ep_print_int_eds (ohci_t *ohci, char * str) { - int i, j; - __u32 * ed_p; - for (i= 0; i < 32; i++) { - j = 5; - ed_p = &(ohci->hcca->int_table [i]); - if (*ed_p == 0) - continue; - printf (__FILE__ ": %s branch int %2d(%2x):", str, i, i); - while (*ed_p != 0 && j--) { - ed_t *ed = (ed_t *)ohci_cpu_to_le32(ed_p); - printf (" ed: %4x;", ed->hwINFO); - ed_p = &ed->hwNextED; - } - printf ("\n"); - } -} - -static void ohci_dump_intr_mask (char *label, __u32 mask) -{ - dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s", - label, - mask, - (mask & OHCI_INTR_MIE) ? " MIE" : "", - (mask & OHCI_INTR_OC) ? " OC" : "", - (mask & OHCI_INTR_RHSC) ? " RHSC" : "", - (mask & OHCI_INTR_FNO) ? " FNO" : "", - (mask & OHCI_INTR_UE) ? " UE" : "", - (mask & OHCI_INTR_RD) ? " RD" : "", - (mask & OHCI_INTR_SF) ? " SF" : "", - (mask & OHCI_INTR_WDH) ? " WDH" : "", - (mask & OHCI_INTR_SO) ? " SO" : "" - ); -} - -static void maybe_print_eds (char *label, __u32 value) -{ - ed_t *edp = (ed_t *)value; - - if (value) { - dbg ("%s %08x", label, value); - dbg ("%08x", edp->hwINFO); - dbg ("%08x", edp->hwTailP); - dbg ("%08x", edp->hwHeadP); - dbg ("%08x", edp->hwNextED); - } -} - -static char * hcfs2string (int state) -{ - switch (state) { - case OHCI_USB_RESET: return "reset"; - case OHCI_USB_RESUME: return "resume"; - case OHCI_USB_OPER: return "operational"; - case OHCI_USB_SUSPEND: return "suspend"; - } - return "?"; -} - -/* dump control and status registers */ -static void ohci_dump_status (ohci_t *controller) -{ - struct ohci_regs *regs = controller->regs; - __u32 temp; - - temp = readl (®s->revision) & 0xff; - if (temp != 0x10) - dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f)); - - temp = readl (®s->control); - dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp, - (temp & OHCI_CTRL_RWE) ? " RWE" : "", - (temp & OHCI_CTRL_RWC) ? " RWC" : "", - (temp & OHCI_CTRL_IR) ? " IR" : "", - hcfs2string (temp & OHCI_CTRL_HCFS), - (temp & OHCI_CTRL_BLE) ? " BLE" : "", - (temp & OHCI_CTRL_CLE) ? " CLE" : "", - (temp & OHCI_CTRL_IE) ? " IE" : "", - (temp & OHCI_CTRL_PLE) ? " PLE" : "", - temp & OHCI_CTRL_CBSR - ); - - temp = readl (®s->cmdstatus); - dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp, - (temp & OHCI_SOC) >> 16, - (temp & OHCI_OCR) ? " OCR" : "", - (temp & OHCI_BLF) ? " BLF" : "", - (temp & OHCI_CLF) ? " CLF" : "", - (temp & OHCI_HCR) ? " HCR" : "" - ); - - ohci_dump_intr_mask ("intrstatus", readl (®s->intrstatus)); - ohci_dump_intr_mask ("intrenable", readl (®s->intrenable)); - - maybe_print_eds ("ed_periodcurrent", readl (®s->ed_periodcurrent)); - - maybe_print_eds ("ed_controlhead", readl (®s->ed_controlhead)); - maybe_print_eds ("ed_controlcurrent", readl (®s->ed_controlcurrent)); - - maybe_print_eds ("ed_bulkhead", readl (®s->ed_bulkhead)); - maybe_print_eds ("ed_bulkcurrent", readl (®s->ed_bulkcurrent)); - - maybe_print_eds ("donehead", readl (®s->donehead)); -} - -static void ohci_dump_roothub (ohci_t *controller, int verbose) -{ - __u32 temp, ndp, i; - - temp = roothub_a (controller); - ndp = (temp & RH_A_NDP); - - if (verbose) { - dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp, - ((temp & RH_A_POTPGT) >> 24) & 0xff, - (temp & RH_A_NOCP) ? " NOCP" : "", - (temp & RH_A_OCPM) ? " OCPM" : "", - (temp & RH_A_DT) ? " DT" : "", - (temp & RH_A_NPS) ? " NPS" : "", - (temp & RH_A_PSM) ? " PSM" : "", - ndp - ); - temp = roothub_b (controller); - dbg ("roothub.b: %08x PPCM=%04x DR=%04x", - temp, - (temp & RH_B_PPCM) >> 16, - (temp & RH_B_DR) - ); - temp = roothub_status (controller); - dbg ("roothub.status: %08x%s%s%s%s%s%s", - temp, - (temp & RH_HS_CRWE) ? " CRWE" : "", - (temp & RH_HS_OCIC) ? " OCIC" : "", - (temp & RH_HS_LPSC) ? " LPSC" : "", - (temp & RH_HS_DRWE) ? " DRWE" : "", - (temp & RH_HS_OCI) ? " OCI" : "", - (temp & RH_HS_LPS) ? " LPS" : "" - ); - } - - for (i = 0; i < ndp; i++) { - temp = roothub_portstatus (controller, i); - dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s", - i, - temp, - (temp & RH_PS_PRSC) ? " PRSC" : "", - (temp & RH_PS_OCIC) ? " OCIC" : "", - (temp & RH_PS_PSSC) ? " PSSC" : "", - (temp & RH_PS_PESC) ? " PESC" : "", - (temp & RH_PS_CSC) ? " CSC" : "", - - (temp & RH_PS_LSDA) ? " LSDA" : "", - (temp & RH_PS_PPS) ? " PPS" : "", - (temp & RH_PS_PRS) ? " PRS" : "", - (temp & RH_PS_POCI) ? " POCI" : "", - (temp & RH_PS_PSS) ? " PSS" : "", - - (temp & RH_PS_PES) ? " PES" : "", - (temp & RH_PS_CCS) ? " CCS" : "" - ); - } -} - -static void ohci_dump (ohci_t *controller, int verbose) -{ - dbg ("OHCI controller usb-%s state", controller->slot_name); - - /* dumps some of the state we know about */ - ohci_dump_status (controller); - if (verbose) - ep_print_int_eds (controller, "hcca"); - dbg ("hcca frame #%04x", controller->hcca->frame_no); - ohci_dump_roothub (controller, 1); -} - - -#endif /* DEBUG */ - -/*-------------------------------------------------------------------------* - * Interface functions (URB) - *-------------------------------------------------------------------------*/ - -/* get a transfer request */ - -int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *setup, int interval) -{ - ohci_t *ohci; - ed_t * ed; - urb_priv_t *purb_priv; - int i, size = 0; - - ohci = &gohci; - - /* when controller's hung, permit only roothub cleanup attempts - * such as powering down ports */ - if (ohci->disabled) { - err("sohci_submit_job: EPIPE"); - return -1; - } - - /* if we have an unfinished URB from previous transaction let's - * fail and scream as quickly as possible so as not to corrupt - * further communication */ - if (!urb_finished) { - err("sohci_submit_job: URB NOT FINISHED"); - return -1; - } - /* we're about to begin a new transaction here so mark the URB unfinished */ - urb_finished = 0; - - /* every endpoint has a ed, locate and fill it */ - if (!(ed = ep_add_ed (dev, pipe))) { - err("sohci_submit_job: ENOMEM"); - return -1; - } - - /* for the private part of the URB we need the number of TDs (size) */ - switch (usb_pipetype (pipe)) { - case PIPE_BULK: /* one TD for every 4096 Byte */ - size = (transfer_len - 1) / 4096 + 1; - break; - case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */ - size = (transfer_len == 0)? 2: - (transfer_len - 1) / 4096 + 3; - break; - } - - if (size >= (N_URB_TD - 1)) { - err("need %d TDs, only have %d", size, N_URB_TD); - return -1; - } - purb_priv = &urb_priv; - purb_priv->pipe = pipe; - - /* fill the private part of the URB */ - purb_priv->length = size; - purb_priv->ed = ed; - purb_priv->actual_length = 0; - - /* allocate the TDs */ - /* note that td[0] was allocated in ep_add_ed */ - for (i = 0; i < size; i++) { - purb_priv->td[i] = td_alloc (dev); - if (!purb_priv->td[i]) { - purb_priv->length = i; - urb_free_priv (purb_priv); - err("sohci_submit_job: ENOMEM"); - return -1; - } - } - - if (ed->state == ED_NEW || (ed->state & ED_DEL)) { - urb_free_priv (purb_priv); - err("sohci_submit_job: EINVAL"); - return -1; - } - - /* link the ed into a chain if is not already */ - if (ed->state != ED_OPER) - ep_link (ohci, ed); - - /* fill the TDs and link it to the ed */ - td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv, interval); - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -#ifdef DEBUG -/* tell us the current USB frame number */ - -static int sohci_get_current_frame_number (struct usb_device *usb_dev) -{ - ohci_t *ohci = &gohci; - - return ohci_cpu_to_le16 (ohci->hcca->frame_no); -} -#endif - -/*-------------------------------------------------------------------------* - * ED handling functions - *-------------------------------------------------------------------------*/ - -/* link an ed into one of the HC chains */ - -static int ep_link (ohci_t *ohci, ed_t *edi) -{ - volatile ed_t *ed = edi; - - ed->state = ED_OPER; - - switch (ed->type) { - case PIPE_CONTROL: - ed->hwNextED = 0; - if (ohci->ed_controltail == NULL) { - writel (ed, &ohci->regs->ed_controlhead); - } else { - ohci->ed_controltail->hwNextED = ohci_cpu_to_le32 ((unsigned long)ed); - } - ed->ed_prev = ohci->ed_controltail; - if (!ohci->ed_controltail && !ohci->ed_rm_list[0] && - !ohci->ed_rm_list[1] && !ohci->sleeping) { - ohci->hc_control |= OHCI_CTRL_CLE; - writel (ohci->hc_control, &ohci->regs->control); - } - ohci->ed_controltail = edi; - break; - - case PIPE_BULK: - ed->hwNextED = 0; - if (ohci->ed_bulktail == NULL) { - writel (ed, &ohci->regs->ed_bulkhead); - } else { - ohci->ed_bulktail->hwNextED = ohci_cpu_to_le32 ((unsigned long)ed); - } - ed->ed_prev = ohci->ed_bulktail; - if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] && - !ohci->ed_rm_list[1] && !ohci->sleeping) { - ohci->hc_control |= OHCI_CTRL_BLE; - writel (ohci->hc_control, &ohci->regs->control); - } - ohci->ed_bulktail = edi; - break; - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* unlink an ed from one of the HC chains. - * just the link to the ed is unlinked. - * the link from the ed still points to another operational ed or 0 - * so the HC can eventually finish the processing of the unlinked ed */ - -static int ep_unlink (ohci_t *ohci, ed_t *edi) -{ - volatile ed_t *ed = edi; - - ed->hwINFO |= ohci_cpu_to_le32 (OHCI_ED_SKIP); - - switch (ed->type) { - case PIPE_CONTROL: - if (ed->ed_prev == NULL) { - if (!ed->hwNextED) { - ohci->hc_control &= ~OHCI_CTRL_CLE; - writel (ohci->hc_control, &ohci->regs->control); - } - writel (ohci_cpu_to_le32 (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_controlhead); - } else { - ed->ed_prev->hwNextED = ed->hwNextED; - } - if (ohci->ed_controltail == ed) { - ohci->ed_controltail = ed->ed_prev; - } else { - ((ed_t *)ohci_cpu_to_le32 (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev; - } - break; - - case PIPE_BULK: - if (ed->ed_prev == NULL) { - if (!ed->hwNextED) { - ohci->hc_control &= ~OHCI_CTRL_BLE; - writel (ohci->hc_control, &ohci->regs->control); - } - writel (ohci_cpu_to_le32 (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_bulkhead); - } else { - ed->ed_prev->hwNextED = ed->hwNextED; - } - if (ohci->ed_bulktail == ed) { - ohci->ed_bulktail = ed->ed_prev; - } else { - ((ed_t *)ohci_cpu_to_le32 (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev; - } - break; - } - ed->state = ED_UNLINK; - return 0; -} - - -/*-------------------------------------------------------------------------*/ - -/* add/reinit an endpoint; this should be done once at the usb_set_configuration command, - * but the USB stack is a little bit stateless so we do it at every transaction - * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK - * in all other cases the state is left unchanged - * the ed info fields are setted anyway even though most of them should not change */ - -static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe) -{ - td_t *td; - ed_t *ed_ret; - volatile ed_t *ed; - - ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint (pipe) << 1) | - (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))]; - - if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) { - err("ep_add_ed: pending delete"); - /* pending delete request */ - return NULL; - } - - if (ed->state == ED_NEW) { - ed->hwINFO = ohci_cpu_to_le32 (OHCI_ED_SKIP); /* skip ed */ - /* dummy td; end of td list for ed */ - td = td_alloc (usb_dev); - ed->hwTailP = ohci_cpu_to_le32 ((unsigned long)td); - ed->hwHeadP = ed->hwTailP; - ed->state = ED_UNLINK; - ed->type = usb_pipetype (pipe); - ohci_dev.ed_cnt++; - } - - ed->hwINFO = ohci_cpu_to_le32 (usb_pipedevice (pipe) - | usb_pipeendpoint (pipe) << 7 - | (usb_pipeisoc (pipe)? 0x8000: 0) - | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000)) - | usb_pipeslow (pipe) << 13 - | usb_maxpacket (usb_dev, pipe) << 16); - - return ed_ret; -} - -/*-------------------------------------------------------------------------* - * TD handling functions - *-------------------------------------------------------------------------*/ - -/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */ - -static void td_fill (ohci_t *ohci, unsigned int info, - void *data, int len, - struct usb_device *dev, int index, urb_priv_t *urb_priv) -{ - volatile td_t *td, *td_pt; -#ifdef OHCI_FILL_TRACE - int i; -#endif - - if (index > urb_priv->length) { - err("index > length"); - return; - } - /* use this td as the next dummy */ - td_pt = urb_priv->td [index]; - td_pt->hwNextTD = 0; - - /* fill the old dummy TD */ - td = urb_priv->td [index] = (td_t *)(ohci_cpu_to_le32 (urb_priv->ed->hwTailP) & ~0xf); - - td->ed = urb_priv->ed; - td->next_dl_td = NULL; - td->index = index; - td->data = (__u32)data; -#ifdef OHCI_FILL_TRACE - if (usb_pipebulk(urb_priv->pipe) && usb_pipeout(urb_priv->pipe)) { - for (i = 0; i < len; i++) - printf("td->data[%d] %#2x ",i, ((unsigned char *)td->data)[i]); - printf("\n"); - } -#endif - if (!len) - data = 0; - - td->hwINFO = ohci_cpu_to_le32 (info); - td->hwCBP = ohci_cpu_to_le32 ((unsigned long)data); - if (data) - td->hwBE = ohci_cpu_to_le32 ((unsigned long)(data + len - 1)); - else - td->hwBE = 0; - td->hwNextTD = ohci_cpu_to_le32 ((unsigned long)td_pt); - - /* append to queue */ - td->ed->hwTailP = td->hwNextTD; -} - -/*-------------------------------------------------------------------------*/ - -/* prepare all TDs of a transfer */ -static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *setup, urb_priv_t *urb, int interval) -{ - ohci_t *ohci = &gohci; - int data_len = transfer_len; - void *data; - int cnt = 0; - __u32 info = 0; - unsigned int toggle = 0; - - /* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */ - if(usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) { - toggle = TD_T_TOGGLE; - } else { - toggle = TD_T_DATA0; - usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 1); - } - urb->td_cnt = 0; - if (data_len) - data = buffer; - else - data = 0; - - switch (usb_pipetype (pipe)) { - case PIPE_BULK: - info = usb_pipeout (pipe)? - TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ; - while(data_len > 4096) { - td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, dev, cnt, urb); - data += 4096; data_len -= 4096; cnt++; - } - info = usb_pipeout (pipe)? - TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ; - td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, dev, cnt, urb); - cnt++; - - if (!ohci->sleeping) - writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */ - break; - - case PIPE_CONTROL: - info = TD_CC | TD_DP_SETUP | TD_T_DATA0; - td_fill (ohci, info, setup, 8, dev, cnt++, urb); - if (data_len > 0) { - info = usb_pipeout (pipe)? - TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1; - /* NOTE: mishandles transfers >8K, some >4K */ - td_fill (ohci, info, data, data_len, dev, cnt++, urb); - } - info = usb_pipeout (pipe)? - TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1; - td_fill (ohci, info, data, 0, dev, cnt++, urb); - if (!ohci->sleeping) - writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */ - break; - } - if (urb->length != cnt) - dbg("TD LENGTH %d != CNT %d", urb->length, cnt); -} - -/*-------------------------------------------------------------------------* - * Done List handling functions - *-------------------------------------------------------------------------*/ - - -/* calculate the transfer length and update the urb */ - -static void dl_transfer_length(td_t * td) -{ - __u32 tdINFO, tdBE, tdCBP; - urb_priv_t *lurb_priv = &urb_priv; - - tdINFO = ohci_cpu_to_le32 (td->hwINFO); - tdBE = ohci_cpu_to_le32 (td->hwBE); - tdCBP = ohci_cpu_to_le32 (td->hwCBP); - - - if (!(usb_pipecontrol(lurb_priv->pipe) && - ((td->index == 0) || (td->index == lurb_priv->length - 1)))) { - if (tdBE != 0) { - if (td->hwCBP == 0) - lurb_priv->actual_length += tdBE - td->data + 1; - else - lurb_priv->actual_length += tdCBP - td->data; - } - } -} - -/*-------------------------------------------------------------------------*/ - -/* replies to the request have to be on a FIFO basis so - * we reverse the reversed done-list */ - -static td_t * dl_reverse_done_list (ohci_t *ohci) -{ - __u32 td_list_hc; - td_t *td_rev = NULL; - td_t *td_list = NULL; - urb_priv_t *lurb_priv = NULL; - - td_list_hc = ohci_cpu_to_le32 (ohci->hcca->done_head) & 0xfffffff0; - ohci->hcca->done_head = 0; - - while (td_list_hc) { - td_list = (td_t *)td_list_hc; - - if (TD_CC_GET (ohci_cpu_to_le32 (td_list->hwINFO))) { - lurb_priv = &urb_priv; - dbg(" USB-error/status: %x : %p", - TD_CC_GET (ohci_cpu_to_le32 (td_list->hwINFO)), td_list); - if (td_list->ed->hwHeadP & ohci_cpu_to_le32 (0x1)) { - if (lurb_priv && ((td_list->index + 1) < lurb_priv->length)) { - td_list->ed->hwHeadP = - (lurb_priv->td[lurb_priv->length - 1]->hwNextTD & ohci_cpu_to_le32 (0xfffffff0)) | - (td_list->ed->hwHeadP & ohci_cpu_to_le32 (0x2)); - lurb_priv->td_cnt += lurb_priv->length - td_list->index - 1; - } else - td_list->ed->hwHeadP &= ohci_cpu_to_le32 (0xfffffff2); - } - td_list->hwNextTD = 0; - } - - td_list->next_dl_td = td_rev; - td_rev = td_list; - td_list_hc = ohci_cpu_to_le32 (td_list->hwNextTD) & 0xfffffff0; - } - return td_list; -} - -/*-------------------------------------------------------------------------*/ - -/* td done list */ -static int dl_done_list (ohci_t *ohci, td_t *td_list) -{ - td_t *td_list_next = NULL; - ed_t *ed; - int cc = 0; - int stat = 0; - /* urb_t *urb; */ - urb_priv_t *lurb_priv; - __u32 tdINFO, edHeadP, edTailP; - - while (td_list) { - td_list_next = td_list->next_dl_td; - - lurb_priv = &urb_priv; - tdINFO = ohci_cpu_to_le32 (td_list->hwINFO); - - ed = td_list->ed; - - dl_transfer_length(td_list); - - /* error code of transfer */ - cc = TD_CC_GET (tdINFO); - if (++(lurb_priv->td_cnt) == lurb_priv->length) { - if ((ed->state & (ED_OPER | ED_UNLINK)) - && (lurb_priv->state != URB_DEL)) { - dbg("ConditionCode %#x", cc); - stat = cc_to_error[cc]; - urb_finished = 1; - } - } - - if (ed->state != ED_NEW) { - edHeadP = ohci_cpu_to_le32 (ed->hwHeadP) & 0xfffffff0; - edTailP = ohci_cpu_to_le32 (ed->hwTailP); - - /* unlink eds if they are not busy */ - if ((edHeadP == edTailP) && (ed->state == ED_OPER)) - ep_unlink (ohci, ed); - } - - td_list = td_list_next; - } - return stat; -} - -/*-------------------------------------------------------------------------* - * Virtual Root Hub - *-------------------------------------------------------------------------*/ - -/* Device descriptor */ -static __u8 root_hub_dev_des[] = -{ - 0x12, /* __u8 bLength; */ - 0x01, /* __u8 bDescriptorType; Device */ - 0x10, /* __u16 bcdUSB; v1.1 */ - 0x01, - 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ - 0x00, /* __u8 bDeviceSubClass; */ - 0x00, /* __u8 bDeviceProtocol; */ - 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ - 0x00, /* __u16 idVendor; */ - 0x00, - 0x00, /* __u16 idProduct; */ - 0x00, - 0x00, /* __u16 bcdDevice; */ - 0x00, - 0x00, /* __u8 iManufacturer; */ - 0x01, /* __u8 iProduct; */ - 0x00, /* __u8 iSerialNumber; */ - 0x01 /* __u8 bNumConfigurations; */ -}; - - -/* Configuration descriptor */ -static __u8 root_hub_config_des[] = -{ - 0x09, /* __u8 bLength; */ - 0x02, /* __u8 bDescriptorType; Configuration */ - 0x19, /* __u16 wTotalLength; */ - 0x00, - 0x01, /* __u8 bNumInterfaces; */ - 0x01, /* __u8 bConfigurationValue; */ - 0x00, /* __u8 iConfiguration; */ - 0x40, /* __u8 bmAttributes; - Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */ - 0x00, /* __u8 MaxPower; */ - - /* interface */ - 0x09, /* __u8 if_bLength; */ - 0x04, /* __u8 if_bDescriptorType; Interface */ - 0x00, /* __u8 if_bInterfaceNumber; */ - 0x00, /* __u8 if_bAlternateSetting; */ - 0x01, /* __u8 if_bNumEndpoints; */ - 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ - 0x00, /* __u8 if_bInterfaceSubClass; */ - 0x00, /* __u8 if_bInterfaceProtocol; */ - 0x00, /* __u8 if_iInterface; */ - - /* endpoint */ - 0x07, /* __u8 ep_bLength; */ - 0x05, /* __u8 ep_bDescriptorType; Endpoint */ - 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ - 0x03, /* __u8 ep_bmAttributes; Interrupt */ - 0x02, /* __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */ - 0x00, - 0xff /* __u8 ep_bInterval; 255 ms */ -}; - -static unsigned char root_hub_str_index0[] = -{ - 0x04, /* __u8 bLength; */ - 0x03, /* __u8 bDescriptorType; String-descriptor */ - 0x09, /* __u8 lang ID */ - 0x04, /* __u8 lang ID */ -}; - -static unsigned char root_hub_str_index1[] = -{ - 28, /* __u8 bLength; */ - 0x03, /* __u8 bDescriptorType; String-descriptor */ - 'O', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'H', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'C', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'I', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - ' ', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'R', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'o', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'o', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 't', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - ' ', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'H', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'u', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'b', /* __u8 Unicode */ - 0, /* __u8 Unicode */ -}; - -/* Hub class-specific descriptor is constructed dynamically */ - - -/*-------------------------------------------------------------------------*/ - -#define OK(x) len = (x); break -#ifdef DEBUG -#define WR_RH_STAT(x) {info("WR:status %#8x", (x));writel((x), &gohci.regs->roothub.status);} -#define WR_RH_PORTSTAT(x) {info("WR:portstatus[%d] %#8x", wIndex-1, (x));writel((x), &gohci.regs->roothub.portstatus[wIndex-1]);} -#else -#define WR_RH_STAT(x) writel((x), &gohci.regs->roothub.status) -#define WR_RH_PORTSTAT(x) writel((x), &gohci.regs->roothub.portstatus[wIndex-1]) -#endif -#define RD_RH_STAT roothub_status(&gohci) -#define RD_RH_PORTSTAT roothub_portstatus(&gohci,wIndex-1) - -/* request to virtual root hub */ - -int rh_check_port_status(ohci_t *controller) -{ - __u32 temp, ndp, i; - int res; - - res = -1; - temp = roothub_a (controller); - ndp = (temp & RH_A_NDP); - for (i = 0; i < ndp; i++) { - temp = roothub_portstatus (controller, i); - /* check for a device disconnect */ - if (((temp & (RH_PS_PESC | RH_PS_CSC)) == - (RH_PS_PESC | RH_PS_CSC)) && - ((temp & RH_PS_CCS) == 0)) { - res = i; - break; - } - } - return res; -} - -static int ohci_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 stat = 0; - __u32 datab[4]; - __u8 *data_buf = (__u8 *)datab; - __u16 bmRType_bReq; - __u16 wValue; - __u16 wIndex; - __u16 wLength; - -#ifdef DEBUG -urb_priv.actual_length = 0; -pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe)); -#endif - if (usb_pipeint(pipe)) { - info("Root-Hub submit IRQ: NOT implemented"); - return 0; - } - - bmRType_bReq = cmd->requesttype | (cmd->request << 8); - wValue = m16_swap (cmd->value); - wIndex = m16_swap (cmd->index); - wLength = m16_swap (cmd->length); - - info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x", - dev->devnum, 8, bmRType_bReq, 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: - *(__u16 *) data_buf = m16_swap (1); OK (2); - case RH_GET_STATUS | RH_INTERFACE: - *(__u16 *) data_buf = m16_swap (0); OK (2); - case RH_GET_STATUS | RH_ENDPOINT: - *(__u16 *) data_buf = m16_swap (0); OK (2); - case RH_GET_STATUS | RH_CLASS: - *(__u32 *) data_buf = m32_swap ( - RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE)); - OK (4); - case RH_GET_STATUS | RH_OTHER | RH_CLASS: - *(__u32 *) data_buf = m32_swap (RD_RH_PORTSTAT); OK (4); - - case RH_CLEAR_FEATURE | RH_ENDPOINT: - switch (wValue) { - case (RH_ENDPOINT_STALL): OK (0); - } - break; - - case RH_CLEAR_FEATURE | RH_CLASS: - switch (wValue) { - case RH_C_HUB_LOCAL_POWER: - OK(0); - case (RH_C_HUB_OVER_CURRENT): - WR_RH_STAT(RH_HS_OCIC); OK (0); - } - break; - - case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: - switch (wValue) { - case (RH_PORT_ENABLE): - WR_RH_PORTSTAT (RH_PS_CCS ); OK (0); - case (RH_PORT_SUSPEND): - WR_RH_PORTSTAT (RH_PS_POCI); OK (0); - case (RH_PORT_POWER): - WR_RH_PORTSTAT (RH_PS_LSDA); OK (0); - case (RH_C_PORT_CONNECTION): - WR_RH_PORTSTAT (RH_PS_CSC ); OK (0); - case (RH_C_PORT_ENABLE): - WR_RH_PORTSTAT (RH_PS_PESC); OK (0); - case (RH_C_PORT_SUSPEND): - WR_RH_PORTSTAT (RH_PS_PSSC); OK (0); - case (RH_C_PORT_OVER_CURRENT): - WR_RH_PORTSTAT (RH_PS_OCIC); OK (0); - case (RH_C_PORT_RESET): - WR_RH_PORTSTAT (RH_PS_PRSC); OK (0); - } - break; - - case RH_SET_FEATURE | RH_OTHER | RH_CLASS: - switch (wValue) { - case (RH_PORT_SUSPEND): - WR_RH_PORTSTAT (RH_PS_PSS ); OK (0); - case (RH_PORT_RESET): /* BUG IN HUP CODE *********/ - if (RD_RH_PORTSTAT & RH_PS_CCS) - WR_RH_PORTSTAT (RH_PS_PRS); - OK (0); - case (RH_PORT_POWER): - WR_RH_PORTSTAT (RH_PS_PPS ); OK (0); - case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/ - if (RD_RH_PORTSTAT & RH_PS_CCS) - WR_RH_PORTSTAT (RH_PS_PES ); - OK (0); - } - break; - - case RH_SET_ADDRESS: gohci.rh.devnum = wValue; OK(0); - - case RH_GET_DESCRIPTOR: - switch ((wValue & 0xff00) >> 8) { - case (0x01): /* device descriptor */ - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof (root_hub_dev_des), - wLength)); - data_buf = root_hub_dev_des; OK(len); - case (0x02): /* configuration descriptor */ - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof (root_hub_config_des), - wLength)); - data_buf = root_hub_config_des; OK(len); - case (0x03): /* string descriptors */ - if(wValue==0x0300) { - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof (root_hub_str_index0), - wLength)); - data_buf = root_hub_str_index0; - OK(len); - } - if(wValue==0x0301) { - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof (root_hub_str_index1), - wLength)); - data_buf = root_hub_str_index1; - OK(len); - } - default: - stat = USB_ST_STALLED; - } - break; - - case RH_GET_DESCRIPTOR | RH_CLASS: - { - __u32 temp = roothub_a (&gohci); - - data_buf [0] = 9; /* min length; */ - data_buf [1] = 0x29; - data_buf [2] = temp & RH_A_NDP; - data_buf [3] = 0; - if (temp & RH_A_PSM) /* per-port power switching? */ - data_buf [3] |= 0x1; - if (temp & RH_A_NOCP) /* no overcurrent reporting? */ - data_buf [3] |= 0x10; - else if (temp & RH_A_OCPM) /* per-port overcurrent reporting? */ - data_buf [3] |= 0x8; - - /* corresponds to data_buf[4-7] */ - datab [1] = 0; - data_buf [5] = (temp & RH_A_POTPGT) >> 24; - temp = roothub_b (&gohci); - data_buf [7] = temp & RH_B_DR; - if (data_buf [2] < 7) { - data_buf [8] = 0xff; - } else { - data_buf [0] += 2; - data_buf [8] = (temp & RH_B_DR) >> 8; - data_buf [10] = data_buf [9] = 0xff; - } - - len = min_t(unsigned int, leni, - min_t(unsigned int, data_buf [0], wLength)); - OK (len); - } - - case RH_GET_CONFIGURATION: *(__u8 *) data_buf = 0x01; OK (1); - - case RH_SET_CONFIGURATION: WR_RH_STAT (0x10000); OK (0); - - default: - dbg ("unsupported root hub command"); - stat = USB_ST_STALLED; - } - -#ifdef DEBUG - ohci_dump_roothub (&gohci, 1); -#endif - - len = min_t(int, len, leni); - if (data != data_buf) - memcpy (data, data_buf, len); - dev->act_len = len; - dev->status = stat; - -#ifdef DEBUG - if (transfer_len) - urb_priv.actual_length = transfer_len; - pkt_print(dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/); -#endif - - return stat; -} - -/*-------------------------------------------------------------------------*/ - -/* common code for handling submit messages - used for all but root hub */ -/* accesses. */ -int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *setup, int interval) -{ - int stat = 0; - int maxsize = usb_maxpacket(dev, pipe); - int timeout; - - /* device pulled? Shortcut the action. */ - if (devgone == dev) { - dev->status = USB_ST_CRC_ERR; - return 0; - } - -#ifdef DEBUG - urb_priv.actual_length = 0; - pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe)); -#endif - if (!maxsize) { - err("submit_common_message: pipesize for pipe %lx is zero", - pipe); - return -1; - } - - if (sohci_submit_job(dev, pipe, buffer, transfer_len, setup, interval) < 0) { - err("sohci_submit_job failed"); - return -1; - } - - /* allow more time for a BULK device to react - some are slow */ -#define BULK_TO 5000 /* timeout in milliseconds */ - if (usb_pipebulk(pipe)) - timeout = BULK_TO; - else - timeout = 100; - - /* wait for it to complete */ - for (;;) { - /* check whether the controller is done */ - stat = hc_interrupt(); - if (stat < 0) { - stat = USB_ST_CRC_ERR; - break; - } - - /* NOTE: since we are not interrupt driven in U-Boot and always - * handle only one URB at a time, we cannot assume the - * transaction finished on the first successful return from - * hc_interrupt().. unless the flag for current URB is set, - * meaning that all TD's to/from device got actually - * transferred and processed. If the current URB is not - * finished we need to re-iterate this loop so as - * hc_interrupt() gets called again as there needs to be some - * more TD's to process still */ - if ((stat >= 0) && (stat != 0xff) && (urb_finished)) { - /* 0xff is returned for an SF-interrupt */ - break; - } - - if (--timeout) { - wait_ms(1); - if (!urb_finished) - dbg("\%"); - - } else { - err("CTL:TIMEOUT "); - dbg("submit_common_msg: TO status %x\n", stat); - stat = USB_ST_CRC_ERR; - urb_finished = 1; - break; - } - } -#if 0 - /* we got an Root Hub Status Change interrupt */ - if (got_rhsc) { -#ifdef DEBUG - ohci_dump_roothub (&gohci, 1); -#endif - got_rhsc = 0; - /* abuse timeout */ - timeout = rh_check_port_status(&gohci); - if (timeout >= 0) { -#if 0 /* this does nothing useful, but leave it here in case that changes */ - /* the called routine adds 1 to the passed value */ - usb_hub_port_connect_change(gohci.rh.dev, timeout - 1); -#endif - /* - * XXX - * This is potentially dangerous because it assumes - * that only one device is ever plugged in! - */ - devgone = dev; - } - } -#endif - - dev->status = stat; - dev->act_len = transfer_len; - -#ifdef DEBUG - pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe)); -#endif - - /* free TDs in urb_priv */ - urb_free_priv (&urb_priv); - return 0; -} - -/* submit routines called from usb.c */ -int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len) -{ - info("submit_bulk_msg"); - return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0); -} - -int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *setup) -{ - int maxsize = usb_maxpacket(dev, pipe); - - info("submit_control_msg"); -#ifdef DEBUG - urb_priv.actual_length = 0; - pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe)); -#endif - if (!maxsize) { - err("submit_control_message: pipesize for pipe %lx is zero", - pipe); - return -1; - } - if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) { - gohci.rh.dev = dev; - /* root hub - redirect */ - return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len, - setup); - } - - return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0); -} - -int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, int interval) -{ - info("submit_int_msg"); - return -1; -} - -/*-------------------------------------------------------------------------* - * HC functions - *-------------------------------------------------------------------------*/ - -/* reset the HC and BUS */ - -static int hc_reset (ohci_t *ohci) -{ - int timeout = 30; - int smm_timeout = 50; /* 0,5 sec */ - - if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */ - writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */ - info("USB HC TakeOver from SMM"); - while (readl (&ohci->regs->control) & OHCI_CTRL_IR) { - wait_ms (10); - if (--smm_timeout == 0) { - err("USB HC TakeOver failed!"); - return -1; - } - } - } - - /* Disable HC interrupts */ - writel (OHCI_INTR_MIE, &ohci->regs->intrdisable); - - dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;", - ohci->slot_name, - readl (&ohci->regs->control)); - - /* Reset USB (needed by some controllers) */ - ohci->hc_control = 0; - writel (ohci->hc_control, &ohci->regs->control); - - /* HC Reset requires max 10 us delay */ - writel (OHCI_HCR, &ohci->regs->cmdstatus); - while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { - if (--timeout == 0) { - err("USB HC reset timed out!"); - return -1; - } - udelay (1); - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* Start an OHCI controller, set the BUS operational - * enable interrupts - * connect the virtual root hub */ - -static int hc_start (ohci_t * ohci) -{ - __u32 mask; - unsigned int fminterval; - - ohci->disabled = 1; - - /* Tell the controller where the control and bulk lists are - * The lists are empty now. */ - - writel (0, &ohci->regs->ed_controlhead); - writel (0, &ohci->regs->ed_bulkhead); - - writel ((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */ - - fminterval = 0x2edf; - writel ((fminterval * 9) / 10, &ohci->regs->periodicstart); - fminterval |= ((((fminterval - 210) * 6) / 7) << 16); - writel (fminterval, &ohci->regs->fminterval); - writel (0x628, &ohci->regs->lsthresh); - - /* start controller operations */ - ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER; - ohci->disabled = 0; - writel (ohci->hc_control, &ohci->regs->control); - - /* disable all interrupts */ - mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD | - OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC | - OHCI_INTR_OC | OHCI_INTR_MIE); - writel (mask, &ohci->regs->intrdisable); - /* clear all interrupts */ - mask &= ~OHCI_INTR_MIE; - writel (mask, &ohci->regs->intrstatus); - /* Choose the interrupts we care about now - but w/o MIE */ - mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO; - writel (mask, &ohci->regs->intrenable); - -#ifdef OHCI_USE_NPS - /* required for AMD-756 and some Mac platforms */ - writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM, - &ohci->regs->roothub.a); - writel (RH_HS_LPSC, &ohci->regs->roothub.status); -#endif /* OHCI_USE_NPS */ - -#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);}) - /* POTPGT delay is bits 24-31, in 2 ms units. */ - mdelay ((roothub_a (ohci) >> 23) & 0x1fe); - - /* connect the virtual root hub */ - ohci->rh.devnum = 0; - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* an interrupt happens */ - -static int -hc_interrupt (void) -{ - ohci_t *ohci = &gohci; - struct ohci_regs *regs = ohci->regs; - int ints; - int stat = -1; - - if ((ohci->hcca->done_head != 0) && - !(ohci_cpu_to_le32(ohci->hcca->done_head) & 0x01)) { - - ints = OHCI_INTR_WDH; - - } else if ((ints = readl (®s->intrstatus)) == ~(u32)0) { - ohci->disabled++; - err ("%s device removed!", ohci->slot_name); - return -1; - - } else if ((ints &= readl (®s->intrenable)) == 0) { - dbg("hc_interrupt: returning..\n"); - return 0xff; - } - - /* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */ - - if (ints & OHCI_INTR_RHSC) { - got_rhsc = 1; - stat = 0xff; - } - - if (ints & OHCI_INTR_UE) { - ohci->disabled++; - err ("OHCI Unrecoverable Error, controller usb-%s disabled", - ohci->slot_name); - /* e.g. due to PCI Master/Target Abort */ - -#ifdef DEBUG - ohci_dump (ohci, 1); -#endif - /* FIXME: be optimistic, hope that bug won't repeat often. */ - /* Make some non-interrupt context restart the controller. */ - /* Count and limit the retries though; either hardware or */ - /* software errors can go forever... */ - hc_reset (ohci); - return -1; - } - - if (ints & OHCI_INTR_WDH) { - writel (OHCI_INTR_WDH, ®s->intrdisable); - stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci)); - writel (OHCI_INTR_WDH, ®s->intrenable); - } - - if (ints & OHCI_INTR_SO) { - dbg("USB Schedule overrun\n"); - writel (OHCI_INTR_SO, ®s->intrenable); - stat = -1; - } - - /* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */ - if (ints & OHCI_INTR_SF) { - unsigned int frame = ohci_cpu_to_le16 (ohci->hcca->frame_no) & 1; - wait_ms(1); - writel (OHCI_INTR_SF, ®s->intrdisable); - if (ohci->ed_rm_list[frame] != NULL) - writel (OHCI_INTR_SF, ®s->intrenable); - stat = 0xff; - } - - writel (ints, ®s->intrstatus); - return stat; -} - -/*-------------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------------*/ - -/* De-allocate all resources.. */ - -static void hc_release_ohci (ohci_t *ohci) -{ - dbg ("USB HC release ohci usb-%s", ohci->slot_name); - - if (!ohci->disabled) - hc_reset (ohci); -} - -/*-------------------------------------------------------------------------*/ - -/* - * low level initalisation routine, called from usb.c - */ -static char ohci_inited = 0; - -int usb_lowlevel_init(void) -{ - - /* Set the USB Clock */ - *(vu_long *)MPC5XXX_CDM_48_FDC = CONFIG_USB_CLOCK; - -#ifdef CONFIG_PSC3_USB /* USB is using the alternate configuration */ - /* remove all PSC3 USB bits first before ORing in ours */ - *(vu_long *)MPC5XXX_GPS_PORT_CONFIG &= ~0x00804f00; -#else - /* remove all USB bits first before ORing in ours */ - *(vu_long *)MPC5XXX_GPS_PORT_CONFIG &= ~0x00807000; -#endif - /* Activate USB port */ - *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= CONFIG_USB_CONFIG; - - memset (&gohci, 0, sizeof (ohci_t)); - memset (&urb_priv, 0, sizeof (urb_priv_t)); - - /* align the storage */ - if ((__u32)&ghcca[0] & 0xff) { - err("HCCA not aligned!!"); - return -1; - } - phcca = &ghcca[0]; - info("aligned ghcca %p", phcca); - memset(&ohci_dev, 0, sizeof(struct ohci_device)); - if ((__u32)&ohci_dev.ed[0] & 0x7) { - err("EDs not aligned!!"); - return -1; - } - memset(gtd, 0, sizeof(td_t) * (NUM_TD + 1)); - if ((__u32)gtd & 0x7) { - err("TDs not aligned!!"); - return -1; - } - ptd = gtd; - gohci.hcca = phcca; - memset (phcca, 0, sizeof (struct ohci_hcca)); - - gohci.disabled = 1; - gohci.sleeping = 0; - gohci.irq = -1; - gohci.regs = (struct ohci_regs *)MPC5XXX_USB; - - gohci.flags = 0; - gohci.slot_name = "mpc5200"; - - if (hc_reset (&gohci) < 0) { - hc_release_ohci (&gohci); - return -1; - } - - if (hc_start (&gohci) < 0) { - err ("can't start usb-%s", gohci.slot_name); - hc_release_ohci (&gohci); - return -1; - } - -#ifdef DEBUG - ohci_dump (&gohci, 1); -#endif - ohci_inited = 1; - urb_finished = 1; - - return 0; -} - -int usb_lowlevel_stop(void) -{ - /* this gets called really early - before the controller has */ - /* even been initialized! */ - if (!ohci_inited) - return 0; - /* TODO release any interrupts, etc. */ - /* call hc_release_ohci() here ? */ - hc_reset (&gohci); - return 0; -} - -#endif /* CONFIG_USB_OHCI */ diff --git a/cpu/mpc5xxx/usb_ohci.h b/cpu/mpc5xxx/usb_ohci.h deleted file mode 100644 index 629b529..0000000 --- a/cpu/mpc5xxx/usb_ohci.h +++ /dev/null @@ -1,418 +0,0 @@ -/* - * URB OHCI HCD (Host Controller Driver) for USB. - * - * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> - * (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net> - * - * usb-ohci.h - */ - - -static int cc_to_error[16] = { - -/* mapping of the OHCI CC status to error codes */ - /* No Error */ 0, - /* CRC Error */ USB_ST_CRC_ERR, - /* Bit Stuff */ USB_ST_BIT_ERR, - /* Data Togg */ USB_ST_CRC_ERR, - /* Stall */ USB_ST_STALLED, - /* DevNotResp */ -1, - /* PIDCheck */ USB_ST_BIT_ERR, - /* UnExpPID */ USB_ST_BIT_ERR, - /* DataOver */ USB_ST_BUF_ERR, - /* DataUnder */ USB_ST_BUF_ERR, - /* reservd */ -1, - /* reservd */ -1, - /* BufferOver */ USB_ST_BUF_ERR, - /* BuffUnder */ USB_ST_BUF_ERR, - /* Not Access */ -1, - /* Not Access */ -1 -}; - -/* ED States */ - -#define ED_NEW 0x00 -#define ED_UNLINK 0x01 -#define ED_OPER 0x02 -#define ED_DEL 0x04 -#define ED_URB_DEL 0x08 - -/* usb_ohci_ed */ -struct ed { - __u32 hwINFO; - __u32 hwTailP; - __u32 hwHeadP; - __u32 hwNextED; - - struct ed *ed_prev; - __u8 int_period; - __u8 int_branch; - __u8 int_load; - __u8 int_interval; - __u8 state; - __u8 type; - __u16 last_iso; - struct ed *ed_rm_list; - - struct usb_device *usb_dev; - __u32 unused[3]; -} __attribute__((aligned(16))); -typedef struct ed ed_t; - - -/* TD info field */ -#define TD_CC 0xf0000000 -#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f) -#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28) -#define TD_EC 0x0C000000 -#define TD_T 0x03000000 -#define TD_T_DATA0 0x02000000 -#define TD_T_DATA1 0x03000000 -#define TD_T_TOGGLE 0x00000000 -#define TD_R 0x00040000 -#define TD_DI 0x00E00000 -#define TD_DI_SET(X) (((X) & 0x07)<< 21) -#define TD_DP 0x00180000 -#define TD_DP_SETUP 0x00000000 -#define TD_DP_IN 0x00100000 -#define TD_DP_OUT 0x00080000 - -#define TD_ISO 0x00010000 -#define TD_DEL 0x00020000 - -/* CC Codes */ -#define TD_CC_NOERROR 0x00 -#define TD_CC_CRC 0x01 -#define TD_CC_BITSTUFFING 0x02 -#define TD_CC_DATATOGGLEM 0x03 -#define TD_CC_STALL 0x04 -#define TD_DEVNOTRESP 0x05 -#define TD_PIDCHECKFAIL 0x06 -#define TD_UNEXPECTEDPID 0x07 -#define TD_DATAOVERRUN 0x08 -#define TD_DATAUNDERRUN 0x09 -#define TD_BUFFEROVERRUN 0x0C -#define TD_BUFFERUNDERRUN 0x0D -#define TD_NOTACCESSED 0x0F - - -#define MAXPSW 1 - -struct td { - __u32 hwINFO; - __u32 hwCBP; /* Current Buffer Pointer */ - __u32 hwNextTD; /* Next TD Pointer */ - __u32 hwBE; /* Memory Buffer End Pointer */ - - __u8 unused; - __u8 index; - struct ed *ed; - struct td *next_dl_td; - struct usb_device *usb_dev; - int transfer_len; - __u32 data; - - __u32 unused2[2]; -} __attribute__((aligned(32))); -typedef struct td td_t; - -#define OHCI_ED_SKIP (1 << 14) - -/* - * The HCCA (Host Controller Communications Area) is a 256 byte - * structure defined in the OHCI spec. that the host controller is - * told the base address of. It must be 256-byte aligned. - */ - -#define NUM_INTS 32 /* part of the OHCI standard */ -struct ohci_hcca { - __u32 int_table[NUM_INTS]; /* Interrupt ED table */ - __u16 pad1; /* set to 0 on each frame_no change */ - __u16 frame_no; /* current frame number */ - __u32 done_head; /* info returned for an interrupt */ - u8 reserved_for_hc[116]; -} __attribute__((aligned(256))); - - -/* - * Maximum number of root hub ports. - */ -#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */ - -/* - * This is the structure of the OHCI controller's memory mapped I/O - * region. This is Memory Mapped I/O. You must use the readl() and - * writel() macros defined in asm/io.h to access these!! - */ -struct ohci_regs { - /* control and status registers */ - __u32 revision; - __u32 control; - __u32 cmdstatus; - __u32 intrstatus; - __u32 intrenable; - __u32 intrdisable; - /* memory pointers */ - __u32 hcca; - __u32 ed_periodcurrent; - __u32 ed_controlhead; - __u32 ed_controlcurrent; - __u32 ed_bulkhead; - __u32 ed_bulkcurrent; - __u32 donehead; - /* frame counters */ - __u32 fminterval; - __u32 fmremaining; - __u32 fmnumber; - __u32 periodicstart; - __u32 lsthresh; - /* Root hub ports */ - struct ohci_roothub_regs { - __u32 a; - __u32 b; - __u32 status; - __u32 portstatus[MAX_ROOT_PORTS]; - } roothub; -} __attribute__((aligned(32))); - - -/* OHCI CONTROL AND STATUS REGISTER MASKS */ - -/* - * HcControl (control) register masks - */ -#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */ -#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */ -#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */ -#define OHCI_CTRL_CLE (1 << 4) /* control list enable */ -#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */ -#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */ -#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ -#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ -#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */ - -/* pre-shifted values for HCFS */ -# define OHCI_USB_RESET (0 << 6) -# define OHCI_USB_RESUME (1 << 6) -# define OHCI_USB_OPER (2 << 6) -# define OHCI_USB_SUSPEND (3 << 6) - -/* - * HcCommandStatus (cmdstatus) register masks - */ -#define OHCI_HCR (1 << 0) /* host controller reset */ -#define OHCI_CLF (1 << 1) /* control list filled */ -#define OHCI_BLF (1 << 2) /* bulk list filled */ -#define OHCI_OCR (1 << 3) /* ownership change request */ -#define OHCI_SOC (3 << 16) /* scheduling overrun count */ - -/* - * masks used with interrupt registers: - * HcInterruptStatus (intrstatus) - * HcInterruptEnable (intrenable) - * HcInterruptDisable (intrdisable) - */ -#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */ -#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */ -#define OHCI_INTR_SF (1 << 2) /* start frame */ -#define OHCI_INTR_RD (1 << 3) /* resume detect */ -#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */ -#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */ -#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */ -#define OHCI_INTR_OC (1 << 30) /* ownership change */ -#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */ - - -/* Virtual Root HUB */ -struct virt_root_hub { - int devnum; /* Address of Root Hub endpoint */ - void *dev; /* was urb */ - void *int_addr; - int send; - int interval; -}; - -/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */ - -/* 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 - -#define RH_ACK 0x01 -#define RH_REQ_ERR -1 -#define RH_NACK 0x00 - - -/* OHCI ROOT HUB REGISTER MASKS */ - -/* roothub.portstatus [i] bits */ -#define RH_PS_CCS 0x00000001 /* current connect status */ -#define RH_PS_PES 0x00000002 /* port enable status*/ -#define RH_PS_PSS 0x00000004 /* port suspend status */ -#define RH_PS_POCI 0x00000008 /* port over current indicator */ -#define RH_PS_PRS 0x00000010 /* port reset status */ -#define RH_PS_PPS 0x00000100 /* port power status */ -#define RH_PS_LSDA 0x00000200 /* low speed device attached */ -#define RH_PS_CSC 0x00010000 /* connect status change */ -#define RH_PS_PESC 0x00020000 /* port enable status change */ -#define RH_PS_PSSC 0x00040000 /* port suspend status change */ -#define RH_PS_OCIC 0x00080000 /* over current indicator change */ -#define RH_PS_PRSC 0x00100000 /* port reset status change */ - -/* roothub.status bits */ -#define RH_HS_LPS 0x00000001 /* local power status */ -#define RH_HS_OCI 0x00000002 /* over current indicator */ -#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */ -#define RH_HS_LPSC 0x00010000 /* local power status change */ -#define RH_HS_OCIC 0x00020000 /* over current indicator change */ -#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */ - -/* roothub.b masks */ -#define RH_B_DR 0x0000ffff /* device removable flags */ -#define RH_B_PPCM 0xffff0000 /* port power control mask */ - -/* roothub.a masks */ -#define RH_A_NDP (0xff << 0) /* number of downstream ports */ -#define RH_A_PSM (1 << 8) /* power switching mode */ -#define RH_A_NPS (1 << 9) /* no power switching */ -#define RH_A_DT (1 << 10) /* device type (mbz) */ -#define RH_A_OCPM (1 << 11) /* over current protection mode */ -#define RH_A_NOCP (1 << 12) /* no over current protection */ -#define RH_A_POTPGT (0xff << 24) /* power on to power good time */ - -/* urb */ -#define N_URB_TD 48 -typedef struct -{ - ed_t *ed; - __u16 length; /* number of tds associated with this request */ - __u16 td_cnt; /* number of tds already serviced */ - int state; - unsigned long pipe; - int actual_length; - td_t *td[N_URB_TD]; /* list pointer to all corresponding TDs associated with this request */ -} urb_priv_t; -#define URB_DEL 1 - -/* - * This is the full ohci controller description - * - * Note how the "proper" USB information is just - * a subset of what the full implementation needs. (Linus) - */ - - -typedef struct ohci { - struct ohci_hcca *hcca; /* hcca */ - /*dma_addr_t hcca_dma;*/ - - int irq; - int disabled; /* e.g. got a UE, we're hung */ - int sleeping; - unsigned long flags; /* for HC bugs */ - - struct ohci_regs *regs; /* OHCI controller's memory */ - - ed_t *ed_rm_list[2]; /* lists of all endpoints to be removed */ - ed_t *ed_bulktail; /* last endpoint of bulk list */ - ed_t *ed_controltail; /* last endpoint of control list */ - int intrstatus; - __u32 hc_control; /* copy of the hc control reg */ - struct usb_device *dev[32]; - struct virt_root_hub rh; - - const char *slot_name; -} ohci_t; - -#define NUM_EDS 8 /* num of preallocated endpoint descriptors */ - -struct ohci_device { - ed_t ed[NUM_EDS]; - int ed_cnt; -}; - -/* hcd */ -/* endpoint */ -static int ep_link(ohci_t * ohci, ed_t * ed); -static int ep_unlink(ohci_t * ohci, ed_t * ed); -static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned long pipe); - -/*-------------------------------------------------------------------------*/ - -/* we need more TDs than EDs */ -#define NUM_TD 64 - -/* +1 so we can align the storage */ -td_t gtd[NUM_TD+1]; -/* pointers to aligned storage */ -td_t *ptd; - -/* TDs ... */ -static inline struct td * -td_alloc (struct usb_device *usb_dev) -{ - int i; - struct td *td; - - td = NULL; - for (i = 0; i < NUM_TD; i++) - { - if (ptd[i].usb_dev == NULL) - { - td = &ptd[i]; - td->usb_dev = usb_dev; - break; - } - } - - return td; -} - -static inline void -ed_free (struct ed *ed) -{ - ed->usb_dev = NULL; -} |