sunxi: bump edge to 6.18 (#9049)

* sunxi-6.18: make the mess even worse

* fixing one of megis patches and add sunxi 32bit to the mess

* rewrite against 6.18

* fix media-ov5640-Don-t-powerup-the-sensor-during-driver-probe.patch

* fix media-sun6i-csi-implement-vidioc_enum_framesizes.patch

* fix misc-modem-power-Power-manager-for-modems.patch

* Fix usb-gadget-Fix-dangling-pointer-in-netdev-private-data.patch, include rewrite

* fix mmc-sunxi-mmc-Remove-runtime-PM.patch, two hunks no longer apply

* re-extract all of megis patches

* remove unneeded branch

* add note to disabled patch

* auto-generated, out of date

* drop megous drm patches in favor of Jernej's work. disable broken patches

* disable patch which breaks compilation for armhf

* disable breaking patch, rewrite everything

* remove patches unrelated to sunxi family

* fix spi dev compatible patch

* fix tsc2007 patch

* drop mainlined patch, adjust x96 mate T95 eth sd card hack

* remove upstreamed patch

* re-enable no longer broken

* another rewrite to align stuff properly

* adjust various comments in series.conf

* recover lost overlays

* uew5622: fix compilation against Linux 6.18

* fix Add-sunxi-addr-driver-Used-to-fix-uwe5622-bluetooth-MAC-address.patch

* adjust patch subject to make sense

* restore fixup creation
restore overlay prefix on opiz2
this needs to be properly sorted at some point

* bump to 6.18.1
sunxi and sunxi64 build just fine

* fix and re-enable drv-mfd-axp20x-add-sysfs-interface.patch

* rewrite patches
This commit is contained in:
Werner
2025-12-16 12:35:24 +01:00
committed by GitHub
parent f2dd38e622
commit 3d46ef80e0
570 changed files with 18206 additions and 8247 deletions

View File

@@ -5,6 +5,7 @@ BOARDFAMILY="sun50iw9"
BOARD_MAINTAINER="AGM1968 krachlatte"
BOOTCONFIG="orangepi_zero2_defconfig"
BOOT_LOGO="desktop"
OVERLAY_PREFIX="sun50i-h616"
KERNEL_TARGET="current,edge"
KERNEL_TEST_TARGET="current"
FORCE_BOOTSCRIPT_UPDATE="yes"

View File

@@ -35,8 +35,8 @@ case $BRANCH in
;;
edge)
declare -g KERNEL_MAJOR_MINOR="6.16" # Major and minor versions of this kernel.
declare -g KERNELBRANCH="tag:v6.16.8"
declare -g KERNEL_MAJOR_MINOR="6.18" # Major and minor versions of this kernel.
declare -g KERNELBRANCH="tag:v6.18.1"
;;
esac

View File

@@ -36,8 +36,8 @@ case $BRANCH in
;;
edge)
declare -g KERNEL_MAJOR_MINOR="6.16" # Major and minor versions of this kernel.
declare -g KERNELBRANCH="tag:v6.16.8"
declare -g KERNEL_MAJOR_MINOR="6.18" # Major and minor versions of this kernel.
declare -g KERNELBRANCH="tag:v6.18.1"
;;
esac

View File

@@ -236,11 +236,11 @@ driver_xradio_xr819() {
if linux-version compare "${version}" ge 4.19 && [[ "$LINUXFAMILY" == sun* ]]; then
# Attach to specific commit (is branch:master)
local xradio_xr819_ver="commit:684a91a3692a964c5886dcf4369874cc7c19c0a4" # Commit date: Aug 7, 2025 (please update when updating commit ref)
local xradio_xr819_ver="commit:43992a7e7ed95ff815cf6d8ba81cef1085e50ab9" # Commit date: Oct 11, 2025 (please update when updating commit ref)
display_alert "Adding" "Wireless drivers for Xradio XR819 chipsets" "info"
fetch_from_repo "$GITHUB_SOURCE/igorpecovnik/xradio" "xradio" "${xradio_xr819_ver}" "yes" # Forked from https://github.com/fifteenhex/xradio
fetch_from_repo "$GITHUB_SOURCE/fifteenhex/xradio" "xradio" "${xradio_xr819_ver}" "yes"
cd "$kerneldir" || exit
rm -rf "$kerneldir/drivers/net/wireless/xradio"
mkdir -p "$kerneldir/drivers/net/wireless/xradio/"
@@ -565,7 +565,11 @@ driver_uwe5622() {
if linux-version compare "${version}" ge 6.17; then
process_patch_file "${SRC}/patch/misc/wireless-uwe5622/uwe5622-v6.17.patch" "applying"
fi
fi
if linux-version compare "${version}" ge 6.18; then
process_patch_file "${SRC}/patch/misc/wireless-uwe5622/uwe5622-v6.18.patch" "applying"
fi
fi
}

View File

@@ -1,64 +0,0 @@
From e48549cc1b24a6e51f469768b1a2c13cbf3199d7 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Mon, 14 Jun 2021 22:39:58 +0200
Subject: arm64:dts: sun50i-h616-x96-mate add hdmi
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
.../dts/allwinner/sun50i-h616-x96-mate.dts | 26 +++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts
index e0e9288c4986..22ce0410798c 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts
@@ -24,6 +24,17 @@ chosen {
stdout-path = "serial0:115200n8";
};
+ connector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con_in: endpoint {
+ remote-endpoint = <&hdmi_out_con>;
+ };
+ };
+ };
+
reg_vcc5v: vcc5v {
/* board wide 5V supply directly from the DC input */
compatible = "regulator-fixed";
@@ -43,6 +54,10 @@ &cpu0 {
cpu-supply = <&reg_dcdca>;
};
+&de {
+ status = "okay";
+};
+
&ehci0 {
status = "okay";
};
@@ -74,6 +89,17 @@ rmii_phy: ethernet-phy@1 {
};
};
+&hdmi {
+ hvcc-supply = <&reg_bldo1>;
+ status = "okay";
+};
+
+&hdmi_out {
+ hdmi_out_con: endpoint {
+ remote-endpoint = <&hdmi_con_in>;
+ };
+};
+
&ir {
status = "okay";
};
--
2.51.0

View File

@@ -1,111 +0,0 @@
From c14e5e16fb3eb34fbfc87bd4aefd88981a9d767f Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megi@xff.cz>
Date: Sat, 9 Aug 2025 14:47:14 +0200
Subject: drm: sun4i: Report page flip after vsync is complete, not in the
middle
See: https://xnux.eu/log/080.html
Signed-off-by: Ondrej Jirman <megi@xff.cz>
---
drivers/gpu/drm/sun4i/sun4i_tcon.c | 26 ++++++++++++++++++++++++--
drivers/gpu/drm/sun4i/sun4i_tcon.h | 4 ++++
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 43cc8908a03f..2d0e689bf877 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -240,6 +240,9 @@ void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, bool enable)
if (enable)
val = mask;
+ if (!enable && tcon->quirks->vblank_delay)
+ hrtimer_cancel(&tcon->flip_timer);
+
regmap_update_bits(tcon->regs, SUN4I_TCON_GINT0_REG, mask, val);
}
EXPORT_SYMBOL(sun4i_tcon_enable_vblank);
@@ -850,6 +853,17 @@ static void sun4i_tcon_finish_page_flip(struct drm_device *dev,
spin_unlock_irqrestore(&dev->event_lock, flags);
}
+static enum hrtimer_restart sun4i_tcon_flip_timer_cb(struct hrtimer *timer)
+{
+ struct sun4i_tcon *tcon = container_of(timer,
+ struct sun4i_tcon, flip_timer);
+
+ drm_crtc_handle_vblank(&tcon->crtc->crtc);
+ sun4i_tcon_finish_page_flip(tcon->drm, tcon->crtc);
+
+ return HRTIMER_NORESTART;
+}
+
static irqreturn_t sun4i_tcon_handler(int irq, void *private)
{
struct sun4i_tcon *tcon = private;
@@ -865,8 +879,12 @@ static irqreturn_t sun4i_tcon_handler(int irq, void *private)
SUN4I_TCON_GINT0_TCON0_TRI_FINISH_INT)))
return IRQ_NONE;
- drm_crtc_handle_vblank(&scrtc->crtc);
- sun4i_tcon_finish_page_flip(drm, scrtc);
+ if (tcon->quirks->vblank_delay) {
+ hrtimer_start(&tcon->flip_timer, us_to_ktime(250), HRTIMER_MODE_REL);
+ } else {
+ drm_crtc_handle_vblank(&scrtc->crtc);
+ sun4i_tcon_finish_page_flip(drm, scrtc);
+ }
/* Acknowledge the interrupt */
regmap_update_bits(tcon->regs, SUN4I_TCON_GINT0_REG,
@@ -915,6 +933,9 @@ static int sun4i_tcon_init_irq(struct device *dev,
struct platform_device *pdev = to_platform_device(dev);
int irq, ret;
+ hrtimer_setup(&tcon->flip_timer, sun4i_tcon_flip_timer_cb,
+ CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
@@ -1628,6 +1649,7 @@ static const struct sun4i_tcon_quirks sun50i_a64_lcd_quirks = {
.restores_rate = true,
.dclk_min_div = 1,
.setup_lvds_phy = sun6i_tcon_setup_lvds_phy,
+ .vblank_delay = true,
};
static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index 729d64b78846..2bf91fb4872c 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -12,6 +12,7 @@
#include <drm/drm_crtc.h>
+#include <linux/hrtimer.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/mod_devicetable.h>
@@ -252,6 +253,8 @@ struct sun4i_tcon_quirks {
bool polarity_in_ch0; /* some tcon1 channels have polarity bits in tcon0 pol register */
bool restores_rate; /* restores the initial rate when rate changes */
u8 dclk_min_div; /* minimum divider for TCON0 DCLK */
+ bool vblank_delay; /* delay page flip reporting for 250us (TCON report vblank
+ shortly before register flip) */
/* callback to handle tcon muxing options */
int (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *);
@@ -289,6 +292,7 @@ struct sun4i_tcon {
/* Associated crtc */
struct sun4i_crtc *crtc;
+ struct hrtimer flip_timer;
int id;
--
2.51.0

View File

@@ -1,178 +0,0 @@
From 54669ac67e47835b8cc3eea215026385a0050567 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Sun, 29 Sep 2024 22:04:33 +1300
Subject: drm: sun4i: de2/de3: Change CSC argument
Currently, CSC module takes care only for converting YUV to RGB.
However, DE3 is more suited to work in YUV color space. Change CSC mode
argument to format type to be more neutral. New argument only tells
layer format type and doesn't imply output type.
This commit doesn't make any functional change.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: Ryan Walklin <ryan@testtoast.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
---
drivers/gpu/drm/sun4i/sun8i_csc.c | 22 +++++++++++-----------
drivers/gpu/drm/sun4i/sun8i_csc.h | 10 +++++-----
drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 16 ++++++++--------
3 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c
index 58480d8e4f70..6ebd1c3aa3ab 100644
--- a/drivers/gpu/drm/sun4i/sun8i_csc.c
+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
@@ -108,7 +108,7 @@ static const u32 yuv2rgb_de3[2][3][12] = {
};
static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
- enum sun8i_csc_mode mode,
+ enum format_type fmt_type,
enum drm_color_encoding encoding,
enum drm_color_range range)
{
@@ -118,12 +118,12 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
table = yuv2rgb[range][encoding];
- switch (mode) {
- case SUN8I_CSC_MODE_YUV2RGB:
+ switch (fmt_type) {
+ case FORMAT_TYPE_YUV:
base_reg = SUN8I_CSC_COEFF(base, 0);
regmap_bulk_write(map, base_reg, table, 12);
break;
- case SUN8I_CSC_MODE_YVU2RGB:
+ case FORMAT_TYPE_YVU:
for (i = 0; i < 12; i++) {
if ((i & 3) == 1)
base_reg = SUN8I_CSC_COEFF(base, i + 1);
@@ -141,7 +141,7 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
}
static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer,
- enum sun8i_csc_mode mode,
+ enum format_type fmt_type,
enum drm_color_encoding encoding,
enum drm_color_range range)
{
@@ -151,12 +151,12 @@ static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer,
table = yuv2rgb_de3[range][encoding];
- switch (mode) {
- case SUN8I_CSC_MODE_YUV2RGB:
+ switch (fmt_type) {
+ case FORMAT_TYPE_YUV:
addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0);
regmap_bulk_write(map, addr, table, 12);
break;
- case SUN8I_CSC_MODE_YVU2RGB:
+ case FORMAT_TYPE_YVU:
for (i = 0; i < 12; i++) {
if ((i & 3) == 1)
addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE,
@@ -206,7 +206,7 @@ static void sun8i_de3_ccsc_enable(struct regmap *map, int layer, bool enable)
}
void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer,
- enum sun8i_csc_mode mode,
+ enum format_type fmt_type,
enum drm_color_encoding encoding,
enum drm_color_range range)
{
@@ -214,14 +214,14 @@ void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer,
if (mixer->cfg->is_de3) {
sun8i_de3_ccsc_set_coefficients(mixer->engine.regs, layer,
- mode, encoding, range);
+ fmt_type, encoding, range);
return;
}
base = ccsc_base[mixer->cfg->ccsc][layer];
sun8i_csc_set_coefficients(mixer->engine.regs, base,
- mode, encoding, range);
+ fmt_type, encoding, range);
}
void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable)
diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.h b/drivers/gpu/drm/sun4i/sun8i_csc.h
index 828b86fd0cab..7322770f39f0 100644
--- a/drivers/gpu/drm/sun4i/sun8i_csc.h
+++ b/drivers/gpu/drm/sun4i/sun8i_csc.h
@@ -22,14 +22,14 @@ struct sun8i_mixer;
#define SUN8I_CSC_CTRL_EN BIT(0)
-enum sun8i_csc_mode {
- SUN8I_CSC_MODE_OFF,
- SUN8I_CSC_MODE_YUV2RGB,
- SUN8I_CSC_MODE_YVU2RGB,
+enum format_type {
+ FORMAT_TYPE_RGB,
+ FORMAT_TYPE_YUV,
+ FORMAT_TYPE_YVU,
};
void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer,
- enum sun8i_csc_mode mode,
+ enum format_type fmt_type,
enum drm_color_encoding encoding,
enum drm_color_range range);
void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable);
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
index 9c09d9c08496..8a80934e928f 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
@@ -193,19 +193,19 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
return 0;
}
-static u32 sun8i_vi_layer_get_csc_mode(const struct drm_format_info *format)
+static u32 sun8i_vi_layer_get_format_type(const struct drm_format_info *format)
{
if (!format->is_yuv)
- return SUN8I_CSC_MODE_OFF;
+ return FORMAT_TYPE_RGB;
switch (format->format) {
case DRM_FORMAT_YVU411:
case DRM_FORMAT_YVU420:
case DRM_FORMAT_YVU422:
case DRM_FORMAT_YVU444:
- return SUN8I_CSC_MODE_YVU2RGB;
+ return FORMAT_TYPE_YVU;
default:
- return SUN8I_CSC_MODE_YUV2RGB;
+ return FORMAT_TYPE_YUV;
}
}
@@ -213,7 +213,7 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel,
int overlay, struct drm_plane *plane)
{
struct drm_plane_state *state = plane->state;
- u32 val, ch_base, csc_mode, hw_fmt;
+ u32 val, ch_base, fmt_type, hw_fmt;
const struct drm_format_info *fmt;
int ret;
@@ -231,9 +231,9 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel,
SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay),
SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK, val);
- csc_mode = sun8i_vi_layer_get_csc_mode(fmt);
- if (csc_mode != SUN8I_CSC_MODE_OFF) {
- sun8i_csc_set_ccsc_coefficients(mixer, channel, csc_mode,
+ fmt_type = sun8i_vi_layer_get_format_type(fmt);
+ if (fmt_type != FORMAT_TYPE_RGB) {
+ sun8i_csc_set_ccsc_coefficients(mixer, channel, fmt_type,
state->color_encoding,
state->color_range);
sun8i_csc_enable_ccsc(mixer, channel, true);
--
2.35.3

View File

@@ -1,38 +0,0 @@
From 7e2082f55e6595ca976245d7a7ac1d89d5b1258b Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Sun, 29 Sep 2024 22:04:48 +1300
Subject: drm: sun4i: de2/de3: add generic blender register reference function
The DE2 and DE3 engines have a blender register range within the
mixer engine register map, whereas the DE33 separates this out into
a separate display group.
Prepare for this by adding a function to look the blender reference up,
with a subsequent patch to add a conditional based on the DE type.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: Ryan Walklin <ryan@testtoast.com>
---
drivers/gpu/drm/sun4i/sun8i_mixer.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index 258f528202c1..ecba096c553b 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -227,6 +227,12 @@ sun8i_blender_base(struct sun8i_mixer *mixer)
return mixer->cfg->de_type == sun8i_mixer_de3 ? DE3_BLD_BASE : DE2_BLD_BASE;
}
+static inline struct regmap *
+sun8i_blender_regmap(struct sun8i_mixer *mixer)
+{
+ return mixer->engine.regs;
+}
+
static inline u32
sun8i_channel_base(struct sun8i_mixer *mixer, int channel)
{
--
2.51.0

View File

@@ -1,257 +0,0 @@
From 90f292bafa6d6198248b7349cd9945a1258ceaac Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Sun, 29 Sep 2024 22:04:45 +1300
Subject: drm: sun4i: de2/de3: add mixer version enum
The Allwinner DE2 and DE3 display engine mixers are currently identified
by a simple boolean flag. This will not scale to support additional DE
variants.
Convert the boolean flag to an enum.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: Ryan Walklin <ryan@testtoast.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
---
drivers/gpu/drm/sun4i/sun8i_csc.c | 2 +-
drivers/gpu/drm/sun4i/sun8i_mixer.c | 14 ++++++++++++--
drivers/gpu/drm/sun4i/sun8i_mixer.h | 11 ++++++++---
drivers/gpu/drm/sun4i/sun8i_ui_scaler.c | 2 +-
drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 8 ++++----
drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 4 ++--
6 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c
index e12a81fa9108..2d5a2cf7cba2 100644
--- a/drivers/gpu/drm/sun4i/sun8i_csc.c
+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
@@ -365,7 +365,7 @@ void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer,
{
u32 base;
- if (mixer->cfg->is_de3) {
+ if (mixer->cfg->de_type == sun8i_mixer_de3) {
sun8i_de3_ccsc_setup(&mixer->engine, layer,
fmt_type, encoding, range);
return;
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 1b498568e7df..35b1f3d50504 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -624,7 +624,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
if (!mixer->hw_preconfigured) {
/* Reset registers and disable unused sub-engines */
- if (mixer->cfg->is_de3) {
+ if (mixer->cfg->de_type == sun8i_mixer_de3) {
for (i = 0; i < DE3_MIXER_UNIT_SIZE; i += 4)
regmap_write(mixer->engine.regs, i, 0);
@@ -727,6 +727,7 @@ static void sun8i_mixer_remove(struct platform_device *pdev)
static const struct sun8i_mixer_cfg sun8i_a83t_mixer0_cfg = {
.ccsc = CCSC_MIXER0_LAYOUT,
+ .de_type = sun8i_mixer_de2,
.scaler_mask = 0xf,
.scanline_yuv = 2048,
.ui_num = 3,
@@ -735,6 +736,7 @@ static const struct sun8i_mixer_cfg sun8i_a83t_mixer0_cfg = {
static const struct sun8i_mixer_cfg sun8i_a83t_mixer1_cfg = {
.ccsc = CCSC_MIXER1_LAYOUT,
+ .de_type = sun8i_mixer_de2,
.scaler_mask = 0x3,
.scanline_yuv = 2048,
.ui_num = 1,
@@ -743,6 +745,7 @@ static const struct sun8i_mixer_cfg sun8i_a83t_mixer1_cfg = {
static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg = {
.ccsc = CCSC_MIXER0_LAYOUT,
+ .de_type = sun8i_mixer_de2,
.mod_rate = 432000000,
.scaler_mask = 0xf,
.scanline_yuv = 2048,
@@ -752,6 +755,7 @@ static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg = {
static const struct sun8i_mixer_cfg sun8i_r40_mixer0_cfg = {
.ccsc = CCSC_MIXER0_LAYOUT,
+ .de_type = sun8i_mixer_de2,
.mod_rate = 297000000,
.scaler_mask = 0xf,
.scanline_yuv = 2048,
@@ -761,6 +765,7 @@ static const struct sun8i_mixer_cfg sun8i_r40_mixer0_cfg = {
static const struct sun8i_mixer_cfg sun8i_r40_mixer1_cfg = {
.ccsc = CCSC_MIXER1_LAYOUT,
+ .de_type = sun8i_mixer_de2,
.mod_rate = 297000000,
.scaler_mask = 0x3,
.scanline_yuv = 2048,
@@ -769,6 +774,7 @@ static const struct sun8i_mixer_cfg sun8i_r40_mixer1_cfg = {
};
static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
+ .de_type = sun8i_mixer_de2,
.vi_num = 2,
.ui_num = 1,
.scaler_mask = 0x3,
@@ -779,6 +785,7 @@ static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
static const struct sun8i_mixer_cfg sun20i_d1_mixer0_cfg = {
.ccsc = CCSC_D1_MIXER0_LAYOUT,
+ .de_type = sun8i_mixer_de2,
.mod_rate = 297000000,
.scaler_mask = 0x3,
.scanline_yuv = 2048,
@@ -788,6 +795,7 @@ static const struct sun8i_mixer_cfg sun20i_d1_mixer0_cfg = {
static const struct sun8i_mixer_cfg sun20i_d1_mixer1_cfg = {
.ccsc = CCSC_MIXER1_LAYOUT,
+ .de_type = sun8i_mixer_de2,
.mod_rate = 297000000,
.scaler_mask = 0x1,
.scanline_yuv = 1024,
@@ -797,6 +805,7 @@ static const struct sun8i_mixer_cfg sun20i_d1_mixer1_cfg = {
static const struct sun8i_mixer_cfg sun50i_a64_mixer0_cfg = {
.ccsc = CCSC_MIXER0_LAYOUT,
+ .de_type = sun8i_mixer_de2,
.mod_rate = 297000000,
.scaler_mask = 0xf,
.scanline_yuv = 4096,
@@ -806,6 +815,7 @@ static const struct sun8i_mixer_cfg sun50i_a64_mixer0_cfg = {
static const struct sun8i_mixer_cfg sun50i_a64_mixer1_cfg = {
.ccsc = CCSC_MIXER1_LAYOUT,
+ .de_type = sun8i_mixer_de2,
.mod_rate = 297000000,
.scaler_mask = 0x3,
.scanline_yuv = 2048,
@@ -815,7 +825,7 @@ static const struct sun8i_mixer_cfg sun50i_a64_mixer1_cfg = {
static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = {
.ccsc = CCSC_MIXER0_LAYOUT,
- .is_de3 = true,
+ .de_type = sun8i_mixer_de3,
.has_formatter = 1,
.mod_rate = 600000000,
.scaler_mask = 0xf,
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index 860a2f2cec24..258f528202c1 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -151,6 +151,11 @@ enum {
CCSC_D1_MIXER0_LAYOUT,
};
+enum sun8i_mixer_type {
+ sun8i_mixer_de2,
+ sun8i_mixer_de3,
+};
+
/**
* struct sun8i_mixer_cfg - mixer HW configuration
* @vi_num: number of VI channels
@@ -172,7 +177,7 @@ struct sun8i_mixer_cfg {
int scaler_mask;
int ccsc;
unsigned long mod_rate;
- unsigned int is_de3 : 1;
+ unsigned int de_type;
unsigned int has_formatter : 1;
unsigned int scanline_yuv;
};
@@ -219,13 +224,13 @@ engine_to_sun8i_mixer(struct sunxi_engine *engine)
static inline u32
sun8i_blender_base(struct sun8i_mixer *mixer)
{
- return mixer->cfg->is_de3 ? DE3_BLD_BASE : DE2_BLD_BASE;
+ return mixer->cfg->de_type == sun8i_mixer_de3 ? DE3_BLD_BASE : DE2_BLD_BASE;
}
static inline u32
sun8i_channel_base(struct sun8i_mixer *mixer, int channel)
{
- if (mixer->cfg->is_de3)
+ if (mixer->cfg->de_type == sun8i_mixer_de3)
return DE3_CH_BASE + channel * DE3_CH_SIZE;
else
return DE2_CH_BASE + channel * DE2_CH_SIZE;
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
index ae0806bccac7..504ffa0971a4 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
@@ -93,7 +93,7 @@ static u32 sun8i_ui_scaler_base(struct sun8i_mixer *mixer, int channel)
{
int vi_num = mixer->cfg->vi_num;
- if (mixer->cfg->is_de3)
+ if (mixer->cfg->de_type == sun8i_mixer_de3)
return DE3_VI_SCALER_UNIT_BASE +
DE3_VI_SCALER_UNIT_SIZE * vi_num +
DE3_UI_SCALER_UNIT_SIZE * (channel - vi_num);
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
index 3c657b069d1f..4647e9bcccaa 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
@@ -25,7 +25,7 @@ static void sun8i_vi_layer_update_alpha(struct sun8i_mixer *mixer, int channel,
ch_base = sun8i_channel_base(mixer, channel);
- if (mixer->cfg->is_de3) {
+ if (mixer->cfg->de_type >= sun8i_mixer_de3) {
mask = SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK |
SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MODE_MASK;
val = SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA
@@ -483,7 +483,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
layer->channel = index;
layer->overlay = 0;
- if (mixer->cfg->is_de3) {
+ if (mixer->cfg->de_type >= sun8i_mixer_de3) {
formats = sun8i_vi_layer_de3_formats;
format_count = ARRAY_SIZE(sun8i_vi_layer_de3_formats);
} else {
@@ -507,7 +507,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
plane_cnt = mixer->cfg->ui_num + mixer->cfg->vi_num;
- if (mixer->cfg->vi_num == 1 || mixer->cfg->is_de3) {
+ if (mixer->cfg->vi_num == 1 || mixer->cfg->de_type >= sun8i_mixer_de3) {
ret = drm_plane_create_alpha_property(&layer->plane);
if (ret) {
dev_err(drm->dev, "Couldn't add alpha property\n");
@@ -524,7 +524,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
supported_encodings = BIT(DRM_COLOR_YCBCR_BT601) |
BIT(DRM_COLOR_YCBCR_BT709);
- if (mixer->cfg->is_de3)
+ if (mixer->cfg->de_type >= sun8i_mixer_de3)
supported_encodings |= BIT(DRM_COLOR_YCBCR_BT2020);
supported_ranges = BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
index 2e49a6e5f1f1..aa346c3beb30 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
@@ -835,7 +835,7 @@ static const u32 bicubic4coefftab32[480] = {
static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel)
{
- if (mixer->cfg->is_de3)
+ if (mixer->cfg->de_type == sun8i_mixer_de3)
return DE3_VI_SCALER_UNIT_BASE +
DE3_VI_SCALER_UNIT_SIZE * channel;
else
@@ -982,7 +982,7 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
cvphase = vphase;
}
- if (mixer->cfg->is_de3) {
+ if (mixer->cfg->de_type >= sun8i_mixer_de3) {
u32 val;
if (format->hsub == 1 && format->vsub == 1)
--
2.51.0

View File

@@ -1,64 +0,0 @@
From 000c586a34ad82e4673e6dfda5457147b0d85606 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Sun, 29 Sep 2024 22:04:35 +1300
Subject: drm: sun4i: de2/de3: call csc setup also for UI layer
Currently, only VI layer calls CSC setup function. This comes from DE2
limitation, which doesn't have CSC unit for UI layers. However, DE3 has
separate CSC units for each layer. This allows display pipeline to make
output signal in different color spaces. To support both use cases, add
a call to CSC setup function also in UI layer code. For DE2, this will
be a no-op, but it will allow DE3 to output signal in multiple formats.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: Ryan Walklin <ryan@testtoast.com>
---
drivers/gpu/drm/sun4i/sun8i_csc.c | 8 +++++---
drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 6 ++++++
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c
index 0dcbc0866ae8..68d955c63b05 100644
--- a/drivers/gpu/drm/sun4i/sun8i_csc.c
+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
@@ -209,8 +209,10 @@ void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer,
return;
}
- base = ccsc_base[mixer->cfg->ccsc][layer];
+ if (layer < mixer->cfg->vi_num) {
+ base = ccsc_base[mixer->cfg->ccsc][layer];
- sun8i_csc_setup(mixer->engine.regs, base,
- fmt_type, encoding, range);
+ sun8i_csc_setup(mixer->engine.regs, base,
+ fmt_type, encoding, range);
+ }
}
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
index b90e5edef4e8..aa987bca1dbb 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
@@ -20,6 +20,7 @@
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_probe_helper.h>
+#include "sun8i_csc.h"
#include "sun8i_mixer.h"
#include "sun8i_ui_layer.h"
#include "sun8i_ui_scaler.h"
@@ -135,6 +136,11 @@ static int sun8i_ui_layer_update_formats(struct sun8i_mixer *mixer, int channel,
SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay),
SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_MASK, val);
+ /* Note: encoding and range arguments are ignored for RGB */
+ sun8i_csc_set_ccsc(mixer, channel, FORMAT_TYPE_RGB,
+ DRM_COLOR_YCBCR_BT601,
+ DRM_COLOR_YCBCR_FULL_RANGE);
+
return 0;
}
--
2.35.3

View File

@@ -1,129 +0,0 @@
From 4042b1c4ed4e1cfe9170cbb57d49e13f419afa3d Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Sun, 29 Sep 2024 22:04:46 +1300
Subject: drm: sun4i: de2/de3: refactor mixer initialisation
Now that the DE variant can be selected by enum, take the oppportunity
to factor out some common initialisation code to a separate function.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: Ryan Walklin <ryan@testtoast.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
---
drivers/gpu/drm/sun4i/sun8i_mixer.c | 70 ++++++++++++++++-------------
1 file changed, 38 insertions(+), 32 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 35b1f3d50504..6d26381a2f2b 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -498,6 +498,42 @@ static int sun8i_mixer_of_get_id(struct device_node *node)
return of_ep.id;
}
+static void sun8i_mixer_init(struct sun8i_mixer *mixer)
+{
+ unsigned int base = sun8i_blender_base(mixer);
+ int plane_cnt, i;
+
+ if (!mixer->hw_preconfigured) {
+ /* Enable the mixer */
+ regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL,
+ SUN8I_MIXER_GLOBAL_CTL_RT_EN);
+ }
+
+ /* Set background color to black */
+ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR(base),
+ SUN8I_MIXER_BLEND_COLOR_BLACK);
+
+ /*
+ * Set fill color of bottom plane to black. Generally not needed
+ * except when VI plane is at bottom (zpos = 0) and enabled.
+ */
+ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
+ SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
+ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0),
+ SUN8I_MIXER_BLEND_COLOR_BLACK);
+
+ plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num;
+ for (i = 0; i < plane_cnt; i++)
+ regmap_write(mixer->engine.regs,
+ SUN8I_MIXER_BLEND_MODE(base, i),
+ SUN8I_MIXER_BLEND_MODE_DEF);
+
+ if (!mixer->hw_preconfigured) {
+ regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
+ SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0);
+ }
+}
+
static int sun8i_mixer_bind(struct device *dev, struct device *master,
void *data)
{
@@ -506,8 +542,6 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
struct sun4i_drv *drv = drm->dev_private;
struct sun8i_mixer *mixer;
void __iomem *regs;
- unsigned int base;
- int plane_cnt;
int i, ret;
/*
@@ -620,8 +654,6 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
list_add_tail(&mixer->engine.list, &drv->engine_list);
- base = sun8i_blender_base(mixer);
-
if (!mixer->hw_preconfigured) {
/* Reset registers and disable unused sub-engines */
if (mixer->cfg->de_type == sun8i_mixer_de3) {
@@ -638,7 +670,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
regmap_write(mixer->engine.regs, SUN50I_MIXER_FMT_EN, 0);
regmap_write(mixer->engine.regs, SUN50I_MIXER_CDC0_EN, 0);
regmap_write(mixer->engine.regs, SUN50I_MIXER_CDC1_EN, 0);
- } else {
+ } else if (mixer->cfg->de_type == sun8i_mixer_de2) {
for (i = 0; i < DE2_MIXER_UNIT_SIZE; i += 4)
regmap_write(mixer->engine.regs, i, 0);
@@ -651,35 +683,9 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
regmap_write(mixer->engine.regs, SUN8I_MIXER_DCSC_EN, 0);
}
- /* Enable the mixer */
- regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL,
- SUN8I_MIXER_GLOBAL_CTL_RT_EN);
} /* hw_preconfigured */
- /* Set background color to black */
- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR(base),
- SUN8I_MIXER_BLEND_COLOR_BLACK);
-
- /*
- * Set fill color of bottom plane to black. Generally not needed
- * except when VI plane is at bottom (zpos = 0) and enabled.
- */
- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
- SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0),
- SUN8I_MIXER_BLEND_COLOR_BLACK);
-
- plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num;
- for (i = 0; i < plane_cnt; i++)
- regmap_write(mixer->engine.regs,
- SUN8I_MIXER_BLEND_MODE(base, i),
- SUN8I_MIXER_BLEND_MODE_DEF);
-
- if (!mixer->hw_preconfigured) {
- regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
- SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0);
- }
-
+ sun8i_mixer_init(mixer);
return 0;
err_disable_bus_clk:
--
2.51.0

View File

@@ -1,117 +0,0 @@
From 91877bc54df84b7fabe8265b152ac38032193403 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Sun, 29 Sep 2024 22:04:49 +1300
Subject: drm: sun4i: de2/de3: use generic register reference function for
layer configuration
Use the new blender register lookup function where required in the layer
commit and update code.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: Ryan Walklin <ryan@testtoast.com>
---
drivers/gpu/drm/sun4i/sun8i_mixer.c | 5 +++--
drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 7 +++++--
drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 6 ++++--
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 0419859a9f89..a319db11cc68 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -280,6 +280,7 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine,
{
struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine);
u32 bld_base = sun8i_blender_base(mixer);
+ struct regmap *bld_regs = sun8i_blender_regmap(mixer);
struct drm_plane_state *plane_state;
struct drm_plane *plane;
u32 route = 0, pipe_en = 0;
@@ -346,8 +347,8 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine,
pipe_en |= SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
}
- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ROUTE(bld_base), route);
- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
+ regmap_write(bld_regs, SUN8I_MIXER_BLEND_ROUTE(bld_base), route);
+ regmap_write(bld_regs, SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
pipe_en | SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_DBUFF,
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
index 3840242dfaf3..70218b7132ad 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
@@ -24,6 +24,7 @@
#include "sun8i_mixer.h"
#include "sun8i_ui_layer.h"
#include "sun8i_ui_scaler.h"
+#include "sun8i_vi_scaler.h"
static void sun8i_ui_layer_update_alpha(struct sun8i_mixer *mixer, int channel,
int overlay, struct drm_plane *plane)
@@ -52,6 +53,7 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
{
struct drm_plane_state *state = plane->state;
u32 src_w, src_h, dst_w, dst_h;
+ struct regmap *bld_regs;
u32 bld_base, ch_base;
u32 outsize, insize;
u32 hphase, vphase;
@@ -60,6 +62,7 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
channel, overlay);
bld_base = sun8i_blender_base(mixer);
+ bld_regs = sun8i_blender_regmap(mixer);
ch_base = sun8i_channel_base(mixer, channel);
src_w = drm_rect_width(&state->src) >> 16;
@@ -104,10 +107,10 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
DRM_DEBUG_DRIVER("Layer destination coordinates X: %d Y: %d\n",
state->dst.x1, state->dst.y1);
DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h);
- regmap_write(mixer->engine.regs,
+ regmap_write(bld_regs,
SUN8I_MIXER_BLEND_ATTR_COORD(bld_base, zpos),
SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1));
- regmap_write(mixer->engine.regs,
+ regmap_write(bld_regs,
SUN8I_MIXER_BLEND_ATTR_INSIZE(bld_base, zpos),
outsize);
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
index e348fd0a3d81..d19349eecc9d 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
@@ -55,6 +55,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
struct drm_plane_state *state = plane->state;
const struct drm_format_info *format = state->fb->format;
u32 src_w, src_h, dst_w, dst_h;
+ struct regmap *bld_regs;
u32 bld_base, ch_base;
u32 outsize, insize;
u32 hphase, vphase;
@@ -66,6 +67,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
channel, overlay);
bld_base = sun8i_blender_base(mixer);
+ bld_regs = sun8i_blender_regmap(mixer);
ch_base = sun8i_channel_base(mixer, channel);
src_w = drm_rect_width(&state->src) >> 16;
@@ -182,10 +184,10 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
DRM_DEBUG_DRIVER("Layer destination coordinates X: %d Y: %d\n",
state->dst.x1, state->dst.y1);
DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h);
- regmap_write(mixer->engine.regs,
+ regmap_write(bld_regs,
SUN8I_MIXER_BLEND_ATTR_COORD(bld_base, zpos),
SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1));
- regmap_write(mixer->engine.regs,
+ regmap_write(bld_regs,
SUN8I_MIXER_BLEND_ATTR_INSIZE(bld_base, zpos),
outsize);
--
2.51.0

View File

@@ -1,164 +0,0 @@
From 8bdcc131fedb576a8db65bb6e87ca8742660add0 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Sun, 29 Sep 2024 22:04:37 +1300
Subject: drm: sun4i: de3: Add YUV formatter module
The display engine formatter (FMT) module is present in the DE3 engine
and provides YUV444 to YUV422/YUV420 conversion, format re-mapping and
color depth conversion.
Add support for this module.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: Ryan Walklin <ryan@testtoast.com>
---
drivers/gpu/drm/sun4i/Makefile | 3 +-
drivers/gpu/drm/sun4i/sun50i_fmt.c | 82 ++++++++++++++++++++++++++++++
drivers/gpu/drm/sun4i/sun50i_fmt.h | 32 ++++++++++++
3 files changed, 116 insertions(+), 1 deletion(-)
create mode 100644 drivers/gpu/drm/sun4i/sun50i_fmt.c
create mode 100644 drivers/gpu/drm/sun4i/sun50i_fmt.h
diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile
index bad7497a0d11..3f516329f51e 100644
--- a/drivers/gpu/drm/sun4i/Makefile
+++ b/drivers/gpu/drm/sun4i/Makefile
@@ -16,7 +16,8 @@ sun8i-drm-hdmi-y += sun8i_hdmi_phy_clk.o
sun8i-mixer-y += sun8i_mixer.o sun8i_ui_layer.o \
sun8i_vi_layer.o sun8i_ui_scaler.o \
- sun8i_vi_scaler.o sun8i_csc.o
+ sun8i_vi_scaler.o sun8i_csc.o \
+ sun50i_fmt.o
sun4i-tcon-y += sun4i_crtc.o
sun4i-tcon-y += sun4i_tcon_dclk.o
diff --git a/drivers/gpu/drm/sun4i/sun50i_fmt.c b/drivers/gpu/drm/sun4i/sun50i_fmt.c
new file mode 100644
index 000000000000..050a8716ae86
--- /dev/null
+++ b/drivers/gpu/drm/sun4i/sun50i_fmt.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) Jernej Skrabec <jernej.skrabec@gmail.com>
+ */
+
+#include <uapi/linux/media-bus-format.h>
+
+#include "sun50i_fmt.h"
+
+static bool sun50i_fmt_is_10bit(u32 format)
+{
+ switch (format) {
+ case MEDIA_BUS_FMT_RGB101010_1X30:
+ case MEDIA_BUS_FMT_YUV10_1X30:
+ case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
+ case MEDIA_BUS_FMT_UYVY10_1X20:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static u32 sun50i_fmt_get_colorspace(u32 format)
+{
+ switch (format) {
+ case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
+ case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
+ return SUN50I_FMT_CS_YUV420;
+ case MEDIA_BUS_FMT_UYVY8_1X16:
+ case MEDIA_BUS_FMT_UYVY10_1X20:
+ return SUN50I_FMT_CS_YUV422;
+ default:
+ return SUN50I_FMT_CS_YUV444RGB;
+ }
+}
+
+static void sun50i_fmt_de3_limits(u32 *limits, u32 colorspace, bool bit10)
+{
+ if (colorspace != SUN50I_FMT_CS_YUV444RGB) {
+ limits[0] = SUN50I_FMT_LIMIT(64, 940);
+ limits[1] = SUN50I_FMT_LIMIT(64, 960);
+ limits[2] = SUN50I_FMT_LIMIT(64, 960);
+ } else if (bit10) {
+ limits[0] = SUN50I_FMT_LIMIT(0, 1023);
+ limits[1] = SUN50I_FMT_LIMIT(0, 1023);
+ limits[2] = SUN50I_FMT_LIMIT(0, 1023);
+ } else {
+ limits[0] = SUN50I_FMT_LIMIT(0, 1021);
+ limits[1] = SUN50I_FMT_LIMIT(0, 1021);
+ limits[2] = SUN50I_FMT_LIMIT(0, 1021);
+ }
+}
+
+void sun50i_fmt_setup(struct sun8i_mixer *mixer, u16 width,
+ u16 height, u32 format)
+{
+ u32 colorspace, limit[3], base;
+ struct regmap *regs;
+ bool bit10;
+
+ colorspace = sun50i_fmt_get_colorspace(format);
+ bit10 = sun50i_fmt_is_10bit(format);
+ base = SUN50I_FMT_DE3;
+ regs = sun8i_blender_regmap(mixer);
+
+ sun50i_fmt_de3_limits(limit, colorspace, bit10);
+
+ regmap_write(regs, SUN50I_FMT_CTRL(base), 0);
+
+ regmap_write(regs, SUN50I_FMT_SIZE(base),
+ SUN8I_MIXER_SIZE(width, height));
+ regmap_write(regs, SUN50I_FMT_SWAP(base), 0);
+ regmap_write(regs, SUN50I_FMT_DEPTH(base), bit10);
+ regmap_write(regs, SUN50I_FMT_FORMAT(base), colorspace);
+ regmap_write(regs, SUN50I_FMT_COEF(base), 0);
+
+ regmap_write(regs, SUN50I_FMT_LMT_Y(base), limit[0]);
+ regmap_write(regs, SUN50I_FMT_LMT_C0(base), limit[1]);
+ regmap_write(regs, SUN50I_FMT_LMT_C1(base), limit[2]);
+
+ regmap_write(regs, SUN50I_FMT_CTRL(base), 1);
+}
diff --git a/drivers/gpu/drm/sun4i/sun50i_fmt.h b/drivers/gpu/drm/sun4i/sun50i_fmt.h
new file mode 100644
index 000000000000..4127f7206aad
--- /dev/null
+++ b/drivers/gpu/drm/sun4i/sun50i_fmt.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) Jernej Skrabec <jernej.skrabec@gmail.com>
+ */
+
+#ifndef _SUN50I_FMT_H_
+#define _SUN50I_FMT_H_
+
+#include "sun8i_mixer.h"
+
+#define SUN50I_FMT_DE3 0xa8000
+
+#define SUN50I_FMT_CTRL(base) ((base) + 0x00)
+#define SUN50I_FMT_SIZE(base) ((base) + 0x04)
+#define SUN50I_FMT_SWAP(base) ((base) + 0x08)
+#define SUN50I_FMT_DEPTH(base) ((base) + 0x0c)
+#define SUN50I_FMT_FORMAT(base) ((base) + 0x10)
+#define SUN50I_FMT_COEF(base) ((base) + 0x14)
+#define SUN50I_FMT_LMT_Y(base) ((base) + 0x20)
+#define SUN50I_FMT_LMT_C0(base) ((base) + 0x24)
+#define SUN50I_FMT_LMT_C1(base) ((base) + 0x28)
+
+#define SUN50I_FMT_LIMIT(low, high) (((high) << 16) | (low))
+
+#define SUN50I_FMT_CS_YUV444RGB 0
+#define SUN50I_FMT_CS_YUV422 1
+#define SUN50I_FMT_CS_YUV420 2
+
+void sun50i_fmt_setup(struct sun8i_mixer *mixer, u16 width,
+ u16 height, u32 format);
+
+#endif
--
2.35.3

View File

@@ -1,124 +0,0 @@
From 681152c96fe02df6fb36ecef2fed562511d871fe Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Sun, 29 Sep 2024 22:04:40 +1300
Subject: drm: sun4i: de3: add YUV support to the DE3 mixer
The mixer in the DE3 display engine supports YUV 8 and 10 bit
formats in addition to 8-bit RGB. Add the required register
configuration and format enumeration callback functions to the mixer,
and store the in-use output format (defaulting to RGB) and color
encoding in engine variables.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: Ryan Walklin <ryan@testtoast.com>
---
drivers/gpu/drm/sun4i/sun8i_mixer.c | 47 ++++++++++++++++++++++++++++
drivers/gpu/drm/sun4i/sunxi_engine.h | 5 +++
2 files changed, 52 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index fe1b58004a7b..1b498568e7df 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -23,8 +23,11 @@
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_probe_helper.h>
+#include <uapi/linux/media-bus-format.h>
+
#include "sun4i_drv.h"
#include "sun4i_tcon.h"
+#include "sun50i_fmt.h"
#include "sun8i_mixer.h"
#include "sun8i_ui_layer.h"
#include "sun8i_vi_layer.h"
@@ -420,12 +423,52 @@ static void sun8i_mixer_mode_set(struct sunxi_engine *engine,
DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n",
interlaced ? "on" : "off");
+
+ if (engine->format == MEDIA_BUS_FMT_RGB888_1X24)
+ val = SUN8I_MIXER_BLEND_COLOR_BLACK;
+ else
+ val = 0xff108080;
+
+ regmap_write(mixer->engine.regs,
+ SUN8I_MIXER_BLEND_BKCOLOR(bld_base), val);
+ regmap_write(mixer->engine.regs,
+ SUN8I_MIXER_BLEND_ATTR_FCOLOR(bld_base, 0), val);
+
+ if (mixer->cfg->has_formatter)
+ sun50i_fmt_setup(mixer, mode->hdisplay,
+ mode->vdisplay, mixer->engine.format);
+}
+
+static u32 *sun8i_mixer_get_supported_fmts(struct sunxi_engine *engine, u32 *num)
+{
+ struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine);
+ u32 *formats, count;
+
+ count = 0;
+
+ formats = kcalloc(5, sizeof(*formats), GFP_KERNEL);
+ if (!formats)
+ return NULL;
+
+ if (mixer->cfg->has_formatter) {
+ formats[count++] = MEDIA_BUS_FMT_UYYVYY10_0_5X30;
+ formats[count++] = MEDIA_BUS_FMT_YUV8_1X24;
+ formats[count++] = MEDIA_BUS_FMT_UYVY8_1X16;
+ formats[count++] = MEDIA_BUS_FMT_UYYVYY8_0_5X24;
+ }
+
+ formats[count++] = MEDIA_BUS_FMT_RGB888_1X24;
+
+ *num = count;
+
+ return formats;
}
static const struct sunxi_engine_ops sun8i_engine_ops = {
.commit = sun8i_mixer_commit,
.layers_init = sun8i_layers_init,
.mode_set = sun8i_mixer_mode_set,
+ .get_supported_fmts = sun8i_mixer_get_supported_fmts,
};
static const struct regmap_config sun8i_mixer_regmap_config = {
@@ -487,6 +530,10 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
mixer->engine.ops = &sun8i_engine_ops;
mixer->engine.node = dev->of_node;
mixer->drv = drv;
+ /* default output format, supported by all mixers */
+ mixer->engine.format = MEDIA_BUS_FMT_RGB888_1X24;
+ /* default color encoding, ignored with RGB I/O */
+ mixer->engine.encoding = DRM_COLOR_YCBCR_BT601;
if (of_property_present(dev->of_node, "iommus")) {
/*
diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h
index c48cbc1aceb8..ffafc29b3a0c 100644
--- a/drivers/gpu/drm/sun4i/sunxi_engine.h
+++ b/drivers/gpu/drm/sun4i/sunxi_engine.h
@@ -6,6 +6,8 @@
#ifndef _SUNXI_ENGINE_H_
#define _SUNXI_ENGINE_H_
+#include <drm/drm_color_mgmt.h>
+
struct drm_plane;
struct drm_crtc;
struct drm_device;
@@ -151,6 +153,9 @@ struct sunxi_engine {
int id;
+ u32 format;
+ enum drm_color_encoding encoding;
+
/* Engine list management */
struct list_head list;
};
--
2.51.0

View File

@@ -1,83 +0,0 @@
From 1000fdf61f22e06c607f003ef500d75266bc3920 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Sun, 29 Sep 2024 22:04:43 +1300
Subject: drm: sun4i: de3: add YUV support to the TCON
Account for U/V channel subsampling by reducing the dot clock and
resolution with a divider in the DE3 timing controller if a YUV format
is selected.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: Ryan Walklin <ryan@testtoast.com>
---
drivers/gpu/drm/sun4i/sun4i_tcon.c | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 221df37406d8..43cc8908a03f 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -679,14 +679,26 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
const struct drm_display_mode *mode)
{
- unsigned int bp, hsync, vsync, vtotal;
+ unsigned int bp, hsync, vsync, vtotal, div;
+ struct sun4i_crtc *scrtc = tcon->crtc;
+ struct sunxi_engine *engine = scrtc->engine;
u8 clk_delay;
u32 val;
WARN_ON(!tcon->quirks->has_channel_1);
+ switch (engine->format) {
+ case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
+ case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
+ div = 2;
+ break;
+ default:
+ div = 1;
+ break;
+ }
+
/* Configure the dot clock */
- clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000);
+ clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000 / div);
/* Adjust clock delay */
clk_delay = sun4i_tcon_get_clk_delay(mode, 1);
@@ -705,17 +717,17 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
/* Set the input resolution */
regmap_write(tcon->regs, SUN4I_TCON1_BASIC0_REG,
- SUN4I_TCON1_BASIC0_X(mode->crtc_hdisplay) |
+ SUN4I_TCON1_BASIC0_X(mode->crtc_hdisplay / div) |
SUN4I_TCON1_BASIC0_Y(mode->crtc_vdisplay));
/* Set the upscaling resolution */
regmap_write(tcon->regs, SUN4I_TCON1_BASIC1_REG,
- SUN4I_TCON1_BASIC1_X(mode->crtc_hdisplay) |
+ SUN4I_TCON1_BASIC1_X(mode->crtc_hdisplay / div) |
SUN4I_TCON1_BASIC1_Y(mode->crtc_vdisplay));
/* Set the output resolution */
regmap_write(tcon->regs, SUN4I_TCON1_BASIC2_REG,
- SUN4I_TCON1_BASIC2_X(mode->crtc_hdisplay) |
+ SUN4I_TCON1_BASIC2_X(mode->crtc_hdisplay / div) |
SUN4I_TCON1_BASIC2_Y(mode->crtc_vdisplay));
/* Set horizontal display timings */
@@ -723,8 +735,8 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n",
mode->htotal, bp);
regmap_write(tcon->regs, SUN4I_TCON1_BASIC3_REG,
- SUN4I_TCON1_BASIC3_H_TOTAL(mode->crtc_htotal) |
- SUN4I_TCON1_BASIC3_H_BACKPORCH(bp));
+ SUN4I_TCON1_BASIC3_H_TOTAL(mode->crtc_htotal / div) |
+ SUN4I_TCON1_BASIC3_H_BACKPORCH(bp / div));
bp = mode->crtc_vtotal - mode->crtc_vsync_start;
DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
--
2.51.0

View File

@@ -1,225 +0,0 @@
From a23ed976ee720c2445791716d975f040ef576c2b Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Sun, 29 Sep 2024 22:04:42 +1300
Subject: drm: sun4i: de3: add YUV support to the color space correction module
Add coefficients and support for YUV formats to the display engine
colorspace and dynamic range correction submodule.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: Ryan Walklin <ryan@testtoast.com>
---
drivers/gpu/drm/sun4i/sun8i_csc.c | 164 +++++++++++++++++++++++++++++-
1 file changed, 162 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c
index 8a336ccb27d3..e12a81fa9108 100644
--- a/drivers/gpu/drm/sun4i/sun8i_csc.c
+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
@@ -5,6 +5,8 @@
#include <drm/drm_print.h>
+#include <uapi/linux/media-bus-format.h>
+
#include "sun8i_csc.h"
#include "sun8i_mixer.h"
@@ -107,6 +109,135 @@ static const u32 yuv2rgb_de3[2][3][12] = {
},
};
+/* always convert to limited mode */
+static const u32 rgb2yuv_de3[3][12] = {
+ [DRM_COLOR_YCBCR_BT601] = {
+ 0x0000837A, 0x0001021D, 0x00003221, 0x00000040,
+ 0xFFFFB41C, 0xFFFF6B03, 0x0000E0E1, 0x00000200,
+ 0x0000E0E1, 0xFFFF43B1, 0xFFFFDB6E, 0x00000200,
+ },
+ [DRM_COLOR_YCBCR_BT709] = {
+ 0x00005D7C, 0x00013A7C, 0x00001FBF, 0x00000040,
+ 0xFFFFCC78, 0xFFFF52A7, 0x0000E0E1, 0x00000200,
+ 0x0000E0E1, 0xFFFF33BE, 0xFFFFEB61, 0x00000200,
+ },
+ [DRM_COLOR_YCBCR_BT2020] = {
+ 0x00007384, 0x00012A21, 0x00001A13, 0x00000040,
+ 0xFFFFC133, 0xFFFF5DEC, 0x0000E0E1, 0x00000200,
+ 0x0000E0E1, 0xFFFF3135, 0xFFFFEDEA, 0x00000200,
+ },
+};
+
+/* always convert to limited mode */
+static const u32 yuv2yuv_de3[2][3][3][12] = {
+ [DRM_COLOR_YCBCR_LIMITED_RANGE] = {
+ [DRM_COLOR_YCBCR_BT601] = {
+ [DRM_COLOR_YCBCR_BT601] = {
+ 0x00020000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00020000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00020000, 0x00000000,
+ },
+ [DRM_COLOR_YCBCR_BT709] = {
+ 0x00020000, 0xFFFFC4D7, 0xFFFF9589, 0xFFC00040,
+ 0x00000000, 0x0002098B, 0x00003AAF, 0xFE000200,
+ 0x00000000, 0x0000266D, 0x00020CF8, 0xFE000200,
+ },
+ [DRM_COLOR_YCBCR_BT2020] = {
+ 0x00020000, 0xFFFFBFCE, 0xFFFFC5FF, 0xFFC00040,
+ 0x00000000, 0x00020521, 0x00001F89, 0xFE000200,
+ 0x00000000, 0x00002C87, 0x00020F07, 0xFE000200,
+ },
+ },
+ [DRM_COLOR_YCBCR_BT709] = {
+ [DRM_COLOR_YCBCR_BT601] = {
+ 0x00020000, 0x000032D9, 0x00006226, 0xFFC00040,
+ 0x00000000, 0x0001FACE, 0xFFFFC759, 0xFE000200,
+ 0x00000000, 0xFFFFDAE7, 0x0001F780, 0xFE000200,
+ },
+ [DRM_COLOR_YCBCR_BT709] = {
+ 0x00020000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00020000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00020000, 0x00000000,
+ },
+ [DRM_COLOR_YCBCR_BT2020] = {
+ 0x00020000, 0xFFFFF782, 0x00003036, 0xFFC00040,
+ 0x00000000, 0x0001FD99, 0xFFFFE5CA, 0xFE000200,
+ 0x00000000, 0x000005E4, 0x0002015A, 0xFE000200,
+ },
+ },
+ [DRM_COLOR_YCBCR_BT2020] = {
+ [DRM_COLOR_YCBCR_BT601] = {
+ 0x00020000, 0x00003B03, 0x000034D2, 0xFFC00040,
+ 0x00000000, 0x0001FD8C, 0xFFFFE183, 0xFE000200,
+ 0x00000000, 0xFFFFD4F3, 0x0001F3FA, 0xFE000200,
+ },
+ [DRM_COLOR_YCBCR_BT709] = {
+ 0x00020000, 0x00000916, 0xFFFFD061, 0xFFC00040,
+ 0x00000000, 0x0002021C, 0x00001A40, 0xFE000200,
+ 0x00000000, 0xFFFFFA19, 0x0001FE5A, 0xFE000200,
+ },
+ [DRM_COLOR_YCBCR_BT2020] = {
+ 0x00020000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00020000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00020000, 0x00000000,
+ },
+ },
+ },
+ [DRM_COLOR_YCBCR_FULL_RANGE] = {
+ [DRM_COLOR_YCBCR_BT601] = {
+ [DRM_COLOR_YCBCR_BT601] = {
+ 0x0001B7B8, 0x00000000, 0x00000000, 0x00000040,
+ 0x00000000, 0x0001C1C2, 0x00000000, 0xFE000200,
+ 0x00000000, 0x00000000, 0x0001C1C2, 0xFE000200,
+ },
+ [DRM_COLOR_YCBCR_BT709] = {
+ 0x0001B7B8, 0xFFFFCC08, 0xFFFFA27B, 0x00000040,
+ 0x00000000, 0x0001CA24, 0x0000338D, 0xFE000200,
+ 0x00000000, 0x000021C1, 0x0001CD26, 0xFE000200,
+ },
+ [DRM_COLOR_YCBCR_BT2020] = {
+ 0x0001B7B8, 0xFFFFC79C, 0xFFFFCD0C, 0x00000040,
+ 0x00000000, 0x0001C643, 0x00001BB4, 0xFE000200,
+ 0x00000000, 0x0000271D, 0x0001CEF5, 0xFE000200,
+ },
+ },
+ [DRM_COLOR_YCBCR_BT709] = {
+ [DRM_COLOR_YCBCR_BT601] = {
+ 0x0001B7B8, 0x00002CAB, 0x00005638, 0x00000040,
+ 0x00000000, 0x0001BD32, 0xFFFFCE3C, 0xFE000200,
+ 0x00000000, 0xFFFFDF6A, 0x0001BA4A, 0xFE000200,
+ },
+ [DRM_COLOR_YCBCR_BT709] = {
+ 0x0001B7B8, 0x00000000, 0x00000000, 0x00000040,
+ 0x00000000, 0x0001C1C2, 0x00000000, 0xFE000200,
+ 0x00000000, 0x00000000, 0x0001C1C2, 0xFE000200,
+ },
+ [DRM_COLOR_YCBCR_BT2020] = {
+ 0x0001B7B8, 0xFFFFF88A, 0x00002A5A, 0x00000040,
+ 0x00000000, 0x0001BFA5, 0xFFFFE8FA, 0xFE000200,
+ 0x00000000, 0x0000052D, 0x0001C2F1, 0xFE000200,
+ },
+ },
+ [DRM_COLOR_YCBCR_BT2020] = {
+ [DRM_COLOR_YCBCR_BT601] = {
+ 0x0001B7B8, 0x000033D6, 0x00002E66, 0x00000040,
+ 0x00000000, 0x0001BF9A, 0xFFFFE538, 0xFE000200,
+ 0x00000000, 0xFFFFDA2F, 0x0001B732, 0xFE000200,
+ },
+ [DRM_COLOR_YCBCR_BT709] = {
+ 0x0001B7B8, 0x000007FB, 0xFFFFD62B, 0x00000040,
+ 0x00000000, 0x0001C39D, 0x0000170F, 0xFE000200,
+ 0x00000000, 0xFFFFFAD1, 0x0001C04F, 0xFE000200,
+ },
+ [DRM_COLOR_YCBCR_BT2020] = {
+ 0x0001B7B8, 0x00000000, 0x00000000, 0x00000040,
+ 0x00000000, 0x0001C1C2, 0x00000000, 0xFE000200,
+ 0x00000000, 0x00000000, 0x0001C1C2, 0xFE000200,
+ },
+ },
+ },
+};
+
static void sun8i_csc_setup(struct regmap *map, u32 base,
enum format_type fmt_type,
enum drm_color_encoding encoding,
@@ -148,12 +279,27 @@ static void sun8i_csc_setup(struct regmap *map, u32 base,
regmap_write(map, SUN8I_CSC_CTRL(base), val);
}
+static const u32 *sun8i_csc_get_de3_yuv_table(enum drm_color_encoding in_enc,
+ enum drm_color_range in_range,
+ u32 out_format,
+ enum drm_color_encoding out_enc)
+{
+ if (out_format == MEDIA_BUS_FMT_RGB888_1X24)
+ return yuv2rgb_de3[in_range][in_enc];
+
+ /* check for identity transformation */
+ if (in_range == DRM_COLOR_YCBCR_LIMITED_RANGE && out_enc == in_enc)
+ return NULL;
+
+ return yuv2yuv_de3[in_range][in_enc][out_enc];
+}
+
static void sun8i_de3_ccsc_setup(struct sunxi_engine *engine, int layer,
enum format_type fmt_type,
enum drm_color_encoding encoding,
enum drm_color_range range)
{
- u32 addr, val, mask;
+ u32 addr, val = 0, mask;
struct regmap *map;
const u32 *table;
int i;
@@ -164,14 +310,28 @@ static void sun8i_de3_ccsc_setup(struct sunxi_engine *engine, int layer,
switch (fmt_type) {
case FORMAT_TYPE_RGB:
- val = 0;
+ if (engine->format == MEDIA_BUS_FMT_RGB888_1X24)
+ break;
+ val = mask;
+ addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0);
+ regmap_bulk_write(map, addr, rgb2yuv_de3[engine->encoding], 12);
break;
case FORMAT_TYPE_YUV:
+ table = sun8i_csc_get_de3_yuv_table(encoding, range,
+ engine->format,
+ engine->encoding);
+ if (!table)
+ break;
val = mask;
addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0);
regmap_bulk_write(map, addr, table, 12);
break;
case FORMAT_TYPE_YVU:
+ table = sun8i_csc_get_de3_yuv_table(encoding, range,
+ engine->format,
+ engine->encoding);
+ if (!table)
+ table = yuv2yuv_de3[range][encoding][encoding];
val = mask;
for (i = 0; i < 12; i++) {
if ((i & 3) == 1)
--
2.35.3

View File

@@ -1,63 +0,0 @@
From 99d327853acbc5d6c6d4140f004f82fcd5c40ea1 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Sun, 29 Sep 2024 22:04:38 +1300
Subject: drm: sun4i: de3: add format enumeration function to engine
The DE3 display engine supports YUV formats in addition to RGB.
Add an optional format enumeration function to the engine.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: Ryan Walklin <ryan@testtoast.com>
---
drivers/gpu/drm/sun4i/sunxi_engine.h | 29 ++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h
index ec0c4932f15c..c48cbc1aceb8 100644
--- a/drivers/gpu/drm/sun4i/sunxi_engine.h
+++ b/drivers/gpu/drm/sun4i/sunxi_engine.h
@@ -123,6 +123,17 @@ struct sunxi_engine_ops {
*/
void (*mode_set)(struct sunxi_engine *engine,
const struct drm_display_mode *mode);
+
+ /**
+ * @get_supported_fmts
+ *
+ * This callback is used to enumerate all supported output
+ * formats by the engine. They are used for bridge format
+ * negotiation.
+ *
+ * This function is optional.
+ */
+ u32 *(*get_supported_fmts)(struct sunxi_engine *engine, u32 *num);
};
/**
@@ -215,4 +226,22 @@ sunxi_engine_mode_set(struct sunxi_engine *engine,
if (engine->ops && engine->ops->mode_set)
engine->ops->mode_set(engine, mode);
}
+
+/**
+ * sunxi_engine_get_supported_formats - Provide array of supported formats
+ * @engine: pointer to the engine
+ * @num: pointer to variable, which will hold number of formats
+ *
+ * This list can be used for format negotiation by bridge.
+ */
+static inline u32 *
+sunxi_engine_get_supported_formats(struct sunxi_engine *engine, u32 *num)
+{
+ if (engine->ops && engine->ops->get_supported_fmts)
+ return engine->ops->get_supported_fmts(engine, num);
+
+ *num = 0;
+
+ return NULL;
+}
#endif /* _SUNXI_ENGINE_H_ */
--
2.35.3

View File

@@ -1,53 +0,0 @@
From 56afb6bff57f83073c83a49f6f6bccf387ab8116 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Sun, 29 Sep 2024 22:04:39 +1300
Subject: drm: sun4i: de3: add formatter flag to mixer config
Only the DE3 (and newer) display engines have a formatter module. This
could be inferred from the is_de3 flag alone, however this will not
scale with addition of future DE versions in subsequent patches.
Add a separate flag to signal this in the mixer configuration.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: Ryan Walklin <ryan@testtoast.com>
---
drivers/gpu/drm/sun4i/sun8i_mixer.c | 1 +
drivers/gpu/drm/sun4i/sun8i_mixer.h | 2 ++
2 files changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index fbfa7e6a25aa..fe1b58004a7b 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -769,6 +769,7 @@ static const struct sun8i_mixer_cfg sun50i_a64_mixer1_cfg = {
static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = {
.ccsc = CCSC_MIXER0_LAYOUT,
.is_de3 = true,
+ .has_formatter = 1,
.mod_rate = 600000000,
.scaler_mask = 0xf,
.scanline_yuv = 4096,
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index 68e2741b0962..860a2f2cec24 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -163,6 +163,7 @@ enum {
* @mod_rate: module clock rate that needs to be set in order to have
* a functional block.
* @is_de3: true, if this is next gen display engine 3.0, false otherwise.
+ * @has_formatter: true, if mixer has formatter core, for 10-bit and YUV handling
* @scaline_yuv: size of a scanline for VI scaler for YUV formats.
*/
struct sun8i_mixer_cfg {
@@ -172,6 +173,7 @@ struct sun8i_mixer_cfg {
int ccsc;
unsigned long mod_rate;
unsigned int is_de3 : 1;
+ unsigned int has_formatter : 1;
unsigned int scanline_yuv;
};
--
2.51.0

View File

@@ -1,54 +0,0 @@
From 2d7c88fc2af6d07ccadc99b157753638b4940293 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Sun, 29 Sep 2024 22:04:41 +1300
Subject: drm: sun4i: de3: pass engine reference to ccsc setup function
Configuration of the DE3 colorspace and dynamic range correction module
requires knowledge of the current video format and encoding.
Pass the display engine by reference to the csc setup function, rather
than the register map alone, to allow access to this information.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: Ryan Walklin <ryan@testtoast.com>
---
drivers/gpu/drm/sun4i/sun8i_csc.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c
index 68d955c63b05..8a336ccb27d3 100644
--- a/drivers/gpu/drm/sun4i/sun8i_csc.c
+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
@@ -148,17 +148,19 @@ static void sun8i_csc_setup(struct regmap *map, u32 base,
regmap_write(map, SUN8I_CSC_CTRL(base), val);
}
-static void sun8i_de3_ccsc_setup(struct regmap *map, int layer,
+static void sun8i_de3_ccsc_setup(struct sunxi_engine *engine, int layer,
enum format_type fmt_type,
enum drm_color_encoding encoding,
enum drm_color_range range)
{
u32 addr, val, mask;
+ struct regmap *map;
const u32 *table;
int i;
mask = SUN50I_MIXER_BLEND_CSC_CTL_EN(layer);
table = yuv2rgb_de3[range][encoding];
+ map = engine->regs;
switch (fmt_type) {
case FORMAT_TYPE_RGB:
@@ -204,7 +206,7 @@ void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer,
u32 base;
if (mixer->cfg->is_de3) {
- sun8i_de3_ccsc_setup(mixer->engine.regs, layer,
+ sun8i_de3_ccsc_setup(&mixer->engine, layer,
fmt_type, encoding, range);
return;
}
--
2.35.3

Some files were not shown because too many files have changed in this diff Show More