Xilinx changes for v2022.04-rc3

microblaze:
 - Fix exception handler
 
 zynqmp:
 - Show information about secure images
 - DT changes (som u-boot file removal)
 - Fix zynqmp_pm_cfg_obj_convert.py
 - Fix platform boot
 
 xilinx:
 - Fix bootm_size calculation
 - Remove GPIO_EXTRA_HEADER selection
 
 power:
 - Add zynqmp power management driver
 
 scsi:
 - Add phy support to ceva driver
 
 zynq qspi:
 - Fix unaligned accesses and check baudrate setup
 - Add support for spi memory operations
 
 net:
 - Fix 64bit calculation in axi_emac
 
 video:
 - Add missing gpio dependency for seps driver
 -----BEGIN PGP SIGNATURE-----
 
 iF0EABECAB0WIQQbPNTMvXmYlBPRwx7KSWXLKUoMIQUCYhOKGwAKCRDKSWXLKUoM
 IQP/AJ9U6inecbFh6LWchwX1ByhHVB0NuQCeLExfpcscdJlVUtNBC8kaRrrdjVM=
 =nq1B
 -----END PGP SIGNATURE-----

Merge tag 'xilinx-for-v2022.04-rc3' of https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze

Xilinx changes for v2022.04-rc3

microblaze:
- Fix exception handler

zynqmp:
- Show information about secure images
- DT changes (som u-boot file removal)
- Fix zynqmp_pm_cfg_obj_convert.py
- Fix platform boot

xilinx:
- Fix bootm_size calculation
- Remove GPIO_EXTRA_HEADER selection

power:
- Add zynqmp power management driver

scsi:
- Add phy support to ceva driver

zynq qspi:
- Fix unaligned accesses and check baudrate setup
- Add support for spi memory operations

net:
- Fix 64bit calculation in axi_emac

video:
- Add missing gpio dependency for seps driver
This commit is contained in:
Tom Rini 2022-02-21 08:32:02 -05:00
commit 24b628a8f8
34 changed files with 495 additions and 130 deletions

View file

@ -647,6 +647,7 @@ F: drivers/mtd/nand/raw/zynq_nand.c
F: drivers/net/phy/xilinx_phy.c
F: drivers/net/zynq_gem.c
F: drivers/phy/phy-zynqmp.c
F: drivers/power/domain/zynqmp-power-domain.c
F: drivers/serial/serial_zynq.c
F: drivers/reset/reset-zynqmp.c
F: drivers/rtc/zynqmp_rtc.c

View file

@ -1139,7 +1139,6 @@ config ARCH_VERSAL
select DM_MMC if MMC
select DM_SERIAL
select GICV3
select GPIO_EXTRA_HEADER
select OF_CONTROL
select SOC_DEVICE
imply BOARD_LATE_INIT
@ -1159,13 +1158,13 @@ config ARCH_ZYNQ
select CLK
select CLK_ZYNQ
select CPU_V7A
select DEBUG_UART_BOARD_INIT if SPL && DEBUG_UART
select DM
select DM_ETH if NET
select DM_MMC if MMC
select DM_SERIAL
select DM_SPI
select DM_SPI_FLASH
select GPIO_EXTRA_HEADER
select OF_CONTROL
select SPI
select SPL_BOARD_INIT if SPL
@ -1192,7 +1191,6 @@ config ARCH_ZYNQMP_R5
select DM_ETH if NET
select DM_MMC if MMC
select DM_SERIAL
select GPIO_EXTRA_HEADER
select OF_CONTROL
imply CMD_DM
imply DM_USB_GADGET
@ -1202,6 +1200,7 @@ config ARCH_ZYNQMP
select ARM64
select CLK
select DM
select DEBUG_UART_BOARD_INIT if SPL && DEBUG_UART
select DM_ETH if NET
select DM_MAILBOX
select DM_MMC if MMC
@ -1210,7 +1209,6 @@ config ARCH_ZYNQMP
select DM_SPI_FLASH if DM_SPI
imply FIRMWARE
select GICV2
select GPIO_EXTRA_HEADER
select OF_CONTROL
select SPL_BOARD_INIT if SPL
select SPL_CLK if SPL

View file

@ -12,7 +12,6 @@
#include "zynqmp-clk-ccf.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/phy/phy.h>
#include <include/dt-bindings/gpio/gpio.h>
/ {
model = "Smartlynq+ DLC21 RevA";

View file

@ -1,21 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* dts file for Xilinx ZynqMP K26/KV260 SD wiring
*
* (C) Copyright 2020 - 2021, Xilinx, Inc.
*
* Michal Simek <michal.simek@xilinx.com>
*/
/* SD0 only supports 3.3V, no level shifter */
&sdhci1 { /* on CC - MIO 39 - 51 */
status = "okay";
no-1-8-v;
disable-wp;
broken-cd;
xlnx,mio-bank = <1>;
/* Do not run SD in HS mode from bootloader */
sdhci-caps-mask = <0 0x200000>;
sdhci-caps = <0 0>;
max-frequency = <19000000>;
};

View file

@ -1,21 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* dts file for Xilinx ZynqMP Z2-VSOM
*
* (C) Copyright 2020 - 2021, Xilinx, Inc.
*
* Michal Simek <michal.simek@xilinx.com>
*/
/* SD0 only supports 3.3V, no level shifter */
&sdhci1 { /* FIXME - on CC - MIO 39 - 51 */
status = "okay";
no-1-8-v;
disable-wp;
broken-cd;
xlnx,mio-bank = <1>;
/* Do not run SD in HS mode from bootloader */
sdhci-caps-mask = <0 0x200000>;
sdhci-caps = <0 0>;
max-frequency = <19000000>;
};

View file

@ -1,6 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2016 - 2018 Xilinx, Inc.
*/
/* Empty file - for compilation */

View file

@ -1,10 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2013 Xilinx, Inc.
* Copyright (c) 2015 DAVE Embedded Systems
*/
#ifndef _ZYNQ_GPIO_H
#define _ZYNQ_GPIO_H
#endif /* _ZYNQ_GPIO_H */

View file

@ -16,17 +16,20 @@
#include <asm/arch/sys_proto.h>
#include <asm/arch/ps7_init_gpl.h>
void board_init_f(ulong dummy)
#if defined(CONFIG_DEBUG_UART_BOARD_INIT)
void board_debug_uart_init(void)
{
ps7_init();
}
#endif
void board_init_f(ulong dummy)
{
#if !defined(CONFIG_DEBUG_UART_BOARD_INIT)
ps7_init();
#endif
arch_cpu_init();
#ifdef CONFIG_DEBUG_UART
/* Uart debug for sure */
debug_uart_init();
puts("Debug uart enabled\n"); /* or printch() */
#endif
}
#ifdef CONFIG_SPL_BOARD_INIT

View file

@ -140,6 +140,7 @@ config DEFINE_TCM_OCM_MMAP
config ZYNQMP_PSU_INIT_ENABLED
bool "Include psu_init"
select BOARD_EARLY_INIT_F
help
Include psu_init to full u-boot. SPL include psu_init by default.

View file

@ -6,6 +6,6 @@
obj-y += clk.o
obj-y += cpu.o
obj-$(CONFIG_MP) += mp.o
obj-$(CONFIG_SPL_BUILD) += spl.o handoff.o
obj-$(CONFIG_SPL_BUILD) += spl.o handoff.o psu_spl_init.o
obj-$(CONFIG_SPL_ZYNQMP_DRAM_ECC_INIT) += ecc_spl_init.o
obj-$(CONFIG_ZYNQMP_PSU_INIT_ENABLED) += psu_spl_init.o

View file

@ -1,11 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2015 Xilinx, Inc.
*/
#ifndef __ARCH_ZYNQMP_GPIO_H
#define __ARCH_ZYNQMP_GPIO_H
/* Empty file - sdhci requires this. */
#endif

View file

@ -152,8 +152,12 @@ struct apu_regs {
#define CSU_JTAG_CHAIN_WR_SETUP GENMASK(1, 0)
#define CSU_PCAP_PROG_RELEASE_PL BIT(0)
#define ZYNQMP_CSU_STATUS_AUTHENTICATED BIT(0)
#define ZYNQMP_CSU_STATUS_ENCRYPTED BIT(1)
struct csu_regs {
u32 reserved0[4];
u32 status;
u32 reserved0[3];
u32 multi_boot;
u32 reserved1[7];
u32 jtag_chain_status_wr;

View file

@ -22,5 +22,6 @@ void prog_reg(unsigned long addr, unsigned long mask,
int psu_init(void);
unsigned long psu_post_config_data(void);
int psu_uboot_init(void);
#endif /* _PSU_INIT_GPL_H_ */

View file

@ -19,9 +19,19 @@
#include <asm/arch/psu_init_gpl.h>
#include <asm/arch/sys_proto.h>
#if defined(CONFIG_DEBUG_UART_BOARD_INIT)
void board_debug_uart_init(void)
{
psu_uboot_init();
}
#endif
void board_init_f(ulong dummy)
{
board_early_init_f();
#if !defined(CONFIG_DEBUG_UART_BOARD_INIT)
psu_uboot_init();
#endif
board_early_init_r();
#ifdef CONFIG_SPL_ZYNQMP_DRAM_ECC_INIT
zynqmp_ecc_init();

View file

@ -20,10 +20,25 @@ void _hw_exception_handler (void)
MFS(state, resr);
printf("Hardware exception at 0x%x address\n", address);
R17(address);
printf("Return address from exception 0x%x\n", address);
if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_DELAY_SLOT_EXCEP) &&
(state & 0x1000)) {
/*
* For exceptions in delay slots, the return address is stored
* in the Branch Target Register (BTR), rather than R17.
*/
MFS(address, rbtr);
puts("Exception in delay slot\n");
}
switch (state & 0x1f) { /* mask on exception cause */
case 0x1:
puts("Unaligned data access exception\n");
printf("Unaligned %sword access\n", ((state & 0x800) ? "" : "half"));
printf("Unaligned %s access\n", ((state & 0x400) ? "store" : "load"));
printf("Register R%x\n", (state & 0x3E0) >> 5);
break;
case 0x2:
puts("Illegal op-code exception\n");
@ -37,21 +52,15 @@ void _hw_exception_handler (void)
case 0x5:
puts("Divide by zero exception\n");
break;
#ifdef MICROBLAZE_V5
case 0x7:
puts("Priviledged or stack protection violation exception\n");
break;
case 0x1000:
puts("Exception in delay slot\n");
break;
#endif
default:
puts("Undefined cause\n");
break;
}
printf("Unaligned %sword access\n", ((state & 0x800) ? "" : "half"));
printf("Unaligned %s access\n", ((state & 0x400) ? "store" : "load"));
printf("Register R%x\n", (state & 0x3E) >> 5);
printf("Return address from exception 0x%x\n", address);
hang();
}

View file

@ -319,7 +319,7 @@ __maybe_unused int xilinx_read_eeprom(void)
return 0;
}
#if defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE)
#if defined(CONFIG_OF_BOARD)
void *board_fdt_blob_setup(int *err)
{
void *fdt_blob;
@ -355,6 +355,7 @@ void *board_fdt_blob_setup(int *err)
debug("DTB is also not passed via %p\n", fdt_blob);
*err = -EINVAL;
return NULL;
}
#endif
@ -377,7 +378,7 @@ int board_late_init_xilinx(void)
u32 ret = 0;
int i, id, macid = 0;
struct xilinx_board_description *desc;
phys_size_t bootm_size = gd->ram_size;
phys_size_t bootm_size = gd->ram_top - gd->ram_base;
if (!CONFIG_IS_ENABLED(MICROBLAZE)) {
ulong scriptaddr;

View file

@ -47,6 +47,15 @@ config XILINX_MICROBLAZE0_USR_EXCEP
the exception vector table. The user exception vector is located at
C_BASE_VECTORS + 0x8 address.
config XILINX_MICROBLAZE0_DELAY_SLOT_EXCEP
bool "MicroBlaze delay slot exception support"
default y
help
Enable this option if the MicroBlaze processor supports exceptions
caused by delay slot instructions (processor version >= v5.00). When
enabled, the hw exception handler will print a message indicating
whether the exception was triggered by a delay slot instruction.
config XILINX_MICROBLAZE0_VECTOR_BASE_ADDR
hex "Location of MicroBlaze vectors"
default 0x0

View file

@ -25,6 +25,13 @@
DECLARE_GLOBAL_DATA_PTR;
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_DEBUG_UART_BOARD_INIT)
void board_debug_uart_init(void)
{
/* Add initialization sequence if UART is not configured */
}
#endif
int board_init(void)
{
if (IS_ENABLED(CONFIG_SPL_BUILD))

View file

@ -209,6 +209,19 @@ static int do_zynqmp_pmufw(struct cmd_tbl *cmdtp, int flag, int argc,
if (argc != cmdtp->maxargs)
return CMD_RET_USAGE;
if (!strncmp(argv[2], "node", 4)) {
u32 id;
if (!strncmp(argv[3], "close", 5))
return zynqmp_pmufw_config_close();
id = dectoul(argv[3], NULL);
printf("Enable permission for node ID %d\n", id);
return zynqmp_pmufw_node(id);
}
addr = hextoul(argv[2], NULL);
size = hextoul(argv[3], NULL);
@ -416,6 +429,9 @@ static char zynqmp_help_text[] =
" lock(0)/split(1)\n"
#endif
"zynqmp pmufw address size - load PMU FW configuration object\n"
"zynqmp pmufw node <id> - load PMU FW configuration object\n"
"zynqmp pmufw node close - disable config object loading\n"
" node: keyword, id: NODE_ID in decimal format\n"
"zynqmp rsa srcaddr srclen mod exp rsaop -\n"
" Performs RSA encryption and RSA decryption on blob of data\n"
" at srcaddr and puts it back in srcaddr using modulus and\n"

View file

@ -313,9 +313,8 @@ static char *zynqmp_get_silicon_idcode_name(void)
}
#endif
int board_early_init_f(void)
int __maybe_unused psu_uboot_init(void)
{
#if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED)
int ret;
ret = psu_init();
@ -335,17 +334,32 @@ int board_early_init_f(void)
/* Delay is required for clocks to be propagated */
udelay(1000000);
#endif
#ifdef CONFIG_DEBUG_UART
/* Uart debug for sure */
debug_uart_init();
puts("Debug uart enabled\n"); /* or printch() */
#endif
return 0;
}
#if !defined(CONFIG_SPL_BUILD)
# if defined(CONFIG_DEBUG_UART_BOARD_INIT)
void board_debug_uart_init(void)
{
# if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED)
psu_uboot_init();
# endif
}
# endif
# if defined(CONFIG_BOARD_EARLY_INIT_F)
int board_early_init_f(void)
{
int ret = 0;
# if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED) && !defined(CONFIG_DEBUG_UART_BOARD_INIT)
ret = psu_uboot_init();
# endif
return ret;
}
# endif
#endif
static int multi_boot(void)
{
u32 multiboot = 0;
@ -373,6 +387,18 @@ static void restore_jtag(void)
}
#endif
static void print_secure_boot(void)
{
u32 status = 0;
if (zynqmp_mmio_read((ulong)&csu_base->status, &status))
return;
printf("Secure Boot:\t%sauthenticated, %sencrypted\n",
status & ZYNQMP_CSU_STATUS_AUTHENTICATED ? "" : "not ",
status & ZYNQMP_CSU_STATUS_ENCRYPTED ? "" : "not ");
}
#define PS_SYSMON_ANALOG_BUS_VAL 0x3210
#define PS_SYSMON_ANALOG_BUS_REG 0xFFA50914
@ -413,6 +439,8 @@ int board_init(void)
fpga_add(fpga_xilinx, &zynqmppl);
#endif
/* display secure boot information */
print_secure_boot();
if (current_el() == 3)
printf("Multiboot:\t%d\n", multi_boot());

View file

@ -60,6 +60,7 @@ CONFIG_CMD_MTDPARTS=y
CONFIG_CMD_MTDPARTS_SPREAD=y
CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES=y
CONFIG_CMD_UBI=y
CONFIG_OF_BOARD=y
CONFIG_OF_LIST="zynq-zc702 zynq-zc706 zynq-zc770-xm010 zynq-zc770-xm011 zynq-zc770-xm011-x16 zynq-zc770-xm012 zynq-zc770-xm013 zynq-cc108 zynq-microzed zynq-minized zynq-picozed zynq-zed zynq-zturn zynq-zturn-v5 zynq-zybo zynq-zybo-z7 zynq-dlc20-rev1.0"
CONFIG_ENV_IS_NOWHERE=y
CONFIG_ENV_IS_IN_FAT=y

View file

@ -18,7 +18,6 @@ CONFIG_ZYNQ_MAC_IN_EEPROM=y
CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20
CONFIG_CMD_FRU=y
CONFIG_ZYNQMP_USB=y
CONFIG_ZYNQMP_PSU_INIT_ENABLED=y
CONFIG_AHCI=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_REMAKE_ELF=y
@ -30,7 +29,6 @@ CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
CONFIG_USE_PREBOOT=y
CONFIG_PREBOOT="run scsi_init;usb start"
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_FPGA=y
@ -83,6 +81,7 @@ CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES=y
CONFIG_CMD_UBI=y
CONFIG_PARTITION_TYPE_GUID=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_OF_BOARD=y
CONFIG_OF_LIST="avnet-ultra96-rev1 zynqmp-a2197-revA zynqmp-e-a2197-00-revA zynqmp-g-a2197-00-revA zynqmp-m-a2197-01-revA zynqmp-m-a2197-02-revA zynqmp-m-a2197-03-revA zynqmp-p-a2197-00-revA zynqmp-zc1232-revA zynqmp-zc1254-revA zynqmp-zc1751-xm015-dc1 zynqmp-zc1751-xm016-dc2 zynqmp-zc1751-xm017-dc3 zynqmp-zc1751-xm018-dc4 zynqmp-zc1751-xm019-dc5 zynqmp-zcu100-revC zynqmp-zcu102-rev1.1 zynqmp-zcu102-rev1.0 zynqmp-zcu102-revA zynqmp-zcu102-revB zynqmp-zcu104-revA zynqmp-zcu104-revC zynqmp-zcu106-revA zynqmp-zcu111-revA zynqmp-zcu1275-revA zynqmp-zcu1275-revB zynqmp-zcu1285-revA zynqmp-zcu208-revA zynqmp-zcu216-revA zynqmp-topic-miamimp-xilinx-xdp-v1r1 zynqmp-sm-k26-revA zynqmp-smk-k26-revA zynqmp-dlc21-revA"
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent interrupts iommus power-domains"
CONFIG_ENV_IS_NOWHERE=y

View file

@ -6,9 +6,12 @@
#include <common.h>
#include <dm.h>
#include <ahci.h>
#include <generic-phy.h>
#include <log.h>
#include <reset.h>
#include <scsi.h>
#include <asm/io.h>
#include <dm/device_compat.h>
#include <linux/ioport.h>
/* Vendor Specific Register Offsets */
@ -181,6 +184,47 @@ static int sata_ceva_bind(struct udevice *dev)
static int sata_ceva_probe(struct udevice *dev)
{
struct ceva_sata_priv *priv = dev_get_priv(dev);
struct phy phy;
int ret;
struct reset_ctl_bulk resets;
ret = generic_phy_get_by_index(dev, 0, &phy);
if (!ret) {
dev_dbg(dev, "Perform PHY initialization\n");
ret = generic_phy_init(&phy);
if (ret)
return ret;
} else if (ret != -ENOENT) {
dev_dbg(dev, "could not get phy (err %d)\n", ret);
return ret;
}
/* reset is optional */
ret = reset_get_bulk(dev, &resets);
if (ret && ret != -ENOTSUPP && ret != -ENOENT) {
dev_dbg(dev, "Getting reset fails (err %d)\n", ret);
return ret;
}
/* Just trigger reset when reset is specified */
if (!ret) {
dev_dbg(dev, "Perform IP reset\n");
ret = reset_deassert_bulk(&resets);
if (ret) {
dev_dbg(dev, "Reset fails (err %d)\n", ret);
reset_release_bulk(&resets);
return ret;
}
}
if (phy.dev) {
dev_dbg(dev, "Perform PHY power on\n");
ret = generic_phy_power_on(&phy);
if (ret) {
dev_dbg(dev, "PHY power on failed (err %d)\n", ret);
return ret;
}
}
ceva_init_sata(priv);

View file

@ -8,6 +8,7 @@
#include <common.h>
#include <cpu_func.h>
#include <dm.h>
#include <dm/lists.h>
#include <log.h>
#include <zynqmp_firmware.h>
#include <asm/cache.h>
@ -27,6 +28,57 @@ struct zynqmp_power {
struct mbox_chan rx_chan;
} zynqmp_power;
#define NODE_ID_LOCATION 5
static unsigned int xpm_configobject[] = {
/**********************************************************************/
/* HEADER */
2, /* Number of remaining words in the header */
1, /* Number of sections included in config object */
PM_CONFIG_OBJECT_TYPE_OVERLAY, /* Type of Config object as overlay */
/**********************************************************************/
/* SLAVE SECTION */
PM_CONFIG_SLAVE_SECTION_ID, /* Section ID */
1, /* Number of slaves */
0, /* Node ID which will be changed below */
PM_SLAVE_FLAG_IS_SHAREABLE,
PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK |
PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK |
PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK, /* IPI Mask */
};
static unsigned int xpm_configobject_close[] = {
/**********************************************************************/
/* HEADER */
2, /* Number of remaining words in the header */
1, /* Number of sections included in config object */
PM_CONFIG_OBJECT_TYPE_OVERLAY, /* Type of Config object as overlay */
/**********************************************************************/
/* SET CONFIG SECTION */
PM_CONFIG_SET_CONFIG_SECTION_ID,
0U, /* Loading permission to Overlay config object */
};
int zynqmp_pmufw_config_close(void)
{
zynqmp_pmufw_load_config_object(xpm_configobject_close,
sizeof(xpm_configobject_close));
return 0;
}
int zynqmp_pmufw_node(u32 id)
{
/* Record power domain id */
xpm_configobject[NODE_ID_LOCATION] = id;
zynqmp_pmufw_load_config_object(xpm_configobject,
sizeof(xpm_configobject));
return 0;
}
static int ipi_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen)
{
struct zynqmp_ipi_msg msg;
@ -226,8 +278,27 @@ static const struct udevice_id zynqmp_firmware_ids[] = {
{ }
};
static int zynqmp_firmware_bind(struct udevice *dev)
{
int ret;
struct udevice *child;
if (IS_ENABLED(CONFIG_ZYNQMP_POWER_DOMAIN)) {
ret = device_bind_driver_to_node(dev, "zynqmp_power_domain",
"zynqmp_power_domain",
dev_ofnode(dev), &child);
if (ret) {
printf("zynqmp power domain driver is not bound: %d\n", ret);
return ret;
}
}
return dm_scan_fdt_dev(dev);
}
U_BOOT_DRIVER(zynqmp_firmware) = {
.id = UCLASS_FIRMWARE,
.name = "zynqmp_firmware",
.of_match = zynqmp_firmware_ids,
.bind = zynqmp_firmware_bind,
};

View file

@ -832,8 +832,8 @@ static int axi_emac_of_to_plat(struct udevice *dev)
printf("%s: axistream is not found\n", __func__);
return -EINVAL;
}
plat->dmatx = (struct axidma_reg *)fdtdec_get_addr(gd->fdt_blob,
offset, "reg");
plat->dmatx = (struct axidma_reg *)fdtdec_get_addr_size_auto_parent
(gd->fdt_blob, 0, offset, "reg", 0, NULL, false);
if (!plat->dmatx) {
printf("%s: axi_dma register space not found\n", __func__);
return -EINVAL;

View file

@ -373,6 +373,29 @@ static void xpsgtr_bypass_scrambler_8b10b(struct xpsgtr_phy *gtr_phy)
xpsgtr_write_phy(gtr_phy, L0_TX_DIG_61, L0_TM_DISABLE_SCRAMBLE_ENCODER);
}
/* DP-specific initialization. */
static void xpsgtr_phy_init_dp(struct xpsgtr_phy *gtr_phy)
{
xpsgtr_write_phy(gtr_phy, L0_TXPMD_TM_45,
L0_TXPMD_TM_45_OVER_DP_MAIN |
L0_TXPMD_TM_45_ENABLE_DP_MAIN |
L0_TXPMD_TM_45_OVER_DP_POST1 |
L0_TXPMD_TM_45_OVER_DP_POST2 |
L0_TXPMD_TM_45_ENABLE_DP_POST2);
xpsgtr_write_phy(gtr_phy, L0_TX_ANA_TM_118,
L0_TX_ANA_TM_118_FORCE_17_0);
}
/* SATA-specific initialization. */
static void xpsgtr_phy_init_sata(struct xpsgtr_phy *gtr_phy)
{
struct xpsgtr_dev *gtr_dev = gtr_phy->dev;
xpsgtr_bypass_scrambler_8b10b(gtr_phy);
writel(gtr_phy->lane, gtr_dev->siou + SATA_CONTROL_OFFSET);
}
/* SGMII-specific initialization. */
static void xpsgtr_phy_init_sgmii(struct xpsgtr_phy *gtr_phy)
{
@ -427,9 +450,12 @@ static int xpsgtr_init(struct phy *x)
case ICM_PROTOCOL_SGMII:
xpsgtr_phy_init_sgmii(gtr_phy);
break;
case ICM_PROTOCOL_DP:
case ICM_PROTOCOL_SATA:
return -EINVAL;
xpsgtr_phy_init_sata(gtr_phy);
break;
case ICM_PROTOCOL_DP:
xpsgtr_phy_init_dp(gtr_phy);
break;
}
dev_dbg(gtr_dev->dev, "lane %u (type %u, protocol %u): init done\n",

View file

@ -88,4 +88,13 @@ config TI_POWER_DOMAIN
help
Generic power domain implementation for TI K3 devices.
config ZYNQMP_POWER_DOMAIN
bool "Enable the Xilinx ZynqMP Power domain driver"
depends on POWER_DOMAIN && ZYNQMP_FIRMWARE
help
Generic power domain implementation for Xilinx ZynqMP devices.
The driver should be enabled when system starts in very minimal
configuration and it is extended at run time. Then enabling
the driver will ensure that PMUFW enable access to requested IP.
endmenu

View file

@ -16,3 +16,4 @@ obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain-test.o
obj-$(CONFIG_TEGRA186_POWER_DOMAIN) += tegra186-power-domain.o
obj-$(CONFIG_TI_SCI_POWER_DOMAIN) += ti-sci-power-domain.o
obj-$(CONFIG_TI_POWER_DOMAIN) += ti-power-domain.o
obj-$(CONFIG_ZYNQMP_POWER_DOMAIN) += zynqmp-power-domain.o

View file

@ -0,0 +1,89 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2021, Xilinx. Inc.
*/
#include <common.h>
#include <dm.h>
#include <log.h>
#include <malloc.h>
#include <misc.h>
#include <power-domain-uclass.h>
#include <linux/bitops.h>
#include <zynqmp_firmware.h>
#define NODE_ID_LOCATION 5
static unsigned int xpm_configobject[] = {
/* HEADER */
2, /* Number of remaining words in the header */
1, /* Number of sections included in config object */
PM_CONFIG_OBJECT_TYPE_OVERLAY, /* Type of Config object as overlay */
/* SLAVE SECTION */
PM_CONFIG_SLAVE_SECTION_ID, /* Section ID */
1, /* Number of slaves */
0, /* Node ID which will be changed below */
PM_SLAVE_FLAG_IS_SHAREABLE,
PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK |
PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK |
PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK, /* IPI Mask */
};
static int zynqmp_pm_request_node(const u32 node, const u32 capabilities,
const u32 qos, const enum zynqmp_pm_request_ack ack)
{
return xilinx_pm_request(PM_REQUEST_NODE, node, capabilities,
qos, ack, NULL);
}
static int zynqmp_power_domain_request(struct power_domain *power_domain)
{
/* Record power domain id */
xpm_configobject[NODE_ID_LOCATION] = power_domain->id;
zynqmp_pmufw_load_config_object(xpm_configobject, sizeof(xpm_configobject));
return 0;
}
static int zynqmp_power_domain_free(struct power_domain *power_domain)
{
/* nop now */
return 0;
}
static int zynqmp_power_domain_on(struct power_domain *power_domain)
{
return zynqmp_pm_request_node(power_domain->id,
ZYNQMP_PM_CAPABILITY_ACCESS,
ZYNQMP_PM_MAX_QOS,
ZYNQMP_PM_REQUEST_ACK_BLOCKING);
}
static int zynqmp_power_domain_off(struct power_domain *power_domain)
{
/* nop now */
return 0;
}
struct power_domain_ops zynqmp_power_domain_ops = {
.request = zynqmp_power_domain_request,
.rfree = zynqmp_power_domain_free,
.on = zynqmp_power_domain_on,
.off = zynqmp_power_domain_off,
};
static int zynqmp_power_domain_probe(struct udevice *dev)
{
return 0;
}
U_BOOT_DRIVER(zynqmp_power_domain) = {
.name = "zynqmp_power_domain",
.id = UCLASS_POWER_DOMAIN,
.probe = zynqmp_power_domain_probe,
.ops = &zynqmp_power_domain_ops,
};

View file

@ -16,6 +16,7 @@
#include <asm/global_data.h>
#include <asm/io.h>
#include <linux/bitops.h>
#include <spi-mem.h>
DECLARE_GLOBAL_DATA_PTR;
@ -49,6 +50,9 @@ DECLARE_GLOBAL_DATA_PTR;
#define ZYNQ_QSPI_CR_BAUD_SHIFT 3 /* Baud rate divisor shift */
#define ZYNQ_QSPI_CR_SS_SHIFT 10 /* Slave select shift */
#define ZYNQ_QSPI_MAX_BAUD_RATE 0x7
#define ZYNQ_QSPI_DEFAULT_BAUD_RATE 0x2
#define ZYNQ_QSPI_FIFO_DEPTH 63
#define ZYNQ_QSPI_WAIT (CONFIG_SYS_HZ / 100) /* 10 ms */
@ -230,12 +234,16 @@ static void zynq_qspi_read_data(struct zynq_qspi_priv *priv, u32 data, u8 size)
priv->rx_buf += 1;
break;
case 2:
*((u16 *)priv->rx_buf) = data;
priv->rx_buf += 2;
*((u8 *)priv->rx_buf) = data;
priv->rx_buf += 1;
*((u8 *)priv->rx_buf) = (u8)(data >> 8);
priv->rx_buf += 1;
break;
case 3:
*((u16 *)priv->rx_buf) = data;
priv->rx_buf += 2;
*((u8 *)priv->rx_buf) = data;
priv->rx_buf += 1;
*((u8 *)priv->rx_buf) = (u8)(data >> 8);
priv->rx_buf += 1;
byte3 = (u8)(data >> 16);
*((u8 *)priv->rx_buf) = byte3;
priv->rx_buf += 1;
@ -272,13 +280,17 @@ static void zynq_qspi_write_data(struct zynq_qspi_priv *priv,
*data |= 0xFFFFFF00;
break;
case 2:
*data = *((u16 *)priv->tx_buf);
priv->tx_buf += 2;
*data = *((u8 *)priv->tx_buf);
priv->tx_buf += 1;
*data |= (*((u8 *)priv->tx_buf) << 8);
priv->tx_buf += 1;
*data |= 0xFFFF0000;
break;
case 3:
*data = *((u16 *)priv->tx_buf);
priv->tx_buf += 2;
*data = *((u8 *)priv->tx_buf);
priv->tx_buf += 1;
*data |= (*((u8 *)priv->tx_buf) << 8);
priv->tx_buf += 1;
*data |= (*((u8 *)priv->tx_buf) << 16);
priv->tx_buf += 1;
*data |= 0xFF000000;
@ -613,6 +625,9 @@ static int zynq_qspi_set_speed(struct udevice *bus, uint speed)
(2 << baud_rate_val)) > speed))
baud_rate_val++;
if (baud_rate_val > ZYNQ_QSPI_MAX_BAUD_RATE)
baud_rate_val = ZYNQ_QSPI_DEFAULT_BAUD_RATE;
plat->speed_hz = speed / (2 << baud_rate_val);
}
confr &= ~ZYNQ_QSPI_CR_BAUD_MASK;
@ -649,12 +664,72 @@ static int zynq_qspi_set_mode(struct udevice *bus, uint mode)
return 0;
}
static int zynq_qspi_exec_op(struct spi_slave *slave,
const struct spi_mem_op *op)
{
int op_len, pos = 0, ret, i;
unsigned int flag = 0;
const u8 *tx_buf = NULL;
u8 *rx_buf = NULL;
if (op->data.nbytes) {
if (op->data.dir == SPI_MEM_DATA_IN)
rx_buf = op->data.buf.in;
else
tx_buf = op->data.buf.out;
}
op_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes;
u8 op_buf[op_len];
op_buf[pos++] = op->cmd.opcode;
if (op->addr.nbytes) {
for (i = 0; i < op->addr.nbytes; i++)
op_buf[pos + i] = op->addr.val >>
(8 * (op->addr.nbytes - i - 1));
pos += op->addr.nbytes;
}
if (op->dummy.nbytes)
memset(op_buf + pos, 0xff, op->dummy.nbytes);
/* 1st transfer: opcode + address + dummy cycles */
/* Make sure to set END bit if no tx or rx data messages follow */
if (!tx_buf && !rx_buf)
flag |= SPI_XFER_END;
ret = zynq_qspi_xfer(slave->dev, op_len * 8, op_buf, NULL,
flag | SPI_XFER_BEGIN);
if (ret)
return ret;
/* 2nd transfer: rx or tx data path */
if (tx_buf || rx_buf) {
ret = zynq_qspi_xfer(slave->dev, op->data.nbytes * 8, tx_buf,
rx_buf, flag | SPI_XFER_END);
if (ret)
return ret;
}
spi_release_bus(slave);
return 0;
}
static const struct spi_controller_mem_ops zynq_qspi_mem_ops = {
.exec_op = zynq_qspi_exec_op,
};
static const struct dm_spi_ops zynq_qspi_ops = {
.claim_bus = zynq_qspi_claim_bus,
.release_bus = zynq_qspi_release_bus,
.xfer = zynq_qspi_xfer,
.set_speed = zynq_qspi_set_speed,
.set_mode = zynq_qspi_set_mode,
.mem_ops = &zynq_qspi_mem_ops,
};
static const struct udevice_id zynq_qspi_ids[] = {

View file

@ -675,7 +675,7 @@ config VIDEO_NX
config VIDEO_SEPS525
bool "Enable video support for Seps525"
depends on DM_VIDEO
depends on DM_VIDEO && DM_GPIO
help
Enable support for the Syncoam PM-OLED display driver (RGB 160x128).
Currently driver is supporting only SPI interface.

View file

@ -11,9 +11,6 @@
/* Microblaze is microblaze_0 */
#define XILINX_FSL_NUMBER 3
/* MicroBlaze CPU */
#define MICROBLAZE_V5 1
#define CONFIG_SYS_BOOTM_LEN (64 * 1024 * 1024)
/* uart */

View file

@ -342,20 +342,20 @@ enum pm_ioctl_id {
IOCTL_AIE_ISR_CLEAR = 24,
};
#define PM_SIP_SVC 0xc2000000
#define PM_SIP_SVC 0xc2000000
#define ZYNQMP_PM_VERSION_MAJOR 1
#define ZYNQMP_PM_VERSION_MINOR 0
#define ZYNQMP_PM_VERSION_MAJOR_SHIFT 16
#define ZYNQMP_PM_VERSION_MINOR_MASK 0xFFFF
#define ZYNQMP_PM_VERSION_MAJOR 1
#define ZYNQMP_PM_VERSION_MINOR 0
#define ZYNQMP_PM_VERSION_MAJOR_SHIFT 16
#define ZYNQMP_PM_VERSION_MINOR_MASK 0xFFFF
#define ZYNQMP_PM_VERSION \
((ZYNQMP_PM_VERSION_MAJOR << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | \
ZYNQMP_PM_VERSION_MINOR)
#define ZYNQMP_PM_VERSION_INVALID ~0
#define ZYNQMP_PM_VERSION_INVALID ~0
#define PMUFW_V1_0 ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0)
#define PMUFW_V1_0 ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0)
/*
* Return payload size
@ -367,8 +367,41 @@ enum pm_ioctl_id {
#define PAYLOAD_ARG_CNT 5U
unsigned int zynqmp_firmware_version(void);
int zynqmp_pmufw_node(u32 id);
int zynqmp_pmufw_config_close(void);
void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size);
int xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
u32 arg3, u32 *ret_payload);
/* Type of Config Object */
#define PM_CONFIG_OBJECT_TYPE_BASE 0x1U
#define PM_CONFIG_OBJECT_TYPE_OVERLAY 0x2U
/* Section Id */
#define PM_CONFIG_SLAVE_SECTION_ID 0x102U
#define PM_CONFIG_SET_CONFIG_SECTION_ID 0x107U
/* Flag Option */
#define PM_SLAVE_FLAG_IS_SHAREABLE 0x1U
#define PM_MASTER_USING_SLAVE_MASK 0x2U
/* IPI Mask for Master */
#define PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK 0x00000001
#define PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK 0x00000100
#define PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK 0x00000200
enum zynqmp_pm_request_ack {
ZYNQMP_PM_REQUEST_ACK_NO = 1,
ZYNQMP_PM_REQUEST_ACK_BLOCKING = 2,
ZYNQMP_PM_REQUEST_ACK_NON_BLOCKING = 3,
};
/* Node capabilities */
#define ZYNQMP_PM_CAPABILITY_ACCESS 0x1U
#define ZYNQMP_PM_CAPABILITY_CONTEXT 0x2U
#define ZYNQMP_PM_CAPABILITY_WAKEUP 0x4U
#define ZYNQMP_PM_CAPABILITY_UNUSABLE 0x8U
#define ZYNQMP_PM_MAX_QOS 100U
#endif /* _ZYNQMP_FIRMWARE_H_ */

View file

@ -244,6 +244,8 @@ pm_define = {
'SUSPEND_TIMEOUT' : 0xFFFFFFFF,
'PM_CONFIG_OBJECT_TYPE_BASE' : 0x1,
'PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK' : 0x00000001,
'PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK' : 0x00000100,
'PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK' : 0x00000200,