- 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:
@@ -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) {
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
18
board/kontron/sl28/Kconfig
Normal file
18
board/kontron/sl28/Kconfig
Normal 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
|
||||
7
board/kontron/sl28/MAINTAINERS
Normal file
7
board/kontron/sl28/MAINTAINERS
Normal 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
|
||||
8
board/kontron/sl28/Makefile
Normal file
8
board/kontron/sl28/Makefile
Normal 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
178
board/kontron/sl28/cmds.c
Normal 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));
|
||||
10
board/kontron/sl28/common.c
Normal file
10
board/kontron/sl28/common.c
Normal 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
98
board/kontron/sl28/ddr.c
Normal 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
68
board/kontron/sl28/sl28.c
Normal 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
32
board/kontron/sl28/spl.c
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user