Merge git://git.denx.de/u-boot-dm

This commit is contained in:
Tom Rini 2016-01-12 18:12:42 -05:00
commit 077678eb0c
54 changed files with 1457 additions and 558 deletions

View file

@ -11,7 +11,6 @@ else
obj-$(CONFIG_ROCKCHIP_RK3288) += board.o
endif
obj-y += rk_timer.o
obj-y += rk_early_print.o
obj-$(CONFIG_$(SPL_)ROCKCHIP_COMMON) += common.o
obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/

View file

@ -5,6 +5,7 @@
*/
#include <common.h>
#include <debug_uart.h>
#include <asm/io.h>
#include <asm/arch/grf_rk3036.h>
#include <asm/arch/hardware.h>
@ -34,7 +35,7 @@ void board_init_f(ulong dummy)
GPIO1C2_MASK << GPIO1C2_SHIFT,
GPIO1C3_UART2_SOUT << GPIO1C3_SHIFT |
GPIO1C2_UART2_SIN << GPIO1C2_SHIFT);
rk_uart_init((void *)DEBUG_UART_BASE);
debug_uart_init();
#endif
rockchip_timer_init();
sdram_init();
@ -53,3 +54,9 @@ void board_init_r(gd_t *id, ulong dest_addr)
while (1)
;
}
void hang(void)
{
while (1)
;
}

View file

@ -1,63 +0,0 @@
/*
* (C) Copyright 2015 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm/io.h>
#include <asm/arch/uart.h>
#include <common.h>
static struct rk_uart *uart_ptr;
static void uart_wrtie_byte(char byte)
{
writel(byte, &uart_ptr->rbr);
while (!(readl(&uart_ptr->lsr) & 0x40))
;
}
void print(char *s)
{
while (*s) {
if (*s == '\n')
uart_wrtie_byte('\r');
uart_wrtie_byte(*s);
s++;
}
}
void print_hex(unsigned int n)
{
int i;
int temp;
uart_wrtie_byte('0');
uart_wrtie_byte('x');
for (i = 8; i > 0; i--) {
temp = (n >> (i - 1) * 4) & 0x0f;
if (temp < 10)
uart_wrtie_byte((char)(temp + '0'));
else
uart_wrtie_byte((char)(temp - 10 + 'a'));
}
uart_wrtie_byte('\n');
uart_wrtie_byte('\r');
}
/*
* TODO: since rk3036 only 4K sram to use in SPL, for saving space,
* we implement uart driver this way, we should convert this to use
* ns16550 driver in future, which support DEBUG_UART in the standard way
*/
void rk_uart_init(void *base)
{
uart_ptr = (struct rk_uart *)base;
writel(0x83, &uart_ptr->lcr);
writel(0x0d, &uart_ptr->rbr);
writel(0x03, &uart_ptr->lcr);
/* fifo enable, sfe is shadow register of FCR[0] */
writel(0x01, &uart_ptr->sfe);
}

View file

@ -3,6 +3,7 @@ if TEGRA
config TEGRA_COMMON
bool "Tegra common options"
select DM
select DM_ETH
select DM_GPIO
select DM_I2C
select DM_KEYBOARD

View file

@ -76,6 +76,10 @@ static int _raw_packet_start(const char *ifname, unsigned char *ethmac,
printf("Failed to set promiscuous mode: %d %s\n"
"Falling back to the old \"flags\" way...\n",
errno, strerror(errno));
if (strlen(ifname) >= IFNAMSIZ) {
printf("Interface name %s is too long.\n", ifname);
return -EINVAL;
}
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
if (ioctl(priv->sd, SIOCGIFFLAGS, &ifr) < 0) {
printf("Failed to read flags: %d %s\n", errno,

View file

@ -14,12 +14,12 @@
static struct pci_device_id mmc_supported[] = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDCARD },
{},
};
int cpu_mmc_init(bd_t *bis)
{
return pci_mmc_init("ValleyView SDHCI", mmc_supported,
ARRAY_SIZE(mmc_supported));
return pci_mmc_init("ValleyView SDHCI", mmc_supported);
}
#ifndef CONFIG_EFI_APP

View file

@ -86,8 +86,10 @@ static int bd82x6x_probe(struct udevice *dev)
debug("%s: Cannot find GMA node\n", __func__);
return -EINVAL;
}
ret = gma_func0_init(PCH_VIDEO_DEV, pci_bus_to_hose(0), blob,
gma_node);
ret = dm_pci_bus_find_bdf(PCH_VIDEO_DEV, &dev);
if (ret)
return ret;
ret = gma_func0_init(dev, blob, gma_node);
if (ret)
return ret;

View file

@ -728,8 +728,7 @@ static int int15_handler(void)
return res;
}
int gma_func0_init(pci_dev_t dev, struct pci_controller *hose,
const void *blob, int node)
int gma_func0_init(struct udevice *dev, const void *blob, int node)
{
#ifdef CONFIG_VIDEO
ulong start;
@ -740,16 +739,16 @@ int gma_func0_init(pci_dev_t dev, struct pci_controller *hose,
int ret;
/* IGD needs to be Bus Master */
reg32 = x86_pci_read_config32(dev, PCI_COMMAND);
dm_pci_read_config32(dev, PCI_COMMAND, &reg32);
reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
x86_pci_write_config32(dev, PCI_COMMAND, reg32);
dm_pci_write_config32(dev, PCI_COMMAND, reg32);
/* Use write-combining for the graphics memory, 256MB */
base = pci_read_bar32(hose, dev, 2);
base = dm_pci_read_bar32(dev, 2);
mtrr_add_request(MTRR_TYPE_WRCOMB, base, 256 << 20);
mtrr_commit(true);
gtt_bar = (void *)pci_read_bar32(pci_bus_to_hose(0), dev, 0);
gtt_bar = (void *)dm_pci_read_bar32(dev, 0);
debug("GT bar %p\n", gtt_bar);
ret = gma_pm_init_pre_vbios(gtt_bar);
if (ret)
@ -757,8 +756,8 @@ int gma_func0_init(pci_dev_t dev, struct pci_controller *hose,
#ifdef CONFIG_VIDEO
start = get_timer(0);
ret = pci_run_vga_bios(dev, int15_handler, PCI_ROM_USE_NATIVE |
PCI_ROM_ALLOW_FALLBACK);
ret = dm_pci_run_vga_bios(dev, int15_handler,
PCI_ROM_USE_NATIVE | PCI_ROM_ALLOW_FALLBACK);
debug("BIOS ran in %lums\n", get_timer(start));
#endif
/* Post VBIOS init */

View file

@ -19,6 +19,7 @@
static struct pci_device_id mmc_supported[] = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QRK_SDIO },
{},
};
/*
@ -337,8 +338,7 @@ int arch_early_init_r(void)
int cpu_mmc_init(bd_t *bis)
{
return pci_mmc_init("Quark SDHCI", mmc_supported,
ARRAY_SIZE(mmc_supported));
return pci_mmc_init("Quark SDHCI", mmc_supported);
}
void cpu_irq_init(void)

View file

@ -11,10 +11,10 @@
static struct pci_device_id mmc_supported[] = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_0 },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_1 },
{},
};
int cpu_mmc_init(bd_t *bis)
{
return pci_mmc_init("Topcliff SDHCI", mmc_supported,
ARRAY_SIZE(mmc_supported));
return pci_mmc_init("Topcliff SDHCI", mmc_supported);
}

View file

@ -12,8 +12,7 @@ void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node);
void bd82x6x_pci_init(pci_dev_t dev);
void bd82x6x_usb_ehci_init(pci_dev_t dev);
void bd82x6x_usb_xhci_init(pci_dev_t dev);
int gma_func0_init(pci_dev_t dev, struct pci_controller *hose,
const void *blob, int node);
int gma_func0_init(struct udevice *dev, const void *blob, int node);
int bd82x6x_init(void);
/**

View file

@ -242,9 +242,10 @@ static void vbe_set_graphics(int vesa_mode, struct vbe_mode_info *mode_info)
vbe_set_mode(mode_info);
}
void bios_run_on_x86(pci_dev_t pcidev, unsigned long addr, int vesa_mode,
void bios_run_on_x86(struct udevice *dev, unsigned long addr, int vesa_mode,
struct vbe_mode_info *mode_info)
{
pci_dev_t pcidev = dm_pci_get_bdf(dev);
u32 num_dev;
num_dev = PCI_BUS(pcidev) << 8 | PCI_DEV(pcidev) << 3 |

View file

@ -105,13 +105,15 @@ int int1a_handler(void)
unsigned short func = (unsigned short)M.x86.R_EAX;
int retval = 1;
unsigned short devid, vendorid, devfn;
struct udevice *dev;
/* Use short to get rid of gabage in upper half of 32-bit register */
short devindex;
unsigned char bus;
pci_dev_t dev;
pci_dev_t bdf;
u32 dword;
u16 word;
u8 byte, reg;
int ret;
switch (func) {
case 0xb101: /* PCIBIOS Check */
@ -131,17 +133,20 @@ int int1a_handler(void)
devid = M.x86.R_ECX;
vendorid = M.x86.R_EDX;
devindex = M.x86.R_ESI;
dev = pci_find_device(vendorid, devid, devindex);
if (dev != -1) {
bdf = -1;
ret = dm_pci_find_device(vendorid, devid, devindex, &dev);
if (!ret) {
unsigned short busdevfn;
bdf = dm_pci_get_bdf(dev);
M.x86.R_EAX &= 0xffff00ff; /* Clear AH */
M.x86.R_EAX |= PCIBIOS_SUCCESSFUL;
/*
* busnum is an unsigned char;
* devfn is an int, so we mask it off.
*/
busdevfn = (PCI_BUS(dev) << 8) | PCI_DEV(dev) << 3 |
PCI_FUNC(dev);
busdevfn = (PCI_BUS(bdf) << 8) | PCI_DEV(bdf) << 3 |
PCI_FUNC(bdf);
debug("0x%x: return 0x%x\n", func, busdevfn);
M.x86.R_EBX = busdevfn;
retval = 1;
@ -160,35 +165,40 @@ int int1a_handler(void)
devfn = M.x86.R_EBX & 0xff;
bus = M.x86.R_EBX >> 8;
reg = M.x86.R_EDI;
dev = PCI_BDF(bus, devfn >> 3, devfn & 7);
bdf = PCI_BDF(bus, devfn >> 3, devfn & 7);
ret = dm_pci_bus_find_bdf(bdf, &dev);
if (ret) {
debug("%s: Device %x not found\n", __func__, bdf);
break;
}
switch (func) {
case 0xb108: /* Read Config Byte */
byte = x86_pci_read_config8(dev, reg);
dm_pci_read_config8(dev, reg, &byte);
M.x86.R_ECX = byte;
break;
case 0xb109: /* Read Config Word */
word = x86_pci_read_config16(dev, reg);
dm_pci_read_config16(dev, reg, &word);
M.x86.R_ECX = word;
break;
case 0xb10a: /* Read Config Dword */
dword = x86_pci_read_config32(dev, reg);
dm_pci_read_config32(dev, reg, &dword);
M.x86.R_ECX = dword;
break;
case 0xb10b: /* Write Config Byte */
byte = M.x86.R_ECX;
x86_pci_write_config8(dev, reg, byte);
dm_pci_write_config8(dev, reg, byte);
break;
case 0xb10c: /* Write Config Word */
word = M.x86.R_ECX;
x86_pci_write_config16(dev, reg, word);
dm_pci_write_config16(dev, reg, word);
break;
case 0xb10d: /* Write Config Dword */
dword = M.x86.R_ECX;
x86_pci_write_config32(dev, reg, dword);
dm_pci_write_config32(dev, reg, dword);
break;
}
#ifdef CONFIG_REALMODE_DEBUG
debug("0x%x: bus %d devfn 0x%x reg 0x%x val 0x%x\n", func,
bus, devfn, reg, M.x86.R_ECX);

View file

@ -13,7 +13,6 @@
#include <asm/arch/pinmux.h>
#include <asm/gpio.h>
#include <i2c.h>
#include <netdev.h>
void pin_mux_usb(void)
{
@ -41,10 +40,3 @@ void pin_mux_mmc(void)
/* For CD GPIO PP1 */
pinmux_tristate_disable(PMUX_PINGRP_DAP3);
}
#ifdef CONFIG_PCI
int board_eth_init(bd_t *bis)
{
return pci_eth_init(bis);
}
#endif

View file

@ -13,7 +13,6 @@
#include <asm/gpio.h>
#include "pinmux-config-cardhu.h"
#include <i2c.h>
#include <netdev.h>
#define PMU_I2C_ADDRESS 0x2D
#define MAX_I2C_RETRY 3
@ -129,9 +128,4 @@ int tegra_pcie_board_init(void)
return 0;
}
int board_eth_init(bd_t *bis)
{
return pci_eth_init(bis);
}
#endif /* PCI */

View file

@ -6,7 +6,6 @@
*/
#include <common.h>
#include <netdev.h>
#include <power/as3722.h>
#include <asm/arch/gpio.h>
@ -73,9 +72,4 @@ int tegra_pcie_board_init(void)
return 0;
}
int board_eth_init(bd_t *bis)
{
return pci_eth_init(bis);
}
#endif /* PCI */

View file

@ -6,7 +6,6 @@
*/
#include <common.h>
#include <netdev.h>
#include <i2c.h>
#include <asm/arch/gpio.h>
#include <asm/arch/pinmux.h>
@ -73,9 +72,4 @@ int tegra_pcie_board_init(void)
return 0;
}
int board_eth_init(bd_t *bis)
{
return pci_eth_init(bis);
}
#endif /* PCI */

View file

@ -14,7 +14,6 @@
#include <asm/io.h>
#include <dm.h>
#include <i2c.h>
#include <netdev.h>
#include "pinmux-config-apalis_t30.h"
@ -92,9 +91,4 @@ int tegra_pcie_board_init(void)
return 0;
}
int board_eth_init(bd_t *bis)
{
return pci_eth_init(bis);
}
#endif /* CONFIG_PCI_TEGRA */

View file

@ -606,7 +606,7 @@ static int do_pci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
#ifdef CONFIG_DM_PCI
ret = pci_bus_find_bdf(bdf, &dev);
ret = dm_pci_bus_find_bdf(bdf, &dev);
if (ret) {
printf("No such device\n");
return CMD_RET_FAILURE;

View file

@ -184,7 +184,7 @@ int scsi_get_disk_count(void)
#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
void scsi_init(void)
{
int busdevfunc;
int busdevfunc = -1;
int i;
/*
* Find a device from the list, this driver will support a single
@ -192,9 +192,21 @@ void scsi_init(void)
*/
for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
/* get PCI Device ID */
#ifdef CONFIG_DM_PCI
struct udevice *dev;
int ret;
ret = dm_pci_find_device(scsi_device_list[i].vendor,
scsi_device_list[i].device, 0, &dev);
if (!ret) {
busdevfunc = dm_pci_get_bdf(dev);
break;
}
#else
busdevfunc = pci_find_device(scsi_device_list[i].vendor,
scsi_device_list[i].device,
0);
#endif
if (busdevfunc != -1)
break;
}

View file

@ -24,3 +24,9 @@ CONFIG_DM_MMC=y
CONFIG_USE_PRIVATE_LIBGCC=y
CONFIG_CMD_DHRYSTONE=y
CONFIG_ERRNO_STR=y
CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_NS16550=y
CONFIG_DEBUG_UART_BASE=0x20068000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART_SHIFT=2
# CONFIG_SPL_SERIAL_PRESENT is not set

View file

@ -10,6 +10,7 @@
#include <common.h>
#include <command.h>
#include <dm.h>
#include <pci.h>
#include <asm/processor.h>
#include <asm/errno.h>
@ -168,9 +169,14 @@ int ahci_reset(void __iomem *base)
static int ahci_host_init(struct ahci_probe_ent *probe_ent)
{
#ifndef CONFIG_SCSI_AHCI_PLAT
# ifdef CONFIG_DM_PCI
struct udevice *dev = probe_ent->dev;
struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
# else
pci_dev_t pdev = probe_ent->dev;
u16 tmp16;
unsigned short vendor;
# endif
u16 tmp16;
#endif
void __iomem *mmio = probe_ent->mmio_base;
u32 tmp, cap_save, cmd;
@ -193,6 +199,14 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
writel_with_flush(0xf, mmio + HOST_PORTS_IMPL);
#ifndef CONFIG_SCSI_AHCI_PLAT
# ifdef CONFIG_DM_PCI
if (pplat->vendor == PCI_VENDOR_ID_INTEL) {
u16 tmp16;
dm_pci_read_config16(dev, 0x92, &tmp16);
dm_pci_write_config16(dev, 0x92, tmp16 | 0xf);
}
# else
pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
if (vendor == PCI_VENDOR_ID_INTEL) {
@ -201,6 +215,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
tmp16 |= 0xf;
pci_write_config_word(pdev, 0x92, tmp16);
}
# endif
#endif
probe_ent->cap = readl(mmio + HOST_CAP);
probe_ent->port_map = readl(mmio + HOST_PORTS_IMPL);
@ -313,9 +328,15 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
tmp = readl(mmio + HOST_CTL);
debug("HOST_CTL 0x%x\n", tmp);
#ifndef CONFIG_SCSI_AHCI_PLAT
# ifdef CONFIG_DM_PCI
dm_pci_read_config16(dev, PCI_COMMAND, &tmp16);
tmp |= PCI_COMMAND_MASTER;
dm_pci_write_config16(dev, PCI_COMMAND, tmp16);
# else
pci_read_config_word(pdev, PCI_COMMAND, &tmp16);
tmp |= PCI_COMMAND_MASTER;
pci_write_config_word(pdev, PCI_COMMAND, tmp16);
# endif
#endif
return 0;
}
@ -324,7 +345,11 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
static void ahci_print_info(struct ahci_probe_ent *probe_ent)
{
#ifndef CONFIG_SCSI_AHCI_PLAT
# ifdef CONFIG_DM_PCI
struct udevice *dev = probe_ent->dev;
# else
pci_dev_t pdev = probe_ent->dev;
# endif
u16 cc;
#endif
void __iomem *mmio = probe_ent->mmio_base;
@ -350,7 +375,11 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent)
#ifdef CONFIG_SCSI_AHCI_PLAT
scc_s = "SATA";
#else
# ifdef CONFIG_DM_PCI
dm_pci_read_config16(dev, 0x0a, &cc);
# else
pci_read_config_word(pdev, 0x0a, &cc);
# endif
if (cc == 0x0101)
scc_s = "IDE";
else if (cc == 0x0106)
@ -395,7 +424,11 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent)
}
#ifndef CONFIG_SCSI_AHCI_PLAT
static int ahci_init_one(pci_dev_t pdev)
# ifdef CONFIG_DM_PCI
static int ahci_init_one(struct udevice *dev)
# else
static int ahci_init_one(pci_dev_t dev)
# endif
{
u16 vendor;
int rc;
@ -407,7 +440,7 @@ static int ahci_init_one(pci_dev_t pdev)
}
memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
probe_ent->dev = pdev;
probe_ent->dev = dev;
probe_ent->host_flags = ATA_FLAG_SATA
| ATA_FLAG_NO_LEGACY
@ -417,18 +450,31 @@ static int ahci_init_one(pci_dev_t pdev)
probe_ent->pio_mask = 0x1f;
probe_ent->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */
probe_ent->mmio_base = pci_map_bar(pdev, PCI_BASE_ADDRESS_5,
PCI_REGION_MEM);
debug("ahci mmio_base=0x%p\n", probe_ent->mmio_base);
#ifdef CONFIG_DM_PCI
probe_ent->mmio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_5,
PCI_REGION_MEM);
/* Take from kernel:
* JMicron-specific fixup:
* make sure we're in AHCI mode
*/
pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
dm_pci_read_config16(dev, PCI_VENDOR_ID, &vendor);
if (vendor == 0x197b)
pci_write_config_byte(pdev, 0x41, 0xa1);
dm_pci_write_config8(dev, 0x41, 0xa1);
#else
probe_ent->mmio_base = pci_map_bar(dev, PCI_BASE_ADDRESS_5,
PCI_REGION_MEM);
/* Take from kernel:
* JMicron-specific fixup:
* make sure we're in AHCI mode
*/
pci_read_config_word(dev, PCI_VENDOR_ID, &vendor);
if (vendor == 0x197b)
pci_write_config_byte(dev, 0x41, 0xa1);
#endif
debug("ahci mmio_base=0x%p\n", probe_ent->mmio_base);
/* initialize adapter */
rc = ahci_host_init(probe_ent);
if (rc)
@ -915,7 +961,17 @@ void scsi_low_level_init(int busdevfunc)
u32 linkmap;
#ifndef CONFIG_SCSI_AHCI_PLAT
# ifdef CONFIG_DM_PCI
struct udevice *dev;
int ret;
ret = dm_pci_bus_find_bdf(busdevfunc, &dev);
if (ret)
return;
ahci_init_one(dev);
# else
ahci_init_one(busdevfunc);
# endif
#endif
linkmap = probe_ent->link_port_map;

View file

@ -597,22 +597,31 @@ fdt_addr_t dev_get_addr(struct udevice *dev)
* Use the full-fledged translate function for complex
* bus setups.
*/
return fdt_translate_address((void *)gd->fdt_blob,
addr = fdt_translate_address((void *)gd->fdt_blob,
dev->of_offset, reg);
} else {
/*
* Use the "simple" translate function for less complex
* bus setups.
*/
addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
dev->parent->of_offset,
dev->of_offset, "reg",
0, NULL);
if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) {
if (device_get_uclass_id(dev->parent) ==
UCLASS_SIMPLE_BUS)
addr = simple_bus_translate(dev->parent, addr);
}
}
/*
* Use the "simple" translate function for less complex
* bus setups.
* Some platforms need a special address translation. Those
* platforms (e.g. mvebu in SPL) can configure a translation
* offset in the DM by calling dm_set_translation_offset() that
* will get added to all addresses returned by dev_get_addr().
*/
addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
dev->parent->of_offset,
dev->of_offset, "reg",
0, NULL);
if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) {
if (device_get_uclass_id(dev->parent) == UCLASS_SIMPLE_BUS)
addr = simple_bus_translate(dev->parent, addr);
}
addr += dm_get_translation_offset();
return addr;
#else

View file

@ -23,6 +23,10 @@
DECLARE_GLOBAL_DATA_PTR;
struct root_priv {
fdt_addr_t translation_offset; /* optional translation offset */
};
static const struct driver_info root_info = {
.name = "root_driver",
};
@ -37,6 +41,22 @@ struct udevice *dm_root(void)
return gd->dm_root;
}
fdt_addr_t dm_get_translation_offset(void)
{
struct udevice *root = dm_root();
struct root_priv *priv = dev_get_priv(root);
return priv->translation_offset;
}
void dm_set_translation_offset(fdt_addr_t offs)
{
struct udevice *root = dm_root();
struct root_priv *priv = dev_get_priv(root);
priv->translation_offset = offs;
}
#if defined(CONFIG_NEEDS_MANUAL_RELOC)
void fix_drivers(void)
{
@ -228,6 +248,7 @@ int dm_init_and_scan(bool pre_reloc_only)
U_BOOT_DRIVER(root_driver) = {
.name = "root_driver",
.id = UCLASS_ROOT,
.priv_auto_alloc_size = sizeof(struct root_priv),
};
/* This is the root uclass */

View file

@ -11,26 +11,25 @@
#include <sdhci.h>
#include <asm/pci.h>
int pci_mmc_init(const char *name, struct pci_device_id *mmc_supported,
int num_ids)
int pci_mmc_init(const char *name, struct pci_device_id *mmc_supported)
{
struct sdhci_host *mmc_host;
pci_dev_t devbusfn;
u32 iobase;
int ret;
int i;
for (i = 0; i < num_ids; i++) {
devbusfn = pci_find_devices(mmc_supported, i);
if (devbusfn == -1)
return -ENODEV;
for (i = 0; ; i++) {
struct udevice *dev;
ret = pci_find_device_id(mmc_supported, i, &dev);
if (ret)
return ret;
mmc_host = malloc(sizeof(struct sdhci_host));
if (!mmc_host)
return -ENOMEM;
mmc_host->name = (char *)name;
pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase);
dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0, &iobase);
mmc_host->ioaddr = (void *)iobase;
mmc_host->quirks = 0;
ret = add_sdhci(mmc_host, 0, 0);

View file

@ -584,7 +584,7 @@ static int designware_eth_probe(struct udevice *dev)
* or via a PCI bridge, fill in platdata before we probe the hardware.
*/
if (device_is_on_pci_bus(dev)) {
pci_dev_t bdf = pci_get_bdf(dev);
pci_dev_t bdf = dm_pci_get_bdf(dev);
dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0, &iobase);
iobase &= PCI_BASE_ADDRESS_MEM_MASK;

View file

@ -5628,8 +5628,8 @@ static int e1000_eth_probe(struct udevice *dev)
int ret;
hw->name = dev->name;
ret = e1000_init_one(hw, trailing_strtol(dev->name), pci_get_bdf(dev),
plat->enetaddr);
ret = e1000_init_one(hw, trailing_strtol(dev->name),
dm_pci_get_bdf(dev), plat->enetaddr);
if (ret < 0) {
printf(pr_fmt("failed to initialize card: %d\n"), ret);
return ret;

View file

@ -424,7 +424,7 @@ int pch_gbe_probe(struct udevice *dev)
pci_dev_t devno;
u32 iobase;
devno = pci_get_bdf(dev);
devno = dm_pci_get_bdf(dev);
/*
* The priv structure contains the descriptors and frame buffers which

View file

@ -513,8 +513,13 @@ static void rtl_flush_buffer(void *buf, size_t size)
/**************************************************************************
RECV - Receive a frame
***************************************************************************/
static int rtl_recv_common(pci_dev_t bdf, unsigned long dev_iobase,
#ifdef CONFIG_DM_ETH
static int rtl_recv_common(struct udevice *dev, unsigned long dev_iobase,
uchar **packetp)
#else
static int rtl_recv_common(pci_dev_t dev, unsigned long dev_iobase,
uchar **packetp)
#endif
{
/* return true if there's an ethernet packet ready to read */
/* nic->packet should contain data on return */
@ -545,9 +550,16 @@ static int rtl_recv_common(pci_dev_t bdf, unsigned long dev_iobase,
else
tpc->RxDescArray[cur_rx].status =
cpu_to_le32(OWNbit + RX_BUF_SIZE);
#ifdef CONFIG_DM_ETH
tpc->RxDescArray[cur_rx].buf_addr = cpu_to_le32(
pci_mem_to_phys(bdf, (pci_addr_t)(unsigned long)
dm_pci_mem_to_phys(dev,
(pci_addr_t)(unsigned long)
tpc->RxBufferRing[cur_rx]));
#else
tpc->RxDescArray[cur_rx].buf_addr = cpu_to_le32(
pci_mem_to_phys(dev, (pci_addr_t)(unsigned long)
tpc->RxBufferRing[cur_rx]));
#endif
rtl_flush_rx_desc(&tpc->RxDescArray[cur_rx]);
#ifdef CONFIG_DM_ETH
*packetp = rxdata;
@ -576,7 +588,7 @@ int rtl8169_eth_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct rtl8169_private *priv = dev_get_priv(dev);
return rtl_recv_common(pci_get_bdf(dev), priv->iobase, packetp);
return rtl_recv_common(dev, priv->iobase, packetp);
}
#else
static int rtl_recv(struct eth_device *dev)
@ -590,8 +602,13 @@ static int rtl_recv(struct eth_device *dev)
/**************************************************************************
SEND - Transmit a frame
***************************************************************************/
static int rtl_send_common(pci_dev_t bdf, unsigned long dev_iobase,
#ifdef CONFIG_DM_ETH
static int rtl_send_common(struct udevice *dev, unsigned long dev_iobase,
void *packet, int length)
#else
static int rtl_send_common(pci_dev_t dev, unsigned long dev_iobase,
void *packet, int length)
#endif
{
/* send the packet to destination */
@ -618,8 +635,13 @@ static int rtl_send_common(pci_dev_t bdf, unsigned long dev_iobase,
ptxb[len++] = '\0';
tpc->TxDescArray[entry].buf_Haddr = 0;
#ifdef CONFIG_DM_ETH
tpc->TxDescArray[entry].buf_addr = cpu_to_le32(
pci_mem_to_phys(bdf, (pci_addr_t)(unsigned long)ptxb));
dm_pci_mem_to_phys(dev, (pci_addr_t)(unsigned long)ptxb));
#else
tpc->TxDescArray[entry].buf_addr = cpu_to_le32(
pci_mem_to_phys(dev, (pci_addr_t)(unsigned long)ptxb));
#endif
if (entry != (NUM_TX_DESC - 1)) {
tpc->TxDescArray[entry].status =
cpu_to_le32((OWNbit | FSbit | LSbit) |
@ -661,7 +683,7 @@ int rtl8169_eth_send(struct udevice *dev, void *packet, int length)
{
struct rtl8169_private *priv = dev_get_priv(dev);
return rtl_send_common(pci_get_bdf(dev), priv->iobase, packet, length);
return rtl_send_common(dev, priv->iobase, packet, length);
}
#else
@ -695,7 +717,11 @@ static void rtl8169_set_rx_mode(void)
RTL_W32(MAR0 + 4, mc_filter[1]);
}
static void rtl8169_hw_start(pci_dev_t bdf)
#ifdef CONFIG_DM_ETH
static void rtl8169_hw_start(struct udevice *dev)
#else
static void rtl8169_hw_start(pci_dev_t dev)
#endif
{
u32 i;
@ -740,11 +766,21 @@ static void rtl8169_hw_start(pci_dev_t bdf)
tpc->cur_rx = 0;
RTL_W32(TxDescStartAddrLow, pci_mem_to_phys(bdf,
#ifdef CONFIG_DM_ETH
RTL_W32(TxDescStartAddrLow, dm_pci_mem_to_phys(dev,
(pci_addr_t)(unsigned long)tpc->TxDescArray));
#else
RTL_W32(TxDescStartAddrLow, pci_mem_to_phys(dev,
(pci_addr_t)(unsigned long)tpc->TxDescArray));
#endif
RTL_W32(TxDescStartAddrHigh, (unsigned long)0);
#ifdef CONFIG_DM_ETH
RTL_W32(RxDescStartAddrLow, dm_pci_mem_to_phys(
dev, (pci_addr_t)(unsigned long)tpc->RxDescArray));
#else
RTL_W32(RxDescStartAddrLow, pci_mem_to_phys(
bdf, (pci_addr_t)(unsigned long)tpc->RxDescArray));
dev, (pci_addr_t)(unsigned long)tpc->RxDescArray));
#endif
RTL_W32(RxDescStartAddrHigh, (unsigned long)0);
/* RTL-8169sc/8110sc or later version */
@ -766,7 +802,11 @@ static void rtl8169_hw_start(pci_dev_t bdf)
#endif
}
static void rtl8169_init_ring(pci_dev_t bdf)
#ifdef CONFIG_DM_ETH
static void rtl8169_init_ring(struct udevice *dev)
#else
static void rtl8169_init_ring(pci_dev_t dev)
#endif
{
int i;
@ -794,8 +834,13 @@ static void rtl8169_init_ring(pci_dev_t bdf)
cpu_to_le32(OWNbit + RX_BUF_SIZE);
tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE];
#ifdef CONFIG_DM_ETH
tpc->RxDescArray[i].buf_addr = cpu_to_le32(dm_pci_mem_to_phys(
dev, (pci_addr_t)(unsigned long)tpc->RxBufferRing[i]));
#else
tpc->RxDescArray[i].buf_addr = cpu_to_le32(pci_mem_to_phys(
bdf, (pci_addr_t)(unsigned long)tpc->RxBufferRing[i]));
dev, (pci_addr_t)(unsigned long)tpc->RxBufferRing[i]));
#endif
rtl_flush_rx_desc(&tpc->RxDescArray[i]);
}
@ -804,7 +849,11 @@ static void rtl8169_init_ring(pci_dev_t bdf)
#endif
}
static void rtl8169_common_start(pci_dev_t bdf, unsigned char *enetaddr)
#ifdef CONFIG_DM_ETH
static void rtl8169_common_start(struct udevice *dev, unsigned char *enetaddr)
#else
static void rtl8169_common_start(pci_dev_t dev, unsigned char *enetaddr)
#endif
{
int i;
@ -813,8 +862,8 @@ static void rtl8169_common_start(pci_dev_t bdf, unsigned char *enetaddr)
printf ("%s\n", __FUNCTION__);
#endif
rtl8169_init_ring(bdf);
rtl8169_hw_start(bdf);
rtl8169_init_ring(dev);
rtl8169_hw_start(dev);
/* Construct a perfect filter frame with the mac address as first match
* and broadcast for all others */
for (i = 0; i < 192; i++)
@ -837,7 +886,7 @@ static int rtl8169_eth_start(struct udevice *dev)
{
struct eth_pdata *plat = dev_get_platdata(dev);
rtl8169_common_start(pci_get_bdf(dev), plat->enetaddr);
rtl8169_common_start(dev, plat->enetaddr);
return 0;
}
@ -1130,10 +1179,9 @@ static int rtl8169_eth_probe(struct udevice *dev)
region = 1;
break;
}
pci_read_config32(pci_get_bdf(dev), PCI_BASE_ADDRESS_0 + region * 4,
&iobase);
dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0 + region * 4, &iobase);
iobase &= ~0xf;
priv->iobase = (int)pci_mem_to_phys(pci_get_bdf(dev), iobase);
priv->iobase = (int)dm_pci_mem_to_phys(dev, iobase);
ret = rtl_init(priv->iobase, dev->name, plat->enetaddr);
if (ret < 0) {

View file

@ -6,15 +6,16 @@
#
ifneq ($(CONFIG_DM_PCI),)
obj-$(CONFIG_PCI) += pci-uclass.o
obj-y += pci_rom.o
obj-$(CONFIG_PCI) += pci-uclass.o pci_auto.o
obj-$(CONFIG_DM_PCI_COMPAT) += pci_compat.o
obj-$(CONFIG_PCI_SANDBOX) += pci_sandbox.o
obj-$(CONFIG_SANDBOX) += pci-emul-uclass.o
obj-$(CONFIG_X86) += pci_x86.o
else
obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_PCI) += pci.o pci_auto_old.o
endif
obj-$(CONFIG_PCI) += pci_auto_common.o pci_auto_old.o pci_common.o pci_rom.o
obj-$(CONFIG_PCI) += pci_auto_common.o pci_common.o
obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o
obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o

View file

@ -11,12 +11,14 @@
#include <fdtdec.h>
#include <inttypes.h>
#include <pci.h>
#include <asm/io.h>
#include <dm/lists.h>
#include <dm/root.h>
#include <dm/device-internal.h>
#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
#include <asm/fsp/fsp_support.h>
#endif
#include "pci_internal.h"
DECLARE_GLOBAL_DATA_PTR;
@ -61,7 +63,7 @@ struct udevice *pci_get_controller(struct udevice *dev)
return dev;
}
pci_dev_t pci_get_bdf(struct udevice *dev)
pci_dev_t dm_pci_get_bdf(struct udevice *dev)
{
struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
struct udevice *bus = dev->parent;
@ -128,7 +130,7 @@ int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn,
return -ENODEV;
}
int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp)
int dm_pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp)
{
struct udevice *bus;
int ret;
@ -194,6 +196,65 @@ int pci_find_device_id(struct pci_device_id *ids, int index,
return -ENODEV;
}
static int dm_pci_bus_find_device(struct udevice *bus, unsigned int vendor,
unsigned int device, int *indexp,
struct udevice **devp)
{
struct pci_child_platdata *pplat;
struct udevice *dev;
for (device_find_first_child(bus, &dev);
dev;
device_find_next_child(&dev)) {
pplat = dev_get_parent_platdata(dev);
if (pplat->vendor == vendor && pplat->device == device) {
if (!(*indexp)--) {
*devp = dev;
return 0;
}
}
}
return -ENODEV;
}
int dm_pci_find_device(unsigned int vendor, unsigned int device, int index,
struct udevice **devp)
{
struct udevice *bus;
/* Scan all known buses */
for (uclass_first_device(UCLASS_PCI, &bus);
bus;
uclass_next_device(&bus)) {
if (!dm_pci_bus_find_device(bus, vendor, device, &index, devp))
return device_probe(*devp);
}
*devp = NULL;
return -ENODEV;
}
int dm_pci_find_class(uint find_class, int index, struct udevice **devp)
{
struct udevice *dev;
/* Scan all known buses */
for (pci_find_first_device(&dev);
dev;
pci_find_next_device(&dev)) {
struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
if (pplat->class == find_class && !index--) {
*devp = dev;
return device_probe(*devp);
}
}
*devp = NULL;
return -ENODEV;
}
int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset,
unsigned long value, enum pci_size_t size)
{
@ -225,7 +286,8 @@ int dm_pci_write_config(struct udevice *dev, int offset, unsigned long value,
for (bus = dev; device_is_on_pci_bus(bus);)
bus = bus->parent;
return pci_bus_write_config(bus, pci_get_bdf(dev), offset, value, size);
return pci_bus_write_config(bus, dm_pci_get_bdf(dev), offset, value,
size);
}
@ -290,7 +352,7 @@ int dm_pci_read_config(struct udevice *dev, int offset, unsigned long *valuep,
for (bus = dev; device_is_on_pci_bus(bus);)
bus = bus->parent;
return pci_bus_read_config(bus, pci_get_bdf(dev), offset, valuep,
return pci_bus_read_config(bus, dm_pci_get_bdf(dev), offset, valuep,
size);
}
@ -403,7 +465,7 @@ int pci_auto_config_devices(struct udevice *bus)
int ret;
debug("%s: device %s\n", __func__, dev->name);
ret = pciauto_config_device(hose, pci_get_bdf(dev));
ret = dm_pciauto_config_device(dev);
if (ret < 0)
return ret;
max_bus = ret;
@ -418,26 +480,16 @@ int pci_auto_config_devices(struct udevice *bus)
return sub_bus;
}
int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf)
int dm_pci_hose_probe_bus(struct udevice *bus)
{
struct udevice *parent, *bus;
int sub_bus;
int ret;
debug("%s\n", __func__);
parent = hose->bus;
/* Find the bus within the parent */
ret = pci_bus_find_devfn(parent, PCI_MASK_BUS(bdf), &bus);
if (ret) {
debug("%s: Cannot find device %x on bus %s: %d\n", __func__,
bdf, parent->name, ret);
return ret;
}
sub_bus = pci_get_bus_max() + 1;
debug("%s: bus = %d/%s\n", __func__, sub_bus, bus->name);
pciauto_prescan_setup_bridge(hose, bdf, sub_bus);
dm_pciauto_prescan_setup_bridge(bus, sub_bus);
ret = device_probe(bus);
if (ret) {
@ -451,7 +503,7 @@ int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf)
return -EPIPE;
}
sub_bus = pci_get_bus_max();
pciauto_postscan_setup_bridge(hose, bdf, sub_bus);
dm_pciauto_postscan_setup_bridge(bus, sub_bus);
return sub_bus;
}
@ -622,9 +674,7 @@ int pci_bind_bus_devices(struct udevice *bus)
/* Find this device in the device tree */
ret = pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), &dev);
/* Search for a driver */
/* If nothing in the device tree, bind a generic device */
/* If nothing in the device tree, bind a device */
if (ret == -ENODEV) {
struct pci_device_id find_id;
ulong val;
@ -1004,6 +1054,154 @@ int pci_get_regions(struct udevice *dev, struct pci_region **iop,
return (*iop != NULL) + (*memp != NULL) + (*prefp != NULL);
}
u32 dm_pci_read_bar32(struct udevice *dev, int barnum)
{
u32 addr;
int bar;
bar = PCI_BASE_ADDRESS_0 + barnum * 4;
dm_pci_read_config32(dev, bar, &addr);
if (addr & PCI_BASE_ADDRESS_SPACE_IO)
return addr & PCI_BASE_ADDRESS_IO_MASK;
else
return addr & PCI_BASE_ADDRESS_MEM_MASK;
}
static int _dm_pci_bus_to_phys(struct udevice *ctlr,
pci_addr_t bus_addr, unsigned long flags,
unsigned long skip_mask, phys_addr_t *pa)
{
struct pci_controller *hose = dev_get_uclass_priv(ctlr);
struct pci_region *res;
int i;
for (i = 0; i < hose->region_count; i++) {
res = &hose->regions[i];
if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
continue;
if (res->flags & skip_mask)
continue;
if (bus_addr >= res->bus_start &&
(bus_addr - res->bus_start) < res->size) {
*pa = (bus_addr - res->bus_start + res->phys_start);
return 0;
}
}
return 1;
}
phys_addr_t dm_pci_bus_to_phys(struct udevice *dev, pci_addr_t bus_addr,
unsigned long flags)
{
phys_addr_t phys_addr = 0;
struct udevice *ctlr;
int ret;
/* The root controller has the region information */
ctlr = pci_get_controller(dev);
/*
* if PCI_REGION_MEM is set we do a two pass search with preference
* on matches that don't have PCI_REGION_SYS_MEMORY set
*/
if ((flags & PCI_REGION_TYPE) == PCI_REGION_MEM) {
ret = _dm_pci_bus_to_phys(ctlr, bus_addr,
flags, PCI_REGION_SYS_MEMORY,
&phys_addr);
if (!ret)
return phys_addr;
}
ret = _dm_pci_bus_to_phys(ctlr, bus_addr, flags, 0, &phys_addr);
if (ret)
puts("pci_hose_bus_to_phys: invalid physical address\n");
return phys_addr;
}
int _dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t phys_addr,
unsigned long flags, unsigned long skip_mask,
pci_addr_t *ba)
{
struct pci_region *res;
struct udevice *ctlr;
pci_addr_t bus_addr;
int i;
struct pci_controller *hose;
/* The root controller has the region information */
ctlr = pci_get_controller(dev);
hose = dev_get_uclass_priv(ctlr);
for (i = 0; i < hose->region_count; i++) {
res = &hose->regions[i];
if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
continue;
if (res->flags & skip_mask)
continue;
bus_addr = phys_addr - res->phys_start + res->bus_start;
if (bus_addr >= res->bus_start &&
(bus_addr - res->bus_start) < res->size) {
*ba = bus_addr;
return 0;
}
}
return 1;
}
pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t phys_addr,
unsigned long flags)
{
pci_addr_t bus_addr = 0;
int ret;
/*
* if PCI_REGION_MEM is set we do a two pass search with preference
* on matches that don't have PCI_REGION_SYS_MEMORY set
*/
if ((flags & PCI_REGION_TYPE) == PCI_REGION_MEM) {
ret = _dm_pci_phys_to_bus(dev, phys_addr, flags,
PCI_REGION_SYS_MEMORY, &bus_addr);
if (!ret)
return bus_addr;
}
ret = _dm_pci_phys_to_bus(dev, phys_addr, flags, 0, &bus_addr);
if (ret)
puts("pci_hose_phys_to_bus: invalid physical address\n");
return bus_addr;
}
void *dm_pci_map_bar(struct udevice *dev, int bar, int flags)
{
pci_addr_t pci_bus_addr;
u32 bar_response;
/* read BAR address */
dm_pci_read_config32(dev, bar, &bar_response);
pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
/*
* Pass "0" as the length argument to pci_bus_to_virt. The arg
* isn't actualy used on any platform because u-boot assumes a static
* linear mapping. In the future, this could read the BAR size
* and pass that as the size if needed.
*/
return dm_pci_bus_to_virt(dev, pci_bus_addr, flags, 0, MAP_NOCACHE);
}
UCLASS_DRIVER(pci) = {
.id = UCLASS_PCI,
.name = "pci",

View file

@ -9,7 +9,10 @@
*/
/*
* PCI routines
* Old PCI routines
*
* Do not change this file. Instead, convert your board to use CONFIG_DM_PCI
* and change pci-uclass.c.
*/
#include <common.h>

386
drivers/pci/pci_auto.c Normal file
View file

@ -0,0 +1,386 @@
/*
* PCI autoconfiguration library
*
* Author: Matt Porter <mporter@mvista.com>
*
* Copyright 2000 MontaVista Software Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <errno.h>
#include <pci.h>
/* the user can define CONFIG_SYS_PCI_CACHE_LINE_SIZE to avoid problems */
#ifndef CONFIG_SYS_PCI_CACHE_LINE_SIZE
#define CONFIG_SYS_PCI_CACHE_LINE_SIZE 8
#endif
void dm_pciauto_setup_device(struct udevice *dev, int bars_num,
struct pci_region *mem,
struct pci_region *prefetch, struct pci_region *io,
bool enum_only)
{
u32 bar_response;
pci_size_t bar_size;
u16 cmdstat = 0;
int bar, bar_nr = 0;
u8 header_type;
int rom_addr;
pci_addr_t bar_value;
struct pci_region *bar_res;
int found_mem64 = 0;
u16 class;
dm_pci_read_config16(dev, PCI_COMMAND, &cmdstat);
cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) |
PCI_COMMAND_MASTER;
for (bar = PCI_BASE_ADDRESS_0;
bar < PCI_BASE_ADDRESS_0 + (bars_num * 4); bar += 4) {
/* Tickle the BAR and get the response */
if (!enum_only)
dm_pci_write_config32(dev, bar, 0xffffffff);
dm_pci_read_config32(dev, bar, &bar_response);
/* If BAR is not implemented go to the next BAR */
if (!bar_response)
continue;
found_mem64 = 0;
/* Check the BAR type and set our address mask */
if (bar_response & PCI_BASE_ADDRESS_SPACE) {
bar_size = ((~(bar_response & PCI_BASE_ADDRESS_IO_MASK))
& 0xffff) + 1;
if (!enum_only)
bar_res = io;
debug("PCI Autoconfig: BAR %d, I/O, size=0x%llx, ",
bar_nr, (unsigned long long)bar_size);
} else {
if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
PCI_BASE_ADDRESS_MEM_TYPE_64) {
u32 bar_response_upper;
u64 bar64;
if (!enum_only) {
dm_pci_write_config32(dev, bar + 4,
0xffffffff);
}
dm_pci_read_config32(dev, bar + 4,
&bar_response_upper);
bar64 = ((u64)bar_response_upper << 32) |
bar_response;
bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK)
+ 1;
if (!enum_only)
found_mem64 = 1;
} else {
bar_size = (u32)(~(bar_response &
PCI_BASE_ADDRESS_MEM_MASK) + 1);
}
if (!enum_only) {
if (prefetch && (bar_response &
PCI_BASE_ADDRESS_MEM_PREFETCH)) {
bar_res = prefetch;
} else {
bar_res = mem;
}
}
debug("PCI Autoconfig: BAR %d, %s, size=0x%llx, ",
bar_nr, bar_res == prefetch ? "Prf" : "Mem",
(unsigned long long)bar_size);
}
if (!enum_only && pciauto_region_allocate(bar_res, bar_size,
&bar_value) == 0) {
/* Write it out and update our limit */
dm_pci_write_config32(dev, bar, (u32)bar_value);
if (found_mem64) {
bar += 4;
#ifdef CONFIG_SYS_PCI_64BIT
dm_pci_write_config32(dev, bar,
(u32)(bar_value >> 32));
#else
/*
* If we are a 64-bit decoder then increment to
* the upper 32 bits of the bar and force it to
* locate in the lower 4GB of memory.
*/
dm_pci_write_config32(dev, bar, 0x00000000);
#endif
}
}
cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ?
PCI_COMMAND_IO : PCI_COMMAND_MEMORY;
debug("\n");
bar_nr++;
}
if (!enum_only) {
/* Configure the expansion ROM address */
dm_pci_read_config8(dev, PCI_HEADER_TYPE, &header_type);
header_type &= 0x7f;
if (header_type != PCI_HEADER_TYPE_CARDBUS) {
rom_addr = (header_type == PCI_HEADER_TYPE_NORMAL) ?
PCI_ROM_ADDRESS : PCI_ROM_ADDRESS1;
dm_pci_write_config32(dev, rom_addr, 0xfffffffe);
dm_pci_read_config32(dev, rom_addr, &bar_response);
if (bar_response) {
bar_size = -(bar_response & ~1);
debug("PCI Autoconfig: ROM, size=%#x, ",
(unsigned int)bar_size);
if (pciauto_region_allocate(mem, bar_size,
&bar_value) == 0) {
dm_pci_write_config32(dev, rom_addr,
bar_value);
}
cmdstat |= PCI_COMMAND_MEMORY;
debug("\n");
}
}
}
/* PCI_COMMAND_IO must be set for VGA device */
dm_pci_read_config16(dev, PCI_CLASS_DEVICE, &class);
if (class == PCI_CLASS_DISPLAY_VGA)
cmdstat |= PCI_COMMAND_IO;
dm_pci_write_config16(dev, PCI_COMMAND, cmdstat);
dm_pci_write_config8(dev, PCI_CACHE_LINE_SIZE,
CONFIG_SYS_PCI_CACHE_LINE_SIZE);
dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x80);
}
void dm_pciauto_prescan_setup_bridge(struct udevice *dev, int sub_bus)
{
struct pci_region *pci_mem;
struct pci_region *pci_prefetch;
struct pci_region *pci_io;
u16 cmdstat, prefechable_64;
/* The root controller has the region information */
struct pci_controller *ctlr_hose = pci_bus_to_hose(0);
pci_mem = ctlr_hose->pci_mem;
pci_prefetch = ctlr_hose->pci_prefetch;
pci_io = ctlr_hose->pci_io;
dm_pci_read_config16(dev, PCI_COMMAND, &cmdstat);
dm_pci_read_config16(dev, PCI_PREF_MEMORY_BASE, &prefechable_64);
prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK;
/* Configure bus number registers */
dm_pci_write_config8(dev, PCI_PRIMARY_BUS,
PCI_BUS(dm_pci_get_bdf(dev)));
dm_pci_write_config8(dev, PCI_SECONDARY_BUS, sub_bus);
dm_pci_write_config8(dev, PCI_SUBORDINATE_BUS, 0xff);
if (pci_mem) {
/* Round memory allocator to 1MB boundary */
pciauto_region_align(pci_mem, 0x100000);
/*
* Set up memory and I/O filter limits, assume 32-bit
* I/O space
*/
dm_pci_write_config16(dev, PCI_MEMORY_BASE,
(pci_mem->bus_lower & 0xfff00000) >> 16);
cmdstat |= PCI_COMMAND_MEMORY;
}
if (pci_prefetch) {
/* Round memory allocator to 1MB boundary */
pciauto_region_align(pci_prefetch, 0x100000);
/*
* Set up memory and I/O filter limits, assume 32-bit
* I/O space
*/
dm_pci_write_config16(dev, PCI_PREF_MEMORY_BASE,
(pci_prefetch->bus_lower & 0xfff00000) >> 16);
if (prefechable_64 == PCI_PREF_RANGE_TYPE_64)
#ifdef CONFIG_SYS_PCI_64BIT
dm_pci_write_config32(dev, PCI_PREF_BASE_UPPER32,
pci_prefetch->bus_lower >> 32);
#else
dm_pci_write_config32(dev, PCI_PREF_BASE_UPPER32, 0x0);
#endif
cmdstat |= PCI_COMMAND_MEMORY;
} else {
/* We don't support prefetchable memory for now, so disable */
dm_pci_write_config16(dev, PCI_PREF_MEMORY_BASE, 0x1000);
dm_pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, 0x0);
if (prefechable_64 == PCI_PREF_RANGE_TYPE_64) {
dm_pci_write_config16(dev, PCI_PREF_BASE_UPPER32, 0x0);
dm_pci_write_config16(dev, PCI_PREF_LIMIT_UPPER32, 0x0);
}
}
if (pci_io) {
/* Round I/O allocator to 4KB boundary */
pciauto_region_align(pci_io, 0x1000);
dm_pci_write_config8(dev, PCI_IO_BASE,
(pci_io->bus_lower & 0x0000f000) >> 8);
dm_pci_write_config16(dev, PCI_IO_BASE_UPPER16,
(pci_io->bus_lower & 0xffff0000) >> 16);
cmdstat |= PCI_COMMAND_IO;
}
/* Enable memory and I/O accesses, enable bus master */
dm_pci_write_config16(dev, PCI_COMMAND, cmdstat | PCI_COMMAND_MASTER);
}
void dm_pciauto_postscan_setup_bridge(struct udevice *dev, int sub_bus)
{
struct pci_region *pci_mem;
struct pci_region *pci_prefetch;
struct pci_region *pci_io;
/* The root controller has the region information */
struct pci_controller *ctlr_hose = pci_bus_to_hose(0);
pci_mem = ctlr_hose->pci_mem;
pci_prefetch = ctlr_hose->pci_prefetch;
pci_io = ctlr_hose->pci_io;
/* Configure bus number registers */
dm_pci_write_config8(dev, PCI_SUBORDINATE_BUS, sub_bus);
if (pci_mem) {
/* Round memory allocator to 1MB boundary */
pciauto_region_align(pci_mem, 0x100000);
dm_pci_write_config16(dev, PCI_MEMORY_LIMIT,
(pci_mem->bus_lower - 1) >> 16);
}
if (pci_prefetch) {
u16 prefechable_64;
dm_pci_read_config16(dev, PCI_PREF_MEMORY_LIMIT,
&prefechable_64);
prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK;
/* Round memory allocator to 1MB boundary */
pciauto_region_align(pci_prefetch, 0x100000);
dm_pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT,
(pci_prefetch->bus_lower - 1) >> 16);
if (prefechable_64 == PCI_PREF_RANGE_TYPE_64)
#ifdef CONFIG_SYS_PCI_64BIT
dm_pci_write_config32(dev, PCI_PREF_LIMIT_UPPER32,
(pci_prefetch->bus_lower - 1) >> 32);
#else
dm_pci_write_config32(dev, PCI_PREF_LIMIT_UPPER32, 0x0);
#endif
}
if (pci_io) {
/* Round I/O allocator to 4KB boundary */
pciauto_region_align(pci_io, 0x1000);
dm_pci_write_config8(dev, PCI_IO_LIMIT,
((pci_io->bus_lower - 1) & 0x0000f000) >> 8);
dm_pci_write_config16(dev, PCI_IO_LIMIT_UPPER16,
((pci_io->bus_lower - 1) & 0xffff0000) >> 16);
}
}
/*
* HJF: Changed this to return int. I think this is required
* to get the correct result when scanning bridges
*/
int dm_pciauto_config_device(struct udevice *dev)
{
struct pci_region *pci_mem;
struct pci_region *pci_prefetch;
struct pci_region *pci_io;
unsigned int sub_bus = PCI_BUS(dm_pci_get_bdf(dev));
unsigned short class;
bool enum_only = false;
int n;
#ifdef CONFIG_PCI_ENUM_ONLY
enum_only = true;
#endif
/* The root controller has the region information */
struct pci_controller *ctlr_hose = pci_bus_to_hose(0);
pci_mem = ctlr_hose->pci_mem;
pci_prefetch = ctlr_hose->pci_prefetch;
pci_io = ctlr_hose->pci_io;
dm_pci_read_config16(dev, PCI_CLASS_DEVICE, &class);
switch (class) {
case PCI_CLASS_BRIDGE_PCI:
debug("PCI Autoconfig: Found P2P bridge, device %d\n",
PCI_DEV(dm_pci_get_bdf(dev)));
dm_pciauto_setup_device(dev, 2, pci_mem, pci_prefetch, pci_io,
enum_only);
n = dm_pci_hose_probe_bus(dev);
if (n < 0)
return n;
sub_bus = (unsigned int)n;
break;
case PCI_CLASS_BRIDGE_CARDBUS:
/*
* just do a minimal setup of the bridge,
* let the OS take care of the rest
*/
dm_pciauto_setup_device(dev, 0, pci_mem, pci_prefetch, pci_io,
enum_only);
debug("PCI Autoconfig: Found P2CardBus bridge, device %d\n",
PCI_DEV(dm_pci_get_bdf(dev)));
break;
#if defined(CONFIG_PCIAUTO_SKIP_HOST_BRIDGE)
case PCI_CLASS_BRIDGE_OTHER:
debug("PCI Autoconfig: Skipping bridge device %d\n",
PCI_DEV(dm_pci_get_bdf(dev)));
break;
#endif
#if defined(CONFIG_MPC834x) && !defined(CONFIG_VME8349)
case PCI_CLASS_BRIDGE_OTHER:
/*
* The host/PCI bridge 1 seems broken in 8349 - it presents
* itself as 'PCI_CLASS_BRIDGE_OTHER' and appears as an _agent_
* device claiming resources io/mem/irq.. we only allow for
* the PIMMR window to be allocated (BAR0 - 1MB size)
*/
debug("PCI Autoconfig: Broken bridge found, only minimal config\n");
dm_pciauto_setup_device(dev, 0, hose->pci_mem,
hose->pci_prefetch, hose->pci_io,
enum_only);
break;
#endif
case PCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */
debug("PCI AutoConfig: Found PowerPC device\n");
default:
dm_pciauto_setup_device(dev, 6, pci_mem, pci_prefetch, pci_io,
enum_only);
break;
}
return sub_bus;
}

View file

@ -1,7 +1,5 @@
/*
* arch/powerpc/kernel/pci_auto.c
*
* PCI autoconfiguration library
* PCI autoconfiguration library (legacy version, do not change)
*
* Author: Matt Porter <mporter@mvista.com>
*
@ -14,6 +12,11 @@
#include <errno.h>
#include <pci.h>
/*
* Do not change this file. Instead, convert your board to use CONFIG_DM_PCI
* and change pci_auto.c.
*/
/* the user can define CONFIG_SYS_PCI_CACHE_LINE_SIZE to avoid problems */
#ifndef CONFIG_SYS_PCI_CACHE_LINE_SIZE
#define CONFIG_SYS_PCI_CACHE_LINE_SIZE 8
@ -177,18 +180,9 @@ void pciauto_prescan_setup_bridge(struct pci_controller *hose,
struct pci_region *pci_io;
u16 cmdstat, prefechable_64;
#ifdef CONFIG_DM_PCI
/* The root controller has the region information */
struct pci_controller *ctlr_hose = pci_bus_to_hose(0);
pci_mem = ctlr_hose->pci_mem;
pci_prefetch = ctlr_hose->pci_prefetch;
pci_io = ctlr_hose->pci_io;
#else
pci_mem = hose->pci_mem;
pci_prefetch = hose->pci_prefetch;
pci_io = hose->pci_io;
#endif
pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat);
pci_hose_read_config_word(hose, dev, PCI_PREF_MEMORY_BASE,
@ -196,15 +190,10 @@ void pciauto_prescan_setup_bridge(struct pci_controller *hose,
prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK;
/* Configure bus number registers */
#ifdef CONFIG_DM_PCI
pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS, PCI_BUS(dev));
pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS, sub_bus);
#else
pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS,
PCI_BUS(dev) - hose->first_busno);
pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS,
sub_bus - hose->first_busno);
#endif
pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, 0xff);
if (pci_mem) {
@ -271,26 +260,13 @@ void pciauto_postscan_setup_bridge(struct pci_controller *hose,
struct pci_region *pci_prefetch;
struct pci_region *pci_io;
#ifdef CONFIG_DM_PCI
/* The root controller has the region information */
struct pci_controller *ctlr_hose = pci_bus_to_hose(0);
pci_mem = ctlr_hose->pci_mem;
pci_prefetch = ctlr_hose->pci_prefetch;
pci_io = ctlr_hose->pci_io;
#else
pci_mem = hose->pci_mem;
pci_prefetch = hose->pci_prefetch;
pci_io = hose->pci_io;
#endif
/* Configure bus number registers */
#ifdef CONFIG_DM_PCI
pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, sub_bus);
#else
pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS,
sub_bus - hose->first_busno);
#endif
if (pci_mem) {
/* Round memory allocator to 1MB boundary */
@ -350,18 +326,9 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
unsigned short class;
int n;
#ifdef CONFIG_DM_PCI
/* The root controller has the region information */
struct pci_controller *ctlr_hose = pci_bus_to_hose(0);
pci_mem = ctlr_hose->pci_mem;
pci_prefetch = ctlr_hose->pci_prefetch;
pci_io = ctlr_hose->pci_io;
#else
pci_mem = hose->pci_mem;
pci_prefetch = hose->pci_prefetch;
pci_io = hose->pci_io;
#endif
pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
@ -373,12 +340,6 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
pciauto_setup_device(hose, dev, 2, pci_mem,
pci_prefetch, pci_io);
#ifdef CONFIG_DM_PCI
n = dm_pci_hose_probe_bus(hose, dev);
if (n < 0)
return n;
sub_bus = (unsigned int)n;
#else
/* Passing in current_busno allows for sibling P2P bridges */
hose->current_busno++;
pciauto_prescan_setup_bridge(hose, dev, hose->current_busno);
@ -393,7 +354,6 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
pciauto_postscan_setup_bridge(hose, dev, sub_bus);
sub_bus = hose->current_busno;
#endif
break;
case PCI_CLASS_BRIDGE_CARDBUS:
@ -407,9 +367,7 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
debug("PCI Autoconfig: Found P2CardBus bridge, device %d\n",
PCI_DEV(dev));
#ifndef CONFIG_DM_PCI
hose->current_busno++;
#endif
break;
#if defined(CONFIG_PCIAUTO_SKIP_HOST_BRIDGE)

View file

@ -79,48 +79,6 @@ const char *pci_class_str(u8 class)
};
}
pci_dev_t pci_find_class(uint find_class, int index)
{
int bus;
int devnum;
pci_dev_t bdf;
uint32_t class;
for (bus = 0; bus <= pci_last_busno(); bus++) {
for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES - 1; devnum++) {
pci_read_config_dword(PCI_BDF(bus, devnum, 0),
PCI_CLASS_REVISION, &class);
if (class >> 16 == 0xffff)
continue;
for (bdf = PCI_BDF(bus, devnum, 0);
bdf <= PCI_BDF(bus, devnum,
PCI_MAX_PCI_FUNCTIONS - 1);
bdf += PCI_BDF(0, 0, 1)) {
pci_read_config_dword(bdf, PCI_CLASS_REVISION,
&class);
class >>= 8;
if (class != find_class)
continue;
/*
* Decrement the index. We want to return the
* correct device, so index is 0 for the first
* matching device, 1 for the second, etc.
*/
if (index) {
index--;
continue;
}
/* Return index'th controller. */
return bdf;
}
}
}
return -ENODEV;
}
__weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
{
/*
@ -141,6 +99,7 @@ __weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
return 0;
}
#if !defined(CONFIG_DM_PCI) || defined(CONFIG_DM_PCI_COMPAT)
/* Get a virtual address associated with a BAR region */
void *pci_map_bar(pci_dev_t pdev, int bar, int flags)
{
@ -363,3 +322,46 @@ pci_dev_t pci_hose_find_devices(struct pci_controller *hose, int busnum,
return -1;
}
pci_dev_t pci_find_class(uint find_class, int index)
{
int bus;
int devnum;
pci_dev_t bdf;
uint32_t class;
for (bus = 0; bus <= pci_last_busno(); bus++) {
for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES - 1; devnum++) {
pci_read_config_dword(PCI_BDF(bus, devnum, 0),
PCI_CLASS_REVISION, &class);
if (class >> 16 == 0xffff)
continue;
for (bdf = PCI_BDF(bus, devnum, 0);
bdf <= PCI_BDF(bus, devnum,
PCI_MAX_PCI_FUNCTIONS - 1);
bdf += PCI_BDF(0, 0, 1)) {
pci_read_config_dword(bdf, PCI_CLASS_REVISION,
&class);
class >>= 8;
if (class != find_class)
continue;
/*
* Decrement the index. We want to return the
* correct device, so index is 0 for the first
* matching device, 1 for the second, etc.
*/
if (index) {
index--;
continue;
}
/* Return index'th controller. */
return bdf;
}
}
}
return -ENODEV;
}
#endif /* !CONFIG_DM_PCI || CONFIG_DM_PCI_COMPAT */

View file

@ -34,5 +34,5 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
if (pci_find_device_id(ids, index, &dev))
return -1;
return pci_get_bdf(dev);
return dm_pci_get_bdf(dev);
}

View file

@ -0,0 +1,50 @@
/*
* Internal PCI functions, not exported outside drivers/pci
*
* Copyright (c) 2015 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __pci_internal_h
#define __pci_internal_h
/**
* dm_pciauto_prescan_setup_bridge() - Set up a bridge for scanning
*
* This gets a bridge ready so that its downstream devices can be scanned.
* It sets up the bus number and memory range registers. Once the scan is
* completed, dm_pciauto_postscan_setup_bridge() should be called.
*
* @dev: Bridge device to be scanned
* @sub_bus: Bus number of the 'other side' of the bridge
*/
void dm_pciauto_prescan_setup_bridge(struct udevice *dev, int sub_bus);
/**
* dm_pciauto_postscan_setup_bridge() - Finish set up of a bridge after scanning
*
* This should be called after a bus scan is complete. It adjusts the memory
* ranges to fit with the devices actually found on the other side (downstream)
* of the bridge.
*
* @dev: Bridge device that was scanned
* @sub_bus: Bus number of the 'other side' of the bridge
*/
void dm_pciauto_postscan_setup_bridge(struct udevice *dev, int sub_bus);
/**
* dm_pciauto_config_device() - Configure a PCI device ready for use
*
* If the device is a bridge, downstream devices will be probed.
*
* @dev: Device to configure
* @return the maximum PCI bus number found by this device. If there are no
* bridges, this just returns the device's bus number. If the device is a
* bridge then it will return a larger number, depending on the devices on
* that bridge. On error, returns a -ve error number.
*/
int dm_pciauto_config_device(struct udevice *dev);
#endif

View file

@ -25,6 +25,7 @@
#include <common.h>
#include <bios_emul.h>
#include <dm.h>
#include <errno.h>
#include <malloc.h>
#include <pci.h>
@ -33,12 +34,12 @@
#include <video_fb.h>
#include <linux/screen_info.h>
__weak bool board_should_run_oprom(pci_dev_t dev)
__weak bool board_should_run_oprom(struct udevice *dev)
{
return true;
}
static bool should_load_oprom(pci_dev_t dev)
static bool should_load_oprom(struct udevice *dev)
{
if (IS_ENABLED(CONFIG_ALWAYS_LOAD_OPROM))
return 1;
@ -53,21 +54,18 @@ __weak uint32_t board_map_oprom_vendev(uint32_t vendev)
return vendev;
}
static int pci_rom_probe(pci_dev_t dev, uint class,
struct pci_rom_header **hdrp)
static int pci_rom_probe(struct udevice *dev, struct pci_rom_header **hdrp)
{
struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
struct pci_rom_header *rom_header;
struct pci_rom_data *rom_data;
u16 vendor, device;
u16 rom_vendor, rom_device;
u32 rom_class;
u32 vendev;
u32 mapped_vendev;
u32 rom_address;
pci_read_config_word(dev, PCI_VENDOR_ID, &vendor);
pci_read_config_word(dev, PCI_DEVICE_ID, &device);
vendev = vendor << 16 | device;
vendev = pplat->vendor << 16 | pplat->device;
mapped_vendev = board_map_oprom_vendev(vendev);
if (vendev != mapped_vendev)
debug("Device ID mapped to %#08x\n", mapped_vendev);
@ -76,15 +74,15 @@ static int pci_rom_probe(pci_dev_t dev, uint class,
rom_address = CONFIG_VGA_BIOS_ADDR;
#else
pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_address);
dm_pci_read_config32(dev, PCI_ROM_ADDRESS, &rom_address);
if (rom_address == 0x00000000 || rom_address == 0xffffffff) {
debug("%s: rom_address=%x\n", __func__, rom_address);
return -ENOENT;
}
/* Enable expansion ROM address decoding. */
pci_write_config_dword(dev, PCI_ROM_ADDRESS,
rom_address | PCI_ROM_ADDRESS_ENABLE);
dm_pci_write_config32(dev, PCI_ROM_ADDRESS,
rom_address | PCI_ROM_ADDRESS_ENABLE);
#endif
debug("Option ROM address %x\n", rom_address);
rom_header = (struct pci_rom_header *)(unsigned long)rom_address;
@ -98,7 +96,7 @@ static int pci_rom_probe(pci_dev_t dev, uint class,
le16_to_cpu(rom_header->signature));
#ifndef CONFIG_VGA_BIOS_ADDR
/* Disable expansion ROM address decoding */
pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_address);
dm_pci_write_config32(dev, PCI_ROM_ADDRESS, rom_address);
#endif
return -EINVAL;
}
@ -111,7 +109,7 @@ static int pci_rom_probe(pci_dev_t dev, uint class,
rom_vendor, rom_device);
/* If the device id is mapped, a mismatch is expected */
if ((vendor != rom_vendor || device != rom_device) &&
if ((pplat->vendor != rom_vendor || pplat->device != rom_device) &&
(vendev == mapped_vendev)) {
printf("ID mismatch: vendor ID %04x, device ID %04x\n",
rom_vendor, rom_device);
@ -122,9 +120,9 @@ static int pci_rom_probe(pci_dev_t dev, uint class,
debug("PCI ROM image, Class Code %06x, Code Type %02x\n",
rom_class, rom_data->type);
if (class != rom_class) {
if (pplat->class != rom_class) {
debug("Class Code mismatch ROM %06x, dev %06x\n",
rom_class, class);
rom_class, pplat->class);
}
*hdrp = rom_header;
@ -251,27 +249,26 @@ void setup_video(struct screen_info *screen_info)
screen_info->rsvd_pos = vesa->reserved_mask_pos;
}
int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), int exec_method)
int dm_pci_run_vga_bios(struct udevice *dev, int (*int15_handler)(void),
int exec_method)
{
struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
struct pci_rom_header *rom, *ram;
int vesa_mode = -1;
uint class;
bool emulate;
int ret;
/* Only execute VGA ROMs */
pci_read_config_dword(dev, PCI_REVISION_ID, &class);
if (((class >> 16) ^ PCI_CLASS_DISPLAY_VGA) & 0xff00) {
debug("%s: Class %#x, should be %#x\n", __func__, class,
if (((pplat->class >> 8) ^ PCI_CLASS_DISPLAY_VGA) & 0xff00) {
debug("%s: Class %#x, should be %#x\n", __func__, pplat->class,
PCI_CLASS_DISPLAY_VGA);
return -ENODEV;
}
class >>= 8;
if (!should_load_oprom(dev))
return -ENXIO;
ret = pci_rom_probe(dev, class, &rom);
ret = pci_rom_probe(dev, &rom);
if (ret)
return ret;
@ -314,12 +311,12 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), int exec_method)
#ifdef CONFIG_BIOSEMU
BE_VGAInfo *info;
ret = biosemu_setup(dev, &info);
ret = biosemu_setup(dm_pci_get_bdf(dev), &info);
if (ret)
return ret;
biosemu_set_interrupt_handler(0x15, int15_handler);
ret = biosemu_run(dev, (uchar *)ram, 1 << 16, info, true,
vesa_mode, &mode_info);
ret = biosemu_run(dm_pci_get_bdf(dev), (uchar *)ram, 1 << 16,
info, true, vesa_mode, &mode_info);
if (ret)
return ret;
#endif

View file

@ -15,6 +15,26 @@ config REQUIRE_SERIAL_CONSOLE
during serial port initialization (default y). Set this to n on
boards which have no debug serial port whatsoever.
config SERIAL_PRESENT
bool "Provide a serial driver"
depends on DM_SERIAL
default y
help
In very space-constrained devices even the full UART driver is too
large. In this case the debug UART can still be used in some cases.
This option enables the full UART in U-Boot, so if is it disabled,
the full UART driver will be omitted, thus saving space.
config SPL_SERIAL_PRESENT
bool "Provide a serial driver in SPL"
depends on DM_SERIAL
default y
help
In very space-constrained devices even the full UART driver is too
large. In this case the debug UART can still be used in some cases.
This option enables the full UART in SPL, so if is it disabled,
the full UART driver will be omitted, thus saving space.
config DM_SERIAL
bool "Enable Driver Model for serial drivers"
depends on DM

View file

@ -368,7 +368,7 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
/* try Processor Local Bus device first */
addr = dev_get_addr(dev);
#ifdef CONFIG_PCI
#if defined(CONFIG_PCI) && defined(CONFIG_DM_PCI)
if (addr == FDT_ADDR_T_NONE) {
/* then try pci device */
struct fdt_pci_addr pci_addr;
@ -389,8 +389,7 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
return ret;
}
ret = fdtdec_get_pci_bar32(gd->fdt_blob, dev->of_offset,
&pci_addr, &bar);
ret = fdtdec_get_pci_bar32(dev, &pci_addr, &bar);
if (ret)
return ret;
@ -440,6 +439,7 @@ static const struct udevice_id ns16550_serial_ids[] = {
};
#endif
#if CONFIG_IS_ENABLED(SERIAL_PRESENT)
U_BOOT_DRIVER(ns16550_serial) = {
.name = "ns16550_serial",
.id = UCLASS_SERIAL,
@ -453,4 +453,5 @@ U_BOOT_DRIVER(ns16550_serial) = {
.ops = &ns16550_serial_ops,
.flags = DM_FLAG_PRE_RELOC,
};
#endif
#endif /* CONFIG_DM_SERIAL */

View file

@ -204,7 +204,7 @@ void serial_stdio_init(void)
{
}
#ifdef CONFIG_DM_STDIO
#if defined(CONFIG_DM_STDIO) && CONFIG_IS_ENABLED(SERIAL_PRESENT)
static void serial_stub_putc(struct stdio_dev *sdev, const char ch)
{
_serial_putc(sdev->priv, ch);
@ -287,6 +287,7 @@ static int on_baudrate(const char *name, const char *value, enum env_op op,
}
U_BOOT_ENV_CALLBACK(baudrate, on_baudrate);
#if CONFIG_IS_ENABLED(SERIAL_PRESENT)
static int serial_post_probe(struct udevice *dev)
{
struct dm_serial_ops *ops = serial_get_ops(dev);
@ -356,3 +357,4 @@ UCLASS_DRIVER(serial) = {
.pre_remove = serial_pre_remove,
.per_device_auto_alloc_size = sizeof(struct serial_dev_priv),
};
#endif

View file

@ -11,6 +11,7 @@
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <linux/mii.h>
#include <malloc.h>
@ -83,19 +84,23 @@ struct mcs7830_regs {
* @mchash: shadow for the network adapter's multicast hash registers
*/
struct mcs7830_private {
#ifdef CONFIG_DM_ETH
uint8_t rx_buf[MCS7830_RX_URB_SIZE];
struct ueth_data ueth;
#endif
uint8_t config;
uint8_t mchash[8];
};
/*
* mcs7830_read_reg() - read a register of the network adapter
* @dev: network device to read from
* @udev: network device to read from
* @idx: index of the register to start reading from
* @size: number of bytes to read
* @data: buffer to read into
* Return: zero upon success, negative upon error
*/
static int mcs7830_read_reg(struct ueth_data *dev, uint8_t idx,
static int mcs7830_read_reg(struct usb_device *udev, uint8_t idx,
uint16_t size, void *data)
{
int len;
@ -103,8 +108,8 @@ static int mcs7830_read_reg(struct ueth_data *dev, uint8_t idx,
debug("%s() idx=0x%04X sz=%d\n", __func__, idx, size);
len = usb_control_msg(dev->pusb_dev,
usb_rcvctrlpipe(dev->pusb_dev, 0),
len = usb_control_msg(udev,
usb_rcvctrlpipe(udev, 0),
MCS7830_RD_BREQ,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, idx, buf, size,
@ -119,13 +124,13 @@ static int mcs7830_read_reg(struct ueth_data *dev, uint8_t idx,
/*
* mcs7830_write_reg() - write a register of the network adapter
* @dev: network device to write to
* @udev: network device to write to
* @idx: index of the register to start writing to
* @size: number of bytes to write
* @data: buffer holding the data to write
* Return: zero upon success, negative upon error
*/
static int mcs7830_write_reg(struct ueth_data *dev, uint8_t idx,
static int mcs7830_write_reg(struct usb_device *udev, uint8_t idx,
uint16_t size, void *data)
{
int len;
@ -134,8 +139,8 @@ static int mcs7830_write_reg(struct ueth_data *dev, uint8_t idx,
debug("%s() idx=0x%04X sz=%d\n", __func__, idx, size);
memcpy(buf, data, size);
len = usb_control_msg(dev->pusb_dev,
usb_sndctrlpipe(dev->pusb_dev, 0),
len = usb_control_msg(udev,
usb_sndctrlpipe(udev, 0),
MCS7830_WR_BREQ,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, idx, buf, size,
@ -149,12 +154,12 @@ static int mcs7830_write_reg(struct ueth_data *dev, uint8_t idx,
/*
* mcs7830_phy_emit_wait() - emit PHY read/write access, wait for its execution
* @dev: network device to talk to
* @udev: network device to talk to
* @rwflag: PHY_CMD1_READ or PHY_CMD1_WRITE opcode
* @index: number of the PHY register to read or write
* Return: zero upon success, negative upon error
*/
static int mcs7830_phy_emit_wait(struct ueth_data *dev,
static int mcs7830_phy_emit_wait(struct usb_device *udev,
uint8_t rwflag, uint8_t index)
{
int rc;
@ -164,14 +169,14 @@ static int mcs7830_phy_emit_wait(struct ueth_data *dev,
/* send the PHY read/write request */
cmd[0] = rwflag | PHY_CMD1_PHYADDR;
cmd[1] = PHY_CMD2_PEND | (index & 0x1f);
rc = mcs7830_write_reg(dev, REG_PHY_CMD, sizeof(cmd), cmd);
rc = mcs7830_write_reg(udev, REG_PHY_CMD, sizeof(cmd), cmd);
if (rc < 0)
return rc;
/* wait for the response to become available (usually < 1ms) */
retry = 10;
do {
rc = mcs7830_read_reg(dev, REG_PHY_CMD, sizeof(cmd), cmd);
rc = mcs7830_read_reg(udev, REG_PHY_CMD, sizeof(cmd), cmd);
if (rc < 0)
return rc;
if (cmd[1] & PHY_CMD2_READY)
@ -185,50 +190,51 @@ static int mcs7830_phy_emit_wait(struct ueth_data *dev,
/*
* mcs7830_read_phy() - read a PHY register of the network adapter
* @dev: network device to read from
* @udev: network device to read from
* @index: index of the PHY register to read from
* Return: non-negative 16bit register content, negative upon error
*/
static int mcs7830_read_phy(struct ueth_data *dev, uint8_t index)
static int mcs7830_read_phy(struct usb_device *udev, uint8_t index)
{
int rc;
uint16_t val;
/* issue the PHY read request and wait for its execution */
rc = mcs7830_phy_emit_wait(dev, PHY_CMD1_READ, index);
rc = mcs7830_phy_emit_wait(udev, PHY_CMD1_READ, index);
if (rc < 0)
return rc;
/* fetch the PHY data which was read */
rc = mcs7830_read_reg(dev, REG_PHY_DATA, sizeof(val), &val);
rc = mcs7830_read_reg(udev, REG_PHY_DATA, sizeof(val), &val);
if (rc < 0)
return rc;
rc = le16_to_cpu(val);
debug("%s(%s, %d) => 0x%04X\n", __func__, dev->eth_dev.name, index, rc);
debug("%s(%d) => 0x%04X\n", __func__, index, rc);
return rc;
}
/*
* mcs7830_write_phy() - write a PHY register of the network adapter
* @dev: network device to write to
* @udev: network device to write to
* @index: index of the PHY register to write to
* @val: value to write to the PHY register
* Return: zero upon success, negative upon error
*/
static int mcs7830_write_phy(struct ueth_data *dev, uint8_t index, uint16_t val)
static int mcs7830_write_phy(struct usb_device *udev, uint8_t index,
uint16_t val)
{
int rc;
debug("%s(%s, %d, 0x%04X)\n", __func__, dev->eth_dev.name, index, val);
debug("%s(%d, 0x%04X)\n", __func__, index, val);
/* setup the PHY data which is to get written */
val = cpu_to_le16(val);
rc = mcs7830_write_reg(dev, REG_PHY_DATA, sizeof(val), &val);
rc = mcs7830_write_reg(udev, REG_PHY_DATA, sizeof(val), &val);
if (rc < 0)
return rc;
/* issue the PHY write request and wait for its execution */
rc = mcs7830_phy_emit_wait(dev, PHY_CMD1_WRITE, index);
rc = mcs7830_phy_emit_wait(udev, PHY_CMD1_WRITE, index);
if (rc < 0)
return rc;
@ -237,21 +243,21 @@ static int mcs7830_write_phy(struct ueth_data *dev, uint8_t index, uint16_t val)
/*
* mcs7830_write_config() - write to the network adapter's config register
* @eth: network device to write to
* @udev: network device to write to
* @priv: private data
* Return: zero upon success, negative upon error
*
* the data which gets written is taken from the shadow config register
* within the device driver's private data
*/
static int mcs7830_write_config(struct ueth_data *dev)
static int mcs7830_write_config(struct usb_device *udev,
struct mcs7830_private *priv)
{
struct mcs7830_private *priv;
int rc;
debug("%s()\n", __func__);
priv = dev->dev_priv;
rc = mcs7830_write_reg(dev, REG_CONFIG,
rc = mcs7830_write_reg(udev, REG_CONFIG,
sizeof(priv->config), &priv->config);
if (rc < 0) {
debug("writing config to adapter failed\n");
@ -263,21 +269,21 @@ static int mcs7830_write_config(struct ueth_data *dev)
/*
* mcs7830_write_mchash() - write the network adapter's multicast filter
* @eth: network device to write to
* @udev: network device to write to
* @priv: private data
* Return: zero upon success, negative upon error
*
* the data which gets written is taken from the shadow multicast hashes
* within the device driver's private data
*/
static int mcs7830_write_mchash(struct ueth_data *dev)
static int mcs7830_write_mchash(struct usb_device *udev,
struct mcs7830_private *priv)
{
struct mcs7830_private *priv;
int rc;
debug("%s()\n", __func__);
priv = dev->dev_priv;
rc = mcs7830_write_reg(dev, REG_MULTICAST_HASH,
rc = mcs7830_write_reg(udev, REG_MULTICAST_HASH,
sizeof(priv->mchash), &priv->mchash);
if (rc < 0) {
debug("writing multicast hash to adapter failed\n");
@ -289,12 +295,12 @@ static int mcs7830_write_mchash(struct ueth_data *dev)
/*
* mcs7830_set_autoneg() - setup and trigger ethernet link autonegotiation
* @eth: network device to run link negotiation on
* @udev: network device to run link negotiation on
* Return: zero upon success, negative upon error
*
* the routine advertises available media and starts autonegotiation
*/
static int mcs7830_set_autoneg(struct ueth_data *dev)
static int mcs7830_set_autoneg(struct usb_device *udev)
{
int adv, flg;
int rc;
@ -310,39 +316,39 @@ static int mcs7830_set_autoneg(struct ueth_data *dev)
*/
adv = ADVERTISE_PAUSE_CAP | ADVERTISE_ALL | ADVERTISE_CSMA;
rc = mcs7830_write_phy(dev, MII_ADVERTISE, adv);
rc = mcs7830_write_phy(udev, MII_ADVERTISE, adv);
flg = 0;
if (!rc)
rc = mcs7830_write_phy(dev, MII_BMCR, flg);
rc = mcs7830_write_phy(udev, MII_BMCR, flg);
flg |= BMCR_ANENABLE;
if (!rc)
rc = mcs7830_write_phy(dev, MII_BMCR, flg);
rc = mcs7830_write_phy(udev, MII_BMCR, flg);
flg |= BMCR_ANRESTART;
if (!rc)
rc = mcs7830_write_phy(dev, MII_BMCR, flg);
rc = mcs7830_write_phy(udev, MII_BMCR, flg);
return rc;
}
/*
* mcs7830_get_rev() - identify a network adapter's chip revision
* @eth: network device to identify
* @udev: network device to identify
* Return: non-negative number, reflecting the revision number
*
* currently, only "rev C and higher" and "below rev C" are needed, so
* the return value is #1 for "below rev C", and #2 for "rev C and above"
*/
static int mcs7830_get_rev(struct ueth_data *dev)
static int mcs7830_get_rev(struct usb_device *udev)
{
uint8_t buf[2];
int rc;
int rev;
/* register 22 is readable in rev C and higher */
rc = mcs7830_read_reg(dev, REG_FRAME_DROP_COUNTER, sizeof(buf), buf);
rc = mcs7830_read_reg(udev, REG_FRAME_DROP_COUNTER, sizeof(buf), buf);
if (rc < 0)
rev = 1;
else
@ -353,19 +359,19 @@ static int mcs7830_get_rev(struct ueth_data *dev)
/*
* mcs7830_apply_fixup() - identify an adapter and potentially apply fixups
* @eth: network device to identify and apply fixups to
* @udev: network device to identify and apply fixups to
* Return: zero upon success (no errors emitted from here)
*
* this routine identifies the network adapter's chip revision, and applies
* fixups for known issues
*/
static int mcs7830_apply_fixup(struct ueth_data *dev)
static int mcs7830_apply_fixup(struct usb_device *udev)
{
int rev;
int i;
uint8_t thr;
rev = mcs7830_get_rev(dev);
rev = mcs7830_get_rev(udev);
debug("%s() rev=%d\n", __func__, rev);
/*
@ -374,10 +380,10 @@ static int mcs7830_apply_fixup(struct ueth_data *dev)
* exactly", the introductory comment says "rev C and above")
*/
if (rev == 2) {
debug("%s: applying rev C fixup\n", dev->eth_dev.name);
debug("%s: applying rev C fixup\n", __func__);
thr = PAUSE_THRESHOLD_DEFAULT;
for (i = 0; i < 2; i++) {
(void)mcs7830_write_reg(dev, REG_PAUSE_THRESHOLD,
(void)mcs7830_write_reg(udev, REG_PAUSE_THRESHOLD,
sizeof(thr), &thr);
mdelay(1);
}
@ -395,13 +401,12 @@ static int mcs7830_apply_fixup(struct ueth_data *dev)
* of the interface callbacks can exchange ethernet frames; link negotiation is
* triggered from here already and continues in background
*/
static int mcs7830_basic_reset(struct ueth_data *dev)
static int mcs7830_basic_reset(struct usb_device *udev,
struct mcs7830_private *priv)
{
struct mcs7830_private *priv;
int rc;
debug("%s()\n", __func__);
priv = dev->dev_priv;
/*
* comment from the respective Linux driver, which
@ -411,25 +416,25 @@ static int mcs7830_basic_reset(struct ueth_data *dev)
priv->config = CONF_TXENABLE;
priv->config |= CONF_ALLMULTICAST;
rc = mcs7830_set_autoneg(dev);
rc = mcs7830_set_autoneg(udev);
if (rc < 0) {
error("setting autoneg failed\n");
return rc;
}
rc = mcs7830_write_mchash(dev);
rc = mcs7830_write_mchash(udev, priv);
if (rc < 0) {
error("failed to set multicast hash\n");
return rc;
}
rc = mcs7830_write_config(dev);
rc = mcs7830_write_config(udev, priv);
if (rc < 0) {
error("failed to set configuration\n");
return rc;
}
rc = mcs7830_apply_fixup(dev);
rc = mcs7830_apply_fixup(udev);
if (rc < 0) {
error("fixup application failed\n");
return rc;
@ -440,51 +445,38 @@ static int mcs7830_basic_reset(struct ueth_data *dev)
/*
* mcs7830_read_mac() - read an ethernet adapter's MAC address
* @eth: network device to read from
* @udev: network device to read from
* @enetaddr: place to put ethernet MAC address
* Return: zero upon success, negative upon error
*
* this routine fetches the MAC address stored within the ethernet adapter,
* and stores it in the ethernet interface's data structure
*/
static int mcs7830_read_mac(struct eth_device *eth)
static int mcs7830_read_mac(struct usb_device *udev, unsigned char enetaddr[])
{
struct ueth_data *dev;
int rc;
uint8_t buf[ETH_ALEN];
debug("%s()\n", __func__);
dev = eth->priv;
rc = mcs7830_read_reg(dev, REG_ETHER_ADDR, ETH_ALEN, buf);
rc = mcs7830_read_reg(udev, REG_ETHER_ADDR, ETH_ALEN, buf);
if (rc < 0) {
debug("reading MAC from adapter failed\n");
return rc;
}
memcpy(&eth->enetaddr[0], buf, ETH_ALEN);
memcpy(enetaddr, buf, ETH_ALEN);
return 0;
}
/*
* mcs7830_write_mac() - write an ethernet adapter's MAC address
* @eth: network device to write to
* Return: zero upon success, negative upon error
*
* this routine takes the MAC address from the ethernet interface's data
* structure, and writes it into the ethernet adapter such that subsequent
* exchange of ethernet frames uses this address
*/
static int mcs7830_write_mac(struct eth_device *eth)
static int mcs7830_write_mac_common(struct usb_device *udev,
unsigned char enetaddr[])
{
struct ueth_data *dev;
int rc;
debug("%s()\n", __func__);
dev = eth->priv;
if (sizeof(eth->enetaddr) != ETH_ALEN)
return -EINVAL;
rc = mcs7830_write_reg(dev, REG_ETHER_ADDR, ETH_ALEN, eth->enetaddr);
rc = mcs7830_write_reg(udev, REG_ETHER_ADDR, ETH_ALEN, enetaddr);
if (rc < 0) {
debug("writing MAC to adapter failed\n");
return rc;
@ -492,28 +484,16 @@ static int mcs7830_write_mac(struct eth_device *eth)
return 0;
}
/*
* mcs7830_init() - network interface's init callback
* @eth: network device to initialize
* @bd: board information
* Return: zero upon success, negative upon error
*
* after initial setup during probe() and get_info(), this init() callback
* ensures that the link is up and subsequent send() and recv() calls can
* exchange ethernet frames
*/
static int mcs7830_init(struct eth_device *eth, bd_t *bd)
static int mcs7830_init_common(struct usb_device *udev)
{
struct ueth_data *dev;
int timeout;
int have_link;
debug("%s()\n", __func__);
dev = eth->priv;
timeout = 0;
do {
have_link = mcs7830_read_phy(dev, MII_BMSR) & BMSR_LSTATUS;
have_link = mcs7830_read_phy(udev, MII_BMSR) & BMSR_LSTATUS;
if (have_link)
break;
udelay(LINKSTATUS_TIMEOUT_RES * 1000);
@ -526,28 +506,18 @@ static int mcs7830_init(struct eth_device *eth, bd_t *bd)
return 0;
}
/*
* mcs7830_send() - network interface's send callback
* @eth: network device to send the frame from
* @packet: ethernet frame content
* @length: ethernet frame length
* Return: zero upon success, negative upon error
*
* this routine send an ethernet frame out of the network interface
*/
static int mcs7830_send(struct eth_device *eth, void *packet, int length)
static int mcs7830_send_common(struct ueth_data *ueth, void *packet,
int length)
{
struct ueth_data *dev;
struct usb_device *udev = ueth->pusb_dev;
int rc;
int gotlen;
/* there is a status byte after the ethernet frame */
ALLOC_CACHE_ALIGN_BUFFER(uint8_t, buf, PKTSIZE + sizeof(uint8_t));
dev = eth->priv;
memcpy(buf, packet, length);
rc = usb_bulk_msg(dev->pusb_dev,
usb_sndbulkpipe(dev->pusb_dev, dev->ep_out),
rc = usb_bulk_msg(udev,
usb_sndbulkpipe(udev, ueth->ep_out),
&buf[0], length, &gotlen,
USBCALL_TIMEOUT);
debug("%s() TX want len %d, got len %d, rc %d\n",
@ -555,28 +525,17 @@ static int mcs7830_send(struct eth_device *eth, void *packet, int length)
return rc;
}
/*
* mcs7830_recv() - network interface's recv callback
* @eth: network device to receive frames from
* Return: zero upon success, negative upon error
*
* this routine checks for available ethernet frames that the network
* interface might have received, and notifies the network stack
*/
static int mcs7830_recv(struct eth_device *eth)
static int mcs7830_recv_common(struct ueth_data *ueth, uint8_t *buf)
{
struct ueth_data *dev;
ALLOC_CACHE_ALIGN_BUFFER(uint8_t, buf, MCS7830_RX_URB_SIZE);
int rc, wantlen, gotlen;
uint8_t sts;
debug("%s()\n", __func__);
dev = eth->priv;
/* fetch input data from the adapter */
wantlen = MCS7830_RX_URB_SIZE;
rc = usb_bulk_msg(dev->pusb_dev,
usb_rcvbulkpipe(dev->pusb_dev, dev->ep_in),
rc = usb_bulk_msg(ueth->pusb_dev,
usb_rcvbulkpipe(ueth->pusb_dev, ueth->ep_in),
&buf[0], wantlen, &gotlen,
USBCALL_TIMEOUT);
debug("%s() RX want len %d, got len %d, rc %d\n",
@ -601,8 +560,7 @@ static int mcs7830_recv(struct eth_device *eth)
if (sts == STAT_RX_FRAME_CORRECT) {
debug("%s() got a frame, len=%d\n", __func__, gotlen);
net_process_received_packet(buf, gotlen);
return 0;
return gotlen;
}
debug("RX: frame error (sts 0x%02X, %s %s %s %s %s)\n",
@ -615,6 +573,61 @@ static int mcs7830_recv(struct eth_device *eth)
return -EIO;
}
#ifndef CONFIG_DM_ETH
/*
* mcs7830_init() - network interface's init callback
* @udev: network device to initialize
* @bd: board information
* Return: zero upon success, negative upon error
*
* after initial setup during probe() and get_info(), this init() callback
* ensures that the link is up and subsequent send() and recv() calls can
* exchange ethernet frames
*/
static int mcs7830_init(struct eth_device *eth, bd_t *bd)
{
struct ueth_data *dev = eth->priv;
return mcs7830_init_common(dev->pusb_dev);
}
/*
* mcs7830_send() - network interface's send callback
* @eth: network device to send the frame from
* @packet: ethernet frame content
* @length: ethernet frame length
* Return: zero upon success, negative upon error
*
* this routine send an ethernet frame out of the network interface
*/
static int mcs7830_send(struct eth_device *eth, void *packet, int length)
{
struct ueth_data *dev = eth->priv;
return mcs7830_send_common(dev, packet, length);
}
/*
* mcs7830_recv() - network interface's recv callback
* @eth: network device to receive frames from
* Return: zero upon success, negative upon error
*
* this routine checks for available ethernet frames that the network
* interface might have received, and notifies the network stack
*/
static int mcs7830_recv(struct eth_device *eth)
{
ALLOC_CACHE_ALIGN_BUFFER(uint8_t, buf, MCS7830_RX_URB_SIZE);
struct ueth_data *ueth = eth->priv;
int len;
len = mcs7830_recv_common(ueth, buf);
if (len <= 0)
net_process_received_packet(buf, len);
return 0;
}
/*
* mcs7830_halt() - network interface's halt callback
* @eth: network device to cease operation of
@ -628,6 +641,22 @@ static void mcs7830_halt(struct eth_device *eth)
debug("%s()\n", __func__);
}
/*
* mcs7830_write_mac() - write an ethernet adapter's MAC address
* @eth: network device to write to
* Return: zero upon success, negative upon error
*
* this routine takes the MAC address from the ethernet interface's data
* structure, and writes it into the ethernet adapter such that subsequent
* exchange of ethernet frames uses this address
*/
static int mcs7830_write_mac(struct eth_device *eth)
{
struct ueth_data *ueth = eth->priv;
return mcs7830_write_mac_common(ueth->pusb_dev, eth->enetaddr);
}
/*
* mcs7830_iface_idx - index of detected network interfaces
*
@ -802,12 +831,111 @@ int mcs7830_eth_get_info(struct usb_device *dev, struct ueth_data *ss,
eth->write_hwaddr = mcs7830_write_mac;
eth->priv = ss;
if (mcs7830_basic_reset(ss))
if (mcs7830_basic_reset(ss->pusb_dev, ss->dev_priv))
return 0;
if (mcs7830_read_mac(eth))
if (mcs7830_read_mac(ss->pusb_dev, eth->enetaddr))
return 0;
debug("MAC %pM\n", eth->enetaddr);
return 1;
}
#endif
#ifdef CONFIG_DM_ETH
static int mcs7830_eth_start(struct udevice *dev)
{
struct usb_device *udev = dev_get_parent_priv(dev);
return mcs7830_init_common(udev);
}
void mcs7830_eth_stop(struct udevice *dev)
{
debug("** %s()\n", __func__);
}
int mcs7830_eth_send(struct udevice *dev, void *packet, int length)
{
struct mcs7830_private *priv = dev_get_priv(dev);
struct ueth_data *ueth = &priv->ueth;
return mcs7830_send_common(ueth, packet, length);
}
int mcs7830_eth_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct mcs7830_private *priv = dev_get_priv(dev);
struct ueth_data *ueth = &priv->ueth;
int len;
len = mcs7830_recv_common(ueth, priv->rx_buf);
*packetp = priv->rx_buf;
return len;
}
static int mcs7830_free_pkt(struct udevice *dev, uchar *packet, int packet_len)
{
struct mcs7830_private *priv = dev_get_priv(dev);
packet_len = ALIGN(packet_len, 4);
usb_ether_advance_rxbuf(&priv->ueth, sizeof(u32) + packet_len);
return 0;
}
int mcs7830_write_hwaddr(struct udevice *dev)
{
struct usb_device *udev = dev_get_parent_priv(dev);
struct eth_pdata *pdata = dev_get_platdata(dev);
return mcs7830_write_mac_common(udev, pdata->enetaddr);
}
static int mcs7830_eth_probe(struct udevice *dev)
{
struct usb_device *udev = dev_get_parent_priv(dev);
struct mcs7830_private *priv = dev_get_priv(dev);
struct eth_pdata *pdata = dev_get_platdata(dev);
struct ueth_data *ueth = &priv->ueth;
if (mcs7830_basic_reset(udev, priv))
return 0;
if (mcs7830_read_mac(udev, pdata->enetaddr))
return 0;
return usb_ether_register(dev, ueth, MCS7830_RX_URB_SIZE);
}
static const struct eth_ops mcs7830_eth_ops = {
.start = mcs7830_eth_start,
.send = mcs7830_eth_send,
.recv = mcs7830_eth_recv,
.free_pkt = mcs7830_free_pkt,
.stop = mcs7830_eth_stop,
.write_hwaddr = mcs7830_write_hwaddr,
};
U_BOOT_DRIVER(mcs7830_eth) = {
.name = "mcs7830_eth",
.id = UCLASS_ETH,
.probe = mcs7830_eth_probe,
.ops = &mcs7830_eth_ops,
.priv_auto_alloc_size = sizeof(struct mcs7830_private),
.platdata_auto_alloc_size = sizeof(struct eth_pdata),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
};
static const struct usb_device_id mcs7830_eth_id_table[] = {
{ USB_DEVICE(0x9710, 0x7832) }, /* Moschip 7832 */
{ USB_DEVICE(0x9710, 0x7830), }, /* Moschip 7830 */
{ USB_DEVICE(0x9710, 0x7730), }, /* Moschip 7730 */
{ USB_DEVICE(0x0df6, 0x0021), }, /* Sitecom LN 30 */
{ } /* Terminating entry */
};
U_BOOT_USB_DEVICE(mcs7830_eth, mcs7830_eth_id_table);
#endif

View file

@ -18,32 +18,34 @@ struct ehci_pci_priv {
struct ehci_ctrl ehci;
};
static void ehci_pci_common_init(pci_dev_t pdev, struct ehci_hccr **ret_hccr,
struct ehci_hcor **ret_hcor)
#ifdef CONFIG_DM_USB
static void ehci_pci_init(struct udevice *dev, struct ehci_hccr **ret_hccr,
struct ehci_hcor **ret_hcor)
{
struct ehci_hccr *hccr;
struct ehci_hcor *hcor;
uint32_t cmd;
u32 cmd;
hccr = (struct ehci_hccr *)pci_map_bar(pdev,
hccr = (struct ehci_hccr *)dm_pci_map_bar(dev,
PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
hcor = (struct ehci_hcor *)((uint32_t) hccr +
hcor = (struct ehci_hcor *)((uintptr_t) hccr +
HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
debug("EHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n",
(uint32_t)hccr, (uint32_t)hcor,
(uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
(u32)hccr, (u32)hcor,
(u32)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
*ret_hccr = hccr;
*ret_hcor = hcor;
/* enable busmaster */
pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
dm_pci_read_config32(dev, PCI_COMMAND, &cmd);
cmd |= PCI_COMMAND_MASTER;
pci_write_config_dword(pdev, PCI_COMMAND, cmd);
dm_pci_write_config32(dev, PCI_COMMAND, cmd);
}
#ifndef CONFIG_DM_USB
#else
#ifdef CONFIG_PCI_EHCI_DEVICE
static struct pci_device_id ehci_pci_ids[] = {
@ -55,6 +57,31 @@ static struct pci_device_id ehci_pci_ids[] = {
};
#endif
static void ehci_pci_legacy_init(pci_dev_t pdev, struct ehci_hccr **ret_hccr,
struct ehci_hcor **ret_hcor)
{
struct ehci_hccr *hccr;
struct ehci_hcor *hcor;
u32 cmd;
hccr = (struct ehci_hccr *)pci_map_bar(pdev,
PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
hcor = (struct ehci_hcor *)((uintptr_t) hccr +
HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
debug("EHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n",
(u32)hccr, (u32)hcor,
(u32)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
*ret_hccr = hccr;
*ret_hcor = hcor;
/* enable busmaster */
pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
cmd |= PCI_COMMAND_MASTER;
pci_write_config_dword(pdev, PCI_COMMAND, cmd);
}
/*
* Create the appropriate control structures to manage
* a new EHCI host controller.
@ -73,7 +100,7 @@ int ehci_hcd_init(int index, enum usb_init_type init,
printf("EHCI host controller not found\n");
return -1;
}
ehci_pci_common_init(pdev, ret_hccr, ret_hcor);
ehci_pci_legacy_init(pdev, ret_hccr, ret_hcor);
return 0;
}
@ -94,7 +121,7 @@ static int ehci_pci_probe(struct udevice *dev)
struct ehci_hccr *hccr;
struct ehci_hcor *hcor;
ehci_pci_common_init(pci_get_bdf(dev), &hccr, &hcor);
ehci_pci_init(dev, &hccr, &hcor);
return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
}

View file

@ -19,8 +19,8 @@ GraphicDevice ctfb;
void *video_hw_init(void)
{
GraphicDevice *gdev = &ctfb;
struct udevice *dev;
int bits_per_pixel;
pci_dev_t dev;
int ret;
printf("Video: ");
@ -33,14 +33,14 @@ void *video_hw_init(void)
return NULL;
}
if (vbe_get_video_info(gdev)) {
dev = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, 0);
if (dev < 0) {
ret = dm_pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, 0, &dev);
if (ret) {
printf("no card detected\n");
return NULL;
}
bootstage_start(BOOTSTAGE_ID_ACCUM_LCD, "vesa display");
ret = pci_run_vga_bios(dev, NULL, PCI_ROM_USE_NATIVE |
PCI_ROM_ALLOW_FALLBACK);
ret = dm_pci_run_vga_bios(dev, NULL, PCI_ROM_USE_NATIVE |
PCI_ROM_ALLOW_FALLBACK);
bootstage_accum(BOOTSTAGE_ID_ACCUM_LCD);
if (ret) {
printf("failed to run video BIOS: %d\n", ret);

View file

@ -145,7 +145,11 @@ struct ahci_ioports {
};
struct ahci_probe_ent {
#ifdef CONFIG_DM_PCI
struct udevice *dev;
#else
pci_dev_t dev;
#endif
struct ahci_ioports port[AHCI_MAX_PORTS];
u32 n_ports;
u32 hard_port_no;

View file

@ -42,7 +42,7 @@ struct vbe_mode_info;
int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo **pVGAInfo, int cleanUp);
/* Run a BIOS ROM natively (only supported on x86 machines) */
void bios_run_on_x86(pci_dev_t pcidev, unsigned long addr, int vesa_mode,
void bios_run_on_x86(struct udevice *dev, unsigned long addr, int vesa_mode,
struct vbe_mode_info *mode_info);
/**

View file

@ -24,6 +24,8 @@
#define CONFIG_SYS_TIMER_BASE 0x200440a0 /* TIMER5 */
#define CONFIG_SYS_TIMER_COUNTER (CONFIG_SYS_TIMER_BASE + 8)
#define CONFIG_SPL_SERIAL_SUPPORT
#define CONFIG_SYS_NS16550
#define CONFIG_SYS_NS16550_MEM32

View file

@ -776,4 +776,25 @@ static inline void devm_kfree(struct udevice *dev, void *ptr)
#endif /* ! CONFIG_DEVRES */
/**
* dm_set_translation_offset() - Set translation offset
* @offs: Translation offset
*
* Some platforms need a special address translation. Those
* platforms (e.g. mvebu in SPL) can configure a translation
* offset in the DM by calling this function. It will be
* added to all addresses returned in dev_get_addr().
*/
void dm_set_translation_offset(fdt_addr_t offs);
/**
* dm_get_translation_offset() - Get translation offset
*
* This function returns the translation offset that can
* be configured by calling dm_set_translation_offset().
*
* @return translation offset for the device address (0 as default).
*/
fdt_addr_t dm_get_translation_offset(void);
#endif

View file

@ -443,34 +443,17 @@ int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type,
int fdtdec_get_pci_vendev(const void *blob, int node,
u16 *vendor, u16 *device);
/**
* Look at the pci address of a device node that represents a PCI device
* and parse the bus, device and function number from it. For some cases
* like the bus number encoded in reg property is not correct after pci
* enumeration, this function looks through the node's compatible strings
* to get these numbers extracted instead.
*
* @param blob FDT blob
* @param node node to examine
* @param addr pci address in the form of fdt_pci_addr
* @param bdf returns bus, device, function triplet
* @return 0 if ok, negative on error
*/
int fdtdec_get_pci_bdf(const void *blob, int node,
struct fdt_pci_addr *addr, pci_dev_t *bdf);
/**
* Look at the pci address of a device node that represents a PCI device
* and return base address of the pci device's registers.
*
* @param blob FDT blob
* @param node node to examine
* @param dev device to examine
* @param addr pci address in the form of fdt_pci_addr
* @param bar returns base address of the pci device's registers
* @return 0 if ok, negative on error
*/
int fdtdec_get_pci_bar32(const void *blob, int node,
struct fdt_pci_addr *addr, u32 *bar);
int fdtdec_get_pci_bar32(struct udevice *dev, struct fdt_pci_addr *addr,
u32 *bar);
/**
* Look up a 32-bit integer property in a node and return it. The property

View file

@ -489,11 +489,9 @@ struct pci_device_id;
* This finds all the matching PCI IDs and sets them up as MMC devices.
*
* @name: Name to use for devices
* @mmc_supported: PCI IDs to search for
* @num_ids: Number of elements in @mmc_supported
* @mmc_supported: PCI IDs to search for, terminated by {0, 0}
*/
int pci_mmc_init(const char *name, struct pci_device_id *mmc_supported,
int num_ids);
int pci_mmc_init(const char *name, struct pci_device_id *mmc_supported);
/* Set block count limit because of 16 bit register limit on some hardware*/
#ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT

View file

@ -621,6 +621,7 @@ static inline void pci_set_ops(struct pci_controller *hose,
extern void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data);
#endif
#if !defined(CONFIG_DM_PCI) || defined(CONFIG_DM_PCI_COMPAT)
extern phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
pci_addr_t addr, unsigned long flags);
extern pci_addr_t pci_hose_phys_to_bus(struct pci_controller* hose,
@ -656,7 +657,6 @@ extern pci_addr_t pci_hose_phys_to_bus(struct pci_controller* hose,
pci_bus_to_virt((dev), (addr), PCI_REGION_IO, (len), (map_flags))
/* For driver model these are defined in macros in pci_compat.c */
#if !defined(CONFIG_DM_PCI) || defined(CONFIG_DM_PCI_COMPAT)
extern int pci_hose_read_config_byte(struct pci_controller *hose,
pci_dev_t dev, int where, u8 *val);
extern int pci_hose_read_config_word(struct pci_controller *hose,
@ -862,12 +862,12 @@ struct dm_pci_ops {
#define pci_get_ops(dev) ((struct dm_pci_ops *)(dev)->driver->ops)
/**
* pci_get_bdf() - Get the BDF value for a device
* dm_pci_get_bdf() - Get the BDF value for a device
*
* @dev: Device to check
* @return bus/device/function value (see PCI_BDF())
*/
pci_dev_t pci_get_bdf(struct udevice *dev);
pci_dev_t dm_pci_get_bdf(struct udevice *dev);
/**
* pci_bind_bus_devices() - scan a PCI bus and bind devices
@ -902,13 +902,13 @@ int pci_bind_bus_devices(struct udevice *bus);
int pci_auto_config_devices(struct udevice *bus);
/**
* pci_bus_find_bdf() - Find a device given its PCI bus address
* dm_pci_bus_find_bdf() - Find a device given its PCI bus address
*
* @bdf: PCI device address: bus, device and function -see PCI_BDF()
* @devp: Returns the device for this address, if found
* @return 0 if OK, -ENODEV if not found
*/
int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp);
int dm_pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp);
/**
* pci_bus_find_devfn() - Find a device on a bus
@ -995,7 +995,7 @@ int pci_find_device_id(struct pci_device_id *ids, int index,
* @bdf: PCI bus address to scan (PCI_BUS(bdf) is the bus number)
* @return 0 if OK, -ve on error
*/
int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf);
int dm_pci_hose_probe_bus(struct udevice *bus);
/**
* pci_bus_read_config() - Read a configuration value from a device
@ -1166,6 +1166,96 @@ struct udevice *pci_get_controller(struct udevice *dev);
int pci_get_regions(struct udevice *dev, struct pci_region **iop,
struct pci_region **memp, struct pci_region **prefp);
/**
* dm_pci_read_bar32() - read a base address register from a device
*
* @dev: Device to check
* @barnum: Bar number to read (numbered from 0)
* @return: value of BAR
*/
u32 dm_pci_read_bar32(struct udevice *dev, int barnum);
/**
* dm_pci_bus_to_phys() - convert a PCI bus address to a physical address
*
* @dev: Device containing the PCI address
* @addr: PCI address to convert
* @flags: Flags for the region type (PCI_REGION_...)
* @return physical address corresponding to that PCI bus address
*/
phys_addr_t dm_pci_bus_to_phys(struct udevice *dev, pci_addr_t addr,
unsigned long flags);
/**
* dm_pci_phys_to_bus() - convert a physical address to a PCI bus address
*
* @dev: Device containing the bus address
* @addr: Physical address to convert
* @flags: Flags for the region type (PCI_REGION_...)
* @return PCI bus address corresponding to that physical address
*/
pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr,
unsigned long flags);
/**
* dm_pci_map_bar() - get a virtual address associated with a BAR region
*
* Looks up a base address register and finds the physical memory address
* that corresponds to it
*
* @dev: Device to check
* @bar: Bar number to read (numbered from 0)
* @flags: Flags for the region type (PCI_REGION_...)
* @return: pointer to the virtual address to use
*/
void *dm_pci_map_bar(struct udevice *dev, int bar, int flags);
#define dm_pci_virt_to_bus(dev, addr, flags) \
dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), (flags))
#define dm_pci_bus_to_virt(dev, addr, flags, len, map_flags) \
map_physmem(dm_pci_bus_to_phys(dev, (addr), (flags)), \
(len), (map_flags))
#define dm_pci_phys_to_mem(dev, addr) \
dm_pci_phys_to_bus((dev), (addr), PCI_REGION_MEM)
#define dm_pci_mem_to_phys(dev, addr) \
dm_pci_bus_to_phys((dev), (addr), PCI_REGION_MEM)
#define dm_pci_phys_to_io(dev, addr) \
dm_pci_phys_to_bus((dev), (addr), PCI_REGION_IO)
#define dm_pci_io_to_phys(dev, addr) \
dm_pci_bus_to_phys((dev), (addr), PCI_REGION_IO)
#define dm_pci_virt_to_mem(dev, addr) \
dm_pci_virt_to_bus((dev), (addr), PCI_REGION_MEM)
#define dm_pci_mem_to_virt(dev, addr, len, map_flags) \
dm_pci_bus_to_virt((dev), (addr), PCI_REGION_MEM, (len), (map_flags))
#define dm_pci_virt_to_io(dev, addr) \
dm_dm_pci_virt_to_bus((dev), (addr), PCI_REGION_IO)
#define dm_pci_io_to_virt(dev, addr, len, map_flags) \
dm_dm_pci_bus_to_virt((dev), (addr), PCI_REGION_IO, (len), (map_flags))
/**
* dm_pci_find_device() - find a device by vendor/device ID
*
* @vendor: Vendor ID
* @device: Device ID
* @index: 0 to find the first match, 1 for second, etc.
* @devp: Returns pointer to the device, if found
* @return 0 if found, -ve on error
*/
int dm_pci_find_device(unsigned int vendor, unsigned int device, int index,
struct udevice **devp);
/**
* dm_pci_find_class() - find a device by class
*
* @find_class: 3-byte (24-bit) class value to find
* @index: 0 to find the first match, 1 for second, etc.
* @devp: Returns pointer to the device, if found
* @return 0 if found, -ve on error
*/
int dm_pci_find_class(uint find_class, int index, struct udevice **devp);
/**
* struct dm_pci_emul_ops - PCI device emulator operations
*/

View file

@ -44,14 +44,14 @@ enum pci_rom_emul {
};
/**
* pci_run_vga_bios() - Run the VGA BIOS in an x86 PC
* dm_pci_run_vga_bios() - Run the VGA BIOS in an x86 PC
*
* @dev: Video device containing the BIOS
* @int15_handler: Function to call to handle int 0x15
* @exec_method: flags from enum pci_rom_emul
*/
int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void),
int exec_method);
int dm_pci_run_vga_bios(struct udevice *dev, int (*int15_handler)(void),
int exec_method);
/**
* board_map_oprom_vendev() - map several PCI IDs to the one the ROM expects

View file

@ -5,6 +5,7 @@
#ifndef USE_HOSTCC
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <serial.h>
#include <libfdt.h>
@ -190,7 +191,7 @@ fdt_addr_t fdtdec_get_addr(const void *blob, int node,
return fdtdec_get_addr_size(blob, node, prop_name, NULL);
}
#ifdef CONFIG_PCI
#if defined(CONFIG_PCI) && defined(CONFIG_DM_PCI)
int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type,
const char *prop_name, struct fdt_pci_addr *addr)
{
@ -283,58 +284,10 @@ int fdtdec_get_pci_vendev(const void *blob, int node, u16 *vendor, u16 *device)
return -ENOENT;
}
int fdtdec_get_pci_bdf(const void *blob, int node,
struct fdt_pci_addr *addr, pci_dev_t *bdf)
int fdtdec_get_pci_bar32(struct udevice *dev, struct fdt_pci_addr *addr,
u32 *bar)
{
u16 dt_vendor, dt_device, vendor, device;
int ret;
/* get vendor id & device id from the compatible string */
ret = fdtdec_get_pci_vendev(blob, node, &dt_vendor, &dt_device);
if (ret)
return ret;
/* extract the bdf from fdt_pci_addr */
*bdf = addr->phys_hi & 0xffff00;
/* read vendor id & device id based on bdf */
pci_read_config_word(*bdf, PCI_VENDOR_ID, &vendor);
pci_read_config_word(*bdf, PCI_DEVICE_ID, &device);
/*
* Note there are two places in the device tree to fully describe
* a pci device: one is via compatible string with a format of
* "pciVVVV,DDDD" and the other one is the bdf numbers encoded in
* the device node's reg address property. We read the vendor id
* and device id based on bdf and compare the values with the
* "VVVV,DDDD". If they are the same, then we are good to use bdf
* to read device's bar. But if they are different, we have to rely
* on the vendor id and device id extracted from the compatible
* string and locate the real bdf by pci_find_device(). This is
* because normally we may only know device's device number and
* function number when writing device tree. The bus number is
* dynamically assigned during the pci enumeration process.
*/
if ((dt_vendor != vendor) || (dt_device != device)) {
*bdf = pci_find_device(dt_vendor, dt_device, 0);
if (*bdf == -1)
return -ENODEV;
}
return 0;
}
int fdtdec_get_pci_bar32(const void *blob, int node,
struct fdt_pci_addr *addr, u32 *bar)
{
pci_dev_t bdf;
int barnum;
int ret;
/* get pci devices's bdf */
ret = fdtdec_get_pci_bdf(blob, node, addr, &bdf);
if (ret)
return ret;
/* extract the bar number from fdt_pci_addr */
barnum = addr->phys_hi & 0xff;
@ -342,7 +295,7 @@ int fdtdec_get_pci_bar32(const void *blob, int node,
return -EINVAL;
barnum = (barnum - PCI_BASE_ADDRESS_0) / 4;
*bar = pci_read_bar32(pci_bus_to_hose(PCI_BUS(bdf)), bdf, barnum);
*bar = dm_pci_read_bar32(dev, barnum);
return 0;
}

View file

@ -35,20 +35,17 @@ DM_TEST(dm_test_pci_busnum, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
/* Test that we can use the swapcase device correctly */
static int dm_test_pci_swapcase(struct unit_test_state *uts)
{
pci_dev_t pci_dev = PCI_BDF(0, 0x1f, 0);
struct pci_controller *hose;
struct udevice *bus, *swap;
struct udevice *emul, *swap;
ulong io_addr, mem_addr;
char *ptr;
/* Check that asking for the device automatically fires up PCI */
ut_assertok(uclass_get_device(UCLASS_PCI_EMUL, 0, &swap));
ut_assertok(uclass_get_device(UCLASS_PCI, 0, &bus));
hose = dev_get_uclass_priv(bus);
ut_assertok(uclass_get_device(UCLASS_PCI_EMUL, 0, &emul));
ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1f, 0), &swap));
ut_assert(device_active(swap));
/* First test I/O */
io_addr = pci_read_bar32(hose, pci_dev, 0);
io_addr = dm_pci_read_bar32(swap, 0);
outb(2, io_addr);
ut_asserteq(2, inb(io_addr));
@ -56,7 +53,7 @@ static int dm_test_pci_swapcase(struct unit_test_state *uts)
* Now test memory mapping - note we must unmap and remap to cause
* the swapcase emulation to see our data and response.
*/
mem_addr = pci_read_bar32(hose, pci_dev, 1);
mem_addr = dm_pci_read_bar32(swap, 1);
ptr = map_sysmem(mem_addr, 20);
strcpy(ptr, "This is a TesT");
unmap_sysmem(ptr);