drm: sun4i: add Display Engine 3.3 (DE33) support
Subsystems (7)
v5 cover drm: sun4i: add Display Engine 3.3 (DE33) support
Hi,
V5 of this patch series adding support for the Allwinner DE33 display engine variant. V5 is rebased on torvalds/master as of today with the 6.12 drm-next patches included, with no code changes required. V3 and V4 were in turn rebased on top of the layer init and modesetting changes merged for 6.11. No functional changes from V4, fixes and reviews from previous V1-4 added, and relevant issues found by checkpatch.pl corrected.
Original blurb below:
There is existing mainline support for the DE2 and DE3 AllWinner display pipeline IP blocks, used in the A64 and H6 among others, however the H700 (as well as the H616/H618 and the T507 automotive SoC) have a newer version of the Display Engine (v3.3/DE33) which adds additional high-resolution support as well as YUV colour formats and AFBC compression support.
This patch set adds DE33 support, following up from the previous RFC [1], with significant rework to break down the previous relatively complex set into more logical steps, detailed below.
1. Refactor the existing DE2/DE3 code in readiness to support YUV colour formats in the DE3 engine (patches 1-4).
2. Add YUV420 colour format support in the DE3 driver (patches 5-12).
3. Replace the is_de3 mixer flag with an enum to support multiple DE versions (patch 13).
4. Refactor the mixer, vi_scaler and some register code to merge common init code and more easily support multiple DE versions (patches 14-17).
5. Add Arm Frame Buffer Compression (AFBC) compressed buffer support to the DE3 driver. This is currently only supported for VI layers (for HW-decoded video output) but is well integrated into these changes and a subsequent patchset to enable the Video Engine is planned. (patch 18).
6. Add DT bindings for the DE33 engine. (patches 19-21).
7. Extend the DE2/3 driver for the DE33, comprising clock, mixer, vi_scaler, fmt and csc module support (patches 22-26).
Further patchsets are planned to support HDMI and the LCD timing controller present in these SoCs.
Regards,
Ryan
Jernej Skrabec (22):
drm: sun4i: de2/de3: Change CSC argument
drm: sun4i: de2/de3: Merge CSC functions into one
drm: sun4i: de2/de3: call csc setup also for UI layer
drm: sun4i: de2: Initialize layer fields earlier
drm: sun4i: de3: Add YUV formatter module
drm: sun4i: de3: add format enumeration function to engine
drm: sun4i: de3: add formatter flag to mixer config
drm: sun4i: de3: add YUV support to the DE3 mixer
drm: sun4i: de3: pass engine reference to ccsc setup function
drm: sun4i: de3: add YUV support to the color space correction module
drm: sun4i: de3: add YUV support to the TCON
drm: sun4i: support YUV formats in VI scaler
drm: sun4i: de2/de3: add mixer version enum
drm: sun4i: de2/de3: refactor mixer initialisation
drm: sun4i: vi_scaler refactor vi_scaler enablement
drm: sun4i: de2/de3: add generic blender register reference function
drm: sun4i: de2/de3: use generic register reference function for layer
configuration
drm: sun4i: de3: Implement AFBC support
drm: sun4i: de33: mixer: add Display Engine 3.3 (DE33) support
drm: sun4i: de33: vi_scaler: add Display Engine 3.3 (DE33) support
drm: sun4i: de33: fmt: add Display Engine 3.3 (DE33) support
drm: sun4i: de33: csc: add Display Engine 3.3 (DE33) support
Ryan Walklin (4):
dt-bindings: allwinner: add H616 DE33 bus binding
dt-bindings: allwinner: add H616 DE33 clock binding
dt-bindings: allwinner: add H616 DE33 mixer binding
clk: sunxi-ng: ccu: add Display Engine 3.3 (DE33) support
.../bus/allwinner,sun50i-a64-de2.yaml | 4 +- .../clock/allwinner,sun8i-a83t-de2-clk.yaml | 1 + .../allwinner,sun8i-a83t-de2-mixer.yaml | 1 + drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 25 ++ drivers/gpu/drm/sun4i/Makefile | 3 +- drivers/gpu/drm/sun4i/sun4i_tcon.c | 26 +- drivers/gpu/drm/sun4i/sun50i_afbc.c | 250 +++++++++++++ drivers/gpu/drm/sun4i/sun50i_afbc.h | 87 +++++ drivers/gpu/drm/sun4i/sun50i_fmt.c | 99 +++++ drivers/gpu/drm/sun4i/sun50i_fmt.h | 33 ++ drivers/gpu/drm/sun4i/sun8i_csc.c | 341 +++++++++++++++--- drivers/gpu/drm/sun4i/sun8i_csc.h | 20 +- drivers/gpu/drm/sun4i/sun8i_mixer.c | 226 +++++++++--- drivers/gpu/drm/sun4i/sun8i_mixer.h | 31 +- drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 41 ++- drivers/gpu/drm/sun4i/sun8i_ui_scaler.c | 2 +- drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 133 +++++-- drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 115 ++++-- drivers/gpu/drm/sun4i/sun8i_vi_scaler.h | 2 +- drivers/gpu/drm/sun4i/sunxi_engine.h | 34 ++ 20 files changed, 1269 insertions(+), 205 deletions(-) create mode 100644 drivers/gpu/drm/sun4i/sun50i_afbc.c create mode 100644 drivers/gpu/drm/sun4i/sun50i_afbc.h create mode 100644 drivers/gpu/drm/sun4i/sun50i_fmt.c create mode 100644 drivers/gpu/drm/sun4i/sun50i_fmt.h
Signature · 1 line
2.46.1
PATCH v5 1/26 drm: sun4i: de2/de3: Change CSC argument
From: Jernej Skrabec <[email protected]>
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.
--- 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(-)
drivers/gpu/drm/sun4i/sun8i_csc.c +11 -11
@@ -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)
drivers/gpu/drm/sun4i/sun8i_csc.h +5 -5
@@ -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);
drivers/gpu/drm/sun4i/sun8i_vi_layer.c +8 -8
@@ -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);
Signature · 1 line
2.46.1
Re: [PATCH v5 01/26] drm: sun4i: de2/de3: Change CSC argument
Quoted 24 lines · Ryan Walklin
From: Jernej Skrabec <[email protected]>
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 <[email protected]>Signed-off-by Ryan Walklin <[email protected]>Reviewed-by Andre Przywara <[email protected]>--- 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(-)void
sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable)drivers/gpu/drm/sun4i/sun8i_csc.h +0
-0
drivers/gpu/drm/sun4i/sun8i_csc.h struct sun8i_mixer; · line 25
Quoted 8 lines
drivers/gpu/drm/sun4i/sun8i_csc.h +1
-4@@ -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 {
enum sun8i_format_type, unless there is a strong reason to name it otherwise.
Quoted 12 lines
drivers/gpu/drm/sun4i/sun8i_csc.h +4
-1+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);
Signature · 2 lines
With best wishes Dmitry
Re: [PATCH v5 01/26] drm: sun4i: de2/de3: Change CSC argument
Quoted 1 line · Dmitry Baryshkov
On Sun, Sep 29, 2024 at 10:04:33PM +1300, Ryan Walklin wrote:
Hi Dmitry, thanks for reviewing, and apologies for the delay in replying.
Quoted 8 lines
drivers/gpu/drm/sun4i/sun8i_csc.h struct sun8i_mixer; · line 25
Quoted 5 lines
drivers/gpu/drm/sun4i/sun8i_csc.h +1
-4-enum sun8i_csc_mode { -SUN8I_CSC_MODE_OFF , -SUN8I_CSC_MODE_YUV2RGB , -SUN8I_CSC_MODE_YVU2RGB , +enum format_type {enum
sun8i_format_type, unless there is a strong reason to name it otherwise.
No problem, will make that change.
Regards,
Ryan
PATCH v5 2/26 drm: sun4i: de2/de3: Merge CSC functions into one
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
At the moment the colour space conversion is handled by two functions:
one to setup the conversion parameters, and another one to enable the conversion. Merging both into one gives more flexibility for upcoming extensions to support whole YUV pipelines, in the DE33.
--- drivers/gpu/drm/sun4i/sun8i_csc.c | 89 ++++++++++---------------- drivers/gpu/drm/sun4i/sun8i_csc.h | 9 ++- drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 11 +--- 3 files changed, 40 insertions(+), 69 deletions(-)
drivers/gpu/drm/sun4i/sun8i_csc.c +33 -56
@@ -107,23 +107,28 @@ static const u32 yuv2rgb_de3[2][3][12] = { }, }; -static void sun8i_csc_set_coefficients (struct regmap *map,u32 base, -enum format_type fmt_type, -enum drm_color_encoding encoding, -enum drm_color_range range) +static void sun8i_csc_setup (struct regmap *map,u32 base, +enum format_type fmt_type, +enum drm_color_encoding encoding, +enum drm_color_range range) { +u32 base_reg, val;const u32 *table; -u32 base_reg;int i; table = yuv2rgb[range][encoding];switch (fmt_type) { +case FORMAT_TYPE_RGB : + val =0 ; +break ;case FORMAT_TYPE_YUV : + val =SUN8I_CSC_CTRL_EN ; base_reg =SUN8I_CSC_COEFF (base,0 );regmap_bulk_write (map, base_reg, table,12 );break ;case FORMAT_TYPE_YVU : + val =SUN8I_CSC_CTRL_EN ;for (i =0 ; i <12 ; i++) {if ((i &3 ) ==1 ) base_reg =SUN8I_CSC_COEFF (base, i +1 );
@@ -135,28 +140,37 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, }break ;default : + val =0 ;DRM_WARN ("Wrong CSC mode specified.\n" );return ; } + +regmap_write (map,SUN8I_CSC_CTRL (base), val); } -static void sun8i_de3_ccsc_set_coefficients (struct regmap *map,int layer, -enum format_type fmt_type, -enum drm_color_encoding encoding, -enum drm_color_range range) +static void sun8i_de3_ccsc_setup (struct regmap *map,int layer, +enum format_type fmt_type, +enum drm_color_encoding encoding, +enum drm_color_range range) { +u32 addr, val, mask;const u32 *table; -u32 addr;int i; + mask =SUN50I_MIXER_BLEND_CSC_CTL_EN (layer); table = yuv2rgb_de3[range][encoding];switch (fmt_type) { +case FORMAT_TYPE_RGB : + val =0 ; +break ;case FORMAT_TYPE_YUV : + 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 : + val = mask;for (i =0 ; i <12 ; i++) {if ((i &3 ) ==1 ) addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE,
@@ -173,67 +187,30 @@ static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, }break ;default : + val =0 ;DRM_WARN ("Wrong CSC mode specified.\n" );return ; } -} - -static void sun8i_csc_enable (struct regmap *map,u32 base,bool enable) -{ -u32 val; - -if (enable) - val =SUN8I_CSC_CTRL_EN ; -else - val =0 ; - -regmap_update_bits (map,SUN8I_CSC_CTRL (base),SUN8I_CSC_CTRL_EN , val); -} - -static void sun8i_de3_ccsc_enable (struct regmap *map,int layer,bool enable) -{ -u32 val, mask; - - mask =SUN50I_MIXER_BLEND_CSC_CTL_EN (layer); - -if (enable) - val = mask; -else - val =0 ;regmap_update_bits (map,SUN50I_MIXER_BLEND_CSC_CTL (DE3_BLD_BASE ), mask, val); } -void sun8i_csc_set_ccsc_coefficients (struct sun8i_mixer *mixer,int layer, -enum format_type fmt_type, -enum drm_color_encoding encoding, -enum drm_color_range range) -{ -u32 base; - -if (mixer->cfg->is_de3) { -sun8i_de3_ccsc_set_coefficients (mixer->engine.regs, layer, - fmt_type, encoding, range); -return ; - } - - base = ccsc_base[mixer->cfg->ccsc][layer]; - -sun8i_csc_set_coefficients (mixer->engine.regs, base, - fmt_type, encoding, range); -} - -void sun8i_csc_enable_ccsc (struct sun8i_mixer *mixer,int layer,bool enable) +void sun8i_csc_set_ccsc (struct sun8i_mixer *mixer,int layer, +enum format_type fmt_type, +enum drm_color_encoding encoding, +enum drm_color_range range) {u32 base;if (mixer->cfg->is_de3) { -sun8i_de3_ccsc_enable (mixer->engine.regs, layer, enable); +sun8i_de3_ccsc_setup (mixer->engine.regs, layer, + fmt_type, encoding, range);return ; } base = ccsc_base[mixer->cfg->ccsc][layer]; -sun8i_csc_enable (mixer->engine.regs, base, enable); +sun8i_csc_setup (mixer->engine.regs, base, + fmt_type, encoding, range); }
drivers/gpu/drm/sun4i/sun8i_csc.h +4 -5
@@ -28,10 +28,9 @@ enum format_type { FORMAT_TYPE_YVU, }; -void sun8i_csc_set_ccsc_coefficients (struct sun8i_mixer *mixer,int layer, -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); +void sun8i_csc_set_ccsc (struct sun8i_mixer *mixer,int layer, +enum format_type fmt_type, +enum drm_color_encoding encoding, +enum drm_color_range range);#endif
drivers/gpu/drm/sun4i/sun8i_vi_layer.c +3 -8
@@ -232,14 +232,9 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel, SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK, val); 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); - }else { -sun8i_csc_enable_ccsc (mixer, channel, false); - } +sun8i_csc_set_ccsc (mixer, channel, fmt_type, + state->color_encoding, + state->color_range);if (!fmt->is_yuv) val =SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE ;
Signature · 1 line
2.46.1
PATCH v5 3/26 drm: sun4i: de2/de3: call csc setup also for UI layer
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
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.
--- drivers/gpu/drm/sun4i/sun8i_csc.c | 8 +++++--- drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 6 ++++++ 2 files changed, 11 insertions(+), 3 deletions(-)
drivers/gpu/drm/sun4i/sun8i_csc.c +5 -3
@@ -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); + } }
drivers/gpu/drm/sun4i/sun8i_ui_layer.c +6 -0
@@ -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 ; }
Signature · 1 line
2.46.1
PATCH v5 4/26 drm: sun4i: de2: Initialize layer fields earlier
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
drm_universal_plane_init() can already call some callbacks, like format_mod_supported, during initialization. Because of that, fields should be initialized beforehand.
--- drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 9 +++++---- drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-)
drivers/gpu/drm/sun4i/sun8i_ui_layer.c +5 -4
@@ -295,6 +295,11 @@ struct sun8i_layer *sun8i_ui_layer_init_one(struct drm_device *drm,if (!layer)return ERR_PTR (-ENOMEM ); + layer->mixer = mixer; + layer->type =SUN8I_LAYER_TYPE_UI ; + layer->channel = channel; + layer->overlay =0 ; +if (index ==0 ) type =DRM_PLANE_TYPE_PRIMARY ;
@@ -325,10 +330,6 @@ struct sun8i_layer *sun8i_ui_layer_init_one(struct drm_device *drm, }drm_plane_helper_add (&layer->plane, &sun8i_ui_layer_helper_funcs); - layer->mixer = mixer; - layer->type =SUN8I_LAYER_TYPE_UI ; - layer->channel = channel; - layer->overlay =0 ;return layer; }
drivers/gpu/drm/sun4i/sun8i_vi_layer.c +5 -4
@@ -478,6 +478,11 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,if (!layer)return ERR_PTR (-ENOMEM ); + layer->mixer = mixer; + layer->type =SUN8I_LAYER_TYPE_VI ; + layer->channel = index; + layer->overlay =0 ; +if (mixer->cfg->is_de3) { formats = sun8i_vi_layer_de3_formats; format_count =ARRAY_SIZE (sun8i_vi_layer_de3_formats);
@@ -536,10 +541,6 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, }drm_plane_helper_add (&layer->plane, &sun8i_vi_layer_helper_funcs); - layer->mixer = mixer; - layer->type =SUN8I_LAYER_TYPE_VI ; - layer->channel = index; - layer->overlay =0 ;return layer; }
Signature · 1 line
2.46.1
PATCH v5 5/26 drm: sun4i: de3: Add YUV formatter module
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
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.
--- 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
drivers/gpu/drm/sun4i/Makefile +2 -1
@@ -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
drivers/gpu/drm/sun4i/sun50i_fmt.c new file +82 -0
82 lines not on this page · raw message
drivers/gpu/drm/sun4i/sun50i_fmt.h new file +32 -0
@@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* +* Copyright (C) Jernej Skrabec <[email protected]> +*/ + +#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
Signature · 1 line
2.46.1
PATCH v5 6/26 drm: sun4i: de3: add format enumeration function to engine
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
The DE3 display engine supports YUV formats in addition to RGB.
Add an optional format enumeration function to the engine.
--- drivers/gpu/drm/sun4i/sunxi_engine.h | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
drivers/gpu/drm/sun4i/sunxi_engine.h +29 -0
@@ -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_ */
Signature · 1 line
2.46.1
PATCH v5 7/26 drm: sun4i: de3: add formatter flag to mixer config
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
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.
--- drivers/gpu/drm/sun4i/sun8i_mixer.c | 1 + drivers/gpu/drm/sun4i/sun8i_mixer.h | 2 ++ 2 files changed, 3 insertions(+)
drivers/gpu/drm/sun4i/sun8i_mixer.c +1 -0
@@ -717,6 +717,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 ,
drivers/gpu/drm/sun4i/sun8i_mixer.h +2 -0
@@ -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; };
Signature · 1 line
2.46.1
PATCH v5 8/26 drm: sun4i: de3: add YUV support to the DE3 mixer
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
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.
---
Changelog v4..v5:
- Remove trailing whitespace
--- drivers/gpu/drm/sun4i/sun8i_mixer.c | 53 ++++++++++++++++++++++++++-- drivers/gpu/drm/sun4i/sunxi_engine.h | 5 +++ 2 files changed, 55 insertions(+), 3 deletions(-)
drivers/gpu/drm/sun4i/sun8i_mixer.c +50 -3
@@ -23,7 +23,10 @@#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 "sun50i_fmt.h" #include "sun8i_mixer.h" #include "sun8i_ui_layer.h" #include "sun8i_vi_layer.h"
@@ -390,12 +393,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, + .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 = {
@@ -456,6 +499,10 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,dev_set_drvdata (dev, mixer); mixer->engine.ops = &sun8i_engine_ops; mixer->engine.node = dev->of_node; +/* 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" )) {/*
drivers/gpu/drm/sun4i/sunxi_engine.h +5 -0
@@ -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; };
Signature · 1 line
2.46.1
Re: [PATCH v5 08/26] drm: sun4i: de3: add YUV support to the DE3 mixer
Quoted 115 lines · Ryan Walklin
From: Jernej Skrabec <[email protected]>
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 <[email protected]>Signed-off-by Ryan Walklin <[email protected]>---
Changelog v4..v5:
- Remove trailing whitespace--- drivers/gpu/drm/sun4i/sun8i_mixer.c | 53 ++++++++++++++++++++++++++-- drivers/gpu/drm/sun4i/sunxi_engine.h | 5 +++ 2 files changed, 55 insertions(+), 3 deletions(-)drivers/gpu/drm/sun4i/sun8i_mixer.c +50
-3@@ -23,7 +23,10 @@#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 "sun50i_fmt.h" #include "sun8i_mixer.h" #include "sun8i_ui_layer.h" #include "sun8i_vi_layer.h" @@ -390,12 +393,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, + .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 = {@@ -456,6 +499,10 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,dev_set_drvdata (dev, mixer); mixer->engine.ops = &sun8i_engine_ops; mixer->engine.node = dev->of_node; +/* 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" )) {/* drivers/gpu/drm/sun4i/sunxi_engine.h +2
-0@@ -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 ;
drivers/gpu/drm/sun4i/sunxi_engine.h struct sunxi_engine { · line 157
Quoted 5 lines
drivers/gpu/drm/sun4i/sunxi_engine.h +2
-0@@ -151,6 +153,9 @@ struct sunxi_engine {int id; +u32 format; +enum drm_color_encoding encoding;
Should these be a part of the state instead of being a part of the sunxi_engine?
Quoted 7 lines
drivers/gpu/drm/sun4i/sunxi_engine.h +1
-0+/* Engine list management */ struct list_head list; };Signature · 1 line
2.46.1
Signature · 2 lines
With best wishes Dmitry
Re: [PATCH v5 08/26] drm: sun4i: de3: add YUV support to the DE3 mixer
Quoted 9 lines · Dmitry Baryshkov
Quoted 7 lines · Ryan Walklin
drivers/gpu/drm/sun4i/sunxi_engine.h +0
-0@@ -151,6 +153,9 @@ struct sunxi_engine {
Quoted 7 lines
drivers/gpu/drm/sun4i/sunxi_engine.h struct sunxi_engine { · line 157
Quoted 4 lines
drivers/gpu/drm/sun4i/sunxi_engine.h +2
-0int id; +u32 format; +enum drm_color_encoding encoding;Should these be a part of the state instead of being a part of the
sunxi_engine?
Sure, would you suggest in sun8i_mixer_cfg?
Regards,
Ryan
Re: [PATCH v5 08/26] drm: sun4i: de3: add YUV support to the DE3 mixer
Quoted 12 lines · Ryan Walklin
Quoted 11 lines · Dmitry Baryshkov
Quoted 9 lines · Ryan Walklin
drivers/gpu/drm/sun4i/sunxi_engine.h +0
-0@@ -151,6 +153,9 @@ struct sunxi_engine {int id;
Quoted 7 lines
Quoted 5 lines
drivers/gpu/drm/sun4i/sunxi_engine.h struct sunxi_engine { · line 157
Quoted 2 lines
drivers/gpu/drm/sun4i/sunxi_engine.h +2
-0+u32 format; +enum drm_color_encoding encoding;Should these be a part of the state instead of being a part of the
sunxi_engine?Sure, would you suggest in
sun8i_mixer_cfg?
Hmm, on second thought the mixer config is a const struct, presumably because it is defined per engine variant in sun8i_mixer.c. Is there a better place to store state like this? Otherwise the engine may not be the worst choice, as the color format and encoding apply to the entire pipeline, at least in the case of a single display?
Regards,
Ryan
PATCH v5 9/26 drm: sun4i: de3: pass engine reference to ccsc setup function
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
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.
--- drivers/gpu/drm/sun4i/sun8i_csc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/gpu/drm/sun4i/sun8i_csc.c +4 -2
@@ -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 ; }
Signature · 1 line
2.46.1
PATCH v5 10/26 drm: sun4i: de3: add YUV support to the color space correction module
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
Add coefficients and support for YUV formats to the display engine colorspace and dynamic range correction submodule.
--- drivers/gpu/drm/sun4i/sun8i_csc.c | 164 +++++++++++++++++++++++++++++- 1 file changed, 162 insertions(+), 2 deletions(-)
drivers/gpu/drm/sun4i/sun8i_csc.c +162 -2
@@ -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 )
Signature · 1 line
2.46.1
PATCH v5 11/26 drm: sun4i: de3: add YUV support to the TCON
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
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.
--- drivers/gpu/drm/sun4i/sun4i_tcon.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-)
drivers/gpu/drm/sun4i/sun4i_tcon.c +19 -7
@@ -598,14 +598,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 );
@@ -624,17 +636,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 */
@@ -642,8 +654,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",
Signature · 1 line
2.46.1
PATCH v5 12/26 drm: sun4i: support YUV formats in VI scaler
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
Now that YUV formats are available, enable support in the VI scaler.
Changelog v4..v5:
- Add commit description
--- drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 85 +++++++++++++++++-------- 1 file changed, 58 insertions(+), 27 deletions(-)
drivers/gpu/drm/sun4i/sun8i_vi_scaler.c +58 -27
@@ -843,6 +843,11 @@ static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel)DE2_VI_SCALER_UNIT_SIZE * channel; } +static bool sun8i_vi_scaler_is_vi_plane (struct sun8i_mixer *mixer,int channel) +{ +return true; +} +static int sun8i_vi_scaler_coef_index (unsigned int step) {unsigned int scale, int_part, float_part;
@@ -867,44 +872,65 @@ static int sun8i_vi_scaler_coef_index(unsigned int step) } } -static void sun8i_vi_scaler_set_coeff (struct regmap *map,u32 base, -u32 hstep,u32 vstep, -const struct drm_format_info *format) +static void sun8i_vi_scaler_set_coeff_vi (struct regmap *map,u32 base, +u32 hstep,u32 vstep, +const struct drm_format_info *format) {const u32 *ch_left, *ch_right, *cy; -int offset, i; +int offset; -if (format->hsub ==1 && format->vsub ==1 ) { - ch_left = lan3coefftab32_left; - ch_right = lan3coefftab32_right; - cy = lan2coefftab32; - }else { +if (format->is_yuv) { ch_left = bicubic8coefftab32_left; ch_right = bicubic8coefftab32_right; cy = bicubic4coefftab32; + }else { + ch_left = lan3coefftab32_left; + ch_right = lan3coefftab32_right; + cy = lan2coefftab32; } offset =sun8i_vi_scaler_coef_index (hstep) *SUN8I_VI_SCALER_COEFF_COUNT ; -for (i =0 ; i <SUN8I_VI_SCALER_COEFF_COUNT ; i++) { -regmap_write (map,SUN8I_SCALER_VSU_YHCOEFF0 (base, i), - lan3coefftab32_left[offset + i]); -regmap_write (map,SUN8I_SCALER_VSU_YHCOEFF1 (base, i), - lan3coefftab32_right[offset + i]); -regmap_write (map,SUN8I_SCALER_VSU_CHCOEFF0 (base, i), - ch_left[offset + i]); -regmap_write (map,SUN8I_SCALER_VSU_CHCOEFF1 (base, i), - ch_right[offset + i]); - } +regmap_bulk_write (map,SUN8I_SCALER_VSU_YHCOEFF0 (base,0 ), + &lan3coefftab32_left[offset], +SUN8I_VI_SCALER_COEFF_COUNT ); +regmap_bulk_write (map,SUN8I_SCALER_VSU_YHCOEFF1 (base,0 ), + &lan3coefftab32_right[offset], +SUN8I_VI_SCALER_COEFF_COUNT ); +regmap_bulk_write (map,SUN8I_SCALER_VSU_CHCOEFF0 (base,0 ), + &ch_left[offset],SUN8I_VI_SCALER_COEFF_COUNT ); +regmap_bulk_write (map,SUN8I_SCALER_VSU_CHCOEFF1 (base,0 ), + &ch_right[offset],SUN8I_VI_SCALER_COEFF_COUNT ); offset =sun8i_vi_scaler_coef_index (hstep) *SUN8I_VI_SCALER_COEFF_COUNT ; -for (i =0 ; i <SUN8I_VI_SCALER_COEFF_COUNT ; i++) { -regmap_write (map,SUN8I_SCALER_VSU_YVCOEFF (base, i), - lan2coefftab32[offset + i]); -regmap_write (map,SUN8I_SCALER_VSU_CVCOEFF (base, i), - cy[offset + i]); - } +regmap_bulk_write (map,SUN8I_SCALER_VSU_YVCOEFF (base,0 ), + &lan2coefftab32[offset],SUN8I_VI_SCALER_COEFF_COUNT ); +regmap_bulk_write (map,SUN8I_SCALER_VSU_CVCOEFF (base,0 ), + &cy[offset],SUN8I_VI_SCALER_COEFF_COUNT ); +} + +static void sun8i_vi_scaler_set_coeff_ui (struct regmap *map,u32 base, +u32 hstep,u32 vstep, +const struct drm_format_info *format) +{ +const u32 *table; +int offset; + + offset =sun8i_vi_scaler_coef_index (hstep) * +SUN8I_VI_SCALER_COEFF_COUNT ; +regmap_bulk_write (map,SUN8I_SCALER_VSU_YHCOEFF0 (base,0 ), + &lan2coefftab32[offset],SUN8I_VI_SCALER_COEFF_COUNT ); + offset =sun8i_vi_scaler_coef_index (vstep) * +SUN8I_VI_SCALER_COEFF_COUNT ; +regmap_bulk_write (map,SUN8I_SCALER_VSU_YVCOEFF (base,0 ), + &lan2coefftab32[offset],SUN8I_VI_SCALER_COEFF_COUNT ); + + table = format->is_yuv ? bicubic4coefftab32 : lan2coefftab32; + offset =sun8i_vi_scaler_coef_index (hstep) * +SUN8I_VI_SCALER_COEFF_COUNT ; +regmap_bulk_write (map,SUN8I_SCALER_VSU_CHCOEFF0 (base,0 ), + &table[offset],SUN8I_VI_SCALER_COEFF_COUNT ); }void sun8i_vi_scaler_enable (struct sun8i_mixer *mixer,int layer,bool enable)
@@ -994,6 +1020,11 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer, SUN8I_SCALER_VSU_CHPHASE(base), chphase);regmap_write (mixer->engine.regs,SUN8I_SCALER_VSU_CVPHASE (base), cvphase); -sun8i_vi_scaler_set_coeff (mixer->engine.regs, base, - hscale, vscale, format); + +if (sun8i_vi_scaler_is_vi_plane (mixer, layer)) +sun8i_vi_scaler_set_coeff_vi (mixer->engine.regs, base, + hscale, vscale, format); +else +sun8i_vi_scaler_set_coeff_ui (mixer->engine.regs, base, + hscale, vscale, format); }
Signature · 1 line
2.46.1
PATCH v5 13/26 drm: sun4i: de2/de3: add mixer version enum
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
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.
--- 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(-)
drivers/gpu/drm/sun4i/sun8i_csc.c +1 -1
@@ -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 ;
drivers/gpu/drm/sun4i/sun8i_mixer.c +12 -2
@@ -584,7 +584,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, base =sun8i_blender_base (mixer);/* 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 );
@@ -675,6 +675,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 ,
@@ -683,6 +684,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 ,
@@ -691,6 +693,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 ,
@@ -700,6 +703,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 ,
@@ -709,6 +713,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 ,
@@ -717,6 +722,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 ,
@@ -727,6 +733,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 ,
@@ -736,6 +743,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 ,
@@ -745,6 +753,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 ,
@@ -754,6 +763,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 ,
@@ -763,7 +773,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 ,
drivers/gpu/drm/sun4i/sun8i_mixer.h +8 -3
@@ -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; };
@@ -216,13 +221,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 ;
drivers/gpu/drm/sun4i/sun8i_ui_scaler.c +1 -1
@@ -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);
drivers/gpu/drm/sun4i/sun8i_vi_layer.c +4 -4
@@ -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) |
drivers/gpu/drm/sun4i/sun8i_vi_scaler.c +2 -2
@@ -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 )
Signature · 1 line
2.46.1
PATCH v5 14/26 drm: sun4i: de2/de3: refactor mixer initialisation
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
Now that the DE variant can be selected by enum, take the oppportunity to factor out some common initialisation code to a separate function.
---
Changelog v1..v2:
- Combine base register allocation and initialisation in sun8i_mixer_init
- Whitespace fix
Changelog v4..v5:
- Remove trailing whitespace
--- drivers/gpu/drm/sun4i/sun8i_mixer.c | 64 +++++++++++++++-------------- 1 file changed, 34 insertions(+), 30 deletions(-)
drivers/gpu/drm/sun4i/sun8i_mixer.c +34 -30
@@ -468,6 +468,38 @@ 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; + +/* 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 ); + +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) {
@@ -476,8 +508,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;/*
@@ -581,8 +611,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); -/* Reset registers and disable unused sub-engines */ if (mixer->cfg->de_type == sun8i_mixer_de3) {for (i =0 ; i <DE3_MIXER_UNIT_SIZE ; i +=4 )
@@ -598,7 +626,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 );
@@ -611,31 +639,7 @@ 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 ); - -/* 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 ); - -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 ;
Signature · 1 line
2.46.1
PATCH v5 15/26 drm: sun4i: vi_scaler refactor vi_scaler enablement
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
If the video scaler is required, then it is obligatory to set the relevant register to enable it, so move this to the sun8i_vi_scaler_setup() function.
This simplifies the alternate case (scaler not required) so replace the vi_scaler_enable() function with a vi_scaler_disable() function.
--- drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 3 +-- drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 21 +++++++++++---------- drivers/gpu/drm/sun4i/sun8i_vi_scaler.h | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-)
drivers/gpu/drm/sun4i/sun8i_vi_layer.c +1 -2
@@ -156,10 +156,9 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,sun8i_vi_scaler_setup (mixer, channel, src_w, src_h, dst_w, dst_h, hscale, vscale, hphase, vphase, format); -sun8i_vi_scaler_enable (mixer, channel, true); }else {DRM_DEBUG_DRIVER ("HW scaling is not needed\n" ); -sun8i_vi_scaler_enable (mixer, channel, false); +sun8i_vi_scaler_disable (mixer, channel); } regmap_write(mixer->engine.regs,
drivers/gpu/drm/sun4i/sun8i_vi_scaler.c +11 -10
@@ -933,20 +933,13 @@ static void sun8i_vi_scaler_set_coeff_ui(struct regmap *map, u32 base, &table[offset], SUN8I_VI_SCALER_COEFF_COUNT); } -void sun8i_vi_scaler_enable (struct sun8i_mixer *mixer,int layer,bool enable) +void sun8i_vi_scaler_disable (struct sun8i_mixer *mixer,int layer) { -u32 val, base; +u32 base; base =sun8i_vi_scaler_base (mixer, layer); -if (enable) - val =SUN8I_SCALER_VSU_CTRL_EN | -SUN8I_SCALER_VSU_CTRL_COEFF_RDY ; -else - val =0 ; - -regmap_write (mixer->engine.regs, -SUN8I_SCALER_VSU_CTRL (base), val); +regmap_write (mixer->engine.regs,SUN8I_SCALER_VSU_CTRL (base),0 ); } void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
@@ -982,6 +975,9 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer, cvphase = vphase; } +regmap_write (mixer->engine.regs,SUN8I_SCALER_VSU_CTRL (base), +SUN8I_SCALER_VSU_CTRL_EN ); +if (mixer->cfg->de_type >= sun8i_mixer_de3) {u32 val;
@@ -1027,4 +1023,9 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,else sun8i_vi_scaler_set_coeff_ui (mixer->engine.regs, base, hscale, vscale, format); + +if (mixer->cfg->de_type <= sun8i_mixer_de3) +regmap_write (mixer->engine.regs,SUN8I_SCALER_VSU_CTRL (base), +SUN8I_SCALER_VSU_CTRL_EN | +SUN8I_SCALER_VSU_CTRL_COEFF_RDY ); }
drivers/gpu/drm/sun4i/sun8i_vi_scaler.h +1 -1
@@ -69,7 +69,7 @@#define SUN50I_SCALER_VSU_ANGLE_SHIFT (x) (((x) << 16) & 0xF)#define SUN50I_SCALER_VSU_ANGLE_OFFSET (x) ((x) & 0xFF) -void sun8i_vi_scaler_enable (struct sun8i_mixer *mixer,int layer,bool enable); +void sun8i_vi_scaler_disable (struct sun8i_mixer *mixer,int layer); void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer, u32 src_w, u32 src_h, u32 dst_w, u32 dst_h, u32 hscale, u32 vscale, u32 hphase, u32 vphase,
Signature · 1 line
2.46.1
PATCH v5 16/26 drm: sun4i: de2/de3: add generic blender register reference function
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
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.
--- drivers/gpu/drm/sun4i/sun8i_mixer.h | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/sun4i/sun8i_mixer.h +6 -0
@@ -224,6 +224,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) {
Signature · 1 line
2.46.1
PATCH v5 17/26 drm: sun4i: de2/de3: use generic register reference function for layer configuration
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
Use the new blender register lookup function where required in the layer commit and update code.
---
Changelog v2..v3:
- Refactor for 6.11 layer init/modesetting changes
--- 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(-)
drivers/gpu/drm/sun4i/sun8i_mixer.c +3 -2
@@ -277,6 +277,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 ;
@@ -316,8 +317,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,
drivers/gpu/drm/sun4i/sun8i_ui_layer.c +5 -2
@@ -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);
drivers/gpu/drm/sun4i/sun8i_vi_layer.c +4 -2
@@ -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);
Signature · 1 line
2.46.1
PATCH v5 18/26 drm: sun4i: de3: Implement AFBC support
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
Buffers, compressed with AFBC, are supported by the DE3 and above, and are generally more efficient for memory transfers. Add support for them.
Currently it's implemented only for VI layers, but vendor code and documentation suggest UI layers can have them too. However, I haven't observed any SoC with such feature.
---
Changelog v4..v5:
- Correct strict mode warnings from checkpatch.pl
--- drivers/gpu/drm/sun4i/Makefile | 2 +- drivers/gpu/drm/sun4i/sun50i_afbc.c | 250 +++++++++++++++++++++++++ drivers/gpu/drm/sun4i/sun50i_afbc.h | 87 +++++++++ drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 84 +++++++-- 4 files changed, 409 insertions(+), 14 deletions(-) create mode 100644 drivers/gpu/drm/sun4i/sun50i_afbc.c create mode 100644 drivers/gpu/drm/sun4i/sun50i_afbc.h
drivers/gpu/drm/sun4i/Makefile +1 -1
@@ -17,7 +17,7 @@ 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 \ - sun50i_fmt.o + sun50i_fmt.o sun50i_afbc.o sun4i-tcon-y += sun4i_crtc.o sun4i-tcon-y += sun4i_tcon_dclk.o
drivers/gpu/drm/sun4i/sun50i_afbc.c new file +250 -0
250 lines not on this page · raw message
drivers/gpu/drm/sun4i/sun50i_afbc.h new file +87 -0
87 lines not on this page · raw message
drivers/gpu/drm/sun4i/sun8i_vi_layer.c +71 -13
165 lines not on this page · raw message
Signature · 1 line
2.46.1
PATCH v5 19/26 dt-bindings: allwinner: add H616 DE33 bus binding
In reply to Ryan WalklinThe Allwinner H616 and variants have a new display engine revision (DE33).
Add a display engine bus binding for the DE33.
---
Changelog v1..v2:
- Correct DE2 bus enum to reflect fallback devices accurately.
Changelog v2..v3:
- Separate content into three patches for three separate subsystems
--- .../devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml +3 -1
@@ -24,7 +24,9 @@ properties: oneOf: - const: allwinner,sun50i-a64-de2 - items: - - const: allwinner,sun50i-h6-de3 + - enum: + - allwinner,sun50i-h6-de3 + - allwinner,sun50i-h616-de33 - const: allwinner,sun50i-a64-de2 reg:
Signature · 1 line
2.46.1
Re: [PATCH v5 19/26] dt-bindings: allwinner: add H616 DE33 bus binding
Quoted 37 lines · Ryan Walklin
The Allwinner H616 and variants have a new display engine revision (DE33).
Add a display engine bus binding for the DE33.
Signed-off-by Ryan Walklin <[email protected]>Acked-by Conor Dooley <[email protected]>Reviewed-by Chen-Yu Tsai <[email protected]>---
Changelog v1..v2:
- Correct DE2 bus enum to reflect fallback devices accurately.Changelog v2..v3:
- Separate content into three patches for three separate subsystems--- .../devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml +3
-1@@ -24,7 +24,9 @@ properties: oneOf: - const: allwinner,sun50i-a64-de2 - items: - - const: allwinner,sun50i-h6-de3 + - enum: + - allwinner,sun50i-h6-de3 + - allwinner,sun50i-h616-de33 - const: allwinner,sun50i-a64-de2 reg:Signature · 1 line
2.46.1
Because the h616 uses additional reg values, we need to change
reg:
maxItems: 1
To
reg:
minItems: 1
maxItems: 3
Thank you,
Chris
PATCH v5 20/26 dt-bindings: allwinner: add H616 DE33 clock binding
In reply to Ryan WalklinThe Allwinner H616 and variants have a new display engine revision (DE33).
Add a clock binding for the DE33.
---
Changelog v2..v3:
- Separate content into three patches for three separate subsystems
--- .../devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml | 1 + 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml +1 -0
@@ -25,6 +25,7 @@ properties: - const: allwinner,sun50i-a64-de2-clk - const: allwinner,sun50i-h5-de2-clk - const: allwinner,sun50i-h6-de3-clk + - const: allwinner,sun50i-h616-de33-clk - items: - const: allwinner,sun8i-r40-de2-clk - const: allwinner,sun8i-h3-de2-clk
Signature · 1 line
2.46.1
PATCH v5 21/26 dt-bindings: allwinner: add H616 DE33 mixer binding
In reply to Ryan WalklinThe Allwinner H616 and variants have a new display engine revision (DE33).
The mixer configuration registers are significantly different to the DE3 and DE2 revisions, being split into separate top and display blocks, therefore a fallback for the mixer compatible is not provided.
Add a display engine mixer binding for the DE33.
---
Changelog v2..v3:
- Separate content into three patches for three separate subsystems
--- .../bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml | 1 + 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml +1 -0
@@ -24,6 +24,7 @@ properties: - allwinner,sun50i-a64-de2-mixer-0 - allwinner,sun50i-a64-de2-mixer-1 - allwinner,sun50i-h6-de3-mixer-0 + - allwinner,sun50i-h616-de33-mixer-0 reg: maxItems: 1
Signature · 1 line
2.46.1
Re: [PATCH v5 21/26] dt-bindings: allwinner: add H616 DE33 mixer binding
Quoted 25 lines · Ryan Walklin
The Allwinner H616 and variants have a new display engine revision (DE33).
The mixer configuration registers are significantly different to the DE3 and DE2 revisions, being split into separate top and display blocks, therefore a fallback for the mixer compatible is not provided.
Add a display engine mixer binding for the DE33.
Signed-off-by Ryan Walklin <[email protected]>Acked-by Conor Dooley <[email protected]>Reviewed-by Chen-Yu Tsai <[email protected]>---
Changelog v2..v3:
- Separate content into three patches for three separate subsystems--- .../bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml | 1 + 1 file changed, 1 insertion(+)Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml +0
-0
Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml properties: · line 30
Quoted 7 lines
Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml +1
-0@@ -24,6 +24,7 @@ properties: - allwinner,sun50i-a64-de2-mixer-0 - allwinner,sun50i-a64-de2-mixer-1 - allwinner,sun50i-h6-de3-mixer-0 + - allwinner,sun50i-h616-de33-mixer-0 reg: maxItems: 1
- maxItems: 1 + minItems: 1 + maxItems: 3
Quoted 3 lines
Signature · 1 line
2.46.1
Also need to add constraints to set maxItems to 3 only for the h616-de33
+allOf:
+ - if:
+ properties:
+ compatible:
+ enum:
+ - allwinner,sun50i-h616-de33-mixer-0
+
+ then:
+ properties:
+ reg:
+ maxItems: 3
+
+ else:
+ properties:
+ reg:
+ maxItems: 1
+
Thank you,
Chris
PATCH v5 22/26 clk: sunxi-ng: ccu: add Display Engine 3.3 (DE33) support
In reply to Ryan WalklinThe DE33 is a newer version of the Allwinner Display Engine IP block, found in the H616, H618, H700 and T507 SoCs. DE2 and DE3 are already supported by the mainline driver.
The DE33 in the H616 has mixer0 and writeback units. The clocks and resets required are identical to the H3 and H5 respectively, so use those existing structs for the H616 description.
There are two additional 32-bit registers (at offsets 0x24 and 0x28) which require clearing and setting respectively to bring up the hardware. The function of these registers is currently unknown, and the values are taken from the out-of-tree driver.
Add the required clock description struct and compatible string to the DE2 driver.
---
Changelog v2..v3:
- Lowercase hex value
Changelog v2..v3:
- Correct #include for writel()
Changelog v4..v5:
- Whitespace fix
--- drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
drivers/clk/sunxi-ng/ccu-sun8i-de2.c +25 -0
@@ -5,6 +5,7 @@#include <linux/clk.h> #include <linux/clk-provider.h> +#include <linux/io.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h>
@@ -239,6 +240,16 @@ static const struct sunxi_ccu_desc sun50i_h5_de2_clk_desc = { .num_resets = ARRAY_SIZE(sun50i_h5_de2_resets), }; +static const struct sunxi_ccu_desc sun50i_h616_de33_clk_desc = { + .ccu_clks = sun8i_de2_ccu_clks, + .num_ccu_clks =ARRAY_SIZE (sun8i_de2_ccu_clks), + + .hw_clks = &sun8i_h3_de2_hw_clks, + + .resets = sun50i_h5_de2_resets, + .num_resets =ARRAY_SIZE (sun50i_h5_de2_resets), +}; +static int sunxi_de2_clk_probe (struct platform_device *pdev) {struct clk *bus_clk, *mod_clk;
@@ -291,6 +302,16 @@ static int sunxi_de2_clk_probe(struct platform_device *pdev) goto err_disable_mod_clk; } +/* +* The DE33 requires these additional (unknown) registers set +* during initialisation. +*/ +if (of_device_is_compatible (pdev->dev.of_node, +"allwinner,sun50i-h616-de33-clk" )) { +writel (0 , reg +0x24 ); +writel (0x0000a980 , reg +0x28 ); + } + ret =devm_sunxi_ccu_probe (&pdev->dev, reg, ccu_desc);if (ret) goto err_assert_reset;
@@ -335,6 +356,10 @@ static const struct of_device_id sunxi_de2_clk_ids[] = { .compatible = "allwinner,sun50i-h6-de3-clk", .data = &sun50i_h5_de2_clk_desc, }, + { + .compatible = "allwinner,sun50i-h616-de33-clk", + .data = &sun50i_h616_de33_clk_desc, + }, { } };MODULE_DEVICE_TABLE (of, sunxi_de2_clk_ids);
Signature · 1 line
2.46.1
PATCH v5 23/26 drm: sun4i: de33: mixer: add Display Engine 3.3 (DE33) support
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
The DE33 is a newer version of the Allwinner Display Engine IP block, found in the H616, H618, H700 and T507 SoCs. DE2 and DE3 are already supported by the mainline driver.
Notable features (from the H616 datasheet and implemented):
- 4096 x 2048 (4K) output support
- AFBC ARM Frame Buffer Compression support
- YUV420 input support
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, and adds a top register map.
Extend the mixer to support the DE33.
---
Changelog v4..v5:
- Whitespace fixes
- Correct strict mode warnings from checkpatch.pl
--- drivers/gpu/drm/sun4i/sun8i_mixer.c | 109 ++++++++++++++++++++++++---- drivers/gpu/drm/sun4i/sun8i_mixer.h | 16 +++- 2 files changed, 108 insertions(+), 17 deletions(-)
drivers/gpu/drm/sun4i/sun8i_mixer.c +94 -15
@@ -321,8 +321,12 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine,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 , -SUN8I_MIXER_GLOBAL_DBUFF_ENABLE ); +if (mixer->cfg->de_type == sun8i_mixer_de33) +regmap_write (mixer->top_regs,SUN50I_MIXER_GLOBAL_DBUFF , +SUN8I_MIXER_GLOBAL_DBUFF_ENABLE ); +else +regmap_write (engine->regs,SUN8I_MIXER_GLOBAL_DBUFF , +SUN8I_MIXER_GLOBAL_DBUFF_ENABLE ); } static struct drm_plane **sun8i_layers_init(struct drm_device *drm,
@@ -371,25 +375,33 @@ static void sun8i_mixer_mode_set(struct sunxi_engine *engine, const struct drm_display_mode *mode) {struct sun8i_mixer *mixer =engine_to_sun8i_mixer (engine); +struct regmap *bld_regs, *disp_regs;u32 bld_base, size, val;bool interlaced; bld_base =sun8i_blender_base (mixer); + bld_regs =sun8i_blender_regmap (mixer); interlaced = !!(mode->flags &DRM_MODE_FLAG_INTERLACE ); size =SUN8I_MIXER_SIZE (mode->hdisplay, mode->vdisplay);DRM_DEBUG_DRIVER ("Updating global size W: %u H: %u\n" , mode->hdisplay, mode->vdisplay); -regmap_write (engine->regs,SUN8I_MIXER_GLOBAL_SIZE , size); -regmap_write (engine->regs,SUN8I_MIXER_BLEND_OUTSIZE (bld_base), size); +if (mixer->cfg->de_type == sun8i_mixer_de33) { + disp_regs = mixer->disp_regs; +regmap_write (mixer->top_regs,SUN50I_MIXER_GLOBAL_SIZE , size); + }else { + disp_regs = mixer->engine.regs; +regmap_write (mixer->engine.regs,SUN8I_MIXER_GLOBAL_SIZE , size); + } +regmap_write (bld_regs,SUN8I_MIXER_BLEND_OUTSIZE (bld_base), size);if (interlaced) val =SUN8I_MIXER_BLEND_OUTCTL_INTERLACED ;else val =0 ; -regmap_update_bits (engine->regs,SUN8I_MIXER_BLEND_OUTCTL (bld_base), +regmap_update_bits (bld_regs,SUN8I_MIXER_BLEND_OUTCTL (bld_base),SUN8I_MIXER_BLEND_OUTCTL_INTERLACED , val); DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n",
@@ -400,10 +412,8 @@ static void sun8i_mixer_mode_set(struct sunxi_engine *engine,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); +regmap_write (disp_regs,SUN8I_MIXER_BLEND_BKCOLOR (bld_base), val); +regmap_write (disp_regs,SUN8I_MIXER_BLEND_ATTR_FCOLOR (bld_base,0 ), val);if (mixer->cfg->has_formatter) sun50i_fmt_setup(mixer, mode->hdisplay,
@@ -443,12 +453,29 @@ static const struct sunxi_engine_ops sun8i_engine_ops = { };static const struct regmap_config sun8i_mixer_regmap_config = { + .name ="layers" , .reg_bits =32 , .val_bits =32 , .reg_stride =4 , .max_register =0xffffc ,/* guessed */ }; +static const struct regmap_config sun8i_top_regmap_config = { + .name ="top" , + .reg_bits =32 , + .val_bits =32 , + .reg_stride =4 , + .max_register =0x3c , +}; + +static const struct regmap_config sun8i_disp_regmap_config = { + .name ="display" , + .reg_bits =32 , + .val_bits =32 , + .reg_stride =4 , + .max_register =0x20000 , +}; +static int sun8i_mixer_of_get_id (struct device_node *node) {struct device_node *ep, *remote;
@@ -471,33 +498,45 @@ static int sun8i_mixer_of_get_id(struct device_node *node)static void sun8i_mixer_init (struct sun8i_mixer *mixer) { +struct regmap *top_regs, *disp_regs;unsigned int base =sun8i_blender_base (mixer);int plane_cnt, i; +if (mixer->cfg->de_type == sun8i_mixer_de33) { + top_regs = mixer->top_regs; + disp_regs = mixer->disp_regs; + }else { + top_regs = mixer->engine.regs; + disp_regs = mixer->engine.regs; + } +/* Enable the mixer */ -regmap_write (mixer->engine.regs,SUN8I_MIXER_GLOBAL_CTL , +regmap_write (top_regs,SUN8I_MIXER_GLOBAL_CTL ,SUN8I_MIXER_GLOBAL_CTL_RT_EN ); +if (mixer->cfg->de_type == sun8i_mixer_de33) +regmap_write (top_regs,SUN50I_MIXER_GLOBAL_CLK ,1 ); +/* Set background color to black */ -regmap_write (mixer->engine.regs,SUN8I_MIXER_BLEND_BKCOLOR (base), +regmap_write (disp_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), +regmap_write (disp_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 ), +regmap_write (disp_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, +regmap_write (disp_regs,SUN8I_MIXER_BLEND_MODE (base, i),SUN8I_MIXER_BLEND_MODE_DEF ); -regmap_update_bits (mixer->engine.regs,SUN8I_MIXER_BLEND_PIPE_CTL (base), +regmap_update_bits (disp_regs,SUN8I_MIXER_BLEND_PIPE_CTL (base),SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK ,0 ); }
@@ -573,6 +612,30 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,return PTR_ERR (mixer->engine.regs); } +if (mixer->cfg->de_type == sun8i_mixer_de33) { + regs =devm_platform_ioremap_resource (pdev,1 ); +if (IS_ERR (regs)) +return PTR_ERR (regs); + + mixer->top_regs =devm_regmap_init_mmio (dev, regs, + &sun8i_top_regmap_config); +if (IS_ERR (mixer->top_regs)) { +dev_err (dev,"Couldn't create the top regmap\n" ); +return PTR_ERR (mixer->top_regs); + } + + regs =devm_platform_ioremap_resource (pdev,2 ); +if (IS_ERR (regs)) +return PTR_ERR (regs); + + mixer->disp_regs =devm_regmap_init_mmio (dev, regs, + &sun8i_disp_regmap_config); +if (IS_ERR (mixer->disp_regs)) { +dev_err (dev,"Couldn't create the disp regmap\n" ); +return PTR_ERR (mixer->disp_regs); + } + } + mixer->reset =devm_reset_control_get (dev,NULL );if (IS_ERR (mixer->reset)) {dev_err (dev,"Couldn't get our reset line\n" );
@@ -787,6 +850,18 @@ static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = { .vi_num = 1, }; +static const struct sun8i_mixer_cfg sun50i_h616_mixer0_cfg = { + .ccsc =CCSC_MIXER0_LAYOUT , + .de_type = sun8i_mixer_de33, + .has_formatter =1 , + .mod_rate =600000000 , + .scaler_mask =0xf , + .scanline_yuv =4096 , + .ui_num =3 , + .vi_num =1 , + .map = {0 ,6 ,7 ,8 }, +}; +static const struct of_device_id sun8i_mixer_of_table[] = { { .compatible ="allwinner,sun8i-a83t-de2-mixer-0" ,
@@ -832,6 +907,10 @@ static const struct of_device_id sun8i_mixer_of_table[] = { .compatible = "allwinner,sun50i-h6-de3-mixer-0", .data = &sun50i_h6_mixer0_cfg, }, + { + .compatible = "allwinner,sun50i-h616-de33-mixer-0", + .data = &sun50i_h616_mixer0_cfg, + }, { } };MODULE_DEVICE_TABLE (of, sun8i_mixer_of_table);
drivers/gpu/drm/sun4i/sun8i_mixer.h +14 -2
@@ -21,6 +21,10 @@#define SUN8I_MIXER_GLOBAL_DBUFF 0x8#define SUN8I_MIXER_GLOBAL_SIZE 0xc +#define SUN50I_MIXER_GLOBAL_SIZE 0x8 +#define SUN50I_MIXER_GLOBAL_CLK 0xc +#define SUN50I_MIXER_GLOBAL_DBUFF 0x10 +#define SUN8I_MIXER_GLOBAL_CTL_RT_EN BIT(0)#define SUN8I_MIXER_GLOBAL_DBUFF_ENABLE BIT(0)
@@ -154,6 +158,7 @@ enum {enum sun8i_mixer_type { sun8i_mixer_de2, sun8i_mixer_de3, + sun8i_mixer_de33, };/**
@@ -180,6 +185,7 @@ struct sun8i_mixer_cfg {unsigned int de_type; unsigned int has_formatter : 1;unsigned int scanline_yuv; +unsigned int map[6 ]; };struct sun8i_mixer {
@@ -191,6 +197,9 @@ struct sun8i_mixer {struct clk *bus_clk;struct clk *mod_clk; + +struct regmap *top_regs; +struct regmap *disp_regs; };enum {
@@ -227,13 +236,16 @@ sun8i_blender_base(struct sun8i_mixer *mixer)static inline struct regmap *sun8i_blender_regmap (struct sun8i_mixer *mixer) { -return mixer->engine.regs; +return mixer->cfg->de_type == sun8i_mixer_de33 ? + mixer->disp_regs : mixer->engine.regs; }static inline u32 sun8i_channel_base (struct sun8i_mixer *mixer,int channel) { -if (mixer->cfg->de_type == sun8i_mixer_de3) +if (mixer->cfg->de_type == sun8i_mixer_de33) +return mixer->cfg->map[channel] *0x20000 +DE2_CH_SIZE ; +else 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 ;
Signature · 1 line
2.46.1
PATCH v5 24/26 drm: sun4i: de33: vi_scaler: add Display Engine 3.3 (DE33) support
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
The vi_scaler appears to be used in preference to the ui_scaler module for hardware video scaling in the DE33.
Enable support for this scaler.
--- drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 19 +++++++++++++++---- drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 7 ++++++- 2 files changed, 21 insertions(+), 5 deletions(-)
drivers/gpu/drm/sun4i/sun8i_ui_layer.c +15 -4
@@ -95,12 +95,23 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel, hscale = state->src_w / state->crtc_w; vscale = state->src_h / state->crtc_h; -sun8i_ui_scaler_setup (mixer, channel, src_w, src_h, dst_w, - dst_h, hscale, vscale, hphase, vphase); -sun8i_ui_scaler_enable (mixer, channel, true); +if (mixer->cfg->de_type == sun8i_mixer_de33) { +sun8i_vi_scaler_setup (mixer, channel, src_w, src_h, + dst_w, dst_h, hscale, vscale, + hphase, vphase, + state->fb->format); + }else { +sun8i_ui_scaler_setup (mixer, channel, src_w, src_h, + dst_w, dst_h, hscale, vscale, + hphase, vphase); +sun8i_ui_scaler_enable (mixer, channel, true); + } }else {DRM_DEBUG_DRIVER ("HW scaling is not needed\n" ); -sun8i_ui_scaler_enable (mixer, channel, false); +if (mixer->cfg->de_type == sun8i_mixer_de33) +sun8i_vi_scaler_disable (mixer, channel); +else +sun8i_ui_scaler_enable (mixer, channel, false); }/* Set base coordinates */
drivers/gpu/drm/sun4i/sun8i_vi_scaler.c +6 -1
@@ -835,7 +835,9 @@ static const u32 bicubic4coefftab32[480] = {static u32 sun8i_vi_scaler_base (struct sun8i_mixer *mixer,int channel) { -if (mixer->cfg->de_type == sun8i_mixer_de3) +if (mixer->cfg->de_type == sun8i_mixer_de33) +return sun8i_channel_base (mixer, channel) +0x3000 ; +else if (mixer->cfg->de_type == sun8i_mixer_de3)return DE3_VI_SCALER_UNIT_BASE +DE3_VI_SCALER_UNIT_SIZE * channel;else
@@ -845,6 +847,9 @@ static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel)static bool sun8i_vi_scaler_is_vi_plane (struct sun8i_mixer *mixer,int channel) { +if (mixer->cfg->de_type == sun8i_mixer_de33) +return mixer->cfg->map[channel] < mixer->cfg->vi_num; +return true; }
Signature · 1 line
2.46.1
PATCH v5 25/26 drm: sun4i: de33: fmt: add Display Engine 3.3 (DE33) support
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
Like the DE3, the DE33 has a FMT (formatter) module, which provides YUV444 to YUV422/YUV420 conversion, format re-mapping and color depth conversion, although the DE33 module appears significantly more capable, including up to 4K video support.
Add support for the DE33.
--- drivers/gpu/drm/sun4i/sun50i_fmt.c | 21 +++++++++++++++++++-- drivers/gpu/drm/sun4i/sun50i_fmt.h | 1 + 2 files changed, 20 insertions(+), 2 deletions(-)
drivers/gpu/drm/sun4i/sun50i_fmt.c +19 -2
@@ -51,6 +51,19 @@ static void sun50i_fmt_de3_limits(u32 *limits, u32 colorspace, bool bit10) } } +static void sun50i_fmt_de33_limits (u32 *limits,u32 colorspace) +{ +if (colorspace ==SUN50I_FMT_CS_YUV444RGB ) { + limits[0 ] =SUN50I_FMT_LIMIT (0 ,4095 ); + limits[1 ] =SUN50I_FMT_LIMIT (0 ,4095 ); + limits[2 ] =SUN50I_FMT_LIMIT (0 ,4095 ); + }else { + limits[0 ] =SUN50I_FMT_LIMIT (256 ,3840 ); + limits[1 ] =SUN50I_FMT_LIMIT (256 ,3840 ); + limits[2 ] =SUN50I_FMT_LIMIT (256 ,3840 ); + } +} +void sun50i_fmt_setup (struct sun8i_mixer *mixer,u16 width,u16 height,u32 format) {
@@ -60,10 +73,14 @@ void sun50i_fmt_setup(struct sun8i_mixer *mixer, u16 width, colorspace =sun50i_fmt_get_colorspace (format); bit10 =sun50i_fmt_is_10bit (format); - base =SUN50I_FMT_DE3 ; + base = mixer->cfg->de_type == sun8i_mixer_de3 ? +SUN50I_FMT_DE3 :SUN50I_FMT_DE33 ; regs =sun8i_blender_regmap (mixer); -sun50i_fmt_de3_limits (limit, colorspace, bit10); +if (mixer->cfg->de_type == sun8i_mixer_de3) +sun50i_fmt_de3_limits (limit, colorspace, bit10); +else +sun50i_fmt_de33_limits (limit, colorspace);regmap_write (regs,SUN50I_FMT_CTRL (base),0 );
drivers/gpu/drm/sun4i/sun50i_fmt.h +1 -0
@@ -9,6 +9,7 @@#include "sun8i_mixer.h" #define SUN50I_FMT_DE3 0xa8000 +#define SUN50I_FMT_DE33 0x5000#define SUN50I_FMT_CTRL (base) ((base) + 0x00)#define SUN50I_FMT_SIZE (base) ((base) + 0x04)
Signature · 1 line
2.46.1
PATCH v5 26/26 drm: sun4i: de33: csc: add Display Engine 3.3 (DE33) support
In reply to Ryan WalklinFrom: Jernej Skrabec <[email protected]>
Like earlier DE versions, the DE33 has a CSC (Color Space Correction) module. which provides color space conversion between BT2020/BT709, and dynamic range conversion between SDR/ST2084/HLG.
Add support for the DE33.
--- drivers/gpu/drm/sun4i/sun8i_csc.c | 96 +++++++++++++++++++++++++++++++ drivers/gpu/drm/sun4i/sun8i_csc.h | 3 + 2 files changed, 99 insertions(+)
drivers/gpu/drm/sun4i/sun8i_csc.c +96 -0
@@ -238,6 +238,14 @@ static const u32 yuv2yuv_de3[2][3][3][12] = { }, }; +static u32 sun8i_csc_base (struct sun8i_mixer *mixer,int layer) +{ +if (mixer->cfg->de_type == sun8i_mixer_de33) +return sun8i_channel_base (mixer, layer) -0x800 ; +else +return ccsc_base[mixer->cfg->ccsc][layer]; +} + static void sun8i_csc_setup(struct regmap *map, u32 base, enum format_type fmt_type, enum drm_color_encoding encoding,
@@ -358,6 +366,90 @@ static void sun8i_de3_ccsc_setup(struct sunxi_engine *engine, int layer, mask, val); } +/* extract constant from high word and invert sign if necessary */ +static u32 sun8i_de33_ccsc_get_constant (u32 value) +{ + value >>=16 ; + +if (value &BIT (15 )) +return 0x400 - (value &0x3ff ); + +return value; +} + +static void sun8i_de33_convert_table (const u32 *src,u32 *dst) +{ + dst[0 ] =sun8i_de33_ccsc_get_constant (src[3 ]); + dst[1 ] =sun8i_de33_ccsc_get_constant (src[7 ]); + dst[2 ] =sun8i_de33_ccsc_get_constant (src[11 ]); +memcpy (&dst[3 ], src,sizeof (u32) *12 ); + dst[6 ] &=0xffff ; + dst[10 ] &=0xffff ; + dst[14 ] &=0xffff ; +} + +static void sun8i_de33_ccsc_setup (struct sun8i_mixer *mixer,int layer, +enum format_type fmt_type, +enum drm_color_encoding encoding, +enum drm_color_range range) +{ +u32 addr, val =0 , base, csc[15 ]; +struct sunxi_engine *engine; +struct regmap *map; +const u32 *table; +int i; + + table = yuv2rgb_de3[range][encoding]; + base =sun8i_csc_base (mixer, layer); + engine = &mixer->engine; + map = engine->regs; + +switch (fmt_type) { +case FORMAT_TYPE_RGB : +if (engine->format ==MEDIA_BUS_FMT_RGB888_1X24 ) +break ; + val =SUN8I_CSC_CTRL_EN ; +sun8i_de33_convert_table (rgb2yuv_de3[engine->encoding], csc); +regmap_bulk_write (map,SUN50I_CSC_COEFF (base,0 ), csc,15 ); +break ; +case FORMAT_TYPE_YUV : + table =sun8i_csc_get_de3_yuv_table (encoding, range, + engine->format, + engine->encoding); +if (!table) +break ; + val =SUN8I_CSC_CTRL_EN ; +sun8i_de33_convert_table (table, csc); +regmap_bulk_write (map,SUN50I_CSC_COEFF (base,0 ), csc,15 ); +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 =SUN8I_CSC_CTRL_EN ; +sun8i_de33_convert_table (table, csc); +for (i =0 ; i <15 ; i++) { + addr =SUN50I_CSC_COEFF (base, i); +if (i >3 ) { +if (((i -3 ) &3 ) ==1 ) + addr =SUN50I_CSC_COEFF (base, i +1 ); +else if (((i -3 ) &3 ) ==2 ) + addr =SUN50I_CSC_COEFF (base, i -1 ); + } +regmap_write (map, addr, csc[i]); + } +break ; +default : + val =0 ; +DRM_WARN ("Wrong CSC mode specified.\n" ); +return ; + } + +regmap_write (map,SUN8I_CSC_CTRL (base), val); +} + void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, enum format_type fmt_type, enum drm_color_encoding encoding,
@@ -369,6 +461,10 @@ void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer,sun8i_de3_ccsc_setup (&mixer->engine, layer, fmt_type, encoding, range);return ; + }else if (mixer->cfg->de_type == sun8i_mixer_de33) { +sun8i_de33_ccsc_setup (mixer, layer, fmt_type, + encoding, range); +return ; }if (layer < mixer->cfg->vi_num) {
drivers/gpu/drm/sun4i/sun8i_csc.h +3 -0
@@ -20,6 +20,9 @@ struct sun8i_mixer;#define SUN8I_CSC_CTRL (base) ((base) + 0x0)#define SUN8I_CSC_COEFF (base, i) ((base) + 0x10 + 4 * (i)) +#define SUN50I_CSC_COEFF (base, i) ((base) + 0x04 + 4 * (i)) +#define SUN50I_CSC_ALPHA (base) ((base) + 0x40) +#define SUN8I_CSC_CTRL_EN BIT(0)enum format_type {
Signature · 1 line
2.46.1
tested on 6.12-rc1 with RG35XX-H
Quoted 81 lines · Ryan Walklin
Hi,
V5 of this patch series adding support for the Allwinner DE33 display engine variant. V5 is rebased on torvalds/master as of today with the 6.12 drm-next patches included, with no code changes required. V3 and V4 were in turn rebased on top of the layer init and modesetting changes merged for 6.11. No functional changes from V4, fixes and reviews from previous V1-4 added, and relevant issues found by checkpatch.pl corrected.
Original blurb below:
There is existing mainline support for the DE2 and DE3 AllWinner display pipeline IP blocks, used in the A64 and H6 among others, however the H700 (as well as the H616/H618 and the T507 automotive SoC) have a newer version of the Display Engine (v3.3/DE33) which adds additional high-resolution support as well as YUV colour formats and AFBC compression support.
This patch set adds DE33 support, following up from the previous RFC [1], with significant rework to break down the previous relatively complex set into more logical steps, detailed below.
1. Refactor the existing DE2/DE3 code in readiness to support YUV colour formats in the DE3 engine (patches 1-4).
2. Add YUV420 colour format support in the DE3 driver (patches 5-12).
3. Replace theis_de3mixer flag with an enum to support multiple DE versions (patch 13).
4. Refactor the mixer,vi_scalerand some register code to merge common init code and more easily support multiple DE versions (patches 14-17).
5. Add Arm Frame Buffer Compression (AFBC) compressed buffer support to the DE3 driver. This is currently only supported for VI layers (for HW-decoded video output) but is well integrated into these changes and a subsequent patchset to enable the Video Engine is planned. (patch 18).
6. Add DT bindings for the DE33 engine. (patches 19-21).
7. Extend the DE2/3 driver for the DE33, comprising clock, mixer,vi_scaler, fmt and csc module support (patches 22-26).Further patchsets are planned to support HDMI and the LCD timing controller present in these SoCs.
Regards,
Ryan
Jernej Skrabec (22):
drm: sun4i: de2/de3: Change CSC argument
drm: sun4i: de2/de3: Merge CSC functions into one
drm: sun4i: de2/de3: call csc setup also for UI layer
drm: sun4i: de2: Initialize layer fields earlier
drm: sun4i: de3: Add YUV formatter module
drm: sun4i: de3: add format enumeration function to engine
drm: sun4i: de3: add formatter flag to mixer config
drm: sun4i: de3: add YUV support to the DE3 mixer
drm: sun4i: de3: pass engine reference to ccsc setup function
drm: sun4i: de3: add YUV support to the color space correction module
drm: sun4i: de3: add YUV support to the TCON
drm: sun4i: support YUV formats in VI scaler
drm: sun4i: de2/de3: add mixer version enum
drm: sun4i: de2/de3: refactor mixer initialisation
drm: sun4i:vi_scalerrefactorvi_scalerenablement
drm: sun4i: de2/de3: add generic blender register reference function
drm: sun4i: de2/de3: use generic register reference function for layer
configuration
drm: sun4i: de3: Implement AFBC support
drm: sun4i: de33: mixer: add Display Engine 3.3 (DE33) support
drm: sun4i: de33:vi_scaler: add Display Engine 3.3 (DE33) support
drm: sun4i: de33: fmt: add Display Engine 3.3 (DE33) support
drm: sun4i: de33: csc: add Display Engine 3.3 (DE33) supportRyan Walklin (4):
dt-bindings: allwinner: add H616 DE33 bus binding
dt-bindings: allwinner: add H616 DE33 clock binding
dt-bindings: allwinner: add H616 DE33 mixer binding
clk: sunxi-ng: ccu: add Display Engine 3.3 (DE33) support.../bus/allwinner,sun50i-a64-de2.yaml | 4 +- .../clock/allwinner,sun8i-a83t-de2-clk.yaml | 1 + .../allwinner,sun8i-a83t-de2-mixer.yaml | 1 + drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 25 ++ drivers/gpu/drm/sun4i/Makefile | 3 +- drivers/gpu/drm/sun4i/sun4i_tcon.c | 26 +- drivers/gpu/drm/sun4i/sun50i_afbc.c | 250 +++++++++++++ drivers/gpu/drm/sun4i/sun50i_afbc.h | 87 +++++ drivers/gpu/drm/sun4i/sun50i_fmt.c | 99 +++++ drivers/gpu/drm/sun4i/sun50i_fmt.h | 33 ++ drivers/gpu/drm/sun4i/sun8i_csc.c | 341 +++++++++++++++--- drivers/gpu/drm/sun4i/sun8i_csc.h | 20 +- drivers/gpu/drm/sun4i/sun8i_mixer.c | 226 +++++++++--- drivers/gpu/drm/sun4i/sun8i_mixer.h | 31 +- drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 41 ++- drivers/gpu/drm/sun4i/sun8i_ui_scaler.c | 2 +- drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 133 +++++-- drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 115 ++++-- drivers/gpu/drm/sun4i/sun8i_vi_scaler.h | 2 +- drivers/gpu/drm/sun4i/sunxi_engine.h | 34 ++ 20 files changed, 1269 insertions(+), 205 deletions(-)create mode 100644
drivers/gpu/drm/sun4i/sun50i_afbc.ccreate mode 100644drivers/gpu/drm/sun4i/sun50i_afbc.hcreate mode 100644drivers/gpu/drm/sun4i/sun50i_fmt.ccreate mode 100644drivers/gpu/drm/sun4i/sun50i_fmt.h
Chris Morgan
Tested-byQuoted 86 lines · Philippe Simons
tested on 6.12-rc1 with RG35XX-H
Tested-by Philippe Simons <[email protected]>Quoted 81 lines · Ryan Walklin
Hi,
V5 of this patch series adding support for the Allwinner DE33 display engine variant. V5 is rebased on torvalds/master as of today with the 6.12 drm-next patches included, with no code changes required. V3 and V4 were in turn rebased on top of the layer init and modesetting changes merged for 6.11. No functional changes from V4, fixes and reviews from previous V1-4 added, and relevant issues found by checkpatch.pl corrected.
Original blurb below:
There is existing mainline support for the DE2 and DE3 AllWinner display pipeline IP blocks, used in the A64 and H6 among others, however the H700 (as well as the H616/H618 and the T507 automotive SoC) have a newer version of the Display Engine (v3.3/DE33) which adds additional high-resolution support as well as YUV colour formats and AFBC compression support.
This patch set adds DE33 support, following up from the previous RFC [1], with significant rework to break down the previous relatively complex set into more logical steps, detailed below.
1. Refactor the existing DE2/DE3 code in readiness to support YUV colour formats in the DE3 engine (patches 1-4).
2. Add YUV420 colour format support in the DE3 driver (patches 5-12).
3. Replace theis_de3mixer flag with an enum to support multiple DE versions (patch 13).
4. Refactor the mixer,vi_scalerand some register code to merge common init code and more easily support multiple DE versions (patches 14-17).
5. Add Arm Frame Buffer Compression (AFBC) compressed buffer support to the DE3 driver. This is currently only supported for VI layers (for HW-decoded video output) but is well integrated into these changes and a subsequent patchset to enable the Video Engine is planned. (patch 18).
6. Add DT bindings for the DE33 engine. (patches 19-21).
7. Extend the DE2/3 driver for the DE33, comprising clock, mixer,vi_scaler, fmt and csc module support (patches 22-26).Further patchsets are planned to support HDMI and the LCD timing controller present in these SoCs.
Regards,
Ryan
Jernej Skrabec (22):
drm: sun4i: de2/de3: Change CSC argument
drm: sun4i: de2/de3: Merge CSC functions into one
drm: sun4i: de2/de3: call csc setup also for UI layer
drm: sun4i: de2: Initialize layer fields earlier
drm: sun4i: de3: Add YUV formatter module
drm: sun4i: de3: add format enumeration function to engine
drm: sun4i: de3: add formatter flag to mixer config
drm: sun4i: de3: add YUV support to the DE3 mixer
drm: sun4i: de3: pass engine reference to ccsc setup function
drm: sun4i: de3: add YUV support to the color space correction module
drm: sun4i: de3: add YUV support to the TCON
drm: sun4i: support YUV formats in VI scaler
drm: sun4i: de2/de3: add mixer version enum
drm: sun4i: de2/de3: refactor mixer initialisation
drm: sun4i:vi_scalerrefactorvi_scalerenablement
drm: sun4i: de2/de3: add generic blender register reference function
drm: sun4i: de2/de3: use generic register reference function for layer
configuration
drm: sun4i: de3: Implement AFBC support
drm: sun4i: de33: mixer: add Display Engine 3.3 (DE33) support
drm: sun4i: de33:vi_scaler: add Display Engine 3.3 (DE33) support
drm: sun4i: de33: fmt: add Display Engine 3.3 (DE33) support
drm: sun4i: de33: csc: add Display Engine 3.3 (DE33) supportRyan Walklin (4):
dt-bindings: allwinner: add H616 DE33 bus binding
dt-bindings: allwinner: add H616 DE33 clock binding
dt-bindings: allwinner: add H616 DE33 mixer binding
clk: sunxi-ng: ccu: add Display Engine 3.3 (DE33) support.../bus/allwinner,sun50i-a64-de2.yaml | 4 +- .../clock/allwinner,sun8i-a83t-de2-clk.yaml | 1 + .../allwinner,sun8i-a83t-de2-mixer.yaml | 1 + drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 25 ++ drivers/gpu/drm/sun4i/Makefile | 3 +- drivers/gpu/drm/sun4i/sun4i_tcon.c | 26 +- drivers/gpu/drm/sun4i/sun50i_afbc.c | 250 +++++++++++++ drivers/gpu/drm/sun4i/sun50i_afbc.h | 87 +++++ drivers/gpu/drm/sun4i/sun50i_fmt.c | 99 +++++ drivers/gpu/drm/sun4i/sun50i_fmt.h | 33 ++ drivers/gpu/drm/sun4i/sun8i_csc.c | 341 +++++++++++++++--- drivers/gpu/drm/sun4i/sun8i_csc.h | 20 +- drivers/gpu/drm/sun4i/sun8i_mixer.c | 226 +++++++++--- drivers/gpu/drm/sun4i/sun8i_mixer.h | 31 +- drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 41 ++- drivers/gpu/drm/sun4i/sun8i_ui_scaler.c | 2 +- drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 133 +++++-- drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 115 ++++-- drivers/gpu/drm/sun4i/sun8i_vi_scaler.h | 2 +- drivers/gpu/drm/sun4i/sunxi_engine.h | 34 ++ 20 files changed, 1269 insertions(+), 205 deletions(-)create mode 100644
drivers/gpu/drm/sun4i/sun50i_afbc.ccreate mode 100644drivers/gpu/drm/sun4i/sun50i_afbc.hcreate mode 100644drivers/gpu/drm/sun4i/sun50i_fmt.ccreate mode 100644drivers/gpu/drm/sun4i/sun50i_fmt.h
I just wanted to add my Tested-By to this patch series. That said, I can confirm that we also need to add support for the clock and reset before we activate the display engine. I'll submit patches for that in a different series (it's a pre-requisite of this but can be done independently).
Additionally, I do have a few comments on the yaml documentation.
Thank you,
Chris