Messages in this thread Patch in this message | | | Date | Fri, 24 Nov 2023 14:40:18 +0100 | Subject | Re: [PATCH v2 5/6] drm/vs: Add KMS crtc&plane | From | Thomas Zimmermann <> |
| |
Hi
Am 25.10.23 um 12:39 schrieb Keith Zhao: [...] > + > +static struct drm_crtc_state * > +vs_crtc_atomic_duplicate_state(struct drm_crtc *crtc) > +{ > + struct vs_crtc_state *ori_state;
I have not yet seen 'ori_' being used anywhere. Typical names are 'state' for the current state and 'new_state' for the newly created state. Would be nice for consistency with other drivers.
> + struct vs_crtc_state *state; > + > + if (!crtc->state) > + return NULL; > + > + ori_state = to_vs_crtc_state(crtc->state); > + state = kzalloc(sizeof(*state), GFP_KERNEL); > + if (!state) > + return NULL; > + > + __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base); > + > + state->output_fmt = ori_state->output_fmt; > + state->encoder_type = ori_state->encoder_type; > + state->bpp = ori_state->bpp; > + state->underflow = ori_state->underflow; > + > + return &state->base; > +} > + > +static void vs_crtc_atomic_destroy_state(struct drm_crtc *crtc, > + struct drm_crtc_state *state) > +{ > + __drm_atomic_helper_crtc_destroy_state(state); > + kfree(to_vs_crtc_state(state)); > +} > + > +static int vs_crtc_enable_vblank(struct drm_crtc *crtc) > +{ > + struct vs_crtc *vs_crtc = to_vs_crtc(crtc); > + struct vs_dc *dc = dev_get_drvdata(vs_crtc->dev); > + > + vs_dc_enable_vblank(dc, true); > + > + return 0; > +} > + > +static void vs_crtc_disable_vblank(struct drm_crtc *crtc) > +{ > + struct vs_crtc *vs_crtc = to_vs_crtc(crtc); > + struct vs_dc *dc = dev_get_drvdata(vs_crtc->dev); > + > + vs_dc_enable_vblank(dc, false); > +} > + > +static const struct drm_crtc_funcs vs_crtc_funcs = { > + .set_config = drm_atomic_helper_set_config, > + .page_flip = drm_atomic_helper_page_flip, > + .reset = vs_crtc_reset, > + .atomic_duplicate_state = vs_crtc_atomic_duplicate_state, > + .atomic_destroy_state = vs_crtc_atomic_destroy_state, > + .enable_vblank = vs_crtc_enable_vblank, > + .disable_vblank = vs_crtc_disable_vblank, > +}; > + > +static u8 cal_pixel_bits(u32 bus_format) > +{ > + u8 bpp; > + > + switch (bus_format) { > + case MEDIA_BUS_FMT_RGB565_1X16: > + case MEDIA_BUS_FMT_UYVY8_1X16: > + bpp = 16; > + break; > + case MEDIA_BUS_FMT_RGB666_1X18: > + case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: > + bpp = 18; > + break; > + case MEDIA_BUS_FMT_UYVY10_1X20: > + bpp = 20; > + break; > + case MEDIA_BUS_FMT_BGR888_1X24: > + case MEDIA_BUS_FMT_UYYVYY8_0_5X24: > + case MEDIA_BUS_FMT_YUV8_1X24: > + bpp = 24; > + break; > + case MEDIA_BUS_FMT_RGB101010_1X30: > + case MEDIA_BUS_FMT_UYYVYY10_0_5X30: > + case MEDIA_BUS_FMT_YUV10_1X30: > + bpp = 30; > + break; > + default: > + bpp = 24; > + break; > + } > + > + return bpp; > +} > + > +static void vs_crtc_atomic_enable(struct drm_crtc *crtc, > + struct drm_atomic_state *state) > +{ > + struct vs_crtc *vs_crtc = to_vs_crtc(crtc); > + struct vs_dc *dc = dev_get_drvdata(vs_crtc->dev); > + struct vs_crtc_state *vs_crtc_state = to_vs_crtc_state(crtc->state); > + > + vs_crtc_state->bpp = cal_pixel_bits(vs_crtc_state->output_fmt); > + > + vs_dc_enable(dc, crtc); > + drm_crtc_vblank_on(crtc); > +} > + > +static void vs_crtc_atomic_disable(struct drm_crtc *crtc, > + struct drm_atomic_state *state) > +{ > + struct vs_crtc *vs_crtc = to_vs_crtc(crtc); > + struct vs_dc *dc = dev_get_drvdata(vs_crtc->dev); > + > + drm_crtc_vblank_off(crtc); > + > + vs_dc_disable(dc, crtc); > + > + if (crtc->state->event && !crtc->state->active) { > + spin_lock_irq(&crtc->dev->event_lock); > + drm_crtc_send_vblank_event(crtc, crtc->state->event); > + spin_unlock_irq(&crtc->dev->event_lock); > + > + crtc->state->event = NULL; > + } > +} > + > +static void vs_crtc_atomic_begin(struct drm_crtc *crtc, > + struct drm_atomic_state *state) > +{ > + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, > + crtc); > + > + struct vs_crtc *vs_crtc = to_vs_crtc(crtc); > + struct device *dev = vs_crtc->dev; > + struct drm_property_blob *blob = crtc->state->gamma_lut; > + struct drm_color_lut *lut; > + struct vs_dc *dc = dev_get_drvdata(dev); > + > + if (crtc_state->color_mgmt_changed) { > + if (blob && blob->length) { > + lut = blob->data; > + vs_dc_set_gamma(dc, crtc, lut, > + blob->length / sizeof(*lut)); > + vs_dc_enable_gamma(dc, crtc, true); > + } else { > + vs_dc_enable_gamma(dc, crtc, false); > + } > + } > +} > + > +static void vs_crtc_atomic_flush(struct drm_crtc *crtc, > + struct drm_atomic_state *state) > +{ > + struct vs_crtc *vs_crtc = to_vs_crtc(crtc); > + struct drm_pending_vblank_event *event = crtc->state->event; > + struct vs_dc *dc = dev_get_drvdata(vs_crtc->dev); > + > + vs_dc_commit(dc); > + > + if (event) { > + WARN_ON(drm_crtc_vblank_get(crtc) != 0); > + > + spin_lock_irq(&crtc->dev->event_lock); > + drm_crtc_arm_vblank_event(crtc, event); > + spin_unlock_irq(&crtc->dev->event_lock); > + crtc->state->event = NULL; > + } > +} > + > +static const struct drm_crtc_helper_funcs vs_crtc_helper_funcs = { > + .atomic_check = drm_crtc_helper_atomic_check, > + .atomic_enable = vs_crtc_atomic_enable, > + .atomic_disable = vs_crtc_atomic_disable, > + .atomic_begin = vs_crtc_atomic_begin, > + .atomic_flush = vs_crtc_atomic_flush, > +}; > + > +static const struct drm_prop_enum_list vs_sync_mode_enum_list[] = { > + { VS_SINGLE_DC, "single dc mode" }, > + { VS_MULTI_DC_PRIMARY, "primary dc for multi dc mode" }, > + { VS_MULTI_DC_SECONDARY, "secondary dc for multi dc mode" }, > +}; > + > +struct vs_crtc *vs_crtc_create(struct drm_device *drm_dev, > + struct vs_dc_info *info) > +{ > + struct vs_crtc *crtc; > + int ret; > + > + if (!info) > + return NULL; > + > + crtc = drmm_kzalloc(drm_dev, sizeof(*crtc), GFP_KERNEL); > + if (!crtc) > + return NULL; > + > + ret = drmm_crtc_init_with_planes(drm_dev, &crtc->base, > + NULL, NULL, &vs_crtc_funcs, > + info->name ? info->name : NULL); > + if (ret) > + return NULL; > + > + drm_crtc_helper_add(&crtc->base, &vs_crtc_helper_funcs); > + > + if (info->gamma_size) { > + ret = drm_mode_crtc_set_gamma_size(&crtc->base, > + info->gamma_size); > + if (ret) > + return NULL; > + > + drm_crtc_enable_color_mgmt(&crtc->base, 0, false, > + info->gamma_size); > + } > + > + crtc->max_bpc = info->max_bpc; > + crtc->color_formats = info->color_formats; > + return crtc; > +} > diff --git a/drivers/gpu/drm/verisilicon/vs_crtc.h b/drivers/gpu/drm/verisilicon/vs_crtc.h > new file mode 100644 > index 000000000..526dd63e5 > --- /dev/null > +++ b/drivers/gpu/drm/verisilicon/vs_crtc.h > @@ -0,0 +1,43 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2023 VeriSilicon Holdings Co., Ltd. > + */ > + > +#ifndef __VS_CRTC_H__ > +#define __VS_CRTC_H__ > + > +#include <drm/drm_crtc.h> > +#include <drm/drm_crtc_helper.h> > + > +#include "vs_type.h" > + > +struct vs_crtc_state { > + struct drm_crtc_state base; > + > + u32 output_fmt; > + u8 encoder_type; > + u8 bpp; > + bool underflow; > +}; > + > +struct vs_crtc { > + struct drm_crtc base; > + struct device *dev; > + unsigned int max_bpc; > + unsigned int color_formats; > +}; > + > +struct vs_crtc *vs_crtc_create(struct drm_device *drm_dev, > + struct vs_dc_info *info); > + > +static inline struct vs_crtc *to_vs_crtc(struct drm_crtc *crtc) > +{ > + return container_of(crtc, struct vs_crtc, base); > +} > + > +static inline struct vs_crtc_state * > +to_vs_crtc_state(struct drm_crtc_state *state) > +{ > + return container_of(state, struct vs_crtc_state, base); > +} > +#endif /* __VS_CRTC_H__ */ > diff --git a/drivers/gpu/drm/verisilicon/vs_dc.c b/drivers/gpu/drm/verisilicon/vs_dc.c > new file mode 100644 > index 000000000..b5ab92d98 > --- /dev/null > +++ b/drivers/gpu/drm/verisilicon/vs_dc.c > @@ -0,0 +1,1002 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2023 VeriSilicon Holdings Co., Ltd. > + */ > + > +#include <linux/component.h> > +#include <linux/clk.h> > +#include <linux/of.h> > +#include <linux/of_device.h> > +#include <linux/pm_runtime.h> > +#include <linux/reset.h> > + > +#include <drm/drm_atomic.h> > +#include <drm/drm_atomic_helper.h> > +#include <drm/drm_blend.h> > +#include <drm/drm_framebuffer.h> > +#include <drm/drm_vblank.h> > +#include <drm/vs_drm.h> > + > +#include "vs_dc_hw.h" > +#include "vs_dc.h" > +#include "vs_drv.h" > + > +static const char * const vout_clocks[] = { > + "noc_bus", > + "channel0", > + "channel1", > + "dc_core", > + "axi_core", > + "ahb", > + "hdmi_tx", > + "dc_parent", > + > +}; > + > +static const char * const vout_resets[] = { > + "axi", > + "ahb", > + "core", > +}; > + > +static inline void update_format(u32 format, u64 mod, struct dc_hw_fb *fb) > +{ > + u8 f = FORMAT_A8R8G8B8; > + > + switch (format) { > + case DRM_FORMAT_XRGB4444: > + case DRM_FORMAT_RGBX4444: > + case DRM_FORMAT_XBGR4444: > + case DRM_FORMAT_BGRX4444: > + f = FORMAT_X4R4G4B4; > + break; > + case DRM_FORMAT_ARGB4444: > + case DRM_FORMAT_RGBA4444: > + case DRM_FORMAT_ABGR4444: > + case DRM_FORMAT_BGRA4444: > + f = FORMAT_A4R4G4B4; > + break; > + case DRM_FORMAT_XRGB1555: > + case DRM_FORMAT_RGBX5551: > + case DRM_FORMAT_XBGR1555: > + case DRM_FORMAT_BGRX5551: > + f = FORMAT_X1R5G5B5; > + break; > + case DRM_FORMAT_ARGB1555: > + case DRM_FORMAT_RGBA5551: > + case DRM_FORMAT_ABGR1555: > + case DRM_FORMAT_BGRA5551: > + f = FORMAT_A1R5G5B5; > + break; > + case DRM_FORMAT_RGB565: > + case DRM_FORMAT_BGR565: > + f = FORMAT_R5G6B5; > + break; > + case DRM_FORMAT_XRGB8888: > + case DRM_FORMAT_RGBX8888: > + case DRM_FORMAT_XBGR8888: > + case DRM_FORMAT_BGRX8888: > + f = FORMAT_X8R8G8B8; > + break; > + case DRM_FORMAT_ARGB8888: > + case DRM_FORMAT_RGBA8888: > + case DRM_FORMAT_ABGR8888: > + case DRM_FORMAT_BGRA8888: > + f = FORMAT_A8R8G8B8; > + break; > + case DRM_FORMAT_YUYV: > + case DRM_FORMAT_YVYU: > + f = FORMAT_YUY2; > + break; > + case DRM_FORMAT_UYVY: > + case DRM_FORMAT_VYUY: > + f = FORMAT_UYVY; > + break; > + case DRM_FORMAT_YUV420: > + case DRM_FORMAT_YVU420: > + f = FORMAT_YV12; > + break; > + case DRM_FORMAT_NV21: > + f = FORMAT_NV12; > + break; > + case DRM_FORMAT_NV16: > + case DRM_FORMAT_NV61: > + f = FORMAT_NV16; > + break; > + case DRM_FORMAT_P010: > + f = FORMAT_P010; > + break; > + case DRM_FORMAT_ARGB2101010: > + case DRM_FORMAT_RGBA1010102: > + case DRM_FORMAT_ABGR2101010: > + case DRM_FORMAT_BGRA1010102: > + f = FORMAT_A2R10G10B10; > + break; > + case DRM_FORMAT_NV12: > + f = FORMAT_NV12; > + break; > + case DRM_FORMAT_YUV444: > + f = FORMAT_YUV444; > + break; > + default: > + break; > + } > + > + fb->format = f; > +} > + > +static inline void update_swizzle(u32 format, struct dc_hw_fb *fb) > +{ > + fb->swizzle = SWIZZLE_ARGB; > + fb->uv_swizzle = 0; > + > + switch (format) { > + case DRM_FORMAT_RGBX4444: > + case DRM_FORMAT_RGBA4444: > + case DRM_FORMAT_RGBX5551: > + case DRM_FORMAT_RGBA5551: > + case DRM_FORMAT_RGBX8888: > + case DRM_FORMAT_RGBA8888: > + case DRM_FORMAT_RGBA1010102: > + fb->swizzle = SWIZZLE_RGBA; > + break; > + case DRM_FORMAT_XBGR4444: > + case DRM_FORMAT_ABGR4444: > + case DRM_FORMAT_XBGR1555: > + case DRM_FORMAT_ABGR1555: > + case DRM_FORMAT_BGR565: > + case DRM_FORMAT_XBGR8888: > + case DRM_FORMAT_ABGR8888: > + case DRM_FORMAT_ABGR2101010: > + fb->swizzle = SWIZZLE_ABGR; > + break; > + case DRM_FORMAT_BGRX4444: > + case DRM_FORMAT_BGRA4444: > + case DRM_FORMAT_BGRX5551: > + case DRM_FORMAT_BGRA5551: > + case DRM_FORMAT_BGRX8888: > + case DRM_FORMAT_BGRA8888: > + case DRM_FORMAT_BGRA1010102: > + fb->swizzle = SWIZZLE_BGRA; > + break; > + case DRM_FORMAT_YVYU: > + case DRM_FORMAT_VYUY: > + case DRM_FORMAT_NV21: > + case DRM_FORMAT_NV61: > + fb->uv_swizzle = 1; > + break; > + default: > + break; > + } > +} > + > +static inline void update_watermark(struct drm_property_blob *watermark, > + struct dc_hw_fb *fb) > +{ > + struct drm_vs_watermark *data; > + > + fb->water_mark = 0; > + > + if (watermark) { > + data = watermark->data; > + fb->water_mark = data->watermark & 0xFFFFF; > + } > +} > + > +static inline u8 to_vs_rotation(unsigned int rotation) > +{ > + u8 rot; > + > + switch (rotation & DRM_MODE_REFLECT_MASK) { > + case DRM_MODE_REFLECT_X: > + rot = FLIP_X; > + return rot; > + case DRM_MODE_REFLECT_Y: > + rot = FLIP_Y; > + return rot; > + case DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y: > + rot = FLIP_XY; > + return rot; > + default: > + break; > + } > + > + switch (rotation & DRM_MODE_ROTATE_MASK) { > + case DRM_MODE_ROTATE_0: > + rot = ROT_0; > + break; > + case DRM_MODE_ROTATE_90: > + rot = ROT_90; > + break; > + case DRM_MODE_ROTATE_180: > + rot = ROT_180; > + break; > + case DRM_MODE_ROTATE_270: > + rot = ROT_270; > + break; > + default: > + rot = ROT_0; > + break; > + } > + > + return rot; > +} > + > +static inline u8 to_vs_yuv_color_space(u32 color_space) > +{ > + u8 cs; > + > + switch (color_space) { > + case DRM_COLOR_YCBCR_BT601: > + cs = COLOR_SPACE_601; > + break; > + case DRM_COLOR_YCBCR_BT709: > + cs = COLOR_SPACE_709; > + break; > + case DRM_COLOR_YCBCR_BT2020: > + cs = COLOR_SPACE_2020; > + break; > + default: > + cs = COLOR_SPACE_601; > + break; > + } > + > + return cs; > +} > + > +static inline u8 to_vs_tile_mode(u64 modifier) > +{ > + if (modifier == DRM_FORMAT_MOD_VIVANTE_TILED) > + return DC_TILE_MODE4X4; > + > + return (u8)(modifier & DRM_FORMAT_MOD_VERISILICON_NORM_MODE_MASK); > +} > + > +static inline u8 to_vs_display_id(struct vs_dc *dc, struct drm_crtc *crtc) > +{ > + u8 panel_num = dc->hw.info->panel_num; > + u32 index = drm_crtc_index(crtc); > + int i; > + > + for (i = 0; i < panel_num; i++) { > + if (index == dc->crtc[i]->base.index) > + return i; > + } > + > + return 0; > +} > + > +static void vs_drm_update_pitch_alignment(struct drm_device *drm_dev, > + unsigned int alignment) > +{ > + struct vs_drm_device *priv = to_vs_drm_private(drm_dev); > + > + if (alignment > priv->pitch_alignment) > + priv->pitch_alignment = alignment; > +} > + > +static int plda_clk_rst_init(struct device *dev) > +{ > + int ret = 0; > + struct vs_dc *dc = dev_get_drvdata(dev); > + > + ret = clk_bulk_prepare_enable(dc->nclks, dc->clk_vout); > + if (ret) { > + dev_err(dev, "failed to enable clocks\n"); > + return ret; > + } > + > + ret = reset_control_bulk_deassert(dc->nrsts, dc->rst_vout); > + return ret; > +} > + > +static void plda_clk_rst_deinit(struct device *dev) > +{ > + struct vs_dc *dc = dev_get_drvdata(dev); > + > + reset_control_bulk_assert(dc->nrsts, dc->rst_vout); > + clk_bulk_disable_unprepare(dc->nclks, dc->clk_vout); > +} > + > +static void dc_deinit(struct device *dev) > +{ > + struct vs_dc *dc = dev_get_drvdata(dev); > + > + dc_hw_enable_interrupt(&dc->hw, 0); > + dc_hw_deinit(&dc->hw); > + plda_clk_rst_deinit(dev); > +} > + > +static int dc_init(struct device *dev) > +{ > + struct vs_dc *dc = dev_get_drvdata(dev); > + int ret; > + > + dc->first_frame = true; > + > + ret = plda_clk_rst_init(dev); > + if (ret < 0) { > + dev_err(dev, "failed to init dc clk reset: %d\n", ret); > + return ret; > + } > + > + ret = dc_hw_init(&dc->hw); > + if (ret) { > + dev_err(dev, "failed to init DC HW\n"); > + return ret; > + } > + return 0; > +} > + > +void vs_dc_enable(struct vs_dc *dc, struct drm_crtc *crtc) > +{ > + struct vs_crtc_state *crtc_state = to_vs_crtc_state(crtc->state); > + struct drm_display_mode *mode = &crtc->state->adjusted_mode; > + struct dc_hw_display display; > + > + display.bus_format = crtc_state->output_fmt; > + display.h_active = mode->hdisplay; > + display.h_total = mode->htotal; > + display.h_sync_start = mode->hsync_start; > + display.h_sync_end = mode->hsync_end; > + if (mode->flags & DRM_MODE_FLAG_PHSYNC) > + display.h_sync_polarity = true; > + else > + display.h_sync_polarity = false; > + > + display.v_active = mode->vdisplay; > + display.v_total = mode->vtotal; > + display.v_sync_start = mode->vsync_start; > + display.v_sync_end = mode->vsync_end; > + > + if (mode->flags & DRM_MODE_FLAG_PVSYNC) > + display.v_sync_polarity = true; > + else > + display.v_sync_polarity = false; > + > + display.id = to_vs_display_id(dc, crtc); > + > + display.enable = true; > + > + if (crtc_state->encoder_type == DRM_MODE_ENCODER_DSI) { > + dc_hw_set_out(&dc->hw, OUT_DPI, display.id); > + clk_set_rate(dc->clk_vout[CLK_VOUT_SOC_PIX].clk, mode->clock * 1000); > + clk_set_parent(dc->clk_vout[CLK_VOUT_PIX1].clk, > + dc->clk_vout[CLK_VOUT_SOC_PIX].clk); > + } else { > + dc_hw_set_out(&dc->hw, OUT_DP, display.id); > + clk_set_parent(dc->clk_vout[CLK_VOUT_PIX0].clk, > + dc->clk_vout[CLK_VOUT_HDMI_PIX].clk); > + } > + > + dc_hw_setup_display(&dc->hw, &display); > +} > + > +void vs_dc_disable(struct vs_dc *dc, struct drm_crtc *crtc) > +{ > + struct dc_hw_display display; > + > + display.id = to_vs_display_id(dc, crtc); > + display.enable = false; > + > + dc_hw_setup_display(&dc->hw, &display); > +} > + > +void vs_dc_set_gamma(struct vs_dc *dc, struct drm_crtc *crtc, > + struct drm_color_lut *lut, unsigned int size) > +{ > + u16 i, r, g, b; > + u8 bits, id; > + > + if (size != dc->hw.info->gamma_size) { > + drm_err(crtc->dev, "gamma size does not match!\n"); > + return; > + } > + > + id = to_vs_display_id(dc, crtc); > + > + bits = dc->hw.info->gamma_bits; > + for (i = 0; i < size; i++) { > + r = drm_color_lut_extract(lut[i].red, bits); > + g = drm_color_lut_extract(lut[i].green, bits); > + b = drm_color_lut_extract(lut[i].blue, bits); > + dc_hw_update_gamma(&dc->hw, id, i, r, g, b); > + } > +} > + > +void vs_dc_enable_gamma(struct vs_dc *dc, struct drm_crtc *crtc, > + bool enable) > +{ > + u8 id; > + > + id = to_vs_display_id(dc, crtc); > + dc_hw_enable_gamma(&dc->hw, id, enable); > +} > + > +void vs_dc_enable_vblank(struct vs_dc *dc, bool enable) > +{ > + dc_hw_enable_interrupt(&dc->hw, enable); > +} > + > +static u32 calc_factor(u32 src, u32 dest) > +{ > + u32 factor = 1 << 16; > + > + if (src > 1 && dest > 1) > + factor = ((src - 1) << 16) / (dest - 1); > + > + return factor; > +} > + > +static void update_scale(struct drm_plane_state *state, struct dc_hw_roi *roi, > + struct dc_hw_scale *scale) > +{ > + int dst_w = drm_rect_width(&state->dst); > + int dst_h = drm_rect_height(&state->dst); > + int src_w, src_h, temp; > + > + scale->enable = false; > + > + if (roi->enable) { > + src_w = roi->width; > + src_h = roi->height; > + } else { > + src_w = drm_rect_width(&state->src) >> 16; > + src_h = drm_rect_height(&state->src) >> 16; > + } > + > + if (drm_rotation_90_or_270(state->rotation)) { > + temp = src_w; > + src_w = src_h; > + src_h = temp; > + } > + > + if (src_w != dst_w) { > + scale->scale_factor_x = calc_factor(src_w, dst_w); > + scale->enable = true; > + } else { > + scale->scale_factor_x = 1 << 16; > + } > + if (src_h != dst_h) { > + scale->scale_factor_y = calc_factor(src_h, dst_h); > + scale->enable = true; > + } else { > + scale->scale_factor_y = 1 << 16; > + } > +} > + > +static void update_fb(struct vs_plane *plane, u8 display_id, > + struct dc_hw_fb *fb, struct drm_plane_state *state) > +{ > + struct vs_plane_state *plane_state = to_vs_plane_state(state); > + struct drm_framebuffer *drm_fb = state->fb; > + struct drm_rect *src = &state->src; > + > + fb->display_id = display_id; > + fb->y_address = plane_state->dma_addr[0]; > + fb->y_stride = drm_fb->pitches[0]; > + if (drm_fb->format->format == DRM_FORMAT_YVU420) { > + fb->u_address = plane_state->dma_addr[2]; > + fb->v_address = plane_state->dma_addr[1]; > + fb->u_stride = drm_fb->pitches[2]; > + fb->v_stride = drm_fb->pitches[1]; > + } else { > + fb->u_address = plane_state->dma_addr[1]; > + fb->v_address = plane_state->dma_addr[2]; > + fb->u_stride = drm_fb->pitches[1]; > + fb->v_stride = drm_fb->pitches[2]; > + } > + fb->width = drm_rect_width(src) >> 16; > + fb->height = drm_rect_height(src) >> 16; > + fb->tile_mode = to_vs_tile_mode(drm_fb->modifier); > + fb->rotation = to_vs_rotation(state->rotation); > + fb->yuv_color_space = to_vs_yuv_color_space(state->color_encoding); > + fb->zpos = state->zpos; > + fb->enable = state->visible; > + update_format(drm_fb->format->format, drm_fb->modifier, fb); > + update_swizzle(drm_fb->format->format, fb); > + update_watermark(plane_state->watermark, fb); > + plane_state->status.tile_mode = fb->tile_mode; > +} > + > +static void update_degamma(struct vs_dc *dc, struct vs_plane *plane, > + struct vs_plane_state *plane_state) > +{ > + dc_hw_update_degamma(&dc->hw, plane->id, plane_state->degamma); > + plane_state->degamma_changed = false; > +} > + > +static void update_roi(struct vs_dc *dc, u8 id, > + struct vs_plane_state *plane_state, > + struct dc_hw_roi *roi, > + struct drm_plane_state *state) > +{ > + struct drm_vs_roi *data; > + struct drm_rect *src = &state->src; > + u16 src_w = drm_rect_width(src) >> 16; > + u16 src_h = drm_rect_height(src) >> 16; > + > + if (plane_state->roi) { > + data = plane_state->roi->data; > + > + if (data->enable) { > + roi->x = data->roi_x; > + roi->y = data->roi_y; > + roi->width = (data->roi_x + data->roi_w > src_w) ? > + (src_w - data->roi_x) : data->roi_w; > + roi->height = (data->roi_y + data->roi_h > src_h) ? > + (src_h - data->roi_y) : data->roi_h; > + roi->enable = true; > + } else { > + roi->enable = false; > + } > + > + dc_hw_update_roi(&dc->hw, id, roi); > + } else { > + roi->enable = false; > + } > +} > + > +static void update_color_mgmt(struct vs_dc *dc, u8 id, > + struct dc_hw_fb *fb, > + struct vs_plane_state *plane_state) > +{ > + struct drm_vs_color_mgmt *data; > + struct dc_hw_colorkey colorkey; > + > + if (plane_state->color_mgmt) { > + data = plane_state->color_mgmt->data; > + > + fb->clear_enable = data->clear_enable; > + fb->clear_value = data->clear_value; > + > + if (data->colorkey > data->colorkey_high) > + data->colorkey = data->colorkey_high; > + > + colorkey.colorkey = data->colorkey; > + colorkey.colorkey_high = data->colorkey_high; > + colorkey.transparency = (data->transparency) ? > + DC_TRANSPARENCY_KEY : DC_TRANSPARENCY_OPAQUE; > + dc_hw_update_colorkey(&dc->hw, id, &colorkey); > + } > +} > + > +static void update_plane(struct vs_dc *dc, struct vs_plane *plane, > + struct drm_plane *drm_plane, > + struct drm_atomic_state *drm_state) > +{ > + struct dc_hw_fb fb = {0}; > + struct dc_hw_scale scale; > + struct dc_hw_position pos; > + struct dc_hw_blend blend; > + struct dc_hw_roi roi; > + struct drm_plane_state *state = drm_atomic_get_new_plane_state(drm_state, > + drm_plane); > + struct vs_plane_state *plane_state = to_vs_plane_state(state); > + struct drm_rect *dest = &state->dst; > + bool dec_enable = false; > + u8 display_id = 0; > + > + display_id = to_vs_display_id(dc, state->crtc); > + update_fb(plane, display_id, &fb, state); > + fb.dec_enable = dec_enable; > + > + update_roi(dc, plane->id, plane_state, &roi, state); > + > + update_scale(state, &roi, &scale); > + > + if (plane_state->degamma_changed) > + update_degamma(dc, plane, plane_state); > + > + pos.start_x = dest->x1; > + pos.start_y = dest->y1; > + pos.end_x = dest->x2; > + pos.end_y = dest->y2; > + > + blend.alpha = (u8)(state->alpha >> 8); > + blend.blend_mode = (u8)(state->pixel_blend_mode); > + > + update_color_mgmt(dc, plane->id, &fb, plane_state); > + > + dc_hw_update_plane(&dc->hw, plane->id, &fb, &scale, &pos, &blend); > +} > + > +static void update_qos(struct vs_dc *dc, struct vs_plane *plane, > + struct drm_plane *drm_plane, > + struct drm_atomic_state *drm_state) > +{ > + struct drm_plane_state *state = drm_atomic_get_new_plane_state(drm_state, > + drm_plane); > + struct vs_plane_state *plane_state = to_vs_plane_state(state); > + struct drm_vs_watermark *data; > + struct dc_hw_qos qos; > + > + if (plane_state->watermark) { > + data = plane_state->watermark->data; > + > + if (data->qos_high) { > + if (data->qos_low > data->qos_high) > + data->qos_low = data->qos_high; > + > + qos.low_value = data->qos_low & 0x0F; > + qos.high_value = data->qos_high & 0x0F; > + dc_hw_update_qos(&dc->hw, &qos); > + } > + } > +} > + > +static void update_cursor_size(struct drm_plane_state *state, struct dc_hw_cursor *cursor) > +{ > + u8 size_type; > + > + switch (state->crtc_w) { > + case 32: > + size_type = CURSOR_SIZE_32X32; > + break; > + case 64: > + size_type = CURSOR_SIZE_64X64; > + break; > + default: > + size_type = CURSOR_SIZE_32X32; > + break; > + } > + > + cursor->size = size_type; > +} > + > +static void update_cursor_plane(struct vs_dc *dc, struct vs_plane *plane, > + struct drm_plane *drm_plane, > + struct drm_atomic_state *drm_state) > +{ > + struct drm_plane_state *state = drm_atomic_get_new_plane_state(drm_state, > + drm_plane); > + struct vs_plane_state *plane_state = to_vs_plane_state(state); > + struct drm_framebuffer *drm_fb = state->fb; > + struct dc_hw_cursor cursor; > + > + cursor.address = plane_state->dma_addr[0]; > + cursor.x = state->crtc_x; > + cursor.y = state->crtc_y; > + cursor.hot_x = drm_fb->hot_x; > + cursor.hot_y = drm_fb->hot_y; > + cursor.display_id = to_vs_display_id(dc, state->crtc); > + update_cursor_size(state, &cursor); > + cursor.enable = true; > + > + dc_hw_update_cursor(&dc->hw, cursor.display_id, &cursor); > +} > + > +void vs_dc_update_plane(struct vs_dc *dc, struct vs_plane *plane, > + struct drm_plane *drm_plane, > + struct drm_atomic_state *drm_state) > +{ > + update_plane(dc, plane, drm_plane, drm_state); > + update_qos(dc, plane, drm_plane, drm_state); > +} > + > +void vs_dc_update_cursor_plane(struct vs_dc *dc, struct vs_plane *plane, > + struct drm_plane *drm_plane, > + struct drm_atomic_state *drm_state) > +{ > + update_cursor_plane(dc, plane, drm_plane, drm_state); > +} > + > +void vs_dc_disable_plane(struct vs_dc *dc, struct vs_plane *plane, > + struct drm_plane_state *old_state) > +{ > + struct dc_hw_fb fb = {0}; > + > + fb.enable = false; > + dc_hw_update_plane(&dc->hw, plane->id, &fb, NULL, NULL, NULL); > +} > + > +void vs_dc_disable_cursor_plane(struct vs_dc *dc, struct vs_plane *plane, > + struct drm_plane_state *old_state) > +{ > + struct dc_hw_cursor cursor = {0}; > + > + cursor.enable = false; > + cursor.display_id = to_vs_display_id(dc, old_state->crtc); > + dc_hw_update_cursor(&dc->hw, cursor.display_id, &cursor); > +} > + > +static bool vs_dc_mod_supported(const struct vs_plane_info *plane_info, > + u64 modifier) > +{ > + const u64 *mods; > + > + if (!plane_info->modifiers) > + return false; > + > + for (mods = plane_info->modifiers; *mods != DRM_FORMAT_MOD_INVALID; mods++) { > + if (*mods == modifier) > + return true; > + } > + > + return false; > +} > + > +int vs_dc_check_plane(struct vs_dc *dc, struct drm_plane *plane, > + struct drm_atomic_state *state) > +{ > + struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, > + plane); > + > + struct drm_framebuffer *fb = new_plane_state->fb; > + const struct vs_plane_info *plane_info; > + struct drm_crtc *crtc = new_plane_state->crtc; > + struct drm_crtc_state *crtc_state; > + struct vs_plane *vs_plane = to_vs_plane(plane); > + > + plane_info = &dc->hw.info->planes[vs_plane->id]; > + > + if (fb->width < plane_info->min_width || > + fb->width > plane_info->max_width || > + fb->height < plane_info->min_height || > + fb->height > plane_info->max_height) > + drm_err_once(plane->dev, "buffer size may not support on plane%d.\n", > + vs_plane->id); > + > + if (!vs_dc_mod_supported(plane_info, fb->modifier)) { > + drm_err(plane->dev, "unsupported modifier on plane%d.\n", vs_plane->id); > + return -EINVAL; > + } > + > + crtc_state = drm_atomic_get_existing_crtc_state(state, crtc); > + return drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, > + plane_info->min_scale, > + plane_info->max_scale, > + true, true); > +} > + > +int vs_dc_check_cursor_plane(struct vs_dc *dc, struct drm_plane *plane, > + struct drm_atomic_state *state) > +{ > + struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, > + plane); > + struct drm_framebuffer *fb = new_plane_state->fb; > + const struct vs_plane_info *plane_info; > + struct drm_crtc *crtc = new_plane_state->crtc; > + struct drm_crtc_state *crtc_state; > + struct vs_plane *vs_plane = to_vs_plane(plane); > + > + plane_info = &dc->hw.info->planes[vs_plane->id]; > + > + if (fb->width < plane_info->min_width || > + fb->width > plane_info->max_width || > + fb->height < plane_info->min_height || > + fb->height > plane_info->max_height) > + drm_err_once(plane->dev, "buffer size may not support on plane%d.\n", vs_plane->id); > + > + crtc_state = drm_atomic_get_existing_crtc_state(state, crtc); > + if (IS_ERR(crtc_state)) > + return -EINVAL; > + > + return drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, > + plane_info->min_scale, > + plane_info->max_scale, > + true, true); > +} > + > +static void vs_crtc_handle_vblank(struct drm_crtc *crtc, bool underflow) > +{ > + struct vs_crtc_state *vs_crtc_state = to_vs_crtc_state(crtc->state); > + > + drm_crtc_handle_vblank(crtc); > + > + vs_crtc_state->underflow = underflow; > +} > + > +static irqreturn_t dc_isr(int irq, void *data) > +{ > + struct vs_dc *dc = data; > + struct vs_dc_info *dc_info = dc->hw.info; > + u32 i, ret; > + > + ret = dc_hw_get_interrupt(&dc->hw); > + > + for (i = 0; i < dc_info->panel_num; i++) > + vs_crtc_handle_vblank(&dc->crtc[i]->base, dc_hw_check_underflow(&dc->hw)); > + > + return IRQ_HANDLED; > +} > + > +void vs_dc_commit(struct vs_dc *dc) > +{ > + dc_hw_enable_shadow_register(&dc->hw, false); > + > + dc_hw_commit(&dc->hw); > + > + if (dc->first_frame) > + dc->first_frame = false; > + > + dc_hw_enable_shadow_register(&dc->hw, true); > +} > + > +static int dc_bind(struct device *dev, struct device *master, void *data) > +{ > + struct drm_device *drm_dev = data; > + struct vs_dc *dc = dev_get_drvdata(dev); > + struct device_node *port; > + struct vs_crtc *crtc; > + struct vs_dc_info *dc_info; > + struct vs_plane *plane; > + struct vs_plane_info *plane_info; > + int i, ret; > + u32 ctrc_mask = 0; > + > + if (!drm_dev || !dc) { > + dev_err(dev, "devices are not created.\n"); > + return -ENODEV; > + } > + > + ret = dc_init(dev); > + if (ret < 0) { > + drm_err(drm_dev, "Failed to initialize DC hardware.\n"); > + return ret; > + } > + > + port = of_get_child_by_name(dev->of_node, "port"); > + if (!port) { > + drm_err(drm_dev, "no port node found\n"); > + return -ENODEV; > + } > + of_node_put(port); > + > + dc_info = dc->hw.info; > + > + for (i = 0; i < dc_info->panel_num; i++) { > + crtc = vs_crtc_create(drm_dev, dc_info); > + if (!crtc) { > + drm_err(drm_dev, "Failed to create CRTC.\n"); > + ret = -ENOMEM; > + return ret; > + } > + > + crtc->base.port = port; > + crtc->dev = dev; > + dc->crtc[i] = crtc; > + ctrc_mask |= drm_crtc_mask(&crtc->base); > + } > + > + for (i = 0; i < dc_info->plane_num; i++) { > + plane_info = (struct vs_plane_info *)&dc_info->planes[i]; > + > + if (!strcmp(plane_info->name, "Primary") || !strcmp(plane_info->name, "Cursor")) { > + plane = vs_plane_create(drm_dev, plane_info, dc_info->layer_num, > + drm_crtc_mask(&dc->crtc[0]->base)); > + } else if (!strcmp(plane_info->name, "Primary_1") || > + !strcmp(plane_info->name, "Cursor_1")) { > + plane = vs_plane_create(drm_dev, plane_info, dc_info->layer_num, > + drm_crtc_mask(&dc->crtc[1]->base));
Do you somehow verify that dc->crtc[0] and dc->crtc[1] are not NULL here?
> + } else { > + plane = vs_plane_create(drm_dev, plane_info, > + dc_info->layer_num, ctrc_mask); > + }
In addition to Maxime's comment, I think it would be easier to read if you only set the plane's crtc make in these if-else branches and then call vs_plane_create() with the result. Like this
plane_crtc_mask = crtc_mask;
if (primary || cursor) plane_crtc_mask = drm_crtc_mask(&dc->crtc[0]->base) else if (primary_1 || cursor_1) plane_crtc_mask = drm_crtc_mask(&dc->crtc[1]->base)
vs_plane_create(..., plane_crtc_mask)
> + > + if (IS_ERR(plane)) { > + dev_err(dev, "failed to construct plane\n"); > + return PTR_ERR(plane); > + } > + > + plane->id = i; > + dc->planes[i].id = plane_info->id; > + > + if (plane_info->type == DRM_PLANE_TYPE_PRIMARY) { > + if (!strcmp(plane_info->name, "Primary")) > + dc->crtc[0]->base.primary = &plane->base; > + else > + dc->crtc[1]->base.primary = &plane->base; > + drm_dev->mode_config.min_width = plane_info->min_width; > + drm_dev->mode_config.min_height = > + plane_info->min_height; > + drm_dev->mode_config.max_width = plane_info->max_width; > + drm_dev->mode_config.max_height = > + plane_info->max_height; > + }
If you have multiple primary planes, the later planes overwrite the settings from the earlier ones. Is that intentional?
> + > + if (plane_info->type == DRM_PLANE_TYPE_CURSOR) { > + if (!strcmp(plane_info->name, "Cursor")) > + dc->crtc[0]->base.cursor = &plane->base; > + else > + dc->crtc[1]->base.cursor = &plane->base; > + drm_dev->mode_config.cursor_width = > + plane_info->max_width; > + drm_dev->mode_config.cursor_height = > + plane_info->max_height; > + }
Same question about overwriting as for the primary planes?
> + } > + > + vs_drm_update_pitch_alignment(drm_dev, dc_info->pitch_alignment); > + return 0; > +} > + > +static void dc_unbind(struct device *dev, struct device *master, void *data) > +{ > + dc_deinit(dev); > +} > + > +const struct component_ops dc_component_ops = { > + .bind = dc_bind, > + .unbind = dc_unbind, > +}; > + > +static const struct of_device_id dc_driver_dt_match[] = { > + { .compatible = "starfive,jh7110-dc8200", }, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, dc_driver_dt_match); > + > +static int dc_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct vs_dc *dc; > + int irq, ret, i; > + > + dc = devm_kzalloc(dev, sizeof(*dc), GFP_KERNEL); > + if (!dc) > + return -ENOMEM; > + > + dc->hw.hi_base = devm_platform_ioremap_resource(pdev, 0); > + if (IS_ERR(dc->hw.hi_base)) > + return PTR_ERR(dc->hw.hi_base); > + > + dc->hw.reg_base = devm_platform_ioremap_resource(pdev, 1); > + if (IS_ERR(dc->hw.reg_base)) > + return PTR_ERR(dc->hw.reg_base); > + > + dc->nclks = ARRAY_SIZE(dc->clk_vout); > + for (i = 0; i < dc->nclks; ++i) > + dc->clk_vout[i].id = vout_clocks[i]; > + ret = devm_clk_bulk_get(dev, dc->nclks, dc->clk_vout); > + if (ret) { > + dev_err(dev, "Failed to get clk controls\n"); > + return ret; > + } > + > + dc->nrsts = ARRAY_SIZE(dc->rst_vout); > + for (i = 0; i < dc->nrsts; ++i) > + dc->rst_vout[i].id = vout_resets[i]; > + ret = devm_reset_control_bulk_get_shared(dev, dc->nrsts, > + dc->rst_vout); > + if (ret) { > + dev_err(dev, "Failed to get reset controls\n"); > + return ret; > + } > + > + irq = platform_get_irq(pdev, 0); > + > + ret = devm_request_irq(dev, irq, dc_isr, 0, dev_name(dev), dc); > + if (ret < 0) { > + dev_err(dev, "Failed to install irq:%u.\n", irq); > + return ret; > + } > + > + dev_set_drvdata(dev, dc); > + > + return component_add(dev, &dc_component_ops); > +} > + > +static int dc_remove(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + > + component_del(dev, &dc_component_ops); > + > + dev_set_drvdata(dev, NULL); > + > + return 0; > +} > + > +struct platform_driver dc_platform_driver = { > + .probe = dc_probe, > + .remove = dc_remove, > + .driver = { > + .name = "vs-dc", > + .of_match_table = of_match_ptr(dc_driver_dt_match), > + }, > +}; > + > +MODULE_AUTHOR("StarFive Corporation"); > +MODULE_DESCRIPTION("VeriSilicon DC Driver"); > +MODULE_LICENSE("GPL"); > diff --git a/drivers/gpu/drm/verisilicon/vs_dc.h b/drivers/gpu/drm/verisilicon/vs_dc.h > new file mode 100644 > index 000000000..8e96fd32c > --- /dev/null > +++ b/drivers/gpu/drm/verisilicon/vs_dc.h > @@ -0,0 +1,80 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2023 VeriSilicon Holdings Co., Ltd. > + */ > + > +#ifndef __VS_DC_H__ > +#define __VS_DC_H__ > + > +#include <linux/clk.h> > +#include <linux/mm_types.h> > +#include <linux/reset.h> > + > +#include <drm/drm_fourcc.h> > +#include <drm/drm_modes.h> > + > +#include "vs_crtc.h" > +#include "vs_dc_hw.h" > +#include "vs_plane.h" > + > +struct vs_dc_plane { > + enum dc_hw_plane_id id; > +}; > + > +enum vout_clk { > + CLK_VOUT_NOC_DISP = 0, > + CLK_VOUT_PIX0, > + CLK_VOUT_PIX1, > + CLK_VOUT_CORE, > + CLK_VOUT_AXI, > + CLK_VOUT_AHB, > + CLK_VOUT_HDMI_PIX, > + CLK_VOUT_SOC_PIX, > + CLK_VOUT_NUM > +}; > + > +enum rst_vout { > + RST_VOUT_AXI = 0, > + RST_VOUT_AHB, > + RST_VOUT_CORE, > + RST_VOUT_NUM > +}; > + > +struct vs_dc { > + struct vs_crtc *crtc[DC_DISPLAY_NUM]; > + struct dc_hw hw; > + bool first_frame; > + > + struct vs_dc_plane planes[PLANE_NUM]; > + struct clk_bulk_data clk_vout[CLK_VOUT_NUM]; > + int nclks; > + struct reset_control_bulk_data rst_vout[RST_VOUT_NUM]; > + int nrsts; > +}; > + > +void vs_dc_enable(struct vs_dc *dc, struct drm_crtc *crtc); > +void vs_dc_disable(struct vs_dc *dc, struct drm_crtc *crtc); > + > +void vs_dc_set_gamma(struct vs_dc *dc, struct drm_crtc *crtc, > + struct drm_color_lut *lut, unsigned int size); > +void vs_dc_enable_gamma(struct vs_dc *dc, struct drm_crtc *crtc, bool enable); > +void vs_dc_enable_vblank(struct vs_dc *dc, bool enable); > +void vs_dc_commit(struct vs_dc *dc); > +void vs_dc_update_plane(struct vs_dc *dc, struct vs_plane *plane, > + struct drm_plane *drm_plane, > + struct drm_atomic_state *drm_state); > +void vs_dc_disable_plane(struct vs_dc *dc, struct vs_plane *plane, > + struct drm_plane_state *old_state); > +int vs_dc_check_plane(struct vs_dc *dc, struct drm_plane *plane, > + struct drm_atomic_state *state); > +void vs_dc_update_cursor_plane(struct vs_dc *dc, struct vs_plane *plane, > + struct drm_plane *drm_plane, > + struct drm_atomic_state *drm_state); > +void vs_dc_disable_cursor_plane(struct vs_dc *dc, struct vs_plane *plane, > + struct drm_plane_state *old_state); > +int vs_dc_check_cursor_plane(struct vs_dc *dc, struct drm_plane *plane, > + struct drm_atomic_state *state); > + > +extern struct platform_driver dc_platform_driver; > + > +#endif /* __VS_DC_H__ */ > diff --git a/drivers/gpu/drm/verisilicon/vs_dc_hw.c b/drivers/gpu/drm/verisilicon/vs_dc_hw.c > new file mode 100644 > index 000000000..e5acb7eb4 > --- /dev/null > +++ b/drivers/gpu/drm/verisilicon/vs_dc_hw.c > @@ -0,0 +1,1959 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2023 VeriSilicon Holdings Co., Ltd. > + */ > + > +#include <linux/bits.h> > +#include <linux/io.h> > +#include <linux/media-bus-format.h> > +#include <drm/drm_atomic_helper.h> > +#include <drm/drm_blend.h> > +#include <drm/drm_fourcc.h> > +#include <drm/vs_drm.h> > + > +#include "vs_dc_hw.h" > +#include "vs_type.h" > + > +static const u32 horkernel[] = { > + 0x00000000, 0x20000000, 0x00002000, 0x00000000, > + 0x00000000, 0x00000000, 0x23fd1c03, 0x00000000, > + 0x00000000, 0x00000000, 0x181f0000, 0x000027e1, > + 0x00000000, 0x00000000, 0x00000000, 0x2b981468, > + 0x00000000, 0x00000000, 0x00000000, 0x10f00000, > + 0x00002f10, 0x00000000, 0x00000000, 0x00000000, > + 0x32390dc7, 0x00000000, 0x00000000, 0x00000000, > + 0x0af50000, 0x0000350b, 0x00000000, 0x00000000, > + 0x00000000, 0x3781087f, 0x00000000, 0x00000000, > + 0x00000000, 0x06660000, 0x0000399a, 0x00000000, > + 0x00000000, 0x00000000, 0x3b5904a7, 0x00000000, > + 0x00000000, 0x00000000, 0x033c0000, 0x00003cc4, > + 0x00000000, 0x00000000, 0x00000000, 0x3de1021f, > + 0x00000000, 0x00000000, 0x00000000, 0x01470000, > + 0x00003eb9, 0x00000000, 0x00000000, 0x00000000, > + 0x3f5300ad, 0x00000000, 0x00000000, 0x00000000, > + 0x00480000, 0x00003fb8, 0x00000000, 0x00000000, > + 0x00000000, 0x3fef0011, 0x00000000, 0x00000000, > + 0x00000000, 0x00000000, 0x00004000, 0x00000000, > + 0x00000000, 0x00000000, 0x20002000, 0x00000000, > + 0x00000000, 0x00000000, 0x1c030000, 0x000023fd, > + 0x00000000, 0x00000000, 0x00000000, 0x27e1181f, > + 0x00000000, 0x00000000, 0x00000000, 0x14680000, > + 0x00002b98, 0x00000000, 0x00000000, 0x00000000, > + 0x2f1010f0, 0x00000000, 0x00000000, 0x00000000, > + 0x0dc70000, 0x00003239, 0x00000000, 0x00000000, > + 0x00000000, 0x350b0af5, 0x00000000, 0x00000000, > + 0x00000000, 0x087f0000, 0x00003781, 0x00000000, > + 0x00000000, 0x00000000, 0x399a0666, 0x00000000, > + 0x00000000, 0x00000000, 0x04a70000, 0x00003b59, > + 0x00000000, 0x00000000, 0x00000000, 0x3cc4033c, > + 0x00000000, 0x00000000, 0x00000000, 0x021f0000, > +}; > + > +#define H_COEF_SIZE (sizeof(horkernel) / sizeof(u32)) Either drop this in favor of the regular ARRAY_SIZE() macro, or hardcode the size if it's a fixed hardware setting.
> + > +static const u32 verkernel[] = { > + 0x00000000, 0x20000000, 0x00002000, 0x00000000, > + 0x00000000, 0x00000000, 0x23fd1c03, 0x00000000, > + 0x00000000, 0x00000000, 0x181f0000, 0x000027e1, > + 0x00000000, 0x00000000, 0x00000000, 0x2b981468, > + 0x00000000, 0x00000000, 0x00000000, 0x10f00000, > + 0x00002f10, 0x00000000, 0x00000000, 0x00000000, > + 0x32390dc7, 0x00000000, 0x00000000, 0x00000000, > + 0x0af50000, 0x0000350b, 0x00000000, 0x00000000, > + 0x00000000, 0x3781087f, 0x00000000, 0x00000000, > + 0x00000000, 0x06660000, 0x0000399a, 0x00000000, > + 0x00000000, 0x00000000, 0x3b5904a7, 0x00000000, > + 0x00000000, 0x00000000, 0x033c0000, 0x00003cc4, > + 0x00000000, 0x00000000, 0x00000000, 0x3de1021f, > + 0x00000000, 0x00000000, 0x00000000, 0x01470000, > + 0x00003eb9, 0x00000000, 0x00000000, 0x00000000, > + 0x3f5300ad, 0x00000000, 0x00000000, 0x00000000, > + 0x00480000, 0x00003fb8, 0x00000000, 0x00000000, > + 0x00000000, 0x3fef0011, 0x00000000, 0x00000000, > + 0x00000000, 0x00000000, 0x00004000, 0x00000000, > + 0xcdcd0000, 0xfdfdfdfd, 0xabababab, 0xabababab, > + 0x00000000, 0x00000000, 0x5ff5f456, 0x000f5f58, > + 0x02cc6c78, 0x02cc0c28, 0xfeeefeee, 0xfeeefeee, > + 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, > + 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, > + 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, > + 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, > + 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, > + 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, > + 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, > + 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, > + 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, > + 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee, > +}; > + > +#define V_COEF_SIZE (sizeof(verkernel) / sizeof(u32))
Same as H_COEF_SIZE; > + > +/* > + * RGB 709->2020 conversion parameters > + */ > +static u16 RGB2RGB[RGB_TO_RGB_TABLE_SIZE] = {
'static const' here and for the arrays below.
> + 10279, 5395, 709, > + 1132, 15065, 187, > + 269, 1442, 14674 > +}; > + > +/* > + * YUV601 to RGB conversion parameters > + * YUV2RGB[0] - [8] : C0 - C8; > + * YUV2RGB[9] - [11]: D0 - D2; > + * YUV2RGB[12] - [13]: Y clamp min & max calue; > + * YUV2RGB[14] - [15]: UV clamp min & max calue; > + */ > +static s32 YUV601_2RGB[YUV_TO_RGB_TABLE_SIZE] = { > + 1196, 0, 1640, 1196, > + -404, -836, 1196, 2076, > + 0, -916224, 558336, -1202944, > + 64, 940, 64, 960
Might be my email reader, but indention looks off here.
> +}; > + > +/* > + * YUV709 to RGB conversion parameters > + * YUV2RGB[0] - [8] : C0 - C8; > + * YUV2RGB[9] - [11]: D0 - D2; > + * YUV2RGB[12] - [13]: Y clamp min & max calue; > + * YUV2RGB[14] - [15]: UV clamp min & max calue; > + */ > +static s32 YUV709_2RGB[YUV_TO_RGB_TABLE_SIZE] = { > + 1196, 0, 1844, 1196, > + -220, -548, 1196, 2172, > + 0, -1020672, 316672, -1188608, > + 64, 940, 64, 960
Indention?
> +}; > + > +/* > + * YUV2020 to RGB conversion parameters > + * YUV2RGB[0] - [8] : C0 - C8; > + * YUV2RGB[9] - [11]: D0 - D2; > + * YUV2RGB[12] - [13]: Y clamp min & max calue; > + * YUV2RGB[14] - [15]: UV clamp min & max calue; > + */ > +static s32 YUV2020_2RGB[YUV_TO_RGB_TABLE_SIZE] = { > + 1196, 0, 1724, 1196, > + -192, -668, 1196, 2200, > + 0, -959232, 363776, -1202944, > + 64, 940, 64, 960
Indention.
> +}; > + > +/* > + * RGB to YUV2020 conversion parameters > + * RGB2YUV[0] - [8] : C0 - C8; > + * RGB2YUV[9] - [11]: D0 - D2; > + */ > +static s16 RGB2YUV[RGB_TO_YUV_TABLE_SIZE] = { > + 230, 594, 52, > + -125, -323, 448, > + 448, -412, -36, > + 64, 512, 512 > +}; > + > +/* > + * Degamma table for 709 color space data. > + */ > +static u16 DEGAMMA_709[DEGAMMA_SIZE] = { > + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0005, > + 0x0007, 0x000a, 0x000d, 0x0011, 0x0015, 0x0019, 0x001e, 0x0024, > + 0x002a, 0x0030, 0x0038, 0x003f, 0x0048, 0x0051, 0x005a, 0x0064, > + 0x006f, 0x007b, 0x0087, 0x0094, 0x00a1, 0x00af, 0x00be, 0x00ce, > + 0x00de, 0x00ef, 0x0101, 0x0114, 0x0127, 0x013b, 0x0150, 0x0166, > + 0x017c, 0x0193, 0x01ac, 0x01c4, 0x01de, 0x01f9, 0x0214, 0x0230, > + 0x024d, 0x026b, 0x028a, 0x02aa, 0x02ca, 0x02ec, 0x030e, 0x0331, > + 0x0355, 0x037a, 0x03a0, 0x03c7, 0x03ef, 0x0418, 0x0441, 0x046c, > + 0x0498, 0x04c4, 0x04f2, 0x0520, 0x0550, 0x0581, 0x05b2, 0x05e5, > + 0x0618, 0x064d, 0x0682, 0x06b9, 0x06f0, 0x0729, 0x0763, 0x079d, > + 0x07d9, 0x0816, 0x0854, 0x0893, 0x08d3, 0x0914, 0x0956, 0x0999, > + 0x09dd, 0x0a23, 0x0a69, 0x0ab1, 0x0afa, 0x0b44, 0x0b8f, 0x0bdb, > + 0x0c28, 0x0c76, 0x0cc6, 0x0d17, 0x0d69, 0x0dbb, 0x0e10, 0x0e65, > + 0x0ebb, 0x0f13, 0x0f6c, 0x0fc6, 0x1021, 0x107d, 0x10db, 0x113a, > + 0x119a, 0x11fb, 0x125d, 0x12c1, 0x1325, 0x138c, 0x13f3, 0x145b, > + 0x14c5, 0x1530, 0x159c, 0x160a, 0x1678, 0x16e8, 0x175a, 0x17cc, > + 0x1840, 0x18b5, 0x192b, 0x19a3, 0x1a1c, 0x1a96, 0x1b11, 0x1b8e, > + 0x1c0c, 0x1c8c, 0x1d0c, 0x1d8e, 0x1e12, 0x1e96, 0x1f1c, 0x1fa3, > + 0x202c, 0x20b6, 0x2141, 0x21ce, 0x225c, 0x22eb, 0x237c, 0x240e, > + 0x24a1, 0x2536, 0x25cc, 0x2664, 0x26fc, 0x2797, 0x2832, 0x28cf, > + 0x296e, 0x2a0e, 0x2aaf, 0x2b51, 0x2bf5, 0x2c9b, 0x2d41, 0x2dea, > + 0x2e93, 0x2f3e, 0x2feb, 0x3099, 0x3148, 0x31f9, 0x32ab, 0x335f, > + 0x3414, 0x34ca, 0x3582, 0x363c, 0x36f7, 0x37b3, 0x3871, 0x3930, > + 0x39f1, 0x3ab3, 0x3b77, 0x3c3c, 0x3d02, 0x3dcb, 0x3e94, 0x3f5f, > + 0x402c, 0x40fa, 0x41ca, 0x429b, 0x436d, 0x4442, 0x4517, 0x45ee, > + 0x46c7, 0x47a1, 0x487d, 0x495a, 0x4a39, 0x4b19, 0x4bfb, 0x4cde, > + 0x4dc3, 0x4eaa, 0x4f92, 0x507c, 0x5167, 0x5253, 0x5342, 0x5431, > + 0x5523, 0x5616, 0x570a, 0x5800, 0x58f8, 0x59f1, 0x5aec, 0x5be9, > + 0x5ce7, 0x5de6, 0x5ee7, 0x5fea, 0x60ef, 0x61f5, 0x62fc, 0x6406, > + 0x6510, 0x661d, 0x672b, 0x683b, 0x694c, 0x6a5f, 0x6b73, 0x6c8a, > + 0x6da2, 0x6ebb, 0x6fd6, 0x70f3, 0x7211, 0x7331, 0x7453, 0x7576, > + 0x769b, 0x77c2, 0x78ea, 0x7a14, 0x7b40, 0x7c6d, 0x7d9c, 0x7ecd, > + 0x3f65, 0x3f8c, 0x3fb2, 0x3fd8 > +}; > + > +/* > + * Degamma table for 2020 color space data. > + */ > +static u16 DEGAMMA_2020[DEGAMMA_SIZE] = { > + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, > + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, > + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, > + 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, > + 0x0001, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0003, 0x0003, > + 0x0003, 0x0003, 0x0004, 0x0004, 0x0004, 0x0005, 0x0005, 0x0006, > + 0x0006, 0x0006, 0x0007, 0x0007, 0x0008, 0x0008, 0x0009, 0x000a, > + 0x000a, 0x000b, 0x000c, 0x000c, 0x000d, 0x000e, 0x000f, 0x000f, > + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0016, 0x0017, 0x0018, > + 0x0019, 0x001b, 0x001c, 0x001e, 0x001f, 0x0021, 0x0022, 0x0024, > + 0x0026, 0x0028, 0x002a, 0x002c, 0x002e, 0x0030, 0x0033, 0x0035, > + 0x0038, 0x003a, 0x003d, 0x0040, 0x0043, 0x0046, 0x0049, 0x004d, > + 0x0050, 0x0054, 0x0057, 0x005b, 0x005f, 0x0064, 0x0068, 0x006d, > + 0x0071, 0x0076, 0x007c, 0x0081, 0x0086, 0x008c, 0x0092, 0x0098, > + 0x009f, 0x00a5, 0x00ac, 0x00b4, 0x00bb, 0x00c3, 0x00cb, 0x00d3, > + 0x00dc, 0x00e5, 0x00ee, 0x00f8, 0x0102, 0x010c, 0x0117, 0x0123, > + 0x012e, 0x013a, 0x0147, 0x0154, 0x0161, 0x016f, 0x017e, 0x018d, > + 0x019c, 0x01ac, 0x01bd, 0x01ce, 0x01e0, 0x01f3, 0x0206, 0x021a, > + 0x022f, 0x0244, 0x025a, 0x0272, 0x0289, 0x02a2, 0x02bc, 0x02d6, > + 0x02f2, 0x030f, 0x032c, 0x034b, 0x036b, 0x038b, 0x03ae, 0x03d1, > + 0x03f5, 0x041b, 0x0443, 0x046b, 0x0495, 0x04c1, 0x04ee, 0x051d, > + 0x054e, 0x0580, 0x05b4, 0x05ea, 0x0622, 0x065c, 0x0698, 0x06d6, > + 0x0717, 0x075a, 0x079f, 0x07e7, 0x0831, 0x087e, 0x08cd, 0x0920, > + 0x0976, 0x09ce, 0x0a2a, 0x0a89, 0x0aec, 0x0b52, 0x0bbc, 0x0c2a, > + 0x0c9b, 0x0d11, 0x0d8b, 0x0e0a, 0x0e8d, 0x0f15, 0x0fa1, 0x1033, > + 0x10ca, 0x1167, 0x120a, 0x12b2, 0x1360, 0x1415, 0x14d1, 0x1593, > + 0x165d, 0x172e, 0x1806, 0x18e7, 0x19d0, 0x1ac1, 0x1bbb, 0x1cbf, > + 0x1dcc, 0x1ee3, 0x2005, 0x2131, 0x2268, 0x23ab, 0x24fa, 0x2656, > + 0x27be, 0x2934, 0x2ab8, 0x2c4a, 0x2dec, 0x2f9d, 0x315f, 0x3332, > + 0x3516, 0x370d, 0x3916, 0x3b34, 0x3d66, 0x3fad, 0x420b, 0x4480, > + 0x470d, 0x49b3, 0x4c73, 0x4f4e, 0x5246, 0x555a, 0x588e, 0x5be1, > + 0x5f55, 0x62eb, 0x66a6, 0x6a86, 0x6e8c, 0x72bb, 0x7714, 0x7b99, > + 0x3dcb, 0x3e60, 0x3ef5, 0x3f8c > +}; > + > +/* one is for primary plane and the other is for all overlay planes */ > +static const struct dc_hw_plane_reg dc_plane_reg[] = { > + { > + .y_address = DC_FRAMEBUFFER_ADDRESS, > + .u_address = DC_FRAMEBUFFER_U_ADDRESS, > + .v_address = DC_FRAMEBUFFER_V_ADDRESS, > + .y_stride = DC_FRAMEBUFFER_STRIDE, > + .u_stride = DC_FRAMEBUFFER_U_STRIDE, > + .v_stride = DC_FRAMEBUFFER_V_STRIDE, > + .size = DC_FRAMEBUFFER_SIZE, > + .top_left = DC_FRAMEBUFFER_TOP_LEFT, > + .bottom_right = DC_FRAMEBUFFER_BOTTOM_RIGHT, > + .scale_factor_x = DC_FRAMEBUFFER_SCALE_FACTOR_X, > + .scale_factor_y = DC_FRAMEBUFFER_SCALE_FACTOR_Y, > + .h_filter_coef_index = DC_FRAMEBUFFER_H_FILTER_COEF_INDEX, > + .h_filter_coef_data = DC_FRAMEBUFFER_H_FILTER_COEF_DATA, > + .v_filter_coef_index = DC_FRAMEBUFFER_V_FILTER_COEF_INDEX, > + .v_filter_coef_data = DC_FRAMEBUFFER_V_FILTER_COEF_DATA, > + .init_offset = DC_FRAMEBUFFER_INIT_OFFSET, > + .color_key = DC_FRAMEBUFFER_COLOR_KEY, > + .color_key_high = DC_FRAMEBUFFER_COLOR_KEY_HIGH, > + .clear_value = DC_FRAMEBUFFER_CLEAR_VALUE, > + .color_table_index = DC_FRAMEBUFFER_COLOR_TABLE_INDEX, > + .color_table_data = DC_FRAMEBUFFER_COLOR_TABLE_DATA, > + .scale_config = DC_FRAMEBUFFER_SCALE_CONFIG, > + .water_mark = DC_FRAMEBUFFER_WATER_MARK, > + .degamma_index = DC_FRAMEBUFFER_DEGAMMA_INDEX, > + .degamma_data = DC_FRAMEBUFFER_DEGAMMA_DATA, > + .degamma_ex_data = DC_FRAMEBUFFER_DEGAMMA_EX_DATA, > + .src_global_color = DC_FRAMEBUFFER_SRC_GLOBAL_COLOR, > + .dst_global_color = DC_FRAMEBUFFER_DST_GLOBAL_COLOR, > + .blend_config = DC_FRAMEBUFFER_BLEND_CONFIG, > + .roi_origin = DC_FRAMEBUFFER_ROI_ORIGIN, > + .roi_size = DC_FRAMEBUFFER_ROI_SIZE, > + .yuv_to_rgb_coef0 = DC_FRAMEBUFFER_YUVTORGB_COEF0, > + .yuv_to_rgb_coef1 = DC_FRAMEBUFFER_YUVTORGB_COEF1, > + .yuv_to_rgb_coef2 = DC_FRAMEBUFFER_YUVTORGB_COEF2, > + .yuv_to_rgb_coef3 = DC_FRAMEBUFFER_YUVTORGB_COEF3, > + .yuv_to_rgb_coef4 = DC_FRAMEBUFFER_YUVTORGB_COEF4, > + .yuv_to_rgb_coefd0 = DC_FRAMEBUFFER_YUVTORGB_COEFD0, > + .yuv_to_rgb_coefd1 = DC_FRAMEBUFFER_YUVTORGB_COEFD1, > + .yuv_to_rgb_coefd2 = DC_FRAMEBUFFER_YUVTORGB_COEFD2, > + .y_clamp_bound = DC_FRAMEBUFFER_Y_CLAMP_BOUND, > + .uv_clamp_bound = DC_FRAMEBUFFER_UV_CLAMP_BOUND, > + .rgb_to_rgb_coef0 = DC_FRAMEBUFFER_RGBTORGB_COEF0, > + .rgb_to_rgb_coef1 = DC_FRAMEBUFFER_RGBTORGB_COEF1, > + .rgb_to_rgb_coef2 = DC_FRAMEBUFFER_RGBTORGB_COEF2, > + .rgb_to_rgb_coef3 = DC_FRAMEBUFFER_RGBTORGB_COEF3, > + .rgb_to_rgb_coef4 = DC_FRAMEBUFFER_RGBTORGB_COEF4, > + }, > + { > + .y_address = DC_OVERLAY_ADDRESS, > + .u_address = DC_OVERLAY_U_ADDRESS, > + .v_address = DC_OVERLAY_V_ADDRESS, > + .y_stride = DC_OVERLAY_STRIDE, > + .u_stride = DC_OVERLAY_U_STRIDE, > + .v_stride = DC_OVERLAY_V_STRIDE, > + .size = DC_OVERLAY_SIZE, > + .top_left = DC_OVERLAY_TOP_LEFT, > + .bottom_right = DC_OVERLAY_BOTTOM_RIGHT, > + .scale_factor_x = DC_OVERLAY_SCALE_FACTOR_X, > + .scale_factor_y = DC_OVERLAY_SCALE_FACTOR_Y, > + .h_filter_coef_index = DC_OVERLAY_H_FILTER_COEF_INDEX, > + .h_filter_coef_data = DC_OVERLAY_H_FILTER_COEF_DATA, > + .v_filter_coef_index = DC_OVERLAY_V_FILTER_COEF_INDEX, > + .v_filter_coef_data = DC_OVERLAY_V_FILTER_COEF_DATA, > + .init_offset = DC_OVERLAY_INIT_OFFSET, > + .color_key = DC_OVERLAY_COLOR_KEY, > + .color_key_high = DC_OVERLAY_COLOR_KEY_HIGH, > + .clear_value = DC_OVERLAY_CLEAR_VALUE, > + .color_table_index = DC_OVERLAY_COLOR_TABLE_INDEX, > + .color_table_data = DC_OVERLAY_COLOR_TABLE_DATA, > + .scale_config = DC_OVERLAY_SCALE_CONFIG, > + .water_mark = DC_OVERLAY_WATER_MARK, > + .degamma_index = DC_OVERLAY_DEGAMMA_INDEX, > + .degamma_data = DC_OVERLAY_DEGAMMA_DATA, > + .degamma_ex_data = DC_OVERLAY_DEGAMMA_EX_DATA, > + .src_global_color = DC_OVERLAY_SRC_GLOBAL_COLOR, > + .dst_global_color = DC_OVERLAY_DST_GLOBAL_COLOR, > + .blend_config = DC_OVERLAY_BLEND_CONFIG, > + .roi_origin = DC_OVERLAY_ROI_ORIGIN, > + .roi_size = DC_OVERLAY_ROI_SIZE, > + .yuv_to_rgb_coef0 = DC_OVERLAY_YUVTORGB_COEF0, > + .yuv_to_rgb_coef1 = DC_OVERLAY_YUVTORGB_COEF1, > + .yuv_to_rgb_coef2 = DC_OVERLAY_YUVTORGB_COEF2, > + .yuv_to_rgb_coef3 = DC_OVERLAY_YUVTORGB_COEF3, > + .yuv_to_rgb_coef4 = DC_OVERLAY_YUVTORGB_COEF4, > + .yuv_to_rgb_coefd0 = DC_OVERLAY_YUVTORGB_COEFD0, > + .yuv_to_rgb_coefd1 = DC_OVERLAY_YUVTORGB_COEFD1, > + .yuv_to_rgb_coefd2 = DC_OVERLAY_YUVTORGB_COEFD2, > + .y_clamp_bound = DC_OVERLAY_Y_CLAMP_BOUND, > + .uv_clamp_bound = DC_OVERLAY_UV_CLAMP_BOUND, > + .rgb_to_rgb_coef0 = DC_OVERLAY_RGBTORGB_COEF0, > + .rgb_to_rgb_coef1 = DC_OVERLAY_RGBTORGB_COEF1, > + .rgb_to_rgb_coef2 = DC_OVERLAY_RGBTORGB_COEF2, > + .rgb_to_rgb_coef3 = DC_OVERLAY_RGBTORGB_COEF3, > + .rgb_to_rgb_coef4 = DC_OVERLAY_RGBTORGB_COEF4, > + }, > +}; > + > +static const u32 primary_overlay_format0[] = {
These format arrays are supposed to be roughly sorted by hardware preference. This gives user-space programs an idea of what the hardware wants. Are these 4444 and 1555 formats really preferable over their 8888 and 2101010 variants? > + DRM_FORMAT_XRGB4444, > + DRM_FORMAT_XBGR4444, > + DRM_FORMAT_RGBX4444, > + DRM_FORMAT_BGRX4444, > + DRM_FORMAT_ARGB4444, > + DRM_FORMAT_ABGR4444, > + DRM_FORMAT_RGBA4444, > + DRM_FORMAT_BGRA4444, > + DRM_FORMAT_XRGB1555, > + DRM_FORMAT_XBGR1555, > + DRM_FORMAT_RGBX5551, > + DRM_FORMAT_BGRX5551, > + DRM_FORMAT_ARGB1555, > + DRM_FORMAT_ABGR1555, > + DRM_FORMAT_RGBA5551, > + DRM_FORMAT_BGRA5551, > + DRM_FORMAT_RGB565, > + DRM_FORMAT_BGR565, > + DRM_FORMAT_XRGB8888, > + DRM_FORMAT_XBGR8888, > + DRM_FORMAT_RGBX8888, > + DRM_FORMAT_BGRX8888, > + DRM_FORMAT_ARGB8888, > + DRM_FORMAT_ABGR8888, > + DRM_FORMAT_RGBA8888, > + DRM_FORMAT_BGRA8888, > + DRM_FORMAT_ARGB2101010, > + DRM_FORMAT_ABGR2101010, > + DRM_FORMAT_RGBA1010102, > + DRM_FORMAT_BGRA1010102, > + DRM_FORMAT_YUYV, > + DRM_FORMAT_YVYU, > + DRM_FORMAT_UYVY, > + DRM_FORMAT_VYUY, > + DRM_FORMAT_YVU420, > + DRM_FORMAT_YUV420, > + DRM_FORMAT_NV12, > + DRM_FORMAT_NV21, > + DRM_FORMAT_NV16, > + DRM_FORMAT_NV61, > + DRM_FORMAT_P010, > +}; > + > +static const u32 primary_overlay_format1[] = { > + DRM_FORMAT_XRGB8888, > + DRM_FORMAT_XBGR8888, > + DRM_FORMAT_RGBX8888, > + DRM_FORMAT_BGRX8888, > + DRM_FORMAT_ARGB8888, > + DRM_FORMAT_ABGR8888, > + DRM_FORMAT_RGBA8888, > + DRM_FORMAT_BGRA8888, > + DRM_FORMAT_ARGB2101010, > + DRM_FORMAT_ABGR2101010, > + DRM_FORMAT_RGBA1010102, > + DRM_FORMAT_BGRA1010102, > + DRM_FORMAT_NV12, > + DRM_FORMAT_NV21, > + DRM_FORMAT_YUV444, > +}; > + > +static const u32 cursor_formats[] = { > + DRM_FORMAT_ARGB8888 > +}; > + > +static const u64 format_modifier0[] = { > + DRM_FORMAT_MOD_LINEAR, > + fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VERISILICON_SUPER_TILED_XMAJOR_8X8), > + fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VERISILICON_SUPER_TILED_YMAJOR_8X8), > + fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VERISILICON_TILE_8X8), > + fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VERISILICON_TILE_8X4), > + fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VERISILICON_SUPER_TILED_XMAJOR_8X4), > + fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VERISILICON_SUPER_TILED_YMAJOR_4X8), > + DRM_FORMAT_MOD_INVALID > +}; > + > +static const u64 secondary_format_modifiers[] = { > + DRM_FORMAT_MOD_LINEAR, > + DRM_FORMAT_MOD_INVALID > +}; > + > +#define FRAC_16_16(mult, div) (((mult) << 16) / (div)) > + > +static const struct vs_plane_info dc_hw_planes[][PLANE_NUM] = {
Please double-check the indention in this array.
Best regards Thomas
-- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg) [unhandled content-type:application/pgp-signature] | |