Merge branch '2019-11-07-master-imports'

- Add Phytium Durian Board
- Assorted bugfixes
- Allow for  make ERR_PTR/PTR_ERR architecture specific
This commit is contained in:
Tom Rini 2019-11-08 07:27:45 -05:00
commit ee1c499851
29 changed files with 774 additions and 48 deletions

14
Kconfig
View File

@ -281,6 +281,20 @@ config SYS_LDSCRIPT
Path within the source tree to the linker script to use for the
main U-Boot binary.
config ERR_PTR_OFFSET
hex
default 0x0
help
Some U-Boot pointers have redundant information, so we can use a
scheme where we can return either an error code or a pointer with the
same return value. The default implementation just casts the pointer
to a number, however, this may fail on platforms where the end of the
address range is used for valid pointers (e.g. 0xffffff00 is a valid
heap pointer in socfpga SPL).
For such platforms, this value provides an upper range of those error
pointer values - up to 'MAX_ERRNO' bytes below this value must be
unused/invalid addresses.
endmenu # General setup
menu "Boot images"

View File

@ -481,6 +481,13 @@ S: Maintained
T: git https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze.git
F: arch/arm/mach-zynqmp-r5/
ARM PHYTIUM
M: liuhao <liuhao@phytium.com.cn>
M: shuyiqi <shuyiqi@phytium.com.cn>
S: Maintained
F: drivers/pci/pcie_phytium.c
F: arch/arm/dts/phytium-durian.dts
BINMAN
M: Simon Glass <sjg@chromium.org>
S: Maintained

View File

@ -295,27 +295,31 @@ static int API_dev_close(va_list ap)
/*
* Notice: this is for sending network packets only, as U-Boot does not
* support writing to storage at the moment (12.2007)
*
* pseudo signature:
*
* int API_dev_write(
* struct device_info *di,
* void *buf,
* int *len
* int *len,
* unsigned long *start
* )
*
* buf: ptr to buffer from where to get the data to send
*
* len: length of packet to be sent (in bytes)
* len: ptr to length to be read
* - network: len of packet to be sent (in bytes)
* - storage: # of blocks to write (can vary in size depending on define)
*
* start: ptr to start block (only used for storage devices, ignored for
* network)
*/
static int API_dev_write(va_list ap)
{
struct device_info *di;
void *buf;
int *len;
lbasize_t *len_stor, act_len_stor;
lbastart_t *start;
int *len_net;
int err = 0;
/* 1. arg is ptr to the device_info struct */
@ -333,23 +337,36 @@ static int API_dev_write(va_list ap)
if (buf == NULL)
return API_EINVAL;
/* 3. arg is length of buffer */
len = (int *)va_arg(ap, uintptr_t);
if (len == NULL)
return API_EINVAL;
if (*len <= 0)
return API_EINVAL;
if (di->type & DEV_TYP_STOR) {
/* 3. arg - ptr to var with # of blocks to write */
len_stor = (lbasize_t *)va_arg(ap, uintptr_t);
if (!len_stor)
return API_EINVAL;
if (*len_stor <= 0)
return API_EINVAL;
if (di->type & DEV_TYP_STOR)
/*
* write to storage is currently not supported by U-Boot:
* no storage device implements block_write() method
*/
return API_ENODEV;
/* 4. arg - ptr to var with start block */
start = (lbastart_t *)va_arg(ap, uintptr_t);
else if (di->type & DEV_TYP_NET)
err = dev_write_net(di->cookie, buf, *len);
else
act_len_stor = dev_write_stor(di->cookie, buf, *len_stor, *start);
if (act_len_stor != *len_stor) {
debugf("write @ %llu: done %llu out of %llu blocks",
(uint64_t)blk, (uint64_t)act_len_stor,
(uint64_t)len_stor);
return API_EIO;
}
} else if (di->type & DEV_TYP_NET) {
/* 3. arg points to the var with length of packet to write */
len_net = (int *)va_arg(ap, uintptr_t);
if (!len_net)
return API_EINVAL;
if (*len_net <= 0)
return API_EINVAL;
err = dev_write_net(di->cookie, buf, *len_net);
} else
err = API_ENODEV;
return err;

View File

@ -22,6 +22,7 @@ int dev_close_stor(void *);
int dev_close_net(void *);
lbasize_t dev_read_stor(void *, void *, lbasize_t, lbastart_t);
lbasize_t dev_write_stor(void *, void *, lbasize_t, lbastart_t);
int dev_read_net(void *, void *, int);
int dev_write_net(void *, void *, int);

View File

@ -349,3 +349,27 @@ lbasize_t dev_read_stor(void *cookie, void *buf, lbasize_t len, lbastart_t start
return dd->block_read(dd, start, len, buf);
#endif /* defined(CONFIG_BLK) */
}
lbasize_t dev_write_stor(void *cookie, void *buf, lbasize_t len, lbastart_t start)
{
struct blk_desc *dd = (struct blk_desc *)cookie;
int type = dev_stor_type(dd);
if (type == ENUM_MAX)
return 0;
if (!dev_stor_is_valid(type, dd))
return 0;
#ifdef CONFIG_BLK
return blk_dwrite(dd, start, len, buf);
#else
if (dd->block_write == NULL) {
debugf("no block_write() for device 0x%08x\n", cookie);
return 0;
}
return dd->block_write(dd, start, len, buf);
#endif /* defined(CONFIG_BLK) */
}

View File

@ -1631,6 +1631,13 @@ config ARCH_ASPEED
select OF_CONTROL
imply CMD_DM
config TARGET_DURIAN
bool "Support Phytium Durian Platform"
select ARM64
help
Support for durian platform.
It has 2GB Sdram, uart and pcie.
endchoice
config ARCH_SUPPORT_TFABOOT
@ -1830,6 +1837,7 @@ source "board/woodburn/Kconfig"
source "board/xilinx/Kconfig"
source "board/xilinx/zynq/Kconfig"
source "board/xilinx/zynqmp/Kconfig"
source "board/phytium/durian/Kconfig"
source "arch/arm/Kconfig.debug"

View File

@ -834,6 +834,8 @@ dtb-$(CONFIG_TARGET_VEXPRESS_CA5X2) += vexpress-v2p-ca5s.dtb
dtb-$(CONFIG_TARGET_VEXPRESS_CA9X4) += vexpress-v2p-ca9.dtb
dtb-$(CONFIG_TARGET_VEXPRESS_CA15_TC2) += vexpress-v2p-ca15_a7.dtb
dtb-$(CONFIG_TARGET_DURIAN) += phytium-durian.dtb
targets += $(dtb-y)
# Add any required device tree compiler flags here

View File

@ -0,0 +1,33 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2019, Phytium Ltd.
* shuyiqi <shuyiqi@phytium.com.cn>
*/
/dts-v1/;
/ {
model = "Phytium Durian";
compatible = "phytium,durian";
#address-cells = <2>;
#size-cells = <2>;
pcie-controller@40000000 {
compatible = "phytium,pcie-host-1.0";
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
reg = <0x0 0x40000000 0x0 0x10000000>;
bus-range = <0x0 0xff>;
ranges = <0x1000000 0x0 0x0 0x0 0x50000000 0x0 0xF00000>,
<0x2000000 0x0 0x58000000 0x0 0x58000000 0x0 0x28000000>,
<0x43000000 0x10 0x00000000 0x10 0x00000000 0x10 0x00000000>;
};
uart@28001000 {
compatible = "arm,pl011";
reg = <0x0 0x28001000 0x0 0x1000>;
clock = <48000000>;
};
};

View File

@ -23,6 +23,7 @@
#ifdef __KERNEL__
#include <linux/types.h>
#include <linux/kernel.h>
#include <asm/byteorder.h>
#include <asm/memory.h>
#include <asm/barriers.h>
@ -315,9 +316,105 @@ extern void _memset_io(unsigned long, int, size_t);
extern void __readwrite_bug(const char *fn);
/* Optimized copy functions to read from/write to IO sapce */
#ifdef CONFIG_ARM64
/*
* Copy data from IO memory space to "real" memory space.
*/
static inline
void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
{
while (count && !IS_ALIGNED((unsigned long)from, 8)) {
*(u8 *)to = __raw_readb(from);
from++;
to++;
count--;
}
while (count >= 8) {
*(u64 *)to = __raw_readq(from);
from += 8;
to += 8;
count -= 8;
}
while (count) {
*(u8 *)to = __raw_readb(from);
from++;
to++;
count--;
}
}
/*
* Copy data from "real" memory space to IO memory space.
*/
static inline
void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
{
while (count && !IS_ALIGNED((unsigned long)to, 8)) {
__raw_writeb(*(u8 *)from, to);
from++;
to++;
count--;
}
while (count >= 8) {
__raw_writeq(*(u64 *)from, to);
from += 8;
to += 8;
count -= 8;
}
while (count) {
__raw_writeb(*(u8 *)from, to);
from++;
to++;
count--;
}
}
/*
* "memset" on IO memory space.
*/
static inline
void __memset_io(volatile void __iomem *dst, int c, size_t count)
{
u64 qc = (u8)c;
qc |= qc << 8;
qc |= qc << 16;
qc |= qc << 32;
while (count && !IS_ALIGNED((unsigned long)dst, 8)) {
__raw_writeb(c, dst);
dst++;
count--;
}
while (count >= 8) {
__raw_writeq(qc, dst);
dst += 8;
count -= 8;
}
while (count) {
__raw_writeb(c, dst);
dst++;
count--;
}
}
#endif /* CONFIG_ARM64 */
#ifdef CONFIG_ARM64
#define memset_io(a, b, c) __memset_io((a), (b), (c))
#define memcpy_fromio(a, b, c) __memcpy_fromio((a), (b), (c))
#define memcpy_toio(a, b, c) __memcpy_toio((a), (b), (c))
#else
#define memset_io(a, b, c) memset((void *)(a), (b), (c))
#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c))
#define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c))
#endif
/*
* If this architecture has ISA IO, then define the isa_read/isa_write

View File

@ -235,12 +235,18 @@ static void cache_disable(uint32_t cache_bit)
/* if cache isn;t enabled no need to disable */
if ((reg & CR_C) != CR_C)
return;
#ifdef CONFIG_SYS_ARM_MMU
/* if disabling data cache, disable mmu too */
cache_bit |= CR_M;
#endif
}
reg = get_cr();
#ifdef CONFIG_SYS_ARM_MMU
if (cache_bit == (CR_C | CR_M))
#elif defined(CONFIG_SYS_ARM_MPU)
if (cache_bit == CR_C)
#endif
flush_dcache_all();
set_cr(reg & ~cache_bit);
}

View File

@ -1,5 +1,8 @@
if ARCH_SOCFPGA
config ERR_PTR_OFFSET
default 0xfffec000 if TARGET_SOCFPGA_GEN5 # Boot ROM range
config NR_DRAM_BANKS
default 1

View File

@ -0,0 +1,12 @@
if TARGET_DURIAN
config SYS_BOARD
default "durian"
config SYS_VENDOR
default "phytium"
config SYS_CONFIG_NAME
default "durian"
endif

View File

@ -0,0 +1,8 @@
DURIAN BOARD
M: liuhao <liuhao@phytium.com.cn>
M: shuyiqi <shuyiqi@phytium.com.cn>
S: Maintained
F: board/phytium/durian/*
F: include/configs/durian.h
F: configs/durian_defconfig

View File

@ -0,0 +1,9 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2019
# shuyiqi <shuyiqi@phytium.com.cn>
# liuhao <liuhao@phytium.com.cn>
#
obj-y += durian.o

View File

@ -0,0 +1,59 @@
Here is the step-by-step to boot U-Boot on phytium durian board.
Compile U-Boot
==============
> make durian_defconfig
> make
Get the prebuild binary about BPF
=================================
> cd ../
> git clone https://github.com/phytium-durian/bpf.git
Package the image
=================
> cd bpf
> cp ../u-boot/u-boot.bin ./
> ./dopack
The fip-all.bin is the final image.
Flash the image into the spi nor-flash
======================================
Any spi nor-flash and appropriate tool can be used to flash.
For example, we choose the S25FL256 chip that produced from
SPANSION company and EZP_XPro V1.2.
Reset the board, you can get U-Boot log message from boot console:
Power on...
Start pcie setup!
End pcie setup!
Start ddr setup!
End ddr setup!
Jump to entrypoint: 0x500000
U-Boot 2019.10-00594-g9ccc1b17ea-dirty (Oct 18 2019 - 00:17:09 +0800)
DRAM: 1.9 GiB
In: uart@28001000
Out: uart@28001000
Err: uart@28001000
scanning bus for devices...
Target spinup took 0 ms.
SATA link 1 timeout.
SATA link 2 timeout.
SATA link 3 timeout.
AHCI 0001.0000 32 slots 4 ports 6 Gbps 0xf impl SATA mode
flags: 64bit ncq led only pmp fbss pio slum part sxs
Device 0: (0:0) Vendor: ATA Prod.: ST1000DM010-2EP1 Rev: CC43
Type: Hard Disk
Capacity: 953869.7 MB = 931.5 GB (1953525168 x 512)
SATA link 0 timeout.
SATA link 1 timeout.
SATA link 2 timeout.
SATA link 3 timeout.
AHCI 0001.0000 32 slots 4 ports 6 Gbps 0xf impl SATA mode
flags: 64bit ncq led only pmp fbss pio slum part sxs
Hit any key to stop autoboot: 0
durian#

View File

@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2019
* Phytium Technology Ltd <www.phytium.com>
* shuyiqi <shuyiqi@phytium.com.cn>
*/
#ifndef _FT_DURIAN_H
#define _FT_DURIAN_H
/* FLUSH L3 CASHE */
#define HNF_COUNT 0x8
#define HNF_PSTATE_REQ (HNF_BASE + 0x10)
#define HNF_PSTATE_STAT (HNF_BASE + 0x18)
#define HNF_PSTATE_OFF 0x0
#define HNF_PSTATE_SFONLY 0x1
#define HNF_PSTATE_HALF 0x2
#define HNF_PSTATE_FULL 0x3
#define HNF_STRIDE 0x10000
#define HNF_BASE (unsigned long)(0x3A200000)
#endif /* _FT_DURIAN_H */

View File

@ -0,0 +1,110 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2019
* shuyiqi <shuyiqi@phytium.com.cn>
* liuhao <liuhao@phytium.com.cn>
*/
#include <common.h>
#include <asm/armv8/mmu.h>
#include <asm/system.h>
#include <asm/io.h>
#include <linux/arm-smccc.h>
#include <linux/kernel.h>
#include <scsi.h>
#include "cpu.h"
DECLARE_GLOBAL_DATA_PTR;
int dram_init(void)
{
gd->mem_clk = 0;
gd->ram_size = PHYS_SDRAM_1_SIZE;
return 0;
}
int dram_init_banksize(void)
{
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
return 0;
}
int board_init(void)
{
return 0;
}
void reset_cpu(ulong addr)
{
struct arm_smccc_res res;
arm_smccc_smc(0x84000009, 0, 0, 0, 0, 0, 0, 0, &res);
debug("reset cpu error, %lx\n", res.a0);
}
static struct mm_region durian_mem_map[] = {
{
.virt = 0x0UL,
.phys = 0x0UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN |
PTE_BLOCK_UXN
},
{
.virt = (u64)PHYS_SDRAM_1,
.phys = (u64)PHYS_SDRAM_1,
.size = (u64)PHYS_SDRAM_1_SIZE,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_NS |
PTE_BLOCK_INNER_SHARE
},
{
0,
}
};
struct mm_region *mem_map = durian_mem_map;
int print_cpuinfo(void)
{
printf("CPU: Phytium ft2004 %ld MHz\n", gd->cpu_clk);
return 0;
}
int __asm_flush_l3_dcache(void)
{
int i, pstate;
for (i = 0; i < HNF_COUNT; i++)
writeq(HNF_PSTATE_SFONLY, HNF_PSTATE_REQ + i * HNF_STRIDE);
for (i = 0; i < HNF_COUNT; i++) {
do {
pstate = readq(HNF_PSTATE_STAT + i * HNF_STRIDE);
} while ((pstate & 0xf) != (HNF_PSTATE_SFONLY << 2));
}
for (i = 0; i < HNF_COUNT; i++)
writeq(HNF_PSTATE_FULL, HNF_PSTATE_REQ + i * HNF_STRIDE);
return 0;
}
int last_stage_init(void)
{
int ret;
/* pci e */
pci_init();
/* scsi scan */
ret = scsi_scan(true);
if (ret) {
printf("scsi scan failed\n");
return CMD_RET_FAILURE;
}
return ret;
}

View File

@ -263,13 +263,6 @@ config CMD_BOOTI
help
Boot an AArch64 Linux Kernel image from memory.
config CMD_BOOTEFI
bool "bootefi"
depends on EFI_LOADER
default y
help
Boot an EFI image from memory.
config BOOTM_LINUX
bool "Support booting Linux OS images"
depends on CMD_BOOTM || CMD_BOOTZ || CMD_BOOTI
@ -318,6 +311,13 @@ config BOOTM_VXWORKS
help
Support booting VxWorks images via the bootm command.
config CMD_BOOTEFI
bool "bootefi"
depends on EFI_LOADER
default y
help
Boot an EFI image from memory.
config CMD_BOOTEFI_HELLO_COMPILE
bool "Compile a standard EFI hello world binary for testing"
depends on CMD_BOOTEFI && !CPU_V7M && !SANDBOX
@ -1986,6 +1986,14 @@ config CMD_MTDPARTS_SPREAD
at least as large as the size specified in the mtdparts variable and
2) each partition starts on a good block.
config CMD_MTDPARTS_SHOW_NET_SIZES
bool "Show net size (w/o bad blocks) of partitions"
depends on CMD_MTDPARTS
help
Adds two columns to the printed partition table showing the
effective usable size of a partition, if bad blocks are taken
into account.
config CMD_REISER
bool "reiser - Access to reiserfs filesystems"
help

View File

@ -1233,11 +1233,11 @@ static uint64_t net_part_size(struct mtd_info *mtd, struct part_info *part)
{
uint64_t i, net_size = 0;
if (!mtd->block_isbad)
if (!mtd->_block_isbad)
return part->size;
for (i = 0; i < part->size; i += mtd->erasesize) {
if (!mtd->block_isbad(mtd, part->offset + i))
if (!mtd->_block_isbad(mtd, part->offset + i))
net_size += mtd->erasesize;
}
@ -1274,7 +1274,7 @@ static void print_partition_table(void)
part = list_entry(pentry, struct part_info, link);
net_size = net_part_size(mtd, part);
size_note = part->size == net_size ? " " : " (!)";
printf("%2d: %-20s0x%08x\t0x%08x%s\t0x%08x\t%d\n",
printf("%2d: %-20s0x%08llx\t0x%08x%s\t0x%08llx\t%d\n",
part_num, part->name, part->size,
net_size, size_note, part->offset,
part->mask_flags);

View File

@ -34,7 +34,6 @@
/* partition handling routines */
int mtdparts_init(void);
int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num);
int find_dev_and_part(const char *id, struct mtd_device **dev,
u8 *part_num, struct part_info **part);
#endif

View File

@ -75,10 +75,10 @@
#define __U_BOOT__
#ifdef __U_BOOT__
#include <common.h> /* readline */
#include <env.h>
#include <malloc.h> /* malloc, free, realloc*/
#include <linux/ctype.h> /* isalpha, isdigit */
#include <common.h> /* readline */
#include <console.h>
#include <bootretry.h>
#include <cli.h>

View File

@ -2086,7 +2086,7 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
{
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
MALLOC_ZERO(mem, sz);
memset(mem, 0, sz);
return mem;
}
#endif

View File

@ -1014,8 +1014,19 @@ config SPL_SERIAL_SUPPORT
unless there are space reasons not to. Even then, consider
enabling SPL_USE_TINY_PRINTF which is a small printf() version.
config SPL_SPI_SUPPORT
bool "Support SPI drivers"
help
Enable support for using SPI in SPL. This is used for connecting
to SPI flash for loading U-Boot. See SPL_SPI_FLASH_SUPPORT for
more details on that. The SPI driver provides the transport for
data between the SPI flash and the CPU. This option can be used to
enable SPI drivers that are needed for other purposes also, such
as a SPI PMIC.
config SPL_SPI_FLASH_SUPPORT
bool "Support SPI flash drivers"
depends on SPL_SPI_SUPPORT
help
Enable support for using SPI flash in SPL, and loading U-Boot from
SPI flash. SPI flash (Serial Peripheral Bus flash) is named after
@ -1060,16 +1071,6 @@ config SYS_SPI_U_BOOT_OFFS
Address within SPI-Flash from where the u-boot payload is fetched
from.
config SPL_SPI_SUPPORT
bool "Support SPI drivers"
help
Enable support for using SPI in SPL. This is used for connecting
to SPI flash for loading U-Boot. See SPL_SPI_FLASH_SUPPORT for
more details on that. The SPI driver provides the transport for
data between the SPI flash and the CPU. This option can be used to
enable SPI drivers that are needed for other purposes also, such
as a SPI PMIC.
config SPL_THERMAL
bool "Driver support for thermal devices"
help

33
configs/durian_defconfig Normal file
View File

@ -0,0 +1,33 @@
CONFIG_ARM=y
CONFIG_ARM_SMCCC=y
CONFIG_TARGET_DURIAN=y
CONFIG_SYS_TEXT_BASE=0x500000
CONFIG_NR_DRAM_BANKS=1
# CONFIG_PSCI_RESET is not set
CONFIG_AHCI=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyAMA0,115200 earlycon=pl011,0x28001000 root=/dev/sda2 rw"
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_LAST_STAGE_INIT=y
CONFIG_SYS_PROMPT="durian#"
# CONFIG_CMD_LZMADEC is not set
# CONFIG_CMD_UNZIP is not set
CONFIG_CMD_PCI=y
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="phytium-durian"
# CONFIG_NET is not set
CONFIG_DM=y
CONFIG_SCSI_AHCI=y
CONFIG_AHCI_PCI=y
CONFIG_BLK=y
# CONFIG_MMC is not set
CONFIG_PCI=y
CONFIG_DM_PCI=y
CONFIG_DM_PCI_COMPAT=y
CONFIG_PCI_PHYTIUM=y
CONFIG_SCSI=y
CONFIG_DM_SCSI=y
CONFIG_DM_SERIAL=y
CONFIG_PL01X_SERIAL=y

View File

@ -51,6 +51,13 @@ config PCIE_ECAM_GENERIC
Say Y here if you want to enable support for generic ECAM-based
PCIe host controllers, such as the one emulated by QEMU.
config PCI_PHYTIUM
bool "Phytium PCIe support"
depends on DM_PCI
help
Say Y here if you want to enable PCIe controller support on
Phytium SoCs.
config PCIE_DW_MVEBU
bool "Enable Armada-8K PCIe driver (DesignWare core)"
depends on DM_PCI

View File

@ -38,6 +38,7 @@ obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape_fixup.o
obj-$(CONFIG_PCIE_LAYERSCAPE_GEN4) += pcie_layerscape_gen4.o \
pcie_layerscape_gen4_fixup.o
obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o
obj-$(CONFIG_PCI_PHYTIUM) += pcie_phytium.o
obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o
obj-$(CONFIG_PCI_KEYSTONE) += pcie_dw_ti.o
obj-$(CONFIG_PCIE_MEDIATEK) += pcie_mediatek.o

200
drivers/pci/pcie_phytium.c Normal file
View File

@ -0,0 +1,200 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Phytium PCIE host driver
*
* Heavily based on drivers/pci/pcie_xilinx.c
*
* Copyright (C) 2019
*/
#include <common.h>
#include <dm.h>
#include <pci.h>
#include <asm/io.h>
/**
* struct phytium_pcie - phytium PCIe controller state
* @cfg_base: The base address of memory mapped configuration space
*/
struct phytium_pcie {
void *cfg_base;
};
/*
* phytium_pci_skip_dev()
* @parent: Identifies the PCIe device to access
*
* Checks whether the parent of the PCIe device is bridge
*
* Return: true if it is bridge, else false.
*/
static int phytium_pci_skip_dev(pci_dev_t parent)
{
unsigned char pos, id;
unsigned long addr = 0x40000000;
unsigned short capreg;
unsigned char port_type;
addr += PCI_BUS(parent) << 20;
addr += PCI_DEV(parent) << 15;
addr += PCI_FUNC(parent) << 12;
pos = 0x34;
while (1) {
pos = readb(addr + pos);
if (pos < 0x40)
break;
pos &= ~3;
id = readb(addr + pos);
if (id == 0xff)
break;
if (id == 0x10) {
capreg = readw(addr + pos + 2);
port_type = (capreg >> 4) & 0xf;
if (port_type == 0x6 || port_type == 0x4)
return 1;
else
return 0;
}
pos += 1;
}
return 0;
}
/**
* pci_phytium_conf_address() - Calculate the address of a config access
* @bus: Pointer to the PCI bus
* @bdf: Identifies the PCIe device to access
* @offset: The offset into the device's configuration space
* @paddress: Pointer to the pointer to write the calculates address to
*
* Calculates the address that should be accessed to perform a PCIe
* configuration space access for a given device identified by the PCIe
* controller device @pcie and the bus, device & function numbers in @bdf. If
* access to the device is not valid then the function will return an error
* code. Otherwise the address to access will be written to the pointer pointed
* to by @paddress.
*/
static int pci_phytium_conf_address(struct udevice *bus, pci_dev_t bdf,
uint offset,
void **paddress)
{
struct phytium_pcie *pcie = dev_get_priv(bus);
void *addr;
pci_dev_t bdf_parent;
unsigned int bus_no = PCI_BUS(bdf);
unsigned int dev_no = PCI_DEV(bdf);
bdf_parent = PCI_BDF((bus_no - 1), 0, 0);
addr = pcie->cfg_base;
addr += PCI_BUS(bdf) << 20;
addr += PCI_DEV(bdf) << 15;
addr += PCI_FUNC(bdf) << 12;
if (bus_no > 0 && dev_no > 0) {
if ((readb(addr + PCI_HEADER_TYPE) & 0x7f) !=
PCI_HEADER_TYPE_BRIDGE)
return -ENODEV;
if (phytium_pci_skip_dev(bdf_parent))
return -ENODEV;
}
addr += offset;
*paddress = addr;
return 0;
}
/**
* pci_phytium_read_config() - Read from configuration space
* @bus: Pointer to the PCI bus
* @bdf: Identifies the PCIe device to access
* @offset: The offset into the device's configuration space
* @valuep: A pointer at which to store the read value
* @size: Indicates the size of access to perform
*
* Read a value of size @size from offset @offset within the configuration
* space of the device identified by the bus, device & function numbers in @bdf
* on the PCI bus @bus.
*/
static int pci_phytium_read_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong *valuep,
enum pci_size_t size)
{
return pci_generic_mmap_read_config(bus, pci_phytium_conf_address,
bdf, offset, valuep, size);
}
/**
* pci_phytium_write_config() - Write to configuration space
* @bus: Pointer to the PCI bus
* @bdf: Identifies the PCIe device to access
* @offset: The offset into the device's configuration space
* @value: The value to write
* @size: Indicates the size of access to perform
*
* Write the value @value of size @size from offset @offset within the
* configuration space of the device identified by the bus, device & function
* numbers in @bdf on the PCI bus @bus.
*/
static int pci_phytium_write_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong value,
enum pci_size_t size)
{
return pci_generic_mmap_write_config(bus, pci_phytium_conf_address,
bdf, offset, value, size);
}
/**
* pci_phytium_ofdata_to_platdata() - Translate from DT to device state
* @dev: A pointer to the device being operated on
*
* Translate relevant data from the device tree pertaining to device @dev into
* state that the driver will later make use of. This state is stored in the
* device's private data structure.
*
* Return: 0 on success, else -EINVAL
*/
static int pci_phytium_ofdata_to_platdata(struct udevice *dev)
{
struct phytium_pcie *pcie = dev_get_priv(dev);
struct fdt_resource reg_res;
DECLARE_GLOBAL_DATA_PTR;
int err;
err = fdt_get_resource(gd->fdt_blob, dev_of_offset(dev), "reg",
0, &reg_res);
if (err < 0) {
pr_err("\"reg\" resource not found\n");
return err;
}
pcie->cfg_base = map_physmem(reg_res.start,
fdt_resource_size(&reg_res),
MAP_NOCACHE);
return 0;
}
static const struct dm_pci_ops pci_phytium_ops = {
.read_config = pci_phytium_read_config,
.write_config = pci_phytium_write_config,
};
static const struct udevice_id pci_phytium_ids[] = {
{ .compatible = "phytium,pcie-host-1.0" },
{ }
};
U_BOOT_DRIVER(pci_phytium) = {
.name = "pci_phytium",
.id = UCLASS_PCI,
.of_match = pci_phytium_ids,
.ops = &pci_phytium_ops,
.ofdata_to_platdata = pci_phytium_ofdata_to_platdata,
.priv_auto_alloc_size = sizeof(struct phytium_pcie),
};

44
include/configs/durian.h Normal file
View File

@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2019
* shuyiqi <shuyiqi@phytium.com.cn>
* liuhao <liuhao@phytium.com.cn>
*/
#ifndef __DURIAN_CONFIG_H__
#define __DURIAN_CONFIG_H__
/* Sdram Bank #1 Address */
#define PHYS_SDRAM_1 0x80000000
#define PHYS_SDRAM_1_SIZE 0x7B000000
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x10000000)
/* Size of Malloc Pool */
#define CONFIG_ENV_SIZE 4096
#define CONFIG_SYS_MALLOC_LEN (1 * 1024 * 1024 + CONFIG_ENV_SIZE)
#define CONFIG_SYS_INIT_SP_ADDR (0x88000000 - 0x100000)
/* PCI CONFIG */
#define CONFIG_SYS_PCI_64BIT 1
#define CONFIG_PCI_SCAN_SHOW
/* SCSI */
#define CONFIG_SYS_SCSI_MAX_SCSI_ID 4
#define CONFIG_SYS_SCSI_MAX_LUN 1
#define CONFIG_SYS_SCSI_MAX_DEVICE 128
#define CONFIG_SCSI_AHCI_PLAT
#define CONFIG_SYS_SATA_MAX_DEVICE 4
/* BOOT */
#define CONFIG_SYS_BOOTM_LEN (60 * 1024 * 1024)
#define CONFIG_EXTRA_ENV_SETTINGS \
"load_kernel=ext4load scsi 0:1 0x90100000 uImage-2004\0" \
"load_fdt=ext4load scsi 0:1 0x95000000 ft2004-pci-64.dtb\0"\
"boot_fdt=bootm 0x90100000 -:- 0x95000000\0" \
"distro_bootcmd=run load_kernel; run load_fdt; run boot_fdt"
#endif

View File

@ -23,22 +23,22 @@
static inline void *ERR_PTR(long error)
{
return (void *) error;
return (void *)(CONFIG_ERR_PTR_OFFSET + error);
}
static inline long PTR_ERR(const void *ptr)
{
return (long) ptr;
return ((long)ptr - CONFIG_ERR_PTR_OFFSET);
}
static inline long IS_ERR(const void *ptr)
{
return IS_ERR_VALUE((unsigned long)ptr);
return IS_ERR_VALUE((unsigned long)PTR_ERR(ptr));
}
static inline bool IS_ERR_OR_NULL(const void *ptr)
{
return !ptr || IS_ERR_VALUE((unsigned long)ptr);
return !ptr || IS_ERR_VALUE((unsigned long)PTR_ERR(ptr));
}
/**