avionic design with actual uboot and tooling

submodule of avionic design uboot bootloader and with included tools to
get you started , read readme.md and readme-tk1-loader.md
This commit is contained in:
2026-03-03 21:46:32 +02:00
parent fe3ba02c96
commit 68d74d3181
11967 changed files with 2221897 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
if TARGET_KMP204X
config SYS_BOARD
default "kmp204x"
config SYS_VENDOR
default "keymile"
config SYS_CONFIG_NAME
default "kmp204x"
endif

View File

@@ -0,0 +1,7 @@
KMP204X BOARD
M: Valentin Longchamp <valentin.longchamp@keymile.com>
S: Maintained
F: board/keymile/kmp204x/
F: include/configs/kmp204x.h
F: configs/kmcoge4_defconfig
F: configs/kmlion1_defconfig

View File

@@ -0,0 +1,12 @@
#
# (C) Copyright 2001-2007
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := kmp204x.o ddr.o eth.o tlb.o pci.o law.o qrio.o \
../common/common.o ../common/ivm.o

View File

@@ -0,0 +1,64 @@
/*
* (C) Copyright 2013 Keymile AG
* Valentin Longchamp <valentin.longchamp@keymile.com>
*
* Copyright 2009-2011 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <i2c.h>
#include <hwconfig.h>
#include <asm/mmu.h>
#include <fsl_ddr_sdram.h>
#include <fsl_ddr_dimm_params.h>
void fsl_ddr_board_options(memctl_options_t *popts,
dimm_params_t *pdimm,
unsigned int ctrl_num)
{
if (ctrl_num) {
printf("Wrong parameter for controller number %d", ctrl_num);
return;
}
/* automatic calibration for nb of cycles between read and DQS pre */
popts->cpo_override = 0xFF;
/* 1/2 clk delay between wr command and data strobe */
popts->write_data_delay = 4;
/* clk lauched 1/2 applied cylcle after address command */
popts->clk_adjust = 4;
/* 1T timing: command/address held for only 1 cycle */
popts->twot_en = 0;
/* we have only one module, half str should be OK */
popts->half_strength_driver_enable = 1;
/* wrlvl values overriden as recommended by ddr init func */
popts->wrlvl_override = 1;
popts->wrlvl_sample = 0xf;
popts->wrlvl_start = 0x6;
/* Enable ZQ calibration */
popts->zq_en = 1;
/* DHC_EN =1, ODT = 75 Ohm */
popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR_ODT_75ohm;
}
phys_size_t initdram(int board_type)
{
phys_size_t dram_size = 0;
puts("Initializing with SPD\n");
dram_size = fsl_ddr_sdram();
dram_size = setup_ddr_tlbs(dram_size / 0x100000);
dram_size *= 0x100000;
debug(" DDR: ");
return dram_size;
}

View File

@@ -0,0 +1,71 @@
/*
* (C) Copyright 2013 Keymile AG
* Valentin Longchamp <valentin.longchamp@keymile.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <netdev.h>
#include <fm_eth.h>
#include <fsl_mdio.h>
#include <phy.h>
int board_eth_init(bd_t *bis)
{
int ret = 0;
#ifdef CONFIG_FMAN_ENET
struct fsl_pq_mdio_info dtsec_mdio_info;
printf("Initializing Fman\n");
dtsec_mdio_info.regs =
(struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR;
dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;
/* Register the real 1G MDIO bus */
fsl_pq_mdio_init(bis, &dtsec_mdio_info);
/* DTESC1/2 don't have a PHY, they are temporarily disabled
* so that u-boot doesn't try to unsuccessfuly enable them */
fm_disable_port(FM1_DTSEC1);
fm_disable_port(FM1_DTSEC2);
/*
* Program RGMII DTSEC5 (FM1 MAC5) on the EC2 physical itf
* This is the debug interface, the only one used in u-boot
*/
fm_info_set_phy_address(FM1_DTSEC5, CONFIG_SYS_FM1_DTSEC5_PHY_ADDR);
fm_info_set_mdio(FM1_DTSEC5,
miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME));
ret = cpu_eth_init(bis);
/* reenable DTSEC1/2 for later (kernel) */
fm_enable_port(FM1_DTSEC1);
fm_enable_port(FM1_DTSEC2);
#endif
return ret;
}
#if defined(CONFIG_PHYLIB) && defined(CONFIG_PHY_MARVELL)
#define mv88E1118_PAGE_REG 22
int board_phy_config(struct phy_device *phydev)
{
if (phydev->addr == CONFIG_SYS_FM1_DTSEC5_PHY_ADDR) {
/* driver config is good */
if (phydev->drv->config)
phydev->drv->config(phydev);
/* but we still need to fix the LEDs */
phy_write(phydev, MDIO_DEVAD_NONE, mv88E1118_PAGE_REG, 0x0003);
phy_write(phydev, MDIO_DEVAD_NONE, 0x10, 0x0840);
phy_write(phydev, MDIO_DEVAD_NONE, mv88E1118_PAGE_REG, 0x0000);
}
return 0;
}
#endif

View File

@@ -0,0 +1,307 @@
/*
* (C) Copyright 2013 Keymile AG
* Valentin Longchamp <valentin.longchamp@keymile.com>
*
* Copyright 2011,2012 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <command.h>
#include <netdev.h>
#include <linux/compiler.h>
#include <asm/mmu.h>
#include <asm/processor.h>
#include <asm/cache.h>
#include <asm/immap_85xx.h>
#include <asm/fsl_law.h>
#include <asm/fsl_serdes.h>
#include <asm/fsl_portals.h>
#include <asm/fsl_liodn.h>
#include <fm_eth.h>
#include "../common/common.h"
#include "kmp204x.h"
DECLARE_GLOBAL_DATA_PTR;
static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN];
int checkboard(void)
{
printf("Board: Keymile %s\n", CONFIG_KM_BOARD_NAME);
return 0;
}
/* I2C deblocking uses the algorithm defined in board/keymile/common/common.c
* 2 dedicated QRIO GPIOs externally pull the SCL and SDA lines
* For I2C only the low state is activly driven and high state is pulled-up
* by a resistor. Therefore the deblock GPIOs are used
* -> as an active output to drive a low state
* -> as an open-drain input to have a pulled-up high state
*/
/* QRIO GPIOs used for deblocking */
#define DEBLOCK_PORT1 GPIO_A
#define DEBLOCK_SCL1 20
#define DEBLOCK_SDA1 21
/* By default deblock GPIOs are floating */
static void i2c_deblock_gpio_cfg(void)
{
/* set I2C bus 1 deblocking GPIOs input, but 0 value for open drain */
qrio_gpio_direction_input(DEBLOCK_PORT1, DEBLOCK_SCL1);
qrio_gpio_direction_input(DEBLOCK_PORT1, DEBLOCK_SDA1);
qrio_set_gpio(DEBLOCK_PORT1, DEBLOCK_SCL1, 0);
qrio_set_gpio(DEBLOCK_PORT1, DEBLOCK_SDA1, 0);
}
void set_sda(int state)
{
qrio_set_opendrain_gpio(DEBLOCK_PORT1, DEBLOCK_SDA1, state);
}
void set_scl(int state)
{
qrio_set_opendrain_gpio(DEBLOCK_PORT1, DEBLOCK_SCL1, state);
}
int get_sda(void)
{
return qrio_get_gpio(DEBLOCK_PORT1, DEBLOCK_SDA1);
}
int get_scl(void)
{
return qrio_get_gpio(DEBLOCK_PORT1, DEBLOCK_SCL1);
}
#define ZL30158_RST 8
#define BFTIC4_RST 0
#define RSTRQSR1_WDT_RR 0x00200000
#define RSTRQSR1_SW_RR 0x00100000
int board_early_init_f(void)
{
ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
bool cpuwd_flag = false;
/* configure mode for uP reset request */
qrio_uprstreq(UPREQ_CORE_RST);
/* board only uses the DDR_MCK0, so disable the DDR_MCK1/2/3 */
setbits_be32(&gur->ddrclkdr, 0x001f000f);
/* set reset reason according CPU register */
if ((gur->rstrqsr1 & (RSTRQSR1_WDT_RR | RSTRQSR1_SW_RR)) ==
RSTRQSR1_WDT_RR)
cpuwd_flag = true;
qrio_cpuwd_flag(cpuwd_flag);
/* clear CPU bits by writing 1 */
setbits_be32(&gur->rstrqsr1, RSTRQSR1_WDT_RR | RSTRQSR1_SW_RR);
/* set the BFTIC's prstcfg to reset at power-up and unit reset only */
qrio_prstcfg(BFTIC4_RST, PRSTCFG_POWUP_UNIT_RST);
/* and enable WD on it */
qrio_wdmask(BFTIC4_RST, true);
/* set the ZL30138's prstcfg to reset at power-up only */
qrio_prstcfg(ZL30158_RST, PRSTCFG_POWUP_RST);
/* and take it out of reset as soon as possible (needed for Hooper) */
qrio_prst(ZL30158_RST, false, false);
return 0;
}
int board_early_init_r(void)
{
int ret = 0;
/* Flush d-cache and invalidate i-cache of any FLASH data */
flush_dcache();
invalidate_icache();
set_liodns();
setup_portals();
ret = trigger_fpga_config();
if (ret)
printf("error triggering PCIe FPGA config\n");
/* enable the Unit LED (red) & Boot LED (on) */
qrio_set_leds();
/* enable Application Buffer */
qrio_enable_app_buffer();
return ret;
}
unsigned long get_board_sys_clk(unsigned long dummy)
{
return 66666666;
}
#define ETH_FRONT_PHY_RST 15
#define QSFP2_RST 11
#define QSFP1_RST 10
#define ZL30343_RST 9
int misc_init_f(void)
{
/* configure QRIO pis for i2c deblocking */
i2c_deblock_gpio_cfg();
/* configure the front phy's prstcfg and take it out of reset */
qrio_prstcfg(ETH_FRONT_PHY_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
qrio_prst(ETH_FRONT_PHY_RST, false, false);
/* set the ZL30343 prstcfg to reset at power-up only */
qrio_prstcfg(ZL30343_RST, PRSTCFG_POWUP_RST);
/* and enable the WD on it */
qrio_wdmask(ZL30343_RST, true);
/* set the QSFPs' prstcfg to reset at power-up and unit rst only */
qrio_prstcfg(QSFP1_RST, PRSTCFG_POWUP_UNIT_RST);
qrio_prstcfg(QSFP2_RST, PRSTCFG_POWUP_UNIT_RST);
/* and enable the WD on them */
qrio_wdmask(QSFP1_RST, true);
qrio_wdmask(QSFP2_RST, true);
return 0;
}
#define NUM_SRDS_BANKS 2
int misc_init_r(void)
{
serdes_corenet_t *regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
u32 expected[NUM_SRDS_BANKS] = {SRDS_PLLCR0_RFCK_SEL_100,
SRDS_PLLCR0_RFCK_SEL_125};
unsigned int i;
/* check SERDES reference clocks */
for (i = 0; i < NUM_SRDS_BANKS; i++) {
u32 actual = in_be32(&regs->bank[i].pllcr0);
actual &= SRDS_PLLCR0_RFCK_SEL_MASK;
if (actual != expected[i]) {
printf("Warning: SERDES bank %u expects reference \
clock %sMHz, but actual is %sMHz\n", i + 1,
serdes_clock_to_string(expected[i]),
serdes_clock_to_string(actual));
}
}
ivm_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
return 0;
}
#if defined(CONFIG_HUSH_INIT_VAR)
int hush_init_var(void)
{
ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
return 0;
}
#endif
#if defined(CONFIG_LAST_STAGE_INIT)
int last_stage_init(void)
{
#if defined(CONFIG_KMCOGE4)
/* on KMCOGE4, the BFTIC4 is on the LBAPP2 */
struct bfticu_iomap *bftic4 =
(struct bfticu_iomap *)CONFIG_SYS_LBAPP2_BASE;
u8 dip_switch = in_8((u8 *)&(bftic4->mswitch)) & BFTICU_DIPSWITCH_MASK;
if (dip_switch != 0) {
/* start bootloader */
puts("DIP: Enabled\n");
setenv("actual_bank", "0");
}
#endif
set_km_env();
return 0;
}
#endif
#ifdef CONFIG_SYS_DPAA_FMAN
void fdt_fixup_fman_mac_addresses(void *blob)
{
int node, i, ret;
char *tmp, *end;
unsigned char mac_addr[6];
/* get the mac addr from env */
tmp = getenv("ethaddr");
if (!tmp) {
printf("ethaddr env variable not defined\n");
return;
}
for (i = 0; i < 6; i++) {
mac_addr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
if (tmp)
tmp = (*end) ? end+1 : end;
}
/* find the correct fdt ethernet path and correct it */
node = fdt_path_offset(blob, "/soc/fman/ethernet@e8000");
if (node < 0) {
printf("no /soc/fman/ethernet path offset\n");
return;
}
ret = fdt_setprop(blob, node, "local-mac-address", &mac_addr, 6);
if (ret) {
printf("error setting local-mac-address property\n");
return;
}
}
#endif
int ft_board_setup(void *blob, bd_t *bd)
{
phys_addr_t base;
phys_size_t size;
ft_cpu_setup(blob, bd);
base = getenv_bootm_low();
size = getenv_bootm_size();
fdt_fixup_memory(blob, (u64)base, (u64)size);
#if defined(CONFIG_HAS_FSL_DR_USB) || defined(CONFIG_HAS_FSL_MPH_USB)
fdt_fixup_dr_usb(blob, bd);
#endif
#ifdef CONFIG_PCI
pci_of_setup(blob, bd);
#endif
fdt_fixup_liodn(blob);
#ifdef CONFIG_SYS_DPAA_FMAN
fdt_fixup_fman_ethernet(blob);
fdt_fixup_fman_mac_addresses(blob);
#endif
return 0;
}
#if defined(CONFIG_POST)
/* DIC26_SELFTEST GPIO used to start factory test sw */
#define SELFTEST_PORT GPIO_A
#define SELFTEST_PIN 31
int post_hotkeys_pressed(void)
{
qrio_gpio_direction_input(SELFTEST_PORT, SELFTEST_PIN);
return qrio_get_gpio(SELFTEST_PORT, SELFTEST_PIN);
}
#endif

View File

@@ -0,0 +1,35 @@
/*
* (C) Copyright 2013 Keymile AG
* Valentin Longchamp <valentin.longchamp@keymile.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
/* QRIO GPIO ports */
#define GPIO_A 0x40
#define GPIO_B 0x60
int qrio_get_gpio(u8 port_off, u8 gpio_nr);
void qrio_set_opendrain_gpio(u8 port_off, u8 gpio_nr, u8 val);
void qrio_set_gpio(u8 port_off, u8 gpio_nr, bool value);
void qrio_gpio_direction_output(u8 port_off, u8 gpio_nr, bool value);
void qrio_gpio_direction_input(u8 port_off, u8 gpio_nr);
#define PRSTCFG_POWUP_UNIT_CORE_RST 0x0
#define PRSTCFG_POWUP_UNIT_RST 0x1
#define PRSTCFG_POWUP_RST 0x3
void qrio_prst(u8 bit, bool en, bool wden);
void qrio_wdmask(u8 bit, bool wden);
void qrio_prstcfg(u8 bit, u8 mode);
void qrio_set_leds(void);
void qrio_enable_app_buffer(void);
void qrio_cpuwd_flag(bool flag);
int qrio_reset_reason(void);
#define UPREQ_UNIT_RST 0x0
#define UPREQ_CORE_RST 0x1
void qrio_uprstreq(u8 mode);
void pci_of_setup(void *blob, bd_t *bd);

View File

@@ -0,0 +1,40 @@
/*
* (C) Copyright 2013 Keymile AG
* Valentin Longchamp <valentin.longchamp@keymile.com>
*
* Copyright 2008-2011 Freescale Semiconductor, Inc.
*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/fsl_law.h>
#include <asm/mmu.h>
struct law_entry law_table[] = {
#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 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_32K, LAW_TRGT_IF_LBC),
#endif
SET_LAW(CONFIG_SYS_QRIO_BASE_PHYS, LAW_SIZE_64K, LAW_TRGT_IF_LBC),
#ifdef CONFIG_SYS_LBAPP1_BASE_PHYS
SET_LAW(CONFIG_SYS_LBAPP1_BASE_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_LBC),
#endif
#ifdef CONFIG_SYS_LBAPP2_BASE_PHYS
SET_LAW(CONFIG_SYS_LBAPP2_BASE_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_LBC),
#endif
};
int num_law_entries = ARRAY_SIZE(law_table);

View File

@@ -0,0 +1,76 @@
#
# Copyright 2012 Freescale Semiconductor, Inc.
#
# SPDX-License-Identifier: GPL-2.0+
#
# Refer docs/README.pblimage for more details about how-to configure
# and create PBL boot image
#
#PBI commands
#Configure ALTCBAR for DCSR -> DCSR@89000000
091380c0 000009C4
09000010 00000000
091380c0 000009C4
09000014 00000000
091380c0 000009C4
09000018 81d00000
#Workaround for A-004849
091380c0 000009C4
890B0050 00000002
091380c0 000009C4
890B0054 00000002
091380c0 000009C4
890B0058 00000002
091380c0 000009C4
890B005C 00000002
091380c0 000009C4
890B0090 00000002
091380c0 000009C4
890B0094 00000002
091380c0 000009C4
890B0098 00000002
091380c0 000009C4
890B009C 00000002
091380c0 000009C4
890B0108 00000012
091380c0 000009C4
#Workaround for A-006559 needed for rev 2.0 of P2041 silicon
89021008 0000f000
091380c0 000009C4
89021028 0000f000
091380c0 000009C4
89021048 0000f000
091380c0 000009C4
89021068 0000f000
091380c0 000009C4
#Flush PBL data
09138000 00000000
#Disable ALTCBAR
09000018 00000000
091380c0 000009C4
#Initialize CPC1 as 1MB SRAM
09010000 00200400
09138000 00000000
091380c0 00000100
09010100 00000000
09010104 fff0000b
09010f00 08000000
09010000 80000000
#Configure LAW for CPC1
09000d00 00000000
09000d04 fff00000
09000d08 81000013
09000010 00000000
09000014 ff000000
09000018 81000000
#Initialize eSPI controller, default configuration is slow for eSPI to
#load data, this configuration comes from u-boot eSPI driver.
09110000 80000403
09110020 27170008
09110024 00100008
09110028 00100008
0911002c 00100008
#Flush PBL data
09138000 00000000
091380c0 00000000

View File

@@ -0,0 +1,123 @@
/*
* (C) Copyright 2013 Keymile AG
* Valentin Longchamp <valentin.longchamp@keymile.com>
*
* Copyright 2007-2011 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <command.h>
#include <pci.h>
#include <asm/fsl_pci.h>
#include <libfdt.h>
#include <fdt_support.h>
#include <asm/fsl_serdes.h>
#include <asm/errno.h>
#include "kmp204x.h"
#define PROM_SEL_L 11
/* control the PROM_SEL_L signal*/
static void toggle_fpga_eeprom_bus(bool cpu_own)
{
qrio_gpio_direction_output(GPIO_A, PROM_SEL_L, !cpu_own);
}
#define CONF_SEL_L 10
#define FPGA_PROG_L 19
#define FPGA_DONE 18
#define FPGA_INIT_L 17
int trigger_fpga_config(void)
{
int ret = 0, init_l;
/* approx 10ms */
u32 timeout = 10000;
/* make sure the FPGA_can access the EEPROM */
toggle_fpga_eeprom_bus(false);
/* assert CONF_SEL_L to be able to drive FPGA_PROG_L */
qrio_gpio_direction_output(GPIO_A, CONF_SEL_L, 0);
/* trigger the config start */
qrio_gpio_direction_output(GPIO_A, FPGA_PROG_L, 0);
/* small delay for INIT_L line */
udelay(10);
/* wait for FPGA_INIT to be asserted */
do {
init_l = qrio_get_gpio(GPIO_A, FPGA_INIT_L);
if (timeout-- == 0) {
printf("FPGA_INIT timeout\n");
ret = -EFAULT;
break;
}
udelay(10);
} while (init_l);
/* deassert FPGA_PROG, config should start */
qrio_set_gpio(GPIO_A, FPGA_PROG_L, 1);
return ret;
}
/* poll the FPGA_DONE signal and give the EEPROM back to the QorIQ */
static int wait_for_fpga_config(void)
{
int ret = 0, done;
/* approx 5 s */
u32 timeout = 500000;
printf("PCIe FPGA config:");
do {
done = qrio_get_gpio(GPIO_A, FPGA_DONE);
if (timeout-- == 0) {
printf(" FPGA_DONE timeout\n");
ret = -EFAULT;
goto err_out;
}
udelay(10);
} while (!done);
printf(" done\n");
err_out:
/* deactive CONF_SEL and give the CPU conf EEPROM access */
qrio_set_gpio(GPIO_A, CONF_SEL_L, 1);
toggle_fpga_eeprom_bus(true);
return ret;
}
#define PCIE_SW_RST 14
#define PEXHC_RST 13
#define HOOPER_RST 12
void pci_init_board(void)
{
qrio_prstcfg(PCIE_SW_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
qrio_prstcfg(PEXHC_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
qrio_prstcfg(HOOPER_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
/* wait for the PCIe FPGA to be configured
* it has been triggered earlier in board_early_init_r */
if (wait_for_fpga_config())
printf("error finishing PCIe FPGA config\n");
qrio_prst(PCIE_SW_RST, false, false);
qrio_prst(PEXHC_RST, false, false);
qrio_prst(HOOPER_RST, false, false);
/* Hooper is not direcly PCIe capable */
mdelay(50);
fsl_pcie_init_board(0);
}
void pci_of_setup(void *blob, bd_t *bd)
{
FT_FSL_PCI_SETUP;
}

View File

@@ -0,0 +1,207 @@
/*
* (C) Copyright 2013 Keymile AG
* Valentin Longchamp <valentin.longchamp@keymile.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include "../common/common.h"
#include "kmp204x.h"
/* QRIO GPIO register offsets */
#define DIRECT_OFF 0x18
#define GPRT_OFF 0x1c
int qrio_get_gpio(u8 port_off, u8 gpio_nr)
{
u32 gprt;
void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
gprt = in_be32(qrio_base + port_off + GPRT_OFF);
return (gprt >> gpio_nr) & 1U;
}
void qrio_set_gpio(u8 port_off, u8 gpio_nr, bool value)
{
u32 gprt, mask;
void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
mask = 1U << gpio_nr;
gprt = in_be32(qrio_base + port_off + GPRT_OFF);
if (value)
gprt |= mask;
else
gprt &= ~mask;
out_be32(qrio_base + port_off + GPRT_OFF, gprt);
}
void qrio_gpio_direction_output(u8 port_off, u8 gpio_nr, bool value)
{
u32 direct, mask;
void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
mask = 1U << gpio_nr;
direct = in_be32(qrio_base + port_off + DIRECT_OFF);
direct |= mask;
out_be32(qrio_base + port_off + DIRECT_OFF, direct);
qrio_set_gpio(port_off, gpio_nr, value);
}
void qrio_gpio_direction_input(u8 port_off, u8 gpio_nr)
{
u32 direct, mask;
void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
mask = 1U << gpio_nr;
direct = in_be32(qrio_base + port_off + DIRECT_OFF);
direct &= ~mask;
out_be32(qrio_base + port_off + DIRECT_OFF, direct);
}
void qrio_set_opendrain_gpio(u8 port_off, u8 gpio_nr, u8 val)
{
u32 direct, mask;
void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
mask = 1U << gpio_nr;
direct = in_be32(qrio_base + port_off + DIRECT_OFF);
if (val == 0)
/* set to output -> GPIO drives low */
direct |= mask;
else
/* set to input -> GPIO floating */
direct &= ~mask;
out_be32(qrio_base + port_off + DIRECT_OFF, direct);
}
#define WDMASK_OFF 0x16
void qrio_wdmask(u8 bit, bool wden)
{
u16 wdmask;
void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
wdmask = in_be16(qrio_base + WDMASK_OFF);
if (wden)
wdmask |= (1 << bit);
else
wdmask &= ~(1 << bit);
out_be16(qrio_base + WDMASK_OFF, wdmask);
}
#define PRST_OFF 0x1a
void qrio_prst(u8 bit, bool en, bool wden)
{
u16 prst;
void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
qrio_wdmask(bit, wden);
prst = in_be16(qrio_base + PRST_OFF);
if (en)
prst &= ~(1 << bit);
else
prst |= (1 << bit);
out_be16(qrio_base + PRST_OFF, prst);
}
#define PRSTCFG_OFF 0x1c
void qrio_prstcfg(u8 bit, u8 mode)
{
u32 prstcfg;
u8 i;
void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
prstcfg = in_be32(qrio_base + PRSTCFG_OFF);
for (i = 0; i < 2; i++) {
if (mode & (1<<i))
set_bit(2*bit+i, &prstcfg);
else
clear_bit(2*bit+i, &prstcfg);
}
out_be32(qrio_base + PRSTCFG_OFF, prstcfg);
}
#define CTRLH_OFF 0x02
#define CTRLH_WRL_BOOT 0x01
#define CTRLH_WRL_UNITRUN 0x02
void qrio_set_leds(void)
{
u8 ctrlh;
void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
/* set UNIT LED to RED and BOOT LED to ON */
ctrlh = in_8(qrio_base + CTRLH_OFF);
ctrlh |= (CTRLH_WRL_BOOT | CTRLH_WRL_UNITRUN);
out_8(qrio_base + CTRLH_OFF, ctrlh);
}
#define CTRLL_OFF 0x03
#define CTRLL_WRB_BUFENA 0x20
void qrio_enable_app_buffer(void)
{
u8 ctrll;
void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
/* enable application buffer */
ctrll = in_8(qrio_base + CTRLL_OFF);
ctrll |= (CTRLL_WRB_BUFENA);
out_8(qrio_base + CTRLL_OFF, ctrll);
}
#define REASON1_OFF 0x12
#define REASON1_CPUWD 0x01
void qrio_cpuwd_flag(bool flag)
{
u8 reason1;
void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
reason1 = in_8(qrio_base + REASON1_OFF);
if (flag)
reason1 |= REASON1_CPUWD;
else
reason1 &= ~REASON1_CPUWD;
out_8(qrio_base + REASON1_OFF, reason1);
}
#define RSTCFG_OFF 0x11
void qrio_uprstreq(u8 mode)
{
u32 rstcfg;
void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
rstcfg = in_8(qrio_base + RSTCFG_OFF);
if (mode & UPREQ_CORE_RST)
rstcfg |= UPREQ_CORE_RST;
else
rstcfg &= ~UPREQ_CORE_RST;
out_8(qrio_base + RSTCFG_OFF, rstcfg);
}

View File

@@ -0,0 +1,11 @@
#
# Default RCW for kmp204x boards
#
#PBL preamble and RCW header
aa55aa55 010e0100
#64 bytes RCW data
14600000 00000000 28200000 00000000
148E70CF CFC02000 58000000 41000000
00000000 00000000 00000000 F0428816
00000000 00000000 00000000 00000000

View File

@@ -0,0 +1,110 @@
/*
* (C) Copyright 2013 Keymile AG
* Valentin Longchamp <valentin.longchamp@keymile.com>
*
* Copyright 2008-2011 Freescale Semiconductor, Inc.
*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/mmu.h>
struct fsl_e_tlb_entry tlb_table[] = {
/* TLB 0 - for temp stack in cache */
SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR,
CONFIG_SYS_INIT_RAM_ADDR_PHYS,
MAS3_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),
/* TLB 1 */
/* *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),
/* *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),
/* QRIO */
SET_TLB_ENTRY(1, CONFIG_SYS_QRIO_BASE, CONFIG_SYS_QRIO_BASE_PHYS,
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
0, 2, BOOKE_PAGESZ_64K, 1),
/* *I*G* - PCI1 */
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_512M, 1),
/* *I*G* - PCI3 */
SET_TLB_ENTRY(1, CONFIG_SYS_PCIE3_MEM_VIRT, CONFIG_SYS_PCIE3_MEM_PHYS,
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
0, 4, BOOKE_PAGESZ_512M, 1),
/* *I*G* - PCI1&3 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_128K, 1),
#ifdef CONFIG_SYS_LBAPP1_BASE_PHYS
/* LBAPP1 */
SET_TLB_ENTRY(1, CONFIG_SYS_LBAPP1_BASE, CONFIG_SYS_LBAPP1_BASE_PHYS,
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
0, 7, BOOKE_PAGESZ_256M, 1),
#endif
#ifdef CONFIG_SYS_LBAPP2_BASE_PHYS
/* LBAPP2 */
SET_TLB_ENTRY(1, CONFIG_SYS_LBAPP2_BASE, CONFIG_SYS_LBAPP2_BASE_PHYS,
MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
0, 8, BOOKE_PAGESZ_256M, 1),
#endif
/* 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_SW|MAS3_SR, MAS2_I|MAS2_G,
0, 16, BOOKE_PAGESZ_32K, 1),
#endif
};
int num_tlb_entries = ARRAY_SIZE(tlb_table);