diff options
Diffstat (limited to 'qemu/roms/u-boot/board/freescale/p2041rdb')
-rw-r--r-- | qemu/roms/u-boot/board/freescale/p2041rdb/Makefile | 12 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/freescale/p2041rdb/README | 123 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/freescale/p2041rdb/cpld.c | 158 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/freescale/p2041rdb/cpld.h | 55 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/freescale/p2041rdb/ddr.c | 140 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/freescale/p2041rdb/eth.c | 201 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/freescale/p2041rdb/p2041rdb.c | 236 |
7 files changed, 925 insertions, 0 deletions
diff --git a/qemu/roms/u-boot/board/freescale/p2041rdb/Makefile b/qemu/roms/u-boot/board/freescale/p2041rdb/Makefile new file mode 100644 index 000000000..c74f4c62f --- /dev/null +++ b/qemu/roms/u-boot/board/freescale/p2041rdb/Makefile @@ -0,0 +1,12 @@ +# +# Copyright 2011 Freescale Semiconductor, Inc. +# (C) Copyright 2001-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += p2041rdb.o +obj-y += cpld.o +obj-y += ddr.o +obj-y += eth.o diff --git a/qemu/roms/u-boot/board/freescale/p2041rdb/README b/qemu/roms/u-boot/board/freescale/p2041rdb/README new file mode 100644 index 000000000..9b5539fff --- /dev/null +++ b/qemu/roms/u-boot/board/freescale/p2041rdb/README @@ -0,0 +1,123 @@ +Overview +========= +The P2041 Processor combines four Power Architecture processor cores +with high-performance datapath acceleration architecture(DPAA), CoreNet +fabric infrastructure, as well as network and peripheral bus interfaces +required for networking, telecom/datacom, wireless infrastructure, and +military/aerospace applications. + +P2041RDB board is a quad core platform supporting the P2041 processor +of QorIQ DPAA series. + +Boot from NOR flash +=================== +1. Build image + make P2041RDB_config + make all + +2. Program image + => tftp 1000000 u-boot.bin + => protect off all + => erase eff40000 efffffff + => cp.b 1000000 eff40000 c0000 + +3. Program RCW + => tftp 1000000 rcw.bin + => protect off all + => erase e8000000 e801ffff + => cp.b 1000000 e8000000 50 + +4. Program FMAN Firmware ucode + => tftp 1000000 ucode.bin + => protect off all + => erase eff00000 eff3ffff + => cp.b 1000000 eff00000 2000 + +5. Change DIP-switch + SW1[1-5] = 10110 + Note: 1 stands for 'on', 0 stands for 'off' + +Boot from SDCard +=================== +1. Build image + make P2041RDB_SDCARD_config + make all + +2. Generate PBL imge + Use PE tool to produce a image used to be programed to + SDCard which contains RCW and U-Boot image. + +3. Program the PBL image to SDCard + => tftp 1000000 pbl_sd.bin + => mmcinfo + => mmc write 1000000 8 672 + +4. Program FMAN Firmware ucode + => tftp 1000000 ucode.bin + => mmc write 1000000 690 10 + +5. Change DIP-switch + SW1[1-5] = 01100 + Note: 1 stands for 'on', 0 stands for 'off' + +Boot from SPI flash +=================== +1. Build image + make P2041RDB_SPIFLASH_config + make all + +2. Generate PBL imge + Use PE tool to produce a image used to be programed to + SPI flash which contains RCW and U-Boot image. + +3. Program the PBL image to SPI flash + => tftp 1000000 pbl_spi.bin + => spi probe 0 + => sf erase 0 100000 + => sf write 1000000 0 $filesize + +4. Program FMAN Firmware ucode + => tftp 1000000 ucode.bin + => sf erase 110000 10000 + => sf write 1000000 110000 $filesize + +5. Change DIP-switch + SW1[1-5] = 10100 + Note: 1 stands for 'on', 0 stands for 'off' + +CPLD command +============ +The CPLD is used to control the power sequence and some serdes lane +mux function. + +cpld reset - hard reset to default bank +cpld reset altbank - reset to alternate bank +cpld lane_mux <lane> <mux_value> - set multiplexed lane pin + lane 6: 0 -> slot1 (Default) + 1 -> SGMII + lane a: 0 -> slot2 (Default) + 1 -> AURORA + lane c: 0 -> slot2 (Default) + 1 -> SATA0 + lane d: 0 -> slot2 (Default) + 1 -> SATA1 + +Using the Device Tree Source File +================================= +To create the DTB (Device Tree Binary) image file, use a command +similar to this: + dtc -O dtb -b 0 -p 1024 p2041rdb.dts > p2041rdb.dtb + +Or use the following command: + {linux-2.6}/make p2041rdb.dtb ARCH=powerpc + +then the dtb file will be generated under the following directory: + {linux-2.6}/arch/powerpc/boot/p2041rdb.dtb + +Booting Linux +============= +Place a linux uImage in the TFTP disk area. + tftp 1000000 uImage + tftp 2000000 rootfs.ext2.gz.uboot + tftp 3000000 p2041rdb.dtb + bootm 1000000 2000000 3000000 diff --git a/qemu/roms/u-boot/board/freescale/p2041rdb/cpld.c b/qemu/roms/u-boot/board/freescale/p2041rdb/cpld.c new file mode 100644 index 000000000..34901aa3c --- /dev/null +++ b/qemu/roms/u-boot/board/freescale/p2041rdb/cpld.c @@ -0,0 +1,158 @@ +/** + * Copyright 2011 Freescale Semiconductor + * Author: Mingkai Hu <Mingkai.hu@freescale.com> + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This file provides support for the board-specific CPLD used on some Freescale + * reference boards. + * + * The following macros need to be defined: + * + * CPLD_BASE - The virtual address of the base of the CPLD register map + */ + +#include <common.h> +#include <command.h> +#include <asm/io.h> + +#include "cpld.h" + +static u8 __cpld_read(unsigned int reg) +{ + void *p = (void *)CPLD_BASE; + + return in_8(p + reg); +} +u8 cpld_read(unsigned int reg) __attribute__((weak, alias("__cpld_read"))); + +static void __cpld_write(unsigned int reg, u8 value) +{ + void *p = (void *)CPLD_BASE; + + out_8(p + reg, value); +} +void cpld_write(unsigned int reg, u8 value) + __attribute__((weak, alias("__cpld_write"))); + +/* + * Reset the board. This honors the por_cfg registers. + */ +void __cpld_reset(void) +{ + CPLD_WRITE(system_rst, 1); +} +void cpld_reset(void) __attribute__((weak, alias("__cpld_reset"))); + +/** + * Set the boot bank to the alternate bank + */ +void __cpld_set_altbank(void) +{ + u8 reg5 = CPLD_READ(sw_ctl_on); + + CPLD_WRITE(sw_ctl_on, reg5 | CPLD_SWITCH_BANK_ENABLE); + CPLD_WRITE(fbank_sel, 1); + CPLD_WRITE(system_rst, 1); +} +void cpld_set_altbank(void) + __attribute__((weak, alias("__cpld_set_altbank"))); + +/** + * Set the boot bank to the default bank + */ +void __cpld_set_defbank(void) +{ + CPLD_WRITE(system_rst_default, 1); +} +void cpld_set_defbank(void) + __attribute__((weak, alias("__cpld_set_defbank"))); + +#ifdef DEBUG +static void cpld_dump_regs(void) +{ + printf("cpld_ver = 0x%02x\n", CPLD_READ(cpld_ver)); + printf("cpld_ver_sub = 0x%02x\n", CPLD_READ(cpld_ver_sub)); + printf("pcba_ver = 0x%02x\n", CPLD_READ(pcba_ver)); + printf("system_rst = 0x%02x\n", CPLD_READ(system_rst)); + printf("sw_ctl_on = 0x%02x\n", CPLD_READ(sw_ctl_on)); + printf("por_cfg = 0x%02x\n", CPLD_READ(por_cfg)); + printf("switch_strobe = 0x%02x\n", CPLD_READ(switch_strobe)); + printf("jtag_sel = 0x%02x\n", CPLD_READ(jtag_sel)); + printf("sdbank1_clk = 0x%02x\n", CPLD_READ(sdbank1_clk)); + printf("sdbank2_clk = 0x%02x\n", CPLD_READ(sdbank2_clk)); + printf("fbank_sel = 0x%02x\n", CPLD_READ(fbank_sel)); + printf("serdes_mux = 0x%02x\n", CPLD_READ(serdes_mux)); + printf("SW[2] = 0x%02x\n", in_8(&CPLD_SW(2))); + putc('\n'); +} +#endif + +int cpld_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int rc = 0; + + if (argc <= 1) + return cmd_usage(cmdtp); + + if (strcmp(argv[1], "reset") == 0) { + if (strcmp(argv[2], "altbank") == 0) + cpld_set_altbank(); + else + cpld_set_defbank(); + } else if (strcmp(argv[1], "lane_mux") == 0) { + u32 lane = simple_strtoul(argv[2], NULL, 16); + u8 val = (u8)simple_strtoul(argv[3], NULL, 16); + u8 reg = CPLD_READ(serdes_mux); + + switch (lane) { + case 0x6: + reg &= ~SERDES_MUX_LANE_6_MASK; + reg |= val << SERDES_MUX_LANE_6_SHIFT; + break; + case 0xa: + reg &= ~SERDES_MUX_LANE_A_MASK; + reg |= val << SERDES_MUX_LANE_A_SHIFT; + break; + case 0xc: + reg &= ~SERDES_MUX_LANE_C_MASK; + reg |= val << SERDES_MUX_LANE_C_SHIFT; + break; + case 0xd: + reg &= ~SERDES_MUX_LANE_D_MASK; + reg |= val << SERDES_MUX_LANE_D_SHIFT; + break; + default: + printf("Invalid value\n"); + break; + } + + CPLD_WRITE(serdes_mux, reg); +#ifdef DEBUG + } else if (strcmp(argv[1], "dump") == 0) { + cpld_dump_regs(); +#endif + } else + rc = cmd_usage(cmdtp); + + return rc; +} + +U_BOOT_CMD( + cpld_cmd, CONFIG_SYS_MAXARGS, 1, cpld_cmd, + "Reset the board or pin mulexing selection using the CPLD sequencer", + "reset - hard reset to default bank\n" + "cpld_cmd reset altbank - reset to alternate bank\n" + "cpld_cmd lane_mux <lane> <mux_value> - set multiplexed lane pin\n" + " lane 6: 0 -> slot1\n" + " 1 -> SGMII (Default)\n" + " lane a: 0 -> slot2\n" + " 1 -> AURORA (Default)\n" + " lane c: 0 -> slot2\n" + " 1 -> SATA0 (Default)\n" + " lane d: 0 -> slot2\n" + " 1 -> SATA1 (Default)\n" +#ifdef DEBUG + "cpld_cmd dump - display the CPLD registers\n" +#endif + ); diff --git a/qemu/roms/u-boot/board/freescale/p2041rdb/cpld.h b/qemu/roms/u-boot/board/freescale/p2041rdb/cpld.h new file mode 100644 index 000000000..64487f1bf --- /dev/null +++ b/qemu/roms/u-boot/board/freescale/p2041rdb/cpld.h @@ -0,0 +1,55 @@ +/** + * Copyright 2011 Freescale Semiconductor + * Author: Mingkai Hu <Mingkai.hu@freescale.com> + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This file provides support for the ngPIXIS, a board-specific FPGA used on + * some Freescale reference boards. + */ + +/* + * CPLD register set. Feel free to add board-specific #ifdefs where necessary. + */ +typedef struct cpld_data { + u8 cpld_ver; /* 0x0 - CPLD Major Revision Register */ + u8 cpld_ver_sub; /* 0x1 - CPLD Minor Revision Register */ + u8 pcba_ver; /* 0x2 - PCBA Revision Register */ + u8 system_rst; /* 0x3 - system reset register */ + u8 res0; /* 0x4 - not used */ + u8 sw_ctl_on; /* 0x5 - Switch Control Enable Register */ + u8 por_cfg; /* 0x6 - POR Control Register */ + u8 switch_strobe; /* 0x7 - Multiplexed pin Select Register */ + u8 jtag_sel; /* 0x8 - JTAG or AURORA Selection */ + u8 sdbank1_clk; /* 0x9 - SerDes Bank1 Reference clock */ + u8 sdbank2_clk; /* 0xa - SerDes Bank2 Reference clock */ + u8 fbank_sel; /* 0xb - Flash bank selection */ + u8 serdes_mux; /* 0xc - Multiplexed pin Select Register */ + u8 sw[1]; /* 0xd - SW2 Status */ + u8 system_rst_default; /* 0xe - system reset to default register */ + u8 sysclk_sw1; /* 0xf - sysclk configuration register */ +} __attribute__ ((packed)) cpld_data_t; + +#define SERDES_MUX_LANE_6_MASK 0x2 +#define SERDES_MUX_LANE_6_SHIFT 1 +#define SERDES_MUX_LANE_A_MASK 0x1 +#define SERDES_MUX_LANE_A_SHIFT 0 +#define SERDES_MUX_LANE_C_MASK 0x4 +#define SERDES_MUX_LANE_C_SHIFT 2 +#define SERDES_MUX_LANE_D_MASK 0x8 +#define SERDES_MUX_LANE_D_SHIFT 3 +#define CPLD_SWITCH_BANK_ENABLE 0x40 +#define CPLD_SYSCLK_83 0x1 /* system clock 83.3MHz */ +#define CPLD_SYSCLK_100 0x2 /* system clock 100MHz */ + +/* Pointer to the CPLD register set */ +#define cpld ((cpld_data_t *)CPLD_BASE) + +/* The CPLD SW register that corresponds to board switch X, where x >= 1 */ +#define CPLD_SW(x) (cpld->sw[(x) - 2]) + +u8 cpld_read(unsigned int reg); +void cpld_write(unsigned int reg, u8 value); + +#define CPLD_READ(reg) cpld_read(offsetof(cpld_data_t, reg)) +#define CPLD_WRITE(reg, value) cpld_write(offsetof(cpld_data_t, reg), value) diff --git a/qemu/roms/u-boot/board/freescale/p2041rdb/ddr.c b/qemu/roms/u-boot/board/freescale/p2041rdb/ddr.c new file mode 100644 index 000000000..b8bbcdf2a --- /dev/null +++ b/qemu/roms/u-boot/board/freescale/p2041rdb/ddr.c @@ -0,0 +1,140 @@ +/* + * Copyright 2011 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. + */ + +#include <common.h> +#include <i2c.h> +#include <hwconfig.h> +#include <asm/mmu.h> +#include <fsl_ddr_sdram.h> +#include <fsl_ddr_dimm_params.h> +#include <asm/fsl_law.h> + +struct board_specific_parameters { + u32 n_ranks; + u32 datarate_mhz_high; + u32 clk_adjust; + u32 wrlvl_start; + u32 cpo; + u32 write_data_delay; + u32 force_2t; +}; + +/* + * This table contains all valid speeds we want to override with board + * specific parameters. datarate_mhz_high values need to be in ascending order + * for each n_ranks group. + * + * ranges for parameters: + * wr_data_delay = 0-6 + * clk adjust = 0-8 + * cpo 2-0x1E (30) + */ +static const struct board_specific_parameters dimm0[] = { + /* + * memory controller 0 + * num| hi| clk| wrlvl | cpo |wrdata|2T + * ranks| mhz|adjst| start | delay| + */ + {2, 750, 3, 5, 0xff, 2, 0}, + {2, 1250, 4, 6, 0xff, 2, 0}, + {2, 1350, 5, 7, 0xff, 2, 0}, + {2, 1666, 5, 8, 0xff, 2, 0}, + {} +}; + +void fsl_ddr_board_options(memctl_options_t *popts, + dimm_params_t *pdimm, + unsigned int ctrl_num) +{ + const struct board_specific_parameters *pbsp, *pbsp_highest = NULL; + ulong ddr_freq; + + if (ctrl_num) { + printf("Wrong parameter for controller number %d", ctrl_num); + return; + } + if (!pdimm->n_ranks) + return; + + pbsp = dimm0; + + /* + * Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr + * freqency and n_banks specified in board_specific_parameters table. + */ + ddr_freq = get_ddr_freq(0) / 1000000; + while (pbsp->datarate_mhz_high) { + if (pbsp->n_ranks == pdimm->n_ranks) { + if (ddr_freq <= pbsp->datarate_mhz_high) { + popts->cpo_override = pbsp->cpo; + popts->write_data_delay = + pbsp->write_data_delay; + popts->clk_adjust = pbsp->clk_adjust; + popts->wrlvl_start = pbsp->wrlvl_start; + popts->twot_en = pbsp->force_2t; + goto found; + } + pbsp_highest = pbsp; + } + pbsp++; + } + + if (pbsp_highest) { + printf("Error: board specific timing not found " + "for data rate %lu MT/s!\n" + "Trying to use the highest speed (%u) parameters\n", + ddr_freq, pbsp_highest->datarate_mhz_high); + popts->cpo_override = pbsp_highest->cpo; + popts->write_data_delay = pbsp_highest->write_data_delay; + popts->clk_adjust = pbsp_highest->clk_adjust; + popts->wrlvl_start = pbsp_highest->wrlvl_start; + popts->twot_en = pbsp_highest->force_2t; + } else { + panic("DIMM is not supported by this board"); + } + +found: + /* + * Factors to consider for half-strength driver enable: + * - number of DIMMs installed + */ + popts->half_strength_driver_enable = 0; + /* Write leveling override */ + popts->wrlvl_override = 1; + popts->wrlvl_sample = 0xf; + + /* Rtt and Rtt_WR override */ + popts->rtt_override = 0; + + /* Enable ZQ calibration */ + popts->zq_en = 1; + + /* DHC_EN =1, ODT = 60 Ohm */ + popts->ddr_cdr1 = DDR_CDR1_DHC_EN; +} + +phys_size_t initdram(int board_type) +{ + phys_size_t dram_size = 0; + + puts("Initializing...."); + + if (fsl_use_spd()) { + puts("using SPD\n"); + dram_size = fsl_ddr_sdram(); + } else { + puts("no SPD and fixed parameters\n"); + return dram_size; + } + + dram_size = setup_ddr_tlbs(dram_size / 0x100000); + dram_size *= 0x100000; + + debug(" DDR: "); + return dram_size; +} diff --git a/qemu/roms/u-boot/board/freescale/p2041rdb/eth.c b/qemu/roms/u-boot/board/freescale/p2041rdb/eth.c new file mode 100644 index 000000000..532eeac84 --- /dev/null +++ b/qemu/roms/u-boot/board/freescale/p2041rdb/eth.c @@ -0,0 +1,201 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * Author: Mingkai Hu <Mingkai.hu@freescale.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * The RGMII PHYs are provided by the two on-board PHY. The SGMII PHYs + * are provided by the three on-board PHY or by the standard Freescale + * four-port SGMII riser card. We need to change the phy-handle in the + * kernel dts file to point to the correct PHY according to serdes mux + * and serdes protocol selection. + */ + +#include <common.h> +#include <netdev.h> +#include <asm/fsl_serdes.h> +#include <fm_eth.h> +#include <fsl_mdio.h> +#include <malloc.h> +#include <asm/fsl_dtsec.h> + +#include "cpld.h" +#include "../common/fman.h" + +#ifdef CONFIG_FMAN_ENET +/* + * Mapping of all 18 SERDES lanes to board slots. A value of '0' here means + * that the mapping must be determined dynamically, or that the lane maps to + * something other than a board slot + */ +static u8 lane_to_slot[] = { + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0 +}; + +static int riser_phy_addr[] = { + CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR, + CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR, + CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR, + CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR, +}; + +/* + * Initialize the lane_to_slot[] array. + * + * On the P2040RDB board the mapping is controlled by CPLD register. + */ +static void initialize_lane_to_slot(void) +{ + u8 mux = CPLD_READ(serdes_mux); + + lane_to_slot[6] = (mux & SERDES_MUX_LANE_6_MASK) ? 0 : 1; + lane_to_slot[10] = (mux & SERDES_MUX_LANE_A_MASK) ? 0 : 2; + lane_to_slot[12] = (mux & SERDES_MUX_LANE_C_MASK) ? 0 : 2; + lane_to_slot[13] = (mux & SERDES_MUX_LANE_D_MASK) ? 0 : 2; +} + +/* + * Given the following ... + * + * 1) A pointer to an Fman Ethernet node (as identified by the 'compat' + * compatible string and 'addr' physical address) + * + * 2) An Fman port + * + * ... update the phy-handle property of the Ethernet node to point to the + * right PHY. This assumes that we already know the PHY for each port. + * + * The offset of the Fman Ethernet node is also passed in for convenience, but + * it is not used, and we recalculate the offset anyway. + * + * Note that what we call "Fman ports" (enum fm_port) is really an Fman MAC. + * Inside the Fman, "ports" are things that connect to MACs. We only call them + * ports in U-Boot because on previous Ethernet devices (e.g. Gianfar), MACs + * and ports are the same thing. + * + */ +void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr, + enum fm_port port, int offset) +{ + phy_interface_t intf = fm_info_get_enet_if(port); + char phy[16]; + + /* The RGMII PHY is identified by the MAC connected to it */ + if (intf == PHY_INTERFACE_MODE_RGMII) { + sprintf(phy, "phy_rgmii_%u", port == FM1_DTSEC5 ? 0 : 1); + fdt_set_phy_handle(fdt, compat, addr, phy); + } + + /* The SGMII PHY is identified by the MAC connected to it */ + if (intf == PHY_INTERFACE_MODE_SGMII) { + int lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + port); + u8 slot; + if (lane < 0) + return; + slot = lane_to_slot[lane]; + if (slot) { + sprintf(phy, "phy_sgmii_%x", + CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR + + (port - FM1_DTSEC1)); + fdt_set_phy_handle(fdt, compat, addr, phy); + } else { + sprintf(phy, "phy_sgmii_%x", + CONFIG_SYS_FM1_DTSEC1_PHY_ADDR + + (port - FM1_DTSEC1)); + fdt_set_phy_handle(fdt, compat, addr, phy); + } + } + + if (intf == PHY_INTERFACE_MODE_XGMII) { + /* XAUI */ + int lane = serdes_get_first_lane(XAUI_FM1); + if (lane >= 0) { + /* The XAUI PHY is identified by the slot */ + sprintf(phy, "phy_xgmii_%u", lane_to_slot[lane]); + fdt_set_phy_handle(fdt, compat, addr, phy); + } + } +} +#endif /* #ifdef CONFIG_FMAN_ENET */ + +int board_eth_init(bd_t *bis) +{ +#ifdef CONFIG_FMAN_ENET + struct fsl_pq_mdio_info dtsec_mdio_info; + struct tgec_mdio_info tgec_mdio_info; + unsigned int i, slot; + int lane; + + printf("Initializing Fman\n"); + + initialize_lane_to_slot(); + + dtsec_mdio_info.regs = + (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR; + dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME; + + /* Register the real 1G MDIO bus */ + fsl_pq_mdio_init(bis, &dtsec_mdio_info); + + tgec_mdio_info.regs = + (struct tgec_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR; + tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME; + + /* Register the real 10G MDIO bus */ + fm_tgec_mdio_init(bis, &tgec_mdio_info); + + /* + * Program the three on-board SGMII PHY addresses. If the SGMII Riser + * card used, we'll override the PHY address later. For any DTSEC that + * is RGMII, we'll also override its PHY address later. We assume that + * DTSEC4 and DTSEC5 are used for RGMII. + */ + fm_info_set_phy_address(FM1_DTSEC1, CONFIG_SYS_FM1_DTSEC1_PHY_ADDR); + fm_info_set_phy_address(FM1_DTSEC2, CONFIG_SYS_FM1_DTSEC2_PHY_ADDR); + fm_info_set_phy_address(FM1_DTSEC3, CONFIG_SYS_FM1_DTSEC3_PHY_ADDR); + + for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { + int idx = i - FM1_DTSEC1; + + switch (fm_info_get_enet_if(i)) { + case PHY_INTERFACE_MODE_SGMII: + lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx); + if (lane < 0) + break; + slot = lane_to_slot[lane]; + if (slot) + fm_info_set_phy_address(i, riser_phy_addr[i]); + break; + case PHY_INTERFACE_MODE_RGMII: + /* Only DTSEC4 and DTSEC5 can be routed to RGMII */ + fm_info_set_phy_address(i, i == FM1_DTSEC5 ? + CONFIG_SYS_FM1_DTSEC5_PHY_ADDR : + CONFIG_SYS_FM1_DTSEC4_PHY_ADDR); + break; + default: + printf("Fman1: DTSEC%u set to unknown interface %i\n", + idx + 1, fm_info_get_enet_if(i)); + break; + } + + fm_info_set_mdio(i, + miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME)); + } + + lane = serdes_get_first_lane(XAUI_FM1); + if (lane >= 0) { + slot = lane_to_slot[lane]; + if (slot) + fm_info_set_phy_address(FM1_10GEC1, + CONFIG_SYS_FM1_10GEC1_PHY_ADDR); + } + + fm_info_set_mdio(FM1_10GEC1, + miiphy_get_dev_by_name(DEFAULT_FM_TGEC_MDIO_NAME)); + cpu_eth_init(bis); +#endif + + return pci_eth_init(bis); +} diff --git a/qemu/roms/u-boot/board/freescale/p2041rdb/p2041rdb.c b/qemu/roms/u-boot/board/freescale/p2041rdb/p2041rdb.c new file mode 100644 index 000000000..8554512df --- /dev/null +++ b/qemu/roms/u-boot/board/freescale/p2041rdb/p2041rdb.c @@ -0,0 +1,236 @@ +/* + * Copyright 2011,2012 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <netdev.h> +#include <linux/compiler.h> +#include <asm/mmu.h> +#include <asm/processor.h> +#include <asm/cache.h> +#include <asm/immap_85xx.h> +#include <asm/fsl_law.h> +#include <asm/fsl_serdes.h> +#include <asm/fsl_portals.h> +#include <asm/fsl_liodn.h> +#include <fm_eth.h> + +extern void pci_of_setup(void *blob, bd_t *bd); + +#include "cpld.h" + +DECLARE_GLOBAL_DATA_PTR; + +int checkboard(void) +{ + u8 sw; + struct cpu_type *cpu = gd->arch.cpu; + unsigned int i; + + printf("Board: %sRDB, ", cpu->name); + printf("CPLD version: %d.%d ", CPLD_READ(cpld_ver), + CPLD_READ(cpld_ver_sub)); + + sw = CPLD_READ(fbank_sel); + printf("vBank: %d\n", sw & 0x1); + + /* + * Display the actual SERDES reference clocks as configured by the + * dip switches on the board. Note that the SWx registers could + * technically be set to force the reference clocks to match the + * values that the SERDES expects (or vice versa). For now, however, + * we just display both values and hope the user notices when they + * don't match. + */ + puts("SERDES Reference Clocks: "); + sw = in_8(&CPLD_SW(2)) >> 2; + for (i = 0; i < 2; i++) { + static const char * const freq[][3] = {{"0", "100", "125"}, + {"100", "156.25", "125"} + }; + unsigned int clock = (sw >> (2 * i)) & 3; + + printf("Bank%u=%sMhz ", i+1, freq[i][clock]); + } + puts("\n"); + + return 0; +} + +int board_early_init_f(void) +{ + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + + /* board only uses the DDR_MCK0/1, so disable the DDR_MCK2/3 */ + setbits_be32(&gur->ddrclkdr, 0x000f000f); + + return 0; +} + +#define CPLD_LANE_A_SEL 0x1 +#define CPLD_LANE_G_SEL 0x2 +#define CPLD_LANE_C_SEL 0x4 +#define CPLD_LANE_D_SEL 0x8 + +void board_config_lanes_mux(void) +{ + ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + int srds_prtcl = (in_be32(&gur->rcwsr[4]) & + FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; + + u8 mux = 0; + switch (srds_prtcl) { + case 0x2: + case 0x5: + case 0x9: + case 0xa: + case 0xf: + break; + case 0x8: + mux |= CPLD_LANE_C_SEL | CPLD_LANE_D_SEL; + break; + case 0x14: + mux |= CPLD_LANE_A_SEL; + break; + case 0x17: + mux |= CPLD_LANE_G_SEL; + break; + case 0x16: + case 0x19: + case 0x1a: + mux |= CPLD_LANE_G_SEL | CPLD_LANE_C_SEL | CPLD_LANE_D_SEL; + break; + case 0x1c: + mux |= CPLD_LANE_G_SEL | CPLD_LANE_A_SEL; + break; + default: + printf("Fman:Unsupported SerDes Protocol 0x%02x\n", srds_prtcl); + break; + } + CPLD_WRITE(serdes_mux, mux); +} + +int board_early_init_r(void) +{ + const unsigned int flashbase = CONFIG_SYS_FLASH_BASE; + const u8 flash_esel = find_tlb_idx((void *)flashbase, 1); + + /* + * Remap Boot flash + PROMJET region to caching-inhibited + * so that flash can be erased properly. + */ + + /* Flush d-cache and invalidate i-cache of any FLASH data */ + flush_dcache(); + invalidate_icache(); + + /* invalidate existing TLB entry for flash + promjet */ + disable_tlb(flash_esel); + + set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, flash_esel, BOOKE_PAGESZ_256M, 1); + + set_liodns(); + setup_portals(); + board_config_lanes_mux(); + + return 0; +} + +unsigned long get_board_sys_clk(unsigned long dummy) +{ + u8 sysclk_conf = CPLD_READ(sysclk_sw1); + + switch (sysclk_conf & 0x7) { + case CPLD_SYSCLK_83: + return 83333333; + case CPLD_SYSCLK_100: + return 100000000; + default: + return 66666666; + } +} + +#define NUM_SRDS_BANKS 2 + +int misc_init_r(void) +{ + serdes_corenet_t *regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR; + u32 actual[NUM_SRDS_BANKS]; + unsigned int i; + u8 sw; + static const int freq[][3] = { + {0, SRDS_PLLCR0_RFCK_SEL_100, SRDS_PLLCR0_RFCK_SEL_125}, + {SRDS_PLLCR0_RFCK_SEL_100, SRDS_PLLCR0_RFCK_SEL_156_25, + SRDS_PLLCR0_RFCK_SEL_125} + }; + + sw = in_8(&CPLD_SW(2)) >> 2; + for (i = 0; i < NUM_SRDS_BANKS; i++) { + unsigned int clock = (sw >> (2 * i)) & 3; + if (clock == 0x3) { + printf("Warning: SDREFCLK%u switch setting of '11' is " + "unsupported\n", i + 1); + break; + } + if (i == 0 && clock == 0) + puts("Warning: SDREFCLK1 switch setting of" + "'00' is unsupported\n"); + else + actual[i] = freq[i][clock]; + + /* + * PC board uses a different CPLD with PB board, this CPLD + * has cpld_ver_sub = 1, and pcba_ver = 5. But CPLD on PB + * board has cpld_ver_sub = 0, and pcba_ver = 4. + */ + if ((i == 1) && (CPLD_READ(cpld_ver_sub) == 1) && + (CPLD_READ(pcba_ver) == 5)) { + /* PC board bank2 frequency */ + actual[i] = freq[i-1][clock]; + } + } + + for (i = 0; i < NUM_SRDS_BANKS; i++) { + u32 expected = in_be32(®s->bank[i].pllcr0); + expected &= SRDS_PLLCR0_RFCK_SEL_MASK; + if (expected != actual[i]) { + printf("Warning: SERDES bank %u expects reference clock" + " %sMHz, but actual is %sMHz\n", i + 1, + serdes_clock_to_string(expected), + serdes_clock_to_string(actual[i])); + } + } + + return 0; +} + +void ft_board_setup(void *blob, bd_t *bd) +{ + phys_addr_t base; + phys_size_t size; + + ft_cpu_setup(blob, bd); + + base = getenv_bootm_low(); + size = getenv_bootm_size(); + + fdt_fixup_memory(blob, (u64)base, (u64)size); + +#if defined(CONFIG_HAS_FSL_DR_USB) || defined(CONFIG_HAS_FSL_MPH_USB) + fdt_fixup_dr_usb(blob, bd); +#endif + +#ifdef CONFIG_PCI + pci_of_setup(blob, bd); +#endif + + fdt_fixup_liodn(blob); +#ifdef CONFIG_SYS_DPAA_FMAN + fdt_fixup_fman_ethernet(blob); +#endif +} |