- turris_mox: Enhancements, mostlly defconfig changes (Pali)
- pci-aardvark: Set Max Payload Size and Max Read Request Size
                to 512 bytes (Pali)
- pci_mvebu: Minor cleanup and refactoring (Marek)
- Upgrade A38x DDR3 training to version 14.0.0 (Marek)
This commit is contained in:
Tom Rini 2021-02-26 07:55:16 -05:00
commit 99bebbd5b2
22 changed files with 123 additions and 53 deletions

View File

@ -41,10 +41,7 @@
&spi0 {
u-boot,dm-pre-reloc;
spi-flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <40000000>;
spi-nor@0 {
u-boot,dm-pre-reloc;
};
};

View File

@ -286,6 +286,7 @@ static struct mv_ddr_topology_map board_topology_map_1g = {
MV_DDR_TIM_2T} }, /* timing */
BUS_MASK_32BIT, /* Busses mask */
MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
NOT_COMBINED, /* ddr twin-die combined */
{ {0} }, /* raw spd data */
{0} /* timing parameters */
};
@ -308,6 +309,7 @@ static struct mv_ddr_topology_map board_topology_map_2g = {
MV_DDR_TIM_2T} }, /* timing */
BUS_MASK_32BIT, /* Busses mask */
MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
NOT_COMBINED, /* ddr twin-die combined */
{ {0} }, /* raw spd data */
{0} /* timing parameters */
};

View File

@ -73,6 +73,7 @@ static struct mv_ddr_topology_map board_topology_map = {
MV_DDR_TIM_DEFAULT} }, /* timing */
BUS_MASK_32BIT, /* Busses mask */
MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
NOT_COMBINED, /* ddr twin-die combined */
{ {0} }, /* raw spd data */
{0} /* timing parameters */
};

View File

@ -94,6 +94,7 @@ static struct mv_ddr_topology_map board_topology_map = {
MV_DDR_TIM_DEFAULT} }, /* timing */
BUS_MASK_32BIT, /* Busses mask */
MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
NOT_COMBINED, /* ddr twin-die combined */
{ {0} }, /* raw spd data */
{0} /* timing parameters */
};

View File

@ -68,6 +68,7 @@ static struct mv_ddr_topology_map board_topology_map = {
MV_DDR_TIM_2T} }, /* timing */
BUS_MASK_32BIT_ECC, /* subphys mask */
MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
NOT_COMBINED, /* ddr twin-die combined */
{ {0} }, /* raw spd data */
{0}, /* timing parameters */
{ {0} }, /* electrical configuration */

View File

@ -71,6 +71,7 @@ static struct mv_ddr_topology_map ddr_topology_map = {
MV_DDR_TIM_DEFAULT} }, /* timing */
BUS_MASK_32BIT, /* Busses mask */
MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
NOT_COMBINED, /* ddr twin-die combined */
{ {0} }, /* raw spd data */
{0} /* timing parameters */

View File

@ -71,6 +71,7 @@ static struct mv_ddr_topology_map board_topology_map = {
MV_DDR_TIM_DEFAULT} }, /* timing */
BUS_MASK_32BIT_ECC, /* Busses mask */
MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
NOT_COMBINED, /* ddr twin-die combined */
{ {0} }, /* raw spd data */
{0} /* timing parameters */
};

View File

@ -142,6 +142,7 @@ static struct mv_ddr_topology_map board_topology_map = {
MV_DDR_TIM_DEFAULT} }, /* timing */
BUS_MASK_32BIT, /* Busses mask */
MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
NOT_COMBINED, /* ddr twin-die combined */
{ {0} }, /* raw spd data */
{0}, /* timing parameters */
{ {0} }, /* electrical configuration */

View File

@ -61,10 +61,10 @@ CONFIG_SPI_FLASH_WINBOND=y
CONFIG_PHY_MARVELL=y
CONFIG_PHY_GIGE=y
CONFIG_MVNETA=y
CONFIG_NVME=y
CONFIG_PCI=y
CONFIG_DM_PCI=y
CONFIG_PCI_AARDVARK=y
# CONFIG_PCI_PNP is not set
CONFIG_MVEBU_COMPHY_SUPPORT=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_ARMADA_37XX=y
@ -78,6 +78,7 @@ CONFIG_MVEBU_A3700_SPI=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_PCI=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y

View File

@ -104,6 +104,7 @@ int ddr3_init(void)
static int mv_ddr_training_params_set(u8 dev_num)
{
struct tune_train_params params;
struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
int status;
u32 cs_num;
int ck_delay;
@ -136,6 +137,10 @@ static int mv_ddr_training_params_set(u8 dev_num)
if (ck_delay > 0)
params.ck_delay = ck_delay;
/* Use platform specific override ODT value */
if (tm->odt_config)
params.g_odt_config = tm->odt_config;
status = ddr3_tip_tune_training_params(dev_num, &params);
if (MV_OK != status) {
printf("%s Training Sequence - FAILED\n", ddr_type);

View File

@ -143,6 +143,7 @@ static struct reg_data odpg_default_value[] = {
{0x15a4, 0x0, MASK_ALL_BITS},
{0x15a8, 0x0, MASK_ALL_BITS},
{0x15ac, 0x0, MASK_ALL_BITS},
{0x1600, 0x0, MASK_ALL_BITS},
{0x1604, 0x0, MASK_ALL_BITS},
{0x1608, 0x0, MASK_ALL_BITS},
{0x160c, 0x0, MASK_ALL_BITS},
@ -218,7 +219,7 @@ static int ddr3_tip_pad_inv(void)
DDR_PHY_CONTROL,
PHY_CTRL_PHY_REG,
data, data);
#else /* !CONFIG_ARMADA_38X && !CONFIG_ARMADA_39X && !A70X0 && !A80X0 && !A3900 */
#else /* !CONFIG_ARMADA_38X && !CONFIG_ARMADA_39X */
#pragma message "unknown platform to configure ddr clock swap"
#endif
}
@ -1569,6 +1570,8 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
val = ((cl_mask_table[cl_value] & 0x1) << 2) |
((cl_mask_table[cl_value] & 0xe) << 3);
cs_mask[0] = 0xc;
CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask, MR_CMD0,
val, (0x7 << 4) | (0x1 << 2)));

View File

@ -833,6 +833,9 @@ u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
pattern = pattern_table_get_isi_word16(index);
break;
default:
if (((int)type == 29) || ((int)type == 30))
break;
printf("error: %s: unsupported pattern type [%d] found\n",
__func__, (int)type);
pattern = 0;

View File

@ -80,6 +80,8 @@
#define ADDR_SIZE_2GB 0x10000000
#define ADDR_SIZE_4GB 0x20000000
#define ADDR_SIZE_8GB 0x40000000
#define ADDR_SIZE_16GB 0x80000000
enum hws_edge_compare {
EDGE_PF,

View File

@ -864,8 +864,11 @@ int ddr3_tip_load_all_pattern_to_mem(u32 dev_num)
DUAL_DUNIT_CFG_REG, (1 << 3), (1 << 3)));
}
for (pattern = 0; pattern < PATTERN_LAST; pattern++)
for (pattern = 0; pattern < PATTERN_LAST; pattern++) {
if (pattern == PATTERN_TEST)
continue;
ddr3_tip_load_pattern_to_mem(dev_num, pattern);
}
return MV_OK;
}

View File

@ -14,6 +14,11 @@
#define MV_DDR_MAX_BUS_NUM 9
#define MV_DDR_MAX_IFACE_NUM 1
enum mv_ddr_twin_die {
NOT_COMBINED,
COMBINED,
};
struct bus_params {
/* Chip Select (CS) bitmask (bits 0-CS0, bit 1- CS1 ...) */
u8 cs_bitmask;
@ -113,6 +118,9 @@ struct mv_ddr_topology_map {
/* source of ddr configuration data */
enum mv_ddr_cfg_src cfg_src;
/* ddr twin-die */
enum mv_ddr_twin_die twin_die_combined;
/* raw spd data */
union mv_ddr_spd_data spd_data;
@ -125,6 +133,9 @@ struct mv_ddr_topology_map {
/* electrical parameters */
unsigned int electrical_data[MV_DDR_EDATA_LAST];
/* ODT configuration */
u32 odt_config;
/* Clock enable mask */
u32 clk_enable;
@ -148,7 +159,13 @@ enum mv_ddr_validation {
MV_DDR_VAL_DIS,
MV_DDR_VAL_RX,
MV_DDR_VAL_TX,
MV_DDR_VAL_RX_TX
MV_DDR_VAL_RX_TX,
MV_DDR_MEMORY_CHECK
};
enum mv_ddr_sscg {
SSCG_EN,
SSCG_DIS,
};
struct mv_ddr_iface {
@ -179,8 +196,12 @@ struct mv_ddr_iface {
/* ddr interface validation mode */
enum mv_ddr_validation validation;
/* ddr interface validation mode */
enum mv_ddr_sscg sscg;
/* ddr interface topology map */
struct mv_ddr_topology_map tm;
};
struct mv_ddr_iface *mv_ddr_iface_get(void);

View File

@ -1,3 +1,3 @@
// SPDX-License-Identifier: GPL-2.0
const char mv_ddr_build_message[] = "";
const char mv_ddr_version_string[] = "mv_ddr: mv_ddr-armada-18.09.2";
const char mv_ddr_version_string[] = "mv_ddr: 14.0.0";

View File

@ -4,6 +4,7 @@
*/
#include "ddr3_init.h"
#include "mv_ddr_common.h"
#include "mv_ddr_training_db.h"
#include "mv_ddr_regs.h"
#include "mv_ddr_sys_env_lib.h"
@ -1016,7 +1017,7 @@ int ddr3_calc_mem_cs_size(u32 cs, uint64_t *cs_size)
return MV_BAD_VALUE;
}
*cs_size = cs_mem_size << 20; /* write cs size in bytes */
*cs_size = cs_mem_size;
return MV_OK;
}
@ -1025,9 +1026,11 @@ static int ddr3_fast_path_dynamic_cs_size_config(u32 cs_ena)
{
u32 reg, cs;
uint64_t mem_total_size = 0;
uint64_t cs_mem_size_mb = 0;
uint64_t cs_mem_size = 0;
uint64_t mem_total_size_c, cs_mem_size_c;
#ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE
u32 physical_mem_size;
u32 max_mem_size = DEVICE_MAX_DRAM_ADDRESS_SIZE;
@ -1038,8 +1041,9 @@ static int ddr3_fast_path_dynamic_cs_size_config(u32 cs_ena)
for (cs = 0; cs < MAX_CS_NUM; cs++) {
if (cs_ena & (1 << cs)) {
/* get CS size */
if (ddr3_calc_mem_cs_size(cs, &cs_mem_size) != MV_OK)
if (ddr3_calc_mem_cs_size(cs, &cs_mem_size_mb) != MV_OK)
return MV_FAIL;
cs_mem_size = cs_mem_size_mb * _1M;
#ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE
/*
@ -1088,6 +1092,7 @@ static int ddr3_fast_path_dynamic_cs_size_config(u32 cs_ena)
*/
mem_total_size_c = (mem_total_size >> 16) & 0xffffffffffff;
cs_mem_size_c = (cs_mem_size >> 16) & 0xffffffffffff;
/* if the sum less than 2 G - calculate the value */
if (mem_total_size_c + cs_mem_size_c < 0x10000)
mem_total_size += cs_mem_size;

View File

@ -127,6 +127,11 @@ int mv_ddr_topology_map_update(void)
speed_bin_index = iface_params->speed_bin_index;
freq = iface_params->memory_freq;
if (tm->twin_die_combined == COMBINED) {
iface_params->bus_width = MV_DDR_DEV_WIDTH_8BIT;
iface_params->memory_size -= 1;
}
if (iface_params->cas_l == 0)
iface_params->cas_l = mv_ddr_cl_val_get(speed_bin_index, freq);
@ -144,6 +149,9 @@ unsigned short mv_ddr_bus_bit_mask_get(void)
unsigned int octets_per_if_num = ddr3_tip_dev_attr_get(0, MV_ATTR_OCTET_PER_INTERFACE);
if (tm->cfg_src == MV_DDR_CFG_SPD) {
if (tm->bus_act_mask == MV_DDR_32BIT_ECC_PUP8_BUS_MASK)
tm->spd_data.byte_fields.byte_13.bit_fields.primary_bus_width = MV_DDR_PRI_BUS_WIDTH_32;
enum mv_ddr_pri_bus_width pri_bus_width = mv_ddr_spd_pri_bus_width_get(&tm->spd_data);
enum mv_ddr_bus_width_ext bus_width_ext = mv_ddr_spd_bus_width_ext_get(&tm->spd_data);
@ -151,7 +159,7 @@ unsigned short mv_ddr_bus_bit_mask_get(void)
case MV_DDR_PRI_BUS_WIDTH_16:
pri_and_ext_bus_width = BUS_MASK_16BIT;
break;
case MV_DDR_PRI_BUS_WIDTH_32:
case MV_DDR_PRI_BUS_WIDTH_32: /*each bit represents byte, so 0xf-is means 4 bytes-32 bit*/
pri_and_ext_bus_width = BUS_MASK_32BIT;
break;
case MV_DDR_PRI_BUS_WIDTH_64:
@ -245,7 +253,8 @@ static unsigned int mem_size[] = {
ADDR_SIZE_1GB,
ADDR_SIZE_2GB,
ADDR_SIZE_4GB,
ADDR_SIZE_8GB
ADDR_SIZE_8GB,
ADDR_SIZE_16GB
/* TODO: add capacity up to 256GB */
};
@ -277,7 +286,6 @@ unsigned long long mv_ddr_mem_sz_per_cs_get(void)
mem_sz_per_cs = (unsigned long long)mem_size[iface_params->memory_size] *
(unsigned long long)sphys /
(unsigned long long)sphys_per_dunit;
return mem_sz_per_cs;
}

View File

@ -179,7 +179,9 @@ enum mv_ddr_dic_evalue {
/* phy electrical configuration values */
enum mv_ddr_ohm_evalue {
MV_DDR_OHM_20 = 20,/*relevant for Synopsys C/A Drive strength only*/
MV_DDR_OHM_30 = 30,
MV_DDR_OHM_40 = 40,/*relevant for Synopsys C/A Drive strength only*/
MV_DDR_OHM_48 = 48,
MV_DDR_OHM_60 = 60,
MV_DDR_OHM_80 = 80,

View File

@ -340,7 +340,7 @@ void ddr3_new_tip_ecc_scrub(void)
{
u32 cs_c, max_cs;
u32 cs_ena = 0;
uint64_t total_mem_size, cs_mem_size = 0;
uint64_t total_mem_size, cs_mem_size_mb = 0, cs_mem_size = 0;
printf("DDR Training Sequence - Start scrubbing\n");
max_cs = mv_ddr_cs_num_get();
@ -349,9 +349,9 @@ void ddr3_new_tip_ecc_scrub(void)
#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
/* all chip-selects are of same size */
ddr3_calc_mem_cs_size(0, &cs_mem_size);
ddr3_calc_mem_cs_size(0, &cs_mem_size_mb);
#endif
cs_mem_size = cs_mem_size_mb * _1M;
mv_sys_xor_init(max_cs, cs_ena, cs_mem_size, 0);
total_mem_size = max_cs * cs_mem_size;
mv_xor_mem_init(0, 0, total_mem_size, 0xdeadbeef, 0xdeadbeef);

View File

@ -42,6 +42,10 @@
#define PCIE_CORE_DEV_CTRL_STATS_REG 0xc8
#define PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE (0 << 4)
#define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11)
#define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SIZE 0x2
#define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SIZE_SHIFT 5
#define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE 0x2
#define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT 12
#define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0
#define PCIE_CORE_LINK_TRAINING BIT(5)
#define PCIE_CORE_ERR_CAPCTL_REG 0x118
@ -534,6 +538,10 @@ static int pcie_advk_setup_hw(struct pcie_advk *pcie)
/* Set PCIe Device Control and Status 1 PF0 register */
reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE |
(PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SIZE <<
PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SIZE_SHIFT) |
(PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE <<
PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT) |
PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE;
advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG);

View File

@ -79,7 +79,8 @@ struct mvebu_pcie {
u32 lane;
int devfn;
u32 lane_mask;
pci_dev_t dev;
int first_busno;
int local_dev;
char name[16];
unsigned int mem_target;
unsigned int mem_attr;
@ -144,38 +145,47 @@ static inline struct mvebu_pcie *hose_to_pcie(struct pci_controller *hose)
return container_of(hose, struct mvebu_pcie, hose);
}
static int mvebu_pcie_valid_addr(struct mvebu_pcie *pcie, pci_dev_t bdf)
{
/*
* There are two devices visible on local bus:
* * on slot configured by function mvebu_pcie_set_local_dev_nr()
* (by default this register is set to 0) there is a
* "Marvell Memory controller", which isn't useful in root complex
* mode,
* * on all other slots the real PCIe card connected to the PCIe slot.
*
* We therefore allow access only to the real PCIe card.
*/
if (PCI_BUS(bdf) == pcie->first_busno &&
PCI_DEV(bdf) != !pcie->local_dev)
return 0;
return 1;
}
static int mvebu_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
uint offset, ulong *valuep,
enum pci_size_t size)
{
struct mvebu_pcie *pcie = dev_get_plat(bus);
int local_bus = PCI_BUS(pcie->dev);
int local_dev = PCI_DEV(pcie->dev);
u32 reg;
u32 data;
debug("PCIE CFG read: loc_bus=%d loc_dev=%d (b,d,f)=(%2d,%2d,%2d) ",
local_bus, local_dev, PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
debug("PCIE CFG read: (b,d,f)=(%2d,%2d,%2d) ",
PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
/* Don't access the local host controller via this API */
if (PCI_BUS(bdf) == local_bus && PCI_DEV(bdf) == local_dev) {
debug("- skipping host controller\n");
*valuep = pci_get_ff(size);
return 0;
}
/* If local dev is 0, the first other dev can only be 1 */
if (PCI_BUS(bdf) == local_bus && local_dev == 0 && PCI_DEV(bdf) != 1) {
if (!mvebu_pcie_valid_addr(pcie, bdf)) {
debug("- out of range\n");
*valuep = pci_get_ff(size);
return 0;
}
/* write address */
reg = PCIE_CONF_ADDR(bdf, offset);
writel(reg, pcie->base + PCIE_CONF_ADDR_OFF);
writel(PCIE_CONF_ADDR(bdf, offset), pcie->base + PCIE_CONF_ADDR_OFF);
/* read data */
data = readl(pcie->base + PCIE_CONF_DATA_OFF);
debug("(addr,val)=(0x%04x, 0x%08x)\n", offset, data);
debug("(addr,size,val)=(0x%04x, %d, 0x%08x)\n", offset, size, data);
*valuep = pci_conv_32_to_size(data, offset, size);
return 0;
@ -186,27 +196,21 @@ static int mvebu_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
enum pci_size_t size)
{
struct mvebu_pcie *pcie = dev_get_plat(bus);
int local_bus = PCI_BUS(pcie->dev);
int local_dev = PCI_DEV(pcie->dev);
u32 data;
debug("PCIE CFG write: loc_bus=%d loc_dev=%d (b,d,f)=(%2d,%2d,%2d) ",
local_bus, local_dev, PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value);
debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ",
PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
debug("(addr,size,val)=(0x%04x, %d, 0x%08lx)\n", offset, size, value);
/* Don't access the local host controller via this API */
if (PCI_BUS(bdf) == local_bus && PCI_DEV(bdf) == local_dev) {
debug("- skipping host controller\n");
return 0;
}
/* If local dev is 0, the first other dev can only be 1 */
if (PCI_BUS(bdf) == local_bus && local_dev == 0 && PCI_DEV(bdf) != 1) {
if (!mvebu_pcie_valid_addr(pcie, bdf)) {
debug("- out of range\n");
return 0;
}
/* write address */
writel(PCIE_CONF_ADDR(bdf, offset), pcie->base + PCIE_CONF_ADDR_OFF);
/* write data */
data = pci_conv_size_to_32(0, value, offset, size);
writel(data, pcie->base + PCIE_CONF_DATA_OFF);
@ -273,7 +277,7 @@ static int mvebu_pcie_probe(struct udevice *dev)
struct mvebu_pcie *pcie = dev_get_plat(dev);
struct udevice *ctlr = pci_get_controller(dev);
struct pci_controller *hose = dev_get_uclass_priv(ctlr);
static int bus;
int bus = dev_seq(dev);
u32 reg;
debug("%s: PCIe %d.%d - up, base %08x\n", __func__,
@ -284,9 +288,11 @@ static int mvebu_pcie_probe(struct udevice *dev)
readl(pcie->base), mvebu_pcie_get_local_bus_nr(pcie),
mvebu_pcie_get_local_dev_nr(pcie));
pcie->first_busno = bus;
pcie->local_dev = 1;
mvebu_pcie_set_local_bus_nr(pcie, bus);
mvebu_pcie_set_local_dev_nr(pcie, 0);
pcie->dev = PCI_BDF(bus, 0, 0);
mvebu_pcie_set_local_dev_nr(pcie, pcie->local_dev);
pcie->mem.start = (u32)mvebu_pcie_membase;
pcie->mem.end = pcie->mem.start + PCIE_MEM_SIZE - 1;
@ -336,8 +342,6 @@ static int mvebu_pcie_probe(struct udevice *dev)
writel(SOC_REGS_PHY_BASE, pcie->base + PCIE_BAR_LO_OFF(0));
writel(0, pcie->base + PCIE_BAR_HI_OFF(0));
bus++;
return 0;
}