diff options
author | Tom Rini <trini@ti.com> | 2014-05-13 17:09:28 -0400 |
---|---|---|
committer | Tom Rini <trini@ti.com> | 2014-05-13 17:09:28 -0400 |
commit | 557a3319089499aa0e55d65a6b43b7137f362003 (patch) | |
tree | 092341615ca6449473e4d9f7cb2158391bb86892 /board | |
parent | 27b4e4b9913f65b52d20485dff3f8800bf78f3d7 (diff) | |
parent | 8ad5d45e0044f5e64dbe7c6bd4e6aa0121a26b23 (diff) | |
download | u-boot-imx-557a3319089499aa0e55d65a6b43b7137f362003.zip u-boot-imx-557a3319089499aa0e55d65a6b43b7137f362003.tar.gz u-boot-imx-557a3319089499aa0e55d65a6b43b7137f362003.tar.bz2 |
Merge branch 'master' of git://git.denx.de/u-boot-mpc85xx
Diffstat (limited to 'board')
23 files changed, 1363 insertions, 29 deletions
diff --git a/board/freescale/b4860qds/b4860qds.c b/board/freescale/b4860qds/b4860qds.c index d9c88a0..b2d5378 100644 --- a/board/freescale/b4860qds/b4860qds.c +++ b/board/freescale/b4860qds/b4860qds.c @@ -23,6 +23,7 @@ #include "../common/qixis.h" #include "../common/vsc3316_3308.h" #include "../common/idt8t49n222a_serdes_clk.h" +#include "../common/zm7300.h" #include "b4860qds.h" #include "b4860qds_qixis.h" #include "b4860qds_crossbar_con.h" @@ -94,6 +95,238 @@ int select_i2c_ch_pca(u8 ch) return 0; } +/* + * read_voltage from sensor on I2C bus + * We use average of 4 readings, waiting for 532us befor another reading + */ +#define WAIT_FOR_ADC 532 /* wait for 532 microseconds for ADC */ +#define NUM_READINGS 4 /* prefer to be power of 2 for efficiency */ + +static inline int read_voltage(void) +{ + int i, ret, voltage_read = 0; + u16 vol_mon; + + for (i = 0; i < NUM_READINGS; i++) { + ret = i2c_read(I2C_VOL_MONITOR_ADDR, + I2C_VOL_MONITOR_BUS_V_OFFSET, 1, (void *)&vol_mon, 2); + if (ret) { + printf("VID: failed to read core voltage\n"); + return ret; + } + if (vol_mon & I2C_VOL_MONITOR_BUS_V_OVF) { + printf("VID: Core voltage sensor error\n"); + return -1; + } + debug("VID: bus voltage reads 0x%04x\n", vol_mon); + /* LSB = 4mv */ + voltage_read += (vol_mon >> I2C_VOL_MONITOR_BUS_V_SHIFT) * 4; + udelay(WAIT_FOR_ADC); + } + /* calculate the average */ + voltage_read /= NUM_READINGS; + + return voltage_read; +} + +static int adjust_vdd(ulong vdd_override) +{ + int re_enable = disable_interrupts(); + ccsr_gur_t __iomem *gur = + (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + u32 fusesr; + u8 vid; + int vdd_target, vdd_last; + int existing_voltage, temp_voltage, voltage; /* all in 1/10 mV */ + int ret; + unsigned int orig_i2c_speed; + unsigned long vdd_string_override; + char *vdd_string; + static const uint16_t vdd[32] = { + 0, /* unused */ + 9875, /* 0.9875V */ + 9750, + 9625, + 9500, + 9375, + 9250, + 9125, + 9000, + 8875, + 8750, + 8625, + 8500, + 8375, + 8250, + 8125, + 10000, /* 1.0000V */ + 10125, + 10250, + 10375, + 10500, + 10625, + 10750, + 10875, + 11000, + 0, /* reserved */ + }; + struct vdd_drive { + u8 vid; + unsigned voltage; + }; + + ret = select_i2c_ch_pca(I2C_MUX_CH_VOL_MONITOR); + if (ret) { + printf("VID: I2c failed to switch channel\n"); + ret = -1; + goto exit; + } + + /* get the voltage ID from fuse status register */ + fusesr = in_be32(&gur->dcfg_fusesr); + vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_VID_SHIFT) & + FSL_CORENET_DCFG_FUSESR_VID_MASK; + if (vid == FSL_CORENET_DCFG_FUSESR_VID_MASK) { + vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_ALTVID_SHIFT) & + FSL_CORENET_DCFG_FUSESR_ALTVID_MASK; + } + vdd_target = vdd[vid]; + debug("VID:Reading from from fuse,vid=%x vdd is %dmV\n", + vid, vdd_target/10); + + /* check override variable for overriding VDD */ + vdd_string = getenv("b4qds_vdd_mv"); + if (vdd_override == 0 && vdd_string && + !strict_strtoul(vdd_string, 10, &vdd_string_override)) + vdd_override = vdd_string_override; + if (vdd_override >= 819 && vdd_override <= 1212) { + vdd_target = vdd_override * 10; /* convert to 1/10 mV */ + debug("VDD override is %lu\n", vdd_override); + } else if (vdd_override != 0) { + printf("Invalid value.\n"); + } + + if (vdd_target == 0) { + printf("VID: VID not used\n"); + ret = 0; + goto exit; + } + + /* + * Read voltage monitor to check real voltage. + * Voltage monitor LSB is 4mv. + */ + vdd_last = read_voltage(); + if (vdd_last < 0) { + printf("VID: abort VID adjustment\n"); + ret = -1; + goto exit; + } + + debug("VID: Core voltage is at %d mV\n", vdd_last); + ret = select_i2c_ch_pca(I2C_MUX_CH_DPM); + if (ret) { + printf("VID: I2c failed to switch channel to DPM\n"); + ret = -1; + goto exit; + } + + /* Round up to the value of step of Voltage regulator */ + voltage = roundup(vdd_target, ZM_STEP); + debug("VID: rounded up voltage = %d\n", voltage); + + /* lower the speed to 100kHz to access ZM7300 device */ + debug("VID: Setting bus speed to 100KHz if not already set\n"); + orig_i2c_speed = i2c_get_bus_speed(); + if (orig_i2c_speed != 100000) + i2c_set_bus_speed(100000); + + /* Read the existing level on board, if equal to requsted one, + no need to re-set */ + existing_voltage = zm_read_voltage(); + + /* allowing the voltage difference of one step 0.0125V acceptable */ + if ((existing_voltage >= voltage) && + (existing_voltage < (voltage + ZM_STEP))) { + debug("VID: voltage already set as requested,returning\n"); + ret = existing_voltage; + goto out; + } + debug("VID: Changing voltage for board from %dmV to %dmV\n", + existing_voltage/10, voltage/10); + + if (zm_disable_wp() < 0) { + ret = -1; + goto out; + } + /* Change Voltage: the change is done through all the steps in the + way, to avoid reset to the board due to power good signal fail + in big voltage change gap jump. + */ + if (existing_voltage > voltage) { + temp_voltage = existing_voltage - ZM_STEP; + while (temp_voltage >= voltage) { + ret = zm_write_voltage(temp_voltage); + if (ret == temp_voltage) { + temp_voltage -= ZM_STEP; + } else { + /* ZM7300 device failed to set + * the voltage */ + printf + ("VID:Stepping down vol failed:%dmV\n", + temp_voltage/10); + ret = -1; + goto out; + } + } + } else { + temp_voltage = existing_voltage + ZM_STEP; + while (temp_voltage < (voltage + ZM_STEP)) { + ret = zm_write_voltage(temp_voltage); + if (ret == temp_voltage) { + temp_voltage += ZM_STEP; + } else { + /* ZM7300 device failed to set + * the voltage */ + printf + ("VID:Stepping up vol failed:%dmV\n", + temp_voltage/10); + ret = -1; + goto out; + } + } + } + + if (zm_enable_wp() < 0) + ret = -1; + + /* restore the speed to 400kHz */ +out: debug("VID: Restore the I2C bus speed to %dKHz\n", + orig_i2c_speed/1000); + i2c_set_bus_speed(orig_i2c_speed); + if (ret < 0) + goto exit; + + ret = select_i2c_ch_pca(I2C_MUX_CH_VOL_MONITOR); + if (ret) { + printf("VID: I2c failed to switch channel\n"); + ret = -1; + goto exit; + } + vdd_last = read_voltage(); + select_i2c_ch_pca(I2C_CH_DEFAULT); + + if (vdd_last > 0) + printf("VID: Core voltage %d mV\n", vdd_last); + else + ret = -1; + +exit: + if (re_enable) + enable_interrupts(); + return ret; +} + int configure_vsc3316_3308(void) { ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); @@ -697,6 +930,13 @@ int board_early_init_r(void) #ifdef CONFIG_SYS_DPAA_QBMAN setup_portals(); #endif + /* + * Adjust core voltage according to voltage ID + * This function changes I2C mux to channel 2. + */ + if (adjust_vdd(0) < 0) + printf("Warning: Adjusting core voltage failed\n"); + /* SerDes1 refclks need to be set again, as default clks * are not suitable for CPRI and onboard SGMIIs to work * simultaneously. diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index f6a0879..22b57cc 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_P5020DS) += ics307_clk.o obj-$(CONFIG_P5040DS) += ics307_clk.o obj-$(CONFIG_VSC_CROSSBAR) += vsc3316_3308.o obj-$(CONFIG_IDT8T49N222A) += idt8t49n222a_serdes_clk.o +obj-$(CONFIG_ZM7300) += zm7300.o # deal with common files for P-series corenet based devices obj-$(CONFIG_P2041RDB) += p_corenet/ diff --git a/board/freescale/common/sys_eeprom.c b/board/freescale/common/sys_eeprom.c index 9c18dd8..33a5a5a 100644 --- a/board/freescale/common/sys_eeprom.c +++ b/board/freescale/common/sys_eeprom.c @@ -425,13 +425,13 @@ int mac_read_from_eeprom(void) if (read_eeprom()) { printf("Read failed.\n"); - return -1; + return 0; } 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; + return 0; } #ifdef CONFIG_SYS_I2C_EEPROM_NXID @@ -447,7 +447,7 @@ int mac_read_from_eeprom(void) crcp = (void *)&e + crc_offset; if (crc != be32_to_cpu(*crcp)) { printf("CRC mismatch (%08x != %08x)\n", crc, be32_to_cpu(e.crc)); - return -1; + return 0; } #ifdef CONFIG_SYS_I2C_EEPROM_NXID diff --git a/board/freescale/common/zm7300.c b/board/freescale/common/zm7300.c new file mode 100644 index 0000000..be5953a --- /dev/null +++ b/board/freescale/common/zm7300.c @@ -0,0 +1,235 @@ +/* + * Copyright 2013 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* Power-One ZM7300 DPM */ +#include "zm7300.h" + +#define DPM_WP 0x96 +#define WRP_OPCODE 0x01 +#define WRM_OPCODE 0x02 +#define RRP_OPCODE 0x11 + +#define DPM_SUCCESS 0x01 +#define DPM_EXEC_FAIL 0x00 + +static const uint16_t hex_to_1_10mv[] = { + 5000, + 5125, + 5250, + 5375, + 5500, + 5625, + 5750, + 5875, + 6000, + 6125, + 6250, + 6375, + 6500, + 6625, + 6750, + 6875, + 7000, + 7125, + 7250, + 7375, + 7500, + 7625, + 7750, + 7875, + 8000, + 8125, + 8250, + 8375, + 8500, + 8625, + 8750, + 8875, + 9000, + 9125, + 9250, + 9375, + 9500, /* 0.95mV */ + 9625, + 9750, + 9875, + 10000, /* 1.0V */ + 10125, + 10250, + 10375, + 10500, + 10625, + 10750, + 10875, + 11000, + 11125, + 11250, + 11375, + 11500, + 11625, + 11750, + 11875, + 12000, + 12125, + 12250, + 12375, + 0, /* reserved */ +}; + + +/* Read Data d from Register r of POL p */ +u8 dpm_rrp(uchar r) +{ + u8 ret[5]; + + ret[0] = RRP_OPCODE; + /* POL is 0 */ + ret[1] = 0; + ret[2] = r; + i2c_read(I2C_DPM_ADDR, 0, -3, ret, 2); + if (ret[1] == DPM_SUCCESS) { /* the DPM returned success as status */ + debug("RRP_OPCODE returned success data is %x\n", ret[0]); + return ret[0]; + } else { + return -1; + } +} + +/* Write Data d into DPM register r (RAM) */ +int dpm_wrm(u8 r, u8 d) +{ + u8 ret[5]; + + ret[0] = WRM_OPCODE; + ret[1] = r; + ret[2] = d; + i2c_read(I2C_DPM_ADDR, 0, -3, ret, 1); + if (ret[0] == DPM_SUCCESS) { /* the DPM returned success as status */ + debug("WRM_OPCODE returned success data is %x\n", ret[0]); + return ret[0]; + } else { + return -1; + } +} + +/* Write Data d into Register r of POL(s) a */ +int dpm_wrp(u8 r, u8 d) +{ + u8 ret[7]; + + ret[0] = WRP_OPCODE; + /* only POL0 is present */ + ret[1] = 0x01; + ret[2] = 0x00; + ret[3] = 0x00; + ret[4] = 0x00; + ret[5] = r; + ret[6] = d; + i2c_read(I2C_DPM_ADDR, 0, -7, ret, 1); + if (ret[0] == DPM_SUCCESS) { /* the DPM returned success as status */ + debug("WRP_OPCODE returned success data is %x\n", ret[0]); + return 0; + } else { + return -1; + } +} + +/* Uses the DPM command RRP */ +u8 zm_read(uchar reg) +{ + u8 d; + d = dpm_rrp(reg); + return d; +} + +/* ZM_write -- + Steps: + a. Write data to the register + b. Read data from register and compare to written value + c. Return return_code & voltage_read +*/ +u8 zm_write(u8 reg, u8 data) +{ + u8 d; + + /* write data to register */ + dpm_wrp(reg, data); + + /* read register and compare to written value */ + d = dpm_rrp(reg); + if (d != data) { + printf("zm_write : Comparison register data failed\n"); + return -1; + } + + return d; +} + +/* zm_write_out_voltage + * voltage in 1/10 mV + */ +int zm_write_voltage(int voltage) +{ + u8 reg = 0x7, vid; + uint16_t voltage_read; + u8 ret; + + vid = (voltage - 5000) / ZM_STEP; + + ret = zm_write(reg, vid); + if (ret != -1) { + voltage_read = hex_to_1_10mv[ret]; + debug("voltage set to %dmV\n", voltage_read/10); + return voltage_read; + } + return -1; +} + +/* zm_read_out_voltage + * voltage in 1/10 mV + */ +int zm_read_voltage(void) +{ + u8 reg = 0x7; + u8 ret; + int voltage; + + ret = zm_read(reg); + if (ret != -1) { + voltage = hex_to_1_10mv[ret]; + debug("Voltage read is %dmV\n", voltage/10); + return voltage; + } else { + return -1; + } +} + +int zm_disable_wp() +{ + u8 new_wp_value; + + /* Disable using Write-Protect register 0x96 */ + new_wp_value = 0x8; + if ((dpm_wrm(DPM_WP, new_wp_value)) < 0) { + printf("Disable Write-Protect register failed\n"); + return -1; + } + return 0; +} + +int zm_enable_wp() +{ + u8 orig_wp_value; + orig_wp_value = 0x0; + + /* Enable using Write-Protect register 0x96 */ + if ((dpm_wrm(DPM_WP, orig_wp_value)) < 0) { + printf("Enable Write-Protect register failed\n"); + return -1; + } + return 0; +} + diff --git a/board/freescale/common/zm7300.h b/board/freescale/common/zm7300.h new file mode 100644 index 0000000..6b4d035 --- /dev/null +++ b/board/freescale/common/zm7300.h @@ -0,0 +1,22 @@ +/* + * Copyright 2013 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ZM7300_H_ +#define __ZM7300_H 1_ + +#include <common.h> +#include <i2c.h> +#include <errno.h> +#include <asm/io.h> + +#define ZM_STEP 125 +int zm7300_set_voltage(int voltage_1_10mv); +int zm_write_voltage(int voltage); +int zm_read_voltage(void); +int zm_disable_wp(void); +int zm_enable_wp(void); + +#endif /* __ZM7300_H_ */ diff --git a/board/freescale/qemu-ppce500/qemu-ppce500.c b/board/freescale/qemu-ppce500/qemu-ppce500.c index 3dbb0cf..230870d 100644 --- a/board/freescale/qemu-ppce500/qemu-ppce500.c +++ b/board/freescale/qemu-ppce500/qemu-ppce500.c @@ -346,3 +346,23 @@ ulong get_bus_freq (ulong dummy) get_sys_info(&sys_info); return sys_info.freq_systembus; } + +/* + * Return the number of cores on this SOC. + */ +int cpu_numcores(void) +{ + /* + * The QEMU u-boot target only needs to drive the first core, + * spinning and device tree nodes get driven by QEMU itself + */ + return 1; +} + +/* + * Return a 32-bit mask indicating which cores are present on this SOC. + */ +u32 cpu_mask(void) +{ + return (1 << cpu_numcores()) - 1; +} diff --git a/board/freescale/t4rdb/Makefile b/board/freescale/t4rdb/Makefile new file mode 100644 index 0000000..f7f7fc0 --- /dev/null +++ b/board/freescale/t4rdb/Makefile @@ -0,0 +1,12 @@ +# +# Copyright 2014 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_T4240RDB) += t4240rdb.o +obj-y += ddr.o +obj-y += eth.o +obj-$(CONFIG_PCI) += pci.o +obj-y += law.o +obj-y += tlb.o diff --git a/board/freescale/t4rdb/ddr.c b/board/freescale/t4rdb/ddr.c new file mode 100644 index 0000000..5a43c1b --- /dev/null +++ b/board/freescale/t4rdb/ddr.c @@ -0,0 +1,118 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#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> +#include "ddr.h" + +DECLARE_GLOBAL_DATA_PTR; + +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 > 2) { + printf("Not supported controller number %d\n", ctrl_num); + return; + } + if (!pdimm->n_ranks) + return; + + /* + * we use identical timing for all slots. If needed, change the code + * to pbsp = rdimms[ctrl_num] or pbsp = udimms[ctrl_num]; + */ + if (popts->registered_dimm_en) + pbsp = rdimms[0]; + else + pbsp = udimms[0]; + + + /* 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 && + (pdimm->rank_density >> 30) >= pbsp->rank_gb) { + if (ddr_freq <= pbsp->datarate_mhz_high) { + popts->clk_adjust = pbsp->clk_adjust; + popts->wrlvl_start = pbsp->wrlvl_start; + popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2; + popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3; + goto found; + } + pbsp_highest = pbsp; + } + pbsp++; + } + + if (pbsp_highest) { + printf("Error: board specific timing not found for data\n" + "rate %lu MT/s\n" + "Trying to use the highest speed (%u) parameters\n", + ddr_freq, pbsp_highest->datarate_mhz_high); + popts->clk_adjust = pbsp_highest->clk_adjust; + popts->wrlvl_start = pbsp_highest->wrlvl_start; + popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2; + popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3; + } else { + panic("DIMM is not supported by this board"); + } +found: + debug("Found timing match: n_ranks %d, data rate %d, rank_gb %d\n" + "\tclk_adjust %d, wrlvl_start %d, wrlvl_ctrl_2 0x%x,\n" + "wrlvl_ctrl_3 0x%x\n", + pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb, + pbsp->clk_adjust, pbsp->wrlvl_start, pbsp->wrlvl_ctl_2, + pbsp->wrlvl_ctl_3); + + /* + * 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 = 75 Ohm */ + popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm); + popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm); +} + +phys_size_t initdram(int board_type) +{ + phys_size_t dram_size; + + puts("Initializing....using SPD\n"); + + dram_size = fsl_ddr_sdram(); + + dram_size = setup_ddr_tlbs(dram_size / 0x100000); + dram_size *= 0x100000; + + puts(" DDR: "); + return dram_size; +} diff --git a/board/freescale/t4rdb/ddr.h b/board/freescale/t4rdb/ddr.h new file mode 100644 index 0000000..7b85476 --- /dev/null +++ b/board/freescale/t4rdb/ddr.h @@ -0,0 +1,78 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __DDR_H__ +#define __DDR_H__ +struct board_specific_parameters { + u32 n_ranks; + u32 datarate_mhz_high; + u32 rank_gb; + u32 clk_adjust; + u32 wrlvl_start; + u32 wrlvl_ctl_2; + u32 wrlvl_ctl_3; +}; + +/* + * These tables contain 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. + */ +static const struct board_specific_parameters udimm0[] = { + /* + * memory controller 0 + * num| hi| rank| clk| wrlvl | wrlvl | wrlvl + * ranks| mhz| GB |adjst| start | ctl2 | ctl3 + */ + {2, 1350, 4, 4, 8, 0x0809090b, 0x0c0c0d0a}, + {2, 1350, 0, 5, 7, 0x0709090b, 0x0c0c0d09}, + {2, 1666, 4, 4, 8, 0x080a0a0d, 0x0d10100b}, + {2, 1666, 0, 5, 7, 0x080a0a0c, 0x0d0d0e0a}, + {2, 1900, 0, 4, 8, 0x090a0b0e, 0x0f11120c}, + {2, 2140, 0, 4, 8, 0x090a0b0e, 0x0f11120c}, + {1, 1350, 0, 5, 8, 0x0809090b, 0x0c0c0d0a}, + {1, 1700, 0, 5, 8, 0x080a0a0c, 0x0c0d0e0a}, + {1, 1900, 0, 4, 8, 0x080a0a0c, 0x0e0e0f0a}, + {1, 2140, 0, 4, 8, 0x090a0b0c, 0x0e0f100b}, + {} +}; + +static const struct board_specific_parameters rdimm0[] = { + /* + * memory controller 0 + * num| hi| rank| clk| wrlvl | wrlvl | wrlvl + * ranks| mhz| GB |adjst| start | ctl2 | ctl3 + */ + {4, 1350, 0, 5, 9, 0x08070605, 0x06070806}, + {4, 1666, 0, 5, 11, 0x0a080706, 0x07090906}, + {4, 2140, 0, 5, 12, 0x0b090807, 0x080a0b07}, + {2, 1350, 0, 5, 9, 0x08070605, 0x06070806}, + {2, 1666, 0, 5, 11, 0x0a090806, 0x08090a06}, + {2, 2140, 0, 5, 12, 0x0b090807, 0x080a0b07}, + {1, 1350, 0, 5, 9, 0x08070605, 0x06070806}, + {1, 1666, 0, 5, 11, 0x0a090806, 0x08090a06}, + {1, 2140, 0, 4, 12, 0x0b090807, 0x080a0b07}, + {} +}; + +/* + * The three slots have slightly different timing. The center values are good + * for all slots. We use identical speed tables for them. In future use, if + * DIMMs require separated tables, make more entries as needed. + */ +static const struct board_specific_parameters *udimms[] = { + udimm0, +}; + +/* + * The three slots have slightly different timing. See comments above. + */ +static const struct board_specific_parameters *rdimms[] = { + rdimm0, +}; + + +#endif diff --git a/board/freescale/t4rdb/eth.c b/board/freescale/t4rdb/eth.c new file mode 100644 index 0000000..d220475 --- /dev/null +++ b/board/freescale/t4rdb/eth.c @@ -0,0 +1,146 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * Chunhe Lan <Chunhe.Lan@freescale.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <netdev.h> +#include <asm/mmu.h> +#include <asm/processor.h> +#include <asm/cache.h> +#include <asm/immap_85xx.h> +#include <asm/fsl_law.h> +#include <fsl_ddr_sdram.h> +#include <asm/fsl_serdes.h> +#include <asm/fsl_portals.h> +#include <asm/fsl_liodn.h> +#include <malloc.h> +#include <fm_eth.h> +#include <fsl_mdio.h> +#include <miiphy.h> +#include <phy.h> +#include <asm/fsl_dtsec.h> +#include <asm/fsl_serdes.h> +#include <hwconfig.h> + +#include "../common/fman.h" +#include "t4rdb.h" + +void fdt_fixup_board_enet(void *fdt) +{ + return; +} + +int board_eth_init(bd_t *bis) +{ +#if defined(CONFIG_FMAN_ENET) + int i, interface; + struct memac_mdio_info dtsec_mdio_info; + struct memac_mdio_info tgec_mdio_info; + struct mii_dev *dev; + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + u32 srds_prtcl_s1, srds_prtcl_s2; + + srds_prtcl_s1 = in_be32(&gur->rcwsr[4]) & + FSL_CORENET2_RCWSR4_SRDS1_PRTCL; + srds_prtcl_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT; + srds_prtcl_s2 = in_be32(&gur->rcwsr[4]) & + FSL_CORENET2_RCWSR4_SRDS2_PRTCL; + srds_prtcl_s2 >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT; + + dtsec_mdio_info.regs = + (struct memac_mdio_controller *)CONFIG_SYS_FM2_DTSEC_MDIO_ADDR; + + dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME; + + /* Register the 1G MDIO bus */ + fm_memac_mdio_init(bis, &dtsec_mdio_info); + + tgec_mdio_info.regs = + (struct memac_mdio_controller *)CONFIG_SYS_FM2_TGEC_MDIO_ADDR; + tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME; + + /* Register the 10G MDIO bus */ + fm_memac_mdio_init(bis, &tgec_mdio_info); + + if (srds_prtcl_s1 == 28) { + /* SGMII */ + fm_info_set_phy_address(FM1_DTSEC1, SGMII_PHY_ADDR1); + fm_info_set_phy_address(FM1_DTSEC2, SGMII_PHY_ADDR2); + fm_info_set_phy_address(FM1_DTSEC3, SGMII_PHY_ADDR3); + fm_info_set_phy_address(FM1_DTSEC4, SGMII_PHY_ADDR4); + } else { + puts("Invalid SerDes1 protocol for T4240RDB\n"); + } + + for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { + interface = fm_info_get_enet_if(i); + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + dev = miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME); + fm_info_set_mdio(i, dev); + break; + default: + break; + } + } + + for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) { + switch (fm_info_get_enet_if(i)) { + case PHY_INTERFACE_MODE_XGMII: + dev = miiphy_get_dev_by_name(DEFAULT_FM_TGEC_MDIO_NAME); + fm_info_set_mdio(i, dev); + break; + default: + break; + } + } + +#if (CONFIG_SYS_NUM_FMAN == 2) + if (srds_prtcl_s2 == 56) { + /* SGMII && XFI */ + fm_info_set_phy_address(FM2_DTSEC1, SGMII_PHY_ADDR5); + fm_info_set_phy_address(FM2_DTSEC2, SGMII_PHY_ADDR6); + fm_info_set_phy_address(FM2_DTSEC3, SGMII_PHY_ADDR7); + fm_info_set_phy_address(FM2_DTSEC4, SGMII_PHY_ADDR8); + fm_info_set_phy_address(FM1_10GEC1, FM1_10GEC1_PHY_ADDR); + fm_info_set_phy_address(FM1_10GEC2, FM1_10GEC2_PHY_ADDR); + fm_info_set_phy_address(FM2_10GEC1, FM2_10GEC2_PHY_ADDR); + fm_info_set_phy_address(FM2_10GEC2, FM2_10GEC1_PHY_ADDR); + } else { + puts("Invalid SerDes2 protocol for T4240RDB\n"); + } + + for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) { + interface = fm_info_get_enet_if(i); + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + dev = miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME); + fm_info_set_mdio(i, dev); + break; + default: + break; + } + } + + for (i = FM2_10GEC1; i < FM2_10GEC1 + CONFIG_SYS_NUM_FM2_10GEC; i++) { + switch (fm_info_get_enet_if(i)) { + case PHY_INTERFACE_MODE_XGMII: + dev = miiphy_get_dev_by_name(DEFAULT_FM_TGEC_MDIO_NAME); + fm_info_set_mdio(i, dev); + break; + default: + break; + } + } +#endif /* CONFIG_SYS_NUM_FMAN */ + + cpu_eth_init(bis); +#endif /* CONFIG_FMAN_ENET */ + + return pci_eth_init(bis); +} diff --git a/board/freescale/t4rdb/law.c b/board/freescale/t4rdb/law.c new file mode 100644 index 0000000..1f58768 --- /dev/null +++ b/board/freescale/t4rdb/law.c @@ -0,0 +1,28 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/fsl_law.h> +#include <asm/mmu.h> + +struct law_entry law_table[] = { + SET_LAW(CONFIG_SYS_FLASH_BASE_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_IFC), +#ifdef CONFIG_SYS_BMAN_MEM_PHYS + SET_LAW(CONFIG_SYS_BMAN_MEM_PHYS, LAW_SIZE_32M, LAW_TRGT_IF_BMAN), +#endif +#ifdef CONFIG_SYS_QMAN_MEM_PHYS + SET_LAW(CONFIG_SYS_QMAN_MEM_PHYS, LAW_SIZE_32M, LAW_TRGT_IF_QMAN), +#endif +#ifdef CONFIG_SYS_DCSRBAR_PHYS + /* Limit DCSR to 32M to access NPC Trace Buffer */ + SET_LAW(CONFIG_SYS_DCSRBAR_PHYS, LAW_SIZE_32M, LAW_TRGT_IF_DCSR), +#endif +#ifdef CONFIG_SYS_NAND_BASE_PHYS + SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_64K, LAW_TRGT_IF_IFC), +#endif +}; + +int num_law_entries = ARRAY_SIZE(law_table); diff --git a/board/freescale/t4rdb/pci.c b/board/freescale/t4rdb/pci.c new file mode 100644 index 0000000..6387a20 --- /dev/null +++ b/board/freescale/t4rdb/pci.c @@ -0,0 +1,23 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <pci.h> +#include <asm/fsl_pci.h> +#include <libfdt.h> +#include <fdt_support.h> +#include <asm/fsl_serdes.h> + +void pci_init_board(void) +{ + fsl_pcie_init_board(0); +} + +void pci_of_setup(void *blob, bd_t *bd) +{ + FT_FSL_PCI_SETUP; +} diff --git a/board/freescale/t4rdb/t4240rdb.c b/board/freescale/t4rdb/t4240rdb.c new file mode 100644 index 0000000..5448c86 --- /dev/null +++ b/board/freescale/t4rdb/t4240rdb.c @@ -0,0 +1,125 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <i2c.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> + +#include "t4rdb.h" + +DECLARE_GLOBAL_DATA_PTR; + +int checkboard(void) +{ + struct cpu_type *cpu = gd->arch.cpu; + + printf("Board: %sRDB, ", cpu->name); + + puts("SERDES Reference Clocks:\n"); + printf(" SERDES1=100MHz SERDES2=156.25MHz\n" + " SERDES3=100MHz SERDES4=100MHz\n"); + + return 0; +} + +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(); +#ifdef CONFIG_SYS_DPAA_QBMAN + setup_portals(); +#endif + + return 0; +} + +int misc_init_r(void) +{ + 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); + +#ifdef CONFIG_PCI + pci_of_setup(blob, bd); +#endif + + fdt_fixup_liodn(blob); + fdt_fixup_dr_usb(blob, bd); + +#ifdef CONFIG_SYS_DPAA_FMAN + fdt_fixup_fman_ethernet(blob); + fdt_fixup_board_enet(blob); +#endif +} + +/* + * This function is called by bdinfo to print detail board information. + * As an exmaple for future board, we organize the messages into + * several sections. If applicable, the message is in the format of + * <name> = <value> + * It should aligned with normal output of bdinfo command. + * + * Voltage: Core, DDR and another configurable voltages + * Clock : Critical clocks which are not printed already + * RCW : RCW source if not printed already + * Misc : Other important information not in above catagories + */ +void board_detail(void) +{ + int rcwsrc; + + /* RCW section SW3[4] */ + rcwsrc = 0x0; + puts("RCW source = "); + switch (rcwsrc & 0x1) { + case 0x1: + puts("SDHC/eMMC\n"); + break; + default: + puts("I2C normal addressing\n"); + break; + } +} diff --git a/board/freescale/t4rdb/t4_pbi.cfg b/board/freescale/t4rdb/t4_pbi.cfg new file mode 100644 index 0000000..c9f8ced --- /dev/null +++ b/board/freescale/t4rdb/t4_pbi.cfg @@ -0,0 +1,31 @@ +# +# Copyright 2014 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +#PBI commands +#Initialize CPC1 +09010000 00200400 +09138000 00000000 +091380c0 00000100 +#512KB SRAM +09010100 00000000 +09010104 fff80009 +09010f00 08000000 +#enable CPC1 +09010000 80000000 +#Configure LAW for CPC1 +09000d00 00000000 +09000d04 fff80000 +09000d08 81000012 +#slow mdio clock +095fc030 00008148 +095fd030 00808148 +#Configure alternate space +09000010 00000000 +09000014 ff000000 +09000018 81000000 +#Flush PBL data +09138000 00000000 +091380c0 00000000 diff --git a/board/freescale/t4rdb/t4_rcw.cfg b/board/freescale/t4rdb/t4_rcw.cfg new file mode 100644 index 0000000..13408bd --- /dev/null +++ b/board/freescale/t4rdb/t4_rcw.cfg @@ -0,0 +1,7 @@ +#PBL preamble and RCW header +aa55aa55 010e0100 +#serdes protocol 28_56_2_10 +16070019 18101916 00000000 00000000 +70701050 00448c00 6c020000 f5000000 +00000000 ee0000ee 00000000 000287fc +00000000 50000000 00000000 00000028 diff --git a/board/freescale/t4rdb/t4rdb.h b/board/freescale/t4rdb/t4rdb.h new file mode 100644 index 0000000..fb25d43 --- /dev/null +++ b/board/freescale/t4rdb/t4rdb.h @@ -0,0 +1,18 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __T4RDB_H__ +#define __T4RDB_H__ + +#undef CONFIG_SYS_NUM_FM1_DTSEC +#undef CONFIG_SYS_NUM_FM2_DTSEC +#define CONFIG_SYS_NUM_FM1_DTSEC 4 +#define CONFIG_SYS_NUM_FM2_DTSEC 4 + +void fdt_fixup_board_enet(void *blob); +void pci_of_setup(void *blob, bd_t *bd); + +#endif diff --git a/board/freescale/t4rdb/tlb.c b/board/freescale/t4rdb/tlb.c new file mode 100644 index 0000000..4b50bcd --- /dev/null +++ b/board/freescale/t4rdb/tlb.c @@ -0,0 +1,111 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/mmu.h> + +struct fsl_e_tlb_entry tlb_table[] = { + /* TLB 0 - for temp stack in cache */ + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR, + CONFIG_SYS_INIT_RAM_ADDR_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024, + CONFIG_SYS_INIT_RAM_ADDR_PHYS + 4 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024, + CONFIG_SYS_INIT_RAM_ADDR_PHYS + 8 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024, + CONFIG_SYS_INIT_RAM_ADDR_PHYS + 12 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + + /* TLB 1 */ + /* *I*** - Covers boot page */ +#if defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SYS_INIT_L3_ADDR) + /* + * *I*G - L3SRAM. When L3 is used as 512K SRAM */ + SET_TLB_ENTRY(1, CONFIG_SYS_INIT_L3_ADDR, CONFIG_SYS_INIT_L3_ADDR, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 0, BOOKE_PAGESZ_512K, 1), +#else + SET_TLB_ENTRY(1, 0xfffff000, 0xfffff000, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 0, BOOKE_PAGESZ_4K, 1), +#endif + + /* *I*G* - CCSRBAR */ + SET_TLB_ENTRY(1, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 1, BOOKE_PAGESZ_16M, 1), + + /* *I*G* - Flash, localbus */ + /* This will be changed to *I*G* after relocation to RAM. */ + SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS, + MAS3_SX|MAS3_SR, MAS2_W|MAS2_G, + 0, 2, BOOKE_PAGESZ_256M, 1), + + /* *I*G* - PCI */ + SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT, CONFIG_SYS_PCIE1_MEM_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 3, BOOKE_PAGESZ_1G, 1), + + /* *I*G* - PCI */ + SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT + 0x40000000, + CONFIG_SYS_PCIE1_MEM_PHYS + 0x40000000, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 4, BOOKE_PAGESZ_256M, 1), + + SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT + 0x50000000, + CONFIG_SYS_PCIE1_MEM_PHYS + 0x50000000, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 5, BOOKE_PAGESZ_256M, 1), + + /* *I*G* - PCI I/O */ + SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_IO_VIRT, CONFIG_SYS_PCIE1_IO_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 6, BOOKE_PAGESZ_256K, 1), + + /* Bman/Qman */ +#ifdef CONFIG_SYS_BMAN_MEM_PHYS + SET_TLB_ENTRY(1, CONFIG_SYS_BMAN_MEM_BASE, CONFIG_SYS_BMAN_MEM_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 9, BOOKE_PAGESZ_16M, 1), + SET_TLB_ENTRY(1, CONFIG_SYS_BMAN_MEM_BASE + 0x01000000, + CONFIG_SYS_BMAN_MEM_PHYS + 0x01000000, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 10, BOOKE_PAGESZ_16M, 1), +#endif +#ifdef CONFIG_SYS_QMAN_MEM_PHYS + SET_TLB_ENTRY(1, CONFIG_SYS_QMAN_MEM_BASE, CONFIG_SYS_QMAN_MEM_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 11, BOOKE_PAGESZ_16M, 1), + SET_TLB_ENTRY(1, CONFIG_SYS_QMAN_MEM_BASE + 0x01000000, + CONFIG_SYS_QMAN_MEM_PHYS + 0x01000000, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 12, BOOKE_PAGESZ_16M, 1), +#endif +#ifdef CONFIG_SYS_DCSRBAR_PHYS + SET_TLB_ENTRY(1, CONFIG_SYS_DCSRBAR, CONFIG_SYS_DCSRBAR_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 13, BOOKE_PAGESZ_32M, 1), +#endif +#ifdef CONFIG_SYS_NAND_BASE + /* + * *I*G - NAND + * entry 14 and 15 has been used hard coded, they will be disabled + * in cpu_init_f, so we use entry 16 for nand. + */ + SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 16, BOOKE_PAGESZ_64K, 1), +#endif +}; + +int num_tlb_entries = ARRAY_SIZE(tlb_table); diff --git a/board/keymile/kmp204x/kmp204x.c b/board/keymile/kmp204x/kmp204x.c index 95a19cd..6bc8eb8 100644 --- a/board/keymile/kmp204x/kmp204x.c +++ b/board/keymile/kmp204x/kmp204x.c @@ -79,7 +79,7 @@ int get_scl(void) #define ZL30158_RST 8 -#define ZL30343_RST 9 +#define BFTIC4_RST 0 int board_early_init_f(void) { @@ -88,13 +88,15 @@ int board_early_init_f(void) /* board only uses the DDR_MCK0, so disable the DDR_MCK1/2/3 */ setbits_be32(&gur->ddrclkdr, 0x001f000f); - /* take the Zarlinks out of reset as soon as possible */ - qrio_prst(ZL30158_RST, false, false); - qrio_prst(ZL30343_RST, false, false); + /* set the BFTIC's prstcfg to reset at power-up and unit reset only */ + qrio_prstcfg(BFTIC4_RST, PRSTCFG_POWUP_UNIT_RST); + /* and enable WD on it */ + qrio_wdmask(BFTIC4_RST, true); - /* and set their reset to power-up only */ - qrio_prstcfg(ZL30158_RST, PRSTCFG_POWUP_RST); - qrio_prstcfg(ZL30343_RST, PRSTCFG_POWUP_RST); + /* set the ZL30138's prstcfg to reset at power-up and unit reset only */ + qrio_prstcfg(ZL30158_RST, PRSTCFG_POWUP_UNIT_RST); + /* and take it out of reset as soon as possible (needed for Hooper) */ + qrio_prst(ZL30158_RST, false, false); return 0; } @@ -113,6 +115,12 @@ int board_early_init_r(void) if (ret) printf("error triggering PCIe FPGA config\n"); + /* enable the Unit LED (red) & Boot LED (on) */ + qrio_set_leds(); + + /* enable Application Buffer */ + qrio_enable_app_buffer(); + return ret; } @@ -121,16 +129,37 @@ unsigned long get_board_sys_clk(unsigned long dummy) return 66666666; } +#define ETH_FRONT_PHY_RST 15 +#define QSFP2_RST 11 +#define QSFP1_RST 10 +#define ZL30343_RST 9 + int misc_init_f(void) { /* configure QRIO pis for i2c deblocking */ i2c_deblock_gpio_cfg(); + /* configure the front phy's prstcfg and take it out of reset */ + qrio_prstcfg(ETH_FRONT_PHY_RST, PRSTCFG_POWUP_UNIT_CORE_RST); + qrio_prst(ETH_FRONT_PHY_RST, false, false); + + /* set the ZL30343 prstcfg to reset at power-up and unit reset only */ + qrio_prstcfg(ZL30343_RST, PRSTCFG_POWUP_UNIT_RST); + /* and enable the WD on it */ + qrio_wdmask(ZL30343_RST, true); + + /* set the QSFPs' prstcfg to reset at power-up and unit rst only */ + qrio_prstcfg(QSFP1_RST, PRSTCFG_POWUP_UNIT_RST); + qrio_prstcfg(QSFP2_RST, PRSTCFG_POWUP_UNIT_RST); + + /* and enable the WD on them */ + qrio_wdmask(QSFP1_RST, true); + qrio_wdmask(QSFP2_RST, true); + return 0; } #define NUM_SRDS_BANKS 2 -#define PHY_RST 15 int misc_init_r(void) { @@ -151,9 +180,6 @@ int misc_init_r(void) } } - /* take the mgmt eth phy out of reset */ - qrio_prst(PHY_RST, false, false); - return 0; } @@ -166,9 +192,23 @@ int hush_init_var(void) #endif #if defined(CONFIG_LAST_STAGE_INIT) + int last_stage_init(void) { +#if defined(CONFIG_KMCOGE4) + /* on KMCOGE4, the BFTIC4 is on the LBAPP2 */ + struct bfticu_iomap *bftic4 = + (struct bfticu_iomap *)CONFIG_SYS_LBAPP2_BASE; + u8 dip_switch = in_8((u8 *)&(bftic4->mswitch)) & BFTICU_DIPSWITCH_MASK; + + if (dip_switch != 0) { + /* start bootloader */ + puts("DIP: Enabled\n"); + setenv("actual_bank", "0"); + } +#endif set_km_env(); + return 0; } #endif @@ -232,3 +272,16 @@ void ft_board_setup(void *blob, bd_t *bd) fdt_fixup_fman_mac_addresses(blob); #endif } + +#if defined(CONFIG_POST) + +/* DIC26_SELFTEST GPIO used to start factory test sw */ +#define SELFTEST_PORT GPIO_A +#define SELFTEST_PIN 31 + +int post_hotkeys_pressed(void) +{ + qrio_gpio_direction_input(SELFTEST_PORT, SELFTEST_PIN); + return qrio_get_gpio(SELFTEST_PORT, SELFTEST_PIN); +} +#endif diff --git a/board/keymile/kmp204x/kmp204x.h b/board/keymile/kmp204x/kmp204x.h index 0267596..afede99 100644 --- a/board/keymile/kmp204x/kmp204x.h +++ b/board/keymile/kmp204x/kmp204x.h @@ -20,6 +20,9 @@ void qrio_gpio_direction_input(u8 port_off, u8 gpio_nr); #define PRSTCFG_POWUP_RST 0x3 void qrio_prst(u8 bit, bool en, bool wden); +void qrio_wdmask(u8 bit, bool wden); void qrio_prstcfg(u8 bit, u8 mode); +void qrio_set_leds(void); +void qrio_enable_app_buffer(void); void pci_of_setup(void *blob, bd_t *bd); diff --git a/board/keymile/kmp204x/pbi.cfg b/board/keymile/kmp204x/pbi.cfg index 9af8bd5..1e0a171 100644 --- a/board/keymile/kmp204x/pbi.cfg +++ b/board/keymile/kmp204x/pbi.cfg @@ -8,16 +8,47 @@ # #PBI commands -#Workaround for A-006559 needed for rev 2.0 of P2041 silicon -#Freescale's errarta sheet suggests it may be done with PBI +#Configure ALTCBAR for DCSR -> DCSR@89000000 +091380c0 000009C4 09000010 00000000 +091380c0 000009C4 09000014 00000000 +091380c0 000009C4 09000018 81d00000 -09021008 0000f000 -09021028 0000f000 -09021048 0000f000 -09021068 0000f000 +#Workaround for A-004849 +091380c0 000009C4 +890B0050 00000002 +091380c0 000009C4 +890B0054 00000002 +091380c0 000009C4 +890B0058 00000002 +091380c0 000009C4 +890B005C 00000002 +091380c0 000009C4 +890B0090 00000002 +091380c0 000009C4 +890B0094 00000002 +091380c0 000009C4 +890B0098 00000002 +091380c0 000009C4 +890B009C 00000002 +091380c0 000009C4 +890B0108 00000012 +091380c0 000009C4 +#Workaround for A-006559 needed for rev 2.0 of P2041 silicon +89021008 0000f000 +091380c0 000009C4 +89021028 0000f000 +091380c0 000009C4 +89021048 0000f000 +091380c0 000009C4 +89021068 0000f000 +091380c0 000009C4 +#Flush PBL data +09138000 00000000 +#Disable ALTCBAR 09000018 00000000 +091380c0 000009C4 #Initialize CPC1 as 1MB SRAM 09010000 00200400 09138000 00000000 diff --git a/board/keymile/kmp204x/pci.c b/board/keymile/kmp204x/pci.c index a484eb5..2b0b054 100644 --- a/board/keymile/kmp204x/pci.c +++ b/board/keymile/kmp204x/pci.c @@ -94,20 +94,23 @@ err_out: } #define PCIE_SW_RST 14 -#define PEXHC_SW_RST 13 -#define HOOPER_SW_RST 12 +#define PEXHC_RST 13 +#define HOOPER_RST 12 void pci_init_board(void) { - /* first wait for the PCIe FPGA to be configured + qrio_prstcfg(PCIE_SW_RST, PRSTCFG_POWUP_UNIT_CORE_RST); + qrio_prstcfg(PEXHC_RST, PRSTCFG_POWUP_UNIT_CORE_RST); + qrio_prstcfg(HOOPER_RST, PRSTCFG_POWUP_UNIT_CORE_RST); + + /* wait for the PCIe FPGA to be configured * it has been triggered earlier in board_early_init_r */ - int ret = wait_for_fpga_config(); - if (ret) + if (wait_for_fpga_config()) printf("error finishing PCIe FPGA config\n"); qrio_prst(PCIE_SW_RST, false, false); - qrio_prst(PEXHC_SW_RST, false, false); - qrio_prst(HOOPER_SW_RST, false, false); + qrio_prst(PEXHC_RST, false, false); + qrio_prst(HOOPER_RST, false, false); /* Hooper is not direcly PCIe capable */ mdelay(50); diff --git a/board/keymile/kmp204x/qrio.c b/board/keymile/kmp204x/qrio.c index 49f9aa2..b6ba93a 100644 --- a/board/keymile/kmp204x/qrio.c +++ b/board/keymile/kmp204x/qrio.c @@ -91,7 +91,7 @@ void qrio_set_opendrain_gpio(u8 port_off, u8 gpio_nr, u8 val) #define WDMASK_OFF 0x16 -static void qrio_wdmask(u8 bit, bool wden) +void qrio_wdmask(u8 bit, bool wden) { u16 wdmask; void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE; @@ -144,3 +144,32 @@ void qrio_prstcfg(u8 bit, u8 mode) out_be32(qrio_base + PRSTCFG_OFF, prstcfg); } + +#define CTRLH_OFF 0x02 +#define CTRLH_WRL_BOOT 0x01 +#define CTRLH_WRL_UNITRUN 0x02 + +void qrio_set_leds(void) +{ + u8 ctrlh; + void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE; + + /* set UNIT LED to RED and BOOT LED to ON */ + ctrlh = in_8(qrio_base + CTRLH_OFF); + ctrlh |= (CTRLH_WRL_BOOT | CTRLH_WRL_UNITRUN); + out_8(qrio_base + CTRLH_OFF, ctrlh); +} + +#define CTRLL_OFF 0x03 +#define CTRLL_WRB_BUFENA 0x20 + +void qrio_enable_app_buffer(void) +{ + u8 ctrll; + void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE; + + /* enable application buffer */ + ctrll = in_8(qrio_base + CTRLL_OFF); + ctrll |= (CTRLL_WRB_BUFENA); + out_8(qrio_base + CTRLL_OFF, ctrll); +} diff --git a/board/keymile/kmp204x/rcw_kmp204x.cfg b/board/keymile/kmp204x/rcw_kmp204x.cfg index 2d4c48c..236d513 100644 --- a/board/keymile/kmp204x/rcw_kmp204x.cfg +++ b/board/keymile/kmp204x/rcw_kmp204x.cfg @@ -7,5 +7,5 @@ aa55aa55 010e0100 #64 bytes RCW data 14600000 00000000 28200000 00000000 148E70CF CFC02000 58000000 41000000 -00000000 00000000 00000000 F0428002 +00000000 00000000 00000000 F0428816 00000000 00000000 00000000 00000000 |