GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
if TARGET_B4860QDS || TARGET_B4420QDS
|
||||
|
||||
config SYS_BOARD
|
||||
default "b4860qds"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "freescale"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "B4860QDS"
|
||||
|
||||
source "board/freescale/common/Kconfig"
|
||||
|
||||
endif
|
||||
@@ -0,0 +1,17 @@
|
||||
B4860QDS BOARD
|
||||
M: Ashish Kumar <ashish.kumar@nxp.com>
|
||||
S: Maintained
|
||||
F: board/freescale/b4860qds/
|
||||
F: include/configs/B4860QDS.h
|
||||
F: configs/B4420QDS_defconfig
|
||||
F: configs/B4420QDS_NAND_defconfig
|
||||
F: configs/B4420QDS_SPIFLASH_defconfig
|
||||
F: configs/B4860QDS_defconfig
|
||||
F: configs/B4860QDS_NAND_defconfig
|
||||
F: configs/B4860QDS_SPIFLASH_defconfig
|
||||
F: configs/B4860QDS_SRIO_PCIE_BOOT_defconfig
|
||||
|
||||
B4860QDS_SECURE_BOOT BOARD
|
||||
M: Ruchika Gupta <ruchika.gupta@nxp.com>
|
||||
S: Maintained
|
||||
F: configs/B4860QDS_SECURE_BOOT_defconfig
|
||||
@@ -0,0 +1,16 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright 2012 Freescale Semiconductor, Inc.
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
obj-y += spl.o
|
||||
else
|
||||
obj-y += b4860qds.o
|
||||
obj-$(CONFIG_TARGET_B4860QDS) += eth_b4860qds.o
|
||||
obj-$(CONFIG_TARGET_B4420QDS) += eth_b4860qds.o
|
||||
obj-$(CONFIG_PCI) += pci.o
|
||||
endif
|
||||
|
||||
obj-y += ddr.o
|
||||
obj-y += law.o
|
||||
obj-y += tlb.o
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2011-2012 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __CORENET_DS_H__
|
||||
#define __CORENET_DS_H__
|
||||
|
||||
void fdt_fixup_board_enet(void *blob);
|
||||
void pci_of_setup(void *blob, bd_t *bd);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,72 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __CROSSBAR_CONNECTIONS_H__
|
||||
#define __CROSSBAR_CONNECTIONS_H__
|
||||
|
||||
#define NUM_CON_VSC3316 8
|
||||
#define NUM_CON_VSC3308 4
|
||||
|
||||
static const int8_t vsc16_tx_amc[8][2] = { {15, 3}, {0, 2}, {7, 4}, {9, 10},
|
||||
{5, 11}, {4, 5}, {2, 6}, {12, 9} };
|
||||
|
||||
static int8_t vsc16_tx_sfp[8][2] = { {15, 7}, {0, 1}, {7, 8}, {9, 0},
|
||||
{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} };
|
||||
|
||||
static int8_t vsc16_tx_4sfp_sgmii_12_56[8][2] = { {15, 7}, {0, 1},
|
||||
{7, 8}, {9, 0}, {2, 14}, {12, 15},
|
||||
{-1, -1}, {-1, -1} };
|
||||
|
||||
static const int8_t vsc16_tx_4sfp_sgmii_34[8][2] = { {15, 7}, {0, 1},
|
||||
{7, 8}, {9, 0}, {5, 14}, {4, 15},
|
||||
{-1, -1}, {-1, -1} };
|
||||
|
||||
static int8_t vsc16_tx_sfp_sgmii_aurora[8][2] = { {15, 7}, {0, 1},
|
||||
{7, 8}, {9, 0}, {5, 14},
|
||||
{4, 15}, {2, 12}, {12, 13} };
|
||||
|
||||
#ifdef CONFIG_ARCH_B4420
|
||||
static int8_t vsc16_tx_sgmii_lane_cd[8][2] = { {5, 14}, {4, 15},
|
||||
{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} };
|
||||
#endif
|
||||
|
||||
static const int8_t vsc16_tx_aurora[8][2] = { {2, 13}, {12, 12}, {-1, -1},
|
||||
{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} };
|
||||
|
||||
static const int8_t vsc16_rx_amc[8][2] = { {3, 15}, {2, 1}, {4, 8}, {10, 9},
|
||||
{11, 11}, {5, 10}, {6, 3}, {9, 12} };
|
||||
|
||||
static int8_t vsc16_rx_sfp[8][2] = { {8, 15}, {0, 1}, {7, 8}, {1, 9},
|
||||
{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} };
|
||||
|
||||
static int8_t vsc16_rx_4sfp_sgmii_12_56[8][2] = { {8, 15}, {0, 1},
|
||||
{7, 8}, {1, 9}, {14, 3}, {15, 12},
|
||||
{-1, -1}, {-1, -1} };
|
||||
|
||||
static const int8_t vsc16_rx_4sfp_sgmii_34[8][2] = { {8, 15}, {0, 1},
|
||||
{7, 8}, {1, 9}, {14, 11}, {15, 10},
|
||||
{-1, -1}, {-1, -1} };
|
||||
|
||||
static int8_t vsc16_rx_sfp_sgmii_aurora[8][2] = { {8, 15}, {0, 1},
|
||||
{7, 8}, {1, 9}, {14, 11},
|
||||
{15, 10}, {13, 3}, {12, 12} };
|
||||
|
||||
#ifdef CONFIG_ARCH_B4420
|
||||
static int8_t vsc16_rx_sgmii_lane_cd[8][2] = { {14, 11}, {15, 10},
|
||||
{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} };
|
||||
#endif
|
||||
|
||||
static const int8_t vsc16_rx_aurora[8][2] = { {13, 3}, {12, 12}, {-1, -1},
|
||||
{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} };
|
||||
|
||||
static const int8_t vsc08_tx_amc[4][2] = { {2, 2}, {3, 3}, {7, 4}, {1, 5} };
|
||||
|
||||
static const int8_t vsc08_tx_sfp[4][2] = { {2, 1}, {3, 0}, {7, 6}, {1, 7} };
|
||||
|
||||
static const int8_t vsc08_rx_amc[4][2] = { {2, 3}, {3, 4}, {4, 7}, {5, 1} };
|
||||
|
||||
static const int8_t vsc08_rx_sfp[4][2] = { {1, 3}, {0, 4}, {6, 7}, {7, 1} };
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __B4860QDS_QIXIS_H__
|
||||
#define __B4860QDS_QIXIS_H__
|
||||
|
||||
/* Definitions of QIXIS Registers for B4860QDS */
|
||||
|
||||
/* BRDCFG4[4:7]] select EC1 and EC2 as a pair */
|
||||
#define BRDCFG4_EMISEL_MASK 0xE0
|
||||
#define BRDCFG4_EMISEL_SHIFT 5
|
||||
|
||||
/* CLK */
|
||||
#define QIXIS_CLK_66 0x0
|
||||
#define QIXIS_CLK_100 0x1
|
||||
#define QIXIS_CLK_125 0x2
|
||||
#define QIXIS_CLK_133 0x3
|
||||
|
||||
#define QIXIS_SRDS1CLK_122 0x5a
|
||||
#define QIXIS_SRDS1CLK_125 0x5e
|
||||
|
||||
/* SGMII */
|
||||
#define PHY_BASE_ADDR 0x18
|
||||
#define PORT_NUM 0x04
|
||||
#define REGNUM 0x00
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
#PBI commands
|
||||
#Initialize CPC1
|
||||
09010000 00200400
|
||||
09138000 00000000
|
||||
091380c0 00000100
|
||||
#Configure CPC1 as 512KB SRAM
|
||||
09010100 00000000
|
||||
09010104 fff80009
|
||||
09010f00 08000000
|
||||
09010000 80000000
|
||||
#Configure LAW for CPC1
|
||||
09000d00 00000000
|
||||
09000d04 fff80000
|
||||
09000d08 81000012
|
||||
#Configure alternate space
|
||||
09000010 00000000
|
||||
09000014 ff000000
|
||||
09000018 81000000
|
||||
#Configure SPI controller
|
||||
09110000 80000403
|
||||
09110020 2d170008
|
||||
09110024 00100008
|
||||
09110028 00100008
|
||||
0911002c 00100008
|
||||
#slowing down the MDC clock to make it <= 2.5 MHZ
|
||||
094fc030 00008148
|
||||
094fd030 00008148
|
||||
#Flush PBL data
|
||||
09138000 00000000
|
||||
091380c0 00000000
|
||||
@@ -0,0 +1,7 @@
|
||||
#PBL preamble and RCW header
|
||||
aa55aa55 010e0100
|
||||
# serdes protocol 0x2A_0x98
|
||||
140e0018 0f001218 00000000 00000000
|
||||
54980000 9000a000 e8104000 a9000000
|
||||
01000000 00000000 00000000 0001b1f8
|
||||
00000000 14000020 00000000 00000011
|
||||
@@ -0,0 +1,265 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2011-2012 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <i2c.h>
|
||||
#include <hwconfig.h>
|
||||
#include <fsl_ddr.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <fsl_ddr_sdram.h>
|
||||
#include <fsl_ddr_dimm_params.h>
|
||||
#include <asm/fsl_law.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
dimm_params_t ddr_raw_timing = {
|
||||
.n_ranks = 2,
|
||||
.rank_density = 2147483648u,
|
||||
.capacity = 4294967296u,
|
||||
.primary_sdram_width = 64,
|
||||
.ec_sdram_width = 8,
|
||||
.registered_dimm = 0,
|
||||
.mirrored_dimm = 1,
|
||||
.n_row_addr = 15,
|
||||
.n_col_addr = 10,
|
||||
.n_banks_per_sdram_device = 8,
|
||||
.edc_config = 2, /* ECC */
|
||||
.burst_lengths_bitmask = 0x0c,
|
||||
|
||||
.tckmin_x_ps = 1071,
|
||||
.caslat_x = 0x2fe << 4, /* 5,6,7,8,9,10,11,13 */
|
||||
.taa_ps = 13910,
|
||||
.twr_ps = 15000,
|
||||
.trcd_ps = 13910,
|
||||
.trrd_ps = 6000,
|
||||
.trp_ps = 13910,
|
||||
.tras_ps = 34000,
|
||||
.trc_ps = 48910,
|
||||
.trfc_ps = 260000,
|
||||
.twtr_ps = 7500,
|
||||
.trtp_ps = 7500,
|
||||
.refresh_rate_ps = 7800000,
|
||||
.tfaw_ps = 35000,
|
||||
};
|
||||
|
||||
int fsl_ddr_get_dimm_params(dimm_params_t *pdimm,
|
||||
unsigned int controller_number,
|
||||
unsigned int dimm_number)
|
||||
{
|
||||
const char dimm_model[] = "RAW timing DDR";
|
||||
|
||||
if ((controller_number == 0) && (dimm_number == 0)) {
|
||||
memcpy(pdimm, &ddr_raw_timing, sizeof(dimm_params_t));
|
||||
memset(pdimm->mpart, 0, sizeof(pdimm->mpart));
|
||||
memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct board_specific_parameters {
|
||||
u32 n_ranks;
|
||||
u32 datarate_mhz_high;
|
||||
u32 clk_adjust;
|
||||
u32 wrlvl_start;
|
||||
u32 wrlvl_ctl_2;
|
||||
u32 wrlvl_ctl_3;
|
||||
u32 cpo;
|
||||
u32 write_data_delay;
|
||||
u32 force_2t;
|
||||
};
|
||||
|
||||
/*
|
||||
* This table contains all valid speeds we want to override with board
|
||||
* specific parameters. datarate_mhz_high values need to be in ascending order
|
||||
* for each n_ranks group.
|
||||
*/
|
||||
static const struct board_specific_parameters udimm0[] = {
|
||||
/*
|
||||
* memory controller 0
|
||||
* num| hi| clk| wrlvl | wrlvl | wrlvl | cpo |wrdata|2T
|
||||
* ranks| mhz|adjst| start | ctl2 | ctl3 | |delay |
|
||||
*/
|
||||
{2, 1350, 4, 7, 0x09080807, 0x07060607, 0xff, 2, 0},
|
||||
{2, 1666, 4, 7, 0x09080806, 0x06050607, 0xff, 2, 0},
|
||||
{2, 1900, 3, 7, 0x08070706, 0x06040507, 0xff, 2, 0},
|
||||
{1, 1350, 4, 7, 0x09080807, 0x07060607, 0xff, 2, 0},
|
||||
{1, 1700, 4, 7, 0x09080806, 0x06050607, 0xff, 2, 0},
|
||||
{1, 1900, 3, 7, 0x08070706, 0x06040507, 0xff, 2, 0},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct board_specific_parameters *udimms[] = {
|
||||
udimm0,
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
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) {
|
||||
if (ddr_freq <= pbsp->datarate_mhz_high) {
|
||||
popts->cpo_override = pbsp->cpo;
|
||||
popts->write_data_delay =
|
||||
pbsp->write_data_delay;
|
||||
popts->clk_adjust = pbsp->clk_adjust;
|
||||
popts->wrlvl_start = pbsp->wrlvl_start;
|
||||
popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
|
||||
popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
|
||||
popts->twot_en = pbsp->force_2t;
|
||||
goto found;
|
||||
}
|
||||
pbsp_highest = pbsp;
|
||||
}
|
||||
pbsp++;
|
||||
}
|
||||
|
||||
if (pbsp_highest) {
|
||||
printf("Error: board specific timing not found "
|
||||
"for data rate %lu MT/s\n"
|
||||
"Trying to use the highest speed (%u) parameters\n",
|
||||
ddr_freq, pbsp_highest->datarate_mhz_high);
|
||||
popts->cpo_override = pbsp_highest->cpo;
|
||||
popts->write_data_delay = pbsp_highest->write_data_delay;
|
||||
popts->clk_adjust = pbsp_highest->clk_adjust;
|
||||
popts->wrlvl_start = pbsp_highest->wrlvl_start;
|
||||
popts->twot_en = pbsp_highest->force_2t;
|
||||
} else {
|
||||
panic("DIMM is not supported by this board");
|
||||
}
|
||||
found:
|
||||
/*
|
||||
* Factors to consider for half-strength driver enable:
|
||||
* - number of DIMMs installed
|
||||
*/
|
||||
popts->half_strength_driver_enable = 0;
|
||||
/*
|
||||
* Write leveling override
|
||||
*/
|
||||
popts->wrlvl_override = 1;
|
||||
popts->wrlvl_sample = 0xf;
|
||||
|
||||
/*
|
||||
* Rtt and Rtt_WR override
|
||||
*/
|
||||
popts->rtt_override = 0;
|
||||
|
||||
/* Enable ZQ calibration */
|
||||
popts->zq_en = 1;
|
||||
|
||||
/* DHC_EN =1, ODT = 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);
|
||||
|
||||
/* optimize cpo for erratum A-009942 */
|
||||
popts->cpo_sample = 0x3e;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
phys_size_t dram_size;
|
||||
|
||||
#if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL)
|
||||
puts("Initializing....using SPD\n");
|
||||
dram_size = fsl_ddr_sdram();
|
||||
#else
|
||||
dram_size = fsl_ddr_sdram_size();
|
||||
#endif
|
||||
dram_size = setup_ddr_tlbs(dram_size / 0x100000);
|
||||
dram_size *= 0x100000;
|
||||
|
||||
gd->ram_size = dram_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long step_assign_addresses(fsl_ddr_info_t *pinfo,
|
||||
unsigned int dbw_cap_adj[])
|
||||
{
|
||||
int i, j;
|
||||
unsigned long long total_mem, current_mem_base, total_ctlr_mem;
|
||||
unsigned long long rank_density, ctlr_density = 0;
|
||||
|
||||
current_mem_base = 0ull;
|
||||
total_mem = 0;
|
||||
/*
|
||||
* This board has soldered DDR chips. DDRC1 has two rank.
|
||||
* DDRC2 has only one rank.
|
||||
* Assigning DDRC2 to lower address and DDRC1 to higher address.
|
||||
*/
|
||||
if (pinfo->memctl_opts[0].memctl_interleaving) {
|
||||
rank_density = pinfo->dimm_params[0][0].rank_density >>
|
||||
dbw_cap_adj[0];
|
||||
ctlr_density = rank_density;
|
||||
|
||||
debug("rank density is 0x%llx, ctlr density is 0x%llx\n",
|
||||
rank_density, ctlr_density);
|
||||
for (i = CONFIG_SYS_NUM_DDR_CTLRS - 1; i >= 0; i--) {
|
||||
switch (pinfo->memctl_opts[i].memctl_interleaving_mode) {
|
||||
case FSL_DDR_CACHE_LINE_INTERLEAVING:
|
||||
case FSL_DDR_PAGE_INTERLEAVING:
|
||||
case FSL_DDR_BANK_INTERLEAVING:
|
||||
case FSL_DDR_SUPERBANK_INTERLEAVING:
|
||||
total_ctlr_mem = 2 * ctlr_density;
|
||||
break;
|
||||
default:
|
||||
panic("Unknown interleaving mode");
|
||||
}
|
||||
pinfo->common_timing_params[i].base_address =
|
||||
current_mem_base;
|
||||
pinfo->common_timing_params[i].total_mem =
|
||||
total_ctlr_mem;
|
||||
total_mem = current_mem_base + total_ctlr_mem;
|
||||
debug("ctrl %d base 0x%llx\n", i, current_mem_base);
|
||||
debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Simple linear assignment if memory
|
||||
* controllers are not interleaved.
|
||||
*/
|
||||
for (i = CONFIG_SYS_NUM_DDR_CTLRS - 1; i >= 0; i--) {
|
||||
total_ctlr_mem = 0;
|
||||
pinfo->common_timing_params[i].base_address =
|
||||
current_mem_base;
|
||||
for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
|
||||
/* Compute DIMM base addresses. */
|
||||
unsigned long long cap =
|
||||
pinfo->dimm_params[i][j].capacity;
|
||||
pinfo->dimm_params[i][j].base_address =
|
||||
current_mem_base;
|
||||
debug("ctrl %d dimm %d base 0x%llx\n",
|
||||
i, j, current_mem_base);
|
||||
current_mem_base += cap;
|
||||
total_ctlr_mem += cap;
|
||||
}
|
||||
debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem);
|
||||
pinfo->common_timing_params[i].total_mem =
|
||||
total_ctlr_mem;
|
||||
total_mem += total_ctlr_mem;
|
||||
}
|
||||
}
|
||||
debug("Total mem by %s is 0x%llx\n", __func__, total_mem);
|
||||
|
||||
return total_mem;
|
||||
}
|
||||
@@ -0,0 +1,452 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
* Author: Sandeep Kumar Singh <sandeep@freescale.com>
|
||||
*/
|
||||
|
||||
/* This file is based on board/freescale/corenet_ds/eth_superhydra.c */
|
||||
|
||||
/*
|
||||
* This file handles the board muxing between the Fman Ethernet MACs and
|
||||
* the RGMII/SGMII/XGMII PHYs on a Freescale B4860 "Centaur". The SGMII
|
||||
* PHYs are the two on-board 1Gb ports. There are no RGMII PHY on board.
|
||||
* The 10Gb XGMII PHY is provided via the XAUI riser card. There is only
|
||||
* one Fman device on B4860. The SERDES configuration is used to determine
|
||||
* where the SGMII and XAUI cards exist, and also which Fman MACs are routed
|
||||
* to which PHYs. So for a given Fman MAC, there is one and only PHY it
|
||||
* connects to. MACs cannot be routed to PHYs dynamically. This configuration
|
||||
* is done at boot time by reading SERDES protocol from RCW.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <netdev.h>
|
||||
#include <asm/fsl_serdes.h>
|
||||
#include <fm_eth.h>
|
||||
#include <fsl_mdio.h>
|
||||
#include <malloc.h>
|
||||
#include <fdt_support.h>
|
||||
#include <fsl_dtsec.h>
|
||||
|
||||
#include "../common/ngpixis.h"
|
||||
#include "../common/fman.h"
|
||||
#include "../common/qixis.h"
|
||||
#include "b4860qds_qixis.h"
|
||||
|
||||
#define EMI_NONE 0xFFFFFFFF
|
||||
|
||||
#ifdef CONFIG_FMAN_ENET
|
||||
|
||||
/*
|
||||
* Mapping of all 16 SERDES lanes to board slots. A value n(>0) will mean that
|
||||
* lane at index is mapped to slot number n. A value of '0' will mean
|
||||
* that the mapping must be determined dynamically, or that the lane maps to
|
||||
* something other than a board slot
|
||||
*/
|
||||
static u8 lane_to_slot[] = {
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
1, 1, 1, 1,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* This function initializes the lane_to_slot[] array. It reads RCW to check
|
||||
* if Serdes2{E,F,G,H} is configured as slot 2 or as SFP and initializes
|
||||
* lane_to_slot[] accordingly
|
||||
*/
|
||||
static void initialize_lane_to_slot(void)
|
||||
{
|
||||
unsigned int serdes2_prtcl;
|
||||
ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
||||
serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
|
||||
FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
|
||||
serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
|
||||
debug("Initializing lane to slot: Serdes2 protocol: %x\n",
|
||||
serdes2_prtcl);
|
||||
|
||||
switch (serdes2_prtcl) {
|
||||
case 0x17:
|
||||
case 0x18:
|
||||
/*
|
||||
* Configuration:
|
||||
* SERDES: 2
|
||||
* Lanes: A,B,C,D: SGMII
|
||||
* Lanes: E,F: Aur
|
||||
* Lanes: G,H: SRIO
|
||||
*/
|
||||
case 0x91:
|
||||
/*
|
||||
* Configuration:
|
||||
* SERDES: 2
|
||||
* Lanes: A,B: SGMII
|
||||
* Lanes: C,D: SRIO2
|
||||
* Lanes: E,F,G,H: XAUI2
|
||||
*/
|
||||
case 0x93:
|
||||
/*
|
||||
* Configuration:
|
||||
* SERDES: 2
|
||||
* Lanes: A,B,C,D: SGMII
|
||||
* Lanes: E,F,G,H: XAUI2
|
||||
*/
|
||||
case 0x98:
|
||||
/*
|
||||
* Configuration:
|
||||
* SERDES: 2
|
||||
* Lanes: A,B,C,D: XAUI2
|
||||
* Lanes: E,F,G,H: XAUI2
|
||||
*/
|
||||
case 0x9a:
|
||||
/*
|
||||
* Configuration:
|
||||
* SERDES: 2
|
||||
* Lanes: A,B: PCI
|
||||
* Lanes: C,D: SGMII
|
||||
* Lanes: E,F,G,H: XAUI2
|
||||
*/
|
||||
case 0x9e:
|
||||
/*
|
||||
* Configuration:
|
||||
* SERDES: 2
|
||||
* Lanes: A,B,C,D: PCI
|
||||
* Lanes: E,F,G,H: XAUI2
|
||||
*/
|
||||
case 0xb1:
|
||||
case 0xb2:
|
||||
case 0x8c:
|
||||
case 0x8d:
|
||||
/*
|
||||
* Configuration:
|
||||
* SERDES: 2
|
||||
* Lanes: A,B,C,D: PCI
|
||||
* Lanes: E,F: SGMII 3&4
|
||||
* Lanes: G,H: XFI
|
||||
*/
|
||||
case 0xc2:
|
||||
/*
|
||||
* Configuration:
|
||||
* SERDES: 2
|
||||
* Lanes: A,B: SGMII
|
||||
* Lanes: C,D: SRIO2
|
||||
* Lanes: E,F,G,H: XAUI2
|
||||
*/
|
||||
lane_to_slot[12] = 2;
|
||||
lane_to_slot[13] = lane_to_slot[12];
|
||||
lane_to_slot[14] = lane_to_slot[12];
|
||||
lane_to_slot[15] = lane_to_slot[12];
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Fman: Unsupported SerDes2 Protocol 0x%02x\n",
|
||||
serdes2_prtcl);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* #ifdef CONFIG_FMAN_ENET */
|
||||
|
||||
int board_eth_init(bd_t *bis)
|
||||
{
|
||||
#ifdef CONFIG_FMAN_ENET
|
||||
struct memac_mdio_info memac_mdio_info;
|
||||
struct memac_mdio_info tg_memac_mdio_info;
|
||||
unsigned int i;
|
||||
unsigned int serdes1_prtcl, serdes2_prtcl;
|
||||
int qsgmii;
|
||||
struct mii_dev *bus;
|
||||
ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
||||
serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
|
||||
FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
|
||||
if (!serdes1_prtcl) {
|
||||
printf("SERDES1 is not enabled\n");
|
||||
return 0;
|
||||
}
|
||||
serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
|
||||
debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
|
||||
|
||||
serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
|
||||
FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
|
||||
if (!serdes2_prtcl) {
|
||||
printf("SERDES2 is not enabled\n");
|
||||
return 0;
|
||||
}
|
||||
serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
|
||||
debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
|
||||
|
||||
printf("Initializing Fman\n");
|
||||
|
||||
initialize_lane_to_slot();
|
||||
|
||||
memac_mdio_info.regs =
|
||||
(struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR;
|
||||
memac_mdio_info.name = DEFAULT_FM_MDIO_NAME;
|
||||
|
||||
/* Register the real 1G MDIO bus */
|
||||
fm_memac_mdio_init(bis, &memac_mdio_info);
|
||||
|
||||
tg_memac_mdio_info.regs =
|
||||
(struct memac_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR;
|
||||
tg_memac_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;
|
||||
|
||||
/* Register the real 10G MDIO bus */
|
||||
fm_memac_mdio_init(bis, &tg_memac_mdio_info);
|
||||
|
||||
/*
|
||||
* Program the two on board DTSEC PHY addresses assuming that they are
|
||||
* all SGMII. RGMII is not supported on this board. Setting SGMII 5 and
|
||||
* 6 to on board SGMII phys
|
||||
*/
|
||||
fm_info_set_phy_address(FM1_DTSEC5, CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR);
|
||||
fm_info_set_phy_address(FM1_DTSEC6, CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR);
|
||||
|
||||
switch (serdes1_prtcl) {
|
||||
case 0x29:
|
||||
case 0x2a:
|
||||
/* Serdes 1: A-B SGMII, Configuring DTSEC 5 and 6 */
|
||||
debug("Set phy addresses for FM1_DTSEC5:%x, FM1_DTSEC6:%x\n",
|
||||
CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR,
|
||||
CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR);
|
||||
fm_info_set_phy_address(FM1_DTSEC5,
|
||||
CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR);
|
||||
fm_info_set_phy_address(FM1_DTSEC6,
|
||||
CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR);
|
||||
break;
|
||||
#ifdef CONFIG_ARCH_B4420
|
||||
case 0x17:
|
||||
case 0x18:
|
||||
/* Serdes 1: A-D SGMII, Configuring on board dual SGMII Phy */
|
||||
debug("Set phy addresses for FM1_DTSEC3:%x, FM1_DTSEC4:%x\n",
|
||||
CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR,
|
||||
CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR);
|
||||
/* Fixing Serdes clock by programming FPGA register */
|
||||
QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
|
||||
fm_info_set_phy_address(FM1_DTSEC3,
|
||||
CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR);
|
||||
fm_info_set_phy_address(FM1_DTSEC4,
|
||||
CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("Fman: Unsupported SerDes1 Protocol 0x%02x\n",
|
||||
serdes1_prtcl);
|
||||
break;
|
||||
}
|
||||
switch (serdes2_prtcl) {
|
||||
case 0x17:
|
||||
case 0x18:
|
||||
debug("Set phy address on SGMII Riser for FM1_DTSEC1:%x\n",
|
||||
CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
|
||||
fm_info_set_phy_address(FM1_DTSEC1,
|
||||
CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
|
||||
fm_info_set_phy_address(FM1_DTSEC2,
|
||||
CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR);
|
||||
fm_info_set_phy_address(FM1_DTSEC3,
|
||||
CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR);
|
||||
fm_info_set_phy_address(FM1_DTSEC4,
|
||||
CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR);
|
||||
break;
|
||||
case 0x48:
|
||||
case 0x49:
|
||||
debug("Set phy address on SGMII Riser for FM1_DTSEC1:%x\n",
|
||||
CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
|
||||
fm_info_set_phy_address(FM1_DTSEC1,
|
||||
CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
|
||||
fm_info_set_phy_address(FM1_DTSEC2,
|
||||
CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR);
|
||||
fm_info_set_phy_address(FM1_DTSEC3,
|
||||
CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR);
|
||||
break;
|
||||
case 0xb1:
|
||||
case 0xb2:
|
||||
case 0x8c:
|
||||
case 0x8d:
|
||||
debug("Set phy addresses on SGMII Riser for FM1_DTSEC1:%x\n",
|
||||
CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
|
||||
fm_info_set_phy_address(FM1_DTSEC3,
|
||||
CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
|
||||
fm_info_set_phy_address(FM1_DTSEC4,
|
||||
CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR);
|
||||
/*
|
||||
* XFI does not need a PHY to work, but to make U-Boot
|
||||
* happy, assign a fake PHY address for a XFI port.
|
||||
*/
|
||||
fm_info_set_phy_address(FM1_10GEC1, 0);
|
||||
fm_info_set_phy_address(FM1_10GEC2, 1);
|
||||
break;
|
||||
case 0x98:
|
||||
/* XAUI in Slot1 and Slot2 */
|
||||
debug("Set phy address of AMC2PEX-2S for FM1_10GEC1:%x\n",
|
||||
CONFIG_SYS_FM1_10GEC1_PHY_ADDR);
|
||||
fm_info_set_phy_address(FM1_10GEC1,
|
||||
CONFIG_SYS_FM1_10GEC1_PHY_ADDR);
|
||||
debug("Set phy address of AMC2PEX-2S for FM1_10GEC2:%x\n",
|
||||
CONFIG_SYS_FM1_10GEC2_PHY_ADDR);
|
||||
fm_info_set_phy_address(FM1_10GEC2,
|
||||
CONFIG_SYS_FM1_10GEC2_PHY_ADDR);
|
||||
break;
|
||||
case 0x9E:
|
||||
/* XAUI in Slot2 */
|
||||
debug("Sett phy address of AMC2PEX-2S for FM1_10GEC2:%x\n",
|
||||
CONFIG_SYS_FM1_10GEC2_PHY_ADDR);
|
||||
fm_info_set_phy_address(FM1_10GEC2,
|
||||
CONFIG_SYS_FM1_10GEC2_PHY_ADDR);
|
||||
break;
|
||||
default:
|
||||
printf("Fman: Unsupported SerDes2 Protocol 0x%02x\n",
|
||||
serdes2_prtcl);
|
||||
break;
|
||||
}
|
||||
|
||||
/*set PHY address for QSGMII Riser Card on slot2*/
|
||||
bus = miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME);
|
||||
qsgmii = is_qsgmii_riser_card(bus, PHY_BASE_ADDR, PORT_NUM, REGNUM);
|
||||
|
||||
if (qsgmii) {
|
||||
switch (serdes2_prtcl) {
|
||||
case 0xb2:
|
||||
case 0x8d:
|
||||
fm_info_set_phy_address(FM1_DTSEC3, PHY_BASE_ADDR);
|
||||
fm_info_set_phy_address(FM1_DTSEC4, PHY_BASE_ADDR + 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
|
||||
int idx = i - FM1_DTSEC1;
|
||||
|
||||
switch (fm_info_get_enet_if(i)) {
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
fm_info_set_mdio(i,
|
||||
miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME));
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_NONE:
|
||||
fm_info_set_phy_address(i, 0);
|
||||
break;
|
||||
default:
|
||||
printf("Fman1: DTSEC%u set to unknown interface %i\n",
|
||||
idx + 1, fm_info_get_enet_if(i));
|
||||
fm_info_set_phy_address(i, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) {
|
||||
int idx = i - FM1_10GEC1;
|
||||
|
||||
switch (fm_info_get_enet_if(i)) {
|
||||
case PHY_INTERFACE_MODE_XGMII:
|
||||
fm_info_set_mdio(i,
|
||||
miiphy_get_dev_by_name
|
||||
(DEFAULT_FM_TGEC_MDIO_NAME));
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_NONE:
|
||||
fm_info_set_phy_address(i, 0);
|
||||
break;
|
||||
default:
|
||||
printf("Fman1: TGEC%u set to unknown interface %i\n",
|
||||
idx + 1, fm_info_get_enet_if(i));
|
||||
fm_info_set_phy_address(i, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cpu_eth_init(bis);
|
||||
#endif
|
||||
|
||||
return pci_eth_init(bis);
|
||||
}
|
||||
|
||||
void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
|
||||
enum fm_port port, int offset)
|
||||
{
|
||||
int phy;
|
||||
char alias[32];
|
||||
struct fixed_link f_link;
|
||||
ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
||||
u32 prtcl2 = in_be32(&gur->rcwsr[4]) & FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
|
||||
|
||||
prtcl2 >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
|
||||
|
||||
if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) {
|
||||
phy = fm_info_get_phy_address(port);
|
||||
|
||||
sprintf(alias, "phy_sgmii_%x", phy);
|
||||
fdt_set_phy_handle(fdt, compat, addr, alias);
|
||||
fdt_status_okay_by_alias(fdt, alias);
|
||||
} else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_XGMII) {
|
||||
/* check if it's XFI interface for 10g */
|
||||
switch (prtcl2) {
|
||||
case 0x80:
|
||||
case 0x81:
|
||||
case 0x82:
|
||||
case 0x83:
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
case 0x86:
|
||||
case 0x87:
|
||||
case 0x88:
|
||||
case 0x89:
|
||||
case 0x8a:
|
||||
case 0x8b:
|
||||
case 0x8c:
|
||||
case 0x8d:
|
||||
case 0x8e:
|
||||
case 0xb1:
|
||||
case 0xb2:
|
||||
f_link.phy_id = port;
|
||||
f_link.duplex = 1;
|
||||
f_link.link_speed = 10000;
|
||||
f_link.pause = 0;
|
||||
f_link.asym_pause = 0;
|
||||
|
||||
fdt_delprop(fdt, offset, "phy-handle");
|
||||
fdt_setprop(fdt, offset, "fixed-link", &f_link,
|
||||
sizeof(f_link));
|
||||
break;
|
||||
case 0x98: /* XAUI interface */
|
||||
strcpy(alias, "phy_xaui_slot1");
|
||||
fdt_status_okay_by_alias(fdt, alias);
|
||||
|
||||
strcpy(alias, "phy_xaui_slot2");
|
||||
fdt_status_okay_by_alias(fdt, alias);
|
||||
break;
|
||||
case 0x9e: /* XAUI interface */
|
||||
case 0x9a:
|
||||
case 0x93:
|
||||
case 0x91:
|
||||
strcpy(alias, "phy_xaui_slot1");
|
||||
fdt_status_okay_by_alias(fdt, alias);
|
||||
break;
|
||||
case 0x97: /* XAUI interface */
|
||||
case 0xc3:
|
||||
strcpy(alias, "phy_xaui_slot2");
|
||||
fdt_status_okay_by_alias(fdt, alias);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set status to disabled for unused ethernet node
|
||||
*/
|
||||
void fdt_fixup_board_enet(void *fdt)
|
||||
{
|
||||
int i;
|
||||
char alias[32];
|
||||
|
||||
for (i = FM1_DTSEC1; i <= FM1_10GEC2; i++) {
|
||||
switch (fm_info_get_enet_if(i)) {
|
||||
case PHY_INTERFACE_MODE_NONE:
|
||||
sprintf(alias, "ethernet%u", i);
|
||||
fdt_status_disabled_by_alias(fdt, alias);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2011-2012 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#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
|
||||
SET_LAW(QIXIS_BASE_PHYS, LAW_SIZE_4K, LAW_TRGT_IF_IFC),
|
||||
#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);
|
||||
@@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2011-2012 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <init.h>
|
||||
#include <pci.h>
|
||||
#include <asm/fsl_pci.h>
|
||||
#include <linux/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;
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <console.h>
|
||||
#include <env.h>
|
||||
#include <env_internal.h>
|
||||
#include <asm/spl.h>
|
||||
#include <malloc.h>
|
||||
#include <ns16550.h>
|
||||
#include <nand.h>
|
||||
#include <i2c.h>
|
||||
#include "../common/qixis.h"
|
||||
#include "b4860qds_qixis.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
phys_size_t get_effective_memsize(void)
|
||||
{
|
||||
return CONFIG_SYS_L3_SIZE;
|
||||
}
|
||||
|
||||
unsigned long get_board_sys_clk(void)
|
||||
{
|
||||
u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
|
||||
|
||||
switch ((sysclk_conf & 0x0C) >> 2) {
|
||||
case QIXIS_CLK_100:
|
||||
return 100000000;
|
||||
case QIXIS_CLK_125:
|
||||
return 125000000;
|
||||
case QIXIS_CLK_133:
|
||||
return 133333333;
|
||||
}
|
||||
return 66666666;
|
||||
}
|
||||
|
||||
unsigned long get_board_ddr_clk(void)
|
||||
{
|
||||
u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
|
||||
|
||||
switch (ddrclk_conf & 0x03) {
|
||||
case QIXIS_CLK_100:
|
||||
return 100000000;
|
||||
case QIXIS_CLK_125:
|
||||
return 125000000;
|
||||
case QIXIS_CLK_133:
|
||||
return 133333333;
|
||||
}
|
||||
return 66666666;
|
||||
}
|
||||
|
||||
void board_init_f(ulong bootflag)
|
||||
{
|
||||
u32 plat_ratio, sys_clk, uart_clk;
|
||||
ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
|
||||
|
||||
/* Memcpy existing GD at CONFIG_SPL_GD_ADDR */
|
||||
memcpy((void *)CONFIG_SPL_GD_ADDR, (void *)gd, sizeof(gd_t));
|
||||
|
||||
/* Update GD pointer */
|
||||
gd = (gd_t *)(CONFIG_SPL_GD_ADDR);
|
||||
|
||||
/* compiler optimization barrier needed for GCC >= 3.4 */
|
||||
__asm__ __volatile__("" : : : "memory");
|
||||
|
||||
console_init_f();
|
||||
|
||||
/* initialize selected port with appropriate baud rate */
|
||||
sys_clk = get_board_sys_clk();
|
||||
plat_ratio = (in_be32(&gur->rcwsr[0]) >> 25) & 0x1f;
|
||||
uart_clk = sys_clk * plat_ratio / 2;
|
||||
|
||||
NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1,
|
||||
uart_clk / 16 / CONFIG_BAUDRATE);
|
||||
|
||||
relocate_code(CONFIG_SPL_RELOC_STACK, (gd_t *)CONFIG_SPL_GD_ADDR, 0x0);
|
||||
}
|
||||
|
||||
void board_init_r(gd_t *gd, ulong dest_addr)
|
||||
{
|
||||
bd_t *bd;
|
||||
|
||||
bd = (bd_t *)(gd + sizeof(gd_t));
|
||||
memset(bd, 0, sizeof(bd_t));
|
||||
gd->bd = bd;
|
||||
bd->bi_memstart = CONFIG_SYS_INIT_L3_ADDR;
|
||||
bd->bi_memsize = CONFIG_SYS_L3_SIZE;
|
||||
|
||||
arch_cpu_init();
|
||||
get_clocks();
|
||||
mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR,
|
||||
CONFIG_SPL_RELOC_MALLOC_SIZE);
|
||||
gd->flags |= GD_FLG_FULL_MALLOC_INIT;
|
||||
|
||||
#ifndef CONFIG_SPL_NAND_BOOT
|
||||
env_init();
|
||||
env_relocate();
|
||||
#else
|
||||
/* relocate environment function pointers etc. */
|
||||
nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,
|
||||
(uchar *)SPL_ENV_ADDR);
|
||||
gd->env_addr = (ulong)(SPL_ENV_ADDR);
|
||||
gd->env_valid = ENV_VALID;
|
||||
#endif
|
||||
|
||||
i2c_init_all();
|
||||
|
||||
puts("\n\n");
|
||||
|
||||
dram_init();
|
||||
|
||||
#ifdef CONFIG_SPL_NAND_BOOT
|
||||
nand_boot();
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2011-2012 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#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 1M SRAM, the address of the
|
||||
* SRAM is at 0xfff00000, it covered the 0xfffff000.
|
||||
*/
|
||||
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_1M, 1),
|
||||
#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE)
|
||||
/*
|
||||
* SRIO_PCIE_BOOT-SLAVE. When slave boot, the address of the
|
||||
* space is at 0xfff00000, it covered the 0xfffff000.
|
||||
*/
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR,
|
||||
CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_W|MAS2_G,
|
||||
0, 0, BOOKE_PAGESZ_1M, 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),
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
/* *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_256M, 1),
|
||||
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT + 0x10000000,
|
||||
CONFIG_SYS_PCIE1_MEM_PHYS + 0x10000000,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 4, 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, 5, BOOKE_PAGESZ_64K, 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, 6, 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, 7, 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, 8, 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, 9, BOOKE_PAGESZ_16M, 1),
|
||||
#endif
|
||||
#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, 10, BOOKE_PAGESZ_32M, 1),
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_NAND_BASE
|
||||
/*
|
||||
* *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,
|
||||
0, 11, BOOKE_PAGESZ_64K, 1),
|
||||
#endif
|
||||
SET_TLB_ENTRY(1, QIXIS_BASE, QIXIS_BASE_PHYS,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 12, BOOKE_PAGESZ_4K, 1),
|
||||
|
||||
/*
|
||||
* *I*G - SRIO
|
||||
* entry 14 and 15 has been used hard coded, they will be disabled
|
||||
* in cpu_init_f, so we use entry 16 for SRIO2.
|
||||
*/
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
#ifdef CONFIG_SYS_SRIO1_MEM_PHYS
|
||||
/* *I*G* - SRIO1 */
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_SRIO1_MEM_VIRT, CONFIG_SYS_SRIO1_MEM_PHYS,
|
||||
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 13, BOOKE_PAGESZ_256M, 1),
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_SRIO2_MEM_PHYS
|
||||
/* *I*G* - SRIO2 */
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_SRIO2_MEM_VIRT, CONFIG_SYS_SRIO2_MEM_PHYS,
|
||||
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 16, BOOKE_PAGESZ_256M, 1),
|
||||
#endif
|
||||
#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE
|
||||
/*
|
||||
* SRIO_PCIE_BOOT-SLAVE. 1M space from 0xffe00000 for
|
||||
* fetching ucode and ENV from master
|
||||
*/
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR,
|
||||
CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_G,
|
||||
0, 17, BOOKE_PAGESZ_1M, 1),
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_RAMBOOT_PBL) && !defined(CONFIG_SPL_BUILD)
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE, CONFIG_SYS_DDR_SDRAM_BASE,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_M,
|
||||
0, 17, BOOKE_PAGESZ_2G, 1)
|
||||
#endif
|
||||
};
|
||||
|
||||
int num_tlb_entries = ARRAY_SIZE(tlb_table);
|
||||
@@ -0,0 +1,12 @@
|
||||
if TARGET_BSC9131RDB
|
||||
|
||||
config SYS_BOARD
|
||||
default "bsc9131rdb"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "freescale"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "BSC9131RDB"
|
||||
|
||||
endif
|
||||
@@ -0,0 +1,9 @@
|
||||
BSC9131RDB BOARD
|
||||
M: Poonam Aggrwal <poonam.aggrwal@nxp.com>
|
||||
S: Maintained
|
||||
F: board/freescale/bsc9131rdb/
|
||||
F: include/configs/BSC9131RDB.h
|
||||
F: configs/BSC9131RDB_NAND_defconfig
|
||||
F: configs/BSC9131RDB_NAND_SYSCLK100_defconfig
|
||||
F: configs/BSC9131RDB_SPIFLASH_defconfig
|
||||
F: configs/BSC9131RDB_SPIFLASH_SYSCLK100_defconfig
|
||||
@@ -0,0 +1,21 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright 2011-2012 Freescale Semiconductor, Inc.
|
||||
|
||||
MINIMAL=
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
ifdef CONFIG_SPL_INIT_MINIMAL
|
||||
MINIMAL=y
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MINIMAL
|
||||
obj-y += spl_minimal.o
|
||||
else
|
||||
obj-y += bsc9131rdb.o
|
||||
obj-y += ddr.o
|
||||
endif
|
||||
|
||||
obj-y += law.o
|
||||
obj-y += tlb.o
|
||||
@@ -0,0 +1,151 @@
|
||||
Overview
|
||||
--------
|
||||
- BSC9131 is integrated device that targets Femto base station market.
|
||||
It combines Power Architecture e500v2 and DSP StarCore SC3850 core
|
||||
technologies with MAPLE-B2F baseband acceleration processing elements.
|
||||
- It's MAPLE disabled personality is called 9231.
|
||||
|
||||
The BSC9131 SoC includes the following function and features:
|
||||
. Power Architecture subsystem including a e500 processor with 256-Kbyte shared
|
||||
L2 cache
|
||||
. StarCore SC3850 DSP subsystem with a 512-Kbyte private L2 cache
|
||||
. The Multi Accelerator Platform Engine for Femto BaseStation Baseband
|
||||
Processing (MAPLE-B2F)
|
||||
. A multi-standard baseband algorithm accelerator for Channel Decoding/Encoding,
|
||||
Fourier Transforms, UMTS chip rate processing, LTE UP/DL Channel processing,
|
||||
and CRC algorithms
|
||||
. Consists of accelerators for Convolution, Filtering, Turbo Encoding,
|
||||
Turbo Decoding, Viterbi decoding, Chiprate processing, and Matrix Inversion
|
||||
operations
|
||||
. DDR3/3L memory interface with 32-bit data width without ECC and 16-bit with
|
||||
ECC, up to 400-MHz clock/800 MHz data rate
|
||||
. Dedicated security engine featuring trusted boot
|
||||
. DMA controller
|
||||
. OCNDMA with four bidirectional channels
|
||||
. Interfaces
|
||||
. Two triple-speed Gigabit Ethernet controllers featuring network acceleration
|
||||
including IEEE 1588. v2 hardware support and virtualization (eTSEC)
|
||||
. eTSEC 1 supports RGMII/RMII
|
||||
. eTSEC 2 supports RGMII
|
||||
. High-speed USB 2.0 host and device controller with ULPI interface
|
||||
. Enhanced secure digital (SD/MMC) host controller (eSDHC)
|
||||
. Antenna interface controller (AIC), supporting three industry standard
|
||||
JESD207/three custom ADI RF interfaces (two dual port and one single port)
|
||||
and three MAXIM's MaxPHY serial interfaces
|
||||
. ADI lanes support both full duplex FDD support and half duplex TDD support
|
||||
. Universal Subscriber Identity Module (USIM) interface that facilitates
|
||||
communication to SIM cards or Eurochip pre-paid phone cards
|
||||
. TDM with one TDM port
|
||||
. Two DUART, four eSPI, and two I2C controllers
|
||||
. Integrated Flash memory controller (IFC)
|
||||
. TDM with 256 channels
|
||||
. GPIO
|
||||
. Sixteen 32-bit timers
|
||||
|
||||
The e500 core subsystem within the Power Architecture consists of the following:
|
||||
. 32-Kbyte L1 instruction cache
|
||||
. 32-Kbyte L1 data cache
|
||||
. 256-Kbyte L2 cache/L2 memory/L2 stash
|
||||
. programmable interrupt controller (PIC)
|
||||
. Debug support
|
||||
. Timers
|
||||
|
||||
The SC3850 core subsystem consists of the following:
|
||||
. 32 Kbyte 8-way level 1 instruction cache (L1 ICache)
|
||||
. 32 Kbyte 8-way level 1 data cache (L1 DCache)
|
||||
. 512 Kbyte 8-way level 2 unified instruction/data cache (M2 memory)
|
||||
. Memory management unit (MMU)
|
||||
. Enhanced programmable interrupt controller (EPIC)
|
||||
. Debug and profiling unit (DPU)
|
||||
. Two 32-bit timers
|
||||
|
||||
BSC9131RDB board Overview
|
||||
-------------------------
|
||||
1Gbyte DDR3 (on board DDR)
|
||||
128Mbyte 2K page size NAND Flash
|
||||
256 Kbit M24256 I2C EEPROM
|
||||
128 Mbit SPI Flash memory
|
||||
USB-ULPI
|
||||
eTSEC1: Connected to RGMII PHY
|
||||
eTSEC2: Connected to RGMII PHY
|
||||
DUART interface: supports one UARTs up to 115200 bps for console display
|
||||
USIM connector
|
||||
|
||||
Frequency Combinations Supported
|
||||
--------------------------------
|
||||
Core MHz/CCB MHz/DDR(MT/s)
|
||||
1. 1000/500/800
|
||||
2. 800/400/667
|
||||
|
||||
Boot Methods Supported
|
||||
-----------------------
|
||||
1. NAND Flash
|
||||
2. SPI Flash
|
||||
|
||||
Default Boot Method
|
||||
--------------------
|
||||
NAND boot
|
||||
|
||||
Building U-Boot
|
||||
--------------
|
||||
To build the U-Boot for BSC9131RDB:
|
||||
1. NAND Flash with sysclk 66MHz(J16 on RDB closed, default)
|
||||
make BSC9131RDB_NAND
|
||||
2. NAND Flash with sysclk 100MHz(J16 on RDB open)
|
||||
make BSC9131RDB_NAND_SYSCLK100
|
||||
3. SPI Flash with sysclk 66MHz(J16 on RDB closed, default)
|
||||
make BSC9131RDB_SPIFLASH
|
||||
4. SPI Flash with sysclk 100MHz(J16 on RDB open)
|
||||
make BSC9131RDB_SPIFLASH_SYSCLK100
|
||||
|
||||
Memory map
|
||||
-----------
|
||||
0x0000_0000 0x7FFF_FFFF DDR 1G cacheable
|
||||
0xA0000000 0xBFFFFFFF Shared DSP core L2/M2 space 512M
|
||||
0xC100_0000 0xC13F_FFFF MAPLE-2F 4M
|
||||
0xC1F0_0000 0xC1F3_FFFF PA SRAM Region 0 256K
|
||||
0xC1F8_0000 0xC1F9_FFFF PA SRAM Region 1 128K
|
||||
0xFED0_0000 0xFED0_3FFF SEC Secured RAM 16K
|
||||
0xFEE0_0000 0xFEE0_0FFF DSP Boot ROM 4K
|
||||
0xFF60_0000 0xFF6F_FFFF DSP CCSR 1M
|
||||
0xFF70_0000 0xFF7F_FFFF PA CCSR 1M
|
||||
0xFF80_0000 0xFFFF_FFFF Boot Page & NAND Buffer 8M
|
||||
|
||||
DDR Memory map
|
||||
---------------
|
||||
0x0000_0000 0x36FF_FFFF Memory passed onto Linux
|
||||
0x3700_0000 0x37FF_FFFF PowerPC-DSP shared control area
|
||||
0x3800_0000 0x4FFF_FFFF DSP Private area
|
||||
|
||||
Out of 880M, passed onto Linux, 1hugetlb page of 256M is reserved for
|
||||
data communcation between PowerPC and DSP core.
|
||||
Rest is PowerPC private area.
|
||||
|
||||
Flashing Images
|
||||
---------------
|
||||
To place a new U-Boot image in the NAND flash and then boot
|
||||
with that new image temporarily, use this:
|
||||
tftp 1000000 u-boot-nand.bin
|
||||
nand erase 0 100000
|
||||
nand write 1000000 0 100000
|
||||
reset
|
||||
|
||||
Using the Device Tree Source File
|
||||
---------------------------------
|
||||
To create the DTB (Device Tree Binary) image file,
|
||||
use a command similar to this:
|
||||
|
||||
dtc -b 0 -f -I dts -O dtb bsc9131rdb.dts > bsc9131rdb.dtb
|
||||
|
||||
Likely, that .dts file will come from here;
|
||||
|
||||
linux-2.6/arch/powerpc/boot/dts/bsc9131rdb.dts
|
||||
|
||||
Booting Linux
|
||||
-------------
|
||||
Place a linux uImage in the TFTP disk area.
|
||||
|
||||
tftp 1000000 uImage
|
||||
tftp 2000000 rootfs.ext2.gz.uboot
|
||||
tftp c00000 bsc9131rdb.dtb
|
||||
bootm 1000000 2000000 c00000
|
||||
@@ -0,0 +1,80 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2011-2012 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/immap_85xx.h>
|
||||
#include <asm/io.h>
|
||||
#include <env.h>
|
||||
#include <miiphy.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
#include <fsl_mdio.h>
|
||||
#include <tsec.h>
|
||||
#include <jffs2/load_kernel.h>
|
||||
#include <mtd_node.h>
|
||||
#include <flash.h>
|
||||
#include <netdev.h>
|
||||
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
|
||||
|
||||
clrbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_UART_CTS_B0_GPIO42);
|
||||
setbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_UART_CTS_B0_DSP_TMS);
|
||||
|
||||
clrbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_UART_RTS_B0_GPIO43);
|
||||
setbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_UART_RTS_B0_DSP_TCK |
|
||||
MPC85xx_PMUXCR2_UART_CTS_B1_SIM_PD);
|
||||
setbits_be32(&gur->halt_req_mask, HALTED_TO_HALT_REQ_MASK_0);
|
||||
clrsetbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_IFC_AD_GPIO_MASK |
|
||||
MPC85xx_PMUXCR_IFC_AD17_GPO_MASK,
|
||||
MPC85xx_PMUXCR_IFC_AD_GPIO |
|
||||
MPC85xx_PMUXCR_IFC_AD17_GPO | MPC85xx_PMUXCR_SDHC_USIM);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int checkboard(void)
|
||||
{
|
||||
struct cpu_type *cpu;
|
||||
|
||||
cpu = gd->arch.cpu;
|
||||
printf("Board: %sRDB\n", cpu->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OF_BOARD_SETUP)
|
||||
#ifdef CONFIG_FDT_FIXUP_PARTITIONS
|
||||
static const struct node_info nodes[] = {
|
||||
{ "fsl,ifc-nand", MTD_DEV_TYPE_NAND, },
|
||||
};
|
||||
#endif
|
||||
int ft_board_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
phys_addr_t base;
|
||||
phys_size_t size;
|
||||
|
||||
ft_cpu_setup(blob, bd);
|
||||
|
||||
base = env_get_bootm_low();
|
||||
size = env_get_bootm_size();
|
||||
|
||||
fdt_fixup_memory(blob, (u64)base, (u64)size);
|
||||
#ifdef CONFIG_FDT_FIXUP_PARTITIONS
|
||||
fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
|
||||
#endif
|
||||
|
||||
fsl_fdt_fixup_dr_usb(blob, bd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,169 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2011-2012 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <vsprintf.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/immap_85xx.h>
|
||||
#include <asm/processor.h>
|
||||
#include <fsl_ddr_sdram.h>
|
||||
#include <fsl_ddr_dimm_params.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/fsl_law.h>
|
||||
|
||||
#ifndef CONFIG_SYS_DDR_RAW_TIMING
|
||||
#define CONFIG_SYS_DRAM_SIZE 1024
|
||||
|
||||
fsl_ddr_cfg_regs_t ddr_cfg_regs_800 = {
|
||||
.cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS,
|
||||
.cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG,
|
||||
.cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2,
|
||||
.timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_800,
|
||||
.timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_800,
|
||||
.timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_800,
|
||||
.timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_800,
|
||||
.ddr_sdram_cfg = CONFIG_SYS_DDR_CONTROL,
|
||||
.ddr_sdram_cfg_2 = CONFIG_SYS_DDR_CONTROL_2,
|
||||
.ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_800,
|
||||
.ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_800,
|
||||
.ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL,
|
||||
.ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_800,
|
||||
.ddr_data_init = CONFIG_MEM_INIT_VALUE,
|
||||
.ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_800,
|
||||
.ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR,
|
||||
.ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR,
|
||||
.timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4,
|
||||
.timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5,
|
||||
.ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CONTROL,
|
||||
.ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CONTROL_800,
|
||||
.ddr_sr_cntr = CONFIG_SYS_DDR_SR_CNTR,
|
||||
.ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1,
|
||||
.ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2
|
||||
};
|
||||
|
||||
fixed_ddr_parm_t fixed_ddr_parm_0[] = {
|
||||
{750, 850, &ddr_cfg_regs_800},
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
unsigned long get_sdram_size(void)
|
||||
{
|
||||
return get_ram_size(CONFIG_SYS_DDR_SDRAM_BASE, CONFIG_SYS_DRAM_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fixed sdram init -- doesn't use serial presence detect.
|
||||
*/
|
||||
phys_size_t fixed_sdram(void)
|
||||
{
|
||||
int i;
|
||||
char buf[32];
|
||||
fsl_ddr_cfg_regs_t ddr_cfg_regs;
|
||||
phys_size_t ddr_size;
|
||||
ulong ddr_freq, ddr_freq_mhz;
|
||||
|
||||
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));
|
||||
|
||||
for (i = 0; fixed_ddr_parm_0[i].max_freq > 0; i++) {
|
||||
if ((ddr_freq_mhz > fixed_ddr_parm_0[i].min_freq) &&
|
||||
(ddr_freq_mhz <= fixed_ddr_parm_0[i].max_freq)) {
|
||||
memcpy(&ddr_cfg_regs, fixed_ddr_parm_0[i].ddr_settings,
|
||||
sizeof(ddr_cfg_regs));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fixed_ddr_parm_0[i].max_freq == 0) {
|
||||
panic("Unsupported DDR data rate %s MT/s data rate\n",
|
||||
strmhz(buf, ddr_freq));
|
||||
}
|
||||
|
||||
ddr_size = (phys_size_t) CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
|
||||
fsl_ddr_set_memctl_regs(&ddr_cfg_regs, 0, 0);
|
||||
|
||||
if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE, ddr_size,
|
||||
LAW_TRGT_IF_DDR_1) < 0) {
|
||||
printf("ERROR setting Local Access Windows for DDR\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ddr_size;
|
||||
}
|
||||
|
||||
#else /* CONFIG_SYS_DDR_RAW_TIMING */
|
||||
/* Micron MT41J256M8HX-15E */
|
||||
dimm_params_t ddr_raw_timing = {
|
||||
.n_ranks = 1,
|
||||
.rank_density = 1073741824u,
|
||||
.capacity = 1073741824u,
|
||||
.primary_sdram_width = 32,
|
||||
.ec_sdram_width = 0,
|
||||
.registered_dimm = 0,
|
||||
.mirrored_dimm = 0,
|
||||
.n_row_addr = 15,
|
||||
.n_col_addr = 10,
|
||||
.n_banks_per_sdram_device = 8,
|
||||
.edc_config = 0,
|
||||
.burst_lengths_bitmask = 0x0c,
|
||||
|
||||
.tckmin_x_ps = 1870,
|
||||
.caslat_x = 0x1e << 4, /* 5,6,7,8 */
|
||||
.taa_ps = 13125,
|
||||
.twr_ps = 15000,
|
||||
.trcd_ps = 13125,
|
||||
.trrd_ps = 7500,
|
||||
.trp_ps = 13125,
|
||||
.tras_ps = 37500,
|
||||
.trc_ps = 50625,
|
||||
.trfc_ps = 160000,
|
||||
.twtr_ps = 7500,
|
||||
.trtp_ps = 7500,
|
||||
.refresh_rate_ps = 7800000,
|
||||
.tfaw_ps = 37500,
|
||||
};
|
||||
|
||||
int fsl_ddr_get_dimm_params(dimm_params_t *pdimm,
|
||||
unsigned int controller_number,
|
||||
unsigned int dimm_number)
|
||||
{
|
||||
const char dimm_model[] = "Fixed DDR on board";
|
||||
|
||||
if ((controller_number == 0) && (dimm_number == 0)) {
|
||||
memcpy(pdimm, &ddr_raw_timing, sizeof(dimm_params_t));
|
||||
memset(pdimm->mpart, 0, sizeof(pdimm->mpart));
|
||||
memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fsl_ddr_board_options(memctl_options_t *popts,
|
||||
dimm_params_t *pdimm,
|
||||
unsigned int ctrl_num)
|
||||
{
|
||||
int i;
|
||||
popts->clk_adjust = 6;
|
||||
popts->cpo_override = 0x1f;
|
||||
popts->write_data_delay = 2;
|
||||
popts->half_strength_driver_enable = 1;
|
||||
/* Write leveling override */
|
||||
popts->wrlvl_en = 1;
|
||||
popts->wrlvl_override = 1;
|
||||
popts->wrlvl_sample = 0xf;
|
||||
popts->wrlvl_start = 0x8;
|
||||
popts->trwt_override = 1;
|
||||
popts->trwt = 0;
|
||||
|
||||
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
|
||||
popts->cs_local_opts[i].odt_rd_cfg = FSL_DDR_ODT_NEVER;
|
||||
popts->cs_local_opts[i].odt_wr_cfg = FSL_DDR_ODT_CS;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SYS_DDR_RAW_TIMING */
|
||||
@@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2011-2012 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/fsl_law.h>
|
||||
#include <asm/mmu.h>
|
||||
|
||||
struct law_entry law_table[] = {
|
||||
SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_IFC),
|
||||
SET_LAW(CONFIG_SYS_FSL_DSP_CCSRBAR_PHYS, LAW_SIZE_1M,
|
||||
LAW_TRGT_IF_DSP_CCSR),
|
||||
SET_LAW(CONFIG_SYS_FSL_DSP_M2_RAM_ADDR, LAW_SIZE_16M,
|
||||
LAW_TRGT_IF_OCN_DSP),
|
||||
};
|
||||
|
||||
int num_law_entries = ARRAY_SIZE(law_table);
|
||||
@@ -0,0 +1,103 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <ns16550.h>
|
||||
#include <asm/io.h>
|
||||
#include <nand.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/fsl_law.h>
|
||||
#include <fsl_ddr_sdram.h>
|
||||
#include <asm/global_data.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* Fixed sdram init -- doesn't use serial presence detect.
|
||||
*/
|
||||
static void sdram_init(void)
|
||||
{
|
||||
struct ccsr_ddr __iomem *ddr =
|
||||
(struct ccsr_ddr __iomem *)CONFIG_SYS_FSL_DDR_ADDR;
|
||||
|
||||
__raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds);
|
||||
__raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config);
|
||||
#if CONFIG_CHIP_SELECTS_PER_CTRL > 1
|
||||
__raw_writel(CONFIG_SYS_DDR_CS1_BNDS, &ddr->cs1_bnds);
|
||||
__raw_writel(CONFIG_SYS_DDR_CS1_CONFIG, &ddr->cs1_config);
|
||||
#endif
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_3_800, &ddr->timing_cfg_3);
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_0_800, &ddr->timing_cfg_0);
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_1_800, &ddr->timing_cfg_1);
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_2_800, &ddr->timing_cfg_2);
|
||||
|
||||
__raw_writel(CONFIG_SYS_DDR_CONTROL_2, &ddr->sdram_cfg_2);
|
||||
__raw_writel(CONFIG_SYS_DDR_MODE_1_800, &ddr->sdram_mode);
|
||||
__raw_writel(CONFIG_SYS_DDR_MODE_2_800, &ddr->sdram_mode_2);
|
||||
|
||||
__raw_writel(CONFIG_SYS_DDR_INTERVAL_800, &ddr->sdram_interval);
|
||||
__raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init);
|
||||
__raw_writel(CONFIG_SYS_DDR_CLK_CTRL_800, &ddr->sdram_clk_cntl);
|
||||
|
||||
__raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL_800, &ddr->ddr_wrlvl_cntl);
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_4, &ddr->timing_cfg_4);
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_5, &ddr->timing_cfg_5);
|
||||
__raw_writel(CONFIG_SYS_DDR_ZQ_CONTROL, &ddr->ddr_zq_cntl);
|
||||
|
||||
/* Set, but do not enable the memory */
|
||||
__raw_writel(CONFIG_SYS_DDR_CONTROL & ~SDRAM_CFG_MEM_EN, &ddr->sdram_cfg);
|
||||
|
||||
asm volatile("sync;isync");
|
||||
udelay(500);
|
||||
|
||||
/* Let the controller go */
|
||||
out_be32(&ddr->sdram_cfg, in_be32(&ddr->sdram_cfg) | SDRAM_CFG_MEM_EN);
|
||||
|
||||
set_next_law(CONFIG_SYS_NAND_DDR_LAW, LAW_SIZE_1G, LAW_TRGT_IF_DDR_1);
|
||||
}
|
||||
|
||||
void board_init_f(ulong bootflag)
|
||||
{
|
||||
u32 plat_ratio;
|
||||
ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
|
||||
|
||||
/* 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... ");
|
||||
|
||||
/* Initialize the DDR3 */
|
||||
sdram_init();
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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++);
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2011-2012 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#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,
|
||||
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 + 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 + 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 + 12 * 1024,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, 0,
|
||||
0, 0, BOOKE_PAGESZ_4K, 0),
|
||||
|
||||
/* TLB 1 */
|
||||
/* *I*** - Covers boot page */
|
||||
SET_TLB_ENTRY(1, 0xfffff000, 0xfffff000,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 0, BOOKE_PAGESZ_4K, 1),
|
||||
#ifdef CONFIG_SPL_NAND_BOOT
|
||||
SET_TLB_ENTRY(1, 0xffffe000, 0xffffe000,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 10, BOOKE_PAGESZ_4K, 1),
|
||||
#endif
|
||||
|
||||
/* *I*G* - CCSRBAR (PA) */
|
||||
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_1M, 1),
|
||||
|
||||
/* CCSRBAR (DSP) */
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_FSL_DSP_CCSRBAR,
|
||||
CONFIG_SYS_FSL_DSP_CCSRBAR_PHYS,
|
||||
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 2, BOOKE_PAGESZ_1M, 1),
|
||||
|
||||
#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE, CONFIG_SYS_DDR_SDRAM_BASE,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_M,
|
||||
0, 8, BOOKE_PAGESZ_1G, 1),
|
||||
#endif
|
||||
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 3, BOOKE_PAGESZ_1M, 1)
|
||||
|
||||
};
|
||||
|
||||
int num_tlb_entries = ARRAY_SIZE(tlb_table);
|
||||
@@ -0,0 +1,14 @@
|
||||
if TARGET_BSC9132QDS
|
||||
|
||||
config SYS_BOARD
|
||||
default "bsc9132qds"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "freescale"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "BSC9132QDS"
|
||||
|
||||
source "board/freescale/common/Kconfig"
|
||||
|
||||
endif
|
||||
@@ -0,0 +1,25 @@
|
||||
BSC9132QDS BOARD
|
||||
M: Naveen Burmi <naveen.burmi@nxp.com>
|
||||
S: Maintained
|
||||
F: board/freescale/bsc9132qds/
|
||||
F: include/configs/BSC9132QDS.h
|
||||
F: configs/BSC9132QDS_NAND_DDRCLK100_defconfig
|
||||
F: configs/BSC9132QDS_NAND_DDRCLK133_defconfig
|
||||
F: configs/BSC9132QDS_NOR_DDRCLK100_defconfig
|
||||
F: configs/BSC9132QDS_NOR_DDRCLK133_defconfig
|
||||
F: configs/BSC9132QDS_SDCARD_DDRCLK100_defconfig
|
||||
F: configs/BSC9132QDS_SDCARD_DDRCLK133_defconfig
|
||||
F: configs/BSC9132QDS_SPIFLASH_DDRCLK100_defconfig
|
||||
F: configs/BSC9132QDS_SPIFLASH_DDRCLK133_defconfig
|
||||
|
||||
BSC9132QDS_NAND_DDRCLK100_SECURE BOARD
|
||||
M: Ruchika Gupta <ruchika.gupta@nxp.com>
|
||||
S: Maintained
|
||||
F: configs/BSC9132QDS_NAND_DDRCLK100_SECURE_defconfig
|
||||
F: configs/BSC9132QDS_NAND_DDRCLK133_SECURE_defconfig
|
||||
F: configs/BSC9132QDS_NOR_DDRCLK100_SECURE_defconfig
|
||||
F: configs/BSC9132QDS_NOR_DDRCLK133_SECURE_defconfig
|
||||
F: configs/BSC9132QDS_SDCARD_DDRCLK100_SECURE_defconfig
|
||||
F: configs/BSC9132QDS_SDCARD_DDRCLK133_SECURE_defconfig
|
||||
F: configs/BSC9132QDS_SPIFLASH_DDRCLK100_SECURE_defconfig
|
||||
F: configs/BSC9132QDS_SPIFLASH_DDRCLK133_SECURE_defconfig
|
||||
@@ -0,0 +1,21 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright 2013 Freescale Semiconductor, Inc.
|
||||
|
||||
MINIMAL=
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
ifdef CONFIG_SPL_INIT_MINIMAL
|
||||
MINIMAL=y
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MINIMAL
|
||||
obj-y += spl_minimal.o
|
||||
else
|
||||
obj-y += bsc9132qds.o
|
||||
obj-y += ddr.o
|
||||
endif
|
||||
|
||||
obj-y += law.o
|
||||
obj-y += tlb.o
|
||||
@@ -0,0 +1,150 @@
|
||||
Overview
|
||||
--------
|
||||
The BSC9132 is a highly integrated device that targets the evolving
|
||||
Microcell, Picocell, and Enterprise-Femto base station market subsegments.
|
||||
|
||||
The BSC9132 device combines Power Architecture e500 and DSP StarCore SC3850
|
||||
core technologies with MAPLE-B2P baseband acceleration processing elements
|
||||
to address the need for a high performance, low cost, integrated solution
|
||||
that handles all required processing layers without the need for an
|
||||
external device except for an RF transceiver or, in a Micro base station
|
||||
configuration, a host device that handles the L3/L4 and handover between
|
||||
sectors.
|
||||
|
||||
The BSC9132 SoC includes the following function and features:
|
||||
- Power Architecture subsystem including two e500 processors with
|
||||
512-Kbyte shared L2 cache
|
||||
- Two StarCore SC3850 DSP subsystems, each with a 512-Kbyte private L2
|
||||
cache
|
||||
- 32 Kbyte of shared M3 memory
|
||||
- The Multi Accelerator Platform Engine for Pico BaseStation Baseband
|
||||
Processing (MAPLE-B2P)
|
||||
- Two DDR3/3L memory interfaces with 32-bit data width (40 bits including
|
||||
ECC), up to 1333 MHz data rate
|
||||
- Dedicated security engine featuring trusted boot
|
||||
- Two DMA controllers
|
||||
- OCNDMA with four bidirectional channels
|
||||
- SysDMA with sixteen bidirectional channels
|
||||
- Interfaces
|
||||
- Four-lane SerDes PHY
|
||||
- PCI Express controller complies with the PEX Specification-Rev 2.0
|
||||
- Two Common Public Radio Interface (CPRI) controller lanes
|
||||
- High-speed USB 2.0 host and device controller with ULPI interface
|
||||
- Enhanced secure digital (SD/MMC) host controller (eSDHC)
|
||||
- Antenna interface controller (AIC), supporting four industry
|
||||
standard JESD207/four custom ADI RF interfaces
|
||||
- ADI lanes support both full duplex FDD support & half duplex TDD
|
||||
- Universal Subscriber Identity Module (USIM) interface that
|
||||
facilitates communication to SIM cards or Eurochip pre-paid phone
|
||||
cards
|
||||
- Two DUART, two eSPI, and two I2C controllers
|
||||
- Integrated Flash memory controller (IFC)
|
||||
- GPIO
|
||||
- Sixteen 32-bit timers
|
||||
|
||||
The SC3850 core subsystem consists of the following:
|
||||
- 32 KB, 8-way, level 1 instruction cache (L1 ICache)
|
||||
- 32 KB, 8-way, level 1 data cache (L1 DCache)
|
||||
- 512 KB, 8-way, level 2 unified instruction/data cache (L2 cache/M2 memory)
|
||||
- Memory management unit (MMU)
|
||||
- Global interrupt controller ( GIC)
|
||||
- Debug and profiling unit (DPU)
|
||||
- Two 32-bit quad timers
|
||||
|
||||
BSC9132QDS board Overview
|
||||
-------------------------
|
||||
2Gbyte DDR3 (on board DDR), Dual Ranki
|
||||
32Mbyte 16bit NOR flash
|
||||
128Mbyte 2K page size NAND Flash
|
||||
256 Kbit M24256 I2C EEPROM
|
||||
128 Mbit SPI Flash memory
|
||||
SD slot
|
||||
USB-ULPI
|
||||
eTSEC1: Connected to SGMII PHY
|
||||
eTSEC2: Connected to SGMII PHY
|
||||
PCIe
|
||||
CPRI
|
||||
SerDes
|
||||
I2C RTC
|
||||
DUART interface: supports one UARTs up to 115200 bps for console display
|
||||
|
||||
Frequency Combinations Supported
|
||||
--------------------------------
|
||||
Core MHz/CCB MHz/DDR(MT/s)
|
||||
1. CPU0/CPU1/CCB/DDR: 1000MHz/1000MHz/500MHz/800MHz
|
||||
(SYSCLK = 100MHz, DDRCLK = 100MHz)
|
||||
2. CPU0/CPU1/CCB/DDR: 1200MHz/1200MHz/600MHz/1330MHz
|
||||
(SYSCLK = 100MHz, DDRCLK = 133MHz)
|
||||
|
||||
Boot Methods Supported
|
||||
-----------------------
|
||||
1. NOR Flash
|
||||
2. NAND Flash
|
||||
3. SD Card
|
||||
4. SPI flash
|
||||
|
||||
Default Boot Method
|
||||
--------------------
|
||||
NOR boot
|
||||
|
||||
Building U-Boot
|
||||
--------------
|
||||
To build the U-Boot for BSC9132QDS:
|
||||
1. NOR Flash
|
||||
make BSC9132QDS_NOR_DDRCLK100 : For 100MHZ DDR CLK
|
||||
make BSC9132QDS_NOR_DDRCLK133 : For 133MHZ DDR CLK
|
||||
2. NAND Flash : It is currently not supported
|
||||
3. SPI Flash
|
||||
make BSC9132QDS_SPIFLASH_DDRCLK100 : For 100MHZ DDR CLK
|
||||
make BSC9132QDS_SPIFLASH_DDRCLK133 : For 133MHZ DDR CLK
|
||||
4. SD Card
|
||||
make BSC9132QDS_SDCARD_DDRCLK100 : For 100MHZ DDR CLK
|
||||
make BSC9132QDS_SDCARD_DDRCLK133 : For 133MHZ DDR CLK
|
||||
|
||||
Memory map
|
||||
-----------
|
||||
0x0000_0000 0x7FFF_FFFF DDR 2G cacheable
|
||||
0x8000_0000 0x8FFF_FFFF NOR Flash 256M
|
||||
0x9000_0000 0x9FFF_FFFF PCIe Memory 256M
|
||||
0xA000_0000 0xA7FF_FFFF DSP core1 L2 space 128M
|
||||
0xB000_0000 0xB0FF_FFFF DSP core0 M2 space 16M
|
||||
0xB100_0000 0xB1FF_FFFF DSP core1 M2 space 16M
|
||||
0xC000_0000 0xC000_7FFF M3 Memory 32K
|
||||
0xC001_0000 0xC001_FFFF PCI Express I/O 64K
|
||||
0xC100_0000 0xC13F_FFFF MAPLE-2F 4M
|
||||
0xC1F0_0000 0xC1F7_FFFF PA SRAM Region 0 512K
|
||||
0xC1F8_0000 0xC1FB_FFFF PA SRAM Region 1 512K
|
||||
0xFED0_0000 0xFED0_3FFF SEC Secured RAM 16K
|
||||
0xFEE0_0000 0xFEE0_0FFF DSP Boot ROM 4K
|
||||
0xFF60_0000 0xFF6F_FFFF DSP CCSR 1M
|
||||
0xFF70_0000 0xFF7F_FFFF PA CCSR 1M
|
||||
0xFF80_0000 0xFFFF_FFFF Boot Page & NAND Buffer 8M
|
||||
|
||||
Flashing Images
|
||||
---------------
|
||||
To place a new U-Boot image in the NAND flash and then boot
|
||||
with that new image temporarily, use this:
|
||||
tftp 1000000 u-boot-nand.bin
|
||||
nand erase 0 100000
|
||||
nand write 1000000 0 100000
|
||||
reset
|
||||
|
||||
Using the Device Tree Source File
|
||||
---------------------------------
|
||||
To create the DTB (Device Tree Binary) image file,
|
||||
use a command similar to this:
|
||||
|
||||
dtc -b 0 -f -I dts -O dtb bsc9132qds.dts > bsc9132qds.dtb
|
||||
|
||||
Likely, that .dts file will come from here;
|
||||
|
||||
linux-2.6/arch/powerpc/boot/dts/bsc9132qds.dts
|
||||
|
||||
Booting Linux
|
||||
-------------
|
||||
Place a linux uImage in the TFTP disk area.
|
||||
|
||||
tftp 1000000 uImage
|
||||
tftp 2000000 rootfs.ext2.gz.uboot
|
||||
tftp c00000 bsc9132qds.dtb
|
||||
bootm 1000000 2000000 c00000
|
||||
@@ -0,0 +1,430 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <init.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/immap_85xx.h>
|
||||
#include <asm/io.h>
|
||||
#include <env.h>
|
||||
#include <miiphy.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
#include <fsl_mdio.h>
|
||||
#include <tsec.h>
|
||||
#include <mmc.h>
|
||||
#include <netdev.h>
|
||||
#include <fsl_ifc.h>
|
||||
#include <hwconfig.h>
|
||||
#include <i2c.h>
|
||||
#include <fsl_ddr_sdram.h>
|
||||
#include <jffs2/load_kernel.h>
|
||||
#include <mtd_node.h>
|
||||
#include <flash.h>
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
#include <pci.h>
|
||||
#include <asm/fsl_pci.h>
|
||||
#endif
|
||||
|
||||
#include "../common/qixis.h"
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
struct fsl_ifc ifc = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
|
||||
|
||||
setbits_be32(&ifc.gregs->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void board_config_serdes_mux(void)
|
||||
{
|
||||
ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
||||
u32 pordevsr = in_be32(&gur->pordevsr);
|
||||
u32 srds_cfg = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >>
|
||||
MPC85xx_PORDEVSR_IO_SEL_SHIFT;
|
||||
|
||||
switch (srds_cfg) {
|
||||
/* PEX(1) PEX(2) CPRI 2 CPRI 1 */
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 22:
|
||||
case 23:
|
||||
case 24:
|
||||
case 25:
|
||||
case 26:
|
||||
QIXIS_WRITE_I2C(brdcfg[4], 0x03);
|
||||
break;
|
||||
|
||||
/* PEX(1) PEX(2) SGMII1 CPRI 1 */
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 27:
|
||||
case 28:
|
||||
case 29:
|
||||
case 30:
|
||||
case 31:
|
||||
QIXIS_WRITE_I2C(brdcfg[4], 0x01);
|
||||
break;
|
||||
|
||||
/* PEX(1) PEX(2) SGMII1 SGMII2 */
|
||||
case 11:
|
||||
case 32:
|
||||
QIXIS_WRITE_I2C(brdcfg[4], 0x00);
|
||||
break;
|
||||
|
||||
/* PEX(1) SGMII2 CPRI 2 CPRI 1 */
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
case 33:
|
||||
case 34:
|
||||
case 35:
|
||||
case 36:
|
||||
case 37:
|
||||
QIXIS_WRITE_I2C(brdcfg[4], 0x07);
|
||||
break;
|
||||
|
||||
/* PEX(1) SGMII2 SGMII1 CPRI 1 */
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
case 20:
|
||||
case 21:
|
||||
case 38:
|
||||
case 39:
|
||||
case 40:
|
||||
case 41:
|
||||
case 42:
|
||||
QIXIS_WRITE_I2C(brdcfg[4], 0x05);
|
||||
break;
|
||||
|
||||
/* SGMII1 SGMII2 CPRI 2 CPRI 1 */
|
||||
case 43:
|
||||
case 44:
|
||||
case 45:
|
||||
case 46:
|
||||
case 47:
|
||||
QIXIS_WRITE_I2C(brdcfg[4], 0x0F);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure DSP DDR controller */
|
||||
void dsp_ddr_configure(void)
|
||||
{
|
||||
/*
|
||||
*There are separate DDR-controllers for DSP and PowerPC side DDR.
|
||||
*copy the ddr controller settings from PowerPC side DDR controller
|
||||
*to the DSP DDR controller as connected DDR memories are similar.
|
||||
*/
|
||||
struct ccsr_ddr __iomem *pa_ddr =
|
||||
(struct ccsr_ddr __iomem *)CONFIG_SYS_FSL_DDR_ADDR;
|
||||
struct ccsr_ddr temp_ddr;
|
||||
struct ccsr_ddr __iomem *dsp_ddr =
|
||||
(struct ccsr_ddr __iomem *)CONFIG_SYS_FSL_DSP_CCSR_DDR_ADDR;
|
||||
|
||||
memcpy(&temp_ddr, pa_ddr, sizeof(struct ccsr_ddr));
|
||||
temp_ddr.cs0_bnds = CONFIG_SYS_DDR1_CS0_BNDS;
|
||||
temp_ddr.sdram_cfg &= ~SDRAM_CFG_MEM_EN;
|
||||
memcpy(dsp_ddr, &temp_ddr, sizeof(struct ccsr_ddr));
|
||||
dsp_ddr->sdram_cfg |= SDRAM_CFG_MEM_EN;
|
||||
}
|
||||
|
||||
int board_early_init_r(void)
|
||||
{
|
||||
#ifdef CONFIG_MTD_NOR_FLASH
|
||||
const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
|
||||
int flash_esel = find_tlb_idx((void *)flashbase, 1);
|
||||
|
||||
/*
|
||||
* Remap Boot flash 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();
|
||||
|
||||
if (flash_esel == -1) {
|
||||
/* very unlikely unless something is messed up */
|
||||
puts("Error: Could not find TLB for FLASH BASE\n");
|
||||
flash_esel = 2; /* give our best effort to continue */
|
||||
} else {
|
||||
/* invalidate existing TLB entry for flash */
|
||||
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_64M, 1);
|
||||
|
||||
set_tlb(1, flashbase + 0x4000000,
|
||||
CONFIG_SYS_FLASH_BASE_PHYS + 0x4000000,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, flash_esel+1, BOOKE_PAGESZ_64M, 1);
|
||||
#endif
|
||||
board_config_serdes_mux();
|
||||
dsp_ddr_configure();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
void pci_init_board(void)
|
||||
{
|
||||
fsl_pcie_init_board(0);
|
||||
}
|
||||
#endif /* ifdef CONFIG_PCI */
|
||||
|
||||
int checkboard(void)
|
||||
{
|
||||
struct cpu_type *cpu;
|
||||
u8 sw;
|
||||
|
||||
cpu = gd->arch.cpu;
|
||||
printf("Board: %sQDS\n", cpu->name);
|
||||
|
||||
printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, FPGA Ver: 0x%02x,\n",
|
||||
QIXIS_READ(id), QIXIS_READ(arch), QIXIS_READ(scver));
|
||||
|
||||
sw = QIXIS_READ(brdcfg[0]);
|
||||
sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
|
||||
|
||||
printf("IFC chip select:");
|
||||
switch (sw) {
|
||||
case 0:
|
||||
printf("NOR\n");
|
||||
break;
|
||||
case 2:
|
||||
printf("Promjet\n");
|
||||
break;
|
||||
case 4:
|
||||
printf("NAND\n");
|
||||
break;
|
||||
default:
|
||||
printf("Invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_eth_init(bd_t *bis)
|
||||
{
|
||||
#ifdef CONFIG_TSEC_ENET
|
||||
struct fsl_pq_mdio_info mdio_info;
|
||||
struct tsec_info_struct tsec_info[4];
|
||||
int num = 0;
|
||||
|
||||
#ifdef CONFIG_TSEC1
|
||||
SET_STD_TSEC_INFO(tsec_info[num], 1);
|
||||
num++;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TSEC2
|
||||
SET_STD_TSEC_INFO(tsec_info[num], 2);
|
||||
num++;
|
||||
#endif
|
||||
|
||||
mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR;
|
||||
mdio_info.name = DEFAULT_MII_NAME;
|
||||
|
||||
fsl_pq_mdio_init(bis, &mdio_info);
|
||||
tsec_eth_init(bis, tsec_info, num);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
pci_eth_init(bis);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define USBMUX_SEL_MASK 0xc0
|
||||
#define USBMUX_SEL_UART2 0xc0
|
||||
#define USBMUX_SEL_USB 0x40
|
||||
#define SPIMUX_SEL_UART3 0x80
|
||||
#define GPS_MUX_SEL_GPS 0x40
|
||||
|
||||
#define TSEC_1588_CLKIN_MASK 0x03
|
||||
#define CON_XCVR_REF_CLK 0x00
|
||||
|
||||
int misc_init_r(void)
|
||||
{
|
||||
u8 val;
|
||||
ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
||||
u32 porbmsr = in_be32(&gur->porbmsr);
|
||||
u32 romloc = (porbmsr >> MPC85xx_PORBMSR_ROMLOC_SHIFT) & 0xf;
|
||||
|
||||
/*Configure 1588 clock-in source from RF Card*/
|
||||
val = QIXIS_READ_I2C(brdcfg[5]);
|
||||
QIXIS_WRITE_I2C(brdcfg[5],
|
||||
(val & ~(TSEC_1588_CLKIN_MASK)) | CON_XCVR_REF_CLK);
|
||||
|
||||
if (hwconfig("uart2") && hwconfig("usb1")) {
|
||||
printf("UART2 and USB cannot work together on the board\n");
|
||||
printf("Remove one from hwconfig and reset\n");
|
||||
} else {
|
||||
if (hwconfig("uart2")) {
|
||||
val = QIXIS_READ_I2C(brdcfg[5]);
|
||||
QIXIS_WRITE_I2C(brdcfg[5],
|
||||
(val & ~(USBMUX_SEL_MASK)) | USBMUX_SEL_UART2);
|
||||
clrbits_be32(&gur->pmuxcr3,
|
||||
MPC85xx_PMUXCR3_USB_SEL_MASK);
|
||||
setbits_be32(&gur->pmuxcr3, MPC85xx_PMUXCR3_UART2_SEL);
|
||||
} else {
|
||||
/* By default USB should be selected.
|
||||
* Programming FPGA to select USB. */
|
||||
val = QIXIS_READ_I2C(brdcfg[5]);
|
||||
QIXIS_WRITE_I2C(brdcfg[5],
|
||||
(val & ~(USBMUX_SEL_MASK)) | USBMUX_SEL_USB);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (hwconfig("sim")) {
|
||||
if (romloc == PORBMSR_ROMLOC_NAND_2K ||
|
||||
romloc == PORBMSR_ROMLOC_NOR ||
|
||||
romloc == PORBMSR_ROMLOC_SPI) {
|
||||
|
||||
val = QIXIS_READ_I2C(brdcfg[3]);
|
||||
QIXIS_WRITE_I2C(brdcfg[3], val|0x10);
|
||||
clrbits_be32(&gur->pmuxcr,
|
||||
MPC85xx_PMUXCR0_SIM_SEL_MASK);
|
||||
setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR0_SIM_SEL);
|
||||
}
|
||||
}
|
||||
|
||||
if (hwconfig("uart3")) {
|
||||
if (romloc == PORBMSR_ROMLOC_NAND_2K ||
|
||||
romloc == PORBMSR_ROMLOC_NOR ||
|
||||
romloc == PORBMSR_ROMLOC_SDHC) {
|
||||
|
||||
/* UART3 and SPI1 (Flashes) are muxed together */
|
||||
val = QIXIS_READ_I2C(brdcfg[3]);
|
||||
QIXIS_WRITE_I2C(brdcfg[3], (val | SPIMUX_SEL_UART3));
|
||||
clrbits_be32(&gur->pmuxcr3,
|
||||
MPC85xx_PMUXCR3_UART3_SEL_MASK);
|
||||
setbits_be32(&gur->pmuxcr3, MPC85xx_PMUXCR3_UART3_SEL);
|
||||
|
||||
/* MUX to select UART3 connection to J24 header
|
||||
* or to GPS */
|
||||
val = QIXIS_READ_I2C(brdcfg[6]);
|
||||
if (hwconfig("gps"))
|
||||
QIXIS_WRITE_I2C(brdcfg[6],
|
||||
(val | GPS_MUX_SEL_GPS));
|
||||
else
|
||||
QIXIS_WRITE_I2C(brdcfg[6],
|
||||
(val & ~(GPS_MUX_SEL_GPS)));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fdt_del_node_compat(void *blob, const char *compatible)
|
||||
{
|
||||
int err;
|
||||
int off = fdt_node_offset_by_compatible(blob, -1, compatible);
|
||||
if (off < 0) {
|
||||
printf("WARNING: could not find compatible node %s: %s.\n",
|
||||
compatible, fdt_strerror(off));
|
||||
return;
|
||||
}
|
||||
err = fdt_del_node(blob, off);
|
||||
if (err < 0) {
|
||||
printf("WARNING: could not remove %s: %s.\n",
|
||||
compatible, fdt_strerror(err));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OF_BOARD_SETUP)
|
||||
#ifdef CONFIG_FDT_FIXUP_PARTITIONS
|
||||
static const struct node_info nodes[] = {
|
||||
{ "cfi-flash", MTD_DEV_TYPE_NOR, },
|
||||
{ "fsl,ifc-nand", MTD_DEV_TYPE_NAND, },
|
||||
};
|
||||
#endif
|
||||
int ft_board_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
phys_addr_t base;
|
||||
phys_size_t size;
|
||||
|
||||
ft_cpu_setup(blob, bd);
|
||||
|
||||
base = env_get_bootm_low();
|
||||
size = env_get_bootm_size();
|
||||
|
||||
#if defined(CONFIG_PCI)
|
||||
FT_FSL_PCI_SETUP;
|
||||
#endif
|
||||
|
||||
fdt_fixup_memory(blob, (u64)base, (u64)size);
|
||||
#ifdef CONFIG_FDT_FIXUP_PARTITIONS
|
||||
fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
|
||||
#endif
|
||||
|
||||
ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
||||
u32 porbmsr = in_be32(&gur->porbmsr);
|
||||
u32 romloc = (porbmsr >> MPC85xx_PORBMSR_ROMLOC_SHIFT) & 0xf;
|
||||
|
||||
if (!(hwconfig("uart2") && hwconfig("usb1"))) {
|
||||
/* If uart2 is there in hwconfig remove usb node from
|
||||
* device tree */
|
||||
|
||||
if (hwconfig("uart2")) {
|
||||
/* remove dts usb node */
|
||||
fdt_del_node_compat(blob, "fsl-usb2-dr");
|
||||
} else {
|
||||
fsl_fdt_fixup_dr_usb(blob, bd);
|
||||
fdt_del_node_and_alias(blob, "serial2");
|
||||
}
|
||||
}
|
||||
|
||||
if (hwconfig("uart3")) {
|
||||
if (romloc == PORBMSR_ROMLOC_NAND_2K ||
|
||||
romloc == PORBMSR_ROMLOC_NOR ||
|
||||
romloc == PORBMSR_ROMLOC_SDHC)
|
||||
/* Delete SPI node from the device tree */
|
||||
fdt_del_node_and_alias(blob, "spi1");
|
||||
} else
|
||||
fdt_del_node_and_alias(blob, "serial3");
|
||||
|
||||
if (hwconfig("sim")) {
|
||||
if (romloc == PORBMSR_ROMLOC_NAND_2K ||
|
||||
romloc == PORBMSR_ROMLOC_NOR ||
|
||||
romloc == PORBMSR_ROMLOC_SPI) {
|
||||
|
||||
/* remove dts sdhc node */
|
||||
fdt_del_node_compat(blob, "fsl,esdhc");
|
||||
} else if (romloc == PORBMSR_ROMLOC_SDHC) {
|
||||
|
||||
/* remove dts sim node */
|
||||
fdt_del_node_compat(blob, "fsl,sim-v1.0");
|
||||
printf("SIM & SDHC can't work together on the board");
|
||||
printf("\nRemove sim from hwconfig and reset\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,191 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <vsprintf.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/immap_85xx.h>
|
||||
#include <asm/processor.h>
|
||||
#include <fsl_ddr_sdram.h>
|
||||
#include <fsl_ddr_dimm_params.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/fsl_law.h>
|
||||
|
||||
#ifndef CONFIG_SYS_DDR_RAW_TIMING
|
||||
|
||||
fsl_ddr_cfg_regs_t ddr_cfg_regs_800 = {
|
||||
.cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS,
|
||||
.cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG,
|
||||
.cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2,
|
||||
.timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_800,
|
||||
.timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_800,
|
||||
.timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_800,
|
||||
.timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_800,
|
||||
.ddr_sdram_cfg = CONFIG_SYS_DDR_CONTROL,
|
||||
.ddr_sdram_cfg_2 = CONFIG_SYS_DDR_CONTROL_2,
|
||||
.ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_800,
|
||||
.ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_800,
|
||||
.ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL,
|
||||
.ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_800,
|
||||
.ddr_data_init = CONFIG_MEM_INIT_VALUE,
|
||||
.ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_800,
|
||||
.ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR,
|
||||
.ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR,
|
||||
.timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4,
|
||||
.timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5,
|
||||
.ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CONTROL,
|
||||
.ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CONTROL_800,
|
||||
.ddr_sr_cntr = CONFIG_SYS_DDR_SR_CNTR,
|
||||
.ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1,
|
||||
.ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2
|
||||
};
|
||||
|
||||
fsl_ddr_cfg_regs_t ddr_cfg_regs_1333 = {
|
||||
.cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS,
|
||||
.cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG,
|
||||
.cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2,
|
||||
.timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_1333,
|
||||
.timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_1333,
|
||||
.timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_1333,
|
||||
.timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_1333,
|
||||
.ddr_sdram_cfg = CONFIG_SYS_DDR_CONTROL,
|
||||
.ddr_sdram_cfg_2 = CONFIG_SYS_DDR_CONTROL_2,
|
||||
.ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_1333,
|
||||
.ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_1333,
|
||||
.ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL,
|
||||
.ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_1333,
|
||||
.ddr_data_init = CONFIG_MEM_INIT_VALUE,
|
||||
.ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_1333,
|
||||
.ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR,
|
||||
.ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR,
|
||||
.timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4,
|
||||
.timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5,
|
||||
.ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CONTROL,
|
||||
.ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CONTROL_1333,
|
||||
.ddr_sr_cntr = CONFIG_SYS_DDR_SR_CNTR,
|
||||
.ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1,
|
||||
.ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2
|
||||
};
|
||||
|
||||
|
||||
fixed_ddr_parm_t fixed_ddr_parm_0[] = {
|
||||
{750, 850, &ddr_cfg_regs_800},
|
||||
{1060, 1333, &ddr_cfg_regs_1333},
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
* Fixed sdram init -- doesn't use serial presence detect.
|
||||
*/
|
||||
phys_size_t fixed_sdram(void)
|
||||
{
|
||||
int i;
|
||||
char buf[32];
|
||||
fsl_ddr_cfg_regs_t ddr_cfg_regs;
|
||||
phys_size_t ddr_size;
|
||||
ulong ddr_freq, ddr_freq_mhz;
|
||||
|
||||
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));
|
||||
|
||||
for (i = 0; fixed_ddr_parm_0[i].max_freq > 0; i++) {
|
||||
if ((ddr_freq_mhz > fixed_ddr_parm_0[i].min_freq) &&
|
||||
(ddr_freq_mhz <= fixed_ddr_parm_0[i].max_freq)) {
|
||||
memcpy(&ddr_cfg_regs, fixed_ddr_parm_0[i].ddr_settings,
|
||||
sizeof(ddr_cfg_regs));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fixed_ddr_parm_0[i].max_freq == 0)
|
||||
panic("Unsupported DDR data rate %s MT/s data rate\n",
|
||||
strmhz(buf, ddr_freq));
|
||||
|
||||
ddr_size = (phys_size_t) CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
|
||||
fsl_ddr_set_memctl_regs(&ddr_cfg_regs, 0, 0);
|
||||
|
||||
if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE, ddr_size,
|
||||
LAW_TRGT_IF_DDR_1) < 0) {
|
||||
printf("ERROR setting Local Access Windows for DDR\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ddr_size;
|
||||
}
|
||||
|
||||
#else /* CONFIG_SYS_DDR_RAW_TIMING */
|
||||
/* Micron MT41J512M8_187E */
|
||||
dimm_params_t ddr_raw_timing = {
|
||||
.n_ranks = 1,
|
||||
.rank_density = 1073741824u,
|
||||
.capacity = 1073741824u,
|
||||
.primary_sdram_width = 32,
|
||||
.ec_sdram_width = 0,
|
||||
.registered_dimm = 0,
|
||||
.mirrored_dimm = 0,
|
||||
.n_row_addr = 15,
|
||||
.n_col_addr = 10,
|
||||
.n_banks_per_sdram_device = 8,
|
||||
.edc_config = 0,
|
||||
.burst_lengths_bitmask = 0x0c,
|
||||
|
||||
.tckmin_x_ps = 1870,
|
||||
.caslat_x = 0x1e << 4, /* 5,6,7,8 */
|
||||
.taa_ps = 13125,
|
||||
.twr_ps = 15000,
|
||||
.trcd_ps = 13125,
|
||||
.trrd_ps = 7500,
|
||||
.trp_ps = 13125,
|
||||
.tras_ps = 37500,
|
||||
.trc_ps = 50625,
|
||||
.trfc_ps = 160000,
|
||||
.twtr_ps = 7500,
|
||||
.trtp_ps = 7500,
|
||||
.refresh_rate_ps = 7800000,
|
||||
.tfaw_ps = 37500,
|
||||
};
|
||||
|
||||
int fsl_ddr_get_dimm_params(dimm_params_t *pdimm,
|
||||
unsigned int controller_number,
|
||||
unsigned int dimm_number)
|
||||
{
|
||||
const char dimm_model[] = "Fixed DDR on board";
|
||||
|
||||
if ((controller_number == 0) && (dimm_number == 0)) {
|
||||
memcpy(pdimm, &ddr_raw_timing, sizeof(dimm_params_t));
|
||||
memset(pdimm->mpart, 0, sizeof(pdimm->mpart));
|
||||
memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fsl_ddr_board_options(memctl_options_t *popts,
|
||||
dimm_params_t *pdimm,
|
||||
unsigned int ctrl_num)
|
||||
{
|
||||
int i;
|
||||
popts->clk_adjust = 6;
|
||||
popts->cpo_override = 0x1f;
|
||||
popts->write_data_delay = 2;
|
||||
popts->half_strength_driver_enable = 1;
|
||||
/* Write leveling override */
|
||||
popts->wrlvl_en = 1;
|
||||
popts->wrlvl_override = 1;
|
||||
popts->wrlvl_sample = 0xf;
|
||||
popts->wrlvl_start = 0x8;
|
||||
popts->trwt_override = 1;
|
||||
popts->trwt = 0;
|
||||
|
||||
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
|
||||
popts->cs_local_opts[i].odt_rd_cfg = FSL_DDR_ODT_NEVER;
|
||||
popts->cs_local_opts[i].odt_wr_cfg = FSL_DDR_ODT_CS;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SYS_DDR_RAW_TIMING */
|
||||
@@ -0,0 +1,28 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#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_128M, LAW_TRGT_IF_IFC),
|
||||
#ifdef CONFIG_SYS_NAND_BASE_PHYS
|
||||
SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_IFC),
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FPGA_BASE_PHYS
|
||||
SET_LAW(CONFIG_SYS_FPGA_BASE_PHYS, LAW_SIZE_128K, LAW_TRGT_IF_IFC),
|
||||
#endif
|
||||
SET_LAW(CONFIG_SYS_FSL_DSP_CCSRBAR_PHYS, LAW_SIZE_1M,
|
||||
LAW_TRGT_IF_DSP_CCSR),
|
||||
SET_LAW(CONFIG_SYS_FSL_DSP_M2_RAM_ADDR, LAW_SIZE_32M,
|
||||
LAW_TRGT_IF_OCN_DSP),
|
||||
SET_LAW(CONFIG_SYS_FSL_DSP_M3_RAM_ADDR, LAW_SIZE_32K,
|
||||
LAW_TRGT_IF_CLASS_DSP),
|
||||
SET_LAW(CONFIG_SYS_FSL_DSP_DDR_ADDR, LAW_SIZE_1G,
|
||||
LAW_TRGT_IF_CLASS_DSP)
|
||||
};
|
||||
|
||||
int num_law_entries = ARRAY_SIZE(law_table);
|
||||
@@ -0,0 +1,115 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <ns16550.h>
|
||||
#include <asm/io.h>
|
||||
#include <nand.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/fsl_law.h>
|
||||
#include <fsl_ddr_sdram.h>
|
||||
#include <asm/global_data.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static void sdram_init(void)
|
||||
{
|
||||
struct ccsr_ddr __iomem *ddr =
|
||||
(struct ccsr_ddr __iomem *)CONFIG_SYS_FSL_DDR_ADDR;
|
||||
#if CONFIG_DDR_CLK_FREQ == 100000000
|
||||
__raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds);
|
||||
__raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config);
|
||||
__raw_writel(CONFIG_SYS_DDR_CONTROL_800 | SDRAM_CFG_32_BE, &ddr->sdram_cfg);
|
||||
__raw_writel(CONFIG_SYS_DDR_CONTROL_2_800, &ddr->sdram_cfg_2);
|
||||
__raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init);
|
||||
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_3_800, &ddr->timing_cfg_3);
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_0_800, &ddr->timing_cfg_0);
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_1_800, &ddr->timing_cfg_1);
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_2_800, &ddr->timing_cfg_2);
|
||||
__raw_writel(CONFIG_SYS_DDR_MODE_1_800, &ddr->sdram_mode);
|
||||
__raw_writel(CONFIG_SYS_DDR_MODE_2_800, &ddr->sdram_mode_2);
|
||||
__raw_writel(CONFIG_SYS_DDR_INTERVAL_800, &ddr->sdram_interval);
|
||||
__raw_writel(CONFIG_SYS_DDR_CLK_CTRL_800, &ddr->sdram_clk_cntl);
|
||||
__raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL_800, &ddr->ddr_wrlvl_cntl);
|
||||
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_4_800, &ddr->timing_cfg_4);
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_5_800, &ddr->timing_cfg_5);
|
||||
__raw_writel(CONFIG_SYS_DDR_ZQ_CONTROL, &ddr->ddr_zq_cntl);
|
||||
#elif CONFIG_DDR_CLK_FREQ == 133000000
|
||||
__raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds);
|
||||
__raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config);
|
||||
__raw_writel(CONFIG_SYS_DDR_CONTROL_1333 | SDRAM_CFG_32_BE, &ddr->sdram_cfg);
|
||||
__raw_writel(CONFIG_SYS_DDR_CONTROL_2_1333, &ddr->sdram_cfg_2);
|
||||
__raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init);
|
||||
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_3_1333, &ddr->timing_cfg_3);
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_0_1333, &ddr->timing_cfg_0);
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_1_1333, &ddr->timing_cfg_1);
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_2_1333, &ddr->timing_cfg_2);
|
||||
__raw_writel(CONFIG_SYS_DDR_MODE_1_1333, &ddr->sdram_mode);
|
||||
__raw_writel(CONFIG_SYS_DDR_MODE_2_1333, &ddr->sdram_mode_2);
|
||||
__raw_writel(CONFIG_SYS_DDR_INTERVAL_1333, &ddr->sdram_interval);
|
||||
__raw_writel(CONFIG_SYS_DDR_CLK_CTRL_1333, &ddr->sdram_clk_cntl);
|
||||
__raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL_1333, &ddr->ddr_wrlvl_cntl);
|
||||
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_4_1333, &ddr->timing_cfg_4);
|
||||
__raw_writel(CONFIG_SYS_DDR_TIMING_5_1333, &ddr->timing_cfg_5);
|
||||
__raw_writel(CONFIG_SYS_DDR_ZQ_CONTROL, &ddr->ddr_zq_cntl);
|
||||
#else
|
||||
puts("Not a valid DDR Freq Found! Please Reset\n");
|
||||
#endif
|
||||
asm volatile("sync;isync");
|
||||
udelay(500);
|
||||
|
||||
/* Let the controller go */
|
||||
out_be32(&ddr->sdram_cfg, in_be32(&ddr->sdram_cfg) | SDRAM_CFG_MEM_EN);
|
||||
|
||||
set_next_law(CONFIG_SYS_NAND_DDR_LAW, LAW_SIZE_1G, LAW_TRGT_IF_DDR_1);
|
||||
}
|
||||
|
||||
void board_init_f(ulong bootflag)
|
||||
{
|
||||
u32 plat_ratio;
|
||||
ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
|
||||
|
||||
/* 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... ");
|
||||
|
||||
/* Initialize the DDR3 */
|
||||
sdram_init();
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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++);
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#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,
|
||||
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 + 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 + 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 + 12 * 1024,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, 0,
|
||||
0, 0, BOOKE_PAGESZ_4K, 0),
|
||||
|
||||
/* TLB 1 */
|
||||
/* *I*** - Covers boot page */
|
||||
SET_TLB_ENTRY(1, 0xfffff000, 0xfffff000,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 0, BOOKE_PAGESZ_4K, 1),
|
||||
#ifdef CONFIG_SPL_NAND_BOOT
|
||||
SET_TLB_ENTRY(1, 0xffffe000, 0xffffe000,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 10, BOOKE_PAGESZ_4K, 1),
|
||||
#endif
|
||||
|
||||
/* *I*G* - CCSRBAR (PA) */
|
||||
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_1M, 1),
|
||||
|
||||
/* CCSRBAR (DSP) */
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_FSL_DSP_CCSRBAR,
|
||||
CONFIG_SYS_FSL_DSP_CCSRBAR_PHYS, MAS3_SW|MAS3_SR,
|
||||
MAS2_I|MAS2_G, 0, 2, BOOKE_PAGESZ_1M, 1),
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS,
|
||||
MAS3_SX|MAS3_SR, MAS2_W|MAS2_G,
|
||||
0, 3, BOOKE_PAGESZ_64M, 1),
|
||||
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE + 0x4000000,
|
||||
CONFIG_SYS_FLASH_BASE_PHYS + 0x4000000,
|
||||
MAS3_SX|MAS3_SR, MAS2_W|MAS2_G,
|
||||
0, 4, BOOKE_PAGESZ_64M, 1),
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
/* *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, 6, 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, 7, BOOKE_PAGESZ_64K, 1),
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE, CONFIG_SYS_DDR_SDRAM_BASE,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_M,
|
||||
0, 8, BOOKE_PAGESZ_1G, 1),
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FPGA_BASE
|
||||
/* *I*G - Board FPGA */
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_FPGA_BASE, CONFIG_SYS_FPGA_BASE_PHYS,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 9, BOOKE_PAGESZ_256K, 1),
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_NAND_BASE_PHYS
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 5, BOOKE_PAGESZ_1M, 1),
|
||||
#endif
|
||||
};
|
||||
|
||||
int num_tlb_entries = ARRAY_SIZE(tlb_table);
|
||||
@@ -0,0 +1,14 @@
|
||||
if TARGET_C29XPCIE
|
||||
|
||||
config SYS_BOARD
|
||||
default "c29xpcie"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "freescale"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "C29XPCIE"
|
||||
|
||||
source "board/freescale/common/Kconfig"
|
||||
|
||||
endif
|
||||
@@ -0,0 +1,10 @@
|
||||
C29XPCIE BOARD
|
||||
M: Po Liu <po.liu@nxp.com>
|
||||
S: Maintained
|
||||
F: board/freescale/c29xpcie/
|
||||
F: include/configs/C29XPCIE.h
|
||||
F: configs/C29XPCIE_defconfig
|
||||
F: configs/C29XPCIE_NAND_defconfig
|
||||
F: configs/C29XPCIE_SPIFLASH_defconfig
|
||||
F: configs/C29XPCIE_NOR_SECBOOT_defconfig
|
||||
F: configs/C29XPCIE_SPIFLASH_SECBOOT_defconfig
|
||||
@@ -0,0 +1,25 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright 2013 Freescale Semiconductor, Inc.
|
||||
#
|
||||
|
||||
MINIMAL=
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
ifdef CONFIG_SPL_INIT_MINIMAL
|
||||
MINIMAL=y
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MINIMAL
|
||||
obj-y += spl_minimal.o
|
||||
else
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
obj-y += spl.o
|
||||
endif
|
||||
obj-y += c29xpcie.o
|
||||
obj-y += cpld.o
|
||||
obj-y += ddr.o
|
||||
endif
|
||||
|
||||
obj-y += law.o
|
||||
obj-y += tlb.o
|
||||
@@ -0,0 +1,100 @@
|
||||
Overview
|
||||
=========
|
||||
C29XPCIE board is a series of Freescale PCIe add-in cards to perform
|
||||
as public key crypto accelerator or secure key management module.
|
||||
It includes C293PCIE board, C293PCIE board and C291PCIE board.
|
||||
The Freescale C29x family is a high performance crypto co-processor.
|
||||
It combines a single e500v2 core with necessary SEC engines.
|
||||
(maximum core frequency 1000/1200 MHz).
|
||||
|
||||
The C29xPCIE board features are as follows:
|
||||
Memory subsystem:
|
||||
- 512Mbyte unbuffered DDR3 SDRAM discrete devices (32-bit bus)
|
||||
- 64 Mbyte NOR flash single-chip memory
|
||||
- 4 Gbyte NAND flash memory
|
||||
- 1 Mbit AT24C1024 I2C EEPROM
|
||||
- 16 Mbyte SPI memory
|
||||
|
||||
Interfaces:
|
||||
- 10/100/1000 BaseT Ethernet ports:
|
||||
- eTSEC1, RGMII: one 10/100/1000 port
|
||||
- eTSEC2, RGMII: one 10/100/1000 port
|
||||
- DUART interface:
|
||||
- DUART interface: supports two UARTs up to 115200 bps for
|
||||
console display
|
||||
|
||||
Board connectors:
|
||||
- Mini-ITX power supply connector
|
||||
- JTAG/COP for debugging
|
||||
|
||||
Physical Memory Map on C29xPCIE
|
||||
===============================
|
||||
Address Start Address End Memory type
|
||||
0x0_0000_0000 - 0x0_1fff_ffff 512MB DDR
|
||||
0xc_0000_0000 - 0xc_8fff_ffff 256MB PCIE memory
|
||||
0xf_ec00_0000 - 0xf_efff_ffff 64MB NOR flash
|
||||
0xf_ffb0_0000 - 0xf_ffb7_ffff 512KB SRAM
|
||||
0xf_ffc0_0000 - 0xf_ffc0_ffff 64KB PCIE IO
|
||||
0xf_ffdf_0000 - 0xf_ffdf_0fff 4KB CPLD
|
||||
0xf_ffe0_0000 - 0xf_ffef_ffff 1MB CCSR
|
||||
|
||||
Serial Port Configuration on C29xPCIE
|
||||
=====================================
|
||||
Configure the serial port of the attached computer with the following values:
|
||||
-Data rate: 115200 bps
|
||||
-Number of data bits: 8
|
||||
-Parity: None
|
||||
-Number of Stop bits: 1
|
||||
-Flow Control: Hardware/None
|
||||
|
||||
Settings of DIP-switch
|
||||
======================
|
||||
SW5[1:4]= 1111 and SW5[6]=0 for boot from 16bit NOR flash
|
||||
SW5[1:4]= 0110 and SW5[6]=0 for boot from SPI flash
|
||||
Note: 1 stands for 'off', 0 stands for 'on'
|
||||
|
||||
Build and program U-Boot to NOR flash
|
||||
==================================
|
||||
1. Build u-boot.bin image example:
|
||||
export ARCH=powerpc
|
||||
export CROSS_COMPILE=/your_path/powerpc-linux-gnu-
|
||||
make C293PCIE
|
||||
|
||||
2. Program u-boot.bin into NOR flash
|
||||
=> tftp $loadaddr $uboot
|
||||
=> protect off eff40000 +$filesize
|
||||
=> erase eff40000 +$filesize
|
||||
=> cp.b $loadaddr eff40000 $filesize
|
||||
|
||||
3. Check SW5[1:4]= 1111 and SW5[6]=0, then power on.
|
||||
|
||||
Alternate NOR bank
|
||||
==================
|
||||
There are four banks in C29XPCIE board, example to change bank booting:
|
||||
1. Program u-boot.bin into alternate NOR bank
|
||||
=> tftp $loadaddr $uboot
|
||||
=> protect off e9f40000 +$filesize
|
||||
=> erase e9f40000 +$filesize
|
||||
=> cp.b $loadaddr e9f40000 $filesize
|
||||
|
||||
2. Switch to alternate NOR bank
|
||||
=> cpld_cmd reset altbank [bank]
|
||||
- [bank] bank value select 1-4
|
||||
- bank 1 on the flash 0x0000000~0x0ffffff
|
||||
- bank 2 on the flash 0x1000000~0x1ffffff
|
||||
- bank 3 on the flash 0x2000000~0x2ffffff
|
||||
- bank 4 on the flash 0x3000000~0x3ffffff
|
||||
or set SW5[7]= ON/OFF and SW5[7]= ON/OFF, then power on again.
|
||||
|
||||
Build and program U-Boot to SPI flash
|
||||
==================================
|
||||
1. Build u-boot-spi.bin image
|
||||
make C29xPCIE_SPIFLASH_config; make
|
||||
Need the boot_format tool to generate u-boot-spi.bin from the u-boot.bin.
|
||||
|
||||
2. Program u-boot-spi.bin into SPI flash
|
||||
=> tftp $loadaddr $uboot-spi
|
||||
=> sf erase 0 100000
|
||||
=> sf write $loadaddr 0 $filesize
|
||||
|
||||
3. Check SW5[1:4]= 0110 and SW5[6]=0, then power on.
|
||||
@@ -0,0 +1,157 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <init.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/immap_85xx.h>
|
||||
#include <asm/io.h>
|
||||
#include <env.h>
|
||||
#include <miiphy.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
#include <fsl_mdio.h>
|
||||
#include <tsec.h>
|
||||
#include <mmc.h>
|
||||
#include <netdev.h>
|
||||
#include <pci.h>
|
||||
#include <fsl_ifc.h>
|
||||
#include <asm/fsl_pci.h>
|
||||
|
||||
#include "cpld.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int checkboard(void)
|
||||
{
|
||||
struct cpu_type *cpu = gd->arch.cpu;
|
||||
struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
|
||||
|
||||
printf("Board: %sPCIe, ", cpu->name);
|
||||
printf("CPLD Ver: 0x%02x\n", in_8(&cpld_data->cpldver));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
struct fsl_ifc ifc = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
|
||||
|
||||
/* Clock configuration to access CPLD using IFC(GPCM) */
|
||||
setbits_be32(&ifc.gregs->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_early_init_r(void)
|
||||
{
|
||||
const unsigned long flashbase = CONFIG_SYS_FLASH_BASE;
|
||||
int flash_esel = find_tlb_idx((void *)flashbase, 1);
|
||||
|
||||
/*
|
||||
* Remap Boot flash 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();
|
||||
|
||||
if (flash_esel == -1) {
|
||||
/* very unlikely unless something is messed up */
|
||||
puts("Error: Could not find TLB for FLASH BASE\n");
|
||||
flash_esel = 1; /* give our best effort to continue */
|
||||
} else {
|
||||
/* invalidate existing TLB entry for flash */
|
||||
disable_tlb(flash_esel);
|
||||
}
|
||||
|
||||
set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
|
||||
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, flash_esel, BOOKE_PAGESZ_64M, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
void pci_init_board(void)
|
||||
{
|
||||
fsl_pcie_init_board(0);
|
||||
}
|
||||
#endif /* ifdef CONFIG_PCI */
|
||||
|
||||
int board_eth_init(bd_t *bis)
|
||||
{
|
||||
#ifdef CONFIG_TSEC_ENET
|
||||
struct fsl_pq_mdio_info mdio_info;
|
||||
struct tsec_info_struct tsec_info[2];
|
||||
int num = 0;
|
||||
|
||||
#ifdef CONFIG_TSEC1
|
||||
SET_STD_TSEC_INFO(tsec_info[num], 1);
|
||||
num++;
|
||||
#endif
|
||||
#ifdef CONFIG_TSEC2
|
||||
SET_STD_TSEC_INFO(tsec_info[num], 2);
|
||||
num++;
|
||||
#endif
|
||||
if (!num) {
|
||||
printf("No TSECs initialized\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Register 1G MDIO bus */
|
||||
mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR;
|
||||
mdio_info.name = DEFAULT_MII_NAME;
|
||||
|
||||
fsl_pq_mdio_init(bis, &mdio_info);
|
||||
|
||||
tsec_eth_init(bis, tsec_info, num);
|
||||
#endif
|
||||
|
||||
return pci_eth_init(bis);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OF_BOARD_SETUP)
|
||||
void fdt_del_sec(void *blob, int offset)
|
||||
{
|
||||
int nodeoff = 0;
|
||||
|
||||
while ((nodeoff = fdt_node_offset_by_compat_reg(blob, "fsl,sec-v6.0",
|
||||
CONFIG_SYS_CCSRBAR_PHYS + CONFIG_SYS_FSL_SEC_OFFSET
|
||||
+ offset * CONFIG_SYS_FSL_SEC_IDX_OFFSET)) >= 0) {
|
||||
fdt_del_node(blob, nodeoff);
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
int ft_board_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
phys_addr_t base;
|
||||
phys_size_t size;
|
||||
struct cpu_type *cpu;
|
||||
|
||||
cpu = gd->arch.cpu;
|
||||
|
||||
ft_cpu_setup(blob, bd);
|
||||
|
||||
base = env_get_bootm_low();
|
||||
size = env_get_bootm_size();
|
||||
|
||||
#if defined(CONFIG_PCI)
|
||||
FT_FSL_PCI_SETUP;
|
||||
#endif
|
||||
|
||||
fdt_fixup_memory(blob, (u64)base, (u64)size);
|
||||
if (cpu->soc_ver == SVR_C291)
|
||||
fdt_del_sec(blob, 1);
|
||||
else if (cpu->soc_ver == SVR_C292)
|
||||
fdt_del_sec(blob, 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,132 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/**
|
||||
* Copyright 2013 Freescale Semiconductor
|
||||
* Author: Mingkai Hu <Mingkai.hu@freescale.com>
|
||||
* Po Liu <Po.Liu@freescale.com>
|
||||
*
|
||||
* This file provides support for the board-specific CPLD used on some Freescale
|
||||
* reference boards.
|
||||
*
|
||||
* The following macros need to be defined:
|
||||
*
|
||||
* CONFIG_SYS_CPLD_BASE - The virtual address of the base of the
|
||||
* CPLD register map
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "cpld.h"
|
||||
/**
|
||||
* Set the boot bank to the alternate bank
|
||||
*/
|
||||
void cpld_set_altbank(u8 banksel)
|
||||
{
|
||||
struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
|
||||
u8 reg11;
|
||||
|
||||
reg11 = in_8(&cpld_data->flhcsr);
|
||||
|
||||
switch (banksel) {
|
||||
case 1:
|
||||
out_8(&cpld_data->flhcsr, (reg11 & CPLD_BANKSEL_MASK)
|
||||
| CPLD_BANKSEL_EN | CPLD_SELECT_BANK1);
|
||||
break;
|
||||
case 2:
|
||||
out_8(&cpld_data->flhcsr, (reg11 & CPLD_BANKSEL_MASK)
|
||||
| CPLD_BANKSEL_EN | CPLD_SELECT_BANK2);
|
||||
break;
|
||||
case 3:
|
||||
out_8(&cpld_data->flhcsr, (reg11 & CPLD_BANKSEL_MASK)
|
||||
| CPLD_BANKSEL_EN | CPLD_SELECT_BANK3);
|
||||
break;
|
||||
case 4:
|
||||
out_8(&cpld_data->flhcsr, (reg11 & CPLD_BANKSEL_MASK)
|
||||
| CPLD_BANKSEL_EN | CPLD_SELECT_BANK4);
|
||||
break;
|
||||
default:
|
||||
printf("Invalid value! [1-4]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
udelay(100);
|
||||
do_reset(NULL, 0, 0, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the boot bank to the default bank
|
||||
*/
|
||||
void cpld_set_defbank(void)
|
||||
{
|
||||
cpld_set_altbank(4);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void cpld_dump_regs(void)
|
||||
{
|
||||
struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
|
||||
|
||||
printf("chipid1 = 0x%02x\n", in_8(&cpld_data->chipid1));
|
||||
printf("chipid2 = 0x%02x\n", in_8(&cpld_data->chipid2));
|
||||
printf("hwver = 0x%02x\n", in_8(&cpld_data->hwver));
|
||||
printf("cpldver = 0x%02x\n", in_8(&cpld_data->cpldver));
|
||||
printf("rstcon = 0x%02x\n", in_8(&cpld_data->rstcon));
|
||||
printf("flhcsr = 0x%02x\n", in_8(&cpld_data->flhcsr));
|
||||
printf("wdcsr = 0x%02x\n", in_8(&cpld_data->wdcsr));
|
||||
printf("wdkick = 0x%02x\n", in_8(&cpld_data->wdkick));
|
||||
printf("fancsr = 0x%02x\n", in_8(&cpld_data->fancsr));
|
||||
printf("ledcsr = 0x%02x\n", in_8(&cpld_data->ledcsr));
|
||||
printf("misc = 0x%02x\n", in_8(&cpld_data->misccsr));
|
||||
printf("bootor = 0x%02x\n", in_8(&cpld_data->bootor));
|
||||
printf("bootcfg1 = 0x%02x\n", in_8(&cpld_data->bootcfg1));
|
||||
printf("bootcfg2 = 0x%02x\n", in_8(&cpld_data->bootcfg2));
|
||||
printf("bootcfg3 = 0x%02x\n", in_8(&cpld_data->bootcfg3));
|
||||
printf("bootcfg4 = 0x%02x\n", in_8(&cpld_data->bootcfg4));
|
||||
putc('\n');
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
int cpld_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
int rc = 0;
|
||||
unsigned char value;
|
||||
|
||||
if (argc <= 1)
|
||||
return cmd_usage(cmdtp);
|
||||
|
||||
if (strcmp(argv[1], "reset") == 0) {
|
||||
if (!strcmp(argv[2], "altbank") && argv[3]) {
|
||||
value = (u8)simple_strtoul(argv[3], NULL, 16);
|
||||
cpld_set_altbank(value);
|
||||
} else if (!argv[2])
|
||||
cpld_set_defbank();
|
||||
else
|
||||
cmd_usage(cmdtp);
|
||||
#ifdef DEBUG
|
||||
} else if (strcmp(argv[1], "dump") == 0) {
|
||||
cpld_dump_regs();
|
||||
#endif
|
||||
} else
|
||||
rc = cmd_usage(cmdtp);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
cpld_cmd, CONFIG_SYS_MAXARGS, 1, cpld_cmd,
|
||||
"Reset the board using the CPLD sequencer",
|
||||
"reset - hard reset to default bank 4\n"
|
||||
"cpld_cmd reset altbank [bank]- reset to alternate bank\n"
|
||||
" - [bank] bank value select 1-4\n"
|
||||
" - bank 1 on the flash 0x0000000~0x0ffffff\n"
|
||||
" - bank 2 on the flash 0x1000000~0x1ffffff\n"
|
||||
" - bank 3 on the flash 0x2000000~0x2ffffff\n"
|
||||
" - bank 4 on the flash 0x3000000~0x3ffffff\n"
|
||||
#ifdef DEBUG
|
||||
"cpld_cmd dump - display the CPLD registers\n"
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/**
|
||||
* Copyright 2013 Freescale Semiconductor
|
||||
* Author: Mingkai Hu <Mingkai.Hu@freescale.com>
|
||||
* Po Liu <Po.Liu@freescale.com>
|
||||
*
|
||||
* This file provides support for the ngPIXIS, a board-specific FPGA used on
|
||||
* some Freescale reference boards.
|
||||
*/
|
||||
|
||||
/*
|
||||
* CPLD register set. Feel free to add board-specific #ifdefs where necessary.
|
||||
*/
|
||||
struct cpld_data {
|
||||
u8 chipid1; /* 0x0 - CPLD Chip ID1 Register */
|
||||
u8 chipid2; /* 0x1 - CPLD Chip ID2 Register */
|
||||
u8 hwver; /* 0x2 - Hardware Version Register */
|
||||
u8 cpldver; /* 0x3 - Software Version Register */
|
||||
u8 res[12];
|
||||
u8 rstcon; /* 0x10 - Reset control register */
|
||||
u8 flhcsr; /* 0x11 - Flash control and status Register */
|
||||
u8 wdcsr; /* 0x12 - Watchdog control and status Register */
|
||||
u8 wdkick; /* 0x13 - Watchdog kick Register */
|
||||
u8 fancsr; /* 0x14 - Fan control and status Register */
|
||||
u8 ledcsr; /* 0x15 - LED control and status Register */
|
||||
u8 misccsr; /* 0x16 - Misc control and status Register */
|
||||
u8 bootor; /* 0x17 - Boot configure override Register */
|
||||
u8 bootcfg1; /* 0x18 - Boot configure 1 Register */
|
||||
u8 bootcfg2; /* 0x19 - Boot configure 2 Register */
|
||||
u8 bootcfg3; /* 0x1a - Boot configure 3 Register */
|
||||
u8 bootcfg4; /* 0x1b - Boot configure 4 Register */
|
||||
};
|
||||
|
||||
#define CPLD_BANKSEL_EN 0x02
|
||||
#define CPLD_BANKSEL_MASK 0x3f
|
||||
#define CPLD_SELECT_BANK1 0xc0
|
||||
#define CPLD_SELECT_BANK2 0x80
|
||||
#define CPLD_SELECT_BANK3 0x40
|
||||
#define CPLD_SELECT_BANK4 0x00
|
||||
@@ -0,0 +1,106 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <i2c.h>
|
||||
#include <asm/fsl_law.h>
|
||||
#include <fsl_ddr_sdram.h>
|
||||
#include <fsl_ddr_dimm_params.h>
|
||||
|
||||
#include "cpld.h"
|
||||
|
||||
#define C29XPCIE_HARDWARE_REVA 0x40
|
||||
/*
|
||||
* Micron MT41J128M16HA-15E
|
||||
* */
|
||||
dimm_params_t ddr_raw_timing = {
|
||||
.n_ranks = 1,
|
||||
.rank_density = 536870912u,
|
||||
.capacity = 536870912u,
|
||||
.primary_sdram_width = 32,
|
||||
.ec_sdram_width = 8,
|
||||
.registered_dimm = 0,
|
||||
.mirrored_dimm = 0,
|
||||
.n_row_addr = 14,
|
||||
.n_col_addr = 10,
|
||||
.n_banks_per_sdram_device = 8,
|
||||
.edc_config = 2,
|
||||
.burst_lengths_bitmask = 0x0c,
|
||||
|
||||
.tckmin_x_ps = 1650,
|
||||
.caslat_x = 0x7e << 4, /* 5,6,7,8,9,10 */
|
||||
.taa_ps = 14050,
|
||||
.twr_ps = 15000,
|
||||
.trcd_ps = 13500,
|
||||
.trrd_ps = 75000,
|
||||
.trp_ps = 13500,
|
||||
.tras_ps = 40000,
|
||||
.trc_ps = 49500,
|
||||
.trfc_ps = 160000,
|
||||
.twtr_ps = 75000,
|
||||
.trtp_ps = 75000,
|
||||
.refresh_rate_ps = 7800000,
|
||||
.tfaw_ps = 30000,
|
||||
};
|
||||
|
||||
int fsl_ddr_get_dimm_params(dimm_params_t *pdimm,
|
||||
unsigned int controller_number,
|
||||
unsigned int dimm_number)
|
||||
{
|
||||
const char dimm_model[] = "Fixed DDR on board";
|
||||
|
||||
if ((controller_number == 0) && (dimm_number == 0)) {
|
||||
memcpy(pdimm, &ddr_raw_timing, sizeof(dimm_params_t));
|
||||
memset(pdimm->mpart, 0, sizeof(pdimm->mpart));
|
||||
memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fsl_ddr_board_options(memctl_options_t *popts,
|
||||
dimm_params_t *pdimm,
|
||||
unsigned int ctrl_num)
|
||||
{
|
||||
struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
|
||||
int i;
|
||||
|
||||
popts->clk_adjust = 4;
|
||||
popts->cpo_override = 0x1f;
|
||||
popts->write_data_delay = 4;
|
||||
popts->half_strength_driver_enable = 1;
|
||||
popts->bstopre = 0x3cf;
|
||||
popts->quad_rank_present = 1;
|
||||
popts->rtt_override = 1;
|
||||
popts->rtt_override_value = 1;
|
||||
popts->dynamic_power = 1;
|
||||
/* Write leveling override */
|
||||
popts->wrlvl_en = 1;
|
||||
popts->wrlvl_override = 1;
|
||||
popts->wrlvl_sample = 0xf;
|
||||
popts->wrlvl_start = 0x4;
|
||||
popts->trwt_override = 1;
|
||||
popts->trwt = 0;
|
||||
|
||||
if (in_8(&cpld_data->hwver) == C29XPCIE_HARDWARE_REVA)
|
||||
popts->ecc_mode = 0;
|
||||
|
||||
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
|
||||
popts->cs_local_opts[i].odt_rd_cfg = FSL_DDR_ODT_NEVER;
|
||||
popts->cs_local_opts[i].odt_wr_cfg = FSL_DDR_ODT_CS;
|
||||
}
|
||||
}
|
||||
|
||||
void get_spd(generic_spd_eeprom_t *spd, u8 i2c_address)
|
||||
{
|
||||
int ret = i2c_read(i2c_address, 0, 2, (uint8_t *)spd,
|
||||
sizeof(generic_spd_eeprom_t));
|
||||
|
||||
if (ret) {
|
||||
printf("DDR: failed to read SPD from address %u\n",
|
||||
i2c_address);
|
||||
memset(spd, 0, sizeof(generic_spd_eeprom_t));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#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_64M, LAW_TRGT_IF_IFC),
|
||||
SET_LAW(CONFIG_SYS_CPLD_BASE_PHYS, LAW_SIZE_64K, LAW_TRGT_IF_IFC),
|
||||
SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_64K, LAW_TRGT_IF_IFC),
|
||||
SET_LAW(CONFIG_SYS_PLATFORM_SRAM_BASE_PHYS, LAW_SIZE_512K,
|
||||
LAW_TRGT_IF_PLATFORM_SRAM),
|
||||
};
|
||||
|
||||
int num_law_entries = ARRAY_SIZE(law_table);
|
||||
@@ -0,0 +1,79 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <console.h>
|
||||
#include <env_internal.h>
|
||||
#include <ns16550.h>
|
||||
#include <malloc.h>
|
||||
#include <mmc.h>
|
||||
#include <nand.h>
|
||||
#include <i2c.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
phys_size_t get_effective_memsize(void)
|
||||
{
|
||||
return CONFIG_SYS_L2_SIZE;
|
||||
}
|
||||
|
||||
void board_init_f(ulong bootflag)
|
||||
{
|
||||
u32 plat_ratio;
|
||||
ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
|
||||
|
||||
console_init_f();
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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;
|
||||
|
||||
arch_cpu_init();
|
||||
get_clocks();
|
||||
mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR,
|
||||
CONFIG_SPL_RELOC_MALLOC_SIZE);
|
||||
gd->flags |= GD_FLG_FULL_MALLOC_INIT;
|
||||
|
||||
/* relocate environment function pointers etc. */
|
||||
nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,
|
||||
(uchar *)SPL_ENV_ADDR);
|
||||
gd->env_addr = (ulong)(SPL_ENV_ADDR);
|
||||
gd->env_valid = ENV_VALID;
|
||||
|
||||
i2c_init_all();
|
||||
|
||||
dram_init();
|
||||
|
||||
#ifdef CONFIG_SPL_NAND_BOOT
|
||||
puts("TPL\n");
|
||||
#else
|
||||
puts("SPL\n");
|
||||
#endif
|
||||
|
||||
nand_boot();
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc85xx.h>
|
||||
#include <asm/io.h>
|
||||
#include <ns16550.h>
|
||||
#include <nand.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/immap_85xx.h>
|
||||
#include <asm/fsl_law.h>
|
||||
#include <asm/global_data.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
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...\n");
|
||||
|
||||
/* 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("SPL\n");
|
||||
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++);
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#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,
|
||||
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 + 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 + 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 + 12 * 1024,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, 0,
|
||||
0, 0, BOOKE_PAGESZ_4K, 0),
|
||||
|
||||
/* TLB 1 */
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS,
|
||||
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 0, BOOKE_PAGESZ_1M, 1),
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS,
|
||||
MAS3_SX|MAS3_SR, MAS2_W|MAS2_G,
|
||||
0, 1, BOOKE_PAGESZ_64M, 1),
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT, CONFIG_SYS_PCIE1_MEM_PHYS,
|
||||
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 2, BOOKE_PAGESZ_256M, 1),
|
||||
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_IO_VIRT, CONFIG_SYS_PCIE1_IO_PHYS,
|
||||
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 3, BOOKE_PAGESZ_256K, 1),
|
||||
#endif
|
||||
#endif
|
||||
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_CPLD_BASE, CONFIG_SYS_CPLD_BASE_PHYS,
|
||||
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 4, BOOKE_PAGESZ_64K, 1),
|
||||
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 5, BOOKE_PAGESZ_64K, 1),
|
||||
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_PLATFORM_SRAM_BASE,
|
||||
CONFIG_SYS_PLATFORM_SRAM_BASE_PHYS,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, 0,
|
||||
0, 6, BOOKE_PAGESZ_256K, 1),
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_PLATFORM_SRAM_BASE + 0x40000,
|
||||
CONFIG_SYS_PLATFORM_SRAM_BASE_PHYS + 0x40000,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, 0,
|
||||
0, 7, BOOKE_PAGESZ_256K, 1),
|
||||
|
||||
#if defined(CONFIG_SYS_RAMBOOT) || \
|
||||
(defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD))
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE,
|
||||
CONFIG_SYS_DDR_SDRAM_BASE,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_M,
|
||||
0, 8, BOOKE_PAGESZ_256M, 1),
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE + 0x10000000,
|
||||
CONFIG_SYS_DDR_SDRAM_BASE + 0x10000000,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_M,
|
||||
0, 9, BOOKE_PAGESZ_256M, 1),
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_INIT_L2_ADDR
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_INIT_L2_ADDR, CONFIG_SYS_INIT_L2_ADDR_PHYS,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_G,
|
||||
0, 12, BOOKE_PAGESZ_256K, 1)
|
||||
#endif
|
||||
};
|
||||
|
||||
int num_tlb_entries = ARRAY_SIZE(tlb_table);
|
||||
@@ -0,0 +1,38 @@
|
||||
config CHAIN_OF_TRUST
|
||||
depends on !FIT_SIGNATURE && NXP_ESBC
|
||||
imply CMD_BLOB
|
||||
imply CMD_HASH if ARM
|
||||
select FSL_CAAM
|
||||
select SPL_BOARD_INIT if (ARM && SPL)
|
||||
select SHA_HW_ACCEL
|
||||
select SHA_PROG_HW_ACCEL
|
||||
select ENV_IS_NOWHERE
|
||||
select CMD_EXT4 if ARM
|
||||
select CMD_EXT4_WRITE if ARM
|
||||
bool
|
||||
default y
|
||||
|
||||
config CMD_ESBC_VALIDATE
|
||||
bool "Enable the 'esbc_validate' and 'esbc_halt' commands"
|
||||
default y if CHAIN_OF_TRUST
|
||||
help
|
||||
This option enables two commands used for secure booting:
|
||||
|
||||
esbc_validate - validate signature using RSA verification
|
||||
esbc_halt - put the core in spin loop (Secure Boot Only)
|
||||
|
||||
config VOL_MONITOR_LTC3882_READ
|
||||
depends on VID
|
||||
bool "Enable the LTC3882 voltage monitor read"
|
||||
default n
|
||||
help
|
||||
This option enables LTC3882 voltage monitor read
|
||||
functionality. It is used by common VID driver.
|
||||
|
||||
config VOL_MONITOR_LTC3882_SET
|
||||
depends on VID
|
||||
bool "Enable the LTC3882 voltage monitor set"
|
||||
default n
|
||||
help
|
||||
This option enables LTC3882 voltage monitor set
|
||||
functionality. It is used by common VID driver.
|
||||
@@ -0,0 +1,83 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# (C) Copyright 2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
|
||||
MINIMAL=
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
ifdef CONFIG_SPL_INIT_MINIMAL
|
||||
MINIMAL=y
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MINIMAL
|
||||
# necessary to create built-in.o
|
||||
obj- := __dummy__.o
|
||||
else
|
||||
obj-$(CONFIG_FSL_CADMUS) += cadmus.o
|
||||
obj-$(CONFIG_FSL_VIA) += cds_via.o
|
||||
obj-$(CONFIG_FMAN_ENET) += fman.o
|
||||
obj-$(CONFIG_FSL_PIXIS) += pixis.o
|
||||
ifndef CONFIG_SPL_BUILD
|
||||
obj-$(CONFIG_FSL_NGPIXIS) += ngpixis.o
|
||||
endif
|
||||
obj-$(CONFIG_VID) += vid.o
|
||||
obj-$(CONFIG_FSL_QIXIS) += qixis.o
|
||||
obj-$(CONFIG_PQ_MDS_PIB) += pq-mds-pib.o
|
||||
ifndef CONFIG_SPL_BUILD
|
||||
obj-$(CONFIG_ID_EEPROM) += sys_eeprom.o
|
||||
endif
|
||||
obj-$(CONFIG_FSL_SGMII_RISER) += sgmii_riser.o
|
||||
ifndef CONFIG_RAMBOOT_PBL
|
||||
obj-$(CONFIG_FSL_FIXED_MMC_LOCATION) += sdhc_boot.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_FSL_DIU_CH7301) += diu_ch7301.o
|
||||
|
||||
ifdef CONFIG_ARM
|
||||
obj-$(CONFIG_DEEP_SLEEP) += arm_sleep.o
|
||||
else
|
||||
obj-$(CONFIG_DEEP_SLEEP) += mpc85xx_sleep.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_FSL_DCU_SII9022A) += dcu_sii9022a.o
|
||||
|
||||
obj-$(CONFIG_TARGET_MPC8541CDS) += cds_pci_ft.o
|
||||
obj-$(CONFIG_TARGET_MPC8548CDS) += cds_pci_ft.o
|
||||
obj-$(CONFIG_TARGET_MPC8555CDS) += cds_pci_ft.o
|
||||
|
||||
obj-$(CONFIG_TARGET_MPC8536DS) += ics307_clk.o
|
||||
obj-$(CONFIG_TARGET_MPC8572DS) += ics307_clk.o
|
||||
obj-$(CONFIG_TARGET_P1022DS) += ics307_clk.o
|
||||
obj-$(CONFIG_P2020DS) += ics307_clk.o
|
||||
obj-$(CONFIG_TARGET_P3041DS) += ics307_clk.o
|
||||
obj-$(CONFIG_TARGET_P4080DS) += ics307_clk.o
|
||||
obj-$(CONFIG_TARGET_P5020DS) += ics307_clk.o
|
||||
obj-$(CONFIG_TARGET_P5040DS) += ics307_clk.o
|
||||
obj-$(CONFIG_VSC_CROSSBAR) += vsc3316_3308.o
|
||||
obj-$(CONFIG_IDT8T49N222A) += idt8t49n222a_serdes_clk.o
|
||||
obj-$(CONFIG_ZM7300) += zm7300.o
|
||||
obj-$(CONFIG_POWER_PFUZE100) += pfuze.o
|
||||
obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze.o
|
||||
obj-$(CONFIG_POWER_MC34VR500) += mc34vr500.o
|
||||
|
||||
obj-$(CONFIG_LS102XA_STREAM_ID) += ls102xa_stream_id.o
|
||||
|
||||
obj-$(CONFIG_EMC2305) += emc2305.o
|
||||
|
||||
# deal with common files for P-series corenet based devices
|
||||
obj-$(CONFIG_TARGET_P2041RDB) += p_corenet/
|
||||
obj-$(CONFIG_TARGET_P3041DS) += p_corenet/
|
||||
obj-$(CONFIG_TARGET_P4080DS) += p_corenet/
|
||||
obj-$(CONFIG_TARGET_P5020DS) += p_corenet/
|
||||
obj-$(CONFIG_TARGET_P5040DS) += p_corenet/
|
||||
|
||||
obj-$(CONFIG_LAYERSCAPE_NS_ACCESS) += ns_access.o
|
||||
|
||||
ifdef CONFIG_NXP_ESBC
|
||||
obj-$(CONFIG_CMD_ESBC_VALIDATE) += fsl_validate.o cmd_esbc_validate.o
|
||||
endif
|
||||
obj-$(CONFIG_CHAIN_OF_TRUST) += fsl_chain_of_trust.o
|
||||
|
||||
endif
|
||||
@@ -0,0 +1,129 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#ifndef CONFIG_ARMV7_NONSEC
|
||||
#error " Deep sleep needs non-secure mode support. "
|
||||
#else
|
||||
#include <asm/secure.h>
|
||||
#endif
|
||||
#include <asm/armv7.h>
|
||||
|
||||
#if defined(CONFIG_ARCH_LS1021A)
|
||||
#include <asm/arch/immap_ls102xa.h>
|
||||
#endif
|
||||
|
||||
#include "sleep.h"
|
||||
#ifdef CONFIG_U_QE
|
||||
#include <fsl_qe.h>
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
void __weak board_mem_sleep_setup(void)
|
||||
{
|
||||
}
|
||||
|
||||
void __weak board_sleep_prepare(void)
|
||||
{
|
||||
}
|
||||
|
||||
bool is_warm_boot(void)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
|
||||
|
||||
if (in_be32(&gur->crstsr) & DCFG_CCSR_CRSTSR_WDRFR)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fsl_dp_disable_console(void)
|
||||
{
|
||||
gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE;
|
||||
}
|
||||
|
||||
/*
|
||||
* When wakeup from deep sleep, the first 128 bytes space
|
||||
* will be used to do DDR training which corrupts the data
|
||||
* in there. This function will restore them.
|
||||
*/
|
||||
static void dp_ddr_restore(void)
|
||||
{
|
||||
u64 *src, *dst;
|
||||
int i;
|
||||
struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
|
||||
|
||||
/* get the address of ddr date from SPARECR3 */
|
||||
src = (u64 *)in_le32(&scfg->sparecr[2]);
|
||||
dst = (u64 *)CONFIG_SYS_SDRAM_BASE;
|
||||
|
||||
for (i = 0; i < DDR_BUFF_LEN / 8; i++)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ARMV7_PSCI) && defined(CONFIG_ARCH_LS1021A)
|
||||
void ls1_psci_resume_fixup(void)
|
||||
{
|
||||
u32 tmp;
|
||||
struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
|
||||
|
||||
#ifdef QIXIS_BASE
|
||||
void *qixis_base = (void *)QIXIS_BASE;
|
||||
|
||||
/* Pull on PCIe RST# */
|
||||
out_8(qixis_base + QIXIS_RST_FORCE_3, 0);
|
||||
|
||||
/* disable deep sleep signals in FPGA */
|
||||
tmp = in_8(qixis_base + QIXIS_PWR_CTL2);
|
||||
tmp &= ~QIXIS_PWR_CTL2_PCTL;
|
||||
out_8(qixis_base + QIXIS_PWR_CTL2, tmp);
|
||||
#endif
|
||||
|
||||
/* Disable wakeup interrupt during deep sleep */
|
||||
out_be32(&scfg->pmcintecr, 0);
|
||||
/* Clear PMC interrupt status */
|
||||
out_be32(&scfg->pmcintsr, 0xffffffff);
|
||||
|
||||
/* Disable Warm Device Reset */
|
||||
tmp = in_be32(&scfg->dpslpcr);
|
||||
tmp &= ~SCFG_DPSLPCR_WDRR_EN;
|
||||
out_be32(&scfg->dpslpcr, tmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void dp_resume_prepare(void)
|
||||
{
|
||||
dp_ddr_restore();
|
||||
board_sleep_prepare();
|
||||
armv7_init_nonsec();
|
||||
#ifdef CONFIG_U_QE
|
||||
u_qe_resume();
|
||||
#endif
|
||||
#if defined(CONFIG_ARMV7_PSCI) && defined(CONFIG_ARCH_LS1021A)
|
||||
ls1_psci_resume_fixup();
|
||||
#endif
|
||||
}
|
||||
|
||||
int fsl_dp_resume(void)
|
||||
{
|
||||
u32 start_addr;
|
||||
void (*kernel_resume)(void);
|
||||
struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
|
||||
|
||||
if (!is_warm_boot())
|
||||
return 0;
|
||||
|
||||
dp_resume_prepare();
|
||||
|
||||
/* Get the entry address and jump to kernel */
|
||||
start_addr = in_le32(&scfg->sparecr[3]);
|
||||
debug("Entry address is 0x%08x\n", start_addr);
|
||||
kernel_resume = (void (*)(void))start_addr;
|
||||
secure_ram_addr(_do_nonsec_entry)(kernel_resume, 0, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2004, 2011 Freescale Semiconductor.
|
||||
*/
|
||||
|
||||
|
||||
#include <common.h>
|
||||
|
||||
|
||||
/*
|
||||
* CADMUS Board System Registers
|
||||
*/
|
||||
#ifndef CONFIG_SYS_CADMUS_BASE_REG
|
||||
#define CONFIG_SYS_CADMUS_BASE_REG (CADMUS_BASE_ADDR + 0x4000)
|
||||
#endif
|
||||
|
||||
typedef struct cadmus_reg {
|
||||
u_char cm_ver; /* Board version */
|
||||
u_char cm_csr; /* General control/status */
|
||||
u_char cm_rst; /* Reset control */
|
||||
u_char cm_hsclk; /* High speed clock */
|
||||
u_char cm_hsxclk; /* High speed clock extended */
|
||||
u_char cm_led; /* LED data */
|
||||
u_char cm_pci; /* PCI control/status */
|
||||
u_char cm_dma; /* DMA control */
|
||||
u_char cm_reserved[248]; /* Total 256 bytes */
|
||||
} cadmus_reg_t;
|
||||
|
||||
|
||||
unsigned int
|
||||
get_board_version(void)
|
||||
{
|
||||
volatile cadmus_reg_t *cadmus = (cadmus_reg_t *)CONFIG_SYS_CADMUS_BASE_REG;
|
||||
|
||||
return cadmus->cm_ver;
|
||||
}
|
||||
|
||||
|
||||
unsigned long
|
||||
get_clock_freq(void)
|
||||
{
|
||||
volatile cadmus_reg_t *cadmus = (cadmus_reg_t *)CONFIG_SYS_CADMUS_BASE_REG;
|
||||
|
||||
uint pci1_speed = (cadmus->cm_pci >> 2) & 0x3; /* PSPEED in [4:5] */
|
||||
|
||||
if (pci1_speed == 0) {
|
||||
return 33333333;
|
||||
} else if (pci1_speed == 1) {
|
||||
return 66666666;
|
||||
} else {
|
||||
/* Really, unknown. Be safe? */
|
||||
return 33333333;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
get_pci_slot(void)
|
||||
{
|
||||
volatile cadmus_reg_t *cadmus = (cadmus_reg_t *)CONFIG_SYS_CADMUS_BASE_REG;
|
||||
|
||||
/*
|
||||
* PCI slot in USER bits CSR[6:7] by convention.
|
||||
*/
|
||||
return ((cadmus->cm_csr >> 6) & 0x3) + 1;
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
get_pci_dual(void)
|
||||
{
|
||||
volatile cadmus_reg_t *cadmus = (cadmus_reg_t *)CONFIG_SYS_CADMUS_BASE_REG;
|
||||
|
||||
/*
|
||||
* PCI DUAL in CM_PCI[3]
|
||||
*/
|
||||
return cadmus->cm_pci & 0x10;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2004 Freescale Semiconductor.
|
||||
*/
|
||||
|
||||
#ifndef __CADMUS_H_
|
||||
#define __CADMUS_H_
|
||||
|
||||
|
||||
/*
|
||||
* CADMUS Board System Register interface.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Returns board version register.
|
||||
*/
|
||||
extern unsigned int get_board_version(void);
|
||||
|
||||
/*
|
||||
* Returns either 33000000 or 66000000 as the SYS_CLK_FREQ.
|
||||
*/
|
||||
extern unsigned long get_clock_freq(void);
|
||||
|
||||
|
||||
/*
|
||||
* Returns 1 - 4, as found in the USER CSR[6:7] bits.
|
||||
*/
|
||||
extern unsigned int get_pci_slot(void);
|
||||
|
||||
|
||||
/*
|
||||
* Returns PCI DUAL as found in CM_PCI[3].
|
||||
*/
|
||||
extern unsigned int get_pci_dual(void);
|
||||
|
||||
|
||||
#endif /* __CADMUS_H_ */
|
||||
@@ -0,0 +1,77 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2004 Freescale Semiconductor.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
#include "cadmus.h"
|
||||
|
||||
#if defined(CONFIG_OF_BOARD_SETUP)
|
||||
#if defined(CONFIG_PCI) && !defined(CONFIG_DM_PCI)
|
||||
static void cds_pci_fixup(void *blob)
|
||||
{
|
||||
int node;
|
||||
const char *path;
|
||||
int len, slot, i;
|
||||
u32 *map = NULL, *piccells = NULL;
|
||||
int off, cells;
|
||||
|
||||
node = fdt_path_offset(blob, "/aliases");
|
||||
if (node >= 0) {
|
||||
path = fdt_getprop(blob, node, "pci0", NULL);
|
||||
if (path) {
|
||||
node = fdt_path_offset(blob, path);
|
||||
if (node >= 0) {
|
||||
map = fdt_getprop_w(blob, node, "interrupt-map", &len);
|
||||
}
|
||||
/* Each item in "interrupt-map" property is translated with
|
||||
* following cells:
|
||||
* PCI #address-cells, PCI #interrupt-cells,
|
||||
* PIC address, PIC #address-cells, PIC #interrupt-cells.
|
||||
*/
|
||||
cells = fdt_getprop_u32_default(blob, path, "#address-cells", 1);
|
||||
cells += fdt_getprop_u32_default(blob, path, "#interrupt-cells", 1);
|
||||
off = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*(map+cells)));
|
||||
if (off <= 0)
|
||||
return;
|
||||
cells += 1;
|
||||
piccells = (u32 *)fdt_getprop(blob, off, "#address-cells", NULL);
|
||||
if (piccells == NULL)
|
||||
return;
|
||||
cells += *piccells;
|
||||
piccells = (u32 *)fdt_getprop(blob, off, "#interrupt-cells", NULL);
|
||||
if (piccells == NULL)
|
||||
return;
|
||||
cells += *piccells;
|
||||
}
|
||||
}
|
||||
|
||||
if (map) {
|
||||
len /= sizeof(u32);
|
||||
|
||||
slot = get_pci_slot();
|
||||
|
||||
for (i=0;i<len;i+=cells) {
|
||||
/* We rotate the interrupt pins so that the mapping
|
||||
* changes depending on the slot the carrier card is in.
|
||||
*/
|
||||
map[3] = ((map[3] + slot - 2) % 4) + 1;
|
||||
map+=cells;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int ft_board_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
ft_cpu_setup(blob, bd);
|
||||
#if defined(CONFIG_PCI) && !defined(CONFIG_DM_PCI)
|
||||
ft_pci_setup(blob, bd);
|
||||
cds_pci_fixup(blob);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,92 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2006 Freescale Semiconductor.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <pci.h>
|
||||
|
||||
/* Config the VIA chip */
|
||||
void mpc85xx_config_via(struct pci_controller *hose,
|
||||
pci_dev_t dev, struct pci_config_table *tab)
|
||||
{
|
||||
pci_dev_t bridge;
|
||||
unsigned int cmdstat;
|
||||
|
||||
/* Enable USB and IDE functions */
|
||||
pci_hose_write_config_byte(hose, dev, 0x48, 0x08);
|
||||
|
||||
pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
|
||||
cmdstat |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY| PCI_COMMAND_MASTER;
|
||||
pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat);
|
||||
pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
|
||||
pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
|
||||
|
||||
/*
|
||||
* Force the backplane P2P bridge to have a window
|
||||
* open from 0x00000000-0x00001fff in PCI I/O space.
|
||||
* This allows legacy I/O (i8259, etc) on the VIA
|
||||
* southbridge to be accessed.
|
||||
*/
|
||||
bridge = PCI_BDF(0,BRIDGE_ID,0);
|
||||
pci_hose_write_config_byte(hose, bridge, PCI_IO_BASE, 0);
|
||||
pci_hose_write_config_word(hose, bridge, PCI_IO_BASE_UPPER16, 0);
|
||||
pci_hose_write_config_byte(hose, bridge, PCI_IO_LIMIT, 0x10);
|
||||
pci_hose_write_config_word(hose, bridge, PCI_IO_LIMIT_UPPER16, 0);
|
||||
}
|
||||
|
||||
/* Function 1, IDE */
|
||||
void mpc85xx_config_via_usbide(struct pci_controller *hose,
|
||||
pci_dev_t dev, struct pci_config_table *tab)
|
||||
{
|
||||
pciauto_config_device(hose, dev);
|
||||
/*
|
||||
* Since the P2P window was forced to cover the fixed
|
||||
* legacy I/O addresses, it is necessary to manually
|
||||
* place the base addresses for the IDE and USB functions
|
||||
* within this window.
|
||||
*/
|
||||
pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0x1ff8);
|
||||
pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_1, 0x1ff4);
|
||||
pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_2, 0x1fe8);
|
||||
pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_3, 0x1fe4);
|
||||
pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_4, 0x1fd0);
|
||||
}
|
||||
|
||||
/* Function 2, USB ports 0-1 */
|
||||
void mpc85xx_config_via_usb(struct pci_controller *hose,
|
||||
pci_dev_t dev, struct pci_config_table *tab)
|
||||
{
|
||||
pciauto_config_device(hose, dev);
|
||||
|
||||
pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_4, 0x1fa0);
|
||||
}
|
||||
|
||||
/* Function 3, USB ports 2-3 */
|
||||
void mpc85xx_config_via_usb2(struct pci_controller *hose,
|
||||
pci_dev_t dev, struct pci_config_table *tab)
|
||||
{
|
||||
pciauto_config_device(hose, dev);
|
||||
|
||||
pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_4, 0x1f80);
|
||||
}
|
||||
|
||||
/* Function 5, Power Management */
|
||||
void mpc85xx_config_via_power(struct pci_controller *hose,
|
||||
pci_dev_t dev, struct pci_config_table *tab)
|
||||
{
|
||||
pciauto_config_device(hose, dev);
|
||||
|
||||
pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0x1e00);
|
||||
pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_1, 0x1dfc);
|
||||
pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_2, 0x1df8);
|
||||
}
|
||||
|
||||
/* Function 6, AC97 Interface */
|
||||
void mpc85xx_config_via_ac97(struct pci_controller *hose,
|
||||
pci_dev_t dev, struct pci_config_table *tab)
|
||||
{
|
||||
pciauto_config_device(hose, dev);
|
||||
|
||||
pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0x1c00);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <env.h>
|
||||
#include <fsl_validate.h>
|
||||
|
||||
int do_esbc_halt(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
if (fsl_check_boot_mode_secure() == 0) {
|
||||
printf("Boot Mode is Non-Secure. Not entering spin loop.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("Core is entering spin loop.\n");
|
||||
loop:
|
||||
goto loop;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
static int do_esbc_validate(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
char *hash_str = NULL;
|
||||
uintptr_t haddr;
|
||||
int ret;
|
||||
uintptr_t img_addr = 0;
|
||||
char buf[20];
|
||||
|
||||
if (argc < 2)
|
||||
return cmd_usage(cmdtp);
|
||||
else if (argc > 2)
|
||||
/* Second arg - Optional - Hash Str*/
|
||||
hash_str = argv[2];
|
||||
|
||||
/* First argument - header address -32/64bit */
|
||||
haddr = (uintptr_t)simple_strtoul(argv[1], NULL, 16);
|
||||
|
||||
/* With esbc_validate command, Image address must be
|
||||
* part of header. So, the function is called
|
||||
* by passing this argument as 0.
|
||||
*/
|
||||
ret = fsl_secboot_validate(haddr, hash_str, &img_addr);
|
||||
|
||||
/* Need to set "img_addr" even if validation failure.
|
||||
* Required when SB_EN in RCW set and non-fatal error
|
||||
* to continue U-Boot
|
||||
*/
|
||||
sprintf(buf, "%lx", img_addr);
|
||||
env_set("img_addr", buf);
|
||||
|
||||
if (ret)
|
||||
return 1;
|
||||
|
||||
printf("esbc_validate command successful\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
static char esbc_validate_help_text[] =
|
||||
"esbc_validate hdr_addr <hash_val> - Validates signature using\n"
|
||||
" RSA verification\n"
|
||||
" $hdr_addr Address of header of the image\n"
|
||||
" to be validated.\n"
|
||||
" $hash_val -Optional\n"
|
||||
" It provides Hash of public/srk key to be\n"
|
||||
" used to verify signature.\n";
|
||||
|
||||
U_BOOT_CMD(
|
||||
esbc_validate, 3, 0, do_esbc_validate,
|
||||
"Validates signature on a given image using RSA verification",
|
||||
esbc_validate_help_text
|
||||
);
|
||||
|
||||
U_BOOT_CMD(
|
||||
esbc_halt, 1, 0, do_esbc_halt,
|
||||
"Put the core in spin loop (Secure Boot Only)",
|
||||
""
|
||||
);
|
||||
#endif
|
||||
@@ -0,0 +1,152 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <common.h>
|
||||
#include <fsl_dcu_fb.h>
|
||||
#include <i2c.h>
|
||||
#include <linux/fb.h>
|
||||
|
||||
#define PIXEL_CLK_LSB_REG 0x00
|
||||
#define PIXEL_CLK_MSB_REG 0x01
|
||||
#define VERT_FREQ_LSB_REG 0x02
|
||||
#define VERT_FREQ_MSB_REG 0x03
|
||||
#define TOTAL_PIXELS_LSB_REG 0x04
|
||||
#define TOTAL_PIXELS_MSB_REG 0x05
|
||||
#define TOTAL_LINES_LSB_REG 0x06
|
||||
#define TOTAL_LINES_MSB_REG 0x07
|
||||
#define TPI_INBUS_FMT_REG 0x08
|
||||
#define TPI_INPUT_FMT_REG 0x09
|
||||
#define TPI_OUTPUT_FMT_REG 0x0A
|
||||
#define TPI_SYS_CTRL_REG 0x1A
|
||||
#define TPI_PWR_STAT_REG 0x1E
|
||||
#define TPI_AUDIO_HANDING_REG 0x25
|
||||
#define TPI_AUDIO_INTF_REG 0x26
|
||||
#define TPI_AUDIO_FREQ_REG 0x27
|
||||
#define TPI_SET_PAGE_REG 0xBC
|
||||
#define TPI_SET_OFFSET_REG 0xBD
|
||||
#define TPI_RW_ACCESS_REG 0xBE
|
||||
#define TPI_TRANS_MODE_REG 0xC7
|
||||
|
||||
#define TPI_INBUS_CLOCK_RATIO_1 (1 << 6)
|
||||
#define TPI_INBUS_FULL_PIXEL_WIDE (1 << 5)
|
||||
#define TPI_INBUS_RISING_EDGE (1 << 4)
|
||||
#define TPI_INPUT_CLR_DEPTH_8BIT (0 << 6)
|
||||
#define TPI_INPUT_VRANGE_EXPAN_AUTO (0 << 2)
|
||||
#define TPI_INPUT_CLR_RGB (0 << 0)
|
||||
#define TPI_OUTPUT_CLR_DEPTH_8BIT (0 << 6)
|
||||
#define TPI_OUTPUT_VRANGE_COMPRE_AUTO (0 << 2)
|
||||
#define TPI_OUTPUT_CLR_HDMI_RGB (0 << 0)
|
||||
#define TPI_SYS_TMDS_OUTPUT (0 << 4)
|
||||
#define TPI_SYS_AV_NORAML (0 << 3)
|
||||
#define TPI_SYS_AV_MUTE (1 << 3)
|
||||
#define TPI_SYS_DVI_MODE (0 << 0)
|
||||
#define TPI_SYS_HDMI_MODE (1 << 0)
|
||||
#define TPI_PWR_STAT_MASK (3 << 0)
|
||||
#define TPI_PWR_STAT_D0 (0 << 0)
|
||||
#define TPI_AUDIO_PASS_BASIC (0 << 0)
|
||||
#define TPI_AUDIO_INTF_I2S (2 << 6)
|
||||
#define TPI_AUDIO_INTF_NORMAL (0 << 4)
|
||||
#define TPI_AUDIO_TYPE_PCM (1 << 0)
|
||||
#define TPI_AUDIO_SAMP_SIZE_16BIT (1 << 6)
|
||||
#define TPI_AUDIO_SAMP_FREQ_44K (2 << 3)
|
||||
#define TPI_SET_PAGE_SII9022A 0x01
|
||||
#define TPI_SET_OFFSET_SII9022A 0x82
|
||||
#define TPI_RW_EN_SRC_TERMIN (1 << 0)
|
||||
#define TPI_TRANS_MODE_ENABLE (0 << 7)
|
||||
|
||||
/* Programming of Silicon SIi9022a HDMI Transmitter */
|
||||
int dcu_set_dvi_encoder(struct fb_videomode *videomode)
|
||||
{
|
||||
u8 temp;
|
||||
u16 temp1, temp2;
|
||||
u32 temp3;
|
||||
|
||||
i2c_set_bus_num(CONFIG_SYS_I2C_DVI_BUS_NUM);
|
||||
|
||||
/* Enable TPI transmitter mode */
|
||||
temp = TPI_TRANS_MODE_ENABLE;
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_TRANS_MODE_REG, 1, &temp, 1);
|
||||
|
||||
/* Enter into D0 state, full operation */
|
||||
i2c_read(CONFIG_SYS_I2C_DVI_ADDR, TPI_PWR_STAT_REG, 1, &temp, 1);
|
||||
temp &= ~TPI_PWR_STAT_MASK;
|
||||
temp |= TPI_PWR_STAT_D0;
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_PWR_STAT_REG, 1, &temp, 1);
|
||||
|
||||
/* Enable source termination */
|
||||
temp = TPI_SET_PAGE_SII9022A;
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_SET_PAGE_REG, 1, &temp, 1);
|
||||
temp = TPI_SET_OFFSET_SII9022A;
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_SET_OFFSET_REG, 1, &temp, 1);
|
||||
|
||||
i2c_read(CONFIG_SYS_I2C_DVI_ADDR, TPI_RW_ACCESS_REG, 1, &temp, 1);
|
||||
temp |= TPI_RW_EN_SRC_TERMIN;
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_RW_ACCESS_REG, 1, &temp, 1);
|
||||
|
||||
/* Set TPI system control */
|
||||
temp = TPI_SYS_TMDS_OUTPUT | TPI_SYS_AV_NORAML | TPI_SYS_DVI_MODE;
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_SYS_CTRL_REG, 1, &temp, 1);
|
||||
|
||||
/* Set pixel clock */
|
||||
temp1 = PICOS2KHZ(videomode->pixclock) / 10;
|
||||
temp = (u8)(temp1 & 0xFF);
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, PIXEL_CLK_LSB_REG, 1, &temp, 1);
|
||||
temp = (u8)(temp1 >> 8);
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, PIXEL_CLK_MSB_REG, 1, &temp, 1);
|
||||
|
||||
/* Set total pixels per line */
|
||||
temp1 = videomode->hsync_len + videomode->left_margin +
|
||||
videomode->xres + videomode->right_margin;
|
||||
temp = (u8)(temp1 & 0xFF);
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TOTAL_PIXELS_LSB_REG, 1, &temp, 1);
|
||||
temp = (u8)(temp1 >> 8);
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TOTAL_PIXELS_MSB_REG, 1, &temp, 1);
|
||||
|
||||
/* Set total lines */
|
||||
temp2 = videomode->vsync_len + videomode->upper_margin +
|
||||
videomode->yres + videomode->lower_margin;
|
||||
temp = (u8)(temp2 & 0xFF);
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TOTAL_LINES_LSB_REG, 1, &temp, 1);
|
||||
temp = (u8)(temp2 >> 8);
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TOTAL_LINES_MSB_REG, 1, &temp, 1);
|
||||
|
||||
/* Set vertical frequency in Hz */
|
||||
temp3 = temp1 * temp2;
|
||||
temp3 = (PICOS2KHZ(videomode->pixclock) * 1000) / temp3;
|
||||
temp1 = (u16)temp3 * 100;
|
||||
temp = (u8)(temp1 & 0xFF);
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, VERT_FREQ_LSB_REG, 1, &temp, 1);
|
||||
temp = (u8)(temp1 >> 8);
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, VERT_FREQ_MSB_REG, 1, &temp, 1);
|
||||
|
||||
/* Set TPI input bus and pixel repetition data */
|
||||
temp = TPI_INBUS_CLOCK_RATIO_1 | TPI_INBUS_FULL_PIXEL_WIDE |
|
||||
TPI_INBUS_RISING_EDGE;
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_INBUS_FMT_REG, 1, &temp, 1);
|
||||
|
||||
/* Set TPI AVI Input format data */
|
||||
temp = TPI_INPUT_CLR_DEPTH_8BIT | TPI_INPUT_VRANGE_EXPAN_AUTO |
|
||||
TPI_INPUT_CLR_RGB;
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_INPUT_FMT_REG, 1, &temp, 1);
|
||||
|
||||
/* Set TPI AVI Output format data */
|
||||
temp = TPI_OUTPUT_CLR_DEPTH_8BIT | TPI_OUTPUT_VRANGE_COMPRE_AUTO |
|
||||
TPI_OUTPUT_CLR_HDMI_RGB;
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_OUTPUT_FMT_REG, 1, &temp, 1);
|
||||
|
||||
/* Set TPI audio configuration write data */
|
||||
temp = TPI_AUDIO_PASS_BASIC;
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_AUDIO_HANDING_REG, 1, &temp, 1);
|
||||
|
||||
temp = TPI_AUDIO_INTF_I2S | TPI_AUDIO_INTF_NORMAL |
|
||||
TPI_AUDIO_TYPE_PCM;
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_AUDIO_INTF_REG, 1, &temp, 1);
|
||||
|
||||
temp = TPI_AUDIO_SAMP_SIZE_16BIT | TPI_AUDIO_SAMP_FREQ_44K;
|
||||
i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_AUDIO_FREQ_REG, 1, &temp, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __DCU_HDMI_SII9022A__
|
||||
#define __DCU_HDMI_SII9022A__
|
||||
|
||||
/* Programming of Silicon SII9022A connector HDMI Transmitter*/
|
||||
int dcu_set_dvi_encoder(struct fb_videomode *videomode);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,135 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
* Authors: Priyanka Jain <Priyanka.Jain@freescale.com>
|
||||
* Wang Dongsheng <dongsheng.wang@freescale.com>
|
||||
*
|
||||
* This file is copied and modified from the original t1040qds/diu.c.
|
||||
* Encoder can be used in T104x and LSx Platform.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <stdio_dev.h>
|
||||
#include <i2c.h>
|
||||
|
||||
#define I2C_DVI_INPUT_DATA_FORMAT_REG 0x1F
|
||||
#define I2C_DVI_PLL_CHARGE_CNTL_REG 0x33
|
||||
#define I2C_DVI_PLL_DIVIDER_REG 0x34
|
||||
#define I2C_DVI_PLL_SUPPLY_CNTL_REG 0x35
|
||||
#define I2C_DVI_PLL_FILTER_REG 0x36
|
||||
#define I2C_DVI_TEST_PATTERN_REG 0x48
|
||||
#define I2C_DVI_POWER_MGMT_REG 0x49
|
||||
#define I2C_DVI_LOCK_STATE_REG 0x4D
|
||||
#define I2C_DVI_SYNC_POLARITY_REG 0x56
|
||||
|
||||
/*
|
||||
* Set VSYNC/HSYNC to active high. This is polarity of sync signals
|
||||
* from DIU->DVI. The DIU default is active igh, so DVI is set to
|
||||
* active high.
|
||||
*/
|
||||
#define I2C_DVI_INPUT_DATA_FORMAT_VAL 0x98
|
||||
|
||||
#define I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL 0x06
|
||||
#define I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL 0x26
|
||||
#define I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL 0xA0
|
||||
#define I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL 0x08
|
||||
#define I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL 0x16
|
||||
#define I2C_DVI_PLL_FILTER_LOW_SPEED_VAL 0x60
|
||||
|
||||
/* Clear test pattern */
|
||||
#define I2C_DVI_TEST_PATTERN_VAL 0x18
|
||||
/* Exit Power-down mode */
|
||||
#define I2C_DVI_POWER_MGMT_VAL 0xC0
|
||||
|
||||
/* Monitor polarity is handled via DVI Sync Polarity Register */
|
||||
#define I2C_DVI_SYNC_POLARITY_VAL 0x00
|
||||
|
||||
/* Programming of HDMI Chrontel CH7301 connector */
|
||||
int diu_set_dvi_encoder(unsigned int pixclock)
|
||||
{
|
||||
int ret;
|
||||
u8 temp;
|
||||
|
||||
temp = I2C_DVI_TEST_PATTERN_VAL;
|
||||
ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_TEST_PATTERN_REG, 1,
|
||||
&temp, 1);
|
||||
if (ret) {
|
||||
puts("I2C: failed to select proper dvi test pattern\n");
|
||||
return ret;
|
||||
}
|
||||
temp = I2C_DVI_INPUT_DATA_FORMAT_VAL;
|
||||
ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_INPUT_DATA_FORMAT_REG,
|
||||
1, &temp, 1);
|
||||
if (ret) {
|
||||
puts("I2C: failed to select dvi input data format\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set Sync polarity register */
|
||||
temp = I2C_DVI_SYNC_POLARITY_VAL;
|
||||
ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_SYNC_POLARITY_REG, 1,
|
||||
&temp, 1);
|
||||
if (ret) {
|
||||
puts("I2C: failed to select dvi syc polarity\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set PLL registers based on pixel clock rate*/
|
||||
if (pixclock > 65000000) {
|
||||
temp = I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL;
|
||||
ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
|
||||
I2C_DVI_PLL_CHARGE_CNTL_REG, 1, &temp, 1);
|
||||
if (ret) {
|
||||
puts("I2C: failed to select dvi pll charge_cntl\n");
|
||||
return ret;
|
||||
}
|
||||
temp = I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL;
|
||||
ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
|
||||
I2C_DVI_PLL_DIVIDER_REG, 1, &temp, 1);
|
||||
if (ret) {
|
||||
puts("I2C: failed to select dvi pll divider\n");
|
||||
return ret;
|
||||
}
|
||||
temp = I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL;
|
||||
ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
|
||||
I2C_DVI_PLL_FILTER_REG, 1, &temp, 1);
|
||||
if (ret) {
|
||||
puts("I2C: failed to select dvi pll filter\n");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
temp = I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL;
|
||||
ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
|
||||
I2C_DVI_PLL_CHARGE_CNTL_REG, 1, &temp, 1);
|
||||
if (ret) {
|
||||
puts("I2C: failed to select dvi pll charge_cntl\n");
|
||||
return ret;
|
||||
}
|
||||
temp = I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL;
|
||||
ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
|
||||
I2C_DVI_PLL_DIVIDER_REG, 1, &temp, 1);
|
||||
if (ret) {
|
||||
puts("I2C: failed to select dvi pll divider\n");
|
||||
return ret;
|
||||
}
|
||||
temp = I2C_DVI_PLL_FILTER_LOW_SPEED_VAL;
|
||||
ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
|
||||
I2C_DVI_PLL_FILTER_REG, 1, &temp, 1);
|
||||
if (ret) {
|
||||
puts("I2C: failed to select dvi pll filter\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
temp = I2C_DVI_POWER_MGMT_VAL;
|
||||
ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_POWER_MGMT_REG, 1,
|
||||
&temp, 1);
|
||||
if (ret) {
|
||||
puts("I2C: failed to select dvi power mgmt\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
udelay(500);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __DIU_HDMI_CH7301__
|
||||
#define __DIU_HDMI_CH7301__
|
||||
|
||||
/* Programming of HDMI Chrontel CH7301 connector */
|
||||
int diu_set_dvi_encoder(unsigned int pixclock);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2004 Freescale Semiconductor.
|
||||
*/
|
||||
|
||||
#ifndef __EEPROM_H_
|
||||
#define __EEPROM_H_
|
||||
|
||||
|
||||
/*
|
||||
* EEPROM Board System Register interface.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* CPU Board Revision
|
||||
*/
|
||||
#define MPC85XX_CPU_BOARD_REV(maj, min) ((((maj)&0xff) << 8) | ((min) & 0xff))
|
||||
#define MPC85XX_CPU_BOARD_MAJOR(rev) (((rev) >> 8) & 0xff)
|
||||
#define MPC85XX_CPU_BOARD_MINOR(rev) ((rev) & 0xff)
|
||||
|
||||
#define MPC85XX_CPU_BOARD_REV_UNKNOWN MPC85XX_CPU_BOARD_REV(0,0)
|
||||
#define MPC85XX_CPU_BOARD_REV_1_0 MPC85XX_CPU_BOARD_REV(1,0)
|
||||
#define MPC85XX_CPU_BOARD_REV_1_1 MPC85XX_CPU_BOARD_REV(1,1)
|
||||
|
||||
/*
|
||||
* Returns CPU board revision register as a 16-bit value with
|
||||
* the Major in the high byte, and Minor in the low byte.
|
||||
*/
|
||||
extern unsigned int get_cpu_board_revision(void);
|
||||
|
||||
|
||||
#endif /* __CADMUS_H_ */
|
||||
@@ -0,0 +1,62 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2018 NXP.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <i2c.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "emc2305.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
void set_fan_speed(u8 data)
|
||||
{
|
||||
u8 index;
|
||||
u8 Fan[NUM_OF_FANS] = {I2C_EMC2305_FAN1,
|
||||
I2C_EMC2305_FAN2,
|
||||
I2C_EMC2305_FAN3,
|
||||
I2C_EMC2305_FAN4,
|
||||
I2C_EMC2305_FAN5};
|
||||
|
||||
for (index = 0; index < NUM_OF_FANS; index++) {
|
||||
#ifndef CONFIG_DM_I2C
|
||||
if (i2c_write(I2C_EMC2305_ADDR, Fan[index], 1, &data, 1) != 0) {
|
||||
printf("Error: failed to change fan speed @%x\n",
|
||||
Fan[index]);
|
||||
}
|
||||
#else
|
||||
struct udevice *dev;
|
||||
|
||||
if (i2c_get_chip_for_busnum(0, I2C_EMC2305_ADDR, 1, &dev))
|
||||
continue;
|
||||
|
||||
if (dm_i2c_write(dev, Fan[index], &data, 1) != 0) {
|
||||
printf("Error: failed to change fan speed @%x\n",
|
||||
Fan[index]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void emc2305_init(void)
|
||||
{
|
||||
u8 data;
|
||||
|
||||
data = I2C_EMC2305_CMD;
|
||||
#ifndef CONFIG_DM_I2C
|
||||
if (i2c_write(I2C_EMC2305_ADDR, I2C_EMC2305_CONF, 1, &data, 1) != 0)
|
||||
printf("Error: failed to configure EMC2305\n");
|
||||
#else
|
||||
struct udevice *dev;
|
||||
|
||||
if (!i2c_get_chip_for_busnum(0, I2C_EMC2305_ADDR, 1, &dev))
|
||||
if (dm_i2c_write(dev, I2C_EMC2305_CONF, &data, 1))
|
||||
printf("Error: failed to configure EMC2305\n");
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2018 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __EMC2305_H_
|
||||
#define __EMC2305_H_
|
||||
|
||||
#define I2C_EMC2305_CONF 0x20
|
||||
#define I2C_EMC2305_FAN1 0x30
|
||||
#define I2C_EMC2305_FAN2 0x40
|
||||
#define I2C_EMC2305_FAN3 0x50
|
||||
#define I2C_EMC2305_FAN4 0x60
|
||||
#define I2C_EMC2305_FAN5 0x70
|
||||
|
||||
#define NUM_OF_FANS 5
|
||||
|
||||
void emc2305_init(void);
|
||||
void set_fan_speed(u8 data);
|
||||
|
||||
#endif /* __EMC2305_H_ */
|
||||
@@ -0,0 +1,89 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2011-2015 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <linux/libfdt_env.h>
|
||||
#include <fdt_support.h>
|
||||
|
||||
#include <fm_eth.h>
|
||||
#ifdef CONFIG_FSL_LAYERSCAPE
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
#else
|
||||
#include <asm/fsl_serdes.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Given the following ...
|
||||
*
|
||||
* 1) A pointer to an Fman Ethernet node (as identified by the 'compat'
|
||||
* compatible string and 'addr' physical address)
|
||||
*
|
||||
* 2) The name of an alias that points to the ethernet-phy node (usually inside
|
||||
* a virtual MDIO node)
|
||||
*
|
||||
* ... update that Ethernet node's phy-handle property to point to the
|
||||
* ethernet-phy node. This is how we link an Ethernet node to its PHY, so each
|
||||
* PHY in a virtual MDIO node must have an alias.
|
||||
*
|
||||
* Returns 0 on success, or a negative FDT error code on error.
|
||||
*/
|
||||
int fdt_set_phy_handle(void *fdt, char *compat, phys_addr_t addr,
|
||||
const char *alias)
|
||||
{
|
||||
int offset;
|
||||
unsigned int ph;
|
||||
const char *path;
|
||||
|
||||
/* Get a path to the node that 'alias' points to */
|
||||
path = fdt_get_alias(fdt, alias);
|
||||
if (!path)
|
||||
return -FDT_ERR_BADPATH;
|
||||
|
||||
/* Get the offset of that node */
|
||||
offset = fdt_path_offset(fdt, path);
|
||||
if (offset < 0)
|
||||
return offset;
|
||||
|
||||
ph = fdt_create_phandle(fdt, offset);
|
||||
if (!ph)
|
||||
return -FDT_ERR_BADPHANDLE;
|
||||
|
||||
ph = cpu_to_fdt32(ph);
|
||||
|
||||
offset = fdt_node_offset_by_compat_reg(fdt, compat, addr);
|
||||
if (offset < 0)
|
||||
return offset;
|
||||
|
||||
return fdt_setprop(fdt, offset, "phy-handle", &ph, sizeof(ph));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the SerDes device enum for a given Fman port
|
||||
*
|
||||
* This function just maps the fm_port namespace to the srds_prtcl namespace.
|
||||
*/
|
||||
enum srds_prtcl serdes_device_from_fm_port(enum fm_port port)
|
||||
{
|
||||
static const enum srds_prtcl srds_table[] = {
|
||||
[FM1_DTSEC1] = SGMII_FM1_DTSEC1,
|
||||
[FM1_DTSEC2] = SGMII_FM1_DTSEC2,
|
||||
[FM1_DTSEC3] = SGMII_FM1_DTSEC3,
|
||||
[FM1_DTSEC4] = SGMII_FM1_DTSEC4,
|
||||
[FM1_DTSEC5] = SGMII_FM1_DTSEC5,
|
||||
[FM1_10GEC1] = XAUI_FM1,
|
||||
[FM2_DTSEC1] = SGMII_FM2_DTSEC1,
|
||||
[FM2_DTSEC2] = SGMII_FM2_DTSEC2,
|
||||
[FM2_DTSEC3] = SGMII_FM2_DTSEC3,
|
||||
[FM2_DTSEC4] = SGMII_FM2_DTSEC4,
|
||||
[FM2_DTSEC5] = SGMII_FM2_DTSEC5,
|
||||
[FM2_10GEC1] = XAUI_FM2,
|
||||
};
|
||||
|
||||
if ((port < FM1_DTSEC1) || (port > FM2_10GEC1))
|
||||
return NONE;
|
||||
else
|
||||
return srds_table[port];
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2011 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __FMAN_BOARD_HELPER__
|
||||
#define __FMAN_BOARD_HELPER__
|
||||
|
||||
int fdt_set_phy_handle(void *fdt, char *compat, phys_addr_t addr,
|
||||
const char *alias);
|
||||
|
||||
enum srds_prtcl serdes_device_from_fm_port(enum fm_port port);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,165 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <env.h>
|
||||
#include <fsl_validate.h>
|
||||
#include <fsl_secboot_err.h>
|
||||
#include <fsl_sfp.h>
|
||||
#include <dm/root.h>
|
||||
|
||||
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_FRAMEWORK)
|
||||
#include <spl.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ADDR_MAP
|
||||
#include <asm/mmu.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FSL_CORENET
|
||||
#include <asm/fsl_pamu.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_LS1021A
|
||||
#include <asm/arch/immap_ls102xa.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MPC85xx)
|
||||
#define CONFIG_DCFG_ADDR CONFIG_SYS_MPC85xx_GUTS_ADDR
|
||||
#else
|
||||
#define CONFIG_DCFG_ADDR CONFIG_SYS_FSL_GUTS_ADDR
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_CCSR_GUR_LE
|
||||
#define gur_in32(a) in_le32(a)
|
||||
#else
|
||||
#define gur_in32(a) in_be32(a)
|
||||
#endif
|
||||
|
||||
/* Check the Boot Mode. If Secure, return 1 else return 0 */
|
||||
int fsl_check_boot_mode_secure(void)
|
||||
{
|
||||
uint32_t val;
|
||||
struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_DCFG_ADDR);
|
||||
|
||||
val = sfp_in32(&sfp_regs->ospr) & ITS_MASK;
|
||||
if (val == ITS_MASK)
|
||||
return 1;
|
||||
|
||||
#if defined(CONFIG_FSL_CORENET) || !defined(CONFIG_MPC85xx)
|
||||
/* For PBL based platforms check the SB_EN bit in RCWSR */
|
||||
val = gur_in32(&gur->rcwsr[RCW_SB_EN_REG_INDEX - 1]) & RCW_SB_EN_MASK;
|
||||
if (val == RCW_SB_EN_MASK)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MPC85xx) && !defined(CONFIG_FSL_CORENET)
|
||||
/* For Non-PBL Platforms, check the Device Status register 2*/
|
||||
val = gur_in32(&gur->pordevsr2) & MPC85xx_PORDEVSR2_SBC_MASK;
|
||||
if (val != MPC85xx_PORDEVSR2_SBC_MASK)
|
||||
return 1;
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
int fsl_setenv_chain_of_trust(void)
|
||||
{
|
||||
/* Check Boot Mode
|
||||
* If Boot Mode is Non-Secure, no changes are required
|
||||
*/
|
||||
if (fsl_check_boot_mode_secure() == 0)
|
||||
return 0;
|
||||
|
||||
/* If Boot mode is Secure, set the environment variables
|
||||
* bootdelay = 0 (To disable Boot Prompt)
|
||||
* bootcmd = CONFIG_CHAIN_BOOT_CMD (Validate and execute Boot script)
|
||||
*/
|
||||
env_set("bootdelay", "-2");
|
||||
|
||||
#ifdef CONFIG_ARM
|
||||
env_set("secureboot", "y");
|
||||
#else
|
||||
env_set("bootcmd", CONFIG_CHAIN_BOOT_CMD);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
void spl_validate_uboot(uint32_t hdr_addr, uintptr_t img_addr)
|
||||
{
|
||||
int res;
|
||||
|
||||
/*
|
||||
* Check Boot Mode
|
||||
* If Boot Mode is Non-Secure, skip validation
|
||||
*/
|
||||
if (fsl_check_boot_mode_secure() == 0)
|
||||
return;
|
||||
|
||||
printf("SPL: Validating U-Boot image\n");
|
||||
|
||||
#ifdef CONFIG_ADDR_MAP
|
||||
init_addr_map();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FSL_CORENET
|
||||
if (pamu_init() < 0)
|
||||
fsl_secboot_handle_error(ERROR_ESBC_PAMU_INIT);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FSL_CAAM
|
||||
if (sec_init() < 0)
|
||||
fsl_secboot_handle_error(ERROR_ESBC_SEC_INIT);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* dm_init_and_scan() is called as part of common SPL framework, so no
|
||||
* need to call it again but in case of powerpc platforms which currently
|
||||
* do not use common SPL framework, so need to call this function here.
|
||||
*/
|
||||
#if defined(CONFIG_SPL_DM) && (!defined(CONFIG_SPL_FRAMEWORK))
|
||||
dm_init_and_scan(true);
|
||||
#endif
|
||||
res = fsl_secboot_validate(hdr_addr, CONFIG_SPL_UBOOT_KEY_HASH,
|
||||
&img_addr);
|
||||
|
||||
if (res == 0)
|
||||
printf("SPL: Validation of U-boot successful\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPL_FRAMEWORK
|
||||
/* Override weak funtion defined in SPL framework to enable validation
|
||||
* of main u-boot image before jumping to u-boot image.
|
||||
*/
|
||||
void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
|
||||
{
|
||||
typedef void __noreturn (*image_entry_noargs_t)(void);
|
||||
uint32_t hdr_addr;
|
||||
|
||||
image_entry_noargs_t image_entry =
|
||||
(image_entry_noargs_t)(unsigned long)spl_image->entry_point;
|
||||
|
||||
hdr_addr = (spl_image->entry_point + spl_image->size -
|
||||
CONFIG_U_BOOT_HDR_SIZE);
|
||||
spl_validate_uboot(hdr_addr, (uintptr_t)spl_image->entry_point);
|
||||
/*
|
||||
* In case of failure in validation, spl_validate_uboot would
|
||||
* not return back in case of Production environment with ITS=1.
|
||||
* Thus U-Boot will not start.
|
||||
* In Development environment (ITS=0 and SB_EN=1), the function
|
||||
* may return back in case of non-fatal failures.
|
||||
*/
|
||||
|
||||
debug("image entry point: 0x%lX\n", spl_image->entry_point);
|
||||
image_entry();
|
||||
}
|
||||
#endif /* ifdef CONFIG_SPL_FRAMEWORK */
|
||||
#endif /* ifdef CONFIG_SPL_BUILD */
|
||||
@@ -0,0 +1,962 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <fsl_validate.h>
|
||||
#include <fsl_secboot_err.h>
|
||||
#include <fsl_sfp.h>
|
||||
#include <fsl_sec.h>
|
||||
#include <command.h>
|
||||
#include <malloc.h>
|
||||
#include <u-boot/rsa-mod-exp.h>
|
||||
#include <hash.h>
|
||||
#include <fsl_secboot_err.h>
|
||||
#ifdef CONFIG_ARCH_LS1021A
|
||||
#include <asm/arch/immap_ls102xa.h>
|
||||
#endif
|
||||
|
||||
#define SHA256_BITS 256
|
||||
#define SHA256_BYTES (256/8)
|
||||
#define SHA256_NIBBLES (256/4)
|
||||
#define NUM_HEX_CHARS (sizeof(ulong) * 2)
|
||||
|
||||
#define CHECK_KEY_LEN(key_len) (((key_len) == 2 * KEY_SIZE_BYTES / 4) || \
|
||||
((key_len) == 2 * KEY_SIZE_BYTES / 2) || \
|
||||
((key_len) == 2 * KEY_SIZE_BYTES))
|
||||
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
|
||||
/* Global data structure */
|
||||
static struct fsl_secboot_glb glb;
|
||||
#endif
|
||||
|
||||
/* This array contains DER value for SHA-256 */
|
||||
static const u8 hash_identifier[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
|
||||
0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
|
||||
0x04, 0x20
|
||||
};
|
||||
|
||||
static u8 hash_val[SHA256_BYTES];
|
||||
|
||||
#ifdef CONFIG_ESBC_HDR_LS
|
||||
/* New Barker Code for LS ESBC Header */
|
||||
static const u8 barker_code[ESBC_BARKER_LEN] = { 0x12, 0x19, 0x20, 0x01 };
|
||||
#else
|
||||
static const u8 barker_code[ESBC_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 };
|
||||
#endif
|
||||
|
||||
void branch_to_self(void) __attribute__ ((noreturn));
|
||||
|
||||
/*
|
||||
* This function will put core in infinite loop.
|
||||
* This will be called when the ESBC can not proceed further due
|
||||
* to some unknown errors.
|
||||
*/
|
||||
void branch_to_self(void)
|
||||
{
|
||||
printf("Core is in infinite loop due to errors.\n");
|
||||
self:
|
||||
goto self;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
|
||||
static u32 check_ie(struct fsl_secboot_img_priv *img)
|
||||
{
|
||||
if (img->hdr.ie_flag & IE_FLAG_MASK)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This function returns the CSF Header Address of uboot
|
||||
* For MPC85xx based platforms, the LAW mapping for NOR
|
||||
* flash changes in uboot code. Hence the offset needs
|
||||
* to be calculated and added to the new NOR flash base
|
||||
* address
|
||||
*/
|
||||
#if defined(CONFIG_MPC85xx)
|
||||
int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
||||
u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
|
||||
u32 csf_flash_offset = csf_hdr_addr & ~(CONFIG_SYS_PBI_FLASH_BASE);
|
||||
u32 flash_addr, addr;
|
||||
int found = 0;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
|
||||
flash_addr = flash_info[i].start[0];
|
||||
addr = flash_info[i].start[0] + csf_flash_offset;
|
||||
if (memcmp((u8 *)addr, barker_code, ESBC_BARKER_LEN) == 0) {
|
||||
debug("Barker found on addr %x\n", addr);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return -1;
|
||||
|
||||
*csf_addr = addr;
|
||||
*flash_base_addr = flash_addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
/* For platforms like LS1020, correct flash address is present in
|
||||
* the header. So the function reqturns flash base address as 0
|
||||
*/
|
||||
int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
|
||||
|
||||
if (memcmp((u8 *)(uintptr_t)csf_hdr_addr,
|
||||
barker_code, ESBC_BARKER_LEN))
|
||||
return -1;
|
||||
|
||||
*csf_addr = csf_hdr_addr;
|
||||
*flash_base_addr = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ESBC_HDR_LS)
|
||||
static int get_ie_info_addr(uintptr_t *ie_addr)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
/* For LS-CH3, the address of IE Table is
|
||||
* stated in Scratch13 and scratch14 of DCFG.
|
||||
* Bootrom validates this table while validating uboot.
|
||||
* DCFG is LE*/
|
||||
*ie_addr = in_le32(&gur->scratchrw[SCRATCH_IE_HIGH_ADR - 1]);
|
||||
*ie_addr = *ie_addr << 32;
|
||||
*ie_addr |= in_le32(&gur->scratchrw[SCRATCH_IE_LOW_ADR - 1]);
|
||||
return 0;
|
||||
}
|
||||
#else /* CONFIG_ESBC_HDR_LS */
|
||||
static int get_ie_info_addr(uintptr_t *ie_addr)
|
||||
{
|
||||
struct fsl_secboot_img_hdr *hdr;
|
||||
struct fsl_secboot_sg_table *sg_tbl;
|
||||
u32 flash_base_addr, csf_addr;
|
||||
|
||||
if (get_csf_base_addr(&csf_addr, &flash_base_addr))
|
||||
return -1;
|
||||
|
||||
hdr = (struct fsl_secboot_img_hdr *)(uintptr_t)csf_addr;
|
||||
|
||||
/* For SoC's with Trust Architecture v1 with corenet bus
|
||||
* the sg table field in CSF header has absolute address
|
||||
* for sg table in memory. In other Trust Architecture,
|
||||
* this field specifies the offset of sg table from the
|
||||
* base address of CSF Header
|
||||
*/
|
||||
#if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET)
|
||||
sg_tbl = (struct fsl_secboot_sg_table *)
|
||||
(((u32)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
|
||||
flash_base_addr);
|
||||
#else
|
||||
sg_tbl = (struct fsl_secboot_sg_table *)(uintptr_t)(csf_addr +
|
||||
(u32)hdr->psgtable);
|
||||
#endif
|
||||
|
||||
/* IE Key Table is the first entry in the SG Table */
|
||||
#if defined(CONFIG_MPC85xx)
|
||||
*ie_addr = (uintptr_t)((sg_tbl->src_addr &
|
||||
~(CONFIG_SYS_PBI_FLASH_BASE)) +
|
||||
flash_base_addr);
|
||||
#else
|
||||
*ie_addr = (uintptr_t)sg_tbl->src_addr;
|
||||
#endif
|
||||
|
||||
debug("IE Table address is %lx\n", *ie_addr);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_ESBC_HDR_LS */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KEY_REVOCATION
|
||||
/* This function checks srk_table_flag in header and set/reset srk_flag.*/
|
||||
static u32 check_srk(struct fsl_secboot_img_priv *img)
|
||||
{
|
||||
#ifdef CONFIG_ESBC_HDR_LS
|
||||
/* In LS, No SRK Flag as SRK is always present if IE not present*/
|
||||
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
|
||||
return !check_ie(img);
|
||||
#endif
|
||||
return 1;
|
||||
#else
|
||||
if (img->hdr.len_kr.srk_table_flag & SRK_FLAG)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This function returns ospr's key_revoc values.*/
|
||||
static u32 get_key_revoc(void)
|
||||
{
|
||||
struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
|
||||
return (sfp_in32(&sfp_regs->ospr) & OSPR_KEY_REVOC_MASK) >>
|
||||
OSPR_KEY_REVOC_SHIFT;
|
||||
}
|
||||
|
||||
/* This function checks if selected key is revoked or not.*/
|
||||
static u32 is_key_revoked(u32 keynum, u32 rev_flag)
|
||||
{
|
||||
if (keynum == UNREVOCABLE_KEY)
|
||||
return 0;
|
||||
|
||||
if ((u32)(1 << (ALIGN_REVOC_KEY - keynum)) & rev_flag)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* It read validates srk_table key lengths.*/
|
||||
static u32 read_validate_srk_tbl(struct fsl_secboot_img_priv *img)
|
||||
{
|
||||
int i = 0;
|
||||
u32 ret, key_num, key_revoc_flag, size;
|
||||
struct fsl_secboot_img_hdr *hdr = &img->hdr;
|
||||
void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
|
||||
|
||||
if ((hdr->len_kr.num_srk == 0) ||
|
||||
(hdr->len_kr.num_srk > MAX_KEY_ENTRIES))
|
||||
return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY;
|
||||
|
||||
key_num = hdr->len_kr.srk_sel;
|
||||
if (key_num == 0 || key_num > hdr->len_kr.num_srk)
|
||||
return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM;
|
||||
|
||||
/* Get revoc key from sfp */
|
||||
key_revoc_flag = get_key_revoc();
|
||||
ret = is_key_revoked(key_num, key_revoc_flag);
|
||||
if (ret)
|
||||
return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED;
|
||||
|
||||
size = hdr->len_kr.num_srk * sizeof(struct srk_table);
|
||||
|
||||
memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size);
|
||||
|
||||
for (i = 0; i < hdr->len_kr.num_srk; i++) {
|
||||
if (!CHECK_KEY_LEN(img->srk_tbl[i].key_len))
|
||||
return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN;
|
||||
}
|
||||
|
||||
img->key_len = img->srk_tbl[key_num - 1].key_len;
|
||||
|
||||
memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey),
|
||||
img->key_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ESBC_HDR_LS
|
||||
static u32 read_validate_single_key(struct fsl_secboot_img_priv *img)
|
||||
{
|
||||
struct fsl_secboot_img_hdr *hdr = &img->hdr;
|
||||
void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
|
||||
|
||||
/* check key length */
|
||||
if (!CHECK_KEY_LEN(hdr->key_len))
|
||||
return ERROR_ESBC_CLIENT_HEADER_KEY_LEN;
|
||||
|
||||
memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len);
|
||||
|
||||
img->key_len = hdr->key_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_ESBC_HDR_LS */
|
||||
|
||||
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
|
||||
|
||||
static void install_ie_tbl(uintptr_t ie_tbl_addr,
|
||||
struct fsl_secboot_img_priv *img)
|
||||
{
|
||||
/* Copy IE tbl to Global Data */
|
||||
memcpy(&glb.ie_tbl, (u8 *)ie_tbl_addr, sizeof(struct ie_key_info));
|
||||
img->ie_addr = (uintptr_t)&glb.ie_tbl;
|
||||
glb.ie_addr = img->ie_addr;
|
||||
}
|
||||
|
||||
static u32 read_validate_ie_tbl(struct fsl_secboot_img_priv *img)
|
||||
{
|
||||
struct fsl_secboot_img_hdr *hdr = &img->hdr;
|
||||
u32 ie_key_len, ie_revoc_flag, ie_num;
|
||||
struct ie_key_info *ie_info;
|
||||
|
||||
if (!img->ie_addr) {
|
||||
if (get_ie_info_addr(&img->ie_addr))
|
||||
return ERROR_IE_TABLE_NOT_FOUND;
|
||||
else
|
||||
install_ie_tbl(img->ie_addr, img);
|
||||
}
|
||||
|
||||
ie_info = (struct ie_key_info *)(uintptr_t)img->ie_addr;
|
||||
if (ie_info->num_keys == 0 || ie_info->num_keys > 32)
|
||||
return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY;
|
||||
|
||||
ie_num = hdr->ie_key_sel;
|
||||
if (ie_num == 0 || ie_num > ie_info->num_keys)
|
||||
return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM;
|
||||
|
||||
ie_revoc_flag = ie_info->key_revok;
|
||||
if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag)
|
||||
return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED;
|
||||
|
||||
ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len;
|
||||
|
||||
if (!CHECK_KEY_LEN(ie_key_len))
|
||||
return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN;
|
||||
|
||||
memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey),
|
||||
ie_key_len);
|
||||
|
||||
img->key_len = ie_key_len;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* This function return length of public key.*/
|
||||
static inline u32 get_key_len(struct fsl_secboot_img_priv *img)
|
||||
{
|
||||
return img->key_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles the ESBC uboot client header verification failure.
|
||||
* This function handles all the errors which might occur in the
|
||||
* parsing and checking of ESBC uboot client header. It will also
|
||||
* set the error bits in the SEC_MON.
|
||||
*/
|
||||
static void fsl_secboot_header_verification_failure(void)
|
||||
{
|
||||
struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
|
||||
|
||||
/* 29th bit of OSPR is ITS */
|
||||
u32 its = sfp_in32(&sfp_regs->ospr) >> 2;
|
||||
|
||||
if (its == 1)
|
||||
set_sec_mon_state(HPSR_SSM_ST_SOFT_FAIL);
|
||||
else
|
||||
set_sec_mon_state(HPSR_SSM_ST_NON_SECURE);
|
||||
|
||||
printf("Generating reset request\n");
|
||||
do_reset(NULL, 0, 0, NULL);
|
||||
/* If reset doesn't coocur, halt execution */
|
||||
do_esbc_halt(NULL, 0, 0, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles the ESBC uboot client image verification failure.
|
||||
* This function handles all the errors which might occur in the
|
||||
* public key hash comparison and signature verification of
|
||||
* ESBC uboot client image. It will also
|
||||
* set the error bits in the SEC_MON.
|
||||
*/
|
||||
static void fsl_secboot_image_verification_failure(void)
|
||||
{
|
||||
struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
|
||||
|
||||
u32 its = (sfp_in32(&sfp_regs->ospr) & ITS_MASK) >> ITS_BIT;
|
||||
|
||||
if (its == 1) {
|
||||
set_sec_mon_state(HPSR_SSM_ST_SOFT_FAIL);
|
||||
|
||||
printf("Generating reset request\n");
|
||||
do_reset(NULL, 0, 0, NULL);
|
||||
/* If reset doesn't coocur, halt execution */
|
||||
do_esbc_halt(NULL, 0, 0, NULL);
|
||||
|
||||
} else {
|
||||
set_sec_mon_state(HPSR_SSM_ST_NON_SECURE);
|
||||
}
|
||||
}
|
||||
|
||||
static void fsl_secboot_bootscript_parse_failure(void)
|
||||
{
|
||||
fsl_secboot_header_verification_failure();
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles the errors in esbc boot.
|
||||
* This function handles all the errors which might occur in the
|
||||
* esbc boot phase. It will call the appropriate api to log the
|
||||
* errors and set the error bits in the SEC_MON.
|
||||
*/
|
||||
void fsl_secboot_handle_error(int error)
|
||||
{
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
const struct fsl_secboot_errcode *e;
|
||||
|
||||
for (e = fsl_secboot_errcodes; e->errcode != ERROR_ESBC_CLIENT_MAX;
|
||||
e++) {
|
||||
if (e->errcode == error)
|
||||
printf("ERROR :: %x :: %s\n", error, e->name);
|
||||
}
|
||||
#else
|
||||
printf("ERROR :: %x\n", error);
|
||||
#endif
|
||||
|
||||
/* If Boot Mode is secure, transition the SNVS state and issue
|
||||
* reset based on type of failure and ITS setting.
|
||||
* If Boot mode is non-secure, return from this function.
|
||||
*/
|
||||
if (fsl_check_boot_mode_secure() == 0)
|
||||
return;
|
||||
|
||||
switch (error) {
|
||||
case ERROR_ESBC_CLIENT_HEADER_BARKER:
|
||||
case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE:
|
||||
case ERROR_ESBC_CLIENT_HEADER_KEY_LEN:
|
||||
case ERROR_ESBC_CLIENT_HEADER_SIG_LEN:
|
||||
case ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN:
|
||||
case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1:
|
||||
case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2:
|
||||
case ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD:
|
||||
case ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP:
|
||||
case ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD:
|
||||
case ERROR_KEY_TABLE_NOT_FOUND:
|
||||
#ifdef CONFIG_KEY_REVOCATION
|
||||
case ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED:
|
||||
case ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY:
|
||||
case ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM:
|
||||
case ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN:
|
||||
#endif
|
||||
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
|
||||
/*@fallthrough@*/
|
||||
case ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED:
|
||||
case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY:
|
||||
case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM:
|
||||
case ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN:
|
||||
case ERROR_IE_TABLE_NOT_FOUND:
|
||||
#endif
|
||||
fsl_secboot_header_verification_failure();
|
||||
break;
|
||||
case ERROR_ESBC_SEC_RESET:
|
||||
case ERROR_ESBC_SEC_DEQ:
|
||||
case ERROR_ESBC_SEC_ENQ:
|
||||
case ERROR_ESBC_SEC_DEQ_TO:
|
||||
case ERROR_ESBC_SEC_JOBQ_STATUS:
|
||||
case ERROR_ESBC_CLIENT_HASH_COMPARE_KEY:
|
||||
case ERROR_ESBC_CLIENT_HASH_COMPARE_EM:
|
||||
fsl_secboot_image_verification_failure();
|
||||
break;
|
||||
case ERROR_ESBC_MISSING_BOOTM:
|
||||
fsl_secboot_bootscript_parse_failure();
|
||||
break;
|
||||
case ERROR_ESBC_WRONG_CMD:
|
||||
default:
|
||||
branch_to_self();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void fsl_secblk_handle_error(int error)
|
||||
{
|
||||
switch (error) {
|
||||
case ERROR_ESBC_SEC_ENQ:
|
||||
fsl_secboot_handle_error(ERROR_ESBC_SEC_ENQ);
|
||||
break;
|
||||
case ERROR_ESBC_SEC_DEQ:
|
||||
fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ);
|
||||
break;
|
||||
case ERROR_ESBC_SEC_DEQ_TO:
|
||||
fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ_TO);
|
||||
break;
|
||||
default:
|
||||
printf("Job Queue Output status %x\n", error);
|
||||
fsl_secboot_handle_error(ERROR_ESBC_SEC_JOBQ_STATUS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate hash of key obtained via offset present in ESBC uboot
|
||||
* client hdr. This function calculates the hash of key which is obtained
|
||||
* through offset present in ESBC uboot client header.
|
||||
*/
|
||||
static int calc_img_key_hash(struct fsl_secboot_img_priv *img)
|
||||
{
|
||||
struct hash_algo *algo;
|
||||
void *ctx;
|
||||
int i, srk = 0;
|
||||
int ret = 0;
|
||||
const char *algo_name = "sha256";
|
||||
|
||||
/* Calculate hash of the esbc key */
|
||||
ret = hash_progressive_lookup_algo(algo_name, &algo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = algo->hash_init(algo, &ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Update hash for ESBC key */
|
||||
#ifdef CONFIG_KEY_REVOCATION
|
||||
if (check_srk(img)) {
|
||||
ret = algo->hash_update(algo, ctx,
|
||||
(u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off),
|
||||
img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1);
|
||||
srk = 1;
|
||||
}
|
||||
#endif
|
||||
if (!srk)
|
||||
ret = algo->hash_update(algo, ctx,
|
||||
img->img_key, img->key_len, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Copy hash at destination buffer */
|
||||
ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < SHA256_BYTES; i++)
|
||||
img->img_key_hash[i] = hash_val[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate hash of ESBC hdr and ESBC. This function calculates the
|
||||
* single hash of ESBC header and ESBC image. If SG flag is on, all
|
||||
* SG entries are also hashed alongwith the complete SG table.
|
||||
*/
|
||||
static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img)
|
||||
{
|
||||
struct hash_algo *algo;
|
||||
void *ctx;
|
||||
int ret = 0;
|
||||
int key_hash = 0;
|
||||
const char *algo_name = "sha256";
|
||||
|
||||
/* Calculate the hash of the ESBC */
|
||||
ret = hash_progressive_lookup_algo(algo_name, &algo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = algo->hash_init(algo, &ctx);
|
||||
/* Copy hash at destination buffer */
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Update hash for CSF Header */
|
||||
ret = algo->hash_update(algo, ctx,
|
||||
(u8 *)&img->hdr, sizeof(struct fsl_secboot_img_hdr), 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Update the hash with that of srk table if srk flag is 1
|
||||
* If IE Table is selected, key is not added in the hash
|
||||
* If neither srk table nor IE key table available, add key
|
||||
* from header in the hash calculation
|
||||
*/
|
||||
#ifdef CONFIG_KEY_REVOCATION
|
||||
if (check_srk(img)) {
|
||||
ret = algo->hash_update(algo, ctx,
|
||||
(u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off),
|
||||
img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0);
|
||||
key_hash = 1;
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
|
||||
if (!key_hash && check_ie(img))
|
||||
key_hash = 1;
|
||||
#endif
|
||||
#ifndef CONFIG_ESBC_HDR_LS
|
||||
/* No single key support in LS ESBC header */
|
||||
if (!key_hash) {
|
||||
ret = algo->hash_update(algo, ctx,
|
||||
img->img_key, img->hdr.key_len, 0);
|
||||
key_hash = 1;
|
||||
}
|
||||
#endif
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!key_hash)
|
||||
return ERROR_KEY_TABLE_NOT_FOUND;
|
||||
|
||||
/* Update hash for actual Image */
|
||||
ret = algo->hash_update(algo, ctx,
|
||||
(u8 *)(*(img->img_addr_ptr)), img->img_size, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Copy hash at destination buffer */
|
||||
ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct encoded hash EM' wrt PKCSv1.5. This function calculates the
|
||||
* pointers for padding, DER value and hash. And finally, constructs EM'
|
||||
* which includes hash of complete CSF header and ESBC image. If SG flag
|
||||
* is on, hash of SG table and entries is also included.
|
||||
*/
|
||||
static void construct_img_encoded_hash_second(struct fsl_secboot_img_priv *img)
|
||||
{
|
||||
/*
|
||||
* RSA PKCSv1.5 encoding format for encoded message is below
|
||||
* EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash
|
||||
* PS is Padding String
|
||||
* DER is DER value for SHA-256
|
||||
* Hash is SHA-256 hash
|
||||
* *********************************************************
|
||||
* representative points to first byte of EM initially and is
|
||||
* filled with 0x0
|
||||
* representative is incremented by 1 and second byte is filled
|
||||
* with 0x1
|
||||
* padding points to third byte of EM
|
||||
* digest points to full length of EM - 32 bytes
|
||||
* hash_id (DER value) points to 19 bytes before pDigest
|
||||
* separator is one byte which separates padding and DER
|
||||
*/
|
||||
|
||||
size_t len;
|
||||
u8 *representative;
|
||||
u8 *padding, *digest;
|
||||
u8 *hash_id, *separator;
|
||||
int i;
|
||||
|
||||
len = (get_key_len(img) / 2) - 1;
|
||||
representative = img->img_encoded_hash_second;
|
||||
representative[0] = 0;
|
||||
representative[1] = 1; /* block type 1 */
|
||||
|
||||
padding = &representative[2];
|
||||
digest = &representative[1] + len - 32;
|
||||
hash_id = digest - sizeof(hash_identifier);
|
||||
separator = hash_id - 1;
|
||||
|
||||
/* fill padding area pointed by padding with 0xff */
|
||||
memset(padding, 0xff, separator - padding);
|
||||
|
||||
/* fill byte pointed by separator */
|
||||
*separator = 0;
|
||||
|
||||
/* fill SHA-256 DER value pointed by HashId */
|
||||
memcpy(hash_id, hash_identifier, sizeof(hash_identifier));
|
||||
|
||||
/* fill hash pointed by Digest */
|
||||
for (i = 0; i < SHA256_BYTES; i++)
|
||||
digest[i] = hash_val[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads and validates the ESBC client header.
|
||||
* This function reads key and signature from the ESBC client header.
|
||||
* If Scatter/Gather flag is on, lengths and offsets of images
|
||||
* present as SG entries are also read. This function also checks
|
||||
* whether the header is valid or not.
|
||||
*/
|
||||
static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img)
|
||||
{
|
||||
struct fsl_secboot_img_hdr *hdr = &img->hdr;
|
||||
void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
|
||||
u8 *k, *s;
|
||||
u32 ret = 0;
|
||||
|
||||
int key_found = 0;
|
||||
|
||||
/* check barker code */
|
||||
if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN))
|
||||
return ERROR_ESBC_CLIENT_HEADER_BARKER;
|
||||
|
||||
/* If Image Address is not passed as argument to function,
|
||||
* then Address and Size must be read from the Header.
|
||||
*/
|
||||
if (*(img->img_addr_ptr) == 0) {
|
||||
#ifdef CONFIG_ESBC_ADDR_64BIT
|
||||
*(img->img_addr_ptr) = hdr->pimg64;
|
||||
#else
|
||||
*(img->img_addr_ptr) = hdr->pimg;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!hdr->img_size)
|
||||
return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE;
|
||||
|
||||
img->img_size = hdr->img_size;
|
||||
|
||||
/* Key checking*/
|
||||
#ifdef CONFIG_KEY_REVOCATION
|
||||
if (check_srk(img)) {
|
||||
ret = read_validate_srk_tbl(img);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
key_found = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
|
||||
if (!key_found && check_ie(img)) {
|
||||
ret = read_validate_ie_tbl(img);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
key_found = 1;
|
||||
}
|
||||
#endif
|
||||
#ifndef CONFIG_ESBC_HDR_LS
|
||||
/* Single Key Feature not available in LS ESBC Header */
|
||||
if (key_found == 0) {
|
||||
ret = read_validate_single_key(img);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
key_found = 1;
|
||||
}
|
||||
#endif
|
||||
if (!key_found)
|
||||
return ERROR_KEY_TABLE_NOT_FOUND;
|
||||
|
||||
/* check signaure */
|
||||
if (get_key_len(img) == 2 * hdr->sign_len) {
|
||||
/* check signature length */
|
||||
if (!((hdr->sign_len == KEY_SIZE_BYTES / 4) ||
|
||||
(hdr->sign_len == KEY_SIZE_BYTES / 2) ||
|
||||
(hdr->sign_len == KEY_SIZE_BYTES)))
|
||||
return ERROR_ESBC_CLIENT_HEADER_SIG_LEN;
|
||||
} else {
|
||||
return ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN;
|
||||
}
|
||||
|
||||
memcpy(&img->img_sign, esbc + hdr->psign, hdr->sign_len);
|
||||
/* No SG support in LS-CH3 */
|
||||
#ifndef CONFIG_ESBC_HDR_LS
|
||||
/* No SG support */
|
||||
if (hdr->sg_flag)
|
||||
return ERROR_ESBC_CLIENT_HEADER_SG;
|
||||
#endif
|
||||
|
||||
/* modulus most significant bit should be set */
|
||||
k = (u8 *)&img->img_key;
|
||||
|
||||
if ((k[0] & 0x80) == 0)
|
||||
return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1;
|
||||
|
||||
/* modulus value should be odd */
|
||||
if ((k[get_key_len(img) / 2 - 1] & 0x1) == 0)
|
||||
return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2;
|
||||
|
||||
/* Check signature value < modulus value */
|
||||
s = (u8 *)&img->img_sign;
|
||||
|
||||
if (!(memcmp(s, k, hdr->sign_len) < 0))
|
||||
return ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD;
|
||||
|
||||
return ESBC_VALID_HDR;
|
||||
}
|
||||
|
||||
static inline int str2longbe(const char *p, ulong *num)
|
||||
{
|
||||
char *endptr;
|
||||
ulong tmp;
|
||||
|
||||
if (!p) {
|
||||
return 0;
|
||||
} else {
|
||||
tmp = simple_strtoul(p, &endptr, 16);
|
||||
if (sizeof(ulong) == 4)
|
||||
*num = cpu_to_be32(tmp);
|
||||
else
|
||||
*num = cpu_to_be64(tmp);
|
||||
}
|
||||
|
||||
return *p != '\0' && *endptr == '\0';
|
||||
}
|
||||
/* Function to calculate the ESBC Image Hash
|
||||
* and hash from Digital signature.
|
||||
* The Two hash's are compared to yield the
|
||||
* result of signature validation.
|
||||
*/
|
||||
static int calculate_cmp_img_sig(struct fsl_secboot_img_priv *img)
|
||||
{
|
||||
int ret;
|
||||
uint32_t key_len;
|
||||
struct key_prop prop;
|
||||
#if !defined(USE_HOSTCC)
|
||||
struct udevice *mod_exp_dev;
|
||||
#endif
|
||||
ret = calc_esbchdr_esbc_hash(img);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Construct encoded hash EM' wrt PKCSv1.5 */
|
||||
construct_img_encoded_hash_second(img);
|
||||
|
||||
/* Fill prop structure for public key */
|
||||
memset(&prop, 0, sizeof(struct key_prop));
|
||||
key_len = get_key_len(img) / 2;
|
||||
prop.modulus = img->img_key;
|
||||
prop.public_exponent = img->img_key + key_len;
|
||||
prop.num_bits = key_len * 8;
|
||||
prop.exp_len = key_len;
|
||||
|
||||
ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev);
|
||||
if (ret) {
|
||||
printf("RSA: Can't find Modular Exp implementation\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len,
|
||||
&prop, img->img_encoded_hash);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* compare the encoded messages EM' and EM wrt RSA PKCSv1.5
|
||||
* memcmp returns zero on success
|
||||
* memcmp returns non-zero on failure
|
||||
*/
|
||||
ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash,
|
||||
img->hdr.sign_len);
|
||||
|
||||
if (ret)
|
||||
return ERROR_ESBC_CLIENT_HASH_COMPARE_EM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* Function to initialize img priv and global data structure
|
||||
*/
|
||||
static int secboot_init(struct fsl_secboot_img_priv **img_ptr)
|
||||
{
|
||||
*img_ptr = malloc(sizeof(struct fsl_secboot_img_priv));
|
||||
|
||||
struct fsl_secboot_img_priv *img = *img_ptr;
|
||||
|
||||
if (!img)
|
||||
return -ENOMEM;
|
||||
memset(img, 0, sizeof(struct fsl_secboot_img_priv));
|
||||
|
||||
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
|
||||
if (glb.ie_addr)
|
||||
img->ie_addr = glb.ie_addr;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* haddr - Address of the header of image to be validated.
|
||||
* arg_hash_str - Option hash string. If provided, this
|
||||
* overrides the key hash in the SFP fuses.
|
||||
* img_addr_ptr - Optional pointer to address of image to be validated.
|
||||
* If non zero addr, this overrides the addr of image in header,
|
||||
* otherwise updated to image addr in header.
|
||||
* Acts as both input and output of function.
|
||||
* This pointer shouldn't be NULL.
|
||||
*/
|
||||
int fsl_secboot_validate(uintptr_t haddr, char *arg_hash_str,
|
||||
uintptr_t *img_addr_ptr)
|
||||
{
|
||||
struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
|
||||
ulong hash[SHA256_BYTES/sizeof(ulong)];
|
||||
char hash_str[NUM_HEX_CHARS + 1];
|
||||
struct fsl_secboot_img_priv *img;
|
||||
struct fsl_secboot_img_hdr *hdr;
|
||||
void *esbc;
|
||||
int ret, i, hash_cmd = 0;
|
||||
u32 srk_hash[8];
|
||||
|
||||
if (arg_hash_str != NULL) {
|
||||
const char *cp = arg_hash_str;
|
||||
int i = 0;
|
||||
|
||||
if (*cp == '0' && *(cp + 1) == 'x')
|
||||
cp += 2;
|
||||
|
||||
/* The input string expected is in hex, where
|
||||
* each 4 bits would be represented by a hex
|
||||
* sha256 hash is 256 bits long, which would mean
|
||||
* num of characters = 256 / 4
|
||||
*/
|
||||
if (strlen(cp) != SHA256_NIBBLES) {
|
||||
printf("%s is not a 256 bits hex string as expected\n",
|
||||
arg_hash_str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(hash)/sizeof(ulong); i++) {
|
||||
strncpy(hash_str, cp + (i * NUM_HEX_CHARS),
|
||||
NUM_HEX_CHARS);
|
||||
hash_str[NUM_HEX_CHARS] = '\0';
|
||||
if (!str2longbe(hash_str, &hash[i])) {
|
||||
printf("%s is not a 256 bits hex string ",
|
||||
arg_hash_str);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
hash_cmd = 1;
|
||||
}
|
||||
|
||||
ret = secboot_init(&img);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
/* Update the information in Private Struct */
|
||||
hdr = &img->hdr;
|
||||
img->ehdrloc = haddr;
|
||||
img->img_addr_ptr = img_addr_ptr;
|
||||
esbc = (u8 *)img->ehdrloc;
|
||||
|
||||
memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr));
|
||||
|
||||
/* read and validate esbc header */
|
||||
ret = read_validate_esbc_client_header(img);
|
||||
|
||||
if (ret != ESBC_VALID_HDR) {
|
||||
fsl_secboot_handle_error(ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* SRKH present in SFP */
|
||||
for (i = 0; i < NUM_SRKH_REGS; i++)
|
||||
srk_hash[i] = srk_in32(&sfp_regs->srk_hash[i]);
|
||||
|
||||
/*
|
||||
* Calculate hash of key obtained via offset present in
|
||||
* ESBC uboot client hdr
|
||||
*/
|
||||
ret = calc_img_key_hash(img);
|
||||
if (ret) {
|
||||
fsl_secblk_handle_error(ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Compare hash obtained above with SRK hash present in SFP */
|
||||
if (hash_cmd)
|
||||
ret = memcmp(&hash, &img->img_key_hash, SHA256_BYTES);
|
||||
else
|
||||
ret = memcmp(srk_hash, img->img_key_hash, SHA256_BYTES);
|
||||
|
||||
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
|
||||
if (!hash_cmd && check_ie(img))
|
||||
ret = 0;
|
||||
#endif
|
||||
|
||||
if (ret != 0) {
|
||||
fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_KEY);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = calculate_cmp_img_sig(img);
|
||||
if (ret) {
|
||||
fsl_secboot_handle_error(ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
/* Free Img as it was malloc'ed*/
|
||||
free(img);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2010-2011 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "ics307_clk.h"
|
||||
|
||||
#if defined(CONFIG_FSL_NGPIXIS)
|
||||
#include "ngpixis.h"
|
||||
#define fpga_reg pixis
|
||||
#elif defined(CONFIG_FSL_QIXIS)
|
||||
#include "qixis.h"
|
||||
#define fpga_reg ((struct qixis *)QIXIS_BASE)
|
||||
#else
|
||||
#include "pixis.h"
|
||||
#define fpga_reg pixis
|
||||
#endif
|
||||
|
||||
/* define for SYS CLK or CLK1Frequency */
|
||||
#define TTL 1
|
||||
#define CLK2 0
|
||||
#define CRYSTAL 0
|
||||
#define MAX_VDW (511 + 8)
|
||||
#define MAX_RDW (127 + 2)
|
||||
#define MIN_VDW (4 + 8)
|
||||
#define MIN_RDW (1 + 2)
|
||||
#define NUM_OD_SETTING 8
|
||||
/*
|
||||
* These defines cover the industrial temperature range part,
|
||||
* for commercial, change below to 400000 and 55000, respectively
|
||||
*/
|
||||
#define MAX_VCO 360000
|
||||
#define MIN_VCO 60000
|
||||
|
||||
/* decode S[0-2] to Output Divider (OD) */
|
||||
static u8 ics307_s_to_od[] = {
|
||||
10, 2, 8, 4, 5, 7, 3, 6
|
||||
};
|
||||
|
||||
/*
|
||||
* Find one solution to generate required frequency for SYSCLK
|
||||
* out_freq: KHz, required frequency to the SYSCLK
|
||||
* the result will be retuned with component RDW, VDW, OD, TTL,
|
||||
* CLK2 and crystal
|
||||
*/
|
||||
unsigned long ics307_sysclk_calculator(unsigned long out_freq)
|
||||
{
|
||||
const unsigned long input_freq = CONFIG_ICS307_REFCLK_HZ;
|
||||
unsigned long vdw, rdw, odp, s_vdw = 0, s_rdw = 0, s_odp = 0, od;
|
||||
unsigned long tmp_out, diff, result = 0;
|
||||
int found = 0;
|
||||
|
||||
for (odp = 0; odp < NUM_OD_SETTING; odp++) {
|
||||
od = ics307_s_to_od[odp];
|
||||
if (od * out_freq < MIN_VCO || od * out_freq > MAX_VCO)
|
||||
continue;
|
||||
for (rdw = MIN_RDW; rdw <= MAX_RDW; rdw++) {
|
||||
/* Calculate the VDW */
|
||||
vdw = out_freq * 1000 * od * rdw / (input_freq * 2);
|
||||
if (vdw > MAX_VDW)
|
||||
vdw = MAX_VDW;
|
||||
if (vdw < MIN_VDW)
|
||||
continue;
|
||||
/* Calculate the temp out frequency */
|
||||
tmp_out = input_freq * 2 * vdw / (rdw * od * 1000);
|
||||
diff = max(out_freq, tmp_out) - min(out_freq, tmp_out);
|
||||
/*
|
||||
* calculate the percent, the precision is 1/1000
|
||||
* If greater than 1/1000, continue
|
||||
* otherwise, we think the solution is we required
|
||||
*/
|
||||
if (diff * 1000 / out_freq > 1)
|
||||
continue;
|
||||
else {
|
||||
s_vdw = vdw;
|
||||
s_rdw = rdw;
|
||||
s_odp = odp;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
result = (s_rdw - 2) | (s_vdw - 8) << 7 | s_odp << 16 |
|
||||
CLK2 << 19 | TTL << 21 | CRYSTAL << 22;
|
||||
|
||||
debug("ICS307-02: RDW: %ld, VDW: %ld, OD: %d\n", s_rdw - 2, s_vdw - 8,
|
||||
ics307_s_to_od[s_odp]);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate frequency being generated by ICS307-02 clock chip based upon
|
||||
* the control bytes being programmed into it.
|
||||
*/
|
||||
static unsigned long ics307_clk_freq(u8 cw0, u8 cw1, u8 cw2)
|
||||
{
|
||||
const unsigned long input_freq = CONFIG_ICS307_REFCLK_HZ;
|
||||
unsigned long vdw = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1);
|
||||
unsigned long rdw = cw2 & 0x7F;
|
||||
unsigned long od = ics307_s_to_od[cw0 & 0x7];
|
||||
unsigned long freq;
|
||||
|
||||
/*
|
||||
* CLK1 Freq = Input Frequency * 2 * (VDW + 8) / ((RDW + 2) * OD)
|
||||
*
|
||||
* cw0: C1 C0 TTL F1 F0 S2 S1 S0
|
||||
* cw1: V8 V7 V6 V5 V4 V3 V2 V1
|
||||
* cw2: V0 R6 R5 R4 R3 R2 R1 R0
|
||||
*
|
||||
* R6:R0 = Reference Divider Word (RDW)
|
||||
* V8:V0 = VCO Divider Word (VDW)
|
||||
* S2:S0 = Output Divider Select (OD)
|
||||
* F1:F0 = Function of CLK2 Output
|
||||
* TTL = duty cycle
|
||||
* C1:C0 = internal load capacitance for cyrstal
|
||||
*
|
||||
*/
|
||||
|
||||
freq = input_freq * 2 * (vdw + 8) / ((rdw + 2) * od);
|
||||
|
||||
debug("ICS307: CW[0-2]: %02X %02X %02X => %lu Hz\n", cw0, cw1, cw2,
|
||||
freq);
|
||||
return freq;
|
||||
}
|
||||
|
||||
unsigned long get_board_sys_clk(void)
|
||||
{
|
||||
return ics307_clk_freq(
|
||||
in_8(&fpga_reg->sclk[0]),
|
||||
in_8(&fpga_reg->sclk[1]),
|
||||
in_8(&fpga_reg->sclk[2]));
|
||||
}
|
||||
|
||||
unsigned long get_board_ddr_clk(void)
|
||||
{
|
||||
return ics307_clk_freq(
|
||||
in_8(&fpga_reg->dclk[0]),
|
||||
in_8(&fpga_reg->dclk[1]),
|
||||
in_8(&fpga_reg->dclk[2]));
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2010-2011 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
#ifndef __ICS_CLK_H_
|
||||
#define __ICS_CLK_H_ 1
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern unsigned long get_board_sys_clk(void);
|
||||
extern unsigned long get_board_ddr_clk(void);
|
||||
extern unsigned long ics307_sysclk_calculator(unsigned long out_freq);
|
||||
#endif
|
||||
|
||||
#endif /* __ICS_CLK_H_ */
|
||||
@@ -0,0 +1,206 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
* Author: Shaveta Leekha <shaveta@freescale.com>
|
||||
*/
|
||||
|
||||
#include "idt8t49n222a_serdes_clk.h"
|
||||
|
||||
#define DEVICE_ID_REG 0x00
|
||||
|
||||
static int check_pll_status(u8 idt_addr)
|
||||
{
|
||||
u8 val = 0;
|
||||
int ret;
|
||||
|
||||
ret = i2c_read(idt_addr, 0x17, 1, &val, 1);
|
||||
if (ret < 0) {
|
||||
printf("IDT:0x%x could not read status register from device.\n",
|
||||
idt_addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (val & 0x04) {
|
||||
debug("idt8t49n222a PLL is LOCKED: %x\n", val);
|
||||
} else {
|
||||
printf("idt8t49n222a PLL is not LOCKED: %x\n", val);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_serdes_refclk(u8 idt_addr, u8 serdes_num,
|
||||
enum serdes_refclk refclk1,
|
||||
enum serdes_refclk refclk2, u8 feedback)
|
||||
{
|
||||
u8 dev_id = 0;
|
||||
int i, ret;
|
||||
|
||||
debug("IDT:Configuring idt8t49n222a device at I2C address: 0x%2x\n",
|
||||
idt_addr);
|
||||
|
||||
ret = i2c_read(idt_addr, DEVICE_ID_REG, 1, &dev_id, 1);
|
||||
if (ret < 0) {
|
||||
debug("IDT:0x%x could not read DEV_ID from device.\n",
|
||||
idt_addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((dev_id != 0x00) && (dev_id != 0x24) && (dev_id != 0x2a)) {
|
||||
debug("IDT: device at address 0x%x is not idt8t49n222a.\n",
|
||||
idt_addr);
|
||||
}
|
||||
|
||||
if (serdes_num != 1 && serdes_num != 2) {
|
||||
debug("serdes_num should be 1 for SerDes1 and"
|
||||
" 2 for SerDes2.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((refclk1 == SERDES_REFCLK_122_88 && refclk2 != SERDES_REFCLK_122_88)
|
||||
|| (refclk1 != SERDES_REFCLK_122_88
|
||||
&& refclk2 == SERDES_REFCLK_122_88)) {
|
||||
debug("Only one refclk at 122.88MHz is not supported."
|
||||
" Please set both refclk1 & refclk2 to 122.88MHz"
|
||||
" or both not to 122.88MHz.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (refclk1 != SERDES_REFCLK_100 && refclk1 != SERDES_REFCLK_122_88
|
||||
&& refclk1 != SERDES_REFCLK_125
|
||||
&& refclk1 != SERDES_REFCLK_156_25) {
|
||||
debug("refclk1 should be 100MHZ, 122.88MHz, 125MHz"
|
||||
" or 156.25MHz.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (refclk2 != SERDES_REFCLK_100 && refclk2 != SERDES_REFCLK_122_88
|
||||
&& refclk2 != SERDES_REFCLK_125
|
||||
&& refclk2 != SERDES_REFCLK_156_25) {
|
||||
debug("refclk2 should be 100MHZ, 122.88MHz, 125MHz"
|
||||
" or 156.25MHz.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (feedback != 0 && feedback != 1) {
|
||||
debug("valid values for feedback are 0(default) or 1.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Configuring IDT for output refclks as
|
||||
* Refclk1 = 122.88MHz Refclk2 = 122.88MHz
|
||||
*/
|
||||
if (refclk1 == SERDES_REFCLK_122_88 &&
|
||||
refclk2 == SERDES_REFCLK_122_88) {
|
||||
printf("Setting refclk1:122.88 and refclk2:122.88\n");
|
||||
for (i = 0; i < NUM_IDT_REGS; i++)
|
||||
i2c_reg_write(idt_addr, idt_conf_122_88[i][0],
|
||||
idt_conf_122_88[i][1]);
|
||||
|
||||
if (feedback) {
|
||||
for (i = 0; i < NUM_IDT_REGS_FEEDBACK; i++)
|
||||
i2c_reg_write(idt_addr,
|
||||
idt_conf_122_88_feedback[i][0],
|
||||
idt_conf_122_88_feedback[i][1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (refclk1 != SERDES_REFCLK_122_88 &&
|
||||
refclk2 != SERDES_REFCLK_122_88) {
|
||||
for (i = 0; i < NUM_IDT_REGS; i++)
|
||||
i2c_reg_write(idt_addr, idt_conf_not_122_88[i][0],
|
||||
idt_conf_not_122_88[i][1]);
|
||||
}
|
||||
|
||||
/* Configuring IDT for output refclks as
|
||||
* Refclk1 = 100MHz Refclk2 = 125MHz
|
||||
*/
|
||||
if (refclk1 == SERDES_REFCLK_100 && refclk2 == SERDES_REFCLK_125) {
|
||||
printf("Setting refclk1:100 and refclk2:125\n");
|
||||
i2c_reg_write(idt_addr, 0x11, 0x10);
|
||||
}
|
||||
|
||||
/* Configuring IDT for output refclks as
|
||||
* Refclk1 = 125MHz Refclk2 = 125MHz
|
||||
*/
|
||||
if (refclk1 == SERDES_REFCLK_125 && refclk2 == SERDES_REFCLK_125) {
|
||||
printf("Setting refclk1:125 and refclk2:125\n");
|
||||
i2c_reg_write(idt_addr, 0x10, 0x10);
|
||||
i2c_reg_write(idt_addr, 0x11, 0x10);
|
||||
}
|
||||
|
||||
/* Configuring IDT for output refclks as
|
||||
* Refclk1 = 125MHz Refclk2 = 100MHz
|
||||
*/
|
||||
if (refclk1 == SERDES_REFCLK_125 && refclk2 == SERDES_REFCLK_100) {
|
||||
printf("Setting refclk1:125 and refclk2:100\n");
|
||||
i2c_reg_write(idt_addr, 0x10, 0x10);
|
||||
}
|
||||
|
||||
/* Configuring IDT for output refclks as
|
||||
* Refclk1 = 156.25MHz Refclk2 = 156.25MHz
|
||||
*/
|
||||
if (refclk1 == SERDES_REFCLK_156_25 &&
|
||||
refclk2 == SERDES_REFCLK_156_25) {
|
||||
printf("Setting refclk1:156.25 and refclk2:156.25\n");
|
||||
for (i = 0; i < NUM_IDT_REGS_156_25; i++)
|
||||
i2c_reg_write(idt_addr, idt_conf_156_25[i][0],
|
||||
idt_conf_156_25[i][1]);
|
||||
}
|
||||
|
||||
/* Configuring IDT for output refclks as
|
||||
* Refclk1 = 100MHz Refclk2 = 156.25MHz
|
||||
*/
|
||||
if (refclk1 == SERDES_REFCLK_100 &&
|
||||
refclk2 == SERDES_REFCLK_156_25) {
|
||||
printf("Setting refclk1:100 and refclk2:156.25\n");
|
||||
for (i = 0; i < NUM_IDT_REGS_156_25; i++)
|
||||
i2c_reg_write(idt_addr, idt_conf_100_156_25[i][0],
|
||||
idt_conf_100_156_25[i][1]);
|
||||
}
|
||||
|
||||
/* Configuring IDT for output refclks as
|
||||
* Refclk1 = 125MHz Refclk2 = 156.25MHz
|
||||
*/
|
||||
if (refclk1 == SERDES_REFCLK_125 &&
|
||||
refclk2 == SERDES_REFCLK_156_25) {
|
||||
printf("Setting refclk1:125 and refclk2:156.25\n");
|
||||
for (i = 0; i < NUM_IDT_REGS_156_25; i++)
|
||||
i2c_reg_write(idt_addr, idt_conf_125_156_25[i][0],
|
||||
idt_conf_125_156_25[i][1]);
|
||||
}
|
||||
|
||||
/* Configuring IDT for output refclks as
|
||||
* Refclk1 = 156.25MHz Refclk2 = 100MHz
|
||||
*/
|
||||
if (refclk1 == SERDES_REFCLK_156_25 &&
|
||||
refclk2 == SERDES_REFCLK_100) {
|
||||
printf("Setting refclk1:156.25 and refclk2:100\n");
|
||||
for (i = 0; i < NUM_IDT_REGS_156_25; i++)
|
||||
i2c_reg_write(idt_addr, idt_conf_156_25_100[i][0],
|
||||
idt_conf_156_25_100[i][1]);
|
||||
}
|
||||
|
||||
/* Configuring IDT for output refclks as
|
||||
* Refclk1 = 156.25MHz Refclk2 = 125MHz
|
||||
*/
|
||||
if (refclk1 == SERDES_REFCLK_156_25 &&
|
||||
refclk2 == SERDES_REFCLK_125) {
|
||||
printf("Setting refclk1:156.25 and refclk2:125\n");
|
||||
for (i = 0; i < NUM_IDT_REGS_156_25; i++)
|
||||
i2c_reg_write(idt_addr, idt_conf_156_25_125[i][0],
|
||||
idt_conf_156_25_125[i][1]);
|
||||
}
|
||||
|
||||
/* waiting for maximum of 1 second if PLL doesn'r get locked
|
||||
* initially. then check the status again.
|
||||
*/
|
||||
if (check_pll_status(idt_addr)) {
|
||||
mdelay(1000);
|
||||
if (check_pll_status(idt_addr))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
* Author: Shaveta Leekha <shaveta@freescale.com>
|
||||
*/
|
||||
|
||||
#ifndef __IDT8T49N222A_SERDES_CLK_H_
|
||||
#define __IDT8T49N222A_SERDES_CLK_H_ 1
|
||||
|
||||
#include <common.h>
|
||||
#include <i2c.h>
|
||||
#include "qixis.h"
|
||||
#include "../b4860qds/b4860qds_qixis.h"
|
||||
#include <errno.h>
|
||||
|
||||
#define NUM_IDT_REGS 23
|
||||
#define NUM_IDT_REGS_FEEDBACK 12
|
||||
#define NUM_IDT_REGS_156_25 11
|
||||
|
||||
/* CLK */
|
||||
enum serdes_refclk {
|
||||
SERDES_REFCLK_100, /* refclk 100Mhz */
|
||||
SERDES_REFCLK_122_88, /* refclk 122.88Mhz */
|
||||
SERDES_REFCLK_125, /* refclk 125Mhz */
|
||||
SERDES_REFCLK_156_25, /* refclk 156.25Mhz */
|
||||
SERDES_REFCLK_NONE = -1,
|
||||
};
|
||||
|
||||
/* configuration values for IDT registers for Output Refclks:
|
||||
* Refclk1 = 122.88MHz Refclk2 = 122.88MHz
|
||||
*/
|
||||
static const u8 idt_conf_122_88[23][2] = { {0x00, 0x3C}, {0x01, 0x00},
|
||||
{0x02, 0x9F}, {0x03, 0x00}, {0x04, 0x0B}, {0x05, 0x00},
|
||||
{0x06, 0x00}, {0x07, 0x00}, {0x08, 0x7D}, {0x09, 0x00},
|
||||
{0x0A, 0x08}, {0x0B, 0x00}, {0x0C, 0xDC}, {0x0D, 0x00},
|
||||
{0x0E, 0x00}, {0x0F, 0x00}, {0x10, 0x12}, {0x11, 0x12},
|
||||
{0x12, 0xB9}, {0x13, 0xBC}, {0x14, 0x40}, {0x15, 0x08},
|
||||
{0x16, 0xA0} };
|
||||
|
||||
|
||||
/* configuration values for IDT registers for Output Refclks:
|
||||
* Refclk1 not equal to 122.88MHz Refclk2 not equal to 122.88MHz
|
||||
*/
|
||||
static const u8 idt_conf_not_122_88[23][2] = { {0x00, 0x00}, {0x01, 0x00},
|
||||
{0x02, 0x00}, {0x03, 0x00}, {0x04, 0x0A}, {0x05, 0x00},
|
||||
{0x06, 0x00}, {0x07, 0x00}, {0x08, 0x7D}, {0x09, 0x00},
|
||||
{0x0A, 0x08}, {0x0B, 0x00}, {0x0C, 0xDC}, {0x0D, 0x00},
|
||||
{0x0E, 0x00}, {0x0F, 0x00}, {0x10, 0x14}, {0x11, 0x14},
|
||||
{0x12, 0x35}, {0x13, 0xBC}, {0x14, 0x40}, {0x15, 0x08},
|
||||
{0x16, 0xA0} };
|
||||
|
||||
/* Reconfiguration values for some of IDT registers for
|
||||
* Output Refclks:
|
||||
* Refclk1 = 122.88MHz Refclk2 = 122.88MHz
|
||||
* and with feedback as 1
|
||||
*/
|
||||
static const u8 idt_conf_122_88_feedback[12][2] = { {0x00, 0x50}, {0x02, 0xD7},
|
||||
{0x04, 0x89}, {0x06, 0xC3}, {0x08, 0xC0}, {0x0A, 0x07},
|
||||
{0x0C, 0x80}, {0x10, 0x10}, {0x11, 0x10}, {0x12, 0x1B},
|
||||
{0x14, 0x00}, {0x15, 0xE8} };
|
||||
|
||||
/* configuration values for IDT registers for Output Refclks:
|
||||
* Refclk1 : 156.25MHz Refclk2 : 156.25MHz
|
||||
*/
|
||||
static const u8 idt_conf_156_25[11][2] = { {0x04, 0x19}, {0x06, 0x03},
|
||||
{0x08, 0xC0}, {0x0A, 0x07}, {0x0C, 0xA1}, {0x0E, 0x20},
|
||||
{0x10, 0x10}, {0x11, 0x10}, {0x12, 0xB5}, {0x13, 0x3C},
|
||||
{0x15, 0xE8} };
|
||||
|
||||
/* configuration values for IDT registers for Output Refclks:
|
||||
* Refclk1 : 100MHz Refclk2 : 156.25MHz
|
||||
*/
|
||||
static const u8 idt_conf_100_156_25[11][2] = { {0x04, 0x19}, {0x06, 0x03},
|
||||
{0x08, 0xC0}, {0x0A, 0x07}, {0x0C, 0xA1}, {0x0E, 0x20},
|
||||
{0x10, 0x19}, {0x11, 0x10}, {0x12, 0xB5}, {0x13, 0x3C},
|
||||
{0x15, 0xE8} };
|
||||
|
||||
/* configuration values for IDT registers for Output Refclks:
|
||||
* Refclk1 : 125MHz Refclk2 : 156.25MHz
|
||||
*/
|
||||
static const u8 idt_conf_125_156_25[11][2] = { {0x04, 0x19}, {0x06, 0x03},
|
||||
{0x08, 0xC0}, {0x0A, 0x07}, {0x0C, 0xA1}, {0x0E, 0x20},
|
||||
{0x10, 0x14}, {0x11, 0x10}, {0x12, 0xB5}, {0x13, 0x3C},
|
||||
{0x15, 0xE8} };
|
||||
|
||||
/* configuration values for IDT registers for Output Refclks:
|
||||
* Refclk1 : 156.25MHz Refclk2 : 100MHz
|
||||
*/
|
||||
static const u8 idt_conf_156_25_100[11][2] = { {0x04, 0x19}, {0x06, 0x03},
|
||||
{0x08, 0xC0}, {0x0A, 0x07}, {0x0C, 0xA1}, {0x0E, 0x20},
|
||||
{0x10, 0x10}, {0x11, 0x19}, {0x12, 0xB5}, {0x13, 0x3C},
|
||||
{0x15, 0xE8} };
|
||||
|
||||
/* configuration values for IDT registers for Output Refclks:
|
||||
* Refclk1 : 156.25MHz Refclk2 : 125MHz
|
||||
*/
|
||||
static const u8 idt_conf_156_25_125[11][2] = { {0x04, 0x19}, {0x06, 0x03},
|
||||
{0x08, 0xC0}, {0x0A, 0x07}, {0x0C, 0xA1}, {0x0E, 0x20},
|
||||
{0x10, 0x10}, {0x11, 0x14}, {0x12, 0xB5}, {0x13, 0x3C},
|
||||
{0x15, 0xE8} };
|
||||
|
||||
int set_serdes_refclk(u8 idt_addr, u8 serdes_num,
|
||||
enum serdes_refclk refclk1,
|
||||
enum serdes_refclk refclk2, u8 feedback);
|
||||
|
||||
#endif /*__IDT8T49N222A_SERDES_CLK_H_ */
|
||||
@@ -0,0 +1,35 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/ls102xa_stream_id.h>
|
||||
|
||||
void ls102xa_config_smmu_stream_id(struct smmu_stream_id *id, uint32_t num)
|
||||
{
|
||||
void *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
|
||||
int i;
|
||||
u32 icid;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
icid = (id[i].stream_id & 0xff) << 24;
|
||||
out_be32((u32 *)(scfg + id[i].offset), icid);
|
||||
}
|
||||
}
|
||||
|
||||
void ls1021x_config_caam_stream_id(struct liodn_id_table *tbl, int size)
|
||||
{
|
||||
int i;
|
||||
u32 liodn;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (tbl[i].num_ids == 2)
|
||||
liodn = (tbl[i].id[0] << 16) | tbl[i].id[1];
|
||||
else
|
||||
liodn = tbl[i].id[0];
|
||||
|
||||
out_le32((u32 *)(tbl[i].reg_offset), liodn);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2016 Freescale Semiconductor, Inc.
|
||||
* Hou Zhiqiang <Zhiqiang.Hou@freescale.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <i2c.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/mc34vr500_pmic.h>
|
||||
|
||||
static uint8_t swxvolt_addr[4] = { MC34VR500_SW1VOLT,
|
||||
MC34VR500_SW2VOLT,
|
||||
MC34VR500_SW3VOLT,
|
||||
MC34VR500_SW4VOLT };
|
||||
|
||||
static uint8_t swx_set_point_base[4] = { 13, 9, 9, 9 };
|
||||
|
||||
int mc34vr500_get_sw_volt(uint8_t sw)
|
||||
{
|
||||
struct pmic *p;
|
||||
u32 swxvolt;
|
||||
uint8_t spb;
|
||||
int sw_volt;
|
||||
int ret;
|
||||
|
||||
debug("%s: Get SW%u volt from swxvolt_addr = 0x%x\n",
|
||||
__func__, sw + 1, swxvolt_addr[sw]);
|
||||
if (sw > SW4) {
|
||||
printf("%s: Unsupported SW(sw%d)\n", __func__, sw + 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
p = pmic_get("MC34VR500");
|
||||
if (!p) {
|
||||
printf("%s: Did NOT find PMIC MC34VR500\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = pmic_probe(p);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pmic_reg_read(p, swxvolt_addr[sw], &swxvolt);
|
||||
if (ret) {
|
||||
printf("%s: Failed to get SW%u volt\n", __func__, sw + 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
debug("%s: SW%d step point swxvolt = %u\n", __func__, sw + 1, swxvolt);
|
||||
spb = swx_set_point_base[sw];
|
||||
/* The base of SW volt is 625mV and increase by step 25mV */
|
||||
sw_volt = 625 + (swxvolt - spb) * 25;
|
||||
|
||||
debug("%s: SW%u volt = %dmV\n", __func__, sw + 1, sw_volt);
|
||||
return sw_volt;
|
||||
}
|
||||
|
||||
int mc34vr500_set_sw_volt(uint8_t sw, int sw_volt)
|
||||
{
|
||||
struct pmic *p;
|
||||
u32 swxvolt;
|
||||
uint8_t spb;
|
||||
int ret;
|
||||
|
||||
debug("%s: Set SW%u volt to %dmV\n", __func__, sw + 1, sw_volt);
|
||||
/* The least SW volt is 625mV, and only 4 SW outputs */
|
||||
if (sw > SW4 || sw_volt < 625)
|
||||
return -EINVAL;
|
||||
|
||||
p = pmic_get("MC34VR500");
|
||||
if (!p) {
|
||||
printf("%s: Did NOT find PMIC MC34VR500\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = pmic_probe(p);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
spb = swx_set_point_base[sw];
|
||||
/* The base of SW volt is 625mV and increase by step 25mV */
|
||||
swxvolt = (sw_volt - 625) / 25 + spb;
|
||||
debug("%s: SW%d step point swxvolt = %u\n", __func__, sw + 1, swxvolt);
|
||||
if (swxvolt > 63)
|
||||
return -EINVAL;
|
||||
|
||||
ret = pmic_reg_write(p, swxvolt_addr[sw], swxvolt);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/immap_85xx.h>
|
||||
#include "sleep.h"
|
||||
#ifdef CONFIG_U_QE
|
||||
#include <fsl_qe.h>
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
void __weak board_mem_sleep_setup(void)
|
||||
{
|
||||
}
|
||||
|
||||
void __weak board_sleep_prepare(void)
|
||||
{
|
||||
}
|
||||
|
||||
bool is_warm_boot(void)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
|
||||
|
||||
if (in_be32(&gur->scrtsr[0]) & DCFG_CCSR_CRSTSR_WDRFR)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fsl_dp_disable_console(void)
|
||||
{
|
||||
gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE;
|
||||
}
|
||||
|
||||
/*
|
||||
* When wakeup from deep sleep, the first 128 bytes space
|
||||
* will be used to do DDR training which corrupts the data
|
||||
* in there. This function will restore them.
|
||||
*/
|
||||
static void dp_ddr_restore(void)
|
||||
{
|
||||
u64 *src, *dst;
|
||||
int i;
|
||||
struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_MPC85xx_SCFG;
|
||||
|
||||
/* get the address of ddr date from SPARECR3 */
|
||||
src = (u64 *)(in_be32(&scfg->sparecr[2]) + DDR_BUFF_LEN - 8);
|
||||
dst = (u64 *)(CONFIG_SYS_SDRAM_BASE + DDR_BUFF_LEN - 8);
|
||||
|
||||
for (i = 0; i < DDR_BUFF_LEN / 8; i++)
|
||||
*dst-- = *src--;
|
||||
|
||||
flush_dcache();
|
||||
}
|
||||
|
||||
static void dp_resume_prepare(void)
|
||||
{
|
||||
dp_ddr_restore();
|
||||
|
||||
board_sleep_prepare();
|
||||
|
||||
l2cache_init();
|
||||
#if defined(CONFIG_RAMBOOT_PBL)
|
||||
disable_cpc_sram();
|
||||
#endif
|
||||
enable_cpc();
|
||||
|
||||
#ifdef CONFIG_U_QE
|
||||
u_qe_resume();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int fsl_dp_resume(void)
|
||||
{
|
||||
u32 start_addr;
|
||||
void (*kernel_resume)(void);
|
||||
struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_MPC85xx_SCFG;
|
||||
|
||||
if (!is_warm_boot())
|
||||
return 0;
|
||||
|
||||
dp_resume_prepare();
|
||||
|
||||
/* Get the entry address and jump to kernel */
|
||||
start_addr = in_be32(&scfg->sparecr[1]);
|
||||
debug("Entry address is 0x%08x\n", start_addr);
|
||||
kernel_resume = (void (*)(void))start_addr;
|
||||
kernel_resume();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/**
|
||||
* Copyright 2010-2011 Freescale Semiconductor
|
||||
* Author: Timur Tabi <timur@freescale.com>
|
||||
*
|
||||
* This file provides support for the ngPIXIS, a board-specific FPGA used on
|
||||
* some Freescale reference boards.
|
||||
*
|
||||
* A "switch" is black rectangular block on the motherboard. It contains
|
||||
* eight "bits". The ngPIXIS has a set of memory-mapped registers (SWx) that
|
||||
* shadow the actual physical switches. There is also another set of
|
||||
* registers (ENx) that tell the ngPIXIS which bits of SWx should actually be
|
||||
* used to override the values of the bits in the physical switches.
|
||||
*
|
||||
* The following macros need to be defined:
|
||||
*
|
||||
* PIXIS_BASE - The virtual address of the base of the PIXIS register map
|
||||
*
|
||||
* PIXIS_LBMAP_SWITCH - The switch number (i.e. the "x" in "SWx"). This value
|
||||
* is used in the PIXIS_SW() macro to determine which offset in
|
||||
* the PIXIS register map corresponds to the physical switch that controls
|
||||
* the boot bank.
|
||||
*
|
||||
* PIXIS_LBMAP_MASK - A bit mask the defines which bits in SWx to use.
|
||||
*
|
||||
* PIXIS_LBMAP_SHIFT - The shift value that corresponds to PIXIS_LBMAP_MASK.
|
||||
*
|
||||
* PIXIS_LBMAP_ALTBANK - The value to program into SWx to tell the ngPIXIS to
|
||||
* boot from the alternate bank.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "ngpixis.h"
|
||||
|
||||
static u8 __pixis_read(unsigned int reg)
|
||||
{
|
||||
void *p = (void *)PIXIS_BASE;
|
||||
|
||||
return in_8(p + reg);
|
||||
}
|
||||
u8 pixis_read(unsigned int reg) __attribute__((weak, alias("__pixis_read")));
|
||||
|
||||
static void __pixis_write(unsigned int reg, u8 value)
|
||||
{
|
||||
void *p = (void *)PIXIS_BASE;
|
||||
|
||||
out_8(p + reg, value);
|
||||
}
|
||||
void pixis_write(unsigned int reg, u8 value)
|
||||
__attribute__((weak, alias("__pixis_write")));
|
||||
|
||||
/*
|
||||
* Reset the board. This ignores the ENx registers.
|
||||
*/
|
||||
void __pixis_reset(void)
|
||||
{
|
||||
PIXIS_WRITE(rst, 0);
|
||||
|
||||
while (1);
|
||||
}
|
||||
void pixis_reset(void) __attribute__((weak, alias("__pixis_reset")));
|
||||
|
||||
/*
|
||||
* Reset the board. Like pixis_reset(), but it honors the ENx registers.
|
||||
*/
|
||||
void __pixis_bank_reset(void)
|
||||
{
|
||||
PIXIS_WRITE(vctl, 0);
|
||||
PIXIS_WRITE(vctl, 1);
|
||||
|
||||
while (1);
|
||||
}
|
||||
void pixis_bank_reset(void) __attribute__((weak, alias("__pixis_bank_reset")));
|
||||
|
||||
/**
|
||||
* Set the boot bank to the power-on default bank
|
||||
*/
|
||||
void __clear_altbank(void)
|
||||
{
|
||||
u8 reg;
|
||||
|
||||
/* Tell the ngPIXIS to use this the bits in the physical switch for the
|
||||
* boot bank value, instead of the SWx register. We need to be careful
|
||||
* only to set the bits in SWx that correspond to the boot bank.
|
||||
*/
|
||||
reg = PIXIS_READ(s[PIXIS_LBMAP_SWITCH - 1].en);
|
||||
reg &= ~PIXIS_LBMAP_MASK;
|
||||
PIXIS_WRITE(s[PIXIS_LBMAP_SWITCH - 1].en, reg);
|
||||
}
|
||||
void clear_altbank(void) __attribute__((weak, alias("__clear_altbank")));
|
||||
|
||||
/**
|
||||
* Set the boot bank to the alternate bank
|
||||
*/
|
||||
void __set_altbank(void)
|
||||
{
|
||||
u8 reg;
|
||||
|
||||
/* Program the alternate bank number into the SWx register.
|
||||
*/
|
||||
reg = PIXIS_READ(s[PIXIS_LBMAP_SWITCH - 1].sw);
|
||||
reg = (reg & ~PIXIS_LBMAP_MASK) | PIXIS_LBMAP_ALTBANK;
|
||||
PIXIS_WRITE(s[PIXIS_LBMAP_SWITCH - 1].sw, reg);
|
||||
|
||||
/* Tell the ngPIXIS to use this the bits in the SWx register for the
|
||||
* boot bank value, instead of the physical switch. We need to be
|
||||
* careful only to set the bits in SWx that correspond to the boot bank.
|
||||
*/
|
||||
reg = PIXIS_READ(s[PIXIS_LBMAP_SWITCH - 1].en);
|
||||
reg |= PIXIS_LBMAP_MASK;
|
||||
PIXIS_WRITE(s[PIXIS_LBMAP_SWITCH - 1].en, reg);
|
||||
}
|
||||
void set_altbank(void) __attribute__((weak, alias("__set_altbank")));
|
||||
|
||||
#ifdef DEBUG
|
||||
static void pixis_dump_regs(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
printf("id=%02x\n", PIXIS_READ(id));
|
||||
printf("arch=%02x\n", PIXIS_READ(arch));
|
||||
printf("scver=%02x\n", PIXIS_READ(scver));
|
||||
printf("csr=%02x\n", PIXIS_READ(csr));
|
||||
printf("rst=%02x\n", PIXIS_READ(rst));
|
||||
printf("aux=%02x\n", PIXIS_READ(aux));
|
||||
printf("spd=%02x\n", PIXIS_READ(spd));
|
||||
printf("brdcfg0=%02x\n", PIXIS_READ(brdcfg0));
|
||||
printf("brdcfg1=%02x\n", PIXIS_READ(brdcfg1));
|
||||
printf("addr=%02x\n", PIXIS_READ(addr));
|
||||
printf("data=%02x\n", PIXIS_READ(data));
|
||||
printf("led=%02x\n", PIXIS_READ(led));
|
||||
printf("vctl=%02x\n", PIXIS_READ(vctl));
|
||||
printf("vstat=%02x\n", PIXIS_READ(vstat));
|
||||
printf("vcfgen0=%02x\n", PIXIS_READ(vcfgen0));
|
||||
printf("ocmcsr=%02x\n", PIXIS_READ(ocmcsr));
|
||||
printf("ocmmsg=%02x\n", PIXIS_READ(ocmmsg));
|
||||
printf("gmdbg=%02x\n", PIXIS_READ(gmdbg));
|
||||
printf("sclk=%02x%02x%02x\n",
|
||||
PIXIS_READ(sclk[0]), PIXIS_READ(sclk[1]), PIXIS_READ(sclk[2]));
|
||||
printf("dclk=%02x%02x%02x\n",
|
||||
PIXIS_READ(dclk[0]), PIXIS_READ(dclk[1]), PIXIS_READ(dclk[2]));
|
||||
printf("watch=%02x\n", PIXIS_READ(watch));
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
printf("SW%u=%02x/%02x ", i + 1,
|
||||
PIXIS_READ(s[i].sw), PIXIS_READ(s[i].en));
|
||||
}
|
||||
putc('\n');
|
||||
}
|
||||
#endif
|
||||
|
||||
void pixis_sysclk_set(unsigned long sysclk)
|
||||
{
|
||||
unsigned long freq_word;
|
||||
u8 sclk0, sclk1, sclk2;
|
||||
|
||||
freq_word = ics307_sysclk_calculator(sysclk);
|
||||
sclk2 = freq_word & 0xff;
|
||||
sclk1 = (freq_word >> 8) & 0xff;
|
||||
sclk0 = (freq_word >> 16) & 0xff;
|
||||
|
||||
/* set SYSCLK enable bit */
|
||||
PIXIS_WRITE(vcfgen0, 0x01);
|
||||
|
||||
/* SYSCLK to required frequency */
|
||||
PIXIS_WRITE(sclk[0], sclk0);
|
||||
PIXIS_WRITE(sclk[1], sclk1);
|
||||
PIXIS_WRITE(sclk[2], sclk2);
|
||||
}
|
||||
|
||||
int pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned long sysclk;
|
||||
char *p_altbank = NULL;
|
||||
#ifdef DEBUG
|
||||
char *p_dump = NULL;
|
||||
#endif
|
||||
char *unknown_param = NULL;
|
||||
|
||||
/* No args is a simple reset request.
|
||||
*/
|
||||
if (argc <= 1)
|
||||
pixis_reset();
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "altbank") == 0) {
|
||||
p_altbank = argv[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (strcmp(argv[i], "dump") == 0) {
|
||||
p_dump = argv[i];
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (strcmp(argv[i], "sysclk") == 0) {
|
||||
sysclk = simple_strtoul(argv[i + 1], NULL, 0);
|
||||
i += 1;
|
||||
pixis_sysclk_set(sysclk);
|
||||
continue;
|
||||
}
|
||||
|
||||
unknown_param = argv[i];
|
||||
}
|
||||
|
||||
if (unknown_param) {
|
||||
printf("Invalid option: %s\n", unknown_param);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (p_dump) {
|
||||
pixis_dump_regs();
|
||||
|
||||
/* 'dump' ignores other commands */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p_altbank)
|
||||
set_altbank();
|
||||
else
|
||||
clear_altbank();
|
||||
|
||||
pixis_bank_reset();
|
||||
|
||||
/* Shouldn't be reached. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_LONGHELP
|
||||
static char pixis_help_text[] =
|
||||
"- hard reset to default bank\n"
|
||||
"pixis_reset altbank - reset to alternate bank\n"
|
||||
#ifdef DEBUG
|
||||
"pixis_reset dump - display the PIXIS registers\n"
|
||||
#endif
|
||||
"pixis_reset sysclk <SYSCLK_freq> - reset with SYSCLK frequency(KHz)\n";
|
||||
#endif
|
||||
|
||||
U_BOOT_CMD(
|
||||
pixis_reset, CONFIG_SYS_MAXARGS, 1, pixis_reset_cmd,
|
||||
"Reset the board using the FPGA sequencer", pixis_help_text
|
||||
);
|
||||
@@ -0,0 +1,60 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/**
|
||||
* Copyright 2010-2011 Freescale Semiconductor
|
||||
* Author: Timur Tabi <timur@freescale.com>
|
||||
*
|
||||
* This file provides support for the ngPIXIS, a board-specific FPGA used on
|
||||
* some Freescale reference boards.
|
||||
*/
|
||||
|
||||
/* ngPIXIS register set. Hopefully, this won't change too much over time.
|
||||
* Feel free to add board-specific #ifdefs where necessary.
|
||||
*/
|
||||
typedef struct ngpixis {
|
||||
u8 id;
|
||||
u8 arch;
|
||||
u8 scver;
|
||||
u8 csr;
|
||||
u8 rst;
|
||||
u8 serclk;
|
||||
u8 aux;
|
||||
u8 spd;
|
||||
u8 brdcfg0;
|
||||
u8 brdcfg1; /* On some boards, this register is called 'dma' */
|
||||
u8 addr;
|
||||
u8 brdcfg2;
|
||||
u8 gpiodir;
|
||||
u8 data;
|
||||
u8 led;
|
||||
u8 tag;
|
||||
u8 vctl;
|
||||
u8 vstat;
|
||||
u8 vcfgen0;
|
||||
u8 res4;
|
||||
u8 ocmcsr;
|
||||
u8 ocmmsg;
|
||||
u8 gmdbg;
|
||||
u8 res5[2];
|
||||
u8 sclk[3];
|
||||
u8 dclk[3];
|
||||
u8 watch;
|
||||
struct {
|
||||
u8 sw;
|
||||
u8 en;
|
||||
} s[9]; /* s[0]..s[7] is SW1..SW8, and s[8] is SW11 */
|
||||
} __attribute__ ((packed)) ngpixis_t;
|
||||
|
||||
/* Pointer to the PIXIS register set */
|
||||
#define pixis ((ngpixis_t *)PIXIS_BASE)
|
||||
|
||||
/* The PIXIS SW register that corresponds to board switch X, where x >= 1 */
|
||||
#define PIXIS_SW(x) (pixis->s[(x) - 1].sw)
|
||||
|
||||
/* The PIXIS EN register that corresponds to board switch X, where x >= 1 */
|
||||
#define PIXIS_EN(x) (pixis->s[(x) - 1].en)
|
||||
|
||||
u8 pixis_read(unsigned int reg);
|
||||
void pixis_write(unsigned int reg, u8 value);
|
||||
|
||||
#define PIXIS_READ(reg) pixis_read(offsetof(ngpixis_t, reg))
|
||||
#define PIXIS_WRITE(reg, value) pixis_write(offsetof(ngpixis_t, reg), value)
|
||||
@@ -0,0 +1,239 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <fsl_csu.h>
|
||||
#include <asm/arch/ns_access.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
|
||||
#ifdef CONFIG_ARCH_LS1021A
|
||||
static struct csu_ns_dev ns_dev[] = {
|
||||
{ CSU_CSLX_PCIE2_IO, CSU_ALL_RW },
|
||||
{ CSU_CSLX_PCIE1_IO, CSU_ALL_RW },
|
||||
{ CSU_CSLX_MG2TPR_IP, CSU_ALL_RW },
|
||||
{ CSU_CSLX_IFC_MEM, CSU_ALL_RW },
|
||||
{ CSU_CSLX_OCRAM, CSU_ALL_RW },
|
||||
{ CSU_CSLX_GIC, CSU_ALL_RW },
|
||||
{ CSU_CSLX_PCIE1, CSU_ALL_RW },
|
||||
{ CSU_CSLX_OCRAM2, CSU_ALL_RW },
|
||||
{ CSU_CSLX_QSPI_MEM, CSU_ALL_RW },
|
||||
{ CSU_CSLX_PCIE2, CSU_ALL_RW },
|
||||
{ CSU_CSLX_SATA, CSU_ALL_RW },
|
||||
{ CSU_CSLX_USB3, CSU_ALL_RW },
|
||||
{ CSU_CSLX_SERDES, CSU_ALL_RW },
|
||||
{ CSU_CSLX_QDMA, CSU_ALL_RW },
|
||||
{ CSU_CSLX_LPUART2, CSU_ALL_RW },
|
||||
{ CSU_CSLX_LPUART1, CSU_ALL_RW },
|
||||
{ CSU_CSLX_LPUART4, CSU_ALL_RW },
|
||||
{ CSU_CSLX_LPUART3, CSU_ALL_RW },
|
||||
{ CSU_CSLX_LPUART6, CSU_ALL_RW },
|
||||
{ CSU_CSLX_LPUART5, CSU_ALL_RW },
|
||||
{ CSU_CSLX_DSPI2, CSU_ALL_RW },
|
||||
{ CSU_CSLX_DSPI1, CSU_ALL_RW },
|
||||
{ CSU_CSLX_QSPI, CSU_ALL_RW },
|
||||
{ CSU_CSLX_ESDHC, CSU_ALL_RW },
|
||||
{ CSU_CSLX_2D_ACE, CSU_ALL_RW },
|
||||
{ CSU_CSLX_IFC, CSU_ALL_RW },
|
||||
{ CSU_CSLX_I2C1, CSU_ALL_RW },
|
||||
{ CSU_CSLX_USB2, CSU_ALL_RW },
|
||||
{ CSU_CSLX_I2C3, CSU_ALL_RW },
|
||||
{ CSU_CSLX_I2C2, CSU_ALL_RW },
|
||||
{ CSU_CSLX_DUART2, CSU_ALL_RW },
|
||||
{ CSU_CSLX_DUART1, CSU_ALL_RW },
|
||||
{ CSU_CSLX_WDT2, CSU_ALL_RW },
|
||||
{ CSU_CSLX_WDT1, CSU_ALL_RW },
|
||||
{ CSU_CSLX_EDMA, CSU_ALL_RW },
|
||||
{ CSU_CSLX_SYS_CNT, CSU_ALL_RW },
|
||||
{ CSU_CSLX_DMA_MUX2, CSU_ALL_RW },
|
||||
{ CSU_CSLX_DMA_MUX1, CSU_ALL_RW },
|
||||
{ CSU_CSLX_DDR, CSU_ALL_RW },
|
||||
{ CSU_CSLX_QUICC, CSU_ALL_RW },
|
||||
{ CSU_CSLX_DCFG_CCU_RCPM, CSU_ALL_RW },
|
||||
{ CSU_CSLX_SECURE_BOOTROM, CSU_ALL_RW },
|
||||
{ CSU_CSLX_SFP, CSU_ALL_RW },
|
||||
{ CSU_CSLX_TMU, CSU_ALL_RW },
|
||||
{ CSU_CSLX_SECURE_MONITOR, CSU_ALL_RW },
|
||||
{ CSU_CSLX_RESERVED0, CSU_ALL_RW },
|
||||
{ CSU_CSLX_ETSEC1, CSU_ALL_RW },
|
||||
{ CSU_CSLX_SEC5_5, CSU_ALL_RW },
|
||||
{ CSU_CSLX_ETSEC3, CSU_ALL_RW },
|
||||
{ CSU_CSLX_ETSEC2, CSU_ALL_RW },
|
||||
{ CSU_CSLX_GPIO2, CSU_ALL_RW },
|
||||
{ CSU_CSLX_GPIO1, CSU_ALL_RW },
|
||||
{ CSU_CSLX_GPIO4, CSU_ALL_RW },
|
||||
{ CSU_CSLX_GPIO3, CSU_ALL_RW },
|
||||
{ CSU_CSLX_PLATFORM_CONT, CSU_ALL_RW },
|
||||
{ CSU_CSLX_CSU, CSU_ALL_RW },
|
||||
{ CSU_CSLX_ASRC, CSU_ALL_RW },
|
||||
{ CSU_CSLX_SPDIF, CSU_ALL_RW },
|
||||
{ CSU_CSLX_FLEXCAN2, CSU_ALL_RW },
|
||||
{ CSU_CSLX_FLEXCAN1, CSU_ALL_RW },
|
||||
{ CSU_CSLX_FLEXCAN4, CSU_ALL_RW },
|
||||
{ CSU_CSLX_FLEXCAN3, CSU_ALL_RW },
|
||||
{ CSU_CSLX_SAI2, CSU_ALL_RW },
|
||||
{ CSU_CSLX_SAI1, CSU_ALL_RW },
|
||||
{ CSU_CSLX_SAI4, CSU_ALL_RW },
|
||||
{ CSU_CSLX_SAI3, CSU_ALL_RW },
|
||||
{ CSU_CSLX_FTM2, CSU_ALL_RW },
|
||||
{ CSU_CSLX_FTM1, CSU_ALL_RW },
|
||||
{ CSU_CSLX_FTM4, CSU_ALL_RW },
|
||||
{ CSU_CSLX_FTM3, CSU_ALL_RW },
|
||||
{ CSU_CSLX_FTM6, CSU_ALL_RW },
|
||||
{ CSU_CSLX_FTM5, CSU_ALL_RW },
|
||||
{ CSU_CSLX_FTM8, CSU_ALL_RW },
|
||||
{ CSU_CSLX_FTM7, CSU_ALL_RW },
|
||||
{ CSU_CSLX_COP_DCSR, CSU_ALL_RW },
|
||||
{ CSU_CSLX_EPU, CSU_ALL_RW },
|
||||
{ CSU_CSLX_GDI, CSU_ALL_RW },
|
||||
{ CSU_CSLX_DDI, CSU_ALL_RW },
|
||||
{ CSU_CSLX_RESERVED1, CSU_ALL_RW },
|
||||
{ CSU_CSLX_USB3_PHY, CSU_ALL_RW },
|
||||
{ CSU_CSLX_RESERVED2, CSU_ALL_RW },
|
||||
};
|
||||
|
||||
#else
|
||||
static struct csu_ns_dev ns_dev[] = {
|
||||
{CSU_CSLX_PCIE2_IO, CSU_ALL_RW},
|
||||
{CSU_CSLX_PCIE1_IO, CSU_ALL_RW},
|
||||
{CSU_CSLX_MG2TPR_IP, CSU_ALL_RW},
|
||||
{CSU_CSLX_IFC_MEM, CSU_ALL_RW},
|
||||
{CSU_CSLX_OCRAM, CSU_ALL_RW},
|
||||
{CSU_CSLX_GIC, CSU_ALL_RW},
|
||||
{CSU_CSLX_PCIE1, CSU_ALL_RW},
|
||||
{CSU_CSLX_OCRAM2, CSU_ALL_RW},
|
||||
{CSU_CSLX_QSPI_MEM, CSU_ALL_RW},
|
||||
{CSU_CSLX_PCIE2, CSU_ALL_RW},
|
||||
{CSU_CSLX_SATA, CSU_ALL_RW},
|
||||
{CSU_CSLX_USB1, CSU_ALL_RW},
|
||||
{CSU_CSLX_QM_BM_SWPORTAL, CSU_ALL_RW},
|
||||
{CSU_CSLX_PCIE3, CSU_ALL_RW},
|
||||
{CSU_CSLX_PCIE3_IO, CSU_ALL_RW},
|
||||
{CSU_CSLX_USB3, CSU_ALL_RW},
|
||||
{CSU_CSLX_USB2, CSU_ALL_RW},
|
||||
{CSU_CSLX_PFE, CSU_ALL_RW},
|
||||
{CSU_CSLX_SERDES, CSU_ALL_RW},
|
||||
{CSU_CSLX_QDMA, CSU_ALL_RW},
|
||||
{CSU_CSLX_LPUART2, CSU_ALL_RW},
|
||||
{CSU_CSLX_LPUART1, CSU_ALL_RW},
|
||||
{CSU_CSLX_LPUART4, CSU_ALL_RW},
|
||||
{CSU_CSLX_LPUART3, CSU_ALL_RW},
|
||||
{CSU_CSLX_LPUART6, CSU_ALL_RW},
|
||||
{CSU_CSLX_LPUART5, CSU_ALL_RW},
|
||||
{CSU_CSLX_DSPI1, CSU_ALL_RW},
|
||||
{CSU_CSLX_QSPI, CSU_ALL_RW},
|
||||
{CSU_CSLX_ESDHC, CSU_ALL_RW},
|
||||
{CSU_CSLX_IFC, CSU_ALL_RW},
|
||||
{CSU_CSLX_I2C1, CSU_ALL_RW},
|
||||
{CSU_CSLX_I2C3, CSU_ALL_RW},
|
||||
{CSU_CSLX_I2C2, CSU_ALL_RW},
|
||||
{CSU_CSLX_DUART2, CSU_ALL_RW},
|
||||
{CSU_CSLX_DUART1, CSU_ALL_RW},
|
||||
{CSU_CSLX_WDT2, CSU_ALL_RW},
|
||||
{CSU_CSLX_WDT1, CSU_ALL_RW},
|
||||
{CSU_CSLX_EDMA, CSU_ALL_RW},
|
||||
{CSU_CSLX_SYS_CNT, CSU_ALL_RW},
|
||||
{CSU_CSLX_DMA_MUX2, CSU_ALL_RW},
|
||||
{CSU_CSLX_DMA_MUX1, CSU_ALL_RW},
|
||||
{CSU_CSLX_DDR, CSU_ALL_RW},
|
||||
{CSU_CSLX_QUICC, CSU_ALL_RW},
|
||||
{CSU_CSLX_DCFG_CCU_RCPM, CSU_ALL_RW},
|
||||
{CSU_CSLX_SECURE_BOOTROM, CSU_ALL_RW},
|
||||
{CSU_CSLX_SFP, CSU_ALL_RW},
|
||||
{CSU_CSLX_TMU, CSU_ALL_RW},
|
||||
{CSU_CSLX_SECURE_MONITOR, CSU_ALL_RW},
|
||||
{CSU_CSLX_SCFG, CSU_ALL_RW},
|
||||
{CSU_CSLX_FM, CSU_ALL_RW},
|
||||
{CSU_CSLX_SEC5_5, CSU_ALL_RW},
|
||||
{CSU_CSLX_BM, CSU_ALL_RW},
|
||||
{CSU_CSLX_QM, CSU_ALL_RW},
|
||||
{CSU_CSLX_GPIO2, CSU_ALL_RW},
|
||||
{CSU_CSLX_GPIO1, CSU_ALL_RW},
|
||||
{CSU_CSLX_GPIO4, CSU_ALL_RW},
|
||||
{CSU_CSLX_GPIO3, CSU_ALL_RW},
|
||||
{CSU_CSLX_PLATFORM_CONT, CSU_ALL_RW},
|
||||
{CSU_CSLX_CSU, CSU_ALL_RW},
|
||||
{CSU_CSLX_IIC4, CSU_ALL_RW},
|
||||
{CSU_CSLX_WDT4, CSU_ALL_RW},
|
||||
{CSU_CSLX_WDT3, CSU_ALL_RW},
|
||||
{CSU_CSLX_ESDHC2, CSU_ALL_RW},
|
||||
{CSU_CSLX_WDT5, CSU_ALL_RW},
|
||||
{CSU_CSLX_SAI2, CSU_ALL_RW},
|
||||
{CSU_CSLX_SAI1, CSU_ALL_RW},
|
||||
{CSU_CSLX_SAI4, CSU_ALL_RW},
|
||||
{CSU_CSLX_SAI3, CSU_ALL_RW},
|
||||
{CSU_CSLX_FTM2, CSU_ALL_RW},
|
||||
{CSU_CSLX_FTM1, CSU_ALL_RW},
|
||||
{CSU_CSLX_FTM4, CSU_ALL_RW},
|
||||
{CSU_CSLX_FTM3, CSU_ALL_RW},
|
||||
{CSU_CSLX_FTM6, CSU_ALL_RW},
|
||||
{CSU_CSLX_FTM5, CSU_ALL_RW},
|
||||
{CSU_CSLX_FTM8, CSU_ALL_RW},
|
||||
{CSU_CSLX_FTM7, CSU_ALL_RW},
|
||||
{CSU_CSLX_DSCR, CSU_ALL_RW},
|
||||
};
|
||||
#endif
|
||||
|
||||
void set_devices_ns_access(unsigned long index, u16 val)
|
||||
{
|
||||
u32 *base = (u32 *)CONFIG_SYS_FSL_CSU_ADDR;
|
||||
u32 *reg;
|
||||
uint32_t tmp;
|
||||
|
||||
reg = base + index / 2;
|
||||
tmp = in_be32(reg);
|
||||
if (index % 2 == 0) {
|
||||
tmp &= 0x0000ffff;
|
||||
tmp |= val << 16;
|
||||
} else {
|
||||
tmp &= 0xffff0000;
|
||||
tmp |= val;
|
||||
}
|
||||
|
||||
out_be32(reg, tmp);
|
||||
}
|
||||
|
||||
static void enable_devices_ns_access(struct csu_ns_dev *ns_dev, uint32_t num)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
set_devices_ns_access(ns_dev[i].ind, ns_dev[i].val);
|
||||
}
|
||||
|
||||
void enable_layerscape_ns_access(void)
|
||||
{
|
||||
#ifdef CONFIG_ARM64
|
||||
if (current_el() == 3)
|
||||
#endif
|
||||
enable_devices_ns_access(ns_dev, ARRAY_SIZE(ns_dev));
|
||||
}
|
||||
|
||||
void set_pcie_ns_access(int pcie, u16 val)
|
||||
{
|
||||
switch (pcie) {
|
||||
#ifdef CONFIG_PCIE1
|
||||
case PCIE1:
|
||||
set_devices_ns_access(CSU_CSLX_PCIE1, val);
|
||||
set_devices_ns_access(CSU_CSLX_PCIE1_IO, val);
|
||||
return;
|
||||
#endif
|
||||
#ifdef CONFIG_PCIE2
|
||||
case PCIE2:
|
||||
set_devices_ns_access(CSU_CSLX_PCIE2, val);
|
||||
set_devices_ns_access(CSU_CSLX_PCIE2_IO, val);
|
||||
return;
|
||||
#endif
|
||||
#ifdef CONFIG_PCIE3
|
||||
case PCIE3:
|
||||
set_devices_ns_access(CSU_CSLX_PCIE3, val);
|
||||
set_devices_ns_access(CSU_CSLX_PCIE3_IO, val);
|
||||
return;
|
||||
#endif
|
||||
default:
|
||||
debug("The PCIE%d doesn't exist!\n", pcie);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# (C) Copyright 2002-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
|
||||
obj-y += law.o
|
||||
obj-$(CONFIG_PCI) += pci.o
|
||||
obj-y += tlb.o
|
||||
@@ -0,0 +1,36 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2008-2011 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*/
|
||||
|
||||
#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_LBC),
|
||||
#ifdef CONFIG_SYS_BMAN_MEM_PHYS
|
||||
SET_LAW(CONFIG_SYS_BMAN_MEM_PHYS, LAW_SIZE_2M, LAW_TRGT_IF_BMAN),
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_QMAN_MEM_PHYS
|
||||
SET_LAW(CONFIG_SYS_QMAN_MEM_PHYS, LAW_SIZE_2M, LAW_TRGT_IF_QMAN),
|
||||
#endif
|
||||
#ifdef PIXIS_BASE_PHYS
|
||||
SET_LAW(PIXIS_BASE_PHYS, LAW_SIZE_4K, LAW_TRGT_IF_LBC),
|
||||
#endif
|
||||
#ifdef CPLD_BASE_PHYS
|
||||
SET_LAW(CPLD_BASE_PHYS, LAW_SIZE_4K, LAW_TRGT_IF_LBC),
|
||||
#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_1M, LAW_TRGT_IF_LBC),
|
||||
#endif
|
||||
};
|
||||
|
||||
int num_law_entries = ARRAY_SIZE(law_table);
|
||||
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2007-2011 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <init.h>
|
||||
#include <pci.h>
|
||||
#include <asm/fsl_pci.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
#include <asm/fsl_serdes.h>
|
||||
|
||||
#if !defined(CONFIG_DM_PCI)
|
||||
void pci_init_board(void)
|
||||
{
|
||||
fsl_pcie_init_board(0);
|
||||
}
|
||||
|
||||
void pci_of_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
FT_FSL_PCI_SETUP;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,160 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2008-2011 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*/
|
||||
|
||||
#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_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_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_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_SW|MAS3_SR, 0,
|
||||
0, 0, BOOKE_PAGESZ_4K, 0),
|
||||
#ifdef CPLD_BASE
|
||||
SET_TLB_ENTRY(0, CPLD_BASE, CPLD_BASE_PHYS,
|
||||
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 0, BOOKE_PAGESZ_4K, 0),
|
||||
#endif
|
||||
|
||||
#ifdef PIXIS_BASE
|
||||
SET_TLB_ENTRY(0, PIXIS_BASE, PIXIS_BASE_PHYS,
|
||||
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 0, BOOKE_PAGESZ_4K, 0),
|
||||
#endif
|
||||
|
||||
/* TLB 1 */
|
||||
/* *I*** - Covers boot page */
|
||||
#if defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SYS_INIT_L3_ADDR)
|
||||
|
||||
#if !defined(CONFIG_NXP_ESBC)
|
||||
/*
|
||||
* *I*G - L3SRAM. When L3 is used as 1M SRAM, the address of the
|
||||
* SRAM is at 0xfff00000, it covered the 0xfffff000.
|
||||
*/
|
||||
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_1M, 1),
|
||||
#else
|
||||
/*
|
||||
* *I*G - L3SRAM. When L3 is used as 1M SRAM, in case of Secure Boot
|
||||
* the physical address of the SRAM is at CONFIG_SYS_INIT_L3_ADDR,
|
||||
* and virtual address is CONFIG_SYS_MONITOR_BASE
|
||||
*/
|
||||
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_MONITOR_BASE & 0xfff00000,
|
||||
CONFIG_SYS_INIT_L3_ADDR & 0xfff00000,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 0, BOOKE_PAGESZ_1M, 1),
|
||||
#endif
|
||||
|
||||
#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE)
|
||||
/*
|
||||
* SRIO_PCIE_BOOT-SLAVE. When slave boot, the address of the
|
||||
* space is at 0xfff00000, it covered the 0xfffff000.
|
||||
*/
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR,
|
||||
CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_W|MAS2_G,
|
||||
0, 0, BOOKE_PAGESZ_1M, 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_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_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_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_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_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_SW|MAS3_SR, 0,
|
||||
0, 9, BOOKE_PAGESZ_1M, 1),
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_BMAN_MEM_BASE + 0x00100000,
|
||||
CONFIG_SYS_BMAN_MEM_PHYS + 0x00100000,
|
||||
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 10, BOOKE_PAGESZ_1M, 1),
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_QMAN_MEM_PHYS
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_QMAN_MEM_BASE, CONFIG_SYS_QMAN_MEM_PHYS,
|
||||
MAS3_SW|MAS3_SR, 0,
|
||||
0, 11, BOOKE_PAGESZ_1M, 1),
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_QMAN_MEM_BASE + 0x00100000,
|
||||
CONFIG_SYS_QMAN_MEM_PHYS + 0x00100000,
|
||||
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 12, BOOKE_PAGESZ_1M, 1),
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_DCSRBAR_PHYS
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_DCSRBAR, CONFIG_SYS_DCSRBAR_PHYS,
|
||||
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
|
||||
0, 13, BOOKE_PAGESZ_4M, 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_1M, 1),
|
||||
#endif
|
||||
#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE
|
||||
/*
|
||||
* SRIO_PCIE_BOOT-SLAVE. 1M space from 0xffe00000 for
|
||||
* fetching ucode and ENV from master
|
||||
*/
|
||||
SET_TLB_ENTRY(1, CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR,
|
||||
CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS,
|
||||
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_G,
|
||||
0, 17, BOOKE_PAGESZ_1M, 1),
|
||||
#endif
|
||||
};
|
||||
|
||||
int num_tlb_entries = ARRAY_SIZE(tlb_table);
|
||||
@@ -0,0 +1,173 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/pfuze100_pmic.h>
|
||||
|
||||
#ifndef CONFIG_DM_PMIC_PFUZE100
|
||||
int pfuze_mode_init(struct pmic *p, u32 mode)
|
||||
{
|
||||
unsigned char offset, i, switch_num;
|
||||
u32 id;
|
||||
int ret;
|
||||
|
||||
pmic_reg_read(p, PFUZE100_DEVICEID, &id);
|
||||
id = id & 0xf;
|
||||
|
||||
if (id == 0) {
|
||||
switch_num = 6;
|
||||
offset = PFUZE100_SW1CMODE;
|
||||
} else if (id == 1) {
|
||||
switch_num = 4;
|
||||
offset = PFUZE100_SW2MODE;
|
||||
} else {
|
||||
printf("Not supported, id=%d\n", id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = pmic_reg_write(p, PFUZE100_SW1ABMODE, mode);
|
||||
if (ret < 0) {
|
||||
printf("Set SW1AB mode error!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < switch_num - 1; i++) {
|
||||
ret = pmic_reg_write(p, offset + i * SWITCH_SIZE, mode);
|
||||
if (ret < 0) {
|
||||
printf("Set switch 0x%x mode error!\n",
|
||||
offset + i * SWITCH_SIZE);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct pmic *pfuze_common_init(unsigned char i2cbus)
|
||||
{
|
||||
struct pmic *p;
|
||||
int ret;
|
||||
unsigned int reg;
|
||||
|
||||
ret = power_pfuze100_init(i2cbus);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
p = pmic_get("PFUZE100");
|
||||
ret = pmic_probe(p);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
pmic_reg_read(p, PFUZE100_DEVICEID, ®);
|
||||
printf("PMIC: PFUZE100 ID=0x%02x\n", reg);
|
||||
|
||||
/* Set SW1AB stanby volage to 0.975V */
|
||||
pmic_reg_read(p, PFUZE100_SW1ABSTBY, ®);
|
||||
reg &= ~SW1x_STBY_MASK;
|
||||
reg |= SW1x_0_975V;
|
||||
pmic_reg_write(p, PFUZE100_SW1ABSTBY, reg);
|
||||
|
||||
/* Set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */
|
||||
pmic_reg_read(p, PFUZE100_SW1ABCONF, ®);
|
||||
reg &= ~SW1xCONF_DVSSPEED_MASK;
|
||||
reg |= SW1xCONF_DVSSPEED_4US;
|
||||
pmic_reg_write(p, PFUZE100_SW1ABCONF, reg);
|
||||
|
||||
/* Set SW1C standby voltage to 0.975V */
|
||||
pmic_reg_read(p, PFUZE100_SW1CSTBY, ®);
|
||||
reg &= ~SW1x_STBY_MASK;
|
||||
reg |= SW1x_0_975V;
|
||||
pmic_reg_write(p, PFUZE100_SW1CSTBY, reg);
|
||||
|
||||
/* Set SW1C/VDDSOC step ramp up time from 16us to 4us/25mV */
|
||||
pmic_reg_read(p, PFUZE100_SW1CCONF, ®);
|
||||
reg &= ~SW1xCONF_DVSSPEED_MASK;
|
||||
reg |= SW1xCONF_DVSSPEED_4US;
|
||||
pmic_reg_write(p, PFUZE100_SW1CCONF, reg);
|
||||
|
||||
return p;
|
||||
}
|
||||
#else
|
||||
int pfuze_mode_init(struct udevice *dev, u32 mode)
|
||||
{
|
||||
unsigned char offset, i, switch_num;
|
||||
u32 id;
|
||||
int ret;
|
||||
|
||||
id = pmic_reg_read(dev, PFUZE100_DEVICEID);
|
||||
id = id & 0xf;
|
||||
|
||||
if (id == 0) {
|
||||
switch_num = 6;
|
||||
offset = PFUZE100_SW1CMODE;
|
||||
} else if (id == 1) {
|
||||
switch_num = 4;
|
||||
offset = PFUZE100_SW2MODE;
|
||||
} else {
|
||||
printf("Not supported, id=%d\n", id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = pmic_reg_write(dev, PFUZE100_SW1ABMODE, mode);
|
||||
if (ret < 0) {
|
||||
printf("Set SW1AB mode error!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < switch_num - 1; i++) {
|
||||
ret = pmic_reg_write(dev, offset + i * SWITCH_SIZE, mode);
|
||||
if (ret < 0) {
|
||||
printf("Set switch 0x%x mode error!\n",
|
||||
offset + i * SWITCH_SIZE);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct udevice *pfuze_common_init(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
unsigned int reg, dev_id, rev_id;
|
||||
|
||||
ret = pmic_get("pfuze100@8", &dev);
|
||||
if (ret == -ENODEV)
|
||||
return NULL;
|
||||
|
||||
dev_id = pmic_reg_read(dev, PFUZE100_DEVICEID);
|
||||
rev_id = pmic_reg_read(dev, PFUZE100_REVID);
|
||||
printf("PMIC: PFUZE100! DEV_ID=0x%x REV_ID=0x%x\n", dev_id, rev_id);
|
||||
|
||||
/* Set SW1AB stanby volage to 0.975V */
|
||||
reg = pmic_reg_read(dev, PFUZE100_SW1ABSTBY);
|
||||
reg &= ~SW1x_STBY_MASK;
|
||||
reg |= SW1x_0_975V;
|
||||
pmic_reg_write(dev, PFUZE100_SW1ABSTBY, reg);
|
||||
|
||||
/* Set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */
|
||||
reg = pmic_reg_read(dev, PFUZE100_SW1ABCONF);
|
||||
reg &= ~SW1xCONF_DVSSPEED_MASK;
|
||||
reg |= SW1xCONF_DVSSPEED_4US;
|
||||
pmic_reg_write(dev, PFUZE100_SW1ABCONF, reg);
|
||||
|
||||
/* Set SW1C standby voltage to 0.975V */
|
||||
reg = pmic_reg_read(dev, PFUZE100_SW1CSTBY);
|
||||
reg &= ~SW1x_STBY_MASK;
|
||||
reg |= SW1x_0_975V;
|
||||
pmic_reg_write(dev, PFUZE100_SW1CSTBY, reg);
|
||||
|
||||
/* Set SW1C/VDDSOC step ramp up time from 16us to 4us/25mV */
|
||||
reg = pmic_reg_read(dev, PFUZE100_SW1CCONF);
|
||||
reg &= ~SW1xCONF_DVSSPEED_MASK;
|
||||
reg |= SW1xCONF_DVSSPEED_4US;
|
||||
pmic_reg_write(dev, PFUZE100_SW1CCONF, reg);
|
||||
|
||||
return dev;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __PFUZE_BOARD_HELPER__
|
||||
#define __PFUZE_BOARD_HELPER__
|
||||
|
||||
#ifdef CONFIG_DM_PMIC_PFUZE100
|
||||
struct udevice *pfuze_common_init(void);
|
||||
int pfuze_mode_init(struct udevice *dev, u32 mode);
|
||||
#else
|
||||
struct pmic *pfuze_common_init(unsigned char i2cbus);
|
||||
int pfuze_mode_init(struct pmic *p, u32 mode);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,541 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2006,2010 Freescale Semiconductor
|
||||
* Jeff Brown
|
||||
* Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define pixis_base (u8 *)PIXIS_BASE
|
||||
|
||||
/*
|
||||
* Simple board reset.
|
||||
*/
|
||||
void pixis_reset(void)
|
||||
{
|
||||
out_8(pixis_base + PIXIS_RST, 0);
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Per table 27, page 58 of MPC8641HPCN spec.
|
||||
*/
|
||||
static int set_px_sysclk(unsigned long sysclk)
|
||||
{
|
||||
u8 sysclk_s, sysclk_r, sysclk_v, vclkh, vclkl, sysclk_aux;
|
||||
|
||||
switch (sysclk) {
|
||||
case 33:
|
||||
sysclk_s = 0x04;
|
||||
sysclk_r = 0x04;
|
||||
sysclk_v = 0x07;
|
||||
sysclk_aux = 0x00;
|
||||
break;
|
||||
case 40:
|
||||
sysclk_s = 0x01;
|
||||
sysclk_r = 0x1F;
|
||||
sysclk_v = 0x20;
|
||||
sysclk_aux = 0x01;
|
||||
break;
|
||||
case 50:
|
||||
sysclk_s = 0x01;
|
||||
sysclk_r = 0x1F;
|
||||
sysclk_v = 0x2A;
|
||||
sysclk_aux = 0x02;
|
||||
break;
|
||||
case 66:
|
||||
sysclk_s = 0x01;
|
||||
sysclk_r = 0x04;
|
||||
sysclk_v = 0x04;
|
||||
sysclk_aux = 0x03;
|
||||
break;
|
||||
case 83:
|
||||
sysclk_s = 0x01;
|
||||
sysclk_r = 0x1F;
|
||||
sysclk_v = 0x4B;
|
||||
sysclk_aux = 0x04;
|
||||
break;
|
||||
case 100:
|
||||
sysclk_s = 0x01;
|
||||
sysclk_r = 0x1F;
|
||||
sysclk_v = 0x5C;
|
||||
sysclk_aux = 0x05;
|
||||
break;
|
||||
case 134:
|
||||
sysclk_s = 0x06;
|
||||
sysclk_r = 0x1F;
|
||||
sysclk_v = 0x3B;
|
||||
sysclk_aux = 0x06;
|
||||
break;
|
||||
case 166:
|
||||
sysclk_s = 0x06;
|
||||
sysclk_r = 0x1F;
|
||||
sysclk_v = 0x4B;
|
||||
sysclk_aux = 0x07;
|
||||
break;
|
||||
default:
|
||||
printf("Unsupported SYSCLK frequency.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
vclkh = (sysclk_s << 5) | sysclk_r;
|
||||
vclkl = sysclk_v;
|
||||
|
||||
out_8(pixis_base + PIXIS_VCLKH, vclkh);
|
||||
out_8(pixis_base + PIXIS_VCLKL, vclkl);
|
||||
|
||||
out_8(pixis_base + PIXIS_AUX, sysclk_aux);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set the CFG_SYSPLL bits
|
||||
*
|
||||
* This only has effect if PX_VCFGEN0[SYSPLL]=1, which is true if
|
||||
* read_from_px_regs() is called.
|
||||
*/
|
||||
static int set_px_mpxpll(unsigned long mpxpll)
|
||||
{
|
||||
switch (mpxpll) {
|
||||
case 2:
|
||||
case 4:
|
||||
case 6:
|
||||
case 8:
|
||||
case 10:
|
||||
case 12:
|
||||
case 14:
|
||||
case 16:
|
||||
clrsetbits_8(pixis_base + PIXIS_VSPEED1, 0x1F, mpxpll);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Unsupported MPXPLL ratio.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_px_corepll(unsigned long corepll)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
switch (corepll) {
|
||||
case 20:
|
||||
val = 0x08;
|
||||
break;
|
||||
case 25:
|
||||
val = 0x0C;
|
||||
break;
|
||||
case 30:
|
||||
val = 0x10;
|
||||
break;
|
||||
case 35:
|
||||
val = 0x1C;
|
||||
break;
|
||||
case 40:
|
||||
val = 0x14;
|
||||
break;
|
||||
case 45:
|
||||
val = 0x0E;
|
||||
break;
|
||||
default:
|
||||
printf("Unsupported COREPLL ratio.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
clrsetbits_8(pixis_base + PIXIS_VSPEED0, 0x1F, val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SYS_PIXIS_VCFGEN0_ENABLE
|
||||
#define CONFIG_SYS_PIXIS_VCFGEN0_ENABLE 0x1C
|
||||
#endif
|
||||
|
||||
/* Tell the PIXIS where to find the COREPLL, MPXPLL, SYSCLK values
|
||||
*
|
||||
* The PIXIS can be programmed to look at either the on-board dip switches
|
||||
* or various other PIXIS registers to determine the values for COREPLL,
|
||||
* MPXPLL, and SYSCLK.
|
||||
*
|
||||
* CONFIG_SYS_PIXIS_VCFGEN0_ENABLE is the value to write to the PIXIS_VCFGEN0
|
||||
* register that tells the pixis to use the various PIXIS register.
|
||||
*/
|
||||
static void read_from_px_regs(int set)
|
||||
{
|
||||
u8 tmp = in_8(pixis_base + PIXIS_VCFGEN0);
|
||||
|
||||
if (set)
|
||||
tmp = tmp | CONFIG_SYS_PIXIS_VCFGEN0_ENABLE;
|
||||
else
|
||||
tmp = tmp & ~CONFIG_SYS_PIXIS_VCFGEN0_ENABLE;
|
||||
|
||||
out_8(pixis_base + PIXIS_VCFGEN0, tmp);
|
||||
}
|
||||
|
||||
/* CONFIG_SYS_PIXIS_VBOOT_ENABLE is the value to write to the PX_VCFGEN1
|
||||
* register that tells the pixis to use the PX_VBOOT[LBMAP] register.
|
||||
*/
|
||||
#ifndef CONFIG_SYS_PIXIS_VBOOT_ENABLE
|
||||
#define CONFIG_SYS_PIXIS_VBOOT_ENABLE 0x04
|
||||
#endif
|
||||
|
||||
/* Configure the source of the boot location
|
||||
*
|
||||
* The PIXIS can be programmed to look at either the on-board dip switches
|
||||
* or the PX_VBOOT[LBMAP] register to determine where we should boot.
|
||||
*
|
||||
* If we want to boot from the alternate boot bank, we need to tell the PIXIS
|
||||
* to ignore the on-board dip switches and use the PX_VBOOT[LBMAP] instead.
|
||||
*/
|
||||
static void read_from_px_regs_altbank(int set)
|
||||
{
|
||||
u8 tmp = in_8(pixis_base + PIXIS_VCFGEN1);
|
||||
|
||||
if (set)
|
||||
tmp = tmp | CONFIG_SYS_PIXIS_VBOOT_ENABLE;
|
||||
else
|
||||
tmp = tmp & ~CONFIG_SYS_PIXIS_VBOOT_ENABLE;
|
||||
|
||||
out_8(pixis_base + PIXIS_VCFGEN1, tmp);
|
||||
}
|
||||
|
||||
/* CONFIG_SYS_PIXIS_VBOOT_MASK contains the bits to set in VBOOT register that
|
||||
* tells the PIXIS what the alternate flash bank is.
|
||||
*
|
||||
* Note that it's not really a mask. It contains the actual LBMAP bits that
|
||||
* must be set to select the alternate bank. This code assumes that the
|
||||
* primary bank has these bits set to 0, and the alternate bank has these
|
||||
* bits set to 1.
|
||||
*/
|
||||
#ifndef CONFIG_SYS_PIXIS_VBOOT_MASK
|
||||
#define CONFIG_SYS_PIXIS_VBOOT_MASK (0x40)
|
||||
#endif
|
||||
|
||||
/* Tell the PIXIS to boot from the default flash bank
|
||||
*
|
||||
* Program the default flash bank into the VBOOT register. This register is
|
||||
* used only if PX_VCFGEN1[FLASH]=1.
|
||||
*/
|
||||
static void clear_altbank(void)
|
||||
{
|
||||
clrbits_8(pixis_base + PIXIS_VBOOT, CONFIG_SYS_PIXIS_VBOOT_MASK);
|
||||
}
|
||||
|
||||
/* Tell the PIXIS to boot from the alternate flash bank
|
||||
*
|
||||
* Program the alternate flash bank into the VBOOT register. This register is
|
||||
* used only if PX_VCFGEN1[FLASH]=1.
|
||||
*/
|
||||
static void set_altbank(void)
|
||||
{
|
||||
setbits_8(pixis_base + PIXIS_VBOOT, CONFIG_SYS_PIXIS_VBOOT_MASK);
|
||||
}
|
||||
|
||||
/* Reset the board with watchdog disabled.
|
||||
*
|
||||
* This respects the altbank setting.
|
||||
*/
|
||||
static void set_px_go(void)
|
||||
{
|
||||
/* Disable the VELA sequencer and watchdog */
|
||||
clrbits_8(pixis_base + PIXIS_VCTL, 9);
|
||||
|
||||
/* Reboot by starting the VELA sequencer */
|
||||
setbits_8(pixis_base + PIXIS_VCTL, 0x1);
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
||||
/* Reset the board with watchdog enabled.
|
||||
*
|
||||
* This respects the altbank setting.
|
||||
*/
|
||||
static void set_px_go_with_watchdog(void)
|
||||
{
|
||||
/* Disable the VELA sequencer */
|
||||
clrbits_8(pixis_base + PIXIS_VCTL, 1);
|
||||
|
||||
/* Enable the watchdog and reboot by starting the VELA sequencer */
|
||||
setbits_8(pixis_base + PIXIS_VCTL, 0x9);
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
||||
/* Disable the watchdog
|
||||
*
|
||||
*/
|
||||
static int pixis_disable_watchdog_cmd(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
/* Disable the VELA sequencer and the watchdog */
|
||||
clrbits_8(pixis_base + PIXIS_VCTL, 9);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
diswd, 1, 0, pixis_disable_watchdog_cmd,
|
||||
"Disable watchdog timer",
|
||||
""
|
||||
);
|
||||
|
||||
#ifdef CONFIG_PIXIS_SGMII_CMD
|
||||
|
||||
/* Enable or disable SGMII mode for a TSEC
|
||||
*/
|
||||
static int pixis_set_sgmii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
int which_tsec = -1;
|
||||
unsigned char mask;
|
||||
unsigned char switch_mask;
|
||||
|
||||
if ((argc > 2) && (strcmp(argv[1], "all") != 0))
|
||||
which_tsec = simple_strtoul(argv[1], NULL, 0);
|
||||
|
||||
switch (which_tsec) {
|
||||
#ifdef CONFIG_TSEC1
|
||||
case 1:
|
||||
mask = PIXIS_VSPEED2_TSEC1SER;
|
||||
switch_mask = PIXIS_VCFGEN1_TSEC1SER;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_TSEC2
|
||||
case 2:
|
||||
mask = PIXIS_VSPEED2_TSEC2SER;
|
||||
switch_mask = PIXIS_VCFGEN1_TSEC2SER;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_TSEC3
|
||||
case 3:
|
||||
mask = PIXIS_VSPEED2_TSEC3SER;
|
||||
switch_mask = PIXIS_VCFGEN1_TSEC3SER;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_TSEC4
|
||||
case 4:
|
||||
mask = PIXIS_VSPEED2_TSEC4SER;
|
||||
switch_mask = PIXIS_VCFGEN1_TSEC4SER;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
mask = PIXIS_VSPEED2_MASK;
|
||||
switch_mask = PIXIS_VCFGEN1_MASK;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Toggle whether the switches or FPGA control the settings */
|
||||
if (!strcmp(argv[argc - 1], "switch"))
|
||||
clrbits_8(pixis_base + PIXIS_VCFGEN1, switch_mask);
|
||||
else
|
||||
setbits_8(pixis_base + PIXIS_VCFGEN1, switch_mask);
|
||||
|
||||
/* If it's not the switches, enable or disable SGMII, as specified */
|
||||
if (!strcmp(argv[argc - 1], "on"))
|
||||
clrbits_8(pixis_base + PIXIS_VSPEED2, mask);
|
||||
else if (!strcmp(argv[argc - 1], "off"))
|
||||
setbits_8(pixis_base + PIXIS_VSPEED2, mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
pixis_set_sgmii, CONFIG_SYS_MAXARGS, 1, pixis_set_sgmii,
|
||||
"pixis_set_sgmii"
|
||||
" - Enable or disable SGMII mode for a given TSEC \n",
|
||||
"\npixis_set_sgmii [TSEC num] <on|off|switch>\n"
|
||||
" TSEC num: 1,2,3,4 or 'all'. 'all' is default.\n"
|
||||
" on - enables SGMII\n"
|
||||
" off - disables SGMII\n"
|
||||
" switch - use switch settings"
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This function takes the non-integral cpu:mpx pll ratio
|
||||
* and converts it to an integer that can be used to assign
|
||||
* FPGA register values.
|
||||
* input: strptr i.e. argv[2]
|
||||
*/
|
||||
static unsigned long strfractoint(char *strptr)
|
||||
{
|
||||
int i, j;
|
||||
int mulconst;
|
||||
int no_dec = 0;
|
||||
unsigned long intval = 0, decval = 0;
|
||||
char intarr[3], decarr[3];
|
||||
|
||||
/* Assign the integer part to intarr[]
|
||||
* If there is no decimal point i.e.
|
||||
* if the ratio is an integral value
|
||||
* simply create the intarr.
|
||||
*/
|
||||
i = 0;
|
||||
while (strptr[i] != '.') {
|
||||
if (strptr[i] == 0) {
|
||||
no_dec = 1;
|
||||
break;
|
||||
}
|
||||
intarr[i] = strptr[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
intarr[i] = '\0';
|
||||
|
||||
if (no_dec) {
|
||||
/* Currently needed only for single digit corepll ratios */
|
||||
mulconst = 10;
|
||||
decval = 0;
|
||||
} else {
|
||||
j = 0;
|
||||
i++; /* Skipping the decimal point */
|
||||
while ((strptr[i] >= '0') && (strptr[i] <= '9')) {
|
||||
decarr[j] = strptr[i];
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
|
||||
decarr[j] = '\0';
|
||||
|
||||
mulconst = 1;
|
||||
for (i = 0; i < j; i++)
|
||||
mulconst *= 10;
|
||||
decval = simple_strtoul(decarr, NULL, 10);
|
||||
}
|
||||
|
||||
intval = simple_strtoul(intarr, NULL, 10);
|
||||
intval = intval * mulconst;
|
||||
|
||||
return intval + decval;
|
||||
}
|
||||
|
||||
static int pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
unsigned int i;
|
||||
char *p_cf = NULL;
|
||||
char *p_cf_sysclk = NULL;
|
||||
char *p_cf_corepll = NULL;
|
||||
char *p_cf_mpxpll = NULL;
|
||||
char *p_altbank = NULL;
|
||||
char *p_wd = NULL;
|
||||
int unknown_param = 0;
|
||||
|
||||
/*
|
||||
* No args is a simple reset request.
|
||||
*/
|
||||
if (argc <= 1) {
|
||||
pixis_reset();
|
||||
/* not reached */
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "cf") == 0) {
|
||||
p_cf = argv[i];
|
||||
if (i + 3 >= argc) {
|
||||
break;
|
||||
}
|
||||
p_cf_sysclk = argv[i+1];
|
||||
p_cf_corepll = argv[i+2];
|
||||
p_cf_mpxpll = argv[i+3];
|
||||
i += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(argv[i], "altbank") == 0) {
|
||||
p_altbank = argv[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(argv[i], "wd") == 0) {
|
||||
p_wd = argv[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
unknown_param = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that cf has all required parms
|
||||
*/
|
||||
if ((p_cf && !(p_cf_sysclk && p_cf_corepll && p_cf_mpxpll))
|
||||
|| unknown_param) {
|
||||
#ifdef CONFIG_SYS_LONGHELP
|
||||
puts(cmdtp->help);
|
||||
putc('\n');
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* PIXIS seems to be sensitive to the ordering of
|
||||
* the registers that are touched.
|
||||
*/
|
||||
read_from_px_regs(0);
|
||||
|
||||
if (p_altbank)
|
||||
read_from_px_regs_altbank(0);
|
||||
|
||||
clear_altbank();
|
||||
|
||||
/*
|
||||
* Clock configuration specified.
|
||||
*/
|
||||
if (p_cf) {
|
||||
unsigned long sysclk;
|
||||
unsigned long corepll;
|
||||
unsigned long mpxpll;
|
||||
|
||||
sysclk = simple_strtoul(p_cf_sysclk, NULL, 10);
|
||||
corepll = strfractoint(p_cf_corepll);
|
||||
mpxpll = simple_strtoul(p_cf_mpxpll, NULL, 10);
|
||||
|
||||
if (!(set_px_sysclk(sysclk)
|
||||
&& set_px_corepll(corepll)
|
||||
&& set_px_mpxpll(mpxpll))) {
|
||||
#ifdef CONFIG_SYS_LONGHELP
|
||||
puts(cmdtp->help);
|
||||
putc('\n');
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
read_from_px_regs(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Altbank specified
|
||||
*
|
||||
* NOTE CHANGE IN BEHAVIOR: previous code would default
|
||||
* to enabling watchdog if altbank is specified.
|
||||
* Now the watchdog must be enabled explicitly using 'wd'.
|
||||
*/
|
||||
if (p_altbank) {
|
||||
set_altbank();
|
||||
read_from_px_regs_altbank(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset with watchdog specified.
|
||||
*/
|
||||
if (p_wd)
|
||||
set_px_go_with_watchdog();
|
||||
else
|
||||
set_px_go();
|
||||
|
||||
/*
|
||||
* Shouldn't be reached.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
U_BOOT_CMD(
|
||||
pixis_reset, CONFIG_SYS_MAXARGS, 1, pixis_reset_cmd,
|
||||
"Reset the board using the FPGA sequencer",
|
||||
" pixis_reset\n"
|
||||
" pixis_reset [altbank]\n"
|
||||
" pixis_reset altbank wd\n"
|
||||
" pixis_reset altbank cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>\n"
|
||||
" pixis_reset cf <SYSCLK freq> <COREPLL ratio> <MPXPLL ratio>"
|
||||
);
|
||||
@@ -0,0 +1,165 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2010 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
#ifndef __PIXIS_H_
|
||||
#define __PIXIS_H_ 1
|
||||
|
||||
/* PIXIS register set. */
|
||||
#if defined(CONFIG_TARGET_MPC8536DS)
|
||||
typedef struct pixis {
|
||||
u8 id;
|
||||
u8 ver;
|
||||
u8 pver;
|
||||
u8 csr;
|
||||
u8 rst;
|
||||
u8 rst2;
|
||||
u8 aux1;
|
||||
u8 spd;
|
||||
u8 aux2;
|
||||
u8 csr2;
|
||||
u8 watch;
|
||||
u8 led;
|
||||
u8 pwr;
|
||||
u8 res[3];
|
||||
u8 vctl;
|
||||
u8 vstat;
|
||||
u8 vcfgen0;
|
||||
u8 vcfgen1;
|
||||
u8 vcore0;
|
||||
u8 res1;
|
||||
u8 vboot;
|
||||
u8 vspeed[3];
|
||||
u8 sclk[3];
|
||||
u8 dclk[3];
|
||||
u8 i2cdacr;
|
||||
u8 vcoreacc[4];
|
||||
u8 vcorecnt[3];
|
||||
u8 vcoremax[2];
|
||||
u8 vplatacc[4];
|
||||
u8 vplatcnt[3];
|
||||
u8 vplatmax[2];
|
||||
u8 vtempacc[4];
|
||||
u8 vtempcnt[3];
|
||||
u8 vtempmax[2];
|
||||
u8 res2[4];
|
||||
} __attribute__ ((packed)) pixis_t;
|
||||
|
||||
#elif defined(CONFIG_TARGET_MPC8544DS)
|
||||
typedef struct pixis {
|
||||
u8 id;
|
||||
u8 ver;
|
||||
u8 pver;
|
||||
u8 csr;
|
||||
u8 rst;
|
||||
u8 pwr;
|
||||
u8 aux1;
|
||||
u8 spd;
|
||||
u8 res[8];
|
||||
u8 vctl;
|
||||
u8 vstat;
|
||||
u8 vcfgen0;
|
||||
u8 vcfgen1;
|
||||
u8 vcore0;
|
||||
u8 res1;
|
||||
u8 vboot;
|
||||
u8 vspeed[2];
|
||||
u8 vclkh;
|
||||
u8 vclkl;
|
||||
u8 watch;
|
||||
u8 led;
|
||||
u8 vspeed2;
|
||||
u8 res2[34];
|
||||
} __attribute__ ((packed)) pixis_t;
|
||||
|
||||
#elif defined(CONFIG_TARGET_MPC8572DS)
|
||||
typedef struct pixis {
|
||||
u8 id;
|
||||
u8 ver;
|
||||
u8 pver;
|
||||
u8 csr;
|
||||
u8 rst;
|
||||
u8 pwr1;
|
||||
u8 aux1;
|
||||
u8 spd;
|
||||
u8 aux2;
|
||||
u8 res[7];
|
||||
u8 vctl;
|
||||
u8 vstat;
|
||||
u8 vcfgen0;
|
||||
u8 vcfgen1;
|
||||
u8 vcore0;
|
||||
u8 res1;
|
||||
u8 vboot;
|
||||
u8 vspeed[3];
|
||||
u8 res2[2];
|
||||
u8 sclk[3];
|
||||
u8 dclk[3];
|
||||
u8 res3[2];
|
||||
u8 watch;
|
||||
u8 led;
|
||||
u8 res4[25];
|
||||
} __attribute__ ((packed)) pixis_t;
|
||||
|
||||
#elif defined(CONFIG_TARGET_MPC8610HPCD)
|
||||
typedef struct pixis {
|
||||
u8 id;
|
||||
u8 ver; /* also called arch */
|
||||
u8 pver;
|
||||
u8 csr;
|
||||
u8 rst;
|
||||
u8 pwr;
|
||||
u8 aux;
|
||||
u8 spd;
|
||||
u8 brdcfg0;
|
||||
u8 brdcfg1;
|
||||
u8 res[4];
|
||||
u8 led;
|
||||
u8 serno;
|
||||
u8 vctl;
|
||||
u8 vstat;
|
||||
u8 vcfgen0;
|
||||
u8 vcfgen1;
|
||||
u8 vcore0;
|
||||
u8 res1;
|
||||
u8 vboot;
|
||||
u8 vspeed[2];
|
||||
u8 res2;
|
||||
u8 sclk[3];
|
||||
u8 res3;
|
||||
u8 watch;
|
||||
u8 res4[33];
|
||||
} __attribute__ ((packed)) pixis_t;
|
||||
|
||||
#elif defined(CONFIG_TARGET_MPC8641HPCN)
|
||||
typedef struct pixis {
|
||||
u8 id;
|
||||
u8 ver;
|
||||
u8 pver;
|
||||
u8 csr;
|
||||
u8 rst;
|
||||
u8 pwr;
|
||||
u8 aux;
|
||||
u8 spd;
|
||||
u8 res[8];
|
||||
u8 vctl;
|
||||
u8 vstat;
|
||||
u8 vcfgen0;
|
||||
u8 vcfgen1;
|
||||
u8 vcore0;
|
||||
u8 res1;
|
||||
u8 vboot;
|
||||
u8 vspeed[2];
|
||||
u8 vclkh;
|
||||
u8 vclkl;
|
||||
u8 watch;
|
||||
u8 res3[36];
|
||||
} __attribute__ ((packed)) pixis_t;
|
||||
#else
|
||||
#error Need to define pixis_t for this board
|
||||
#endif
|
||||
|
||||
/* Pointer to the PIXIS register set */
|
||||
#define pixis ((pixis_t *)PIXIS_BASE)
|
||||
|
||||
#endif /* __PIXIS_H_ */
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* Tony Li <tony.li@freescale.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <i2c.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "pq-mds-pib.h"
|
||||
|
||||
int pib_init(void)
|
||||
{
|
||||
u8 val8;
|
||||
u8 orig_i2c_bus;
|
||||
|
||||
/* Switch temporarily to I2C bus #2 */
|
||||
orig_i2c_bus = i2c_get_bus_num();
|
||||
i2c_set_bus_num(1);
|
||||
|
||||
val8 = 0;
|
||||
#if defined(CONFIG_PCI) && !defined(CONFIG_PCISLAVE)
|
||||
/* Assign PIB PMC slot to desired PCI bus */
|
||||
i2c_write(0x23, 0x6, 1, &val8, 1);
|
||||
i2c_write(0x23, 0x7, 1, &val8, 1);
|
||||
val8 = 0xff;
|
||||
i2c_write(0x23, 0x2, 1, &val8, 1);
|
||||
i2c_write(0x23, 0x3, 1, &val8, 1);
|
||||
|
||||
val8 = 0;
|
||||
i2c_write(0x26, 0x6, 1, &val8, 1);
|
||||
val8 = 0x34;
|
||||
i2c_write(0x26, 0x7, 1, &val8, 1);
|
||||
#if defined(CONFIG_TARGET_MPC832XEMDS)
|
||||
val8 = 0xf9; /* PMC2, PMC3 slot to PCI bus */
|
||||
#else
|
||||
val8 = 0xf3; /* PMC1, PMC2, PMC3 slot to PCI bus */
|
||||
#endif
|
||||
i2c_write(0x26, 0x2, 1, &val8, 1);
|
||||
val8 = 0xff;
|
||||
i2c_write(0x26, 0x3, 1, &val8, 1);
|
||||
|
||||
val8 = 0;
|
||||
i2c_write(0x27, 0x6, 1, &val8, 1);
|
||||
i2c_write(0x27, 0x7, 1, &val8, 1);
|
||||
val8 = 0xff;
|
||||
i2c_write(0x27, 0x2, 1, &val8, 1);
|
||||
val8 = 0xef;
|
||||
i2c_write(0x27, 0x3, 1, &val8, 1);
|
||||
|
||||
eieio();
|
||||
|
||||
#if defined(CONFIG_TARGET_MPC832XEMDS)
|
||||
printf("PCI 32bit bus on PMC2 &PMC3\n");
|
||||
#else
|
||||
printf("PCI 32bit bus on PMC1 & PMC2 &PMC3\n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PQ_MDS_PIB_ATM)
|
||||
#if defined(CONFIG_TARGET_MPC8569MDS)
|
||||
val8 = 0;
|
||||
i2c_write(0x20, 0x6, 1, &val8, 1);
|
||||
i2c_write(0x20, 0x7, 1, &val8, 1);
|
||||
|
||||
val8 = 0xdf;
|
||||
i2c_write(0x20, 0x2, 1, &val8, 1);
|
||||
val8 = 0xf7;
|
||||
i2c_write(0x20, 0x3, 1, &val8, 1);
|
||||
|
||||
eieio();
|
||||
|
||||
printf("QOC3 ATM card on PMC0\n");
|
||||
#elif defined(CONFIG_TARGET_MPC832XEMDS)
|
||||
val8 = 0;
|
||||
i2c_write(0x26, 0x7, 1, &val8, 1);
|
||||
val8 = 0xf7;
|
||||
i2c_write(0x26, 0x3, 1, &val8, 1);
|
||||
|
||||
val8 = 0;
|
||||
i2c_write(0x21, 0x6, 1, &val8, 1);
|
||||
i2c_write(0x21, 0x7, 1, &val8, 1);
|
||||
|
||||
val8 = 0xdf;
|
||||
i2c_write(0x21, 0x2, 1, &val8, 1);
|
||||
val8 = 0xef;
|
||||
i2c_write(0x21, 0x3, 1, &val8, 1);
|
||||
|
||||
eieio();
|
||||
|
||||
printf("QOC3 ATM card on PMC1\n");
|
||||
#endif
|
||||
#endif
|
||||
/* Reset to original I2C bus */
|
||||
i2c_set_bus_num(orig_i2c_bus);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*/
|
||||
|
||||
extern int pib_init(void);
|
||||
@@ -0,0 +1,370 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2011 Freescale Semiconductor
|
||||
* Author: Shengzhou Liu <Shengzhou.Liu@freescale.com>
|
||||
*
|
||||
* This file provides support for the QIXIS of some Freescale reference boards.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/time.h>
|
||||
#include <i2c.h>
|
||||
#include "qixis.h"
|
||||
|
||||
#ifndef QIXIS_LBMAP_BRDCFG_REG
|
||||
/*
|
||||
* For consistency with existing platforms
|
||||
*/
|
||||
#define QIXIS_LBMAP_BRDCFG_REG 0x00
|
||||
#endif
|
||||
|
||||
#ifndef QIXIS_RCFG_CTL_RECONFIG_IDLE
|
||||
#define QIXIS_RCFG_CTL_RECONFIG_IDLE 0x20
|
||||
#endif
|
||||
#ifndef QIXIS_RCFG_CTL_RECONFIG_START
|
||||
#define QIXIS_RCFG_CTL_RECONFIG_START 0x21
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_I2C_FPGA_ADDR
|
||||
u8 qixis_read_i2c(unsigned int reg)
|
||||
{
|
||||
#ifndef CONFIG_DM_I2C
|
||||
return i2c_reg_read(CONFIG_SYS_I2C_FPGA_ADDR, reg);
|
||||
#else
|
||||
struct udevice *dev;
|
||||
|
||||
if (i2c_get_chip_for_busnum(0, CONFIG_SYS_I2C_FPGA_ADDR, 1, &dev))
|
||||
return 0xff;
|
||||
|
||||
return dm_i2c_reg_read(dev, reg);
|
||||
#endif
|
||||
}
|
||||
|
||||
void qixis_write_i2c(unsigned int reg, u8 value)
|
||||
{
|
||||
u8 val = value;
|
||||
#ifndef CONFIG_DM_I2C
|
||||
i2c_reg_write(CONFIG_SYS_I2C_FPGA_ADDR, reg, val);
|
||||
#else
|
||||
struct udevice *dev;
|
||||
|
||||
if (!i2c_get_chip_for_busnum(0, CONFIG_SYS_I2C_FPGA_ADDR, 1, &dev))
|
||||
dm_i2c_reg_write(dev, reg, val);
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef QIXIS_BASE
|
||||
u8 qixis_read(unsigned int reg)
|
||||
{
|
||||
void *p = (void *)QIXIS_BASE;
|
||||
|
||||
return in_8(p + reg);
|
||||
}
|
||||
|
||||
void qixis_write(unsigned int reg, u8 value)
|
||||
{
|
||||
void *p = (void *)QIXIS_BASE;
|
||||
|
||||
out_8(p + reg, value);
|
||||
}
|
||||
#endif
|
||||
|
||||
u16 qixis_read_minor(void)
|
||||
{
|
||||
u16 minor;
|
||||
|
||||
/* this data is in little endian */
|
||||
QIXIS_WRITE(tagdata, 5);
|
||||
minor = QIXIS_READ(tagdata);
|
||||
QIXIS_WRITE(tagdata, 6);
|
||||
minor += QIXIS_READ(tagdata) << 8;
|
||||
|
||||
return minor;
|
||||
}
|
||||
|
||||
char *qixis_read_time(char *result)
|
||||
{
|
||||
time_t time = 0;
|
||||
int i;
|
||||
|
||||
/* timestamp is in 32-bit big endian */
|
||||
for (i = 8; i <= 11; i++) {
|
||||
QIXIS_WRITE(tagdata, i);
|
||||
time = (time << 8) + QIXIS_READ(tagdata);
|
||||
}
|
||||
|
||||
return ctime_r(&time, result);
|
||||
}
|
||||
|
||||
char *qixis_read_tag(char *buf)
|
||||
{
|
||||
int i;
|
||||
char tag, *ptr = buf;
|
||||
|
||||
for (i = 16; i <= 63; i++) {
|
||||
QIXIS_WRITE(tagdata, i);
|
||||
tag = QIXIS_READ(tagdata);
|
||||
*(ptr++) = tag;
|
||||
if (!tag)
|
||||
break;
|
||||
}
|
||||
if (i > 63)
|
||||
*ptr = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* return the string of binary of u8 in the format of
|
||||
* 1010 10_0. The masked bit is filled as underscore.
|
||||
*/
|
||||
const char *byte_to_binary_mask(u8 val, u8 mask, char *buf)
|
||||
{
|
||||
char *ptr;
|
||||
int i;
|
||||
|
||||
ptr = buf;
|
||||
for (i = 0x80; i > 0x08 ; i >>= 1, ptr++)
|
||||
*ptr = (val & i) ? '1' : ((mask & i) ? '_' : '0');
|
||||
*(ptr++) = ' ';
|
||||
for (i = 0x08; i > 0 ; i >>= 1, ptr++)
|
||||
*ptr = (val & i) ? '1' : ((mask & i) ? '_' : '0');
|
||||
|
||||
*ptr = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifdef QIXIS_RST_FORCE_MEM
|
||||
void board_assert_mem_reset(void)
|
||||
{
|
||||
u8 rst;
|
||||
|
||||
rst = QIXIS_READ(rst_frc[0]);
|
||||
if (!(rst & QIXIS_RST_FORCE_MEM))
|
||||
QIXIS_WRITE(rst_frc[0], rst | QIXIS_RST_FORCE_MEM);
|
||||
}
|
||||
|
||||
void board_deassert_mem_reset(void)
|
||||
{
|
||||
u8 rst;
|
||||
|
||||
rst = QIXIS_READ(rst_frc[0]);
|
||||
if (rst & QIXIS_RST_FORCE_MEM)
|
||||
QIXIS_WRITE(rst_frc[0], rst & ~QIXIS_RST_FORCE_MEM);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
static void qixis_reset(void)
|
||||
{
|
||||
QIXIS_WRITE(rst_ctl, QIXIS_RST_CTL_RESET);
|
||||
}
|
||||
|
||||
#ifdef QIXIS_LBMAP_ALTBANK
|
||||
static void qixis_bank_reset(void)
|
||||
{
|
||||
QIXIS_WRITE(rcfg_ctl, QIXIS_RCFG_CTL_RECONFIG_IDLE);
|
||||
QIXIS_WRITE(rcfg_ctl, QIXIS_RCFG_CTL_RECONFIG_START);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __maybe_unused set_lbmap(int lbmap)
|
||||
{
|
||||
u8 reg;
|
||||
|
||||
reg = QIXIS_READ(brdcfg[QIXIS_LBMAP_BRDCFG_REG]);
|
||||
reg = (reg & ~QIXIS_LBMAP_MASK) | lbmap;
|
||||
QIXIS_WRITE(brdcfg[QIXIS_LBMAP_BRDCFG_REG], reg);
|
||||
}
|
||||
|
||||
static void __maybe_unused set_rcw_src(int rcw_src)
|
||||
{
|
||||
#ifdef CONFIG_NXP_LSCH3_2
|
||||
QIXIS_WRITE(dutcfg[0], (rcw_src & 0xff));
|
||||
#else
|
||||
u8 reg;
|
||||
|
||||
reg = QIXIS_READ(dutcfg[1]);
|
||||
reg = (reg & ~1) | (rcw_src & 1);
|
||||
QIXIS_WRITE(dutcfg[1], reg);
|
||||
QIXIS_WRITE(dutcfg[0], (rcw_src >> 1) & 0xff);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void qixis_dump_regs(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("id = %02x\n", QIXIS_READ(id));
|
||||
printf("arch = %02x\n", QIXIS_READ(arch));
|
||||
printf("scver = %02x\n", QIXIS_READ(scver));
|
||||
printf("model = %02x\n", QIXIS_READ(model));
|
||||
printf("rst_ctl = %02x\n", QIXIS_READ(rst_ctl));
|
||||
printf("aux = %02x\n", QIXIS_READ(aux));
|
||||
for (i = 0; i < 16; i++)
|
||||
printf("brdcfg%02d = %02x\n", i, QIXIS_READ(brdcfg[i]));
|
||||
for (i = 0; i < 16; i++)
|
||||
printf("dutcfg%02d = %02x\n", i, QIXIS_READ(dutcfg[i]));
|
||||
printf("sclk = %02x%02x%02x\n", QIXIS_READ(sclk[0]),
|
||||
QIXIS_READ(sclk[1]), QIXIS_READ(sclk[2]));
|
||||
printf("dclk = %02x%02x%02x\n", QIXIS_READ(dclk[0]),
|
||||
QIXIS_READ(dclk[1]), QIXIS_READ(dclk[2]));
|
||||
printf("aux = %02x\n", QIXIS_READ(aux));
|
||||
printf("watch = %02x\n", QIXIS_READ(watch));
|
||||
printf("ctl_sys = %02x\n", QIXIS_READ(ctl_sys));
|
||||
printf("rcw_ctl = %02x\n", QIXIS_READ(rcw_ctl));
|
||||
printf("present = %02x\n", QIXIS_READ(present));
|
||||
printf("present2 = %02x\n", QIXIS_READ(present2));
|
||||
printf("clk_spd = %02x\n", QIXIS_READ(clk_spd));
|
||||
printf("stat_dut = %02x\n", QIXIS_READ(stat_dut));
|
||||
printf("stat_sys = %02x\n", QIXIS_READ(stat_sys));
|
||||
printf("stat_alrm = %02x\n", QIXIS_READ(stat_alrm));
|
||||
}
|
||||
|
||||
void __weak qixis_dump_switch(void)
|
||||
{
|
||||
puts("Reverse engineering switch is not implemented for this board\n");
|
||||
}
|
||||
|
||||
static int qixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argc <= 1) {
|
||||
set_lbmap(QIXIS_LBMAP_DFLTBANK);
|
||||
qixis_reset();
|
||||
} else if (strcmp(argv[1], "altbank") == 0) {
|
||||
#ifdef QIXIS_LBMAP_ALTBANK
|
||||
set_lbmap(QIXIS_LBMAP_ALTBANK);
|
||||
qixis_bank_reset();
|
||||
#else
|
||||
printf("No Altbank!\n");
|
||||
#endif
|
||||
} else if (strcmp(argv[1], "nand") == 0) {
|
||||
#ifdef QIXIS_LBMAP_NAND
|
||||
QIXIS_WRITE(rst_ctl, 0x30);
|
||||
QIXIS_WRITE(rcfg_ctl, 0);
|
||||
set_lbmap(QIXIS_LBMAP_NAND);
|
||||
set_rcw_src(QIXIS_RCW_SRC_NAND);
|
||||
QIXIS_WRITE(rcfg_ctl, QIXIS_RCFG_CTL_RECONFIG_IDLE);
|
||||
QIXIS_WRITE(rcfg_ctl, QIXIS_RCFG_CTL_RECONFIG_START);
|
||||
#else
|
||||
printf("Not implemented\n");
|
||||
#endif
|
||||
} else if (strcmp(argv[1], "sd") == 0) {
|
||||
#ifdef QIXIS_LBMAP_SD
|
||||
QIXIS_WRITE(rst_ctl, 0x30);
|
||||
QIXIS_WRITE(rcfg_ctl, 0);
|
||||
#ifdef NON_EXTENDED_DUTCFG
|
||||
QIXIS_WRITE(dutcfg[0], QIXIS_RCW_SRC_SD);
|
||||
#else
|
||||
set_lbmap(QIXIS_LBMAP_SD);
|
||||
set_rcw_src(QIXIS_RCW_SRC_SD);
|
||||
#endif
|
||||
QIXIS_WRITE(rcfg_ctl, QIXIS_RCFG_CTL_RECONFIG_IDLE);
|
||||
QIXIS_WRITE(rcfg_ctl, QIXIS_RCFG_CTL_RECONFIG_START);
|
||||
#else
|
||||
printf("Not implemented\n");
|
||||
#endif
|
||||
} else if (strcmp(argv[1], "ifc") == 0) {
|
||||
#ifdef QIXIS_LBMAP_IFC
|
||||
QIXIS_WRITE(rst_ctl, 0x30);
|
||||
QIXIS_WRITE(rcfg_ctl, 0);
|
||||
set_lbmap(QIXIS_LBMAP_IFC);
|
||||
set_rcw_src(QIXIS_RCW_SRC_IFC);
|
||||
QIXIS_WRITE(rcfg_ctl, QIXIS_RCFG_CTL_RECONFIG_IDLE);
|
||||
QIXIS_WRITE(rcfg_ctl, QIXIS_RCFG_CTL_RECONFIG_START);
|
||||
#else
|
||||
printf("Not implemented\n");
|
||||
#endif
|
||||
} else if (strcmp(argv[1], "emmc") == 0) {
|
||||
#ifdef QIXIS_LBMAP_EMMC
|
||||
QIXIS_WRITE(rst_ctl, 0x30);
|
||||
QIXIS_WRITE(rcfg_ctl, 0);
|
||||
set_lbmap(QIXIS_LBMAP_EMMC);
|
||||
set_rcw_src(QIXIS_RCW_SRC_EMMC);
|
||||
QIXIS_WRITE(rcfg_ctl, QIXIS_RCFG_CTL_RECONFIG_IDLE);
|
||||
QIXIS_WRITE(rcfg_ctl, QIXIS_RCFG_CTL_RECONFIG_START);
|
||||
#else
|
||||
printf("Not implemented\n");
|
||||
#endif
|
||||
} else if (strcmp(argv[1], "sd_qspi") == 0) {
|
||||
#ifdef QIXIS_LBMAP_SD_QSPI
|
||||
QIXIS_WRITE(rst_ctl, 0x30);
|
||||
QIXIS_WRITE(rcfg_ctl, 0);
|
||||
set_lbmap(QIXIS_LBMAP_SD_QSPI);
|
||||
set_rcw_src(QIXIS_RCW_SRC_SD);
|
||||
qixis_write_i2c(offsetof(struct qixis, rcfg_ctl),
|
||||
QIXIS_RCFG_CTL_RECONFIG_IDLE);
|
||||
qixis_write_i2c(offsetof(struct qixis, rcfg_ctl),
|
||||
QIXIS_RCFG_CTL_RECONFIG_START);
|
||||
#else
|
||||
printf("Not implemented\n");
|
||||
#endif
|
||||
} else if (strcmp(argv[1], "qspi") == 0) {
|
||||
#ifdef QIXIS_LBMAP_QSPI
|
||||
QIXIS_WRITE(rst_ctl, 0x30);
|
||||
QIXIS_WRITE(rcfg_ctl, 0);
|
||||
set_lbmap(QIXIS_LBMAP_QSPI);
|
||||
set_rcw_src(QIXIS_RCW_SRC_QSPI);
|
||||
qixis_write_i2c(offsetof(struct qixis, rcfg_ctl),
|
||||
QIXIS_RCFG_CTL_RECONFIG_IDLE);
|
||||
qixis_write_i2c(offsetof(struct qixis, rcfg_ctl),
|
||||
QIXIS_RCFG_CTL_RECONFIG_START);
|
||||
#else
|
||||
printf("Not implemented\n");
|
||||
#endif
|
||||
} else if (strcmp(argv[1], "watchdog") == 0) {
|
||||
static char *period[9] = {"2s", "4s", "8s", "16s", "32s",
|
||||
"1min", "2min", "4min", "8min"};
|
||||
u8 rcfg = QIXIS_READ(rcfg_ctl);
|
||||
|
||||
if (argv[2] == NULL) {
|
||||
printf("qixis watchdog <watchdog_period>\n");
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(period); i++) {
|
||||
if (strcmp(argv[2], period[i]) == 0) {
|
||||
/* disable watchdog */
|
||||
QIXIS_WRITE(rcfg_ctl,
|
||||
rcfg & ~QIXIS_RCFG_CTL_WATCHDOG_ENBLE);
|
||||
QIXIS_WRITE(watch, ((i<<2) - 1));
|
||||
QIXIS_WRITE(rcfg_ctl, rcfg);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (strcmp(argv[1], "dump") == 0) {
|
||||
qixis_dump_regs();
|
||||
return 0;
|
||||
} else if (strcmp(argv[1], "switch") == 0) {
|
||||
qixis_dump_switch();
|
||||
return 0;
|
||||
} else {
|
||||
printf("Invalid option: %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
qixis_reset, CONFIG_SYS_MAXARGS, 1, qixis_reset_cmd,
|
||||
"Reset the board using the FPGA sequencer",
|
||||
"- hard reset to default bank\n"
|
||||
"qixis_reset altbank - reset to alternate bank\n"
|
||||
"qixis_reset nand - reset to nand\n"
|
||||
"qixis_reset sd - reset to sd\n"
|
||||
"qixis_reset sd_qspi - reset to sd with qspi support\n"
|
||||
"qixis_reset qspi - reset to qspi\n"
|
||||
"qixis watchdog <watchdog_period> - set the watchdog period\n"
|
||||
" period: 1s 2s 4s 8s 16s 32s 1min 2min 4min 8min\n"
|
||||
"qixis_reset dump - display the QIXIS registers\n"
|
||||
"qixis_reset switch - display switch\n"
|
||||
);
|
||||
#endif
|
||||
@@ -0,0 +1,136 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2011 Freescale Semiconductor
|
||||
* Author: Shengzhou Liu <Shengzhou.Liu@freescale.com>
|
||||
*
|
||||
* This file provides support for the QIXIS of some Freescale reference boards.
|
||||
*/
|
||||
|
||||
#ifndef __QIXIS_H_
|
||||
#define __QIXIS_H_
|
||||
|
||||
struct qixis {
|
||||
u8 id; /* ID value uniquely identifying each QDS board type */
|
||||
u8 arch; /* Board version information */
|
||||
u8 scver; /* QIXIS Version Register */
|
||||
u8 model; /* Information of software programming model version */
|
||||
u8 tagdata;
|
||||
u8 ctl_sys;
|
||||
u8 aux; /* Auxiliary Register,0x06 */
|
||||
u8 clk_spd;
|
||||
u8 stat_dut;
|
||||
u8 stat_sys;
|
||||
u8 stat_alrm;
|
||||
u8 present;
|
||||
u8 present2; /* Presence Status Register 2,0x0c */
|
||||
u8 rcw_ctl;
|
||||
u8 ctl_led;
|
||||
u8 i2cblk;
|
||||
u8 rcfg_ctl; /* Reconfig Control Register,0x10 */
|
||||
u8 rcfg_st;
|
||||
u8 dcm_ad;
|
||||
u8 dcm_da;
|
||||
u8 dcmd;
|
||||
u8 dmsg;
|
||||
u8 gdc;
|
||||
u8 gdd; /* DCM Debug Data Register,0x17 */
|
||||
u8 dmack;
|
||||
u8 res1[6];
|
||||
u8 watch; /* Watchdog Register,0x1F */
|
||||
u8 pwr_ctl[2]; /* Power Control Register,0x20 */
|
||||
u8 res2[2];
|
||||
u8 pwr_stat[4]; /* Power Status Register,0x24 */
|
||||
u8 res3[8];
|
||||
u8 clk_spd2[2]; /* SYSCLK clock Speed Register,0x30 */
|
||||
u8 res4[2];
|
||||
u8 sclk[3]; /* Clock Configuration Registers,0x34 */
|
||||
u8 res5;
|
||||
u8 dclk[3];
|
||||
u8 res6;
|
||||
u8 clk_dspd[3];
|
||||
u8 res7;
|
||||
u8 rst_ctl; /* Reset Control Register,0x40 */
|
||||
u8 rst_stat; /* Reset Status Register */
|
||||
u8 rst_rsn; /* Reset Reason Register */
|
||||
u8 rst_frc[2]; /* Reset Force Registers,0x43 */
|
||||
u8 res8[11];
|
||||
u8 brdcfg[16]; /* Board Configuration Register,0x50 */
|
||||
u8 dutcfg[16];
|
||||
u8 rcw_ad[2]; /* RCW SRAM Address Registers,0x70 */
|
||||
u8 rcw_data;
|
||||
u8 res9[5];
|
||||
u8 post_ctl;
|
||||
u8 post_stat;
|
||||
u8 post_dat[2];
|
||||
u8 pi_d[4];
|
||||
u8 gpio_io[4];
|
||||
u8 gpio_dir[4];
|
||||
u8 res10[20];
|
||||
u8 rjtag_ctl;
|
||||
u8 rjtag_dat;
|
||||
u8 res11[2];
|
||||
u8 trig_src[4];
|
||||
u8 trig_dst[4];
|
||||
u8 trig_stat;
|
||||
u8 res12[3];
|
||||
u8 trig_ctr[4];
|
||||
u8 res13[16];
|
||||
u8 clk_freq[6]; /* Clock Measurement Registers */
|
||||
u8 res_c6[8];
|
||||
u8 clk_base[2]; /* Clock Frequency Base Reg */
|
||||
u8 res_d0[8];
|
||||
u8 cms[2]; /* Core Management Space Address Register, 0xD8 */
|
||||
u8 res_c0[6];
|
||||
u8 aux2[4]; /* Auxiliary Registers,0xE0 */
|
||||
u8 res14[10];
|
||||
u8 aux_ad;
|
||||
u8 aux_da;
|
||||
u8 res15[16];
|
||||
};
|
||||
|
||||
u8 qixis_read(unsigned int reg);
|
||||
void qixis_write(unsigned int reg, u8 value);
|
||||
u16 qixis_read_minor(void);
|
||||
char *qixis_read_time(char *result);
|
||||
char *qixis_read_tag(char *buf);
|
||||
const char *byte_to_binary_mask(u8 val, u8 mask, char *buf);
|
||||
#ifdef CONFIG_SYS_I2C_FPGA_ADDR
|
||||
u8 qixis_read_i2c(unsigned int reg);
|
||||
void qixis_write_i2c(unsigned int reg, u8 value);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_QIXIS_I2C_ACCESS) && defined(CONFIG_SYS_I2C_FPGA_ADDR)
|
||||
#define QIXIS_READ(reg) qixis_read_i2c(offsetof(struct qixis, reg))
|
||||
#define QIXIS_WRITE(reg, value) \
|
||||
qixis_write_i2c(offsetof(struct qixis, reg), value)
|
||||
#else
|
||||
#define QIXIS_READ(reg) qixis_read(offsetof(struct qixis, reg))
|
||||
#define QIXIS_WRITE(reg, value) qixis_write(offsetof(struct qixis, reg), value)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_I2C_FPGA_ADDR
|
||||
#define QIXIS_READ_I2C(reg) qixis_read_i2c(offsetof(struct qixis, reg))
|
||||
#define QIXIS_WRITE_I2C(reg, value) \
|
||||
qixis_write_i2c(offsetof(struct qixis, reg), value)
|
||||
#endif
|
||||
|
||||
/* Use for SDHC adapter card type identification and operation */
|
||||
#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
|
||||
#define QIXIS_SDID_MASK 0x07
|
||||
#define QIXIS_ESDHC_ADAPTER_TYPE_EMMC45 0x1 /* eMMC Card Rev4.5 */
|
||||
#define QIXIS_ESDHC_ADAPTER_TYPE_SDMMC_LEGACY 0x2 /* SD/MMC Legacy Card */
|
||||
#define QIXIS_ESDHC_ADAPTER_TYPE_EMMC44 0x3 /* eMMC Card Rev4.4 */
|
||||
#define QIXIS_ESDHC_ADAPTER_TYPE_RSV 0x4 /* Reserved */
|
||||
#define QIXIS_ESDHC_ADAPTER_TYPE_MMC 0x5 /* MMC Card */
|
||||
#define QIXIS_ESDHC_ADAPTER_TYPE_SD 0x6 /* SD Card Rev2.0 3.0 */
|
||||
#define QIXIS_ESDHC_NO_ADAPTER 0x7 /* No Card is Present*/
|
||||
|
||||
#define QIXIS_SDCLKIN 0x08
|
||||
#define QIXIS_SDCLKOUT 0x02
|
||||
#define QIXIS_DAT5_6_7 0X02
|
||||
#define QIXIS_DAT4 0X01
|
||||
|
||||
#define QIXIS_EVDD_BY_SDHC_VS 0x0c
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,79 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2011 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <mmc.h>
|
||||
#include <malloc.h>
|
||||
|
||||
/*
|
||||
* The environment variables are written to just after the u-boot image
|
||||
* on SDCard, so we must read the MBR to get the start address and code
|
||||
* length of the u-boot image, then calculate the address of the env.
|
||||
*/
|
||||
#define ESDHC_BOOT_IMAGE_SIZE 0x48
|
||||
#define ESDHC_BOOT_IMAGE_ADDR 0x50
|
||||
|
||||
#define ESDHC_DEFAULT_ENVADDR 0x400
|
||||
|
||||
int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)
|
||||
{
|
||||
u8 *tmp_buf;
|
||||
u32 blklen, code_offset, code_len, n;
|
||||
|
||||
blklen = mmc->read_bl_len;
|
||||
tmp_buf = malloc(blklen);
|
||||
if (!tmp_buf)
|
||||
return 1;
|
||||
|
||||
/* read out the first block, get the config data information */
|
||||
#ifdef CONFIG_BLK
|
||||
n = blk_dread(mmc_get_blk_desc(mmc), 0, 1, tmp_buf);
|
||||
#else
|
||||
n = mmc->block_dev.block_read(&mmc->block_dev, 0, 1, tmp_buf);
|
||||
#endif
|
||||
if (!n) {
|
||||
free(tmp_buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get the Source Address, from offset 0x50 */
|
||||
code_offset = *(u32 *)(tmp_buf + ESDHC_BOOT_IMAGE_ADDR);
|
||||
|
||||
/* Get the code size from offset 0x48 */
|
||||
code_len = *(u32 *)(tmp_buf + ESDHC_BOOT_IMAGE_SIZE);
|
||||
|
||||
#ifdef CONFIG_ESDHC_HC_BLK_ADDR
|
||||
/*
|
||||
* On soc BSC9131, BSC9132:
|
||||
* In High Capacity SD Cards (> 2 GBytes), the 32-bit source address and
|
||||
* code length of these soc specify the memory address in block address
|
||||
* format. Block length is fixed to 512 bytes as per the SD High
|
||||
* Capacity specification.
|
||||
*/
|
||||
u64 tmp;
|
||||
|
||||
if (mmc->high_capacity) {
|
||||
tmp = (u64)code_offset * blklen;
|
||||
tmp += code_len * blklen;
|
||||
} else
|
||||
tmp = code_offset + code_len;
|
||||
|
||||
if ((tmp + CONFIG_ENV_SIZE > mmc->capacity) ||
|
||||
(tmp > 0xFFFFFFFFU))
|
||||
*env_addr = ESDHC_DEFAULT_ENVADDR;
|
||||
else
|
||||
*env_addr = tmp;
|
||||
|
||||
free(tmp_buf);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
*env_addr = code_offset + code_len;
|
||||
|
||||
free(tmp_buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Freescale SGMII Riser Card
|
||||
*
|
||||
* This driver supports the SGMII Riser card found on the
|
||||
* "DS" style of development board from Freescale.
|
||||
*
|
||||
* This software may be used and distributed according to the
|
||||
* terms of the GNU Public License, Version 2, incorporated
|
||||
* herein by reference.
|
||||
*
|
||||
* Copyright 2008 Freescale Semiconductor, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <net.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <tsec.h>
|
||||
#include <fdt_support.h>
|
||||
|
||||
void fsl_sgmii_riser_init(struct tsec_info_struct *tsec_info, int num)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
if (tsec_info[i].flags & TSEC_SGMII)
|
||||
tsec_info[i].phyaddr += SGMII_RISER_PHY_OFFSET;
|
||||
}
|
||||
|
||||
void fsl_sgmii_riser_fdt_fixup(void *fdt)
|
||||
{
|
||||
struct eth_device *dev;
|
||||
int node;
|
||||
int mdio_node;
|
||||
int i = -1;
|
||||
int etsec_num = 0;
|
||||
|
||||
node = fdt_path_offset(fdt, "/aliases");
|
||||
if (node < 0)
|
||||
return;
|
||||
|
||||
while ((dev = eth_get_dev_by_index(++i)) != NULL) {
|
||||
struct tsec_private *priv;
|
||||
int phy_node;
|
||||
int enet_node;
|
||||
uint32_t ph;
|
||||
char sgmii_phy[16];
|
||||
char enet[16];
|
||||
const u32 *phyh;
|
||||
const char *model;
|
||||
const char *path;
|
||||
|
||||
if (!strstr(dev->name, "eTSEC"))
|
||||
continue;
|
||||
|
||||
priv = dev->priv;
|
||||
if (!(priv->flags & TSEC_SGMII)) {
|
||||
etsec_num++;
|
||||
continue;
|
||||
}
|
||||
|
||||
mdio_node = fdt_node_offset_by_compatible(fdt, -1,
|
||||
"fsl,gianfar-mdio");
|
||||
if (mdio_node < 0)
|
||||
return;
|
||||
|
||||
sprintf(sgmii_phy, "sgmii-phy@%d", etsec_num);
|
||||
phy_node = fdt_subnode_offset(fdt, mdio_node, sgmii_phy);
|
||||
if (phy_node > 0) {
|
||||
fdt_increase_size(fdt, 32);
|
||||
ph = fdt_create_phandle(fdt, phy_node);
|
||||
if (!ph)
|
||||
continue;
|
||||
}
|
||||
|
||||
sprintf(enet, "ethernet%d", etsec_num++);
|
||||
path = fdt_getprop(fdt, node, enet, NULL);
|
||||
if (!path) {
|
||||
debug("No alias for %s\n", enet);
|
||||
continue;
|
||||
}
|
||||
|
||||
enet_node = fdt_path_offset(fdt, path);
|
||||
if (enet_node < 0)
|
||||
continue;
|
||||
|
||||
model = fdt_getprop(fdt, enet_node, "model", NULL);
|
||||
|
||||
/*
|
||||
* We only want to do this to eTSECs. On some platforms
|
||||
* there are more than one type of gianfar-style ethernet
|
||||
* controller, and as we are creating an implicit connection
|
||||
* between ethernet nodes and eTSEC devices, it is best to
|
||||
* make the connection use as much explicit information
|
||||
* as exists.
|
||||
*/
|
||||
if (!strstr(model, "TSEC"))
|
||||
continue;
|
||||
|
||||
if (phy_node < 0) {
|
||||
/*
|
||||
* This part is only for old device tree without
|
||||
* sgmii_phy nodes. It's kept just for compatible
|
||||
* reason. Soon to be deprecated if all device tree
|
||||
* get updated.
|
||||
*/
|
||||
phyh = fdt_getprop(fdt, enet_node, "phy-handle", NULL);
|
||||
if (!phyh)
|
||||
continue;
|
||||
|
||||
phy_node = fdt_node_offset_by_phandle(fdt,
|
||||
fdt32_to_cpu(*phyh));
|
||||
|
||||
priv = dev->priv;
|
||||
|
||||
if (priv->flags & TSEC_SGMII)
|
||||
fdt_setprop_cell(fdt, phy_node, "reg",
|
||||
priv->phyaddr);
|
||||
} else {
|
||||
fdt_setprop(fdt, enet_node, "phy-handle", &ph,
|
||||
sizeof(ph));
|
||||
fdt_setprop_string(fdt, enet_node,
|
||||
"phy-connection-type",
|
||||
phy_string_for_interface(
|
||||
PHY_INTERFACE_MODE_SGMII));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Freescale SGMII Riser Card
|
||||
*
|
||||
* This driver supports the SGMII Riser card found on the
|
||||
* "DS" style of development board from Freescale.
|
||||
*
|
||||
* This software may be used and distributed according to the
|
||||
* terms of the GNU Public License, Version 2, incorporated
|
||||
* herein by reference.
|
||||
*
|
||||
* Copyright 2008 Freescale Semiconductor, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
void fsl_sgmii_riser_init(struct tsec_info_struct *tsec_info, int num);
|
||||
void fsl_sgmii_riser_fdt_fixup(void *fdt);
|
||||
@@ -0,0 +1,20 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __SLEEP_H
|
||||
#define __SLEEP_H
|
||||
|
||||
#define DCFG_CCSR_CRSTSR_WDRFR (1 << 3)
|
||||
#define DDR_BUFF_LEN 128
|
||||
|
||||
/* determine if it is a wakeup from deep sleep */
|
||||
bool is_warm_boot(void);
|
||||
|
||||
/* disable console output */
|
||||
void fsl_dp_disable_console(void);
|
||||
|
||||
/* clean up everything and jump to kernel */
|
||||
int fsl_dp_resume(void);
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2016 Google, Inc
|
||||
*/
|
||||
|
||||
#ifndef __FREESCALE_BOARD_SPL_H
|
||||
#define __FREESCALE_BOARD_SPL_H
|
||||
|
||||
void fsl_spi_spl_load_image(uint32_t offs, unsigned int size, void *vdst);
|
||||
void fsl_spi_boot(void) __noreturn;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,620 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2006, 2008-2009, 2011 Freescale Semiconductor
|
||||
* York Sun (yorksun@freescale.com)
|
||||
* Haiying Wang (haiying.wang@freescale.com)
|
||||
* Timur Tabi (timur@freescale.com)
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <env.h>
|
||||
#include <i2c.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <u-boot/crc.h>
|
||||
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_CCID
|
||||
#include "../common/eeprom.h"
|
||||
#define MAX_NUM_PORTS 8
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
|
||||
/* 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 16
|
||||
#endif
|
||||
#define NXID_VERSION 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* static eeprom: EEPROM layout for CCID or NXID formats
|
||||
*
|
||||
* See application note AN3638 for details.
|
||||
*/
|
||||
static struct __attribute__ ((__packed__)) eeprom {
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_CCID
|
||||
u8 id[4]; /* 0x00 - 0x03 EEPROM Tag 'CCID' */
|
||||
u8 major; /* 0x04 Board revision, major */
|
||||
u8 minor; /* 0x05 Board revision, minor */
|
||||
u8 sn[10]; /* 0x06 - 0x0F Serial Number*/
|
||||
u8 errata[2]; /* 0x10 - 0x11 Errata Level */
|
||||
u8 date[6]; /* 0x12 - 0x17 Build Date */
|
||||
u8 res_0[40]; /* 0x18 - 0x3f Reserved */
|
||||
u8 mac_count; /* 0x40 Number of MAC addresses */
|
||||
u8 mac_flag; /* 0x41 MAC table flags */
|
||||
u8 mac[MAX_NUM_PORTS][6]; /* 0x42 - 0x71 MAC addresses */
|
||||
u32 crc; /* 0x72 CRC32 checksum */
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
|
||||
u8 id[4]; /* 0x00 - 0x03 EEPROM Tag 'NXID' */
|
||||
u8 sn[12]; /* 0x04 - 0x0F Serial Number */
|
||||
u8 errata[5]; /* 0x10 - 0x14 Errata Level */
|
||||
u8 date[6]; /* 0x15 - 0x1a Build Date */
|
||||
u8 res_0; /* 0x1b Reserved */
|
||||
u32 version; /* 0x1c - 0x1f NXID Version */
|
||||
u8 tempcal[8]; /* 0x20 - 0x27 Temperature Calibration Factors */
|
||||
u8 tempcalsys[2]; /* 0x28 - 0x29 System Temperature Calibration Factors */
|
||||
u8 tempcalflags; /* 0x2a Temperature Calibration Flags */
|
||||
u8 res_1[21]; /* 0x2b - 0x3f Reserved */
|
||||
u8 mac_count; /* 0x40 Number of MAC addresses */
|
||||
u8 mac_flag; /* 0x41 MAC table flags */
|
||||
u8 mac[MAX_NUM_PORTS][6]; /* 0x42 - 0xa1 MAC addresses */
|
||||
u8 res_2[90]; /* 0xa2 - 0xfb Reserved */
|
||||
u32 crc; /* 0xfc - 0xff CRC32 checksum */
|
||||
#endif
|
||||
} e;
|
||||
|
||||
/* Set to 1 if we've read EEPROM into memory */
|
||||
static int has_been_read = 0;
|
||||
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
|
||||
/* Is this a valid NXID EEPROM? */
|
||||
#define is_valid ((e.id[0] == 'N') || (e.id[1] == 'X') || \
|
||||
(e.id[2] == 'I') || (e.id[3] == 'D'))
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_CCID
|
||||
/* Is this a valid CCID EEPROM? */
|
||||
#define is_valid ((e.id[0] == 'C') || (e.id[1] == 'C') || \
|
||||
(e.id[2] == 'I') || (e.id[3] == 'D'))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* show_eeprom - display the contents of the EEPROM
|
||||
*/
|
||||
static void show_eeprom(void)
|
||||
{
|
||||
int i;
|
||||
unsigned int crc;
|
||||
|
||||
/* EEPROM tag ID, either CCID or NXID */
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
|
||||
printf("ID: %c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3],
|
||||
be32_to_cpu(e.version));
|
||||
#else
|
||||
printf("ID: %c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]);
|
||||
#endif
|
||||
|
||||
/* Serial number */
|
||||
printf("SN: %s\n", e.sn);
|
||||
|
||||
/* Errata level. */
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
|
||||
printf("Errata: %s\n", e.errata);
|
||||
#else
|
||||
printf("Errata: %c%c\n",
|
||||
e.errata[0] ? e.errata[0] : '.',
|
||||
e.errata[1] ? e.errata[1] : '.');
|
||||
#endif
|
||||
|
||||
/* Build date, BCD date values, as YYMMDDhhmmss */
|
||||
printf("Build date: 20%02x/%02x/%02x %02x:%02x:%02x %s\n",
|
||||
e.date[0], e.date[1], e.date[2],
|
||||
e.date[3] & 0x7F, e.date[4], e.date[5],
|
||||
e.date[3] & 0x80 ? "PM" : "");
|
||||
|
||||
/* Show MAC addresses */
|
||||
for (i = 0; i < min(e.mac_count, (u8)MAX_NUM_PORTS); i++) {
|
||||
|
||||
u8 *p = e.mac[i];
|
||||
|
||||
printf("Eth%u: %02x:%02x:%02x:%02x:%02x:%02x\n", i,
|
||||
p[0], p[1], p[2], p[3], p[4], p[5]);
|
||||
}
|
||||
|
||||
crc = crc32(0, (void *)&e, sizeof(e) - 4);
|
||||
|
||||
if (crc == be32_to_cpu(e.crc))
|
||||
printf("CRC: %08x\n", be32_to_cpu(e.crc));
|
||||
else
|
||||
printf("CRC: %08x (should be %08x)\n",
|
||||
be32_to_cpu(e.crc), crc);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("EEPROM dump: (0x%x bytes)\n", sizeof(e));
|
||||
for (i = 0; i < sizeof(e); i++) {
|
||||
if ((i % 16) == 0)
|
||||
printf("%02X: ", i);
|
||||
printf("%02X ", ((u8 *)&e)[i]);
|
||||
if (((i % 16) == 15) || (i == sizeof(e) - 1))
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* read_eeprom - read the EEPROM into memory
|
||||
*/
|
||||
static int read_eeprom(void)
|
||||
{
|
||||
int ret;
|
||||
#ifdef CONFIG_SYS_EEPROM_BUS_NUM
|
||||
#ifndef CONFIG_DM_I2C
|
||||
unsigned int bus;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (has_been_read)
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_SYS_EEPROM_BUS_NUM
|
||||
#ifndef CONFIG_DM_I2C
|
||||
bus = i2c_get_bus_num();
|
||||
i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
ret = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0,
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
|
||||
(void *)&e, sizeof(e));
|
||||
#else
|
||||
struct udevice *dev;
|
||||
#ifdef CONFIG_SYS_EEPROM_BUS_NUM
|
||||
ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM,
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR, 1, &dev);
|
||||
#else
|
||||
ret = i2c_get_chip_for_busnum(0, CONFIG_SYS_I2C_EEPROM_ADDR, 1, &dev);
|
||||
#endif
|
||||
if (!ret)
|
||||
ret = dm_i2c_read(dev, 0, (void *)&e, sizeof(e));
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_EEPROM_BUS_NUM
|
||||
#ifndef CONFIG_DM_I2C
|
||||
i2c_set_bus_num(bus);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
show_eeprom();
|
||||
#endif
|
||||
|
||||
has_been_read = (ret == 0) ? 1 : 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* update_crc - update the CRC
|
||||
*
|
||||
* This function should be called after each update to the EEPROM structure,
|
||||
* to make sure the CRC is always correct.
|
||||
*/
|
||||
static void update_crc(void)
|
||||
{
|
||||
u32 crc;
|
||||
|
||||
crc = crc32(0, (void *)&e, sizeof(e) - 4);
|
||||
e.crc = cpu_to_be32(crc);
|
||||
}
|
||||
|
||||
/**
|
||||
* prog_eeprom - write the EEPROM from memory
|
||||
*/
|
||||
static int prog_eeprom(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int i;
|
||||
void *p;
|
||||
#ifdef CONFIG_SYS_EEPROM_BUS_NUM
|
||||
#ifndef CONFIG_DM_I2C
|
||||
unsigned int bus;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Set the reserved values to 0xFF */
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
|
||||
e.res_0 = 0xFF;
|
||||
memset(e.res_1, 0xFF, sizeof(e.res_1));
|
||||
#else
|
||||
memset(e.res_0, 0xFF, sizeof(e.res_0));
|
||||
#endif
|
||||
update_crc();
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
#ifdef CONFIG_SYS_EEPROM_BUS_NUM
|
||||
bus = i2c_get_bus_num();
|
||||
i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The AT24C02 datasheet says that data can only be written in page
|
||||
* mode, which means 8 bytes at a time, and it takes up to 5ms to
|
||||
* complete a given write.
|
||||
*/
|
||||
for (i = 0, p = &e; i < sizeof(e); i += 8, p += 8) {
|
||||
#ifndef CONFIG_DM_I2C
|
||||
ret = i2c_write(CONFIG_SYS_I2C_EEPROM_ADDR, i,
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
|
||||
p, min((int)(sizeof(e) - i), 8));
|
||||
#else
|
||||
struct udevice *dev;
|
||||
#ifdef CONFIG_SYS_EEPROM_BUS_NUM
|
||||
ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM,
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR,
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
|
||||
&dev);
|
||||
#else
|
||||
ret = i2c_get_chip_for_busnum(0, CONFIG_SYS_I2C_EEPROM_ADDR,
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
|
||||
&dev);
|
||||
#endif
|
||||
if (!ret)
|
||||
ret = dm_i2c_write(dev, i, p, min((int)(sizeof(e) - i),
|
||||
8));
|
||||
#endif
|
||||
if (ret)
|
||||
break;
|
||||
udelay(5000); /* 5ms write cycle timing */
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
/* Verify the write by reading back the EEPROM and comparing */
|
||||
struct eeprom e2;
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
ret = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0,
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
|
||||
(void *)&e2, sizeof(e2));
|
||||
#else
|
||||
struct udevice *dev;
|
||||
#ifdef CONFIG_SYS_EEPROM_BUS_NUM
|
||||
ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM,
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR,
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
|
||||
&dev);
|
||||
#else
|
||||
ret = i2c_get_chip_for_busnum(0, CONFIG_SYS_I2C_EEPROM_ADDR,
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
|
||||
&dev);
|
||||
#endif
|
||||
if (!ret)
|
||||
ret = dm_i2c_read(dev, 0, (void *)&e2, sizeof(e2));
|
||||
#endif
|
||||
if (!ret && memcmp(&e, &e2, sizeof(e)))
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
#ifdef CONFIG_SYS_EEPROM_BUS_NUM
|
||||
i2c_set_bus_num(bus);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (ret) {
|
||||
printf("Programming failed.\n");
|
||||
has_been_read = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Programming passed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* h2i - converts hex character into a number
|
||||
*
|
||||
* This function takes a hexadecimal character (e.g. '7' or 'C') and returns
|
||||
* the integer equivalent.
|
||||
*/
|
||||
static inline u8 h2i(char p)
|
||||
{
|
||||
if ((p >= '0') && (p <= '9'))
|
||||
return p - '0';
|
||||
|
||||
if ((p >= 'A') && (p <= 'F'))
|
||||
return (p - 'A') + 10;
|
||||
|
||||
if ((p >= 'a') && (p <= 'f'))
|
||||
return (p - 'a') + 10;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* set_date - stores the build date into the EEPROM
|
||||
*
|
||||
* This function takes a pointer to a string in the format "YYMMDDhhmmss"
|
||||
* (2-digit year, 2-digit month, etc), converts it to a 6-byte BCD string,
|
||||
* and stores it in the build date field of the EEPROM local copy.
|
||||
*/
|
||||
static void set_date(const char *string)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (strlen(string) != 12) {
|
||||
printf("Usage: mac date YYMMDDhhmmss\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
e.date[i] = h2i(string[2 * i]) << 4 | h2i(string[2 * i + 1]);
|
||||
|
||||
update_crc();
|
||||
}
|
||||
|
||||
/**
|
||||
* set_mac_address - stores a MAC address into the EEPROM
|
||||
*
|
||||
* This function takes a pointer to MAC address string
|
||||
* (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number) and
|
||||
* stores it in one of the MAC address fields of the EEPROM local copy.
|
||||
*/
|
||||
static void set_mac_address(unsigned int index, const char *string)
|
||||
{
|
||||
char *p = (char *) string;
|
||||
unsigned int i;
|
||||
|
||||
if ((index >= MAX_NUM_PORTS) || !string) {
|
||||
printf("Usage: mac <n> XX:XX:XX:XX:XX:XX\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; *p && (i < 6); i++) {
|
||||
e.mac[index][i] = simple_strtoul(p, &p, 16);
|
||||
if (*p == ':')
|
||||
p++;
|
||||
}
|
||||
|
||||
update_crc();
|
||||
}
|
||||
|
||||
int do_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
char cmd;
|
||||
|
||||
if (argc == 1) {
|
||||
show_eeprom();
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmd = argv[1][0];
|
||||
|
||||
if (cmd == 'r') {
|
||||
read_eeprom();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cmd == 'i') {
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
|
||||
memcpy(e.id, "NXID", sizeof(e.id));
|
||||
e.version = cpu_to_be32(NXID_VERSION);
|
||||
#else
|
||||
memcpy(e.id, "CCID", sizeof(e.id));
|
||||
#endif
|
||||
update_crc();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!is_valid) {
|
||||
printf("Please read the EEPROM ('r') and/or set the ID ('i') first.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc == 2) {
|
||||
switch (cmd) {
|
||||
case 's': /* save */
|
||||
prog_eeprom();
|
||||
break;
|
||||
default:
|
||||
return cmd_usage(cmdtp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We know we have at least one parameter */
|
||||
|
||||
switch (cmd) {
|
||||
case 'n': /* serial number */
|
||||
memset(e.sn, 0, sizeof(e.sn));
|
||||
strncpy((char *)e.sn, argv[2], sizeof(e.sn) - 1);
|
||||
update_crc();
|
||||
break;
|
||||
case 'e': /* errata */
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
|
||||
memset(e.errata, 0, 5);
|
||||
strncpy((char *)e.errata, argv[2], 4);
|
||||
#else
|
||||
e.errata[0] = argv[2][0];
|
||||
e.errata[1] = argv[2][1];
|
||||
#endif
|
||||
update_crc();
|
||||
break;
|
||||
case 'd': /* date BCD format YYMMDDhhmmss */
|
||||
set_date(argv[2]);
|
||||
break;
|
||||
case 'p': /* MAC table size */
|
||||
e.mac_count = simple_strtoul(argv[2], NULL, 16);
|
||||
update_crc();
|
||||
break;
|
||||
case '0' ... '9': /* "mac 0" through "mac 22" */
|
||||
set_mac_address(simple_strtoul(argv[1], NULL, 10), argv[2]);
|
||||
break;
|
||||
case 'h': /* help */
|
||||
default:
|
||||
return cmd_usage(cmdtp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mac_read_from_eeprom - read the MAC addresses from EEPROM
|
||||
*
|
||||
* This function reads the MAC addresses from EEPROM and sets the
|
||||
* appropriate environment variables for each one read.
|
||||
*
|
||||
* The environment variables are only set if they haven't been set already.
|
||||
* This ensures that any user-saved variables are never overwritten.
|
||||
*
|
||||
* This function must be called after relocation.
|
||||
*
|
||||
* For NXID v1 EEPROMs, we support loading and up-converting the older NXID v0
|
||||
* format. In a v0 EEPROM, there are only eight MAC addresses and the CRC is
|
||||
* located at a different offset.
|
||||
*/
|
||||
int mac_read_from_eeprom(void)
|
||||
{
|
||||
unsigned int i;
|
||||
u32 crc, crc_offset = offsetof(struct eeprom, crc);
|
||||
u32 *crcp; /* Pointer to the CRC in the data read from the EEPROM */
|
||||
|
||||
puts("EEPROM: ");
|
||||
|
||||
if (read_eeprom()) {
|
||||
printf("Read failed.\n");
|
||||
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 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
|
||||
/*
|
||||
* If we've read an NXID v0 EEPROM, then we need to set the CRC offset
|
||||
* to where it is in v0.
|
||||
*/
|
||||
if (e.version == 0)
|
||||
crc_offset = 0x72;
|
||||
#endif
|
||||
|
||||
crc = crc32(0, (void *)&e, crc_offset);
|
||||
crcp = (void *)&e + crc_offset;
|
||||
if (crc != be32_to_cpu(*crcp)) {
|
||||
printf("CRC mismatch (%08x != %08x)\n", crc, be32_to_cpu(e.crc));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
|
||||
/*
|
||||
* MAC address #9 in v1 occupies the same position as the CRC in v0.
|
||||
* Erase it so that it's not mistaken for a MAC address. We'll
|
||||
* update the CRC later.
|
||||
*/
|
||||
if (e.version == 0)
|
||||
memset(e.mac[8], 0xff, 6);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < min(e.mac_count, (u8)MAX_NUM_PORTS); i++) {
|
||||
if (memcmp(&e.mac[i], "\0\0\0\0\0\0", 6) &&
|
||||
memcmp(&e.mac[i], "\xFF\xFF\xFF\xFF\xFF\xFF", 6)) {
|
||||
char ethaddr[18];
|
||||
char enetvar[9];
|
||||
|
||||
sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
e.mac[i][0],
|
||||
e.mac[i][1],
|
||||
e.mac[i][2],
|
||||
e.mac[i][3],
|
||||
e.mac[i][4],
|
||||
e.mac[i][5]);
|
||||
sprintf(enetvar, i ? "eth%daddr" : "ethaddr", i);
|
||||
/* Only initialize environment variables that are blank
|
||||
* (i.e. have not yet been set)
|
||||
*/
|
||||
if (!env_get(enetvar))
|
||||
env_set(enetvar, ethaddr);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
|
||||
printf("%c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3],
|
||||
be32_to_cpu(e.version));
|
||||
#else
|
||||
printf("%c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
|
||||
/*
|
||||
* Now we need to upconvert the data into v1 format. We do this last so
|
||||
* that at boot time, U-Boot will still say "NXID v0".
|
||||
*/
|
||||
if (e.version == 0) {
|
||||
e.version = cpu_to_be32(NXID_VERSION);
|
||||
update_crc();
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_I2C_EEPROM_CCID
|
||||
|
||||
/**
|
||||
* get_cpu_board_revision - get the CPU board revision on 85xx boards
|
||||
*
|
||||
* Read the EEPROM to determine the board revision.
|
||||
*
|
||||
* This function is called before relocation, so we need to read a private
|
||||
* copy of the EEPROM into a local variable on the stack.
|
||||
*
|
||||
* Also, we assume that CONFIG_SYS_EEPROM_BUS_NUM == CONFIG_SYS_SPD_BUS_NUM. The global
|
||||
* variable i2c_bus_num must be compile-time initialized to CONFIG_SYS_SPD_BUS_NUM,
|
||||
* so that the SPD code will work. This means that all pre-relocation I2C
|
||||
* operations can only occur on the CONFIG_SYS_SPD_BUS_NUM bus. So if
|
||||
* CONFIG_SYS_EEPROM_BUS_NUM != CONFIG_SYS_SPD_BUS_NUM, then we can't read the EEPROM when
|
||||
* this function is called. Oh well.
|
||||
*/
|
||||
unsigned int get_cpu_board_revision(void)
|
||||
{
|
||||
struct board_eeprom {
|
||||
u32 id; /* 0x00 - 0x03 EEPROM Tag 'CCID' */
|
||||
u8 major; /* 0x04 Board revision, major */
|
||||
u8 minor; /* 0x05 Board revision, minor */
|
||||
} be;
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
|
||||
(void *)&be, sizeof(be));
|
||||
#else
|
||||
struct udevice *dev;
|
||||
#ifdef CONFIG_SYS_EEPROM_BUS_NUM
|
||||
ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM,
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR,
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
|
||||
&dev);
|
||||
#else
|
||||
ret = i2c_get_chip_for_busnum(0, CONFIG_SYS_I2C_EEPROM_ADDR,
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
|
||||
&dev)
|
||||
#endif
|
||||
if (!ret)
|
||||
dm_i2c_read(dev, 0, (void *)&be, sizeof(be));
|
||||
#endif
|
||||
|
||||
if (be.id != (('C' << 24) | ('C' << 16) | ('I' << 8) | 'D'))
|
||||
return MPC85XX_CPU_BOARD_REV(0, 0);
|
||||
|
||||
if ((be.major == 0xff) && (be.minor == 0xff))
|
||||
return MPC85XX_CPU_BOARD_REV(0, 0);
|
||||
|
||||
return MPC85XX_CPU_BOARD_REV(be.major, be.minor);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef _MPC85xx_VIA_H
|
||||
void mpc85xx_config_via(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab);
|
||||
|
||||
/* Function 1, IDE */
|
||||
void mpc85xx_config_via_usbide(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab);
|
||||
|
||||
/* Function 2, USB ports 0-1 */
|
||||
void mpc85xx_config_via_usb(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab);
|
||||
|
||||
/* Function 3, USB ports 2-3 */
|
||||
void mpc85xx_config_via_usb2(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab);
|
||||
|
||||
/* Function 5, Power Management */
|
||||
void mpc85xx_config_via_power(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab);
|
||||
|
||||
/* Function 6, AC97 Interface */
|
||||
void mpc85xx_config_via_ac97(struct pci_controller* hose, pci_dev_t dev, struct pci_config_table *tab);
|
||||
#endif /* _MPC85xx_VIA_H */
|
||||
@@ -0,0 +1,965 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <env.h>
|
||||
#include <i2c.h>
|
||||
#include <irq_func.h>
|
||||
#include <asm/io.h>
|
||||
#ifdef CONFIG_FSL_LSCH2
|
||||
#include <asm/arch/immap_lsch2.h>
|
||||
#elif defined(CONFIG_FSL_LSCH3)
|
||||
#include <asm/arch/immap_lsch3.h>
|
||||
#else
|
||||
#include <asm/immap_85xx.h>
|
||||
#endif
|
||||
#include "vid.h"
|
||||
|
||||
int __weak i2c_multiplexer_select_vid_channel(u8 channel)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compensate for a board specific voltage drop between regulator and SoC
|
||||
* return a value in mV
|
||||
*/
|
||||
int __weak board_vdd_drop_compensation(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Board specific settings for specific voltage value
|
||||
*/
|
||||
int __weak board_adjust_vdd(int vdd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
|
||||
defined(CONFIG_VOL_MONITOR_IR36021_READ)
|
||||
/*
|
||||
* Get the i2c address configuration for the IR regulator chip
|
||||
*
|
||||
* There are some variance in the RDB HW regarding the I2C address configuration
|
||||
* for the IR regulator chip, which is likely a problem of external resistor
|
||||
* accuracy. So we just check each address in a hopefully non-intrusive mode
|
||||
* and use the first one that seems to work
|
||||
*
|
||||
* The IR chip can show up under the following addresses:
|
||||
* 0x08 (Verified on T1040RDB-PA,T4240RDB-PB,X-T4240RDB-16GPA)
|
||||
* 0x09 (Verified on T1040RDB-PA)
|
||||
* 0x38 (Verified on T2080QDS, T2081QDS, T4240RDB)
|
||||
*/
|
||||
static int find_ir_chip_on_i2c(void)
|
||||
{
|
||||
int i2caddress;
|
||||
int ret;
|
||||
u8 byte;
|
||||
int i;
|
||||
const int ir_i2c_addr[] = {0x38, 0x08, 0x09};
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *dev;
|
||||
#endif
|
||||
|
||||
/* Check all the address */
|
||||
for (i = 0; i < (sizeof(ir_i2c_addr)/sizeof(ir_i2c_addr[0])); i++) {
|
||||
i2caddress = ir_i2c_addr[i];
|
||||
#ifndef CONFIG_DM_I2C
|
||||
ret = i2c_read(i2caddress,
|
||||
IR36021_MFR_ID_OFFSET, 1, (void *)&byte,
|
||||
sizeof(byte));
|
||||
#else
|
||||
ret = i2c_get_chip_for_busnum(0, i2caddress, 1, &dev);
|
||||
if (!ret)
|
||||
ret = dm_i2c_read(dev, IR36021_MFR_ID_OFFSET,
|
||||
(void *)&byte, sizeof(byte));
|
||||
#endif
|
||||
if ((ret >= 0) && (byte == IR36021_MFR_ID))
|
||||
return i2caddress;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Maximum loop count waiting for new voltage to take effect */
|
||||
#define MAX_LOOP_WAIT_NEW_VOL 100
|
||||
/* Maximum loop count waiting for the voltage to be stable */
|
||||
#define MAX_LOOP_WAIT_VOL_STABLE 100
|
||||
/*
|
||||
* read_voltage from sensor on I2C bus
|
||||
* We use average of 4 readings, waiting for WAIT_FOR_ADC before
|
||||
* another reading
|
||||
*/
|
||||
#define NUM_READINGS 4 /* prefer to be power of 2 for efficiency */
|
||||
|
||||
/* If an INA220 chip is available, we can use it to read back the voltage
|
||||
* as it may have a higher accuracy than the IR chip for the same purpose
|
||||
*/
|
||||
#ifdef CONFIG_VOL_MONITOR_INA220
|
||||
#define WAIT_FOR_ADC 532 /* wait for 532 microseconds for ADC */
|
||||
#define ADC_MIN_ACCURACY 4
|
||||
#else
|
||||
#define WAIT_FOR_ADC 138 /* wait for 138 microseconds for ADC */
|
||||
#define ADC_MIN_ACCURACY 4
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VOL_MONITOR_INA220
|
||||
static int read_voltage_from_INA220(int i2caddress)
|
||||
{
|
||||
int i, ret, voltage_read = 0;
|
||||
u16 vol_mon;
|
||||
u8 buf[2];
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *dev;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < NUM_READINGS; i++) {
|
||||
#ifndef CONFIG_DM_I2C
|
||||
ret = i2c_read(I2C_VOL_MONITOR_ADDR,
|
||||
I2C_VOL_MONITOR_BUS_V_OFFSET, 1,
|
||||
(void *)&buf, 2);
|
||||
#else
|
||||
ret = i2c_get_chip_for_busnum(0, I2C_VOL_MONITOR_ADDR, 1, &dev);
|
||||
if (!ret)
|
||||
ret = dm_i2c_read(dev, I2C_VOL_MONITOR_BUS_V_OFFSET,
|
||||
(void *)&buf, 2);
|
||||
#endif
|
||||
if (ret) {
|
||||
printf("VID: failed to read core voltage\n");
|
||||
return ret;
|
||||
}
|
||||
vol_mon = (buf[0] << 8) | buf[1];
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* read voltage from IR */
|
||||
#ifdef CONFIG_VOL_MONITOR_IR36021_READ
|
||||
static int read_voltage_from_IR(int i2caddress)
|
||||
{
|
||||
int i, ret, voltage_read = 0;
|
||||
u16 vol_mon;
|
||||
u8 buf;
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *dev;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < NUM_READINGS; i++) {
|
||||
#ifndef CONFIG_DM_I2C
|
||||
ret = i2c_read(i2caddress,
|
||||
IR36021_LOOP1_VOUT_OFFSET,
|
||||
1, (void *)&buf, 1);
|
||||
#else
|
||||
ret = i2c_get_chip_for_busnum(0, i2caddress, 1, &dev);
|
||||
if (!ret)
|
||||
ret = dm_i2c_read(dev, IR36021_LOOP1_VOUT_OFFSET,
|
||||
(void *)&buf, 1);
|
||||
#endif
|
||||
if (ret) {
|
||||
printf("VID: failed to read vcpu\n");
|
||||
return ret;
|
||||
}
|
||||
vol_mon = buf;
|
||||
if (!vol_mon) {
|
||||
printf("VID: Core voltage sensor error\n");
|
||||
return -1;
|
||||
}
|
||||
debug("VID: bus voltage reads 0x%02x\n", vol_mon);
|
||||
/* Resolution is 1/128V. We scale up here to get 1/128mV
|
||||
* and divide at the end
|
||||
*/
|
||||
voltage_read += vol_mon * 1000;
|
||||
udelay(WAIT_FOR_ADC);
|
||||
}
|
||||
/* Scale down to the real mV as IR resolution is 1/128V, rounding up */
|
||||
voltage_read = DIV_ROUND_UP(voltage_read, 128);
|
||||
|
||||
/* calculate the average */
|
||||
voltage_read /= NUM_READINGS;
|
||||
|
||||
/* Compensate for a board specific voltage drop between regulator and
|
||||
* SoC before converting into an IR VID value
|
||||
*/
|
||||
voltage_read -= board_vdd_drop_compensation();
|
||||
|
||||
return voltage_read;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VOL_MONITOR_LTC3882_READ
|
||||
/* read the current value of the LTC Regulator Voltage */
|
||||
static int read_voltage_from_LTC(int i2caddress)
|
||||
{
|
||||
int ret, vcode = 0;
|
||||
u8 chan = PWM_CHANNEL0;
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
/* select the PAGE 0 using PMBus commands PAGE for VDD*/
|
||||
ret = i2c_write(I2C_VOL_MONITOR_ADDR,
|
||||
PMBUS_CMD_PAGE, 1, &chan, 1);
|
||||
#else
|
||||
struct udevice *dev;
|
||||
|
||||
ret = i2c_get_chip_for_busnum(0, I2C_VOL_MONITOR_ADDR, 1, &dev);
|
||||
if (!ret)
|
||||
ret = dm_i2c_write(dev, PMBUS_CMD_PAGE, &chan, 1);
|
||||
#endif
|
||||
if (ret) {
|
||||
printf("VID: failed to select VDD Page 0\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
/*read the output voltage using PMBus command READ_VOUT*/
|
||||
ret = i2c_read(I2C_VOL_MONITOR_ADDR,
|
||||
PMBUS_CMD_READ_VOUT, 1, (void *)&vcode, 2);
|
||||
#else
|
||||
ret = dm_i2c_read(dev, PMBUS_CMD_READ_VOUT, (void *)&vcode, 2);
|
||||
if (ret) {
|
||||
printf("VID: failed to read the volatge\n");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
if (ret) {
|
||||
printf("VID: failed to read the volatge\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Scale down to the real mV as LTC resolution is 1/4096V,rounding up */
|
||||
vcode = DIV_ROUND_UP(vcode * 1000, 4096);
|
||||
|
||||
return vcode;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int read_voltage(int i2caddress)
|
||||
{
|
||||
int voltage_read;
|
||||
#ifdef CONFIG_VOL_MONITOR_INA220
|
||||
voltage_read = read_voltage_from_INA220(i2caddress);
|
||||
#elif defined CONFIG_VOL_MONITOR_IR36021_READ
|
||||
voltage_read = read_voltage_from_IR(i2caddress);
|
||||
#elif defined CONFIG_VOL_MONITOR_LTC3882_READ
|
||||
voltage_read = read_voltage_from_LTC(i2caddress);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
return voltage_read;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VOL_MONITOR_IR36021_SET
|
||||
/*
|
||||
* We need to calculate how long before the voltage stops to drop
|
||||
* or increase. It returns with the loop count. Each loop takes
|
||||
* several readings (WAIT_FOR_ADC)
|
||||
*/
|
||||
static int wait_for_new_voltage(int vdd, int i2caddress)
|
||||
{
|
||||
int timeout, vdd_current;
|
||||
|
||||
vdd_current = read_voltage(i2caddress);
|
||||
/* wait until voltage starts to reach the target. Voltage slew
|
||||
* rates by typical regulators will always lead to stable readings
|
||||
* within each fairly long ADC interval in comparison to the
|
||||
* intended voltage delta change until the target voltage is
|
||||
* reached. The fairly small voltage delta change to any target
|
||||
* VID voltage also means that this function will always complete
|
||||
* within few iterations. If the timeout was ever reached, it would
|
||||
* point to a serious failure in the regulator system.
|
||||
*/
|
||||
for (timeout = 0;
|
||||
abs(vdd - vdd_current) > (IR_VDD_STEP_UP + IR_VDD_STEP_DOWN) &&
|
||||
timeout < MAX_LOOP_WAIT_NEW_VOL; timeout++) {
|
||||
vdd_current = read_voltage(i2caddress);
|
||||
}
|
||||
if (timeout >= MAX_LOOP_WAIT_NEW_VOL) {
|
||||
printf("VID: Voltage adjustment timeout\n");
|
||||
return -1;
|
||||
}
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/*
|
||||
* this function keeps reading the voltage until it is stable or until the
|
||||
* timeout expires
|
||||
*/
|
||||
static int wait_for_voltage_stable(int i2caddress)
|
||||
{
|
||||
int timeout, vdd_current, vdd;
|
||||
|
||||
vdd = read_voltage(i2caddress);
|
||||
udelay(NUM_READINGS * WAIT_FOR_ADC);
|
||||
|
||||
/* wait until voltage is stable */
|
||||
vdd_current = read_voltage(i2caddress);
|
||||
/* The maximum timeout is
|
||||
* MAX_LOOP_WAIT_VOL_STABLE * NUM_READINGS * WAIT_FOR_ADC
|
||||
*/
|
||||
for (timeout = MAX_LOOP_WAIT_VOL_STABLE;
|
||||
abs(vdd - vdd_current) > ADC_MIN_ACCURACY &&
|
||||
timeout > 0; timeout--) {
|
||||
vdd = vdd_current;
|
||||
udelay(NUM_READINGS * WAIT_FOR_ADC);
|
||||
vdd_current = read_voltage(i2caddress);
|
||||
}
|
||||
if (timeout == 0)
|
||||
return -1;
|
||||
return vdd_current;
|
||||
}
|
||||
|
||||
/* Set the voltage to the IR chip */
|
||||
static int set_voltage_to_IR(int i2caddress, int vdd)
|
||||
{
|
||||
int wait, vdd_last;
|
||||
int ret;
|
||||
u8 vid;
|
||||
|
||||
/* Compensate for a board specific voltage drop between regulator and
|
||||
* SoC before converting into an IR VID value
|
||||
*/
|
||||
vdd += board_vdd_drop_compensation();
|
||||
#ifdef CONFIG_FSL_LSCH2
|
||||
vid = DIV_ROUND_UP(vdd - 265, 5);
|
||||
#else
|
||||
vid = DIV_ROUND_UP(vdd - 245, 5);
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
ret = i2c_write(i2caddress, IR36021_LOOP1_MANUAL_ID_OFFSET,
|
||||
1, (void *)&vid, sizeof(vid));
|
||||
#else
|
||||
struct udevice *dev;
|
||||
|
||||
ret = i2c_get_chip_for_busnum(0, i2caddress, 1, &dev);
|
||||
if (!ret)
|
||||
ret = dm_i2c_write(dev, IR36021_LOOP1_MANUAL_ID_OFFSET,
|
||||
(void *)&vid, sizeof(vid));
|
||||
|
||||
#endif
|
||||
if (ret) {
|
||||
printf("VID: failed to write VID\n");
|
||||
return -1;
|
||||
}
|
||||
wait = wait_for_new_voltage(vdd, i2caddress);
|
||||
if (wait < 0)
|
||||
return -1;
|
||||
debug("VID: Waited %d us\n", wait * NUM_READINGS * WAIT_FOR_ADC);
|
||||
|
||||
vdd_last = wait_for_voltage_stable(i2caddress);
|
||||
if (vdd_last < 0)
|
||||
return -1;
|
||||
debug("VID: Current voltage is %d mV\n", vdd_last);
|
||||
return vdd_last;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VOL_MONITOR_LTC3882_SET
|
||||
/* this function sets the VDD and returns the value set */
|
||||
static int set_voltage_to_LTC(int i2caddress, int vdd)
|
||||
{
|
||||
int ret, vdd_last, vdd_target = vdd;
|
||||
int count = 100, temp = 0;
|
||||
|
||||
/* Scale up to the LTC resolution is 1/4096V */
|
||||
vdd = (vdd * 4096) / 1000;
|
||||
|
||||
/* 5-byte buffer which needs to be sent following the
|
||||
* PMBus command PAGE_PLUS_WRITE.
|
||||
*/
|
||||
u8 buff[5] = {0x04, PWM_CHANNEL0, PMBUS_CMD_VOUT_COMMAND,
|
||||
vdd & 0xFF, (vdd & 0xFF00) >> 8};
|
||||
|
||||
/* Write the desired voltage code to the regulator */
|
||||
#ifndef CONFIG_DM_I2C
|
||||
ret = i2c_write(I2C_VOL_MONITOR_ADDR,
|
||||
PMBUS_CMD_PAGE_PLUS_WRITE, 1, (void *)&buff, 5);
|
||||
#else
|
||||
struct udevice *dev;
|
||||
|
||||
ret = i2c_get_chip_for_busnum(0, I2C_VOL_MONITOR_ADDR, 1, &dev);
|
||||
if (!ret)
|
||||
ret = dm_i2c_write(dev, PMBUS_CMD_PAGE_PLUS_WRITE,
|
||||
(void *)&buff, 5);
|
||||
#endif
|
||||
if (ret) {
|
||||
printf("VID: I2C failed to write to the volatge regulator\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wait for the volatge to get to the desired value */
|
||||
do {
|
||||
vdd_last = read_voltage_from_LTC(i2caddress);
|
||||
if (vdd_last < 0) {
|
||||
printf("VID: Couldn't read sensor abort VID adjust\n");
|
||||
return -1;
|
||||
}
|
||||
count--;
|
||||
temp = vdd_last - vdd_target;
|
||||
} while ((abs(temp) > 2) && (count > 0));
|
||||
|
||||
return vdd_last;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int set_voltage(int i2caddress, int vdd)
|
||||
{
|
||||
int vdd_last = -1;
|
||||
|
||||
#ifdef CONFIG_VOL_MONITOR_IR36021_SET
|
||||
vdd_last = set_voltage_to_IR(i2caddress, vdd);
|
||||
#elif defined CONFIG_VOL_MONITOR_LTC3882_SET
|
||||
vdd_last = set_voltage_to_LTC(i2caddress, vdd);
|
||||
#else
|
||||
#error Specific voltage monitor must be defined
|
||||
#endif
|
||||
return vdd_last;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FSL_LSCH3
|
||||
int adjust_vdd(ulong vdd_override)
|
||||
{
|
||||
int re_enable = disable_interrupts();
|
||||
struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
u32 fusesr;
|
||||
#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
|
||||
defined(CONFIG_VOL_MONITOR_IR36021_READ)
|
||||
u8 vid, buf;
|
||||
#else
|
||||
u8 vid;
|
||||
#endif
|
||||
int vdd_target, vdd_current, vdd_last;
|
||||
int ret, i2caddress;
|
||||
unsigned long vdd_string_override;
|
||||
char *vdd_string;
|
||||
#ifdef CONFIG_ARCH_LX2160A
|
||||
static const u16 vdd[32] = {
|
||||
8250,
|
||||
7875,
|
||||
7750,
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
8000,
|
||||
8125,
|
||||
8250,
|
||||
0, /* reserved */
|
||||
8500,
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
};
|
||||
#else
|
||||
#ifdef CONFIG_ARCH_LS1088A
|
||||
static const uint16_t vdd[32] = {
|
||||
10250,
|
||||
9875,
|
||||
9750,
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
9000,
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
10000, /* 1.0000V */
|
||||
10125,
|
||||
10250,
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
};
|
||||
|
||||
#else
|
||||
static const uint16_t vdd[32] = {
|
||||
10500,
|
||||
0, /* reserved */
|
||||
9750,
|
||||
0, /* reserved */
|
||||
9500,
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
9000, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
10000, /* 1.0000V */
|
||||
0, /* reserved */
|
||||
10250,
|
||||
0, /* reserved */
|
||||
10500,
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
0, /* reserved */
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
struct vdd_drive {
|
||||
u8 vid;
|
||||
unsigned voltage;
|
||||
};
|
||||
|
||||
ret = i2c_multiplexer_select_vid_channel(I2C_MUX_CH_VOL_MONITOR);
|
||||
if (ret) {
|
||||
debug("VID: I2C failed to switch channel\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
|
||||
defined(CONFIG_VOL_MONITOR_IR36021_READ)
|
||||
ret = find_ir_chip_on_i2c();
|
||||
if (ret < 0) {
|
||||
printf("VID: Could not find voltage regulator on I2C.\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
} else {
|
||||
i2caddress = ret;
|
||||
debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress);
|
||||
}
|
||||
|
||||
/* check IR chip work on Intel mode*/
|
||||
#ifndef CONFIG_DM_I2C
|
||||
ret = i2c_read(i2caddress,
|
||||
IR36021_INTEL_MODE_OOFSET,
|
||||
1, (void *)&buf, 1);
|
||||
#else
|
||||
struct udevice *dev;
|
||||
|
||||
ret = i2c_get_chip_for_busnum(0, i2caddress, 1, &dev);
|
||||
if (!ret)
|
||||
ret = dm_i2c_read(dev, IR36021_INTEL_MODE_OOFSET,
|
||||
(void *)&buf, 1);
|
||||
#endif
|
||||
if (ret) {
|
||||
printf("VID: failed to read IR chip mode.\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((buf & IR36021_MODE_MASK) != IR36021_INTEL_MODE) {
|
||||
printf("VID: IR Chip is not used in Intel mode.\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* get the voltage ID from fuse status register */
|
||||
fusesr = in_le32(&gur->dcfg_fusesr);
|
||||
vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT) &
|
||||
FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK;
|
||||
if ((vid == 0) || (vid == FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK)) {
|
||||
vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT) &
|
||||
FSL_CHASSIS3_DCFG_FUSESR_VID_MASK;
|
||||
}
|
||||
vdd_target = vdd[vid];
|
||||
|
||||
/* check override variable for overriding VDD */
|
||||
vdd_string = env_get(CONFIG_VID_FLS_ENV);
|
||||
if (vdd_override == 0 && vdd_string &&
|
||||
!strict_strtoul(vdd_string, 10, &vdd_string_override))
|
||||
vdd_override = vdd_string_override;
|
||||
|
||||
if (vdd_override >= VDD_MV_MIN && vdd_override <= VDD_MV_MAX) {
|
||||
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");
|
||||
}
|
||||
|
||||
/* divide and round up by 10 to get a value in mV */
|
||||
vdd_target = DIV_ROUND_UP(vdd_target, 10);
|
||||
if (vdd_target == 0) {
|
||||
debug("VID: VID not used\n");
|
||||
ret = 0;
|
||||
goto exit;
|
||||
} else if (vdd_target < VDD_MV_MIN || vdd_target > VDD_MV_MAX) {
|
||||
/* Check vdd_target is in valid range */
|
||||
printf("VID: Target VID %d mV is not in range.\n",
|
||||
vdd_target);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
} else {
|
||||
debug("VID: vid = %d mV\n", vdd_target);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read voltage monitor to check real voltage.
|
||||
*/
|
||||
vdd_last = read_voltage(i2caddress);
|
||||
if (vdd_last < 0) {
|
||||
printf("VID: Couldn't read sensor abort VID adjustment\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
vdd_current = vdd_last;
|
||||
debug("VID: Core voltage is currently at %d mV\n", vdd_last);
|
||||
|
||||
#ifdef CONFIG_VOL_MONITOR_LTC3882_SET
|
||||
/* Set the target voltage */
|
||||
vdd_last = vdd_current = set_voltage(i2caddress, vdd_target);
|
||||
#else
|
||||
/*
|
||||
* Adjust voltage to at or one step above target.
|
||||
* As measurements are less precise than setting the values
|
||||
* we may run through dummy steps that cancel each other
|
||||
* when stepping up and then down.
|
||||
*/
|
||||
while (vdd_last > 0 &&
|
||||
vdd_last < vdd_target) {
|
||||
vdd_current += IR_VDD_STEP_UP;
|
||||
vdd_last = set_voltage(i2caddress, vdd_current);
|
||||
}
|
||||
while (vdd_last > 0 &&
|
||||
vdd_last > vdd_target + (IR_VDD_STEP_DOWN - 1)) {
|
||||
vdd_current -= IR_VDD_STEP_DOWN;
|
||||
vdd_last = set_voltage(i2caddress, vdd_current);
|
||||
}
|
||||
|
||||
#endif
|
||||
if (board_adjust_vdd(vdd_target) < 0) {
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (vdd_last > 0)
|
||||
printf("VID: Core voltage after adjustment is at %d mV\n",
|
||||
vdd_last);
|
||||
else
|
||||
ret = -1;
|
||||
exit:
|
||||
if (re_enable)
|
||||
enable_interrupts();
|
||||
i2c_multiplexer_select_vid_channel(I2C_MUX_CH_DEFAULT);
|
||||
return ret;
|
||||
}
|
||||
#else /* !CONFIG_FSL_LSCH3 */
|
||||
int adjust_vdd(ulong vdd_override)
|
||||
{
|
||||
int re_enable = disable_interrupts();
|
||||
#if defined(CONFIG_FSL_LSCH2)
|
||||
struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
#else
|
||||
ccsr_gur_t __iomem *gur =
|
||||
(void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
||||
#endif
|
||||
u32 fusesr;
|
||||
u8 vid, buf;
|
||||
int vdd_target, vdd_current, vdd_last;
|
||||
int ret, i2caddress;
|
||||
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 = i2c_multiplexer_select_vid_channel(I2C_MUX_CH_VOL_MONITOR);
|
||||
if (ret) {
|
||||
debug("VID: I2C failed to switch channel\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
|
||||
defined(CONFIG_VOL_MONITOR_IR36021_READ)
|
||||
ret = find_ir_chip_on_i2c();
|
||||
if (ret < 0) {
|
||||
printf("VID: Could not find voltage regulator on I2C.\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
} else {
|
||||
i2caddress = ret;
|
||||
debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress);
|
||||
}
|
||||
|
||||
/* check IR chip work on Intel mode*/
|
||||
#ifndef CONFIG_DM_I2C
|
||||
ret = i2c_read(i2caddress,
|
||||
IR36021_INTEL_MODE_OOFSET,
|
||||
1, (void *)&buf, 1);
|
||||
#else
|
||||
struct udevice *dev;
|
||||
|
||||
ret = i2c_get_chip_for_busnum(0, i2caddress, 1, &dev);
|
||||
if (!ret)
|
||||
ret = dm_i2c_read(dev, IR36021_INTEL_MODE_OOFSET,
|
||||
(void *)&buf, 1);
|
||||
#endif
|
||||
if (ret) {
|
||||
printf("VID: failed to read IR chip mode.\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
if ((buf & IR36021_MODE_MASK) != IR36021_INTEL_MODE) {
|
||||
printf("VID: IR Chip is not used in Intel mode.\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* get the voltage ID from fuse status register */
|
||||
fusesr = in_be32(&gur->dcfg_fusesr);
|
||||
/*
|
||||
* VID is used according to the table below
|
||||
* ---------------------------------------
|
||||
* | DA_V |
|
||||
* |-------------------------------------|
|
||||
* | 5b00000 | 5b00001-5b11110 | 5b11111 |
|
||||
* ---------------+---------+-----------------+---------|
|
||||
* | D | 5b00000 | NO VID | VID = DA_V | NO VID |
|
||||
* | A |----------+---------+-----------------+---------|
|
||||
* | _ | 5b00001 |VID = | VID = |VID = |
|
||||
* | V | ~ | DA_V_ALT| DA_V_ALT | DA_A_VLT|
|
||||
* | _ | 5b11110 | | | |
|
||||
* | A |----------+---------+-----------------+---------|
|
||||
* | L | 5b11111 | No VID | VID = DA_V | NO VID |
|
||||
* | T | | | | |
|
||||
* ------------------------------------------------------
|
||||
*/
|
||||
#ifdef CONFIG_FSL_LSCH2
|
||||
vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_ALTVID_SHIFT) &
|
||||
FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK;
|
||||
if ((vid == 0) || (vid == FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK)) {
|
||||
vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_VID_SHIFT) &
|
||||
FSL_CHASSIS2_DCFG_FUSESR_VID_MASK;
|
||||
}
|
||||
#else
|
||||
vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_ALTVID_SHIFT) &
|
||||
FSL_CORENET_DCFG_FUSESR_ALTVID_MASK;
|
||||
if ((vid == 0) || (vid == FSL_CORENET_DCFG_FUSESR_ALTVID_MASK)) {
|
||||
vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_VID_SHIFT) &
|
||||
FSL_CORENET_DCFG_FUSESR_VID_MASK;
|
||||
}
|
||||
#endif
|
||||
vdd_target = vdd[vid];
|
||||
|
||||
/* check override variable for overriding VDD */
|
||||
vdd_string = env_get(CONFIG_VID_FLS_ENV);
|
||||
if (vdd_override == 0 && vdd_string &&
|
||||
!strict_strtoul(vdd_string, 10, &vdd_string_override))
|
||||
vdd_override = vdd_string_override;
|
||||
if (vdd_override >= VDD_MV_MIN && vdd_override <= VDD_MV_MAX) {
|
||||
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) {
|
||||
debug("VID: VID not used\n");
|
||||
ret = 0;
|
||||
goto exit;
|
||||
} else {
|
||||
/* divide and round up by 10 to get a value in mV */
|
||||
vdd_target = DIV_ROUND_UP(vdd_target, 10);
|
||||
debug("VID: vid = %d mV\n", vdd_target);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read voltage monitor to check real voltage.
|
||||
*/
|
||||
vdd_last = read_voltage(i2caddress);
|
||||
if (vdd_last < 0) {
|
||||
printf("VID: Couldn't read sensor abort VID adjustment\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
vdd_current = vdd_last;
|
||||
debug("VID: Core voltage is currently at %d mV\n", vdd_last);
|
||||
/*
|
||||
* Adjust voltage to at or one step above target.
|
||||
* As measurements are less precise than setting the values
|
||||
* we may run through dummy steps that cancel each other
|
||||
* when stepping up and then down.
|
||||
*/
|
||||
while (vdd_last > 0 &&
|
||||
vdd_last < vdd_target) {
|
||||
vdd_current += IR_VDD_STEP_UP;
|
||||
vdd_last = set_voltage(i2caddress, vdd_current);
|
||||
}
|
||||
while (vdd_last > 0 &&
|
||||
vdd_last > vdd_target + (IR_VDD_STEP_DOWN - 1)) {
|
||||
vdd_current -= IR_VDD_STEP_DOWN;
|
||||
vdd_last = set_voltage(i2caddress, vdd_current);
|
||||
}
|
||||
|
||||
if (vdd_last > 0)
|
||||
printf("VID: Core voltage after adjustment is at %d mV\n",
|
||||
vdd_last);
|
||||
else
|
||||
ret = -1;
|
||||
exit:
|
||||
if (re_enable)
|
||||
enable_interrupts();
|
||||
|
||||
i2c_multiplexer_select_vid_channel(I2C_MUX_CH_DEFAULT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int print_vdd(void)
|
||||
{
|
||||
int vdd_last, ret, i2caddress;
|
||||
|
||||
ret = i2c_multiplexer_select_vid_channel(I2C_MUX_CH_VOL_MONITOR);
|
||||
if (ret) {
|
||||
debug("VID : I2c failed to switch channel\n");
|
||||
return -1;
|
||||
}
|
||||
#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
|
||||
defined(CONFIG_VOL_MONITOR_IR36021_READ)
|
||||
ret = find_ir_chip_on_i2c();
|
||||
if (ret < 0) {
|
||||
printf("VID: Could not find voltage regulator on I2C.\n");
|
||||
goto exit;
|
||||
} else {
|
||||
i2caddress = ret;
|
||||
debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Read voltage monitor to check real voltage.
|
||||
*/
|
||||
vdd_last = read_voltage(i2caddress);
|
||||
if (vdd_last < 0) {
|
||||
printf("VID: Couldn't read sensor abort VID adjustment\n");
|
||||
goto exit;
|
||||
}
|
||||
printf("VID: Core voltage is at %d mV\n", vdd_last);
|
||||
exit:
|
||||
i2c_multiplexer_select_vid_channel(I2C_MUX_CH_DEFAULT);
|
||||
|
||||
return ret < 0 ? -1 : 0;
|
||||
|
||||
}
|
||||
|
||||
static int do_vdd_override(cmd_tbl_t *cmdtp,
|
||||
int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
ulong override;
|
||||
|
||||
if (argc < 2)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
if (!strict_strtoul(argv[1], 10, &override))
|
||||
adjust_vdd(override); /* the value is checked by callee */
|
||||
else
|
||||
return CMD_RET_USAGE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_vdd_read(cmd_tbl_t *cmdtp,
|
||||
int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
if (argc < 1)
|
||||
return CMD_RET_USAGE;
|
||||
print_vdd();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
vdd_override, 2, 0, do_vdd_override,
|
||||
"override VDD",
|
||||
" - override with the voltage specified in mV, eg. 1050"
|
||||
);
|
||||
|
||||
U_BOOT_CMD(
|
||||
vdd_read, 1, 0, do_vdd_read,
|
||||
"read VDD",
|
||||
" - Read the voltage specified in mV"
|
||||
)
|
||||
@@ -0,0 +1,23 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __VID_H_
|
||||
#define __VID_H_
|
||||
|
||||
#define IR36021_LOOP1_MANUAL_ID_OFFSET 0x6A
|
||||
#define IR36021_LOOP1_VOUT_OFFSET 0x9A
|
||||
#define IR36021_MFR_ID_OFFSET 0x92
|
||||
#define IR36021_MFR_ID 0x43
|
||||
#define IR36021_INTEL_MODE_OOFSET 0x14
|
||||
#define IR36021_MODE_MASK 0x20
|
||||
#define IR36021_INTEL_MODE 0x00
|
||||
#define IR36021_AMD_MODE 0x20
|
||||
|
||||
/* step the IR regulator in 5mV increments */
|
||||
#define IR_VDD_STEP_DOWN 5
|
||||
#define IR_VDD_STEP_UP 5
|
||||
int adjust_vdd(ulong vdd_override);
|
||||
|
||||
#endif /* __VID_H_ */
|
||||
@@ -0,0 +1,275 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include "vsc3316_3308.h"
|
||||
|
||||
#define REVISION_ID_REG 0x7E
|
||||
#define INTERFACE_MODE_REG 0x79
|
||||
#define CURRENT_PAGE_REGISTER 0x7F
|
||||
#define CONNECTION_CONFIG_PAGE 0x00
|
||||
#define INPUT_STATE_REG 0x13
|
||||
#define GLOBAL_INPUT_ISE1 0x51
|
||||
#define GLOBAL_INPUT_ISE2 0x52
|
||||
#define GLOBAL_INPUT_GAIN 0x53
|
||||
#define GLOBAL_INPUT_LOS 0x55
|
||||
#define GLOBAL_OUTPUT_PE1 0x56
|
||||
#define GLOBAL_OUTPUT_PE2 0x57
|
||||
#define GLOBAL_OUTPUT_LEVEL 0x58
|
||||
#define GLOBAL_OUTPUT_TERMINATION 0x5A
|
||||
#define GLOBAL_CORE_CNTRL 0x5D
|
||||
#define OUTPUT_MODE_PAGE 0x23
|
||||
#define CORE_CONTROL_PAGE 0x25
|
||||
#define CORE_CONFIG_REG 0x75
|
||||
|
||||
int vsc_if_enable(unsigned int vsc_addr)
|
||||
{
|
||||
u8 data;
|
||||
|
||||
debug("VSC:Configuring VSC at I2C address 0x%2x"
|
||||
" for 2-wire interface\n", vsc_addr);
|
||||
|
||||
/* enable 2-wire Serial InterFace (I2C) */
|
||||
data = 0x02;
|
||||
return i2c_write(vsc_addr, INTERFACE_MODE_REG, 1, &data, 1);
|
||||
}
|
||||
|
||||
int vsc3316_config(unsigned int vsc_addr, int8_t con_arr[][2],
|
||||
unsigned int num_con)
|
||||
{
|
||||
unsigned int i;
|
||||
u8 rev_id = 0;
|
||||
int ret;
|
||||
|
||||
debug("VSC:Initializing VSC3316 at I2C address 0x%2x"
|
||||
" for Tx\n", vsc_addr);
|
||||
|
||||
ret = i2c_read(vsc_addr, REVISION_ID_REG, 1, &rev_id, 1);
|
||||
if (ret < 0) {
|
||||
printf("VSC:0x%x could not read REV_ID from device.\n",
|
||||
vsc_addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (rev_id != 0xab) {
|
||||
printf("VSC: device at address 0x%x is not VSC3316/3308.\n",
|
||||
vsc_addr);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = vsc_if_enable(vsc_addr);
|
||||
if (ret) {
|
||||
printf("VSC:0x%x could not configured for 2-wire I/F.\n",
|
||||
vsc_addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* config connections - page 0x00 */
|
||||
i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, CONNECTION_CONFIG_PAGE);
|
||||
|
||||
/* Making crosspoint connections, by connecting required
|
||||
* input to output */
|
||||
for (i = 0; i < num_con ; i++)
|
||||
i2c_reg_write(vsc_addr, con_arr[i][1], con_arr[i][0]);
|
||||
|
||||
/* input state - page 0x13 */
|
||||
i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, INPUT_STATE_REG);
|
||||
/* Configuring the required input of the switch */
|
||||
for (i = 0; i < num_con ; i++)
|
||||
i2c_reg_write(vsc_addr, con_arr[i][0], 0x80);
|
||||
|
||||
/* Setting Global Input LOS threshold value */
|
||||
i2c_reg_write(vsc_addr, GLOBAL_INPUT_LOS, 0x60);
|
||||
|
||||
/* config output mode - page 0x23 */
|
||||
i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, OUTPUT_MODE_PAGE);
|
||||
/* Turn ON the Output driver correspond to required output*/
|
||||
for (i = 0; i < num_con ; i++)
|
||||
i2c_reg_write(vsc_addr, con_arr[i][1], 0);
|
||||
|
||||
/* configure global core control register, Turn on Global core power */
|
||||
i2c_reg_write(vsc_addr, GLOBAL_CORE_CNTRL, 0);
|
||||
|
||||
vsc_wp_config(vsc_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_B4860QDS_XFI_ERR
|
||||
int vsc3308_config_adjust(unsigned int vsc_addr, const int8_t con_arr[][2],
|
||||
unsigned int num_con)
|
||||
{
|
||||
unsigned int i;
|
||||
u8 rev_id = 0;
|
||||
int ret;
|
||||
|
||||
debug("VSC:Initializing VSC3308 at I2C address 0x%x for Tx\n",
|
||||
vsc_addr);
|
||||
|
||||
ret = i2c_read(vsc_addr, REVISION_ID_REG, 1, &rev_id, 1);
|
||||
if (ret < 0) {
|
||||
printf("VSC:0x%x could not read REV_ID from device.\n",
|
||||
vsc_addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (rev_id != 0xab) {
|
||||
printf("VSC: device at address 0x%x is not VSC3316/3308.\n",
|
||||
vsc_addr);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = vsc_if_enable(vsc_addr);
|
||||
if (ret) {
|
||||
printf("VSC:0x%x could not configured for 2-wire I/F.\n",
|
||||
vsc_addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* config connections - page 0x00 */
|
||||
i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, CONNECTION_CONFIG_PAGE);
|
||||
|
||||
/* Configure Global Input ISE */
|
||||
i2c_reg_write(vsc_addr, GLOBAL_INPUT_ISE1, 0);
|
||||
i2c_reg_write(vsc_addr, GLOBAL_INPUT_ISE2, 0);
|
||||
|
||||
/* Configure Tx/Rx Global Output PE1 */
|
||||
i2c_reg_write(vsc_addr, GLOBAL_OUTPUT_PE1, 0);
|
||||
|
||||
/* Configure Tx/Rx Global Output PE2 */
|
||||
i2c_reg_write(vsc_addr, GLOBAL_OUTPUT_PE2, 0);
|
||||
|
||||
/* Configure Tx/Rx Global Input GAIN */
|
||||
i2c_reg_write(vsc_addr, GLOBAL_INPUT_GAIN, 0x3F);
|
||||
|
||||
/* Setting Global Input LOS threshold value */
|
||||
i2c_reg_write(vsc_addr, GLOBAL_INPUT_LOS, 0xE0);
|
||||
|
||||
/* Setting Global output termination */
|
||||
i2c_reg_write(vsc_addr, GLOBAL_OUTPUT_TERMINATION, 0);
|
||||
|
||||
/* Configure Tx/Rx Global Output level */
|
||||
if (vsc_addr == VSC3308_TX_ADDRESS)
|
||||
i2c_reg_write(vsc_addr, GLOBAL_OUTPUT_LEVEL, 4);
|
||||
else
|
||||
i2c_reg_write(vsc_addr, GLOBAL_OUTPUT_LEVEL, 2);
|
||||
|
||||
/* Making crosspoint connections, by connecting required
|
||||
* input to output */
|
||||
for (i = 0; i < num_con ; i++)
|
||||
i2c_reg_write(vsc_addr, con_arr[i][1], con_arr[i][0]);
|
||||
|
||||
/* input state - page 0x13 */
|
||||
i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, INPUT_STATE_REG);
|
||||
/* Turning off all the required input of the switch */
|
||||
for (i = 0; i < num_con; i++)
|
||||
i2c_reg_write(vsc_addr, con_arr[i][0], 1);
|
||||
|
||||
/* only turn on specific Tx/Rx requested by the XFI erratum */
|
||||
if (vsc_addr == VSC3308_TX_ADDRESS) {
|
||||
i2c_reg_write(vsc_addr, 2, 0);
|
||||
i2c_reg_write(vsc_addr, 3, 0);
|
||||
} else {
|
||||
i2c_reg_write(vsc_addr, 0, 0);
|
||||
i2c_reg_write(vsc_addr, 1, 0);
|
||||
}
|
||||
|
||||
/* config output mode - page 0x23 */
|
||||
i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, OUTPUT_MODE_PAGE);
|
||||
/* Turn off the Output driver correspond to required output*/
|
||||
for (i = 0; i < num_con ; i++)
|
||||
i2c_reg_write(vsc_addr, con_arr[i][1], 1);
|
||||
|
||||
/* only turn on specific Tx/Rx requested by the XFI erratum */
|
||||
if (vsc_addr == VSC3308_TX_ADDRESS) {
|
||||
i2c_reg_write(vsc_addr, 0, 0);
|
||||
i2c_reg_write(vsc_addr, 1, 0);
|
||||
} else {
|
||||
i2c_reg_write(vsc_addr, 3, 0);
|
||||
i2c_reg_write(vsc_addr, 4, 0);
|
||||
}
|
||||
|
||||
/* configure global core control register, Turn on Global core power */
|
||||
i2c_reg_write(vsc_addr, GLOBAL_CORE_CNTRL, 0);
|
||||
|
||||
vsc_wp_config(vsc_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int vsc3308_config(unsigned int vsc_addr, const int8_t con_arr[][2],
|
||||
unsigned int num_con)
|
||||
{
|
||||
unsigned int i;
|
||||
u8 rev_id = 0;
|
||||
int ret;
|
||||
|
||||
debug("VSC:Initializing VSC3308 at I2C address 0x%x"
|
||||
" for Tx\n", vsc_addr);
|
||||
|
||||
ret = i2c_read(vsc_addr, REVISION_ID_REG, 1, &rev_id, 1);
|
||||
if (ret < 0) {
|
||||
printf("VSC:0x%x could not read REV_ID from device.\n",
|
||||
vsc_addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (rev_id != 0xab) {
|
||||
printf("VSC: device at address 0x%x is not VSC3316/3308.\n",
|
||||
vsc_addr);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = vsc_if_enable(vsc_addr);
|
||||
if (ret) {
|
||||
printf("VSC:0x%x could not configured for 2-wire I/F.\n",
|
||||
vsc_addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* config connections - page 0x00 */
|
||||
i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, CONNECTION_CONFIG_PAGE);
|
||||
|
||||
/* Making crosspoint connections, by connecting required
|
||||
* input to output */
|
||||
for (i = 0; i < num_con ; i++)
|
||||
i2c_reg_write(vsc_addr, con_arr[i][1], con_arr[i][0]);
|
||||
|
||||
/*Configure Global Input ISE and gain */
|
||||
i2c_reg_write(vsc_addr, GLOBAL_INPUT_ISE1, 0x12);
|
||||
i2c_reg_write(vsc_addr, GLOBAL_INPUT_ISE2, 0x12);
|
||||
|
||||
/* input state - page 0x13 */
|
||||
i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, INPUT_STATE_REG);
|
||||
/* Turning ON the required input of the switch */
|
||||
for (i = 0; i < num_con ; i++)
|
||||
i2c_reg_write(vsc_addr, con_arr[i][0], 0);
|
||||
|
||||
/* Setting Global Input LOS threshold value */
|
||||
i2c_reg_write(vsc_addr, GLOBAL_INPUT_LOS, 0x60);
|
||||
|
||||
/* config output mode - page 0x23 */
|
||||
i2c_reg_write(vsc_addr, CURRENT_PAGE_REGISTER, OUTPUT_MODE_PAGE);
|
||||
/* Turn ON the Output driver correspond to required output*/
|
||||
for (i = 0; i < num_con ; i++)
|
||||
i2c_reg_write(vsc_addr, con_arr[i][1], 0);
|
||||
|
||||
/* configure global core control register, Turn on Global core power */
|
||||
i2c_reg_write(vsc_addr, GLOBAL_CORE_CNTRL, 0);
|
||||
|
||||
vsc_wp_config(vsc_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vsc_wp_config(unsigned int vsc_addr)
|
||||
{
|
||||
debug("VSC:Configuring VSC at address:0x%x for WP\n", vsc_addr);
|
||||
|
||||
/* For new crosspoint configuration to occur, WP bit of
|
||||
* CORE_CONFIG_REG should be set 1 and then reset to 0 */
|
||||
i2c_reg_write(vsc_addr, CORE_CONFIG_REG, 0x01);
|
||||
i2c_reg_write(vsc_addr, CORE_CONFIG_REG, 0x0);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __VSC_CROSSBAR_H_
|
||||
#define __VSC_CROSSBAR_H 1_
|
||||
|
||||
#include <common.h>
|
||||
#include <i2c.h>
|
||||
#include <errno.h>
|
||||
|
||||
int vsc_if_enable(unsigned int vsc_addr);
|
||||
int vsc3316_config(unsigned int vsc_addr, int8_t con_arr[][2],
|
||||
unsigned int num_con);
|
||||
#ifdef CONFIG_SYS_FSL_B4860QDS_XFI_ERR
|
||||
int vsc3308_config_adjust(unsigned int vsc_addr, const int8_t con_arr[][2],
|
||||
unsigned int num_con);
|
||||
#endif
|
||||
int vsc3308_config(unsigned int vsc_addr, const int8_t con_arr[][2],
|
||||
unsigned int num_con);
|
||||
void vsc_wp_config(unsigned int vsc_addr);
|
||||
|
||||
#endif /* __VSC_CROSSBAR_H_ */
|
||||
@@ -0,0 +1,232 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
/* 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)
|
||||
{
|
||||
return dpm_rrp(reg);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#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_ */
|
||||
@@ -0,0 +1,59 @@
|
||||
if TARGET_P3041DS
|
||||
|
||||
config SYS_BOARD
|
||||
default "corenet_ds"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "freescale"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "P3041DS"
|
||||
|
||||
source "board/freescale/common/Kconfig"
|
||||
|
||||
endif
|
||||
|
||||
if TARGET_P4080DS
|
||||
|
||||
config SYS_BOARD
|
||||
default "corenet_ds"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "freescale"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "P4080DS"
|
||||
|
||||
source "board/freescale/common/Kconfig"
|
||||
|
||||
endif
|
||||
|
||||
if TARGET_P5020DS
|
||||
|
||||
config SYS_BOARD
|
||||
default "corenet_ds"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "freescale"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "P5020DS"
|
||||
|
||||
source "board/freescale/common/Kconfig"
|
||||
|
||||
endif
|
||||
|
||||
if TARGET_P5040DS
|
||||
|
||||
config SYS_BOARD
|
||||
default "corenet_ds"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "freescale"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "P5040DS"
|
||||
|
||||
source "board/freescale/common/Kconfig"
|
||||
|
||||
endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user