- Sandbox improvements including .dts refactor
- Minor tracing and PCI improvements
- Various other minor fixes
- Conversion of patman, dtoc and binman to support Python 3
This commit is contained in:
Tom Rini
2019-07-11 18:10:11 -04:00
74 changed files with 1580 additions and 990 deletions

View File

@@ -56,6 +56,13 @@ config SPL_BLOCK_CACHE
help
This option enables the disk-block cache in SPL
config TPL_BLOCK_CACHE
bool "Use block device cache in TPL"
depends on TPL_BLK
default n
help
This option enables the disk-block cache in TPL
config IDE
bool "Support IDE controllers"
select HAVE_BLOCK_DEVICE

View File

@@ -42,6 +42,8 @@ bool dm_ofnode_pre_reloc(ofnode node)
#else
if (ofnode_read_bool(node, "u-boot,dm-pre-reloc"))
return true;
if (ofnode_read_bool(node, "u-boot,dm-pre-proper"))
return true;
/*
* In regular builds individual spl and tpl handling both

View File

@@ -61,11 +61,63 @@ static int sandbox_swap_case_get_devfn(struct udevice *dev)
return plat->devfn;
}
static int sandbox_swap_case_use_ea(struct udevice *dev)
{
return !!ofnode_get_property(dev->node, "use-ea", NULL);
}
/* Please keep these macros in sync with ea_regs below */
#define PCI_CAP_ID_EA_SIZE (sizeof(ea_regs) + 4)
#define PCI_CAP_ID_EA_ENTRY_CNT 4
/* Hardcoded EA structure, excluding 1st DW. */
static const u32 ea_regs[] = {
/* BEI=0, ES=2, BAR0 32b Base + 32b MaxOffset, I/O space */
(2 << 8) | 2,
PCI_CAP_EA_BASE_LO0,
0,
/* BEI=1, ES=2, BAR1 32b Base + 32b MaxOffset */
(1 << 4) | 2,
PCI_CAP_EA_BASE_LO1,
MEM_TEXT_SIZE - 1,
/* BEI=2, ES=3, BAR2 64b Base + 32b MaxOffset */
(2 << 4) | 3,
PCI_CAP_EA_BASE_LO2 | PCI_EA_IS_64,
PCI_CAP_EA_SIZE_LO,
PCI_CAP_EA_BASE_HI2,
/* BEI=4, ES=4, BAR4 64b Base + 64b MaxOffset */
(4 << 4) | 4,
PCI_CAP_EA_BASE_LO4 | PCI_EA_IS_64,
PCI_CAP_EA_SIZE_LO | PCI_EA_IS_64,
PCI_CAP_EA_BASE_HI4,
PCI_CAP_EA_SIZE_HI,
};
static int sandbox_swap_case_read_ea(struct udevice *emul, uint offset,
ulong *valuep, enum pci_size_t size)
{
u32 reg;
offset = offset - PCI_CAP_ID_EA_OFFSET - 4;
reg = ea_regs[offset >> 2];
reg >>= (offset % 4) * 8;
*valuep = reg;
return 0;
}
static int sandbox_swap_case_read_config(struct udevice *emul, uint offset,
ulong *valuep, enum pci_size_t size)
{
struct swap_case_platdata *plat = dev_get_platdata(emul);
/*
* The content of the EA capability structure is handled elsewhere to
* keep the switch/case below sane
*/
if (offset > PCI_CAP_ID_EA_OFFSET + PCI_CAP_LIST_NEXT &&
offset < PCI_CAP_ID_EA_OFFSET + PCI_CAP_ID_EA_SIZE)
return sandbox_swap_case_read_ea(emul, offset, valuep, size);
switch (offset) {
case PCI_COMMAND:
*valuep = plat->command;
@@ -134,9 +186,21 @@ static int sandbox_swap_case_read_config(struct udevice *emul, uint offset,
*valuep = PCI_CAP_ID_MSIX_OFFSET;
break;
case PCI_CAP_ID_MSIX_OFFSET:
*valuep = PCI_CAP_ID_MSIX;
if (sandbox_swap_case_use_ea(emul))
*valuep = (PCI_CAP_ID_EA_OFFSET << 8) | PCI_CAP_ID_MSIX;
else
*valuep = PCI_CAP_ID_MSIX;
break;
case PCI_CAP_ID_MSIX_OFFSET + PCI_CAP_LIST_NEXT:
if (sandbox_swap_case_use_ea(emul))
*valuep = PCI_CAP_ID_EA_OFFSET;
else
*valuep = 0;
break;
case PCI_CAP_ID_EA_OFFSET:
*valuep = (PCI_CAP_ID_EA_ENTRY_CNT << 16) | PCI_CAP_ID_EA;
break;
case PCI_CAP_ID_EA_OFFSET + PCI_CAP_LIST_NEXT:
*valuep = 0;
break;
case PCI_EXT_CAP_ID_ERR_OFFSET:
@@ -257,6 +321,9 @@ int sandbox_swap_case_write_io(struct udevice *dev, unsigned int addr,
return 0;
}
static int pci_ea_bar2_magic = PCI_EA_BAR2_MAGIC;
static int pci_ea_bar4_magic = PCI_EA_BAR4_MAGIC;
static int sandbox_swap_case_map_physmem(struct udevice *dev,
phys_addr_t addr, unsigned long *lenp, void **ptrp)
{
@@ -265,9 +332,42 @@ static int sandbox_swap_case_map_physmem(struct udevice *dev,
int barnum;
int ret;
if (sandbox_swap_case_use_ea(dev)) {
/*
* only support mapping base address in EA test for now, we
* don't handle mapping an offset inside a BAR. Seems good
* enough for the current test.
*/
switch (addr) {
case (phys_addr_t)PCI_CAP_EA_BASE_LO0:
*ptrp = &priv->op;
*lenp = 4;
break;
case (phys_addr_t)PCI_CAP_EA_BASE_LO1:
*ptrp = priv->mem_text;
*lenp = barinfo[1].size - 1;
break;
case (phys_addr_t)((PCI_CAP_EA_BASE_HI2 << 32) |
PCI_CAP_EA_BASE_LO2):
*ptrp = &pci_ea_bar2_magic;
*lenp = PCI_CAP_EA_SIZE_LO;
break;
case (phys_addr_t)((PCI_CAP_EA_BASE_HI4 << 32) |
PCI_CAP_EA_BASE_LO4):
*ptrp = &pci_ea_bar4_magic;
*lenp = (PCI_CAP_EA_SIZE_HI << 32) |
PCI_CAP_EA_SIZE_LO;
break;
default:
return -ENOENT;
}
return 0;
}
ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset);
if (ret)
return ret;
if (barnum == 1) {
*ptrp = priv->mem_text + offset;
avail = barinfo[1].size - offset;

View File

@@ -1341,10 +1341,56 @@ pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t phys_addr,
return bus_addr;
}
static void *dm_pci_map_ea_bar(struct udevice *dev, int bar, int flags,
int ea_off)
{
int ea_cnt, i, entry_size;
int bar_id = (bar - PCI_BASE_ADDRESS_0) >> 2;
u32 ea_entry;
phys_addr_t addr;
/* EA capability structure header */
dm_pci_read_config32(dev, ea_off, &ea_entry);
ea_cnt = (ea_entry >> 16) & PCI_EA_NUM_ENT_MASK;
ea_off += PCI_EA_FIRST_ENT;
for (i = 0; i < ea_cnt; i++, ea_off += entry_size) {
/* Entry header */
dm_pci_read_config32(dev, ea_off, &ea_entry);
entry_size = ((ea_entry & PCI_EA_ES) + 1) << 2;
if (((ea_entry & PCI_EA_BEI) >> 4) != bar_id)
continue;
/* Base address, 1st DW */
dm_pci_read_config32(dev, ea_off + 4, &ea_entry);
addr = ea_entry & PCI_EA_FIELD_MASK;
if (ea_entry & PCI_EA_IS_64) {
/* Base address, 2nd DW, skip over 4B MaxOffset */
dm_pci_read_config32(dev, ea_off + 12, &ea_entry);
addr |= ((u64)ea_entry) << 32;
}
/* size ignored for now */
return map_physmem(addr, flags, 0);
}
return 0;
}
void *dm_pci_map_bar(struct udevice *dev, int bar, int flags)
{
pci_addr_t pci_bus_addr;
u32 bar_response;
int ea_off;
/*
* if the function supports Enhanced Allocation use that instead of
* BARs
*/
ea_off = dm_pci_find_capability(dev, PCI_CAP_ID_EA);
if (ea_off)
return dm_pci_map_ea_bar(dev, bar, flags, ea_off);
/* read BAR address */
dm_pci_read_config32(dev, bar, &bar_response);
@@ -1448,6 +1494,30 @@ int dm_pci_find_ext_capability(struct udevice *dev, int cap)
return dm_pci_find_next_ext_capability(dev, 0, cap);
}
int dm_pci_flr(struct udevice *dev)
{
int pcie_off;
u32 cap;
/* look for PCI Express Capability */
pcie_off = dm_pci_find_capability(dev, PCI_CAP_ID_EXP);
if (!pcie_off)
return -ENOENT;
/* check FLR capability */
dm_pci_read_config32(dev, pcie_off + PCI_EXP_DEVCAP, &cap);
if (!(cap & PCI_EXP_DEVCAP_FLR))
return -ENOENT;
dm_pci_clrset_config16(dev, pcie_off + PCI_EXP_DEVCTL, 0,
PCI_EXP_DEVCTL_BCR_FLR);
/* wait 100ms, per PCI spec */
mdelay(100);
return 0;
}
UCLASS_DRIVER(pci) = {
.id = UCLASS_PCI,
.name = "pci",

View File

@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2019 NXP
* Copyright 2013 Freescale Semiconductor, Inc.
*/
@@ -502,6 +503,9 @@ static int lpuart_serial_ofdata_to_platdata(struct udevice *dev)
plat->reg = (void *)addr;
plat->flags = dev_get_driver_data(dev);
if (fdtdec_get_bool(blob, node, "little-endian"))
plat->flags &= ~LPUART_FLAG_REGMAP_ENDIAN_BIG;
if (!fdt_node_check_compatible(blob, node, "fsl,ls1021a-lpuart"))
plat->devtype = DEV_LS1021A;
else if (!fdt_node_check_compatible(blob, node, "fsl,imx7ulp-lpuart"))

View File

@@ -226,7 +226,7 @@ config SANDBOX_SPI
cs-gpios = <0>, <&gpio_a 0>;
flash@0 {
reg = <0>;
compatible = "spansion,m25p16", "sandbox,spi-flash";
compatible = "spansion,m25p16", "jedec,spi-nor";
spi-max-frequency = <40000000>;
sandbox,filename = "spi.bin";
};

View File

@@ -201,7 +201,6 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
unsigned int pos = 0;
const u8 *tx_buf = NULL;
u8 *rx_buf = NULL;
u8 *op_buf;
int op_len;
u32 flag;
int ret;
@@ -338,7 +337,17 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
}
op_len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes;
op_buf = calloc(1, op_len);
/*
* Avoid using malloc() here so that we can use this code in SPL where
* simple malloc may be used. That implementation does not allow free()
* so repeated calls to this code can exhaust the space.
*
* The value of op_len is small, since it does not include the actual
* data being sent, only the op-code and address. In fact, it should be
* possible to just use a small fixed value here instead of op_len.
*/
u8 op_buf[op_len];
op_buf[pos++] = op->cmd.opcode;
@@ -382,8 +391,6 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
debug("%02x ", tx_buf ? tx_buf[i] : rx_buf[i]);
debug("[ret %d]\n", ret);
free(op_buf);
if (ret < 0)
return ret;
#endif /* __UBOOT__ */

View File

@@ -66,6 +66,7 @@ static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type)
case SYSRESET_POWER_OFF:
if (!state->sysreset_allowed[type])
return -EACCES;
sandbox_exit();
default:
return -ENOSYS;
}

View File

@@ -291,7 +291,9 @@ static int video_post_bind(struct udevice *dev)
return 0;
size = alloc_fb(dev, &addr);
if (addr < gd->video_bottom) {
/* Device tree node may need the 'u-boot,dm-pre-reloc' tag */
/* Device tree node may need the 'u-boot,dm-pre-reloc' or
* 'u-boot,dm-pre-proper' tag
*/
printf("Video device '%s' cannot allocate frame buffer memory -ensure the device is set up before relocation\n",
dev->name);
return -ENOSPC;