mirror of
https://github.com/armbian/build.git
synced 2025-08-15 23:56:57 +02:00
165 lines
4.9 KiB
Diff
165 lines
4.9 KiB
Diff
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
|
|
|