aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/arm/dts/zynqmp-zcu1275-revB.dts24
-rw-r--r--arch/arm/dts/zynqmp-zcu1285-revA.dts23
-rw-r--r--arch/arm/dts/zynqmp.dtsi61
-rw-r--r--board/xilinx/common/fru_ops.c2
-rw-r--r--board/xilinx/microblaze-generic/MAINTAINERS1
-rw-r--r--board/xilinx/microblaze-generic/microblaze-generic.c5
-rw-r--r--board/xilinx/versal/MAINTAINERS1
-rw-r--r--board/xilinx/zynq/MAINTAINERS1
-rw-r--r--board/xilinx/zynqmp/MAINTAINERS1
-rw-r--r--cmd/load.c9
-rw-r--r--common/usb_storage.c4
-rw-r--r--doc/device-tree-bindings/video/syncoam,seps525.txt24
-rw-r--r--drivers/mtd/nand/raw/zynq_nand.c10
-rw-r--r--drivers/serial/serial_xuartlite.c2
-rw-r--r--drivers/spi/zynqmp_gqspi.c6
-rw-r--r--drivers/video/Kconfig7
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/seps525.c327
-rw-r--r--drivers/video/vidconsole-uclass.c40
-rw-r--r--drivers/video/video-uclass.c23
-rw-r--r--drivers/video/video_bmp.c5
-rw-r--r--include/configs/microblaze-generic.h17
-rw-r--r--include/video.h22
-rwxr-xr-xtools/zynqmp_pm_cfg_obj_convert.py2
25 files changed, 540 insertions, 80 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 52d73075258..26dd2543e50 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -548,6 +548,7 @@ S: Maintained
T: git https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze.git
F: arch/arm/mach-zynq/
F: doc/board/xilinx/
+F: doc/device-tree-bindings/video/syncoam,seps525.txt
F: drivers/clk/clk_zynq.c
F: drivers/fpga/zynqpl.c
F: drivers/gpio/zynq_gpio.c
@@ -589,6 +590,7 @@ F: drivers/spi/zynq_qspi.c
F: drivers/spi/zynq_spi.c
F: drivers/timer/cadence-ttc.c
F: drivers/usb/host/ehci-zynq.c
+F: drivers/video/seps525.c
F: drivers/watchdog/cdns_wdt.c
F: include/zynqmppl.h
F: include/zynqmp_firmware.h
diff --git a/arch/arm/dts/zynqmp-zcu1275-revB.dts b/arch/arm/dts/zynqmp-zcu1275-revB.dts
index b612215f40e..1de890c30f6 100644
--- a/arch/arm/dts/zynqmp-zcu1275-revB.dts
+++ b/arch/arm/dts/zynqmp-zcu1275-revB.dts
@@ -23,6 +23,7 @@
serial1 = &dcc;
spi0 = &qspi;
mmc0 = &sdhci1;
+ ethernet0 = &gem1;
};
chosen {
@@ -40,6 +41,29 @@
status = "okay";
};
+&gem1 {
+ status = "okay";
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy1: ethernet-phy@1 {
+ reg = <1>; /* KSZ9031RNXIC on AES-FMC-NETW1-G */
+ rxc-skew-ps = <1800>; /* Skew control of RX_CLK pad output */
+ txc-skew-ps = <1800>; /* Skew control of GTX_CLK pad input */
+ txen-skew-ps = <900>; /* Skew control of TX_CTL pad input */
+ rxdv-skew-ps = <0>; /* Skew control of RX_CTL pad output */
+ rxd0-skew-ps = <0>; /* Skew control of RXD0 pad output */
+ rxd1-skew-ps = <0>; /* Skew control of RXD1 pad output */
+ rxd2-skew-ps = <0>; /* Skew control of RXD2 pad output */
+ rxd3-skew-ps = <0>; /* Skew control of RXD3 pad output */
+ txd0-skew-ps = <900>; /* Skew control of TXD0 pad input */
+ txd1-skew-ps = <900>; /* Skew control of TXD1 pad input */
+ txd2-skew-ps = <900>; /* Skew control of TXD2 pad input */
+ txd3-skew-ps = <900>; /* Skew control of TXD3 pad input */
+ };
+ };
+};
+
&qspi {
status = "okay";
flash@0 {
diff --git a/arch/arm/dts/zynqmp-zcu1285-revA.dts b/arch/arm/dts/zynqmp-zcu1285-revA.dts
index f041df83dab..21d62e993a3 100644
--- a/arch/arm/dts/zynqmp-zcu1285-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu1285-revA.dts
@@ -23,6 +23,7 @@
serial1 = &dcc;
spi0 = &qspi;
mmc0 = &sdhci1;
+ ethernet0 = &gem1; /* EMIO */
i2c = &i2c0; /* EMIO */
};
@@ -222,6 +223,28 @@
};
};
+&gem1 {
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy1: ethernet-phy@1 {
+ reg = <1>; /* KSZ9031RNXIC on AES-FMC-NETW1-G */
+ rxc-skew-ps = <1800>; /* Skew control of RX_CLK pad output */
+ txc-skew-ps = <1800>; /* Skew control of GTX_CLK pad input */
+ txen-skew-ps = <900>; /* Skew control of TX_CTL pad input */
+ rxdv-skew-ps = <0>; /* Skew control of RX_CTL pad output */
+ rxd0-skew-ps = <0>; /* Skew control of RXD0 pad output */
+ rxd1-skew-ps = <0>; /* Skew control of RXD1 pad output */
+ rxd2-skew-ps = <0>; /* Skew control of RXD2 pad output */
+ rxd3-skew-ps = <0>; /* Skew control of RXD3 pad output */
+ txd0-skew-ps = <900>; /* Skew control of TXD0 pad input */
+ txd1-skew-ps = <900>; /* Skew control of TXD1 pad input */
+ txd2-skew-ps = <900>; /* Skew control of TXD2 pad input */
+ txd3-skew-ps = <900>; /* Skew control of TXD3 pad input */
+ };
+ };
+};
+
&qspi {
status = "okay";
flash@0 {
diff --git a/arch/arm/dts/zynqmp.dtsi b/arch/arm/dts/zynqmp.dtsi
index 1634af0bd89..aa0ac95e122 100644
--- a/arch/arm/dts/zynqmp.dtsi
+++ b/arch/arm/dts/zynqmp.dtsi
@@ -115,8 +115,10 @@
<0x0 0xff9905e0 0x0 0x20>,
<0x0 0xff990e80 0x0 0x20>,
<0x0 0xff990ea0 0x0 0x20>;
- reg-names = "local_request_region", "local_response_region",
- "remote_request_region", "remote_response_region";
+ reg-names = "local_request_region",
+ "local_response_region",
+ "remote_request_region",
+ "remote_response_region";
#mbox-cells = <1>;
xlnx,ipi-id = <4>;
};
@@ -145,15 +147,10 @@
firmware {
zynqmp_firmware: zynqmp-firmware {
compatible = "xlnx,zynqmp-firmware";
+ #power-domain-cells = <1>;
method = "smc";
- #power-domain-cells = <0x1>;
u-boot,dm-pre-reloc;
- zynqmp_pcap: pcap {
- compatible = "xlnx,zynqmp-pcap-fpga";
- clock-names = "ref_clk";
- };
-
zynqmp_power: zynqmp-power {
u-boot,dm-pre-reloc;
compatible = "xlnx,zynqmp-power";
@@ -163,6 +160,11 @@
mbox-names = "tx", "rx";
};
+ zynqmp_pcap: pcap {
+ compatible = "xlnx,zynqmp-pcap-fpga";
+ clock-names = "ref_clk";
+ };
+
zynqmp_reset: reset-controller {
compatible = "xlnx,zynqmp-reset";
#reset-cells = <1>;
@@ -206,26 +208,7 @@
};
};
- amba_apu: amba-apu@0 {
- compatible = "simple-bus";
- #address-cells = <2>;
- #size-cells = <1>;
- ranges = <0 0 0 0 0xffffffff>;
-
- gic: interrupt-controller@f9010000 {
- compatible = "arm,gic-400";
- #interrupt-cells = <3>;
- reg = <0x0 0xf9010000 0x10000>,
- <0x0 0xf9020000 0x20000>,
- <0x0 0xf9040000 0x20000>,
- <0x0 0xf9060000 0x20000>;
- interrupt-controller;
- interrupt-parent = <&gic>;
- interrupts = <1 9 0xf04>;
- };
- };
-
- amba: amba {
+ amba: axi {
compatible = "simple-bus";
u-boot,dm-pre-reloc;
#address-cells = <2>;
@@ -380,6 +363,18 @@
power-domains = <&zynqmp_firmware PD_GDMA>;
};
+ gic: interrupt-controller@f9010000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ reg = <0x0 0xf9010000 0x0 0x10000>,
+ <0x0 0xf9020000 0x0 0x20000>,
+ <0x0 0xf9040000 0x0 0x20000>,
+ <0x0 0xf9060000 0x0 0x20000>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <1 9 0xf04>;
+ };
+
gpu: gpu@fd4b0000 {
status = "disabled";
compatible = "arm,mali-400", "arm,mali-utgard";
@@ -590,7 +585,7 @@
};
i2c0: i2c@ff020000 {
- compatible = "cdns,i2c-r1p14", "cdns,i2c-r1p10";
+ compatible = "cdns,i2c-r1p14";
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 17 4>;
@@ -601,7 +596,7 @@
};
i2c1: i2c@ff030000 {
- compatible = "cdns,i2c-r1p14", "cdns,i2c-r1p10";
+ compatible = "cdns,i2c-r1p14";
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 18 4>;
@@ -639,8 +634,8 @@
<0x0 0xfd480000 0x0 0x1000>,
<0x80 0x00000000 0x0 0x1000000>;
reg-names = "breg", "pcireg", "cfg";
- ranges = <0x02000000 0x00000000 0xe0000000 0x00000000 0xe0000000 0x00000000 0x10000000 /* non-prefetchable memory */
- 0x43000000 0x00000006 0x00000000 0x00000006 0x00000000 0x00000002 0x00000000>;/* prefetchable memory */
+ ranges = <0x02000000 0x00000000 0xe0000000 0x00000000 0xe0000000 0x00000000 0x10000000>,/* non-prefetchable memory */
+ <0x43000000 0x00000006 0x00000000 0x00000006 0x00000000 0x00000002 0x00000000>;/* prefetchable memory */
bus-range = <0x00 0xff>;
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc 0x1>,
@@ -770,7 +765,7 @@
clock-output-names = "clk_out_sd1", "clk_in_sd1";
};
- smmu: smmu@fd800000 {
+ smmu: iommu@fd800000 {
compatible = "arm,mmu-500";
reg = <0x0 0xfd800000 0x0 0x20000>;
#iommu-cells = <1>;
diff --git a/board/xilinx/common/fru_ops.c b/board/xilinx/common/fru_ops.c
index b4cd3d49988..44f0913f2eb 100644
--- a/board/xilinx/common/fru_ops.c
+++ b/board/xilinx/common/fru_ops.c
@@ -170,7 +170,7 @@ static int fru_parse_board(unsigned long addr)
data = (u8 *)&fru_data.brd.manufacturer_type_len;
/* Record max structure limit not to write data over allocated space */
- limit = data + sizeof(struct fru_board_data);
+ limit = (u8 *)&fru_data.brd + sizeof(struct fru_board_data);
for (i = 0; ; i++, data += FRU_BOARD_MAX_LEN) {
len = fru_check_type_len(*(u8 *)addr, fru_data.brd.lang_code,
diff --git a/board/xilinx/microblaze-generic/MAINTAINERS b/board/xilinx/microblaze-generic/MAINTAINERS
index 6796d4d51ae..9a42a8b7401 100644
--- a/board/xilinx/microblaze-generic/MAINTAINERS
+++ b/board/xilinx/microblaze-generic/MAINTAINERS
@@ -1,6 +1,7 @@
MICROBLAZE-GENERIC BOARD
M: Michal Simek <monstr@monstr.eu>
S: Maintained
+T: git https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze.git
F: board/xilinx/microblaze-generic/
F: include/configs/microblaze-generic.h
F: configs/microblaze-generic_defconfig
diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c
index e5909997690..d4095c07c1e 100644
--- a/board/xilinx/microblaze-generic/microblaze-generic.c
+++ b/board/xilinx/microblaze-generic/microblaze-generic.c
@@ -67,7 +67,10 @@ int board_late_init(void)
status |= env_set_hex("ramdisk_addr_r",
gd->ram_base + SZ_32M + SZ_4M + SZ_2M);
-
+ if (IS_ENABLED(CONFIG_MTD_NOR_FLASH))
+ status |= env_set_hex("script_offset_nor",
+ gd->bd->bi_flashstart +
+ CONFIG_BOOT_SCRIPT_OFFSET);
if (status)
printf("%s: Saving run time variables FAILED\n", __func__);
diff --git a/board/xilinx/versal/MAINTAINERS b/board/xilinx/versal/MAINTAINERS
index 2d2b8082453..0d40196ade6 100644
--- a/board/xilinx/versal/MAINTAINERS
+++ b/board/xilinx/versal/MAINTAINERS
@@ -1,6 +1,7 @@
XILINX_VERSAL BOARDS
M: Michal Simek <michal.simek@xilinx.com>
S: Maintained
+T: git https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze.git
F: arch/arm/dts/versal*
F: board/xilinx/versal/
F: include/configs/xilinx_versal*
diff --git a/board/xilinx/zynq/MAINTAINERS b/board/xilinx/zynq/MAINTAINERS
index 78bcd84d30e..ce760ab02c3 100644
--- a/board/xilinx/zynq/MAINTAINERS
+++ b/board/xilinx/zynq/MAINTAINERS
@@ -1,6 +1,7 @@
ZYNQ BOARD
M: Michal Simek <monstr@monstr.eu>
S: Maintained
+T: git https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze.git
F: arch/arm/dts/zynq-*
F: board/xilinx/zynq/
F: include/configs/zynq*.h
diff --git a/board/xilinx/zynqmp/MAINTAINERS b/board/xilinx/zynqmp/MAINTAINERS
index 9cd4f3f53ef..a631b380bdd 100644
--- a/board/xilinx/zynqmp/MAINTAINERS
+++ b/board/xilinx/zynqmp/MAINTAINERS
@@ -1,6 +1,7 @@
XILINX_ZYNQMP BOARDS
M: Michal Simek <michal.simek@xilinx.com>
S: Maintained
+T: git https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze.git
F: arch/arm/dts/zynqmp-*
F: arch/arm/dts/avnet-ultra96*
F: board/xilinx/common/
diff --git a/cmd/load.c b/cmd/load.c
index 9a3a16979c7..c6a7cc46515 100644
--- a/cmd/load.c
+++ b/cmd/load.c
@@ -228,12 +228,11 @@ static int read_record(char *buf, ulong len)
*p = c;
}
- /* Check for the console hangup (if any different from serial) */
- if (gd->jt->getc != getchar) {
- if (ctrlc()) {
- return (-1);
+ /* Check for the console hangup (if any different from serial) */
+ if (gd->jt->getc != getchar) {
+ if (ctrlc())
+ return (-1);
}
- }
}
/* line too long - truncate */
diff --git a/common/usb_storage.c b/common/usb_storage.c
index 5d6f704fbcd..946c6b2b323 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -431,8 +431,8 @@ static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
return 0;
}
/* if our try counter reaches 0, bail out */
- debug(" %ld, data %d\n",
- us->pusb_dev->status, partial);
+ debug(" %ld, data %d\n",
+ us->pusb_dev->status, partial);
if (!maxtry--)
return result;
}
diff --git a/doc/device-tree-bindings/video/syncoam,seps525.txt b/doc/device-tree-bindings/video/syncoam,seps525.txt
new file mode 100644
index 00000000000..e1e0db9d71f
--- /dev/null
+++ b/doc/device-tree-bindings/video/syncoam,seps525.txt
@@ -0,0 +1,24 @@
+spi based seps525 framebuffer display driver
+
+Driver for seps525 display controller (in spi mode), This binding supports selection
+of spi chipselect, spi max frequency, gpio to drive dc and reset pin of seps525
+controller and spi transaction bit length.
+
+Required properties:
+- compatible: "syncoam,seps525"
+- reg: Specifies the chip-select the seps525 is connected to on the spi bus
+- reset-gpios: gpio connected to reset pin of seps525 controller.
+- dc-gpios: gpio connected to dc pin of seps525 controller:
+- buswidth: bitlength of each spi transaction
+
+Example:
+ displayspi@0 {
+ compatible = "syncoam,seps525";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+ spi-cpol;
+ spi-cpha;
+ buswidth = <8>;
+ reset-gpios = <&gpio 0x1c GPIO_ACTIVE_LOW>;
+ dc-gpios = <&gpio 0x1b GPIO_ACTIVE_HIGH>;
+ };
diff --git a/drivers/mtd/nand/raw/zynq_nand.c b/drivers/mtd/nand/raw/zynq_nand.c
index 15d4a238e6f..d7925283706 100644
--- a/drivers/mtd/nand/raw/zynq_nand.c
+++ b/drivers/mtd/nand/raw/zynq_nand.c
@@ -1206,12 +1206,10 @@ static int zynq_nand_probe(struct udevice *dev)
nand_chip->options |= NAND_SUBPAGE_READ;
/* On-Die ECC spare bytes offset 8 is used for ECC codes */
- if (ondie_ecc_enabled) {
- nand_chip->ecc.layout = &ondie_nand_oob_64;
- /* Use the BBT pattern descriptors */
- nand_chip->bbt_td = &bbt_main_descr;
- nand_chip->bbt_md = &bbt_mirror_descr;
- }
+ nand_chip->ecc.layout = &ondie_nand_oob_64;
+ /* Use the BBT pattern descriptors */
+ nand_chip->bbt_td = &bbt_main_descr;
+ nand_chip->bbt_md = &bbt_mirror_descr;
} else {
/* Hardware ECC generates 3 bytes ECC code for each 512 bytes */
nand_chip->ecc.mode = NAND_ECC_HW;
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c
index 0efdc93c608..9780a44d09e 100644
--- a/drivers/serial/serial_xuartlite.c
+++ b/drivers/serial/serial_xuartlite.c
@@ -148,7 +148,7 @@ static inline void _debug_uart_init(void)
uart_out32(&regs->control, 0);
uart_out32(&regs->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX);
- uart_in32(&regs->status);
+ ret = uart_in32(&regs->status);
/* Endianness detection */
if ((ret & SR_TX_FIFO_EMPTY) != SR_TX_FIFO_EMPTY) {
little_endian = true;
diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index c9e476eefac..efcbd0557fb 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -429,10 +429,8 @@ static int zynqmp_qspi_fill_tx_fifo(struct zynqmp_qspi_priv *priv, u32 size)
data |= GENMASK(31, 16);
break;
case 3:
- data = *((u16 *)buf);
- buf += 2;
- data |= (*((u8 *)buf) << 16);
- buf += 1;
+ data = *buf;
+ buf += 3;
data |= GENMASK(31, 24);
break;
}
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 998271b9b62..71363409f04 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -652,6 +652,13 @@ config VIDEO_NX
HDMI. This option enables this support which can be used on devices
which have an eDP display connected.
+config VIDEO_SEPS525
+ bool "Enable video support for Seps525"
+ depends on DM_VIDEO
+ help
+ Enable support for the Syncoam PM-OLED display driver (RGB 160x128).
+ Currently driver is supporting only SPI interface.
+
source "drivers/video/nexell/Kconfig"
config VIDEO
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 67a492a2d60..9db96aa891a 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_VIDEO_SIMPLE) += simplefb.o
obj-$(CONFIG_VIDEO_TEGRA20) += tegra.o
obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
obj-$(CONFIG_VIDEO_VESA) += vesa.o
+obj-$(CONFIG_VIDEO_SEPS525) += seps525.o
obj-y += bridge/
obj-y += sunxi/
diff --git a/drivers/video/seps525.c b/drivers/video/seps525.c
new file mode 100644
index 00000000000..369e5e6afc8
--- /dev/null
+++ b/drivers/video/seps525.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * FB driver for the WiseChip Semiconductor Inc. (UG-6028GDEBF02) display
+ * using the SEPS525 (Syncoam) LCD Controller
+ *
+ * Copyright (C) 2020 Xilinx Inc.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cpu_func.h>
+#include <dm.h>
+#include <errno.h>
+#include <spi.h>
+#include <video.h>
+#include <asm/gpio.h>
+#include <dm/device_compat.h>
+#include <linux/delay.h>
+
+#define WIDTH 160
+#define HEIGHT 128
+
+#define SEPS525_INDEX 0x00
+#define SEPS525_STATUS_RD 0x01
+#define SEPS525_OSC_CTL 0x02
+#define SEPS525_IREF 0x80
+#define SEPS525_CLOCK_DIV 0x03
+#define SEPS525_REDUCE_CURRENT 0x04
+#define SEPS525_SOFT_RST 0x05
+#define SEPS525_DISP_ONOFF 0x06
+#define SEPS525_PRECHARGE_TIME_R 0x08
+#define SEPS525_PRECHARGE_TIME_G 0x09
+#define SEPS525_PRECHARGE_TIME_B 0x0A
+#define SEPS525_PRECHARGE_CURRENT_R 0x0B
+#define SEPS525_PRECHARGE_CURRENT_G 0x0C
+#define SEPS525_PRECHARGE_CURRENT_B 0x0D
+#define SEPS525_DRIVING_CURRENT_R 0x10
+#define SEPS525_DRIVING_CURRENT_G 0x11
+#define SEPS525_DRIVING_CURRENT_B 0x12
+#define SEPS525_DISPLAYMODE_SET 0x13
+#define SEPS525_RGBIF 0x14
+#define SEPS525_RGB_POL 0x15
+#define SEPS525_MEMORY_WRITEMODE 0x16
+#define SEPS525_MX1_ADDR 0x17
+#define SEPS525_MX2_ADDR 0x18
+#define SEPS525_MY1_ADDR 0x19
+#define SEPS525_MY2_ADDR 0x1A
+#define SEPS525_MEMORY_ACCESS_POINTER_X 0x20
+#define SEPS525_MEMORY_ACCESS_POINTER_Y 0x21
+#define SEPS525_DDRAM_DATA_ACCESS_PORT 0x22
+#define SEPS525_GRAY_SCALE_TABLE_INDEX 0x50
+#define SEPS525_GRAY_SCALE_TABLE_DATA 0x51
+#define SEPS525_DUTY 0x28
+#define SEPS525_DSL 0x29
+#define SEPS525_D1_DDRAM_FAC 0x2E
+#define SEPS525_D1_DDRAM_FAR 0x2F
+#define SEPS525_D2_DDRAM_SAC 0x31
+#define SEPS525_D2_DDRAM_SAR 0x32
+#define SEPS525_SCR1_FX1 0x33
+#define SEPS525_SCR1_FX2 0x34
+#define SEPS525_SCR1_FY1 0x35
+#define SEPS525_SCR1_FY2 0x36
+#define SEPS525_SCR2_SX1 0x37
+#define SEPS525_SCR2_SX2 0x38
+#define SEPS525_SCR2_SY1 0x39
+#define SEPS525_SCR2_SY2 0x3A
+#define SEPS525_SCREEN_SAVER_CONTEROL 0x3B
+#define SEPS525_SS_SLEEP_TIMER 0x3C
+#define SEPS525_SCREEN_SAVER_MODE 0x3D
+#define SEPS525_SS_SCR1_FU 0x3E
+#define SEPS525_SS_SCR1_MXY 0x3F
+#define SEPS525_SS_SCR2_FU 0x40
+#define SEPS525_SS_SCR2_MXY 0x41
+#define SEPS525_MOVING_DIRECTION 0x42
+#define SEPS525_SS_SCR2_SX1 0x47
+#define SEPS525_SS_SCR2_SX2 0x48
+#define SEPS525_SS_SCR2_SY1 0x49
+#define SEPS525_SS_SCR2_SY2 0x4A
+
+/* SEPS525_DISPLAYMODE_SET */
+#define MODE_SWAP_BGR BIT(7)
+#define MODE_SM BIT(6)
+#define MODE_RD BIT(5)
+#define MODE_CD BIT(4)
+
+/**
+ * struct seps525_priv - Private structure
+ * @reset_gpio: Reset gpio pin
+ * @dc_gpio: Data/command control gpio pin
+ * @dev: Device uclass for video_ops
+ */
+struct seps525_priv {
+ struct gpio_desc reset_gpio;
+ struct gpio_desc dc_gpio;
+ struct udevice *dev;
+};
+
+static int seps525_spi_write_cmd(struct udevice *dev, u32 reg)
+{
+ struct seps525_priv *priv = dev_get_priv(dev);
+ u8 buf8 = reg;
+ int ret;
+
+ ret = dm_gpio_set_value(&priv->dc_gpio, 0);
+ if (ret) {
+ dev_dbg(dev, "Failed to handle dc\n");
+ return ret;
+ }
+
+ ret = dm_spi_xfer(dev, 8, &buf8, NULL, SPI_XFER_BEGIN | SPI_XFER_END);
+ if (ret)
+ dev_dbg(dev, "Failed to write command\n");
+
+ return ret;
+}
+
+static int seps525_spi_write_data(struct udevice *dev, u32 val)
+{
+ struct seps525_priv *priv = dev_get_priv(dev);
+ u8 buf8 = val;
+ int ret;
+
+ ret = dm_gpio_set_value(&priv->dc_gpio, 1);
+ if (ret) {
+ dev_dbg(dev, "Failed to handle dc\n");
+ return ret;
+ }
+
+ ret = dm_spi_xfer(dev, 8, &buf8, NULL, SPI_XFER_BEGIN | SPI_XFER_END);
+ if (ret)
+ dev_dbg(dev, "Failed to write data\n");
+
+ return ret;
+}
+
+static void seps525_spi_write(struct udevice *dev, u32 reg, u32 val)
+{
+ (void)seps525_spi_write_cmd(dev, reg);
+ (void)seps525_spi_write_data(dev, val);
+}
+
+static int seps525_display_init(struct udevice *dev)
+{
+ /* Disable Oscillator Power Down */
+ seps525_spi_write(dev, SEPS525_REDUCE_CURRENT, 0x03);
+ mdelay(5);
+
+ /* Set Normal Driving Current */
+ seps525_spi_write(dev, SEPS525_REDUCE_CURRENT, 0x00);
+ mdelay(5);
+
+ seps525_spi_write(dev, SEPS525_SCREEN_SAVER_CONTEROL, 0x00);
+ /* Set EXPORT1 Pin at Internal Clock */
+ seps525_spi_write(dev, SEPS525_OSC_CTL, 0x01);
+ /* Set Clock as 120 Frames/Sec */
+ seps525_spi_write(dev, SEPS525_CLOCK_DIV, 0x90);
+ /* Set Reference Voltage Controlled by External Resister */
+ seps525_spi_write(dev, SEPS525_IREF, 0x01);
+
+ /* precharge time R G B */
+ seps525_spi_write(dev, SEPS525_PRECHARGE_TIME_R, 0x04);
+ seps525_spi_write(dev, SEPS525_PRECHARGE_TIME_G, 0x05);
+ seps525_spi_write(dev, SEPS525_PRECHARGE_TIME_B, 0x05);
+
+ /* precharge current R G B (uA) */
+ seps525_spi_write(dev, SEPS525_PRECHARGE_CURRENT_R, 0x9D);
+ seps525_spi_write(dev, SEPS525_PRECHARGE_CURRENT_G, 0x8C);
+ seps525_spi_write(dev, SEPS525_PRECHARGE_CURRENT_B, 0x57);
+
+ /* driving current R G B (uA) */
+ seps525_spi_write(dev, SEPS525_DRIVING_CURRENT_R, 0x56);
+ seps525_spi_write(dev, SEPS525_DRIVING_CURRENT_G, 0x4D);
+ seps525_spi_write(dev, SEPS525_DRIVING_CURRENT_B, 0x46);
+ /* Set Color Sequence */
+ seps525_spi_write(dev, SEPS525_DISPLAYMODE_SET, 0x00);
+ /* Set MCU Interface Mode */
+ seps525_spi_write(dev, SEPS525_RGBIF, 0x01);
+ /* Set Memory Write Mode */
+ seps525_spi_write(dev, SEPS525_MEMORY_WRITEMODE, 0x66);
+ /* 1/128 Duty (0x0F~0x7F) */
+ seps525_spi_write(dev, SEPS525_DUTY, 0x7F);
+ /* Set Mapping RAM Display Start Line (0x00~0x7F) */
+ seps525_spi_write(dev, SEPS525_DSL, 0x00);
+ /* Display On (0x00/0x01) */
+ seps525_spi_write(dev, SEPS525_DISP_ONOFF, 0x01);
+ /* Set All Internal Register Value as Normal Mode */
+ seps525_spi_write(dev, SEPS525_SOFT_RST, 0x00);
+ /* Set RGB Interface Polarity as Active Low */
+ seps525_spi_write(dev, SEPS525_RGB_POL, 0x00);
+
+ /* Enable access for data */
+ (void)seps525_spi_write_cmd(dev, SEPS525_DDRAM_DATA_ACCESS_PORT);
+
+ return 0;
+}
+
+static int seps525_spi_startup(struct udevice *dev)
+{
+ struct seps525_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = dm_gpio_set_value(&priv->reset_gpio, 1);
+ if (ret)
+ return ret;
+
+ ret = dm_gpio_set_value(&priv->reset_gpio, 0);
+ if (ret)
+ return ret;
+
+ ret = dm_spi_claim_bus(dev);
+ if (ret) {
+ dev_err(dev, "Failed to claim SPI bus: %d\n", ret);
+ return ret;
+ }
+
+ ret = seps525_display_init(dev);
+ if (ret)
+ return ret;
+
+ dm_spi_release_bus(dev);
+
+ return 0;
+}
+
+static int seps525_sync(struct udevice *vid)
+{
+ struct video_priv *uc_priv = dev_get_uclass_priv(vid);
+ struct seps525_priv *priv = dev_get_priv(vid);
+ struct udevice *dev = priv->dev;
+ int i, ret;
+ u8 data1, data2;
+ u8 *start = uc_priv->fb;
+
+ ret = dm_spi_claim_bus(dev);
+ if (ret) {
+ dev_err(dev, "Failed to claim SPI bus: %d\n", ret);
+ return ret;
+ }
+
+ /* start position X,Y */
+ seps525_spi_write(dev, SEPS525_MEMORY_ACCESS_POINTER_X, 0);
+ seps525_spi_write(dev, SEPS525_MEMORY_ACCESS_POINTER_Y, 0);
+
+ /* Enable access for data */
+ (void)seps525_spi_write_cmd(dev, SEPS525_DDRAM_DATA_ACCESS_PORT);
+
+ for (i = 0; i < (uc_priv->xsize * uc_priv->ysize); i++) {
+ data2 = *start++;
+ data1 = *start++;
+ (void)seps525_spi_write_data(dev, data1);
+ (void)seps525_spi_write_data(dev, data2);
+ }
+
+ dm_spi_release_bus(dev);
+
+ return 0;
+}
+
+static int seps525_probe(struct udevice *dev)
+{
+ struct video_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct seps525_priv *priv = dev_get_priv(dev);
+ u32 buswidth;
+ int ret;
+
+ buswidth = dev_read_u32_default(dev, "buswidth", 0);
+ if (buswidth != 8) {
+ dev_err(dev, "Only 8bit buswidth is supported now");
+ return -EINVAL;
+ }
+
+ ret = gpio_request_by_name(dev, "reset-gpios", 0,
+ &priv->reset_gpio, GPIOD_IS_OUT);
+ if (ret) {
+ dev_err(dev, "missing reset GPIO\n");
+ return ret;
+ }
+
+ ret = gpio_request_by_name(dev, "dc-gpios", 0,
+ &priv->dc_gpio, GPIOD_IS_OUT);
+ if (ret) {
+ dev_err(dev, "missing dc GPIO\n");
+ return ret;
+ }
+
+ uc_priv->bpix = VIDEO_BPP16;
+ uc_priv->xsize = WIDTH;
+ uc_priv->ysize = HEIGHT;
+ uc_priv->rot = 0;
+
+ priv->dev = dev;
+
+ ret = seps525_spi_startup(dev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int seps525_bind(struct udevice *dev)
+{
+ struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+
+ plat->size = WIDTH * HEIGHT * 16;
+
+ return 0;
+}
+
+static const struct video_ops seps525_ops = {
+ .video_sync = seps525_sync,
+};
+
+static const struct udevice_id seps525_ids[] = {
+ { .compatible = "syncoam,seps525" },
+ { }
+};
+
+U_BOOT_DRIVER(seps525_video) = {
+ .name = "seps525_video",
+ .id = UCLASS_VIDEO,
+ .of_match = seps525_ids,
+ .ops = &seps525_ops,
+ .platdata_auto_alloc_size = sizeof(struct video_uc_platdata),
+ .bind = seps525_bind,
+ .probe = seps525_probe,
+ .priv_auto_alloc_size = sizeof(struct seps525_priv),
+};
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index ceb4744354a..81b65f5aaee 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -89,9 +89,7 @@ static int vidconsole_back(struct udevice *dev)
if (priv->ycur < 0)
priv->ycur = 0;
}
- video_sync(dev->parent, false);
-
- return 0;
+ return video_sync(dev->parent, false);
}
/* Move to a newline, scrolling the display if necessary */
@@ -101,7 +99,7 @@ static void vidconsole_newline(struct udevice *dev)
struct udevice *vid_dev = dev->parent;
struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
const int rows = CONFIG_CONSOLE_SCROLL_LINES;
- int i;
+ int i, ret;
priv->xcur_frac = priv->xstart_frac;
priv->ycur += priv->y_charsize;
@@ -116,7 +114,12 @@ static void vidconsole_newline(struct udevice *dev)
}
priv->last_ch = 0;
- video_sync(dev->parent, false);
+ ret = video_sync(dev->parent, false);
+ if (ret) {
+#ifdef DEBUG
+ console_puts_select_stderr(true, "[vc err: video_sync]");
+#endif
+ }
}
static const struct vid_rgb colors[VID_COLOR_COUNT] = {
@@ -348,8 +351,15 @@ static void vidconsole_escape_char(struct udevice *dev, char ch)
parsenum(priv->escape_buf + 1, &mode);
if (mode == 2) {
+ int ret;
+
video_clear(dev->parent);
- video_sync(dev->parent, false);
+ ret = video_sync(dev->parent, false);
+ if (ret) {
+#ifdef DEBUG
+ console_puts_select_stderr(true, "[vc err: video_sync]");
+#endif
+ }
priv->ycur = 0;
priv->xcur_frac = priv->xstart_frac;
} else {
@@ -565,7 +575,12 @@ static void vidconsole_putc(struct stdio_dev *sdev, const char ch)
console_puts_select_stderr(true, "[vc err: putc]");
#endif
}
- video_sync(dev->parent, false);
+ ret = video_sync(dev->parent, false);
+ if (ret) {
+#ifdef DEBUG
+ console_puts_select_stderr(true, "[vc err: video_sync]");
+#endif
+ }
}
static void vidconsole_puts(struct stdio_dev *sdev, const char *s)
@@ -582,7 +597,12 @@ static void vidconsole_puts(struct stdio_dev *sdev, const char *s)
console_puts_select_stderr(true, str);
#endif
}
- video_sync(dev->parent, false);
+ ret = video_sync(dev->parent, false);
+ if (ret) {
+#ifdef DEBUG
+ console_puts_select_stderr(true, "[vc err: video_sync]");
+#endif
+ }
}
/* Set up the number of rows and colours (rotated drivers override this) */
@@ -691,9 +711,7 @@ static int do_video_puts(struct cmd_tbl *cmdtp, int flag, int argc,
for (s = argv[1]; *s; s++)
vidconsole_put_char(dev, *s);
- video_sync(dev->parent, false);
-
- return 0;
+ return video_sync(dev->parent, false);
}
U_BOOT_CMD(
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index 8883e290357..a1d527529ff 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -15,6 +15,7 @@
#include <video_console.h>
#include <asm/cache.h>
#include <dm/lists.h>
+#include <dm/device_compat.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
#ifdef CONFIG_SANDBOX
@@ -142,7 +143,7 @@ int video_clear(struct udevice *dev)
if (ret)
return ret;
- return 0;
+ return video_sync(dev, false);
}
void video_set_default_colors(struct udevice *dev, bool invert)
@@ -172,8 +173,17 @@ void video_set_default_colors(struct udevice *dev, bool invert)
}
/* Flush video activity to the caches */
-void video_sync(struct udevice *vid, bool force)
+int video_sync(struct udevice *vid, bool force)
{
+ struct video_ops *ops = video_get_ops(vid);
+ int ret;
+
+ if (ops && ops->video_sync) {
+ ret = ops->video_sync(vid);
+ if (ret)
+ return ret;
+ }
+
/*
* flush_dcache_range() is declared in common.h but it seems that some
* architectures do not actually implement it. Is there a way to find
@@ -196,17 +206,22 @@ void video_sync(struct udevice *vid, bool force)
last_sync = get_timer(0);
}
#endif
+ return 0;
}
void video_sync_all(void)
{
struct udevice *dev;
+ int ret;
for (uclass_find_first_device(UCLASS_VIDEO, &dev);
dev;
uclass_find_next_device(&dev)) {
- if (device_active(dev))
- video_sync(dev, true);
+ if (device_active(dev)) {
+ ret = video_sync(dev, true);
+ if (ret)
+ dev_dbg(dev, "Video sync failed\n");
+ }
}
}
diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c
index 5a4d12c68d4..66de22318f2 100644
--- a/drivers/video/video_bmp.c
+++ b/drivers/video/video_bmp.c
@@ -379,8 +379,5 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
if (ret)
return log_ret(ret);
- video_sync(dev, false);
-
- return 0;
+ return video_sync(dev, false);
}
-
diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h
index bc0bf049737..59b20cf116a 100644
--- a/include/configs/microblaze-generic.h
+++ b/include/configs/microblaze-generic.h
@@ -81,6 +81,20 @@
# define BOOT_TARGET_DEVICES_QSPI(func)
#endif
+#if defined(CONFIG_MTD_NOR_FLASH)
+# define BOOT_TARGET_DEVICES_NOR(func) func(NOR, nor, na)
+#else
+# define BOOT_TARGET_DEVICES_NOR(func)
+#endif
+
+#define BOOTENV_DEV_NOR(devtypeu, devtypel, instance) \
+ "bootcmd_nor=cp.b ${script_offset_nor} ${scriptaddr} ${script_size_f} && " \
+ "echo NOR: Trying to boot script at ${scriptaddr} && " \
+ "source ${scriptaddr}; echo NOR: SCRIPT FAILED: continuing...;\0"
+
+#define BOOTENV_DEV_NAME_NOR(devtypeu, devtypel, instance) \
+ "nor "
+
#define BOOTENV_DEV_QSPI(devtypeu, devtypel, instance) \
"bootcmd_qspi=sf probe 0 0 0 && " \
"sf read ${scriptaddr} ${script_offset_f} ${script_size_f} && " \
@@ -101,7 +115,8 @@
#define BOOT_TARGET_DEVICES(func) \
BOOT_TARGET_DEVICES_JTAG(func) \
- BOOT_TARGET_DEVICES_QSPI(func) \
+ BOOT_TARGET_DEVICES_QSPI(func) \
+ BOOT_TARGET_DEVICES_NOR(func) \
BOOT_TARGET_DEVICES_DHCP(func) \
BOOT_TARGET_DEVICES_PXE(func)
diff --git a/include/video.h b/include/video.h
index 7b7f62a8277..74d822fadbb 100644
--- a/include/video.h
+++ b/include/video.h
@@ -114,8 +114,16 @@ struct video_priv {
u8 bg_col_idx;
};
-/* Placeholder - there are no video operations at present */
+/**
+ * struct video_ops - structure for keeping video operations
+ * @video_sync: Synchronize FB with device. Some device like SPI based LCD
+ * displays needs synchronization when data in an FB is available.
+ * For these devices implement video_sync hook to call a sync
+ * function. vid is pointer to video device udevice. Function
+ * should return 0 on success video_sync and error code otherwise
+ */
struct video_ops {
+ int (*video_sync)(struct udevice *vid);
};
#define video_get_ops(dev) ((struct video_ops *)(dev)->driver->ops)
@@ -151,15 +159,17 @@ int video_clear(struct udevice *dev);
/**
* video_sync() - Sync a device's frame buffer with its hardware
*
+ * @vid: Device to sync
+ * @force: True to force a sync even if there was one recently (this is
+ * very expensive on sandbox)
+ *
+ * @return: 0 on success, error code otherwise
+ *
* Some frame buffers are cached or have a secondary frame buffer. This
* function syncs these up so that the current contents of the U-Boot frame
* buffer are displayed to the user.
- *
- * @dev: Device to sync
- * @force: True to force a sync even if there was one recently (this is
- * very expensive on sandbox)
*/
-void video_sync(struct udevice *vid, bool force);
+int video_sync(struct udevice *vid, bool force);
/**
* video_sync_all() - Sync all devices' frame buffers with there hardware
diff --git a/tools/zynqmp_pm_cfg_obj_convert.py b/tools/zynqmp_pm_cfg_obj_convert.py
index dd27f479213..0a44710e1e1 100755
--- a/tools/zynqmp_pm_cfg_obj_convert.py
+++ b/tools/zynqmp_pm_cfg_obj_convert.py
@@ -289,7 +289,7 @@ code = in_file.read()
code = re.sub('//.*?\n|/\*.*?\*/', '', code, flags=re.DOTALL)
# remove everything outside the XPm_ConfigObject array definition
-code = re.search('const u32 XPm_ConfigObject.*= {\n(.*)};',
+code = re.search('const u32 XPm_ConfigObject.*=.*{\n(.*)};',
code, flags=re.DOTALL).group(1)
# Process each comma-separated array item