diff --git a/MAINTAINERS b/MAINTAINERS index 4a8b32cc28..ef2cbb3223 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -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 +M: shuyiqi +S: Maintained +F: drivers/pci/pcie_phytium.c +F: arch/arm/dts/phytium-durian.dts + BINMAN M: Simon Glass S: Maintained diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 629c5e8c2d..7b80630aa1 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -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" diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 251d32ca62..89ab8001ce 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -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 diff --git a/arch/arm/dts/phytium-durian.dts b/arch/arm/dts/phytium-durian.dts new file mode 100644 index 0000000000..3b76949a26 --- /dev/null +++ b/arch/arm/dts/phytium-durian.dts @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019, Phytium Ltd. + * shuyiqi + */ + +/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>; + }; +}; + diff --git a/board/phytium/durian/Kconfig b/board/phytium/durian/Kconfig new file mode 100644 index 0000000000..dc0710925b --- /dev/null +++ b/board/phytium/durian/Kconfig @@ -0,0 +1,12 @@ +if TARGET_DURIAN + +config SYS_BOARD + default "durian" + +config SYS_VENDOR + default "phytium" + +config SYS_CONFIG_NAME + default "durian" + +endif diff --git a/board/phytium/durian/MAINTAINERS b/board/phytium/durian/MAINTAINERS new file mode 100644 index 0000000000..895b7621e8 --- /dev/null +++ b/board/phytium/durian/MAINTAINERS @@ -0,0 +1,8 @@ +DURIAN BOARD +M: liuhao +M: shuyiqi +S: Maintained +F: board/phytium/durian/* +F: include/configs/durian.h +F: configs/durian_defconfig + diff --git a/board/phytium/durian/Makefile b/board/phytium/durian/Makefile new file mode 100644 index 0000000000..c2fbf19838 --- /dev/null +++ b/board/phytium/durian/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2019 +# shuyiqi +# liuhao +# + +obj-y += durian.o + diff --git a/board/phytium/durian/README b/board/phytium/durian/README new file mode 100644 index 0000000000..4443133e1a --- /dev/null +++ b/board/phytium/durian/README @@ -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# diff --git a/board/phytium/durian/cpu.h b/board/phytium/durian/cpu.h new file mode 100644 index 0000000000..a5a213d30c --- /dev/null +++ b/board/phytium/durian/cpu.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2019 + * Phytium Technology Ltd + * shuyiqi + */ + +#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 */ + diff --git a/board/phytium/durian/durian.c b/board/phytium/durian/durian.c new file mode 100644 index 0000000000..59f307d357 --- /dev/null +++ b/board/phytium/durian/durian.c @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 + * shuyiqi + * liuhao + */ + +#include +#include +#include +#include +#include +#include +#include +#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; +} + diff --git a/configs/durian_defconfig b/configs/durian_defconfig new file mode 100644 index 0000000000..20177e4776 --- /dev/null +++ b/configs/durian_defconfig @@ -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 diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 71aab85ed3..13603b9d57 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -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 diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 856ac71a1c..219473aa79 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -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 diff --git a/drivers/pci/pcie_phytium.c b/drivers/pci/pcie_phytium.c new file mode 100644 index 0000000000..92e281e7c2 --- /dev/null +++ b/drivers/pci/pcie_phytium.c @@ -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 +#include +#include +#include + +/** + * 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, ®_res); + if (err < 0) { + pr_err("\"reg\" resource not found\n"); + return err; + } + + pcie->cfg_base = map_physmem(reg_res.start, + fdt_resource_size(®_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), +}; diff --git a/include/configs/durian.h b/include/configs/durian.h new file mode 100644 index 0000000000..c42a98b9a0 --- /dev/null +++ b/include/configs/durian.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2019 + * shuyiqi + * liuhao + */ + +#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