diff options
Diffstat (limited to 'u-boot/board/freescale/common')
-rw-r--r-- | u-boot/board/freescale/common/Makefile | 70 | ||||
-rw-r--r-- | u-boot/board/freescale/common/cadmus.c | 95 | ||||
-rw-r--r-- | u-boot/board/freescale/common/cadmus.h | 54 | ||||
-rw-r--r-- | u-boot/board/freescale/common/cds_pci_ft.c | 72 | ||||
-rw-r--r-- | u-boot/board/freescale/common/cds_via.c | 109 | ||||
-rw-r--r-- | u-boot/board/freescale/common/eeprom.h | 50 | ||||
-rw-r--r-- | u-boot/board/freescale/common/ics307_clk.c | 88 | ||||
-rw-r--r-- | u-boot/board/freescale/common/ics307_clk.h | 30 | ||||
-rw-r--r-- | u-boot/board/freescale/common/ngpixis.c | 136 | ||||
-rw-r--r-- | u-boot/board/freescale/common/ngpixis.h | 57 | ||||
-rw-r--r-- | u-boot/board/freescale/common/pixis.c | 558 | ||||
-rw-r--r-- | u-boot/board/freescale/common/pixis.h | 182 | ||||
-rw-r--r-- | u-boot/board/freescale/common/pq-mds-pib.c | 102 | ||||
-rw-r--r-- | u-boot/board/freescale/common/pq-mds-pib.h | 9 | ||||
-rw-r--r-- | u-boot/board/freescale/common/sgmii_riser.c | 88 | ||||
-rw-r--r-- | u-boot/board/freescale/common/sgmii_riser.h | 16 | ||||
-rw-r--r-- | u-boot/board/freescale/common/sys_eeprom.c | 524 | ||||
-rw-r--r-- | u-boot/board/freescale/common/via.h | 18 |
18 files changed, 2258 insertions, 0 deletions
diff --git a/u-boot/board/freescale/common/Makefile b/u-boot/board/freescale/common/Makefile new file mode 100644 index 000000000..1abd3e567 --- /dev/null +++ b/u-boot/board/freescale/common/Makefile @@ -0,0 +1,70 @@ +# +# (C) Copyright 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 + +ifneq ($(OBJTREE),$(SRCTREE)) +$(shell mkdir -p $(obj)board/freescale/common) +endif + +LIB = $(obj)libfreescale.o + +COBJS-$(CONFIG_FSL_CADMUS) += cadmus.o +COBJS-$(CONFIG_FSL_VIA) += cds_via.o +COBJS-$(CONFIG_FSL_PIXIS) += pixis.o +COBJS-$(CONFIG_FSL_NGPIXIS) += ngpixis.o +COBJS-$(CONFIG_PQ_MDS_PIB) += pq-mds-pib.o +COBJS-$(CONFIG_ID_EEPROM) += sys_eeprom.o +COBJS-$(CONFIG_FSL_SGMII_RISER) += sgmii_riser.o + +COBJS-$(CONFIG_MPC8541CDS) += cds_pci_ft.o +COBJS-$(CONFIG_MPC8548CDS) += cds_pci_ft.o +COBJS-$(CONFIG_MPC8555CDS) += cds_pci_ft.o + +COBJS-$(CONFIG_MPC8536DS) += ics307_clk.o +COBJS-$(CONFIG_MPC8572DS) += ics307_clk.o +COBJS-$(CONFIG_P1022DS) += ics307_clk.o +COBJS-$(CONFIG_P2020DS) += ics307_clk.o +COBJS-$(CONFIG_P4080DS) += ics307_clk.o + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/u-boot/board/freescale/common/cadmus.c b/u-boot/board/freescale/common/cadmus.c new file mode 100644 index 000000000..db54bc4d5 --- /dev/null +++ b/u-boot/board/freescale/common/cadmus.c @@ -0,0 +1,95 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * + * 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> + + +/* + * CADMUS Board System Registers + */ +#ifndef CONFIG_SYS_CADMUS_BASE_REG +#define CONFIG_SYS_CADMUS_BASE_REG (CADMUS_BASE_ADDR + 0x4000) +#endif + +typedef struct cadmus_reg { + u_char cm_ver; /* Board version */ + u_char cm_csr; /* General control/status */ + u_char cm_rst; /* Reset control */ + u_char cm_hsclk; /* High speed clock */ + u_char cm_hsxclk; /* High speed clock extended */ + u_char cm_led; /* LED data */ + u_char cm_pci; /* PCI control/status */ + u_char cm_dma; /* DMA control */ + u_char cm_reserved[248]; /* Total 256 bytes */ +} cadmus_reg_t; + + +unsigned int +get_board_version(void) +{ + volatile cadmus_reg_t *cadmus = (cadmus_reg_t *)CONFIG_SYS_CADMUS_BASE_REG; + + return cadmus->cm_ver; +} + + +unsigned long +get_clock_freq(void) +{ + volatile cadmus_reg_t *cadmus = (cadmus_reg_t *)CONFIG_SYS_CADMUS_BASE_REG; + + uint pci1_speed = (cadmus->cm_pci >> 2) & 0x3; /* PSPEED in [4:5] */ + + if (pci1_speed == 0) { + return 33000000; + } else if (pci1_speed == 1) { + return 66000000; + } else { + /* Really, unknown. Be safe? */ + return 33000000; + } +} + + +unsigned int +get_pci_slot(void) +{ + volatile cadmus_reg_t *cadmus = (cadmus_reg_t *)CONFIG_SYS_CADMUS_BASE_REG; + + /* + * PCI slot in USER bits CSR[6:7] by convention. + */ + return ((cadmus->cm_csr >> 6) & 0x3) + 1; +} + + +unsigned int +get_pci_dual(void) +{ + volatile cadmus_reg_t *cadmus = (cadmus_reg_t *)CONFIG_SYS_CADMUS_BASE_REG; + + /* + * PCI DUAL in CM_PCI[3] + */ + return cadmus->cm_pci & 0x10; +} diff --git a/u-boot/board/freescale/common/cadmus.h b/u-boot/board/freescale/common/cadmus.h new file mode 100644 index 000000000..217ea6425 --- /dev/null +++ b/u-boot/board/freescale/common/cadmus.h @@ -0,0 +1,54 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * + * 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 + */ + +#ifndef __CADMUS_H_ +#define __CADMUS_H_ + + +/* + * CADMUS Board System Register interface. + */ + +/* + * Returns board version register. + */ +extern unsigned int get_board_version(void); + +/* + * Returns either 33000000 or 66000000 as the SYS_CLK_FREQ. + */ +extern unsigned long get_clock_freq(void); + + +/* + * Returns 1 - 4, as found in the USER CSR[6:7] bits. + */ +extern unsigned int get_pci_slot(void); + + +/* + * Returns PCI DUAL as found in CM_PCI[3]. + */ +extern unsigned int get_pci_dual(void); + + +#endif /* __CADMUS_H_ */ diff --git a/u-boot/board/freescale/common/cds_pci_ft.c b/u-boot/board/freescale/common/cds_pci_ft.c new file mode 100644 index 000000000..6f221aff2 --- /dev/null +++ b/u-boot/board/freescale/common/cds_pci_ft.c @@ -0,0 +1,72 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * + * 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 <libfdt.h> +#include <fdt_support.h> +#include "cadmus.h" + +#if defined(CONFIG_OF_BOARD_SETUP) +static void cds_pci_fixup(void *blob) +{ + int node, tmp[2]; + const char *path; + int len, slot, i; + u32 *map = NULL; + + node = fdt_path_offset(blob, "/aliases"); + tmp[0] = 0; + if (node >= 0) { + path = fdt_getprop(blob, node, "pci0", NULL); + if (path) { + node = fdt_path_offset(blob, path); + if (node >= 0) { + map = fdt_getprop_w(blob, node, "interrupt-map", &len); + } + } + } + + if (map) { + len /= sizeof(u32); + + slot = get_pci_slot(); + + for (i=0;i<len;i+=7) { + /* We rotate the interrupt pins so that the mapping + * changes depending on the slot the carrier card is in. + */ + map[3] = ((map[3] + slot - 2) % 4) + 1; + map+=7; + } + } +} + +void +ft_board_setup(void *blob, bd_t *bd) +{ + ft_cpu_setup(blob, bd); +#ifdef CONFIG_PCI + ft_pci_setup(blob, bd); + cds_pci_fixup(blob); +#endif +} +#endif diff --git a/u-boot/board/freescale/common/cds_via.c b/u-boot/board/freescale/common/cds_via.c new file mode 100644 index 000000000..4a63d7794 --- /dev/null +++ b/u-boot/board/freescale/common/cds_via.c @@ -0,0 +1,109 @@ +/* + * Copyright 2006 Freescale Semiconductor. + * + * 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 <pci.h> + +/* Config the VIA chip */ +void mpc85xx_config_via(struct pci_controller *hose, + pci_dev_t dev, struct pci_config_table *tab) +{ + pci_dev_t bridge; + unsigned int cmdstat; + + /* Enable USB and IDE functions */ + pci_hose_write_config_byte(hose, dev, 0x48, 0x08); + + pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat); + cmdstat |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY| PCI_COMMAND_MASTER; + pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat); + pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08); + pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80); + + /* + * Force the backplane P2P bridge to have a window + * open from 0x00000000-0x00001fff in PCI I/O space. + * This allows legacy I/O (i8259, etc) on the VIA + * southbridge to be accessed. + */ + bridge = PCI_BDF(0,BRIDGE_ID,0); + pci_hose_write_config_byte(hose, bridge, PCI_IO_BASE, 0); + pci_hose_write_config_word(hose, bridge, PCI_IO_BASE_UPPER16, 0); + pci_hose_write_config_byte(hose, bridge, PCI_IO_LIMIT, 0x10); + pci_hose_write_config_word(hose, bridge, PCI_IO_LIMIT_UPPER16, 0); +} + +/* Function 1, IDE */ +void mpc85xx_config_via_usbide(struct pci_controller *hose, + pci_dev_t dev, struct pci_config_table *tab) +{ + pciauto_config_device(hose, dev); + /* + * Since the P2P window was forced to cover the fixed + * legacy I/O addresses, it is necessary to manually + * place the base addresses for the IDE and USB functions + * within this window. + */ + pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0x1ff8); + pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_1, 0x1ff4); + pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_2, 0x1fe8); + pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_3, 0x1fe4); + pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_4, 0x1fd0); +} + +/* Function 2, USB ports 0-1 */ +void mpc85xx_config_via_usb(struct pci_controller *hose, + pci_dev_t dev, struct pci_config_table *tab) +{ + pciauto_config_device(hose, dev); + + pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_4, 0x1fa0); +} + +/* Function 3, USB ports 2-3 */ +void mpc85xx_config_via_usb2(struct pci_controller *hose, + pci_dev_t dev, struct pci_config_table *tab) +{ + pciauto_config_device(hose, dev); + + pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_4, 0x1f80); +} + +/* Function 5, Power Management */ +void mpc85xx_config_via_power(struct pci_controller *hose, + pci_dev_t dev, struct pci_config_table *tab) +{ + pciauto_config_device(hose, dev); + + pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0x1e00); + pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_1, 0x1dfc); + pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_2, 0x1df8); +} + +/* Function 6, AC97 Interface */ +void mpc85xx_config_via_ac97(struct pci_controller *hose, + pci_dev_t dev, struct pci_config_table *tab) +{ + pciauto_config_device(hose, dev); + + pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0x1c00); +} diff --git a/u-boot/board/freescale/common/eeprom.h b/u-boot/board/freescale/common/eeprom.h new file mode 100644 index 000000000..12a078904 --- /dev/null +++ b/u-boot/board/freescale/common/eeprom.h @@ -0,0 +1,50 @@ +/* + * Copyright 2004 Freescale Semiconductor. + * + * 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 + */ + +#ifndef __EEPROM_H_ +#define __EEPROM_H_ + + +/* + * EEPROM Board System Register interface. + */ + + +/* + * CPU Board Revision + */ +#define MPC85XX_CPU_BOARD_REV(maj, min) ((((maj)&0xff) << 8) | ((min) & 0xff)) +#define MPC85XX_CPU_BOARD_MAJOR(rev) (((rev) >> 8) & 0xff) +#define MPC85XX_CPU_BOARD_MINOR(rev) ((rev) & 0xff) + +#define MPC85XX_CPU_BOARD_REV_UNKNOWN MPC85XX_CPU_BOARD_REV(0,0) +#define MPC85XX_CPU_BOARD_REV_1_0 MPC85XX_CPU_BOARD_REV(1,0) +#define MPC85XX_CPU_BOARD_REV_1_1 MPC85XX_CPU_BOARD_REV(1,1) + +/* + * Returns CPU board revision register as a 16-bit value with + * the Major in the high byte, and Minor in the low byte. + */ +extern unsigned int get_cpu_board_revision(void); + + +#endif /* __CADMUS_H_ */ diff --git a/u-boot/board/freescale/common/ics307_clk.c b/u-boot/board/freescale/common/ics307_clk.c new file mode 100644 index 000000000..89d8810f7 --- /dev/null +++ b/u-boot/board/freescale/common/ics307_clk.c @@ -0,0 +1,88 @@ +/* + * Copyright 2010 Freescale Semiconductor, 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 + */ + +#include <common.h> +#include <asm/io.h> + +#include "ics307_clk.h" + +#ifdef CONFIG_FSL_NGPIXIS +#include "ngpixis.h" +#else +#include "pixis.h" +#endif + +/* decode S[0-2] to Output Divider (OD) */ +static u8 ics307_s_to_od[] = { + 10, 2, 8, 4, 5, 7, 3, 6 +}; + +/* + * Calculate frequency being generated by ICS307-02 clock chip based upon + * the control bytes being programmed into it. + */ +static unsigned long ics307_clk_freq(u8 cw0, u8 cw1, u8 cw2) +{ + const unsigned long input_freq = CONFIG_ICS307_REFCLK_HZ; + unsigned long vdw = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1); + unsigned long rdw = cw2 & 0x7F; + unsigned long od = ics307_s_to_od[cw0 & 0x7]; + unsigned long freq; + + /* + * CLK1 Freq = Input Frequency * 2 * (VDW + 8) / ((RDW + 2) * OD) + * + * cw0: C1 C0 TTL F1 F0 S2 S1 S0 + * cw1: V8 V7 V6 V5 V4 V3 V2 V1 + * cw2: V0 R6 R5 R4 R3 R2 R1 R0 + * + * R6:R0 = Reference Divider Word (RDW) + * V8:V0 = VCO Divider Word (VDW) + * S2:S0 = Output Divider Select (OD) + * F1:F0 = Function of CLK2 Output + * TTL = duty cycle + * C1:C0 = internal load capacitance for cyrstal + * + */ + + freq = input_freq * 2 * (vdw + 8) / ((rdw + 2) * od); + + debug("ICS307: CW[0-2]: %02X %02X %02X => %lu Hz\n", cw0, cw1, cw2, + freq); + return freq; +} + +unsigned long get_board_sys_clk(void) +{ + return ics307_clk_freq( + in_8(&pixis->sclk[0]), + in_8(&pixis->sclk[1]), + in_8(&pixis->sclk[2])); +} + +unsigned long get_board_ddr_clk(void) +{ + return ics307_clk_freq( + in_8(&pixis->dclk[0]), + in_8(&pixis->dclk[1]), + in_8(&pixis->dclk[2])); +} diff --git a/u-boot/board/freescale/common/ics307_clk.h b/u-boot/board/freescale/common/ics307_clk.h new file mode 100644 index 000000000..db3dbc41f --- /dev/null +++ b/u-boot/board/freescale/common/ics307_clk.h @@ -0,0 +1,30 @@ +/* + * Copyright 2010 Freescale Semiconductor, 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 + */ +#ifndef __ICS_CLK_H_ +#define __ICS_CLK_H_ 1 + +#ifndef __ASSEMBLY__ +extern unsigned long get_board_sys_clk(void); +extern unsigned long get_board_ddr_clk(void); +#endif + +#endif /* __ICS_CLK_H_ */ diff --git a/u-boot/board/freescale/common/ngpixis.c b/u-boot/board/freescale/common/ngpixis.c new file mode 100644 index 000000000..a135fbe5e --- /dev/null +++ b/u-boot/board/freescale/common/ngpixis.c @@ -0,0 +1,136 @@ +/** + * Copyright 2010 Freescale Semiconductor + * Author: Timur Tabi <timur@freescale.com> + * + * 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 file provides support for the ngPIXIS, a board-specific FPGA used on + * some Freescale reference boards. + * + * A "switch" is black rectangular block on the motherboard. It contains + * eight "bits". The ngPIXIS has a set of memory-mapped registers (SWx) that + * shadow the actual physical switches. There is also another set of + * registers (ENx) that tell the ngPIXIS which bits of SWx should actually be + * used to override the values of the bits in the physical switches. + * + * The following macros need to be defined: + * + * PIXIS_BASE - The virtual address of the base of the PIXIS register map + * + * PIXIS_LBMAP_SWITCH - The switch number (i.e. the "x" in "SWx"). This value + * is used in the PIXIS_SW() macro to determine which offset in + * the PIXIS register map corresponds to the physical switch that controls + * the boot bank. + * + * PIXIS_LBMAP_MASK - A bit mask the defines which bits in SWx to use. + * + * PIXIS_LBMAP_SHIFT - The shift value that corresponds to PIXIS_LBMAP_MASK. + * + * PIXIS_LBMAP_ALTBANK - The value to program into SWx to tell the ngPIXIS to + * boot from the alternate bank. + */ + +#include <common.h> +#include <command.h> +#include <watchdog.h> +#include <asm/cache.h> +#include <asm/io.h> + +#include "ngpixis.h" + +/* + * Reset the board. This ignores the ENx registers. + */ +void pixis_reset(void) +{ + out_8(&pixis->rst, 0); + + while (1); +} + +/* + * Reset the board. Like pixis_reset(), but it honors the ENx registers. + */ +void pixis_bank_reset(void) +{ + out_8(&pixis->vctl, 0); + out_8(&pixis->vctl, 1); + + while (1); +} + +/** + * Set the boot bank to the power-on default bank + */ +void clear_altbank(void) +{ + /* Tell the ngPIXIS to use this the bits in the physical switch for the + * boot bank value, instead of the SWx register. We need to be careful + * only to set the bits in SWx that correspond to the boot bank. + */ + clrbits_8(&PIXIS_EN(PIXIS_LBMAP_SWITCH), PIXIS_LBMAP_MASK); +} + +/** + * Set the boot bank to the alternate bank + */ +void set_altbank(void) +{ + /* Program the alternate bank number into the SWx register. + */ + clrsetbits_8(&PIXIS_SW(PIXIS_LBMAP_SWITCH), PIXIS_LBMAP_MASK, + PIXIS_LBMAP_ALTBANK); + + /* Tell the ngPIXIS to use this the bits in the SWx register for the + * boot bank value, instead of the physical switch. We need to be + * careful only to set the bits in SWx that correspond to the boot bank. + */ + setbits_8(&PIXIS_EN(PIXIS_LBMAP_SWITCH), PIXIS_LBMAP_MASK); +} + + +int pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unsigned int i; + char *p_altbank = NULL; + char *unknown_param = NULL; + + /* No args is a simple reset request. + */ + if (argc <= 1) + pixis_reset(); + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "altbank") == 0) { + p_altbank = argv[i]; + continue; + } + + unknown_param = argv[i]; + } + + if (unknown_param) { + printf("Invalid option: %s\n", unknown_param); + return 1; + } + + if (p_altbank) + set_altbank(); + else + clear_altbank(); + + pixis_bank_reset(); + + /* Shouldn't be reached. */ + return 0; +} + +U_BOOT_CMD( + pixis_reset, CONFIG_SYS_MAXARGS, 1, pixis_reset_cmd, + "Reset the board using the FPGA sequencer", + "- hard reset to default bank\n" + "pixis_reset altbank - reset to alternate bank\n" + ); diff --git a/u-boot/board/freescale/common/ngpixis.h b/u-boot/board/freescale/common/ngpixis.h new file mode 100644 index 000000000..089408b76 --- /dev/null +++ b/u-boot/board/freescale/common/ngpixis.h @@ -0,0 +1,57 @@ +/** + * Copyright 2010 Freescale Semiconductor + * Author: Timur Tabi <timur@freescale.com> + * + * 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 file provides support for the ngPIXIS, a board-specific FPGA used on + * some Freescale reference boards. + */ + +/* ngPIXIS register set. Hopefully, this won't change too much over time. + * Feel free to add board-specific #ifdefs where necessary. + */ +typedef struct ngpixis { + u8 id; + u8 arch; + u8 scver; + u8 csr; + u8 rst; + u8 res1; + u8 aux; + u8 spd; + u8 brdcfg0; + u8 brdcfg1; /* On some boards, this register is called 'dma' */ + u8 addr; + u8 res2[2]; + u8 data; + u8 led; + u8 res3; + u8 vctl; + u8 vstat; + u8 vcfgen0; + u8 res4; + u8 ocmcsr; + u8 ocmmsg; + u8 gmdbg; + u8 res5[2]; + u8 sclk[3]; + u8 dclk[3]; + u8 watch; + struct { + u8 sw; + u8 en; + } s[8]; +} __attribute__ ((packed)) ngpixis_t; + +/* Pointer to the PIXIS register set */ +#define pixis ((ngpixis_t *)PIXIS_BASE) + +/* The PIXIS SW register that corresponds to board switch X, where x >= 1 */ +#define PIXIS_SW(x) (pixis->s[(x) - 1].sw) + +/* The PIXIS EN register that corresponds to board switch X, where x >= 1 */ +#define PIXIS_EN(x) (pixis->s[(x) - 1].en) diff --git a/u-boot/board/freescale/common/pixis.c b/u-boot/board/freescale/common/pixis.c new file mode 100644 index 000000000..a35b5cfe3 --- /dev/null +++ b/u-boot/board/freescale/common/pixis.c @@ -0,0 +1,558 @@ +/* + * Copyright 2006,2010 Freescale Semiconductor + * Jeff Brown + * Srikanth Srinivasan (srikanth.srinivasan@freescale.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 + */ + +#include <common.h> +#include <command.h> +#include <asm/io.h> + +#define pixis_base (u8 *)PIXIS_BASE + +/* + * Simple board reset. + */ +void pixis_reset(void) +{ + out_8(pixis_base + PIXIS_RST, 0); + + while (1); +} + +/* + * Per table 27, page 58 of MPC8641HPCN spec. + */ +static int set_px_sysclk(unsigned long sysclk) +{ + u8 sysclk_s, sysclk_r, sysclk_v, vclkh, vclkl, sysclk_aux; + + switch (sysclk) { + case 33: + sysclk_s = 0x04; + sysclk_r = 0x04; + sysclk_v = 0x07; + sysclk_aux = 0x00; + break; + case 40: + sysclk_s = 0x01; + sysclk_r = 0x1F; + sysclk_v = 0x20; + sysclk_aux = 0x01; + break; + case 50: + sysclk_s = 0x01; + sysclk_r = 0x1F; + sysclk_v = 0x2A; + sysclk_aux = 0x02; + break; + case 66: + sysclk_s = 0x01; + sysclk_r = 0x04; + sysclk_v = 0x04; + sysclk_aux = 0x03; + break; + case 83: + sysclk_s = 0x01; + sysclk_r = 0x1F; + sysclk_v = 0x4B; + sysclk_aux = 0x04; + break; + case 100: + sysclk_s = 0x01; + sysclk_r = 0x1F; + sysclk_v = 0x5C; + sysclk_aux = 0x05; + break; + case 134: + sysclk_s = 0x06; + sysclk_r = 0x1F; + sysclk_v = 0x3B; + sysclk_aux = 0x06; + break; + case 166: + sysclk_s = 0x06; + sysclk_r = 0x1F; + sysclk_v = 0x4B; + sysclk_aux = 0x07; + break; + default: + printf("Unsupported SYSCLK frequency.\n"); + return 0; + } + + vclkh = (sysclk_s << 5) | sysclk_r; + vclkl = sysclk_v; + + out_8(pixis_base + PIXIS_VCLKH, vclkh); + out_8(pixis_base + PIXIS_VCLKL, vclkl); + + out_8(pixis_base + PIXIS_AUX, sysclk_aux); + + return 1; +} + +/* Set the CFG_SYSPLL bits + * + * This only has effect if PX_VCFGEN0[SYSPLL]=1, which is true if + * read_from_px_regs() is called. + */ +static int set_px_mpxpll(unsigned long mpxpll) +{ + switch (mpxpll) { + case 2: + case 4: + case 6: + case 8: + case 10: + case 12: + case 14: + case 16: + clrsetbits_8(pixis_base + PIXIS_VSPEED1, 0x1F, mpxpll); + return 1; + } + + printf("Unsupported MPXPLL ratio.\n"); + return 0; +} + +static int set_px_corepll(unsigned long corepll) +{ + u8 val; + + switch (corepll) { + case 20: + val = 0x08; + break; + case 25: + val = 0x0C; + break; + case 30: + val = 0x10; + break; + case 35: + val = 0x1C; + break; + case 40: + val = 0x14; + break; + case 45: + val = 0x0E; + break; + default: + printf("Unsupported COREPLL ratio.\n"); + return 0; + } + + clrsetbits_8(pixis_base + PIXIS_VSPEED0, 0x1F, val); + return 1; +} + +#ifndef CONFIG_SYS_PIXIS_VCFGEN0_ENABLE +#define CONFIG_SYS_PIXIS_VCFGEN0_ENABLE 0x1C +#endif + +/* Tell the PIXIS where to find the COREPLL, MPXPLL, SYSCLK values + * + * The PIXIS can be programmed to look at either the on-board dip switches + * or various other PIXIS registers to determine the values for COREPLL, + * MPXPLL, and SYSCLK. + * + * CONFIG_SYS_PIXIS_VCFGEN0_ENABLE is the value to write to the PIXIS_VCFGEN0 + * register that tells the pixis to use the various PIXIS register. + */ +static void read_from_px_regs(int set) +{ + u8 tmp = in_8(pixis_base + PIXIS_VCFGEN0); + + if (set) + tmp = tmp | CONFIG_SYS_PIXIS_VCFGEN0_ENABLE; + else + tmp = tmp & ~CONFIG_SYS_PIXIS_VCFGEN0_ENABLE; + + out_8(pixis_base + PIXIS_VCFGEN0, tmp); +} + +/* CONFIG_SYS_PIXIS_VBOOT_ENABLE is the value to write to the PX_VCFGEN1 + * register that tells the pixis to use the PX_VBOOT[LBMAP] register. + */ +#ifndef CONFIG_SYS_PIXIS_VBOOT_ENABLE +#define CONFIG_SYS_PIXIS_VBOOT_ENABLE 0x04 +#endif + +/* Configure the source of the boot location + * + * The PIXIS can be programmed to look at either the on-board dip switches + * or the PX_VBOOT[LBMAP] register to determine where we should boot. + * + * If we want to boot from the alternate boot bank, we need to tell the PIXIS + * to ignore the on-board dip switches and use the PX_VBOOT[LBMAP] instead. + */ +static void read_from_px_regs_altbank(int set) +{ + u8 tmp = in_8(pixis_base + PIXIS_VCFGEN1); + + if (set) + tmp = tmp | CONFIG_SYS_PIXIS_VBOOT_ENABLE; + else + tmp = tmp & ~CONFIG_SYS_PIXIS_VBOOT_ENABLE; + + out_8(pixis_base + PIXIS_VCFGEN1, tmp); +} + +/* CONFIG_SYS_PIXIS_VBOOT_MASK contains the bits to set in VBOOT register that + * tells the PIXIS what the alternate flash bank is. + * + * Note that it's not really a mask. It contains the actual LBMAP bits that + * must be set to select the alternate bank. This code assumes that the + * primary bank has these bits set to 0, and the alternate bank has these + * bits set to 1. + */ +#ifndef CONFIG_SYS_PIXIS_VBOOT_MASK +#define CONFIG_SYS_PIXIS_VBOOT_MASK (0x40) +#endif + +/* Tell the PIXIS to boot from the default flash bank + * + * Program the default flash bank into the VBOOT register. This register is + * used only if PX_VCFGEN1[FLASH]=1. + */ +static void clear_altbank(void) +{ + clrbits_8(pixis_base + PIXIS_VBOOT, CONFIG_SYS_PIXIS_VBOOT_MASK); +} + +/* Tell the PIXIS to boot from the alternate flash bank + * + * Program the alternate flash bank into the VBOOT register. This register is + * used only if PX_VCFGEN1[FLASH]=1. + */ +static void set_altbank(void) +{ + setbits_8(pixis_base + PIXIS_VBOOT, CONFIG_SYS_PIXIS_VBOOT_MASK); +} + +/* Reset the board with watchdog disabled. + * + * This respects the altbank setting. + */ +static void set_px_go(void) +{ + /* Disable the VELA sequencer and watchdog */ + clrbits_8(pixis_base + PIXIS_VCTL, 9); + + /* Reboot by starting the VELA sequencer */ + setbits_8(pixis_base + PIXIS_VCTL, 0x1); + + while (1); +} + +/* Reset the board with watchdog enabled. + * + * This respects the altbank setting. + */ +static void set_px_go_with_watchdog(void) +{ + /* Disable the VELA sequencer */ + clrbits_8(pixis_base + PIXIS_VCTL, 1); + + /* Enable the watchdog and reboot by starting the VELA sequencer */ + setbits_8(pixis_base + PIXIS_VCTL, 0x9); + + while (1); +} + +/* Disable the watchdog + * + */ +static int pixis_disable_watchdog_cmd(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + /* Disable the VELA sequencer and the watchdog */ + clrbits_8(pixis_base + PIXIS_VCTL, 9); + + return 0; +} + +U_BOOT_CMD( + diswd, 1, 0, pixis_disable_watchdog_cmd, + "Disable watchdog timer", + "" +); + +#ifdef CONFIG_PIXIS_SGMII_CMD + +/* Enable or disable SGMII mode for a TSEC + */ +static int pixis_set_sgmii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int which_tsec = -1; + unsigned char mask; + unsigned char switch_mask; + + if ((argc > 2) && (strcmp(argv[1], "all") != 0)) + which_tsec = simple_strtoul(argv[1], NULL, 0); + + switch (which_tsec) { +#ifdef CONFIG_TSEC1 + case 1: + mask = PIXIS_VSPEED2_TSEC1SER; + switch_mask = PIXIS_VCFGEN1_TSEC1SER; + break; +#endif +#ifdef CONFIG_TSEC2 + case 2: + mask = PIXIS_VSPEED2_TSEC2SER; + switch_mask = PIXIS_VCFGEN1_TSEC2SER; + break; +#endif +#ifdef CONFIG_TSEC3 + case 3: + mask = PIXIS_VSPEED2_TSEC3SER; + switch_mask = PIXIS_VCFGEN1_TSEC3SER; + break; +#endif +#ifdef CONFIG_TSEC4 + case 4: + mask = PIXIS_VSPEED2_TSEC4SER; + switch_mask = PIXIS_VCFGEN1_TSEC4SER; + break; +#endif + default: + mask = PIXIS_VSPEED2_MASK; + switch_mask = PIXIS_VCFGEN1_MASK; + break; + } + + /* Toggle whether the switches or FPGA control the settings */ + if (!strcmp(argv[argc - 1], "switch")) + clrbits_8(pixis_base + PIXIS_VCFGEN1, switch_mask); + else + setbits_8(pixis_base + PIXIS_VCFGEN1, switch_mask); + + /* If it's not the switches, enable or disable SGMII, as specified */ + if (!strcmp(argv[argc - 1], "on")) + clrbits_8(pixis_base + PIXIS_VSPEED2, mask); + else if (!strcmp(argv[argc - 1], "off")) + setbits_8(pixis_base + PIXIS_VSPEED2, mask); + + return 0; +} + +U_BOOT_CMD( + pixis_set_sgmii, CONFIG_SYS_MAXARGS, 1, pixis_set_sgmii, + "pixis_set_sgmii" + " - Enable or disable SGMII mode for a given TSEC \n", + "\npixis_set_sgmii [TSEC num] <on|off|switch>\n" + " TSEC num: 1,2,3,4 or 'all'. 'all' is default.\n" + " on - enables SGMII\n" + " off - disables SGMII\n" + " switch - use switch settings" +); + +#endif + +/* + * This function takes the non-integral cpu:mpx pll ratio + * and converts it to an integer that can be used to assign + * FPGA register values. + * input: strptr i.e. argv[2] + */ +static unsigned long strfractoint(char *strptr) +{ + int i, j; + int mulconst; + int intarr_len, no_dec = 0; + unsigned long intval = 0, decval = 0; + char intarr[3], decarr[3]; + + /* Assign the integer part to intarr[] + * If there is no decimal point i.e. + * if the ratio is an integral value + * simply create the intarr. + */ + i = 0; + while (strptr[i] != '.') { + if (strptr[i] == 0) { + no_dec = 1; + break; + } + intarr[i] = strptr[i]; + i++; + } + + /* Assign length of integer part to intarr_len. */ + intarr_len = i; + intarr[i] = '\0'; + + if (no_dec) { + /* Currently needed only for single digit corepll ratios */ + mulconst = 10; + decval = 0; + } else { + j = 0; + i++; /* Skipping the decimal point */ + while ((strptr[i] >= '0') && (strptr[i] <= '9')) { + decarr[j] = strptr[i]; + i++; + j++; + } + + decarr[j] = '\0'; + + mulconst = 1; + for (i = 0; i < j; i++) + mulconst *= 10; + decval = simple_strtoul(decarr, NULL, 10); + } + + intval = simple_strtoul(intarr, NULL, 10); + intval = intval * mulconst; + + return intval + decval; +} + +static int pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unsigned int i; + char *p_cf = NULL; + char *p_cf_sysclk = NULL; + char *p_cf_corepll = NULL; + char *p_cf_mpxpll = NULL; + char *p_altbank = NULL; + char *p_wd = NULL; + int unknown_param = 0; + + /* + * No args is a simple reset request. + */ + if (argc <= 1) { + pixis_reset(); + /* not reached */ + } + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "cf") == 0) { + p_cf = argv[i]; + if (i + 3 >= argc) { + break; + } + p_cf_sysclk = argv[i+1]; + p_cf_corepll = argv[i+2]; + p_cf_mpxpll = argv[i+3]; + i += 3; + continue; + } + + if (strcmp(argv[i], "altbank") == 0) { + p_altbank = argv[i]; + continue; + } + + if (strcmp(argv[i], "wd") == 0) { + p_wd = argv[i]; + continue; + } + + unknown_param = 1; + } + + /* + * Check that cf has all required parms + */ + if ((p_cf && !(p_cf_sysclk && p_cf_corepll && p_cf_mpxpll)) + || unknown_param) { +#ifdef CONFIG_SYS_LONGHELP + puts(cmdtp->help); +#endif + return 1; + } + + /* + * PIXIS seems to be sensitive to the ordering of + * the registers that are touched. + */ + read_from_px_regs(0); + + if (p_altbank) + read_from_px_regs_altbank(0); + + clear_altbank(); + + /* + * Clock configuration specified. + */ + if (p_cf) { + unsigned long sysclk; + unsigned long corepll; + unsigned long mpxpll; + + sysclk = simple_strtoul(p_cf_sysclk, NULL, 10); + corepll = strfractoint(p_cf_corepll); + mpxpll = simple_strtoul(p_cf_mpxpll, NULL, 10); + + if (!(set_px_sysclk(sysclk) + && set_px_corepll(corepll) + && set_px_mpxpll(mpxpll))) { +#ifdef CONFIG_SYS_LONGHELP + puts(cmdtp->help); +#endif + return 1; + } + read_from_px_regs(1); + } + + /* + * Altbank specified + * + * NOTE CHANGE IN BEHAVIOR: previous code would default + * to enabling watchdog if altbank is specified. + * Now the watchdog must be enabled explicitly using 'wd'. + */ + if (p_altbank) { + set_altbank(); + read_from_px_regs_altbank(1); + } + + /* + * Reset with watchdog specified. + */ + if (p_wd) + set_px_go_with_watchdog(); + else + set_px_go(); + + /* + * Shouldn't be reached. + */ + return 0; +} + + +U_BOOT_CMD( + pixis_reset, CONFIG_SYS_MAXARGS, 1, pixis_reset_cmd, + "Reset the board using the FPGA sequencer", + " pixis_reset\n" + " pixis_reset [altbank]\n" + " pixis_reset altbank wd\n" + " pixis_reset altbank cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>\n" + " pixis_reset cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>" +); diff --git a/u-boot/board/freescale/common/pixis.h b/u-boot/board/freescale/common/pixis.h new file mode 100644 index 000000000..7f86de79d --- /dev/null +++ b/u-boot/board/freescale/common/pixis.h @@ -0,0 +1,182 @@ +/* + * Copyright 2010 Freescale Semiconductor, 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 + */ +#ifndef __PIXIS_H_ +#define __PIXIS_H_ 1 + +/* PIXIS register set. */ +#if defined(CONFIG_MPC8536DS) +typedef struct pixis { + u8 id; + u8 ver; + u8 pver; + u8 csr; + u8 rst; + u8 rst2; + u8 aux1; + u8 spd; + u8 aux2; + u8 csr2; + u8 watch; + u8 led; + u8 pwr; + u8 res[3]; + u8 vctl; + u8 vstat; + u8 vcfgen0; + u8 vcfgen1; + u8 vcore0; + u8 res1; + u8 vboot; + u8 vspeed[3]; + u8 sclk[3]; + u8 dclk[3]; + u8 i2cdacr; + u8 vcoreacc[4]; + u8 vcorecnt[3]; + u8 vcoremax[2]; + u8 vplatacc[4]; + u8 vplatcnt[3]; + u8 vplatmax[2]; + u8 vtempacc[4]; + u8 vtempcnt[3]; + u8 vtempmax[2]; + u8 res2[4]; +} __attribute__ ((packed)) pixis_t; + +#elif defined(CONFIG_MPC8544DS) +typedef struct pixis { + u8 id; + u8 ver; + u8 pver; + u8 csr; + u8 rst; + u8 pwr; + u8 aux1; + u8 spd; + u8 res[8]; + u8 vctl; + u8 vstat; + u8 vcfgen0; + u8 vcfgen1; + u8 vcore0; + u8 res1; + u8 vboot; + u8 vspeed[2]; + u8 vclkh; + u8 vclkl; + u8 watch; + u8 led; + u8 vspeed2; + u8 res2[34]; +} __attribute__ ((packed)) pixis_t; + +#elif defined(CONFIG_MPC8572DS) +typedef struct pixis { + u8 id; + u8 ver; + u8 pver; + u8 csr; + u8 rst; + u8 pwr1; + u8 aux1; + u8 spd; + u8 aux2; + u8 res[7]; + u8 vctl; + u8 vstat; + u8 vcfgen0; + u8 vcfgen1; + u8 vcore0; + u8 res1; + u8 vboot; + u8 vspeed[3]; + u8 res2[2]; + u8 sclk[3]; + u8 dclk[3]; + u8 res3[2]; + u8 watch; + u8 led; + u8 res4[25]; +} __attribute__ ((packed)) pixis_t; + +#elif defined(CONFIG_MPC8610HPCD) +typedef struct pixis { + u8 id; + u8 ver; /* also called arch */ + u8 pver; + u8 csr; + u8 rst; + u8 pwr; + u8 aux; + u8 spd; + u8 brdcfg0; + u8 brdcfg1; + u8 res[4]; + u8 led; + u8 serno; + u8 vctl; + u8 vstat; + u8 vcfgen0; + u8 vcfgen1; + u8 vcore0; + u8 res1; + u8 vboot; + u8 vspeed[2]; + u8 res2; + u8 sclk[3]; + u8 res3; + u8 watch; + u8 res4[33]; +} __attribute__ ((packed)) pixis_t; + +#elif defined(CONFIG_MPC8641HPCN) +typedef struct pixis { + u8 id; + u8 ver; + u8 pver; + u8 csr; + u8 rst; + u8 pwr; + u8 aux; + u8 spd; + u8 res[8]; + u8 vctl; + u8 vstat; + u8 vcfgen0; + u8 vcfgen1; + u8 vcore0; + u8 res1; + u8 vboot; + u8 vspeed[2]; + u8 vclkh; + u8 vclkl; + u8 watch; + u8 res3[36]; +} __attribute__ ((packed)) pixis_t; +#else +#error Need to define pixis_t for this board +#endif + +/* Pointer to the PIXIS register set */ +#define pixis ((pixis_t *)PIXIS_BASE) + +#endif /* __PIXIS_H_ */ diff --git a/u-boot/board/freescale/common/pq-mds-pib.c b/u-boot/board/freescale/common/pq-mds-pib.c new file mode 100644 index 000000000..5f7a67d05 --- /dev/null +++ b/u-boot/board/freescale/common/pq-mds-pib.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2007 Freescale Semiconductor, Inc. + * + * Tony Li <tony.li@freescale.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + */ + +#include <common.h> +#include <i2c.h> +#include <asm/io.h> + +#include "pq-mds-pib.h" + +int pib_init(void) +{ + u8 val8; + u8 orig_i2c_bus; + + /* Switch temporarily to I2C bus #2 */ + orig_i2c_bus = i2c_get_bus_num(); + i2c_set_bus_num(1); + + val8 = 0; +#if defined(CONFIG_PCI) && !defined(CONFIG_PCISLAVE) + /* Assign PIB PMC slot to desired PCI bus */ + i2c_write(0x23, 0x6, 1, &val8, 1); + i2c_write(0x23, 0x7, 1, &val8, 1); + val8 = 0xff; + i2c_write(0x23, 0x2, 1, &val8, 1); + i2c_write(0x23, 0x3, 1, &val8, 1); + + val8 = 0; + i2c_write(0x26, 0x6, 1, &val8, 1); + val8 = 0x34; + i2c_write(0x26, 0x7, 1, &val8, 1); +#if defined(CONFIG_MPC832XEMDS) + val8 = 0xf9; /* PMC2, PMC3 slot to PCI bus */ +#else + val8 = 0xf3; /* PMC1, PMC2, PMC3 slot to PCI bus */ +#endif + i2c_write(0x26, 0x2, 1, &val8, 1); + val8 = 0xff; + i2c_write(0x26, 0x3, 1, &val8, 1); + + val8 = 0; + i2c_write(0x27, 0x6, 1, &val8, 1); + i2c_write(0x27, 0x7, 1, &val8, 1); + val8 = 0xff; + i2c_write(0x27, 0x2, 1, &val8, 1); + val8 = 0xef; + i2c_write(0x27, 0x3, 1, &val8, 1); + + eieio(); + +#if defined(CONFIG_MPC832XEMDS) + printf("PCI 32bit bus on PMC2 &PMC3\n"); +#else + printf("PCI 32bit bus on PMC1 & PMC2 &PMC3\n"); +#endif +#endif + +#if defined(CONFIG_PQ_MDS_PIB_ATM) +#if defined(CONFIG_MPC8360EMDS) || defined(CONFIG_MPC8569MDS) + val8 = 0; + i2c_write(0x20, 0x6, 1, &val8, 1); + i2c_write(0x20, 0x7, 1, &val8, 1); + + val8 = 0xdf; + i2c_write(0x20, 0x2, 1, &val8, 1); + val8 = 0xf7; + i2c_write(0x20, 0x3, 1, &val8, 1); + + eieio(); + + printf("QOC3 ATM card on PMC0\n"); +#elif defined(CONFIG_MPC832XEMDS) + val8 = 0; + i2c_write(0x26, 0x7, 1, &val8, 1); + val8 = 0xf7; + i2c_write(0x26, 0x3, 1, &val8, 1); + + val8 = 0; + i2c_write(0x21, 0x6, 1, &val8, 1); + i2c_write(0x21, 0x7, 1, &val8, 1); + + val8 = 0xdf; + i2c_write(0x21, 0x2, 1, &val8, 1); + val8 = 0xef; + i2c_write(0x21, 0x3, 1, &val8, 1); + + eieio(); + + printf("QOC3 ATM card on PMC1\n"); +#endif +#endif + /* Reset to original I2C bus */ + i2c_set_bus_num(orig_i2c_bus); + return 0; +} diff --git a/u-boot/board/freescale/common/pq-mds-pib.h b/u-boot/board/freescale/common/pq-mds-pib.h new file mode 100644 index 000000000..67066fd11 --- /dev/null +++ b/u-boot/board/freescale/common/pq-mds-pib.h @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2007 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + */ + +extern int pib_init(void); diff --git a/u-boot/board/freescale/common/sgmii_riser.c b/u-boot/board/freescale/common/sgmii_riser.c new file mode 100644 index 000000000..4f40a1d6d --- /dev/null +++ b/u-boot/board/freescale/common/sgmii_riser.c @@ -0,0 +1,88 @@ +/* + * Freescale SGMII Riser Card + * + * This driver supports the SGMII Riser card found on the + * "DS" style of development board from Freescale. + * + * This software may be used and distributed according to the + * terms of the GNU Public License, Version 2, incorporated + * herein by reference. + * + * Copyright 2008 Freescale Semiconductor, Inc. + * + */ + +#include <config.h> +#include <common.h> +#include <net.h> +#include <libfdt.h> +#include <tsec.h> + +void fsl_sgmii_riser_init(struct tsec_info_struct *tsec_info, int num) +{ + int i; + + for (i = 0; i < num; i++) + if (tsec_info[i].flags & TSEC_SGMII) + tsec_info[i].phyaddr += SGMII_RISER_PHY_OFFSET; +} + +void fsl_sgmii_riser_fdt_fixup(void *fdt) +{ + struct eth_device *dev; + int node; + int i = -1; + int etsec_num = 0; + + node = fdt_path_offset(fdt, "/aliases"); + if (node < 0) + return; + + while ((dev = eth_get_dev_by_index(++i)) != NULL) { + struct tsec_private *priv; + int enet_node; + char enet[16]; + const u32 *phyh; + int phynode; + const char *model; + const char *path; + + if (!strstr(dev->name, "eTSEC")) + continue; + + sprintf(enet, "ethernet%d", etsec_num++); + path = fdt_getprop(fdt, node, enet, NULL); + if (!path) { + debug("No alias for %s\n", enet); + continue; + } + + enet_node = fdt_path_offset(fdt, path); + if (enet_node < 0) + continue; + + model = fdt_getprop(fdt, enet_node, "model", NULL); + + /* + * We only want to do this to eTSECs. On some platforms + * there are more than one type of gianfar-style ethernet + * controller, and as we are creating an implicit connection + * between ethernet nodes and eTSEC devices, it is best to + * make the connection use as much explicit information + * as exists. + */ + if (!strstr(model, "TSEC")) + continue; + + phyh = fdt_getprop(fdt, enet_node, "phy-handle", NULL); + if (!phyh) + continue; + + phynode = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*phyh)); + + priv = dev->priv; + + if (priv->flags & TSEC_SGMII) + fdt_setprop_cell(fdt, phynode, "reg", priv->phyaddr); + } +} diff --git a/u-boot/board/freescale/common/sgmii_riser.h b/u-boot/board/freescale/common/sgmii_riser.h new file mode 100644 index 000000000..e1fcc858f --- /dev/null +++ b/u-boot/board/freescale/common/sgmii_riser.h @@ -0,0 +1,16 @@ +/* + * Freescale SGMII Riser Card + * + * This driver supports the SGMII Riser card found on the + * "DS" style of development board from Freescale. + * + * This software may be used and distributed according to the + * terms of the GNU Public License, Version 2, incorporated + * herein by reference. + * + * Copyright 2008 Freescale Semiconductor, Inc. + * + */ + +void fsl_sgmii_riser_init(struct tsec_info_struct *tsec_info, int num); +void fsl_sgmii_riser_fdt_fixup(void *fdt); diff --git a/u-boot/board/freescale/common/sys_eeprom.c b/u-boot/board/freescale/common/sys_eeprom.c new file mode 100644 index 000000000..3ecfb06cc --- /dev/null +++ b/u-boot/board/freescale/common/sys_eeprom.c @@ -0,0 +1,524 @@ +/* + * Copyright 2006, 2008-2009 Freescale Semiconductor + * York Sun (yorksun@freescale.com) + * Haiying Wang (haiying.wang@freescale.com) + * Timur Tabi (timur@freescale.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 + */ + +#include <common.h> +#include <command.h> +#include <i2c.h> +#include <linux/ctype.h> + +#ifdef CONFIG_SYS_I2C_EEPROM_CCID +#include "../common/eeprom.h" +#define MAX_NUM_PORTS 8 +#endif + +#ifdef CONFIG_SYS_I2C_EEPROM_NXID +#define MAX_NUM_PORTS 8 +#define NXID_VERSION 0 +#endif + +#ifdef CONFIG_SYS_I2C_EEPROM_NXID_1 +#define CONFIG_SYS_I2C_EEPROM_NXID +#define MAX_NUM_PORTS 23 +#define NXID_VERSION 1 +#endif + +/** + * static eeprom: EEPROM layout for CCID or NXID formats + * + * See application note AN3638 for details. + */ +static struct __attribute__ ((__packed__)) eeprom { +#ifdef CONFIG_SYS_I2C_EEPROM_CCID + u8 id[4]; /* 0x00 - 0x03 EEPROM Tag 'CCID' */ + u8 major; /* 0x04 Board revision, major */ + u8 minor; /* 0x05 Board revision, minor */ + u8 sn[10]; /* 0x06 - 0x0F Serial Number*/ + u8 errata[2]; /* 0x10 - 0x11 Errata Level */ + u8 date[6]; /* 0x12 - 0x17 Build Date */ + u8 res_0[40]; /* 0x18 - 0x3f Reserved */ + u8 mac_count; /* 0x40 Number of MAC addresses */ + u8 mac_flag; /* 0x41 MAC table flags */ + u8 mac[MAX_NUM_PORTS][6]; /* 0x42 - 0x71 MAC addresses */ + u32 crc; /* 0x72 CRC32 checksum */ +#endif +#ifdef CONFIG_SYS_I2C_EEPROM_NXID + u8 id[4]; /* 0x00 - 0x03 EEPROM Tag 'NXID' */ + u8 sn[12]; /* 0x04 - 0x0F Serial Number */ + u8 errata[5]; /* 0x10 - 0x14 Errata Level */ + u8 date[6]; /* 0x15 - 0x1a Build Date */ + u8 res_0; /* 0x1b Reserved */ + u32 version; /* 0x1c - 0x1f NXID Version */ + u8 tempcal[8]; /* 0x20 - 0x27 Temperature Calibration Factors */ + u8 tempcalsys[2]; /* 0x28 - 0x29 System Temperature Calibration Factors */ + u8 tempcalflags; /* 0x2a Temperature Calibration Flags */ + u8 res_1[21]; /* 0x2b - 0x3f Reserved */ + u8 mac_count; /* 0x40 Number of MAC addresses */ + u8 mac_flag; /* 0x41 MAC table flags */ + u8 mac[MAX_NUM_PORTS][6]; /* 0x42 - x MAC addresses */ + u32 crc; /* x+1 CRC32 checksum */ +#endif +} e; + +/* Set to 1 if we've read EEPROM into memory */ +static int has_been_read = 0; + +#ifdef CONFIG_SYS_I2C_EEPROM_NXID +/* Is this a valid NXID EEPROM? */ +#define is_valid ((e.id[0] == 'N') || (e.id[1] == 'X') || \ + (e.id[2] == 'I') || (e.id[3] == 'D')) +#endif + +#ifdef CONFIG_SYS_I2C_EEPROM_CCID +/* Is this a valid CCID EEPROM? */ +#define is_valid ((e.id[0] == 'C') || (e.id[1] == 'C') || \ + (e.id[2] == 'I') || (e.id[3] == 'D')) +#endif + +/** + * show_eeprom - display the contents of the EEPROM + */ +static void show_eeprom(void) +{ + int i; + unsigned int crc; + + /* EEPROM tag ID, either CCID or NXID */ +#ifdef CONFIG_SYS_I2C_EEPROM_NXID + printf("ID: %c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3], + be32_to_cpu(e.version)); +#else + printf("ID: %c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]); +#endif + + /* Serial number */ + printf("SN: %s\n", e.sn); + + /* Errata level. */ +#ifdef CONFIG_SYS_I2C_EEPROM_NXID + printf("Errata: %s\n", e.errata); +#else + printf("Errata: %c%c\n", + e.errata[0] ? e.errata[0] : '.', + e.errata[1] ? e.errata[1] : '.'); +#endif + + /* Build date, BCD date values, as YYMMDDhhmmss */ + printf("Build date: 20%02x/%02x/%02x %02x:%02x:%02x %s\n", + e.date[0], e.date[1], e.date[2], + e.date[3] & 0x7F, e.date[4], e.date[5], + e.date[3] & 0x80 ? "PM" : ""); + + /* Show MAC addresses */ + for (i = 0; i < min(e.mac_count, MAX_NUM_PORTS); i++) { + + u8 *p = e.mac[i]; + + printf("Eth%u: %02x:%02x:%02x:%02x:%02x:%02x\n", i, + p[0], p[1], p[2], p[3], p[4], p[5]); + } + + crc = crc32(0, (void *)&e, sizeof(e) - 4); + + if (crc == be32_to_cpu(e.crc)) + printf("CRC: %08x\n", be32_to_cpu(e.crc)); + else + printf("CRC: %08x (should be %08x)\n", + be32_to_cpu(e.crc), crc); + +#ifdef DEBUG + printf("EEPROM dump: (0x%x bytes)\n", sizeof(e)); + for (i = 0; i < sizeof(e); i++) { + if ((i % 16) == 0) + printf("%02X: ", i); + printf("%02X ", ((u8 *)&e)[i]); + if (((i % 16) == 15) || (i == sizeof(e) - 1)) + printf("\n"); + } +#endif +} + +/** + * read_eeprom - read the EEPROM into memory + */ +static int read_eeprom(void) +{ + int ret; +#ifdef CONFIG_SYS_EEPROM_BUS_NUM + unsigned int bus; +#endif + + if (has_been_read) + return 0; + +#ifdef CONFIG_SYS_EEPROM_BUS_NUM + bus = i2c_get_bus_num(); + i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM); +#endif + + ret = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, CONFIG_SYS_I2C_EEPROM_ADDR_LEN, + (void *)&e, sizeof(e)); + +#ifdef CONFIG_SYS_EEPROM_BUS_NUM + i2c_set_bus_num(bus); +#endif + +#ifdef DEBUG + show_eeprom(); +#endif + + has_been_read = (ret == 0) ? 1 : 0; + + return ret; +} + +/** + * update_crc - update the CRC + * + * This function should be called after each update to the EEPROM structure, + * to make sure the CRC is always correct. + */ +static void update_crc(void) +{ + u32 crc; + + crc = crc32(0, (void *)&e, sizeof(e) - 4); + e.crc = cpu_to_be32(crc); +} + +/** + * prog_eeprom - write the EEPROM from memory + */ +static int prog_eeprom(void) +{ + int ret = 0; + int i; + void *p; +#ifdef CONFIG_SYS_EEPROM_BUS_NUM + unsigned int bus; +#endif + + /* Set the reserved values to 0xFF */ +#ifdef CONFIG_SYS_I2C_EEPROM_NXID + e.res_0 = 0xFF; + memset(e.res_1, 0xFF, sizeof(e.res_1)); +#else + memset(e.res_0, 0xFF, sizeof(e.res_0)); +#endif + update_crc(); + +#ifdef CONFIG_SYS_EEPROM_BUS_NUM + bus = i2c_get_bus_num(); + i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM); +#endif + + /* + * The AT24C02 datasheet says that data can only be written in page + * mode, which means 8 bytes at a time, and it takes up to 5ms to + * complete a given write. + */ + for (i = 0, p = &e; i < sizeof(e); i += 8, p += 8) { + ret = i2c_write(CONFIG_SYS_I2C_EEPROM_ADDR, i, CONFIG_SYS_I2C_EEPROM_ADDR_LEN, + p, min((sizeof(e) - i), 8)); + if (ret) + break; + udelay(5000); /* 5ms write cycle timing */ + } + + if (!ret) { + /* Verify the write by reading back the EEPROM and comparing */ + struct eeprom e2; + + ret = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, + CONFIG_SYS_I2C_EEPROM_ADDR_LEN, (void *)&e2, sizeof(e2)); + if (!ret && memcmp(&e, &e2, sizeof(e))) + ret = -1; + } + +#ifdef CONFIG_SYS_EEPROM_BUS_NUM + i2c_set_bus_num(bus); +#endif + + if (ret) { + printf("Programming failed.\n"); + has_been_read = 0; + return -1; + } + + printf("Programming passed.\n"); + return 0; +} + +/** + * h2i - converts hex character into a number + * + * This function takes a hexadecimal character (e.g. '7' or 'C') and returns + * the integer equivalent. + */ +static inline u8 h2i(char p) +{ + if ((p >= '0') && (p <= '9')) + return p - '0'; + + if ((p >= 'A') && (p <= 'F')) + return (p - 'A') + 10; + + if ((p >= 'a') && (p <= 'f')) + return (p - 'a') + 10; + + return 0; +} + +/** + * set_date - stores the build date into the EEPROM + * + * This function takes a pointer to a string in the format "YYMMDDhhmmss" + * (2-digit year, 2-digit month, etc), converts it to a 6-byte BCD string, + * and stores it in the build date field of the EEPROM local copy. + */ +static void set_date(const char *string) +{ + unsigned int i; + + if (strlen(string) != 12) { + printf("Usage: mac date YYMMDDhhmmss\n"); + return; + } + + for (i = 0; i < 6; i++) + e.date[i] = h2i(string[2 * i]) << 4 | h2i(string[2 * i + 1]); + + update_crc(); +} + +/** + * set_mac_address - stores a MAC address into the EEPROM + * + * This function takes a pointer to MAC address string + * (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number) and + * stores it in one of the MAC address fields of the EEPROM local copy. + */ +static void set_mac_address(unsigned int index, const char *string) +{ + char *p = (char *) string; + unsigned int i; + + if ((index >= MAX_NUM_PORTS) || !string) { + printf("Usage: mac <n> XX:XX:XX:XX:XX:XX\n"); + return; + } + + for (i = 0; *p && (i < 6); i++) { + e.mac[index][i] = simple_strtoul(p, &p, 16); + if (*p == ':') + p++; + } + + update_crc(); +} + +int do_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + char cmd; + + if (argc == 1) { + show_eeprom(); + return 0; + } + + cmd = argv[1][0]; + + if (cmd == 'r') { + read_eeprom(); + return 0; + } + + if (cmd == 'i') { +#ifdef CONFIG_SYS_I2C_EEPROM_NXID + memcpy(e.id, "NXID", sizeof(e.id)); + e.version = NXID_VERSION; +#else + memcpy(e.id, "CCID", sizeof(e.id)); +#endif + update_crc(); + return 0; + } + + if (!is_valid) { + printf("Please read the EEPROM ('r') and/or set the ID ('i') first.\n"); + return 0; + } + + if (argc == 2) { + switch (cmd) { + case 's': /* save */ + prog_eeprom(); + break; + default: + return cmd_usage(cmdtp); + } + + return 0; + } + + /* We know we have at least one parameter */ + + switch (cmd) { + case 'n': /* serial number */ + memset(e.sn, 0, sizeof(e.sn)); + strncpy((char *)e.sn, argv[2], sizeof(e.sn) - 1); + update_crc(); + break; + case 'e': /* errata */ +#ifdef CONFIG_SYS_I2C_EEPROM_NXID + memset(e.errata, 0, 5); + strncpy((char *)e.errata, argv[2], 4); +#else + e.errata[0] = argv[2][0]; + e.errata[1] = argv[2][1]; +#endif + update_crc(); + break; + case 'd': /* date BCD format YYMMDDhhmmss */ + set_date(argv[2]); + break; + case 'p': /* MAC table size */ + e.mac_count = simple_strtoul(argv[2], NULL, 16); + update_crc(); + break; + case '0' ... '9': /* "mac 0" through "mac 22" */ + set_mac_address(simple_strtoul(argv[1], NULL, 10), argv[2]); + break; + case 'h': /* help */ + default: + return cmd_usage(cmdtp); + } + + return 0; +} + +/** + * mac_read_from_eeprom - read the MAC addresses from EEPROM + * + * This function reads the MAC addresses from EEPROM and sets the + * appropriate environment variables for each one read. + * + * The environment variables are only set if they haven't been set already. + * This ensures that any user-saved variables are never overwritten. + * + * This function must be called after relocation. + */ +int mac_read_from_eeprom(void) +{ + unsigned int i; + u32 crc; + + puts("EEPROM: "); + + if (read_eeprom()) { + printf("Read failed.\n"); + return -1; + } + + if (!is_valid) { + printf("Invalid ID (%02x %02x %02x %02x)\n", + e.id[0], e.id[1], e.id[2], e.id[3]); + return -1; + } + + crc = crc32(0, (void *)&e, sizeof(e) - 4); + if (crc != be32_to_cpu(e.crc)) { + printf("CRC mismatch (%08x != %08x)\n", crc, be32_to_cpu(e.crc)); + return -1; + } + + for (i = 0; i < min(e.mac_count, MAX_NUM_PORTS); i++) { + if (memcmp(&e.mac[i], "\0\0\0\0\0\0", 6) && + memcmp(&e.mac[i], "\xFF\xFF\xFF\xFF\xFF\xFF", 6)) { + char ethaddr[18]; + char enetvar[9]; + + sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X", + e.mac[i][0], + e.mac[i][1], + e.mac[i][2], + e.mac[i][3], + e.mac[i][4], + e.mac[i][5]); + sprintf(enetvar, i ? "eth%daddr" : "ethaddr", i); + /* Only initialize environment variables that are blank + * (i.e. have not yet been set) + */ + if (!getenv(enetvar)) + setenv(enetvar, ethaddr); + } + } + +#ifdef CONFIG_SYS_I2C_EEPROM_NXID + printf("%c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3], + be32_to_cpu(e.version)); +#else + printf("%c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]); +#endif + + return 0; +} + +#ifdef CONFIG_SYS_I2C_EEPROM_CCID + +/** + * get_cpu_board_revision - get the CPU board revision on 85xx boards + * + * Read the EEPROM to determine the board revision. + * + * This function is called before relocation, so we need to read a private + * copy of the EEPROM into a local variable on the stack. + * + * Also, we assume that CONFIG_SYS_EEPROM_BUS_NUM == CONFIG_SYS_SPD_BUS_NUM. The global + * variable i2c_bus_num must be compile-time initialized to CONFIG_SYS_SPD_BUS_NUM, + * so that the SPD code will work. This means that all pre-relocation I2C + * operations can only occur on the CONFIG_SYS_SPD_BUS_NUM bus. So if + * CONFIG_SYS_EEPROM_BUS_NUM != CONFIG_SYS_SPD_BUS_NUM, then we can't read the EEPROM when + * this function is called. Oh well. + */ +unsigned int get_cpu_board_revision(void) +{ + struct board_eeprom { + u32 id; /* 0x00 - 0x03 EEPROM Tag 'CCID' */ + u8 major; /* 0x04 Board revision, major */ + u8 minor; /* 0x05 Board revision, minor */ + } be; + + i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, CONFIG_SYS_I2C_EEPROM_ADDR_LEN, + (void *)&be, sizeof(be)); + + if (be.id != (('C' << 24) | ('C' << 16) | ('I' << 8) | 'D')) + return MPC85XX_CPU_BOARD_REV(0, 0); + + if ((be.major == 0xff) && (be.minor == 0xff)) + return MPC85XX_CPU_BOARD_REV(0, 0); + + return MPC85XX_CPU_BOARD_REV(be.major, be.minor); +} +#endif diff --git a/u-boot/board/freescale/common/via.h b/u-boot/board/freescale/common/via.h new file mode 100644 index 000000000..77cfacc52 --- /dev/null +++ b/u-boot/board/freescale/common/via.h @@ -0,0 +1,18 @@ +#ifndef _MPC85xx_VIA_H +void mpc85xx_config_via(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab); + +/* Function 1, IDE */ +void mpc85xx_config_via_usbide(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab); + +/* Function 2, USB ports 0-1 */ +void mpc85xx_config_via_usb(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab); + +/* Function 3, USB ports 2-3 */ +void mpc85xx_config_via_usb2(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab); + +/* Function 5, Power Management */ +void mpc85xx_config_via_power(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab); + +/* Function 6, AC97 Interface */ +void mpc85xx_config_via_ac97(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab); +#endif /* _MPC85xx_VIA_H */ |