From 4150f24290a4b6a3afe61487413408e5082f33be Mon Sep 17 00:00:00 2001 From: Shaveta Leekha Date: Fri, 11 Apr 2014 14:12:39 +0530 Subject: board/freescale/common: ZM7300 driver Adds Support for PowerOne ZM7300 voltage regulator. This device is available on some Freescale Boards like B4860QDS and has to be programmed to adjust the voltage on the board. The device is accessible via I2C interface. Signed-off-by: Shaveta Leekha Signed-off-by: Poonam Aggrwal --- board/freescale/common/Makefile | 1 + board/freescale/common/zm7300.c | 235 ++++++++++++++++++++++++++++++++++++++++ board/freescale/common/zm7300.h | 22 ++++ 3 files changed, 258 insertions(+) create mode 100644 board/freescale/common/zm7300.c create mode 100644 board/freescale/common/zm7300.h (limited to 'board/freescale') diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index f6a0879753..22b57ccaa8 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/zm7300.c b/board/freescale/common/zm7300.c new file mode 100644 index 0000000000..be5953ad2d --- /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 0000000000..6b4d035970 --- /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 +#include +#include +#include + +#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_ */ -- cgit v1.2.1 From 652e29b4a0d5ff418a4f1a633912976cd7331758 Mon Sep 17 00:00:00 2001 From: Shaveta Leekha Date: Fri, 11 Apr 2014 14:12:40 +0530 Subject: board/b4qds: VID support The fuse status register provides the values from on-chip voltage ID efuses programmed at the factory. These values define the voltage requirements for the chip. u-boot reads FUSESR and translates the values into the appropriate commands to set the voltage output value of an external voltage regulator. B4860QDS has a PowerOne ZM7300 programmable digital Power Manager which is programmed as per the value read from the fuses. Reference for this code is taken from t4qds VID implementation. Signed-off-by: Shaveta Leekha Signed-off-by: Poonam Aggrwal --- board/freescale/b4860qds/b4860qds.c | 240 ++++++++++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) (limited to 'board/freescale') diff --git a/board/freescale/b4860qds/b4860qds.c b/board/freescale/b4860qds/b4860qds.c index d9c88a074f..b2d5378143 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. -- cgit v1.2.1 From 0b2e13d9ccbe56e32dc674cf896b2fb55684368c Mon Sep 17 00:00:00 2001 From: Chunhe Lan Date: Mon, 14 Apr 2014 18:42:06 +0800 Subject: powerpc/85xx: Add T4240RDB board support T4240RDB board Specification ---------------------------- Memory subsystem: 6GB DDR3 128MB NOR flash 2GB NAND flash Ethernet: Eight 1G SGMII ports Four 10Gbps SFP+ ports PCIe: Two PCIe slots USB: Two USB2.0 Type A ports SDHC: One SD-card port SATA: One SATA port UART: Dual RJ45 ports Signed-off-by: Chunhe Lan [York Sun: fix CONFIG_SYS_QE_FMAN_FW_ADDR in T4240RDB.h] --- board/freescale/t4rdb/Makefile | 12 ++++ board/freescale/t4rdb/ddr.c | 118 +++++++++++++++++++++++++++++++ board/freescale/t4rdb/ddr.h | 78 +++++++++++++++++++++ board/freescale/t4rdb/eth.c | 146 +++++++++++++++++++++++++++++++++++++++ board/freescale/t4rdb/law.c | 28 ++++++++ board/freescale/t4rdb/pci.c | 23 ++++++ board/freescale/t4rdb/t4240rdb.c | 125 +++++++++++++++++++++++++++++++++ board/freescale/t4rdb/t4_pbi.cfg | 31 +++++++++ board/freescale/t4rdb/t4_rcw.cfg | 7 ++ board/freescale/t4rdb/t4rdb.h | 18 +++++ board/freescale/t4rdb/tlb.c | 111 +++++++++++++++++++++++++++++ 11 files changed, 697 insertions(+) create mode 100644 board/freescale/t4rdb/Makefile create mode 100644 board/freescale/t4rdb/ddr.c create mode 100644 board/freescale/t4rdb/ddr.h create mode 100644 board/freescale/t4rdb/eth.c create mode 100644 board/freescale/t4rdb/law.c create mode 100644 board/freescale/t4rdb/pci.c create mode 100644 board/freescale/t4rdb/t4240rdb.c create mode 100644 board/freescale/t4rdb/t4_pbi.cfg create mode 100644 board/freescale/t4rdb/t4_rcw.cfg create mode 100644 board/freescale/t4rdb/t4rdb.h create mode 100644 board/freescale/t4rdb/tlb.c (limited to 'board/freescale') diff --git a/board/freescale/t4rdb/Makefile b/board/freescale/t4rdb/Makefile new file mode 100644 index 0000000000..f7f7fc0177 --- /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 0000000000..5a43c1bc78 --- /dev/null +++ b/board/freescale/t4rdb/ddr.c @@ -0,0 +1,118 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#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 0000000000..7b854767e7 --- /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 0000000000..d220475b5a --- /dev/null +++ b/board/freescale/t4rdb/eth.c @@ -0,0 +1,146 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * Chunhe Lan + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 0000000000..1f5876885c --- /dev/null +++ b/board/freescale/t4rdb/law.c @@ -0,0 +1,28 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +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 0000000000..6387a20cae --- /dev/null +++ b/board/freescale/t4rdb/pci.c @@ -0,0 +1,23 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +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 0000000000..5448c86c48 --- /dev/null +++ b/board/freescale/t4rdb/t4240rdb.c @@ -0,0 +1,125 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + * = + * 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 0000000000..c9f8ced2a3 --- /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 0000000000..13408bd01f --- /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 0000000000..fb25d43291 --- /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 0000000000..4b50bcd09b --- /dev/null +++ b/board/freescale/t4rdb/tlb.c @@ -0,0 +1,111 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +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); -- cgit v1.2.1 From b539534d120c3f017965b25aa36fcfb75db8383c Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 30 Apr 2014 19:21:10 +0200 Subject: PPC 85xx QEMU: Always assume 1 core We only need u-boot to bother about a single core in the QEMU machine. Everything that would require additional knowledge of more cores gets handled by QEMU and passed straight into the payload we execute. Because of this setup, it would be counterproductive to enable SMP support in u-boot. We would have to rip CPUs out of already existing spin tables and respin them from u-boot. It would be a pretty big mess. So only assume we have a single core. This fixes errors about CONFIG_MP being disabled. Signed-off-by: Alexander Graf --- board/freescale/qemu-ppce500/qemu-ppce500.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'board/freescale') diff --git a/board/freescale/qemu-ppce500/qemu-ppce500.c b/board/freescale/qemu-ppce500/qemu-ppce500.c index 3dbb0cf43b..230870d90e 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; +} -- cgit v1.2.1 From bffac7aef54039dbe53dbf8bcbc9f8dbe78b8aa5 Mon Sep 17 00:00:00 2001 From: York Sun Date: Wed, 30 Apr 2014 14:43:46 -0700 Subject: powerpc/freescale: Change the return value of mac_read_from_eeprom() The return value has not been checked by its caller, until recent change of using generic board architecture. The error of this function is not critical enough to hang the system. Printing the warning message is enough to catch user's attention. U-boot should continue to boot to give user a chance to fix the EEPROM. Chaning the return value to 0 to avoid hanging in the board_init_r(). Signed-off-by: York Sun --- board/freescale/common/sys_eeprom.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'board/freescale') diff --git a/board/freescale/common/sys_eeprom.c b/board/freescale/common/sys_eeprom.c index 9c18dd8242..33a5a5a8f5 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 -- cgit v1.2.1 From 477c894ff475be9886bd936fa8eeef7bfe862161 Mon Sep 17 00:00:00 2001 From: Ebony Zhu Date: Fri, 25 Apr 2014 18:38:44 -0500 Subject: board/freescale: Move CRC32 offset in NXID v1 data format According to AN3638, CRC of NXID v1 is at the end of the 256-byte I2C memory. The wrong CRC32 offset prevents Uboot from reading system information from EEPROM. No NXID v0 is being used on Freescale boards. Signed-off-by: Ebony Zhu Reviewed-by: York Sun --- board/freescale/common/sys_eeprom.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'board/freescale') diff --git a/board/freescale/common/sys_eeprom.c b/board/freescale/common/sys_eeprom.c index 33a5a5a8f5..6144c533ef 100644 --- a/board/freescale/common/sys_eeprom.c +++ b/board/freescale/common/sys_eeprom.c @@ -21,7 +21,7 @@ /* some boards with non-256-bytes EEPROM have special define */ /* for MAX_NUM_PORTS in board-specific file */ #ifndef MAX_NUM_PORTS -#define MAX_NUM_PORTS 23 +#define MAX_NUM_PORTS 16 #endif #define NXID_VERSION 1 #endif @@ -58,8 +58,9 @@ static struct __attribute__ ((__packed__)) eeprom { 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 */ + u8 mac[MAX_NUM_PORTS][6]; /* 0x42 - 0xa1 MAC addresses */ + u8 res_2[90]; /* 0xa2 - 0xfb Reserved */ + u32 crc; /* 0xfc - 0xff CRC32 checksum */ #endif } e; -- cgit v1.2.1 From 0f1fa36ffffbd34c8512eeacade7139bcffda47c Mon Sep 17 00:00:00 2001 From: Tang Yuantian Date: Wed, 7 May 2014 10:25:06 +0800 Subject: powerpc/t104xrdb: Toggle deep sleep management signals after resume T104xrdb has several sleep management signals that are used for deep sleep. They are enabled by OS to enter deep sleep and should be disabled by u-boot when cores wake up. Signed-off-by: Tang Yuantian Reviewed-by: York Sun --- board/freescale/t104xrdb/t104xrdb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'board/freescale') diff --git a/board/freescale/t104xrdb/t104xrdb.c b/board/freescale/t104xrdb/t104xrdb.c index fb5b84940e..a5e5fffac4 100644 --- a/board/freescale/t104xrdb/t104xrdb.c +++ b/board/freescale/t104xrdb/t104xrdb.c @@ -109,6 +109,8 @@ void ft_board_setup(void *blob, bd_t *bd) #ifdef CONFIG_DEEP_SLEEP void board_mem_sleep_setup(void) { + /* does not provide HW signals for power management */ + CPLD_WRITE(misc_ctl_status, (CPLD_READ(misc_ctl_status) & ~0x40)); /* Disable MCKE isolation */ gpio_set_value(2, 0); udelay(1); -- cgit v1.2.1 From bc2d40ca10075c8bf0c8c3cb970b1381caf5c588 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 15 May 2014 16:43:12 +0530 Subject: board/p1_p2_rdb:Enable p1_p2_rdb boot from NAND/SD/SPI in SPL In the earlier patches, the SPL/TPL fraamework was introduced. For SD/SPI flash booting way, we introduce the SPL to enable a loader stub. The SPL was loaded by the code from the internal on-chip ROM. The SPL initializes the DDR according to the SPD and loads the final uboot image into DDR, then jump to the DDR to begin execution. For NAND booting way, the nand SPL has size limitation on some board(e.g. P1010RDB), it can not be more than 4KB, we can call it "minimal SPL", So the dynamic DDR driver doesn't fit into this minimum SPL. We added the TPL that is loaded by the the minimal SPL. The TPL initializes the DDR according to the SPD and loads the final uboot image into DDR,then jump to the DDR to begin execution. This patch enabled SPL/TPL for P1_P2_RDB to support starting from NAND/SD/SPI flash with SPL framework and initializing the DDR according to SPD in the SPL/TPL. Because the minimal SPL load the TPL to L2 SRAM and the jump to the L2 SRAM to execute, so the section .resetvec is no longer needed. Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun --- board/freescale/p1_p2_rdb/Makefile | 21 ++++- board/freescale/p1_p2_rdb/ddr.c | 16 ++-- board/freescale/p1_p2_rdb/spl.c | 141 ++++++++++++++++++++++++++++++++ board/freescale/p1_p2_rdb/spl_minimal.c | 84 +++++++++++++++++++ board/freescale/p1_p2_rdb/tlb.c | 18 +++- 5 files changed, 267 insertions(+), 13 deletions(-) create mode 100644 board/freescale/p1_p2_rdb/spl.c create mode 100644 board/freescale/p1_p2_rdb/spl_minimal.c (limited to 'board/freescale') diff --git a/board/freescale/p1_p2_rdb/Makefile b/board/freescale/p1_p2_rdb/Makefile index f7b568a021..a97bf45f00 100644 --- a/board/freescale/p1_p2_rdb/Makefile +++ b/board/freescale/p1_p2_rdb/Makefile @@ -4,8 +4,27 @@ # SPDX-License-Identifier: GPL-2.0+ # +MINIMAL= + +ifdef CONFIG_SPL_BUILD +ifdef CONFIG_SPL_INIT_MINIMAL +MINIMAL=y +endif +endif + +ifdef MINIMAL + +obj-y += spl_minimal.o tlb.o law.o + +else +ifdef CONFIG_SPL_BUILD +obj-y += spl.o +else obj-y += p1_p2_rdb.o +obj-$(CONFIG_PCI) += pci.o +endif obj-y += ddr.o obj-y += law.o -obj-$(CONFIG_PCI) += pci.o obj-y += tlb.o + +endif diff --git a/board/freescale/p1_p2_rdb/ddr.c b/board/freescale/p1_p2_rdb/ddr.c index 17d3beac39..98ee5f1021 100644 --- a/board/freescale/p1_p2_rdb/ddr.c +++ b/board/freescale/p1_p2_rdb/ddr.c @@ -180,27 +180,22 @@ fsl_ddr_cfg_regs_t ddr_cfg_regs_800 = { phys_size_t fixed_sdram (void) { - char buf[32]; fsl_ddr_cfg_regs_t ddr_cfg_regs; size_t ddr_size; struct cpu_type *cpu; ulong ddr_freq, ddr_freq_mhz; cpu = gd->arch.cpu; - /* P1020 and it's derivatives support max 32bit DDR width */ - if (cpu->soc_ver == SVR_P1020 || cpu->soc_ver == SVR_P1011) { - ddr_size = (CONFIG_SYS_SDRAM_SIZE * 1024 * 1024 / 2); - } else { - ddr_size = CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; - } + + ddr_size = CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; + #if defined(CONFIG_SYS_RAMBOOT) return ddr_size; #endif ddr_freq = get_ddr_freq(0); ddr_freq_mhz = ddr_freq / 1000000; - printf("Configuring DDR for %s MT/s data rate\n", - strmhz(buf, ddr_freq)); + printf("Configuring DDR for %ld T/s data rate\n", ddr_freq); if(ddr_freq_mhz <= 400) memcpy(&ddr_cfg_regs, &ddr_cfg_regs_400, sizeof(ddr_cfg_regs)); @@ -211,8 +206,7 @@ phys_size_t fixed_sdram (void) else if(ddr_freq_mhz <= 800) memcpy(&ddr_cfg_regs, &ddr_cfg_regs_800, sizeof(ddr_cfg_regs)); else - panic("Unsupported DDR data rate %s MT/s data rate\n", - strmhz(buf, ddr_freq)); + panic("Unsupported DDR data rate %ld T/s\n", ddr_freq); /* P1020 and it's derivatives support max 32bit DDR width */ if (cpu->soc_ver == SVR_P1020 || cpu->soc_ver == SVR_P1011) { diff --git a/board/freescale/p1_p2_rdb/spl.c b/board/freescale/p1_p2_rdb/spl.c new file mode 100644 index 0000000000..f30c5fe3e6 --- /dev/null +++ b/board/freescale/p1_p2_rdb/spl.c @@ -0,0 +1,141 @@ +/* + * Copyright 2013 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define SYSCLK_MASK 0x00200000 +#define BOARDREV_MASK 0x10100000 + +#define SYSCLK_66 66666666 +#define SYSCLK_100 100000000 + +unsigned long get_board_sys_clk(ulong dummy) +{ + ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); + u32 val_gpdat, sysclk_gpio; + + val_gpdat = in_be32(&pgpio->gpdat); + sysclk_gpio = val_gpdat & SYSCLK_MASK; + + if (sysclk_gpio == 0) + return SYSCLK_66; + else + return SYSCLK_100; + + return 0; +} + +phys_size_t get_effective_memsize(void) +{ + return CONFIG_SYS_L2_SIZE; +} + +void board_init_f(ulong bootflag) +{ + u32 plat_ratio, bus_clk; + ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + + console_init_f(); + + /* Set pmuxcr to allow both i2c1 and i2c2 */ + setbits_be32(&gur->pmuxcr, in_be32(&gur->pmuxcr) | 0x1000); + setbits_be32(&gur->pmuxcr, + in_be32(&gur->pmuxcr) | MPC85xx_PMUXCR_SD_DATA); + + /* Read back the register to synchronize the write. */ + in_be32(&gur->pmuxcr); + +#ifdef CONFIG_SPL_SPI_BOOT + clrbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_SD_DATA); +#endif + + /* initialize selected port with appropriate baud rate */ + plat_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_PLAT_RATIO; + plat_ratio >>= 1; + bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio; + gd->bus_clk = bus_clk; + + NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, + bus_clk / 16 / CONFIG_BAUDRATE); +#ifdef CONFIG_SPL_MMC_BOOT + puts("\nSD boot...\n"); +#elif defined(CONFIG_SPL_SPI_BOOT) + puts("\nSPI Flash boot...\n"); +#endif + + /* copy code to RAM and jump to it - this should not return */ + /* NOTE - code has to be copied out of NAND buffer before + * other blocks can be read. + */ + relocate_code(CONFIG_SPL_RELOC_STACK, 0, CONFIG_SPL_RELOC_TEXT_BASE); +} + +void board_init_r(gd_t *gd, ulong dest_addr) +{ + /* Pointer is writable since we allocated a register for it */ + gd = (gd_t *)CONFIG_SPL_GD_ADDR; + bd_t *bd; + + memset(gd, 0, sizeof(gd_t)); + bd = (bd_t *)(CONFIG_SPL_GD_ADDR + sizeof(gd_t)); + memset(bd, 0, sizeof(bd_t)); + gd->bd = bd; + bd->bi_memstart = CONFIG_SYS_INIT_L2_ADDR; + bd->bi_memsize = CONFIG_SYS_L2_SIZE; + + probecpu(); + get_clocks(); + mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, + CONFIG_SPL_RELOC_MALLOC_SIZE); + +#ifdef CONFIG_SPL_MMC_BOOT + mmc_initialize(bd); +#endif + /* relocate environment function pointers etc. */ +#ifdef CONFIG_SPL_NAND_BOOT + nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, + (uchar *)CONFIG_ENV_ADDR); +#endif +#ifdef CONFIG_SPL_NAND_BOOT + nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, + (uchar *)CONFIG_ENV_ADDR); +#endif +#ifdef CONFIG_SPL_MMC_BOOT + mmc_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, + (uchar *)CONFIG_ENV_ADDR); +#endif +#ifdef CONFIG_SPL_SPI_BOOT + spi_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, + (uchar *)CONFIG_ENV_ADDR); +#endif + + gd->env_addr = (ulong)(CONFIG_ENV_ADDR); + gd->env_valid = 1; + + gd->ram_size = initdram(0); +#ifdef CONFIG_SPL_NAND_BOOT + puts("Tertiary program loader running in sram..."); +#else + puts("Second program loader running in sram...\n"); +#endif + +#ifdef CONFIG_SPL_MMC_BOOT + mmc_boot(); +#elif defined(CONFIG_SPL_SPI_BOOT) + spi_boot(); +#elif defined(CONFIG_SPL_NAND_BOOT) + nand_boot(); +#endif +} diff --git a/board/freescale/p1_p2_rdb/spl_minimal.c b/board/freescale/p1_p2_rdb/spl_minimal.c new file mode 100644 index 0000000000..96a4d1cb0a --- /dev/null +++ b/board/freescale/p1_p2_rdb/spl_minimal.c @@ -0,0 +1,84 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; +#define SYSCLK_MASK 0x00200000 +#define BOARDREV_MASK 0x10100000 + +#define SYSCLK_66 66666666 +#define SYSCLK_100 100000000 + +unsigned long get_board_sys_clk(ulong dummy) +{ + ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); + u32 val_gpdat, sysclk_gpio; + + val_gpdat = in_be32(&pgpio->gpdat); + sysclk_gpio = val_gpdat & SYSCLK_MASK; + + if (sysclk_gpio == 0) + return SYSCLK_66; + else + return SYSCLK_100; + + return 0; +} + +void board_init_f(ulong bootflag) +{ + u32 plat_ratio; + ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + +#if defined(CONFIG_SYS_NAND_BR_PRELIM) && defined(CONFIG_SYS_NAND_OR_PRELIM) + set_lbc_br(0, CONFIG_SYS_NAND_BR_PRELIM); + set_lbc_or(0, CONFIG_SYS_NAND_OR_PRELIM); +#endif + + /* initialize selected port with appropriate baud rate */ + plat_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_PLAT_RATIO; + plat_ratio >>= 1; + gd->bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio; + + NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, + gd->bus_clk / 16 / CONFIG_BAUDRATE); + + puts("\nNAND boot... "); + + /* copy code to RAM and jump to it - this should not return */ + /* NOTE - code has to be copied out of NAND buffer before + * other blocks can be read. + */ + relocate_code(CONFIG_SPL_RELOC_STACK, 0, CONFIG_SPL_RELOC_TEXT_BASE); +} + +void board_init_r(gd_t *gd, ulong dest_addr) +{ + puts("\nSecond program loader running in sram..."); + nand_boot(); +} + +void putc(char c) +{ + if (c == '\n') + NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, '\r'); + + NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, c); +} + +void puts(const char *str) +{ + while (*str) + putc(*str++); +} diff --git a/board/freescale/p1_p2_rdb/tlb.c b/board/freescale/p1_p2_rdb/tlb.c index bc98972e33..73f5729ef5 100644 --- a/board/freescale/p1_p2_rdb/tlb.c +++ b/board/freescale/p1_p2_rdb/tlb.c @@ -37,6 +37,7 @@ struct fsl_e_tlb_entry tlb_table[] = { MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 1, BOOKE_PAGESZ_1M, 1), +#ifndef CONFIG_SPL_BUILD /* W**G* - Flash/promjet, 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, @@ -55,6 +56,7 @@ struct fsl_e_tlb_entry tlb_table[] = { 0, 4, BOOKE_PAGESZ_256K, 1), #endif /* #if defined(CONFIG_PCI) */ +#endif /* *I*G - NAND */ SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, @@ -65,7 +67,21 @@ struct fsl_e_tlb_entry tlb_table[] = { MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 6, BOOKE_PAGESZ_1M, 1), -#if defined(CONFIG_SYS_RAMBOOT) +#ifdef CONFIG_SYS_INIT_L2_ADDR + /* *I*G - L2SRAM */ + SET_TLB_ENTRY(1, CONFIG_SYS_INIT_L2_ADDR, CONFIG_SYS_INIT_L2_ADDR_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_G, + 0, 11, BOOKE_PAGESZ_256K, 1), +#if CONFIG_SYS_L2_SIZE >= (256 << 10) + SET_TLB_ENTRY(1, CONFIG_SYS_INIT_L2_ADDR + 0x40000, + CONFIG_SYS_INIT_L2_ADDR_PHYS + 0x40000, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 12, BOOKE_PAGESZ_256K, 1), +#endif +#endif + +#if defined(CONFIG_SYS_RAMBOOT) || \ + (defined(CONFIG_SPL) && !defined(CONFIG_SPL_COMMON_INIT_DDR)) SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE, CONFIG_SYS_DDR_SDRAM_BASE, MAS3_SX|MAS3_SW|MAS3_SR, 0, 0, 7, BOOKE_PAGESZ_1G, 1) -- cgit v1.2.1