- Bug fixes and updates on vid, ls1088a lx2160a and other layerscape
  platforms.
- Add optee_rpmb support for LX2 & Kontron sl28 support
This commit is contained in:
Tom Rini
2020-10-29 09:10:24 -04:00
141 changed files with 2399 additions and 119 deletions

View File

@@ -379,6 +379,7 @@ static int set_voltage_to_LTC(int i2caddress, int vdd)
{
int ret, vdd_last, vdd_target = vdd;
int count = 100, temp = 0;
unsigned char value;
/* Scale up to the LTC resolution is 1/4096V */
vdd = (vdd * 4096) / 1000;
@@ -391,16 +392,51 @@ static int set_voltage_to_LTC(int i2caddress, int vdd)
/* Write the desired voltage code to the regulator */
#ifndef CONFIG_DM_I2C
/* Check write protect state */
ret = i2c_read(I2C_VOL_MONITOR_ADDR,
PMBUS_CMD_WRITE_PROTECT, 1,
(void *)&value, sizeof(value));
if (ret)
goto exit;
if (value != EN_WRITE_ALL_CMD) {
value = EN_WRITE_ALL_CMD;
ret = i2c_write(I2C_VOL_MONITOR_ADDR,
PMBUS_CMD_WRITE_PROTECT, 1,
(void *)&value, sizeof(value));
if (ret)
goto exit;
}
ret = i2c_write(I2C_VOL_MONITOR_ADDR,
PMBUS_CMD_PAGE_PLUS_WRITE, 1, (void *)&buff, 5);
PMBUS_CMD_PAGE_PLUS_WRITE, 1,
(void *)&buff, sizeof(buff));
#else
struct udevice *dev;
ret = i2c_get_chip_for_busnum(0, I2C_VOL_MONITOR_ADDR, 1, &dev);
if (!ret)
if (!ret) {
/* Check write protect state */
ret = dm_i2c_read(dev,
PMBUS_CMD_WRITE_PROTECT,
(void *)&value, sizeof(value));
if (ret)
goto exit;
if (value != EN_WRITE_ALL_CMD) {
value = EN_WRITE_ALL_CMD;
ret = dm_i2c_write(dev,
PMBUS_CMD_WRITE_PROTECT,
(void *)&value, sizeof(value));
if (ret)
goto exit;
}
ret = dm_i2c_write(dev, PMBUS_CMD_PAGE_PLUS_WRITE,
(void *)&buff, 5);
(void *)&buff, sizeof(buff));
}
#endif
exit:
if (ret) {
printf("VID: I2C failed to write to the volatge regulator\n");
return -1;
@@ -892,7 +928,7 @@ exit:
static int print_vdd(void)
{
int vdd_last, ret, i2caddress;
int vdd_last, ret, i2caddress = 0;
ret = i2c_multiplexer_select_vid_channel(I2C_MUX_CH_VOL_MONITOR);
if (ret) {

View File

@@ -18,6 +18,25 @@
/* step the IR regulator in 5mV increments */
#define IR_VDD_STEP_DOWN 5
#define IR_VDD_STEP_UP 5
/* LTC3882 */
#define PMBUS_CMD_WRITE_PROTECT 0x10
/*
* WRITE_PROTECT command supported values
* 0x80: Disable all writes except WRITE_PROTECT, PAGE,
* STORE_USER_ALL and MFR_EE_UNLOCK commands.
* 0x40: Disable all writes except WRITE_PROTECT, PAGE, STORE_USER_ALL,
* MFR_EE_UNLOCK, OPERATION, CLEAR_PEAKS and CLEAR_FAULTS commands.
* Individual faults can also be cleared by writing a 1 to the
* respective status bit.
* 0x20: Disable all writes except WRITE_PROTECT, PAGE, STORE_USER_ ALL,
* MFR_EE_UNLOCK, OPERATION, CLEAR_PEAKS, CLEAR_FAULTS, ON_OFF_CONFIG
* and VOUT_COMMAND commands. Individual faults can be cleared by
* writing a 1 to the respective status bit.
* 0x00: Enables write to all commands
*/
#define EN_WRITE_ALL_CMD (0)
int adjust_vdd(ulong vdd_override);
#endif /* __VID_H_ */

View File

@@ -0,0 +1,18 @@
if TARGET_SL28
config SYS_BOARD
default "sl28"
config SYS_VENDOR
default "kontron"
config SYS_SOC
default "fsl-layerscape"
config SYS_CONFIG_NAME
default "kontron_sl28"
config SYS_TEXT_BASE
default 0x96000000
endif

View File

@@ -0,0 +1,7 @@
Kontron SMARC-sAL28 board
M: Michael Walle <michael@walle.cc>
S: Maintained
F: arch/arm/dts/fsl-ls1028a-kontron-sl28-*
F: board/kontron/sl28/
F: configs/kontron_sl28_defconfig
F: include/configs/kontron_sl28.h

View File

@@ -0,0 +1,8 @@
# SPDX-License-Identifier: GPL-2.0+
ifndef CONFIG_SPL_BUILD
obj-y += sl28.o cmds.o
endif
obj-y += common.o ddr.o
obj-$(CONFIG_SPL_BUILD) += spl.o

178
board/kontron/sl28/cmds.c Normal file
View File

@@ -0,0 +1,178 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* sl28 extension commands
*
* Copyright (c) 2020 Kontron Europe GmbH
*/
#include <common.h>
#include <command.h>
#include <i2c.h>
#include <linux/delay.h>
#define CPLD_I2C_ADDR 0x4a
#define REG_UFM_CTRL 0x02
#define UFM_CTRL_DCLK BIT(1)
#define UFM_CTRL_DIN BIT(2)
#define UFM_CTRL_PROGRAM BIT(3)
#define UFM_CTRL_ERASE BIT(4)
#define UFM_CTRL_DSHIFT BIT(5)
#define UFM_CTRL_DOUT BIT(6)
#define UFM_CTRL_BUSY BIT(7)
static int ufm_shift_data(struct udevice *dev, u16 data_in, u16 *data_out)
{
int i;
int ret;
u16 data = 0;
/* latch data */
ret = dm_i2c_reg_write(dev, REG_UFM_CTRL, 0);
if (ret < 0)
return ret;
ret = dm_i2c_reg_write(dev, REG_UFM_CTRL, UFM_CTRL_DCLK);
if (ret < 0)
return ret;
/* assert drshift */
ret = dm_i2c_reg_write(dev, REG_UFM_CTRL,
UFM_CTRL_DSHIFT | UFM_CTRL_DCLK);
if (ret < 0)
return ret;
/* clock 16 data bits, reverse order */
for (i = 15; i >= 0; i--) {
u8 din = (data_in & (1 << i)) ? UFM_CTRL_DIN : 0;
ret = dm_i2c_reg_write(dev, REG_UFM_CTRL, UFM_CTRL_DSHIFT
| din);
if (ret < 0)
return ret;
if (data_out) {
ret = dm_i2c_reg_read(dev, REG_UFM_CTRL);
if (ret < 0)
return ret;
if (ret & UFM_CTRL_DOUT)
data |= (1 << i);
}
ret = dm_i2c_reg_write(dev, REG_UFM_CTRL,
UFM_CTRL_DSHIFT | UFM_CTRL_DCLK | din);
if (ret < 0)
return ret;
}
/* deassert drshift */
ret = dm_i2c_reg_write(dev, REG_UFM_CTRL, UFM_CTRL_DCLK);
if (ret < 0)
return ret;
if (data_out)
*data_out = data;
return ret;
}
static int ufm_erase(struct udevice *dev)
{
int ret;
/* erase, tEPMX is 500ms */
ret = dm_i2c_reg_write(dev, REG_UFM_CTRL,
UFM_CTRL_DCLK | UFM_CTRL_ERASE);
if (ret < 0)
return ret;
ret = dm_i2c_reg_write(dev, REG_UFM_CTRL, UFM_CTRL_DCLK);
if (ret < 0)
return ret;
mdelay(500);
return 0;
}
static int ufm_program(struct udevice *dev)
{
int ret;
/* program, tPPMX is 100us */
ret = dm_i2c_reg_write(dev, REG_UFM_CTRL,
UFM_CTRL_DCLK | UFM_CTRL_PROGRAM);
if (ret < 0)
return ret;
ret = dm_i2c_reg_write(dev, REG_UFM_CTRL, UFM_CTRL_DCLK);
if (ret < 0)
return ret;
udelay(100);
return 0;
}
static int ufm_write(struct udevice *dev, u16 data)
{
int ret;
ret = ufm_shift_data(dev, data, NULL);
if (ret < 0)
return ret;
ret = ufm_erase(dev);
if (ret < 0)
return ret;
return ufm_program(dev);
}
static int ufm_read(struct udevice *dev, u16 *data)
{
return ufm_shift_data(dev, 0, data);
}
static int do_sl28_nvm(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
struct udevice *dev;
u16 nvm;
int ret;
char *endp;
if (i2c_get_chip_for_busnum(0, CPLD_I2C_ADDR, 1, &dev))
return CMD_RET_FAILURE;
if (argc > 1) {
nvm = simple_strtoul(argv[1], &endp, 16);
if (*endp != '\0') {
printf("ERROR: argument is not a valid number\n");
ret = -EINVAL;
goto out;
}
/*
* We swap all bits, because the a zero bit in hardware means the
* feature is enabled. But this is hard for the user.
*/
nvm ^= 0xffff;
ret = ufm_write(dev, nvm);
if (ret)
goto out;
printf("New settings will be activated after the next power cycle!\n");
} else {
ret = ufm_read(dev, &nvm);
if (ret)
goto out;
nvm ^= 0xffff;
printf("%04hx\n", nvm);
}
return CMD_RET_SUCCESS;
out:
printf("command failed (%d)\n", ret);
return CMD_RET_FAILURE;
}
static char sl28_help_text[] =
"nvm [<hex>] - display/set the 16 non-volatile bits\n";
U_BOOT_CMD_WITH_SUBCMDS(sl28, "SMARC-sAL28 specific", sl28_help_text,
U_BOOT_SUBCMD_MKENT(nvm, 2, 1, do_sl28_nvm));

View File

@@ -0,0 +1,10 @@
// SPDX-License-Identifier: GPL-2.0+
#include <common.h>
#include <asm/arch-fsl-layerscape/soc.h>
int board_early_init_f(void)
{
fsl_lsch3_early_init_f();
return 0;
}

98
board/kontron/sl28/ddr.c Normal file
View File

@@ -0,0 +1,98 @@
// SPDX-License-Identifier: GPL-2.0+
#include <common.h>
#include <asm/io.h>
#include <fsl_ddr_sdram.h>
DECLARE_GLOBAL_DATA_PTR;
#define DCFG_GPPORCR1 0x20
#define GPPORCR1_MEM_MASK (0x7 << 5)
#define GPPORCR1_MEM_512MB_CS0 (0x0 << 5)
#define GPPORCR1_MEM_1GB_CS0 (0x1 << 5)
#define GPPORCR1_MEM_2GB_CS0 (0x2 << 5)
#define GPPORCR1_MEM_4GB_CS0_1 (0x3 << 5)
#define GPPORCR1_MEM_4GB_CS0_2 (0x4 << 5)
#define GPPORCR1_MEM_8GB_CS0_1_2_3 (0x5 << 5)
#define GPPORCR1_MEM_8GB_CS0_1 (0x6 << 5)
static fsl_ddr_cfg_regs_t __maybe_unused ddr_cfg_regs = {
.cs[0].bnds = 0x0000007f,
.cs[0].config = 0x80044402,
.cs[1].bnds = 0x008000ff,
.cs[1].config = 0x80004402,
.timing_cfg_0 = 0x9011010c,
.timing_cfg_3 = 0x010c1000,
.timing_cfg_1 = 0xbcb48c66,
.timing_cfg_2 = 0x0fc0d118,
.ddr_sdram_cfg = 0xe70c000c,
.ddr_sdram_cfg_2 = 0x24401111,
.ddr_sdram_mode = 0x00441c70,
.ddr_sdram_mode_3 = 0x00001c70,
.ddr_sdram_mode_5 = 0x00001c70,
.ddr_sdram_mode_7 = 0x00001c70,
.ddr_sdram_mode_2 = 0x00180000,
.ddr_sdram_mode_4 = 0x00180000,
.ddr_sdram_mode_6 = 0x00180000,
.ddr_sdram_mode_8 = 0x00180000,
.ddr_sdram_interval = 0x0c30030c,
.ddr_data_init = 0xdeadbeef,
.ddr_sdram_clk_cntl = 0x02400000,
.timing_cfg_4 = 0x00000001,
.timing_cfg_5 = 0x04401400,
.ddr_zq_cntl = 0x89080600,
.ddr_wrlvl_cntl = 0x8675f606,
.ddr_wrlvl_cntl_2 = 0x04080700,
.ddr_wrlvl_cntl_3 = 0x00000009,
.ddr_cdr1 = 0x80040000,
.ddr_cdr2 = 0x0000bc01,
};
int fsl_initdram(void)
{
u32 gpporcr1 = in_le32(DCFG_BASE + DCFG_GPPORCR1);
phys_size_t dram_size;
switch (gpporcr1 & GPPORCR1_MEM_MASK) {
case GPPORCR1_MEM_2GB_CS0:
dram_size = 0x80000000;
ddr_cfg_regs.cs[1].bnds = 0;
ddr_cfg_regs.cs[1].config = 0;
ddr_cfg_regs.cs[1].config_2 = 0;
break;
case GPPORCR1_MEM_4GB_CS0_1:
dram_size = 0x100000000ULL;
break;
case GPPORCR1_MEM_512MB_CS0:
dram_size = 0x20000000;
fallthrough; /* for now */
case GPPORCR1_MEM_1GB_CS0:
dram_size = 0x40000000;
fallthrough; /* for now */
case GPPORCR1_MEM_4GB_CS0_2:
dram_size = 0x100000000ULL;
fallthrough; /* for now */
case GPPORCR1_MEM_8GB_CS0_1:
case GPPORCR1_MEM_8GB_CS0_1_2_3:
dram_size = 0x200000000ULL;
fallthrough; /* for now */
default:
panic("Unsupported memory configuration (%08x)\n",
gpporcr1 & GPPORCR1_MEM_MASK);
break;
}
if (!IS_ENABLED(CONFIG_SPL) || IS_ENABLED(CONFIG_SPL_BUILD))
fsl_ddr_set_memctl_regs(&ddr_cfg_regs, 0, 0);
gd->ram_size = dram_size;
return 0;
}

68
board/kontron/sl28/sl28.c Normal file
View File

@@ -0,0 +1,68 @@
// SPDX-License-Identifier: GPL-2.0+
#include <common.h>
#include <malloc.h>
#include <errno.h>
#include <fsl_ddr.h>
#include <fdt_support.h>
#include <linux/libfdt.h>
#include <env_internal.h>
#include <asm/arch-fsl-layerscape/soc.h>
#include <asm/arch-fsl-layerscape/fsl_icid.h>
#include <i2c.h>
#include <asm/arch/soc.h>
#include <fsl_immap.h>
#include <netdev.h>
#include <fdtdec.h>
#include <miiphy.h>
DECLARE_GLOBAL_DATA_PTR;
int board_init(void)
{
if (CONFIG_IS_ENABLED(FSL_CAAM))
sec_init();
return 0;
}
int board_eth_init(struct bd_info *bis)
{
return pci_eth_init(bis);
}
int checkboard(void)
{
printf("EL: %d\n", current_el());
return 0;
}
void detail_board_ddr_info(void)
{
puts("\nDDR ");
print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, "");
print_ddr_info(0);
}
int ft_board_setup(void *blob, struct bd_info *bd)
{
u64 base[CONFIG_NR_DRAM_BANKS];
u64 size[CONFIG_NR_DRAM_BANKS];
int nbanks = CONFIG_NR_DRAM_BANKS;
int i;
ft_cpu_setup(blob, bd);
/* fixup DT for the two GPP DDR banks */
for (i = 0; i < nbanks; i++) {
base[i] = gd->bd->bi_dram[i].start;
size[i] = gd->bd->bi_dram[i].size;
}
fdt_fixup_memory_banks(blob, base, size, nbanks);
fdt_fixup_icid(blob);
return 0;
}

32
board/kontron/sl28/spl.c Normal file
View File

@@ -0,0 +1,32 @@
// SPDX-License-Identifier: GPL-2.0+
#include <common.h>
#include <asm/io.h>
#include <asm/spl.h>
#define DCFG_RCWSR25 0x160
#define GPINFO_HW_VARIANT_MASK 0xff
int sl28_variant(void)
{
return in_le32(DCFG_BASE + DCFG_RCWSR25) & GPINFO_HW_VARIANT_MASK;
}
int board_fit_config_name_match(const char *name)
{
int variant = sl28_variant();
switch (variant) {
case 3:
return strcmp(name, "fsl-ls1028a-kontron-sl28-var3");
case 4:
return strcmp(name, "fsl-ls1028a-kontron-sl28-var4");
default:
return strcmp(name, "fsl-ls1028a-kontron-sl28");
}
}
void board_boot_order(u32 *spl_boot_list)
{
spl_boot_list[0] = BOOT_DEVICE_SPI;
}