From d50e774ba4ff88696a32c38d37d02f3ce6b36b1b Mon Sep 17 00:00:00 2001
From: Henrik Grimler <henrik@grimler.se>
Date: Sun, 19 Dec 2021 12:28:43 +0100
Subject: [PATCH] odroid-xu4: add device

Similar hardware to odroid-hc2.  Use new linux-postmarketos-exynos5
package for kernel.
---
 device/testing/device-odroid-xu4/APKBUILD     |  50 ++
 device/testing/device-odroid-xu4/deviceinfo   |  29 ++
 .../device-odroid-xu4/uboot-script.cmd        |  26 ++
 device/testing/firmware-odroid-xu4/APKBUILD   |  33 ++
 ...u-drm-Add-Hardkernel-3.2-LCD-driver-.patch |  34 ++
 ...u-drm-Add-new-Tiny-DRM-driver-with-I.patch | 426 ++++++++++++++++++
 ...mon-pwm-fan-fix-to-add-pwm1_enable-t.patch | 141 ++++++
 ...u-drm-add-new-display-resolution-256.patch |  77 ++++
 ...vert-drm-dbi-Print-errors-for-mipi_d.patch |  32 ++
 ...N-add-symbol-to-device-tree-compiler.patch |  30 ++
 ...y-realtek-add-Wake-on-Lan-to-Realtek.patch | 107 +++++
 ...machine-description-for-ODROID-XU3-4.patch |  52 +++
 main/linux-postmarketos-exynos5/APKBUILD      |  16 +
 13 files changed, 1053 insertions(+)
 create mode 100644 device/testing/device-odroid-xu4/APKBUILD
 create mode 100644 device/testing/device-odroid-xu4/deviceinfo
 create mode 100644 device/testing/device-odroid-xu4/uboot-script.cmd
 create mode 100644 device/testing/firmware-odroid-xu4/APKBUILD
 create mode 100644 main/linux-postmarketos-exynos5/0001-ODROID-COMMON-gpu-drm-Add-Hardkernel-3.2-LCD-driver-.patch
 create mode 100644 main/linux-postmarketos-exynos5/0002-ODROID-COMMON-gpu-drm-Add-new-Tiny-DRM-driver-with-I.patch
 create mode 100644 main/linux-postmarketos-exynos5/0003-ODROID-COMMON-hwmon-pwm-fan-fix-to-add-pwm1_enable-t.patch
 create mode 100644 main/linux-postmarketos-exynos5/0004-ODROID-COMMON-gpu-drm-add-new-display-resolution-256.patch
 create mode 100644 main/linux-postmarketos-exynos5/0005-ODROID-COMMON-Revert-drm-dbi-Print-errors-for-mipi_d.patch
 create mode 100644 main/linux-postmarketos-exynos5/0006-ODROID-COMMON-add-symbol-to-device-tree-compiler.patch
 create mode 100644 main/linux-postmarketos-exynos5/0007-ODROID-COMMON-phy-realtek-add-Wake-on-Lan-to-Realtek.patch
 create mode 100644 main/linux-postmarketos-exynos5/0008-ARM-exynos-add-machine-description-for-ODROID-XU3-4.patch

diff --git a/device/testing/device-odroid-xu4/APKBUILD b/device/testing/device-odroid-xu4/APKBUILD
new file mode 100644
index 00000000000..ac6ddb7fa33
--- /dev/null
+++ b/device/testing/device-odroid-xu4/APKBUILD
@@ -0,0 +1,50 @@
+# Reference: <https://postmarketos.org/devicepkg>
+# Maintainer: Henrik Grimler <henrik@grimler.se>
+
+pkgname=device-odroid-xu4
+pkgdesc="ODROID XU4"
+pkgver=0.1
+pkgrel=0
+url="https://postmarketos.org"
+license="MIT"
+arch="armv7"
+options="!check !archcheck"
+depends="linux-postmarketos-exynos5
+	 postmarketos-base
+	 u-boot-odroid
+	 u-boot-tools
+	"
+makedepends="devicepkg-dev"
+subpackages="$pkgname-nonfree-firmware:nonfree_firmware"
+source="deviceinfo uboot-script.cmd"
+
+build() {
+	devicepkg_build $startdir $pkgname
+	mkimage \
+		-A arm \
+		-O linux \
+		-T script \
+		-C none \
+		-a 0 \
+		-e 0 \
+		-n postmarketos \
+		-d "$srcdir"/uboot-script.cmd \
+		"$srcdir"/boot.scr
+}
+
+package() {
+	devicepkg_package $startdir $pkgname
+	install -Dm644 "$srcdir"/boot.scr \
+		"$pkgdir"/boot/boot.scr
+}
+
+nonfree_firmware() {
+	pkgdesc="Early bootloaders and trustzone firmware (required for a bootable system) and Realtek firmware"
+	depends="firmware-odroid-xu4 linux-firmware-rtl_nic"
+	mkdir "$subpkgdir"
+}
+
+sha512sums="
+1b88d1c643cca0499c4a0b0cc5645a1b2dd539d59dad7a9ba533e03726e031b061f3e43a981e7084b2b3ef6839b2f44864bef98632552721595b9e977ed84cd6  deviceinfo
+d6001fde71fb393ddf74838a7c2a29635a540f9f466ba8dfdea0fd053bbe99ffa491cb05a0b510f58ca31c80d8483387b1d019e905ff09b9f44a1033fcda7705  uboot-script.cmd
+"
diff --git a/device/testing/device-odroid-xu4/deviceinfo b/device/testing/device-odroid-xu4/deviceinfo
new file mode 100644
index 00000000000..9d89ea15dcc
--- /dev/null
+++ b/device/testing/device-odroid-xu4/deviceinfo
@@ -0,0 +1,29 @@
+# Reference: <https://postmarketos.org/deviceinfo>
+# Please use double quotes only. You can source this file in shell
+# scripts.
+
+deviceinfo_format_version="0"
+deviceinfo_name="Odroid XU4"
+deviceinfo_manufacturer="Odroid"
+deviceinfo_codename="odroid-xu4"
+deviceinfo_year="2015"
+deviceinfo_dtb="exynos5422-odroidxu4"
+deviceinfo_append_dtb="false"
+deviceinfo_arch="armv7"
+deviceinfo_no_framebuffer="true"
+deviceinfo_generate_legacy_uboot_initfs="true"
+deviceinfo_getty="ttySAC2;115200"
+deviceinfo_disable_dhcpd="true"
+deviceinfo_modules_initfs="uas usb-storage scsi_mod sd_mod t10_pi"
+
+# Device related
+deviceinfo_gpu_accelerated="true"
+deviceinfo_chassis="embedded"
+deviceinfo_keyboard="false"
+deviceinfo_external_storage="true"
+
+# Bootloader related
+deviceinfo_flash_method="none"
+deviceinfo_sd_embed_firmware="u-boot/odroid-xu3/bl1.bin:1,u-boot/odroid-xu3/bl2.bin:31,u-boot/odroid-xu3/u-boot.bin:63,u-boot/odroid-xu3/tzsw.bin:2111"
+deviceinfo_sd_embed_firmware_step_size=512
+deviceinfo_boot_part_start=3072
diff --git a/device/testing/device-odroid-xu4/uboot-script.cmd b/device/testing/device-odroid-xu4/uboot-script.cmd
new file mode 100644
index 00000000000..9f180dc550a
--- /dev/null
+++ b/device/testing/device-odroid-xu4/uboot-script.cmd
@@ -0,0 +1,26 @@
+setenv kernel_addr_r "0x40000000"
+setenv initrd_addr_r "0x42000000"
+setenv fdt_addr_r "0x44000000"
+setenv kernel_image "vmlinuz"
+setenv initrd_image "uInitrd"
+setenv dtb_file "exynos5422-odroidxu4.dtb"
+
+printenv
+
+echo Setting bootargs
+setenv bootargs init=/init.sh rw console=tty0 console=ttySAC2,115200 panic=10 consoleblank=0 loglevel=9 cma=256M PMOS_NO_OUTPUT_REDIRECT PMOS_FORCE_PARTITION_RESIZE
+
+echo Loading Kernel
+load mmc ${mmcbootdev}:${mmcbootpart} ${kernel_addr_r} ${kernel_image}
+
+echo Loading Initramfs
+load mmc ${mmcbootdev}:${mmcbootpart} ${initrd_addr_r} ${initrd_image}
+
+echo Loading DTB
+load mmc ${mmcbootdev}:${mmcbootpart} ${fdt_addr_r} ${dtb_file}
+
+echo Resizing FDT
+fdt addr ${fdt_addr_r}
+
+echo Booting kernel
+bootz ${kernel_addr_r} ${initrd_addr_r} ${fdt_addr_r}
diff --git a/device/testing/firmware-odroid-xu4/APKBUILD b/device/testing/firmware-odroid-xu4/APKBUILD
new file mode 100644
index 00000000000..0624854c106
--- /dev/null
+++ b/device/testing/firmware-odroid-xu4/APKBUILD
@@ -0,0 +1,33 @@
+# Maintainer: Henrik Grimler <henrik@grimler.se>
+
+pkgname=firmware-odroid-xu4
+pkgver=2020.01
+pkgrel=0
+pkgdesc="Firmware for ODROID XU4"
+url="https://github.com/hardkernel/u-boot"
+arch="armv7"
+license="proprietary"
+options="!check !strip !archcheck !tracedeps pmb:cross-native"
+source="xu4-bl1.bin.hardkernel::https://github.com/hardkernel/u-boot/raw/u-boot_v$pkgver/board/hardkernel/odroid-xu3/bl1.bin.hardkernel
+	xu4-bl2.bin.hardkernel::https://github.com/hardkernel/u-boot/raw/u-boot_v$pkgver/board/hardkernel/odroid-xu3/bl2.bin.hardkernel.1mb_uboot
+	xu4-tzsw.bin.hardkernel::https://github.com/hardkernel/u-boot/raw/u-boot_v$pkgver/board/hardkernel/odroid-xu3/tzsw.bin.hardkernel
+	"
+
+package() {
+	# Trim bl1.bin.hardkernel to 15360 bytes
+	# See https://forum.odroid.com/viewtopic.php?f=93&t=42724
+	truncate -s15360 "$srcdir"/bl1.bin.hardkernel
+
+	# Install firmware
+	install -D -m644 "$srcdir"/xu4-bl1.bin.hardkernel \
+		"$pkgdir"/usr/share/u-boot/odroid-xu3/bl1.bin
+	install -D -m644 "$srcdir"/xu4-bl2.bin.hardkernel \
+		"$pkgdir"/usr/share/u-boot/odroid-xu3/bl2.bin
+	install -D -m644 "$srcdir"/xu4-tzsw.bin.hardkernel \
+		"$pkgdir"/usr/share/u-boot/odroid-xu3/tzsw.bin
+}
+sha512sums="
+0291c6959990b14ef8af300256fed73ed911970b2df51ceb5b36d5900ae321d9dbe0cb02a7bf8098d08dd4192b3c582570491255d3f1dc113bce575d5f0260a5  bl1.bin.hardkernel
+cc9951cdd8b4e11d244a8b4a3d8d287759b7faddcea462ddb94cc05249afe456bb67791641eeca70580264af044dac92987a8f8309ff10ad2cd9f406cedfd6cb  bl2.bin.hardkernel
+434f6b479ead6b5d25877bb615df4281f95d1637d4171354f4bf324f8a1d7df3855e0a696aa204285c3298b45bf7d1e0ad4c27a88bc705f4cff1f082754f444f  tzsw.bin.hardkernel
+"
diff --git a/main/linux-postmarketos-exynos5/0001-ODROID-COMMON-gpu-drm-Add-Hardkernel-3.2-LCD-driver-.patch b/main/linux-postmarketos-exynos5/0001-ODROID-COMMON-gpu-drm-Add-Hardkernel-3.2-LCD-driver-.patch
new file mode 100644
index 00000000000..7b845af10f5
--- /dev/null
+++ b/main/linux-postmarketos-exynos5/0001-ODROID-COMMON-gpu-drm-Add-Hardkernel-3.2-LCD-driver-.patch
@@ -0,0 +1,34 @@
+From c9bf2897793c8ee7d5845e23e072acd646f40300 Mon Sep 17 00:00:00 2001
+From: Dongjin Kim <tobetter@gmail.com>
+Date: Wed, 10 Feb 2021 06:11:09 +0000
+Subject: [PATCH 01/16] ODROID-COMMON: gpu/drm: Add Hardkernel 3.2" LCD driver
+ to ili9341 driver
+
+Signed-off-by: Dongjin Kim <tobetter@gmail.com>
+Change-Id: I890f0369126eda88ef16723efec828cd85d25b53
+---
+ drivers/gpu/drm/tiny/ili9341.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/tiny/ili9341.c b/drivers/gpu/drm/tiny/ili9341.c
+index 37e0c33399c8..96f0d67b1702 100644
+--- a/drivers/gpu/drm/tiny/ili9341.c
++++ b/drivers/gpu/drm/tiny/ili9341.c
+@@ -162,12 +162,14 @@ static const struct drm_driver ili9341_driver = {
+ 
+ static const struct of_device_id ili9341_of_match[] = {
+ 	{ .compatible = "adafruit,yx240qv29" },
++	{ .compatible = "hardkernel,hktft32" },
+ 	{ }
+ };
+ MODULE_DEVICE_TABLE(of, ili9341_of_match);
+ 
+ static const struct spi_device_id ili9341_id[] = {
+ 	{ "yx240qv29", 0 },
++	{ "hktft32", 0 },
+ 	{ }
+ };
+ MODULE_DEVICE_TABLE(spi, ili9341_id);
+-- 
+2.34.1
+
diff --git a/main/linux-postmarketos-exynos5/0002-ODROID-COMMON-gpu-drm-Add-new-Tiny-DRM-driver-with-I.patch b/main/linux-postmarketos-exynos5/0002-ODROID-COMMON-gpu-drm-Add-new-Tiny-DRM-driver-with-I.patch
new file mode 100644
index 00000000000..fc2ffc8ffa0
--- /dev/null
+++ b/main/linux-postmarketos-exynos5/0002-ODROID-COMMON-gpu-drm-Add-new-Tiny-DRM-driver-with-I.patch
@@ -0,0 +1,426 @@
+From 520c4709aa45bed6ce4c97d0ee1fac4728c84efc Mon Sep 17 00:00:00 2001
+From: Dongjin Kim <tobetter@gmail.com>
+Date: Tue, 9 Feb 2021 13:27:41 +0900
+Subject: [PATCH 02/16] ODROID-COMMON: gpu/drm: Add new Tiny DRM driver with
+ Ili9488
+
+Signed-off-by: Dongjin Kim <tobetter@gmail.com>
+Change-Id: I6e4f783ab642cc735ef445d010afb1cd930757c6
+---
+ drivers/gpu/drm/tiny/Kconfig       |  13 +
+ drivers/gpu/drm/tiny/Makefile      |   1 +
+ drivers/gpu/drm/tiny/ili9488_pio.c | 366 +++++++++++++++++++++++++++++
+ 3 files changed, 380 insertions(+)
+ create mode 100644 drivers/gpu/drm/tiny/ili9488_pio.c
+
+diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig
+index 1ceb93fbdc50..11607c76ba26 100644
+--- a/drivers/gpu/drm/tiny/Kconfig
++++ b/drivers/gpu/drm/tiny/Kconfig
+@@ -119,6 +119,19 @@ config TINYDRM_ILI9486
+ 
+ 	  If M is selected the module will be called ili9486.
+ 
++config TINYDRM_ILI9488_PIO
++	tristate "DRM support for ILI9488 display panels (8bit PIO)"
++	depends on DRM
++	select DRM_KMS_HELPER
++	select DRM_KMS_CMA_HELPER
++	select DRM_MIPI_DBI
++	select BACKLIGHT_CLASS_DEVICE
++	help
++	  DRM driver for th following Ilitek ILI9488 panels:
++          * Hardkernel 3.5" 480x320 TFT (HKTFT 3.5")
++
++	  If M is selected the module will be called hktft35.
++
+ config TINYDRM_MI0283QT
+ 	tristate "DRM support for MI0283QT"
+ 	depends on DRM && SPI
+diff --git a/drivers/gpu/drm/tiny/Makefile b/drivers/gpu/drm/tiny/Makefile
+index e09942895c77..bc1512bd0eb5 100644
+--- a/drivers/gpu/drm/tiny/Makefile
++++ b/drivers/gpu/drm/tiny/Makefile
+@@ -9,6 +9,7 @@ obj-$(CONFIG_TINYDRM_HX8357D)		+= hx8357d.o
+ obj-$(CONFIG_TINYDRM_ILI9225)		+= ili9225.o
+ obj-$(CONFIG_TINYDRM_ILI9341)		+= ili9341.o
+ obj-$(CONFIG_TINYDRM_ILI9486)		+= ili9486.o
++obj-$(CONFIG_TINYDRM_ILI9488_PIO)	+= ili9488_pio.o
+ obj-$(CONFIG_TINYDRM_MI0283QT)		+= mi0283qt.o
+ obj-$(CONFIG_TINYDRM_REPAPER)		+= repaper.o
+ obj-$(CONFIG_TINYDRM_ST7586)		+= st7586.o
+diff --git a/drivers/gpu/drm/tiny/ili9488_pio.c b/drivers/gpu/drm/tiny/ili9488_pio.c
+new file mode 100644
+index 000000000000..f3a0b1fb885a
+--- /dev/null
++++ b/drivers/gpu/drm/tiny/ili9488_pio.c
+@@ -0,0 +1,366 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * DRM driver for Hardkernel 3.5 ISP TFT display
++ *
++ * Copyright 2021 Dongjin Kim <tobetter@gmail.com>
++ *
++ */
++
++#include <linux/delay.h>
++#include <linux/dma-buf.h>
++#include <linux/gpio/consumer.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/property.h>
++#include <linux/of_gpio.h>
++#include <linux/of_address.h>
++#include <linux/io.h>
++#include <video/mipi_display.h>
++
++#include <drm/drm_atomic_helper.h>
++#include <drm/drm_damage_helper.h>
++#include <drm/drm_drv.h>
++#include <drm/drm_fb_cma_helper.h>
++#include <drm/drm_fb_helper.h>
++#include <drm/drm_fourcc.h>
++#include <drm/drm_gem_atomic_helper.h>
++#include <drm/drm_gem_cma_helper.h>
++#include <drm/drm_gem_framebuffer_helper.h>
++#include <drm/drm_managed.h>
++#include <drm/drm_mipi_dbi.h>
++#include <drm/drm_rect.h>
++
++#define ILI9488_COLUMN_ADDR	0x2a
++#define ILI9488_PAGE_ADDR	0x2b
++#define ILI9488_MEMORY_WRITE	0x2c
++#define ILI9488_ITFCTR1         0xb0
++#define ILI9488_FRMCTR1		0xb1
++#define ILI9488_PWCTRL1         0xc2
++#define ILI9488_VMCTRL1         0xc5
++#define ILI9488_PGAMCTRL        0xe0
++#define ILI9488_NGAMCTRL        0xe1
++#define ILI9488_MADCTL_BGR      BIT(3)
++#define ILI9488_MADCTL_MV       BIT(5)
++#define ILI9488_MADCTL_MX       BIT(6)
++#define ILI9488_MADCTL_MY       BIT(7)
++
++struct ili9488_data {
++	struct mipi_dbi_dev *dbidev;
++	struct gpio_desc *wr;
++	struct gpio_desc *cs;
++	struct gpio_desc *db[8];
++	void __iomem *membase;
++	u32 mask;
++	u32 bits[8];
++	u32 bits_wr;
++};
++
++static struct ili9488_data *pdata;
++static u32 *rgb;
++
++static u32 ili9488_rgb565_to_gpiobus(struct ili9488_data *pdata, u8 color)
++{
++	int i;
++	u32 value = 0;
++
++	for (i = 0; i < 8; i++) {
++		if (color & 1)
++			value |= pdata->bits[i];
++		else
++			value &= ~(pdata->bits[i]);
++		color >>= 1;
++	}
++
++	return value;
++}
++
++static int ili9488_bus_write(struct mipi_dbi *dbi, u8 data)
++{
++	int i;
++
++	if (pdata->membase) {
++		u32 v = (readl(pdata->membase) & ~pdata->mask) | *(rgb + data);
++		writel(v, pdata->membase);
++		writel(v | pdata->bits_wr, pdata->membase);
++		return 0;
++	}
++
++	gpiod_set_value(pdata->wr, 0);
++	for (i = 0; i < 8; i++) {
++		gpiod_set_value(pdata->db[i], data & 1);
++		data >>= 1;
++	}
++	gpiod_set_value(pdata->wr, 1);
++
++	return 0;
++}
++
++static int ili9488_command(struct mipi_dbi *dbi, u8 *cmd, u8 *par, size_t num)
++{
++	u8 *p = par;
++
++	gpiod_set_value(dbi->dc, 0);
++	ili9488_bus_write(dbi, *cmd);
++	gpiod_set_value(dbi->dc, 1);
++
++	while (num--)
++		ili9488_bus_write(dbi, *p++);
++
++	return 0;
++}
++
++static void ili9488_pipe_enable(struct drm_simple_display_pipe *pipe,
++				struct drm_crtc_state *crtc_state,
++				struct drm_plane_state *plane_state)
++{
++	struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev);
++	struct mipi_dbi *dbi = &dbidev->dbi;
++	u8 addr_mode;
++	int ret, idx;
++
++	if (!drm_dev_enter(pipe->crtc.dev, &idx))
++		return;
++
++	ret = mipi_dbi_poweron_reset(dbidev);
++	if (ret < 0)
++		goto out_exit;
++	if (ret == 1)
++		goto out_enable;
++
++	gpiod_set_value(pdata->cs, 0);
++
++	mipi_dbi_command(dbi, ILI9488_ITFCTR1, 0x00);
++	mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE);
++	msleep(250);
++
++	mipi_dbi_command(dbi, MIPI_DCS_SET_PIXEL_FORMAT, 0x55);
++	mipi_dbi_command(dbi, ILI9488_PWCTRL1, 0x33);
++	mipi_dbi_command(dbi, ILI9488_VMCTRL1, 0x00, 0x1e, 0x80, 0x00);
++	mipi_dbi_command(dbi, ILI9488_FRMCTR1, 0xb0, 0x11);
++	mipi_dbi_command(dbi, ILI9488_PGAMCTRL,
++			0x00, 0x04, 0x0e, 0x08, 0x17, 0x0a, 0x40, 0x79,
++			0x4d, 0x07, 0x0e, 0x0a, 0x1a, 0x1d, 0x0f);
++	mipi_dbi_command(dbi, ILI9488_NGAMCTRL,
++			0x00, 0x1b, 0x1f, 0x02, 0x10, 0x05, 0x32, 0x34,
++			0x43, 0x02, 0x0a, 0x09, 0x33, 0x37, 0x0f);
++	mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON);
++	msleep(100);
++
++ out_enable:
++	switch (dbidev->rotation) {
++		case 90:
++			addr_mode = ILI9488_MADCTL_MY;
++			break;
++		case 180:
++			addr_mode = ILI9488_MADCTL_MV;
++			break;
++		case 270:
++			addr_mode = ILI9488_MADCTL_MX;
++			break;
++		default:
++			addr_mode = ILI9488_MADCTL_MV | ILI9488_MADCTL_MY |
++				ILI9488_MADCTL_MX;
++			break;
++	}
++
++	addr_mode |= ILI9488_MADCTL_BGR;
++	mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
++	mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
++
++out_exit:
++	drm_dev_exit(idx);
++}
++
++static const struct drm_simple_display_pipe_funcs ili9488_pipe_funcs = {
++	.enable = ili9488_pipe_enable,
++	.disable = mipi_dbi_pipe_disable,
++	.update = mipi_dbi_pipe_update,
++	.prepare_fb = drm_gem_simple_display_pipe_prepare_fb,
++};
++
++static const struct drm_display_mode ili9488_mode = {
++	DRM_SIMPLE_MODE(480, 320, 73, 49),
++};
++
++DEFINE_DRM_GEM_CMA_FOPS(ili9488_fops);
++
++static struct drm_driver ili9488_driver = {
++	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
++	.fops			= &ili9488_fops,
++	DRM_GEM_CMA_DRIVER_OPS_VMAP,
++	.name			= "ili9488",
++	.desc			= "Ilitek ILI9488",
++	.date			= "20210201",
++	.major			= 1,
++	.minor			= 0,
++};
++
++static int ili9488_probe(struct platform_device *pdev)
++{
++	struct device *dev = &pdev->dev;
++	struct device_node *np = dev->of_node;
++	struct mipi_dbi *dbi;
++	struct drm_device *drm;
++	struct mipi_dbi_dev *dbidev;
++	int ret;
++	int i;
++	u32 rotation = 0;
++	struct resource res;
++	char str[32];
++
++	pdata = devm_kzalloc(dev, sizeof(struct ili9488_data), GFP_KERNEL);
++	if (!pdata)
++		return -ENOMEM;
++
++	dbidev = devm_drm_dev_alloc(dev, &ili9488_driver,
++			struct mipi_dbi_dev, drm);
++	if (IS_ERR(dbidev))
++		return PTR_ERR(dbidev);
++
++	dbi = &dbidev->dbi;
++	drm = &dbidev->drm;
++
++	dbi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
++	if (IS_ERR(dbi->reset)) {
++		DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n");
++		return PTR_ERR(dbi->reset);
++	}
++
++	dbi->dc = devm_gpiod_get(dev, "dc", GPIOD_OUT_LOW);
++	if (IS_ERR(dbi->dc)) {
++		DRM_DEV_ERROR(dev, "Failed to get gpio 'dc'\n");
++		return PTR_ERR(dbi->dc);
++	}
++
++	pdata->wr = devm_gpiod_get(dev, "wr", GPIOD_OUT_HIGH);
++	if (IS_ERR(pdata->wr)) {
++		DRM_DEV_ERROR(dev, "Failed to get gpio 'wr'\n");
++		return PTR_ERR(pdata->wr);
++	}
++
++	pdata->cs = devm_gpiod_get(dev, "cs", GPIOD_OUT_LOW);
++	if (IS_ERR(pdata->cs)) {
++		DRM_DEV_ERROR(dev, "Failed to get gpio 'cs'\n");
++		return PTR_ERR(pdata->cs);
++	}
++
++	for (i = 0; i < 8; i++) {
++		struct gpio_desc *desc;
++		int gpio = of_get_named_gpio(np, "db-gpios", i);
++		if (gpio < 0)
++			break;	/* FIXME */
++
++		desc = gpio_to_desc(gpio);
++
++		devm_gpio_request(dev, gpio, NULL);
++		gpiod_direction_output(desc, 1);
++
++		pdata->db[i] = desc;
++	}
++
++	ret = of_address_to_resource(np, 0, &res);
++	if (!ret) {
++		pdata->membase = devm_ioremap(dev, res.start,
++				resource_size(&res));
++		if (!IS_ERR(pdata->membase)) {
++			for (i = 0; i < 8; i++) {
++				sprintf(str, "db-bits-%d", i);
++				ret = of_property_read_u32(np, str,
++						&pdata->bits[i]);
++				if (ret)
++					continue;
++				pdata->mask |= pdata->bits[i];
++			}
++
++			ret = of_property_read_u32(np, "db-bits-wr",
++					&pdata->bits_wr);
++			if (!ret)
++				pdata->mask |= pdata->bits_wr;
++		}
++	}
++
++	dbidev->backlight = devm_of_find_backlight(dev);
++	if (IS_ERR(dbidev->backlight))
++		return PTR_ERR(dbidev->backlight);
++
++	device_property_read_u32(dev, "rotation", &rotation);
++
++	rgb = devm_kzalloc(dev, sizeof(u32) * 256, GFP_KERNEL);
++	if (rgb) {
++		u32 *p = rgb;
++		for (i = 0; i < 256; i++)
++			*p++ = ili9488_rgb565_to_gpiobus(pdata, i);
++	}
++
++	gpiod_set_value(pdata->wr, 1);
++	gpiod_set_value(dbi->dc, 0);
++
++	/* override the command function set in  mipi_dbi_spi_init() */
++	dbi->command = ili9488_command;
++	dbi->read_commands = NULL;
++	dbi->swap_bytes = true;
++
++	ret = mipi_dbi_dev_init(dbidev, &ili9488_pipe_funcs,
++			&ili9488_mode, rotation);
++	if (ret)
++		return ret;
++
++	drm_mode_config_reset(drm);
++
++	ret = drm_dev_register(drm, 0);
++	if (ret)
++		return ret;
++
++	platform_set_drvdata(pdev, pdata);
++	pdata->dbidev = dbidev;
++
++	drm_fbdev_generic_setup(drm, 0);
++
++	return 0;
++}
++
++static int ili9488_remove(struct platform_device *pdev)
++{
++	struct ili9488_data *pdata = platform_get_drvdata(pdev);
++	struct mipi_dbi_dev *dbidev = pdata->dbidev;
++	struct drm_device *drm = &dbidev->drm;
++
++	drm_dev_unplug(drm);
++	drm_atomic_helper_shutdown(drm);
++
++	return 0;
++}
++
++static const struct of_device_id ili9488_dt_ids[] = {
++	{ .compatible = "ili9488", 0 },
++	{ .compatible = "hardkernel,ili9488", 0 },
++	{ },
++};
++
++MODULE_DEVICE_TABLE(of, ili9488_dt_ids);
++
++static struct platform_driver ili9488_platform_driver = {
++	.driver = {
++		.name = "ili9488",
++		.of_match_table = ili9488_dt_ids,
++	},
++	.probe = ili9488_probe,
++	.remove = ili9488_remove,
++};
++
++static int __init ili9488_init(void)
++{
++	return platform_driver_register(&ili9488_platform_driver);
++}
++
++static void __exit ili9488_exit(void)
++{
++	platform_driver_unregister(&ili9488_platform_driver);
++}
++
++module_init(ili9488_init);
++module_exit(ili9488_exit);
++
++MODULE_DESCRIPTION("Ilitek ILI9488 DRM driver (8bit PIO mode)");
++MODULE_AUTHOR("Dongjin Kim <tobetter@gmail.com>");
++MODULE_LICENSE("GPL");
+-- 
+2.34.1
+
diff --git a/main/linux-postmarketos-exynos5/0003-ODROID-COMMON-hwmon-pwm-fan-fix-to-add-pwm1_enable-t.patch b/main/linux-postmarketos-exynos5/0003-ODROID-COMMON-hwmon-pwm-fan-fix-to-add-pwm1_enable-t.patch
new file mode 100644
index 00000000000..361505ff49e
--- /dev/null
+++ b/main/linux-postmarketos-exynos5/0003-ODROID-COMMON-hwmon-pwm-fan-fix-to-add-pwm1_enable-t.patch
@@ -0,0 +1,141 @@
+From 8d9bcc63e41f8709a1bf08f07010b55aa33db48d Mon Sep 17 00:00:00 2001
+From: Dongjin Kim <tobetter@gmail.com>
+Date: Wed, 30 Jun 2021 11:38:33 +0900
+Subject: [PATCH 03/16] ODROID-COMMON: hwmon: (pwm-fan): fix to add
+ 'pwm1_enable' to set PWM fan mode
+
+Change-Id: If0562f497703b8660206dad80d7933902bbf53e4
+---
+ drivers/hwmon/pwm-fan.c | 67 +++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 61 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c
+index f12b9a28a232..383a24316985 100644
+--- a/drivers/hwmon/pwm-fan.c
++++ b/drivers/hwmon/pwm-fan.c
+@@ -8,6 +8,7 @@
+  */
+ 
+ #include <linux/hwmon.h>
++#include <linux/hwmon-sysfs.h>
+ #include <linux/interrupt.h>
+ #include <linux/module.h>
+ #include <linux/mutex.h>
+@@ -44,6 +45,7 @@ struct pwm_fan_ctx {
+ 	unsigned int pwm_fan_max_state;
+ 	unsigned int *pwm_fan_cooling_levels;
+ 	struct thermal_cooling_device *cdev;
++	int enable;
+ 
+ 	struct hwmon_chip_info info;
+ 	struct hwmon_channel_info fan_channel;
+@@ -99,6 +101,10 @@ static int  __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm)
+ 	struct pwm_state *state = &ctx->pwm_state;
+ 
+ 	mutex_lock(&ctx->lock);
++
++	if (!ctx->enable)
++		pwm = MAX_PWM;
++
+ 	if (ctx->pwm_value == pwm)
+ 		goto exit_set_pwm_err;
+ 
+@@ -183,6 +189,51 @@ static const struct hwmon_ops pwm_fan_hwmon_ops = {
+ 	.write = pwm_fan_write,
+ };
+ 
++static ssize_t enable_store(struct device *dev,
++		struct device_attribute *attr,
++		const char *buf, size_t count)
++{
++	struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
++	int err;
++	unsigned long val;
++
++	err = kstrtoul(buf, 10, &val);
++	if (err)
++		return err;
++
++	mutex_lock(&ctx->lock);
++	ctx->enable = val;
++	mutex_unlock(&ctx->lock);
++
++	err = __set_pwm(ctx, ctx->pwm_fan_cooling_levels[ctx->pwm_fan_state]);
++
++	return err ? err : count;
++}
++
++static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
++		char *buf)
++{
++	struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
++
++	return sprintf(buf, "%u\n", ctx->enable);
++}
++
++static SENSOR_DEVICE_ATTR_RW(pwm1_enable, enable, 0);
++
++static struct attribute *pwm_fan_attrs[] = {
++	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
++	NULL,
++};
++
++static const struct attribute_group pwm_fan_group = {
++	.attrs = pwm_fan_attrs,
++};
++
++static const struct attribute_group *pwm_fan_groups[] = {
++	&pwm_fan_group,
++	NULL,
++};
++
+ /* thermal cooling device callbacks */
+ static int pwm_fan_get_max_state(struct thermal_cooling_device *cdev,
+ 				 unsigned long *state)
+@@ -214,7 +265,7 @@ static int
+ pwm_fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
+ {
+ 	struct pwm_fan_ctx *ctx = cdev->devdata;
+-	int ret;
++	int ret = 0;
+ 
+ 	if (!ctx || (state > ctx->pwm_fan_max_state))
+ 		return -EINVAL;
+@@ -222,10 +273,12 @@ pwm_fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
+ 	if (state == ctx->pwm_fan_state)
+ 		return 0;
+ 
+-	ret = __set_pwm(ctx, ctx->pwm_fan_cooling_levels[state]);
+-	if (ret) {
+-		dev_err(&cdev->device, "Cannot set pwm!\n");
+-		return ret;
++	if (ctx->enable >= 2) {
++		ret = __set_pwm(ctx, ctx->pwm_fan_cooling_levels[state]);
++		if (ret) {
++			dev_err(&cdev->device, "Cannot set pwm!\n");
++			return ret;
++		}
+ 	}
+ 
+ 	ctx->pwm_fan_state = state;
+@@ -316,6 +369,8 @@ static int pwm_fan_probe(struct platform_device *pdev)
+ 	if (IS_ERR(ctx->pwm))
+ 		return dev_err_probe(dev, PTR_ERR(ctx->pwm), "Could not get PWM\n");
+ 
++	ctx->enable = 2;
++
+ 	platform_set_drvdata(pdev, ctx);
+ 
+ 	ctx->reg_en = devm_regulator_get_optional(dev, "fan");
+@@ -434,7 +489,7 @@ static int pwm_fan_probe(struct platform_device *pdev)
+ 	ctx->info.info = channels;
+ 
+ 	hwmon = devm_hwmon_device_register_with_info(dev, "pwmfan",
+-						     ctx, &ctx->info, NULL);
++						     ctx, &ctx->info, pwm_fan_groups);
+ 	if (IS_ERR(hwmon)) {
+ 		dev_err(dev, "Failed to register hwmon device\n");
+ 		return PTR_ERR(hwmon);
+-- 
+2.34.1
+
diff --git a/main/linux-postmarketos-exynos5/0004-ODROID-COMMON-gpu-drm-add-new-display-resolution-256.patch b/main/linux-postmarketos-exynos5/0004-ODROID-COMMON-gpu-drm-add-new-display-resolution-256.patch
new file mode 100644
index 00000000000..7fee9041b58
--- /dev/null
+++ b/main/linux-postmarketos-exynos5/0004-ODROID-COMMON-gpu-drm-add-new-display-resolution-256.patch
@@ -0,0 +1,77 @@
+From 57bb14ce9bda301baa6d4f5fb8ed075650ef554b Mon Sep 17 00:00:00 2001
+From: Dongjin Kim <tobetter@gmail.com>
+Date: Thu, 10 Sep 2020 11:01:33 +0900
+Subject: [PATCH 04/16] ODROID-COMMON: gpu/drm: add new display resolution
+ 2560x1440
+
+Signed-off-by: Joy Cho <joy.cho@hardkernel.com>
+Signed-off-by: Dongjin Kim <tobetter@gmail.com>
+---
+ drivers/gpu/drm/meson/meson_vclk.c | 18 ++++++++++++++++++
+ drivers/gpu/drm/meson/meson_venc.c |  5 +++--
+ 2 files changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
+index 2a82119eb58e..eb4c251d79b7 100644
+--- a/drivers/gpu/drm/meson/meson_vclk.c
++++ b/drivers/gpu/drm/meson/meson_vclk.c
+@@ -357,6 +357,8 @@ enum {
+ 	MESON_VCLK_HDMI_594000,
+ /* 2970 /1 /1 /1 /5 /1  => /1 /2 */
+ 	MESON_VCLK_HDMI_594000_YUV420,
++/* 4830 /2 /1 /2 /5 /1  => /1 /1 */
++	MESON_VCLK_HDMI_241500,
+ };
+ 
+ struct meson_vclk_params {
+@@ -467,6 +469,18 @@ struct meson_vclk_params {
+ 		.vid_pll_div = VID_PLL_DIV_5,
+ 		.vclk_div = 1,
+ 	},
++	[MESON_VCLK_HDMI_241500] = {
++		.pll_freq = 4830000,
++		.phy_freq = 2415000,
++		.venc_freq = 241500,
++		.vclk_freq = 241500,
++		.pixel_freq = 241500,
++		.pll_od1 = 2,
++		.pll_od2 = 1,
++		.pll_od3 = 2,
++		.vid_pll_div = VID_PLL_DIV_5,
++		.vclk_div = 1,
++	},
+ 	{ /* sentinel */ },
+ };
+ 
+@@ -873,6 +887,10 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
+ 			m = 0xf7;
+ 			frac = vic_alternate_clock ? 0x8148 : 0x10000;
+ 			break;
++		case 4830000:
++			m = 0xc9;
++			frac = 0xd560;
++			break;
+ 		}
+ 
+ 		meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
+diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
+index 3c55ed003359..559ab3b5e212 100644
+--- a/drivers/gpu/drm/meson/meson_venc.c
++++ b/drivers/gpu/drm/meson/meson_venc.c
+@@ -866,10 +866,11 @@ meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode)
+ 			    DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC))
+ 		return MODE_BAD;
+ 
+-	if (mode->hdisplay < 640 || mode->hdisplay > 1920)
++	/* support higher resolution than 1920x1080 */
++	if (mode->hdisplay < 640 || mode->hdisplay > 2560)
+ 		return MODE_BAD_HVALUE;
+ 
+-	if (mode->vdisplay < 480 || mode->vdisplay > 1200)
++	if (mode->vdisplay < 480 || mode->vdisplay > 1600)
+ 		return MODE_BAD_VVALUE;
+ 
+ 	return MODE_OK;
+-- 
+2.34.1
+
diff --git a/main/linux-postmarketos-exynos5/0005-ODROID-COMMON-Revert-drm-dbi-Print-errors-for-mipi_d.patch b/main/linux-postmarketos-exynos5/0005-ODROID-COMMON-Revert-drm-dbi-Print-errors-for-mipi_d.patch
new file mode 100644
index 00000000000..812d1a8a3ee
--- /dev/null
+++ b/main/linux-postmarketos-exynos5/0005-ODROID-COMMON-Revert-drm-dbi-Print-errors-for-mipi_d.patch
@@ -0,0 +1,32 @@
+From f63e7c1da3e7da923b1d3d11663ad6b81ceb878c Mon Sep 17 00:00:00 2001
+From: Dongjin Kim <tobetter@gmail.com>
+Date: Wed, 3 Nov 2021 18:57:00 +0900
+Subject: [PATCH 05/16] ODROID-COMMON: Revert "drm/dbi: Print errors for
+ mipi_dbi_command()"
+
+This reverts commit 3f5aa5ac0b0f9704f0c60f5fbbbcdc8c043d6eb6.
+---
+ include/drm/drm_mipi_dbi.h | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h
+index 05e194958265..f543d6e3e822 100644
+--- a/include/drm/drm_mipi_dbi.h
++++ b/include/drm/drm_mipi_dbi.h
+@@ -183,12 +183,7 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb,
+ #define mipi_dbi_command(dbi, cmd, seq...) \
+ ({ \
+ 	const u8 d[] = { seq }; \
+-	struct device *dev = &(dbi)->spi->dev;	\
+-	int ret; \
+-	ret = mipi_dbi_command_stackbuf(dbi, cmd, d, ARRAY_SIZE(d)); \
+-	if (ret) \
+-		dev_err_ratelimited(dev, "error %d when sending command %#02x\n", ret, cmd); \
+-	ret; \
++	mipi_dbi_command_stackbuf(dbi, cmd, d, ARRAY_SIZE(d)); \
+ })
+ 
+ #ifdef CONFIG_DEBUG_FS
+-- 
+2.34.1
+
diff --git a/main/linux-postmarketos-exynos5/0006-ODROID-COMMON-add-symbol-to-device-tree-compiler.patch b/main/linux-postmarketos-exynos5/0006-ODROID-COMMON-add-symbol-to-device-tree-compiler.patch
new file mode 100644
index 00000000000..732a0a7f2df
--- /dev/null
+++ b/main/linux-postmarketos-exynos5/0006-ODROID-COMMON-add-symbol-to-device-tree-compiler.patch
@@ -0,0 +1,30 @@
+From d2141d45270cf6a01bf891c022680dc5c69894ed Mon Sep 17 00:00:00 2001
+From: Dongjin Kim <tobetter@gmail.com>
+Date: Wed, 17 Nov 2021 03:25:51 +0900
+Subject: [PATCH 06/16] ODROID-COMMON: add '--symbol' to device tree compiler
+
+This change is to create device tree node '__symbol__' to support device
+treey overlay features, *.dtbo won't be applied without this node.
+
+Signed-off-by: Dongjin Kim <tobetter@gmail.com>
+Change-Id: I3b6102c925e871947f16e7c570563011101f5f86
+---
+ scripts/Makefile.lib | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
+index d1f865b8c0cb..08d2cc9c50e9 100644
+--- a/scripts/Makefile.lib
++++ b/scripts/Makefile.lib
+@@ -294,7 +294,7 @@ quiet_cmd_gzip = GZIP    $@
+ # DTC
+ # ---------------------------------------------------------------------------
+ DTC ?= $(objtree)/scripts/dtc/dtc
+-DTC_FLAGS += -Wno-interrupt_provider
++DTC_FLAGS += -Wno-interrupt_provider --symbol
+ 
+ # Disable noisy checks by default
+ ifeq ($(findstring 1,$(KBUILD_EXTRA_WARN)),)
+-- 
+2.34.1
+
diff --git a/main/linux-postmarketos-exynos5/0007-ODROID-COMMON-phy-realtek-add-Wake-on-Lan-to-Realtek.patch b/main/linux-postmarketos-exynos5/0007-ODROID-COMMON-phy-realtek-add-Wake-on-Lan-to-Realtek.patch
new file mode 100644
index 00000000000..89740a06137
--- /dev/null
+++ b/main/linux-postmarketos-exynos5/0007-ODROID-COMMON-phy-realtek-add-Wake-on-Lan-to-Realtek.patch
@@ -0,0 +1,107 @@
+From eec2539ec9efc8a4f50c68204c01c113c39f2976 Mon Sep 17 00:00:00 2001
+From: Dongjin Kim <tobetter@gmail.com>
+Date: Wed, 17 Nov 2021 13:17:51 +0900
+Subject: [PATCH 07/16] ODROID-COMMON: phy/realtek: add Wake-on-Lan to Realtek
+ PHY
+
+Wake-On-Lan can set with 'ethtool'
+    $ sudo ethtool -s eth0 wol u
+
+Check if 'Wake-on' is set with 'u'
+    $ sudo ethtool eth0 | grep Wake
+    Supports Wake-on: ug
+    Wake-on: u
+
+In order to wake from remote, run 'wakeonlan' with IP address:
+    $ wakeonlan 00:1e:06:42:45:32
+
+Signed-off-by: Dongjin Kim <tobetter@gmail.com>
+Change-Id: I8ade81ab50d8d886e2908b9cec543e3bf8cc7abd
+---
+ .../ethernet/stmicro/stmmac/stmmac_ethtool.c  |  2 ++
+ drivers/net/phy/realtek.c                     | 34 +++++++++++++++++++
+ 2 files changed, 36 insertions(+)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+index d89455803bed..98f3913b7ae5 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+@@ -753,6 +753,8 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+ 	priv->wolopts = wol->wolopts;
+ 	mutex_unlock(&priv->lock);
+ 
++	phy_ethtool_set_wol(dev->phydev, wol);
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
+index a5671ab896b3..f832992d80fd 100644
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -12,6 +12,7 @@
+ #include <linux/phy.h>
+ #include <linux/module.h>
+ #include <linux/delay.h>
++#include <linux/etherdevice.h>
+ 
+ #define RTL821x_PHYSR				0x11
+ #define RTL821x_PHYSR_DUPLEX			BIT(13)
+@@ -228,7 +229,11 @@ static int rtl8211f_config_intr(struct phy_device *phydev)
+ 
+ 		val = RTL8211F_INER_LINK_STATUS;
+ 		err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
++
++		phy_modify_paged(phydev, 0xd40, 0x16, BIT(5), 0);
+ 	} else {
++		phy_modify_paged(phydev, 0xd40, 0x16, 0, BIT(5));
++
+ 		val = 0;
+ 		err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
+ 		if (err)
+@@ -329,6 +334,34 @@ static int rtl8211c_config_init(struct phy_device *phydev)
+ 			    CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
+ }
+ 
++static int rtl8211f_set_wol(struct phy_device *phydev,
++		struct ethtool_wolinfo *wol)
++{
++	struct net_device *netdev = phydev->attached_dev;
++	const u8 *mac = (const u8 *)netdev->dev_addr;
++
++	if ((wol->wolopts & (WAKE_MAGIC | WAKE_UCAST)) == 0) {
++		disable_irq_wake(phydev->irq);
++		return 0;
++	}
++
++	if ((wol->wolopts & WAKE_UCAST)
++			&& is_valid_ether_addr(mac)) {
++		phy_write_paged(phydev, 0xd8c, 0x10, (mac[1] << 8) | mac[0]);
++		phy_write_paged(phydev, 0xd8c, 0x11, (mac[3] << 8) | mac[2]);
++		phy_write_paged(phydev, 0xd8c, 0x12, (mac[5] << 8) | mac[4]);
++	}
++
++	if (wol->wolopts & WAKE_MAGIC) {
++		phy_write_paged(phydev, 0xd8a, 0x10, 0x1000);
++		phy_write_paged(phydev, 0xd8a, 0x11, 0x9fff);
++	}
++
++	enable_irq_wake(phydev->irq);
++
++	return 0;
++}
++
+ static int rtl8211f_config_init(struct phy_device *phydev)
+ {
+ 	struct rtl821x_priv *priv = phydev->priv;
+@@ -921,6 +954,7 @@ static struct phy_driver realtek_drvs[] = {
+ 		.handle_interrupt = rtl8211f_handle_interrupt,
+ 		.suspend	= genphy_suspend,
+ 		.resume		= rtl821x_resume,
++		.set_wol	= rtl8211f_set_wol,
+ 		.read_page	= rtl821x_read_page,
+ 		.write_page	= rtl821x_write_page,
+ 	}, {
+-- 
+2.34.1
+
diff --git a/main/linux-postmarketos-exynos5/0008-ARM-exynos-add-machine-description-for-ODROID-XU3-4.patch b/main/linux-postmarketos-exynos5/0008-ARM-exynos-add-machine-description-for-ODROID-XU3-4.patch
new file mode 100644
index 00000000000..54e33baa4cc
--- /dev/null
+++ b/main/linux-postmarketos-exynos5/0008-ARM-exynos-add-machine-description-for-ODROID-XU3-4.patch
@@ -0,0 +1,52 @@
+From 3b63e36be888ed2fdea0243f0588b7f5e451d658 Mon Sep 17 00:00:00 2001
+From: Dongjin Kim <tobetter@gmail.com>
+Date: Thu, 9 Nov 2017 22:09:37 -0500
+Subject: [PATCH 08/16] ARM: exynos: add machine description for ODROID-XU3/4
+
+Change-Id: Ice75e06366f107f761504512a84fb92affffb124
+Signed-off-by: Dongjin Kim <tobetter@gmail.com>
+[ grimler: bring up to 5.16, fix init_late->pm_init ]
+Signed-off-by: Henrik Grimler <henrik@grimler.se>
+---
+ arch/arm/mach-exynos/exynos.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
+index 8b48326be9fd..e4e1a2c76ed9 100644
+--- a/arch/arm/mach-exynos/exynos.c
++++ b/arch/arm/mach-exynos/exynos.c
+@@ -220,3 +220,31 @@ DT_MACHINE_START(EXYNOS_DT, "Samsung Exynos (Flattened Device Tree)")
+ 	.dt_compat	= exynos_dt_compat,
+ 	.dt_fixup	= exynos_dt_fixup,
+ MACHINE_END
++
++#define ODROID_MACHINE_START(name, compat)			\
++	DT_MACHINE_START(EXYNOS5422_ODROID_##name, "ODROID-"#name)	\
++		.l2c_aux_val	= 0x3c400001,			\
++		.l2c_aux_mask	= 0xc20fffff,			\
++		.smp		= smp_ops(exynos_smp_ops),	\
++		.map_io		= exynos_init_io,		\
++		.init_early	= exynos_firmware_init,		\
++		.init_irq	= exynos_init_irq,		\
++		.init_machine	= exynos_dt_machine_init,	\
++		.init_late	= exynos_pm_init,		\
++		.dt_compat	= compat,			\
++		.dt_fixup	= exynos_dt_fixup,		\
++	MACHINE_END
++
++static char const *const exynos5422_odroidxu3_dt_compat[] __initconst = {
++	"hardkernel,odroid-xu3",
++	"hardkernel,odroid-xu3-lite",
++	NULL,
++};
++
++static char const *const exynos5422_odroidxu4_dt_compat[] __initconst = {
++	"hardkernel,odroid-xu4",
++	NULL,
++};
++
++ODROID_MACHINE_START(XU3, exynos5422_odroidxu3_dt_compat)
++ODROID_MACHINE_START(XU4, exynos5422_odroidxu4_dt_compat)
+-- 
+2.34.1
+
diff --git a/main/linux-postmarketos-exynos5/APKBUILD b/main/linux-postmarketos-exynos5/APKBUILD
index 36629bc5e34..d05e73471db 100644
--- a/main/linux-postmarketos-exynos5/APKBUILD
+++ b/main/linux-postmarketos-exynos5/APKBUILD
@@ -38,6 +38,14 @@ esac
 source="
 	https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-${pkgver//_/-}.tar.xz
 	$_config
+	0001-ODROID-COMMON-gpu-drm-Add-Hardkernel-3.2-LCD-driver-.patch
+	0002-ODROID-COMMON-gpu-drm-Add-new-Tiny-DRM-driver-with-I.patch
+	0003-ODROID-COMMON-hwmon-pwm-fan-fix-to-add-pwm1_enable-t.patch
+	0004-ODROID-COMMON-gpu-drm-add-new-display-resolution-256.patch
+	0005-ODROID-COMMON-Revert-drm-dbi-Print-errors-for-mipi_d.patch
+	0006-ODROID-COMMON-add-symbol-to-device-tree-compiler.patch
+	0007-ODROID-COMMON-phy-realtek-add-Wake-on-Lan-to-Realtek.patch
+	0008-ARM-exynos-add-machine-description-for-ODROID-XU3-4.patch
 "
 builddir="$srcdir/linux-${_kernver//_/-}"
 
@@ -69,4 +77,12 @@ package() {
 sha512sums="
 f47cf92065c7445518452052566251642f701089494c8b5eb7d5b0e147d7177b016957481e0b98050840d79e2b838cfb088aeee1941fd41b75b681972f2fec5d  linux-5.16.1.tar.xz
 0f8a3c7a1aec868f60405e723b44107f66f6518a25fe5e64ace50c9ec4d89b533a7b63775236b81a84017791a569a49a18698f72bb8bf71aacffedafca8f2ecf  config-postmarketos-exynos5.armv7
+8818dee159da213314d21affb33873217a9c281b01598776c46bc26fcde790675e157fc5c604ec432f22d2ee780e703e8590f268a57e54fd0f74fe6d4ad6f315  0001-ODROID-COMMON-gpu-drm-Add-Hardkernel-3.2-LCD-driver-.patch
+1e460183a1e34f25ff615f8e1ead274dc224fb2b337924a799fca3807d382870dbcfc3418f0ff203ce6533fe416e56541a0f93a2e4ff6bc072ae2fbb7245de39  0002-ODROID-COMMON-gpu-drm-Add-new-Tiny-DRM-driver-with-I.patch
+7f4771e6fc701223f5e693e694385daede79e854231c94054179520f5f6b0e21d668554082143ae28048e4a6c2cdfc0608db46d9938a02cde1d9d3a9628be60a  0003-ODROID-COMMON-hwmon-pwm-fan-fix-to-add-pwm1_enable-t.patch
+e540e3be0d0d45135f394f07bf8c9769654bf4c7d79a4558593ade87e02c21ab5cf66c3ff6672dabdb220ea7149ac24b23136efb0cf16c00ef9b0385bd47a245  0004-ODROID-COMMON-gpu-drm-add-new-display-resolution-256.patch
+3c23bf916dfb227bc8fb35efd9753bb378c694e2836a1a9ea642e4030ec77f81d1003b72a261b6106d62f63027a66b247700f6e3e88eba33216a458ead48639e  0005-ODROID-COMMON-Revert-drm-dbi-Print-errors-for-mipi_d.patch
+0272dc43b9218e38ce329c7a358eb869fd7ccdf70c9aae0e5cc3e0a029ba8f9616d3260b247650277376a1c1a3ec160f1ec8bc3df642b6f6cf7e60ba99e828e7  0006-ODROID-COMMON-add-symbol-to-device-tree-compiler.patch
+622f1f90ecc63a3cac32e8dafcfbe265a175031307af0a99088301bb2631bb55f6e6194e889f453d6f06239a5217e52c1b4ee9905570a06e975ce7aa1bb35434  0007-ODROID-COMMON-phy-realtek-add-Wake-on-Lan-to-Realtek.patch
+36b00ee94045b8dce002f55b91e0970dde59f9fa75ec4df7043930532991bfb59a0504256b056cd3f801bab05f5c23b2765e55c6ffbafe706a3e62bcd1ff71b9  0008-ARM-exynos-add-machine-description-for-ODROID-XU3-4.patch
 "
-- 
GitLab