drm/msm: YUV suppport addition for MDP4 & MDP5
cover drm/msm: YUV suppport addition for MDP4 & MDP5
Hi,
So this set of patches adds YUV support for MDP4 and MDP5. This only concerns the public planes (using ViG pipes).
The fun part was to rebase things on top of atomic but things worked out fine. I was able to test this for MDP5 on a 8084 target. I cannot say the same for MDP4 for which I don't have a build based on atomic yet. The change is pretty similar to MDP5 though.
Rgds,
Stephane.
Beeresh Gopal (1):
drm/msm/mdp4: add YUV format support
Stephane Viau (3):
drm/msm/mdp: add register description for YUV support drm/msm/mdp: add common YUV information for MDP4/MDP5 drm/msm/mdp5: add NV12 support for MDP5
drivers/gpu/drm/msm/hdmi/hdmi.c | 149 ++++++++++++++------- drivers/gpu/drm/msm/hdmi/hdmi.h | 8 +- drivers/gpu/drm/msm/hdmi/hdmi_connector.c | 1 - drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h | 44 ++++++ drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | 19 ++- drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 104 +++++++++++++-- drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h | 153 +++++++++++++++++++-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 19 ++- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 215 +++++++++++++++++++++++++++--- drivers/gpu/drm/msm/mdp/mdp_common.xml.h | 30 +++-- drivers/gpu/drm/msm/mdp/mdp_format.c | 108 +++++++++++++-- drivers/gpu/drm/msm/mdp/mdp_kms.h | 24 +++- drivers/gpu/drm/msm/msm_fb.c | 4 +- drivers/gpu/drm/msm/msm_kms.h | 2 + 14 files changed, 754 insertions(+), 126 deletions(-)
Signature · 8 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 1/4 drm/msm/mdp: add register description for YUV support
YUV support addition implies that sub-modules of the ViG pipes need to be configured: Color Space Converter (CSC) and Scaler are the main components used to convert YUV to RGB data. Note that the output of a pipe has to be in RGB888 format since only this format is understood by the (layer) mixers.
Generated headers are kept in a separate change to ease the actual driver's code review.
--- drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h | 44 +++++++++ drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h | 153 +++++++++++++++++++++++++++++-- drivers/gpu/drm/msm/mdp/mdp_common.xml.h | 30 +++--- 3 files changed, 205 insertions(+), 22 deletions(-)
drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h +44 -0
@@ -72,6 +72,18 @@ enum mdp4_cursor_format { CURSOR_XRGB = 2, }; +enum mdp4_frame_format { +FRAME_LINEAR =0 , +FRAME_TILE_ARGB_4X4 =1 , +FRAME_TILE_YCBCR_420 =2 , +}; + +enum mdp4_scale_unit { +SCALE_FIR =0 , +SCALE_MN_PHASE =1 , +SCALE_PIXEL_RPT =2 , +}; +enum mdp4_dma {DMA_P =0 ,DMA_S =1 ,
@@ -637,6 +649,8 @@ static inline uint32_t REG_MDP4_PIPE_SRCP1_BASE(enum mdp4_pipe i0) { return 0x00static inline uint32_t REG_MDP4_PIPE_SRCP2_BASE (enum mdp4_pipe i0) {return 0x00020018 +0x10000 *i0; } +static inline uint32_t REG_MDP4_PIPE_SRCP3_BASE (enum mdp4_pipe i0) {return 0x0002001c +0x10000 *i0; } +static inline uint32_t REG_MDP4_PIPE_SRC_STRIDE_A (enum mdp4_pipe i0) {return 0x00020040 +0x10000 *i0; }#define MDP4_PIPE_SRC_STRIDE_A_P0__MASK 0x0000ffff#define MDP4_PIPE_SRC_STRIDE_A_P0__SHIFT 0
@@ -720,7 +734,25 @@ static inline uint32_t MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT(uint32_t val) }#define MDP4_PIPE_SRC_FORMAT_UNPACK_TIGHT 0x00020000#define MDP4_PIPE_SRC_FORMAT_UNPACK_ALIGN_MSB 0x00040000 +#define MDP4_PIPE_SRC_FORMAT_FETCH_PLANES__MASK 0x00180000 +#define MDP4_PIPE_SRC_FORMAT_FETCH_PLANES__SHIFT 19 +static inline uint32_t MDP4_PIPE_SRC_FORMAT_FETCH_PLANES (uint32_t val) +{ +return ((val) <<MDP4_PIPE_SRC_FORMAT_FETCH_PLANES__SHIFT ) &MDP4_PIPE_SRC_FORMAT_FETCH_PLANES__MASK ; +}#define MDP4_PIPE_SRC_FORMAT_SOLID_FILL 0x00400000 +#define MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP__MASK 0x0c000000 +#define MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP__SHIFT 26 +static inline uint32_t MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP (enum mdp_chroma_samp_type val) +{ +return ((val) <<MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP__SHIFT ) &MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP__MASK ; +} +#define MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT__MASK 0x60000000 +#define MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT__SHIFT 29 +static inline uint32_t MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT (enum mdp4_frame_format val) +{ +return ((val) <<MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT__SHIFT ) &MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT__MASK ; +}static inline uint32_t REG_MDP4_PIPE_SRC_UNPACK (enum mdp4_pipe i0) {return 0x00020054 +0x10000 *i0; }#define MDP4_PIPE_SRC_UNPACK_ELEM0__MASK 0x000000ff
@@ -751,6 +783,18 @@ static inline uint32_t MDP4_PIPE_SRC_UNPACK_ELEM3(uint32_t val)static inline uint32_t REG_MDP4_PIPE_OP_MODE (enum mdp4_pipe i0) {return 0x00020058 +0x10000 *i0; }#define MDP4_PIPE_OP_MODE_SCALEX_EN 0x00000001#define MDP4_PIPE_OP_MODE_SCALEY_EN 0x00000002 +#define MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL__MASK 0x0000000c +#define MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL__SHIFT 2 +static inline uint32_t MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL (enum mdp4_scale_unit val) +{ +return ((val) <<MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL__SHIFT ) &MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL__MASK ; +} +#define MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL__MASK 0x00000030 +#define MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL__SHIFT 4 +static inline uint32_t MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL (enum mdp4_scale_unit val) +{ +return ((val) <<MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL__SHIFT ) &MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL__MASK ; +}#define MDP4_PIPE_OP_MODE_SRC_YCBCR 0x00000200#define MDP4_PIPE_OP_MODE_DST_YCBCR 0x00000400#define MDP4_PIPE_OP_MODE_CSC_EN 0x00000800
drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h +143 -10
195 lines not on this page · raw message
drivers/gpu/drm/msm/mdp/mdp_common.xml.h +18 -12
@@ -8,18 +8,11 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 17996 bytes, from 2013-12-01 19:10:31) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2013-11-30 15:00:52) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-06-25 12:55:02) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-06-25 12:53:44) - -Copyright (C) 2013 by the following authors: +- /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2014-10-28 19:05:31) +- /local/mnt2/workspace2/sviau/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2014-06-02 18:31:15) +- /local/mnt2/workspace2/sviau/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-10-07 21:41:04) + +Copyright (C) 2013-2014 by the following authors: - Rob Clark <[email protected]> (robclark) Permission is hereby granted, free of charge, to any person obtaining
@@ -44,6 +37,19 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ +enum mdp_chroma_samp_type { +CHROMA_RGB =0 , +CHROMA_H2V1 =1 , +CHROMA_H1V2 =2 , +CHROMA_420 =3 , +}; + +enum mdp_sspp_fetch_type { +MDP_PLANE_INTERLEAVED =0 , +MDP_PLANE_PLANAR =1 , +MDP_PLANE_PSEUDO_PLANAR =2 , +}; +enum mdp_mixer_stage_id {STAGE_UNUSED =0 ,STAGE_BASE =1 ,
Signature · 8 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 2/4 drm/msm/mdp: add common YUV information for MDP4/MDP5
In reply to Stephane ViauBoth MDP4 and MDP5 share some code as far as YUV support is concerned. This change adds this information and will be followed by the actual MDP4 and MDP5 YUV support patches.
--- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | 19 ++++-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 19 ++++-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 2 - drivers/gpu/drm/msm/mdp/mdp_format.c | 108 +++++++++++++++++++++++++++--- drivers/gpu/drm/msm/mdp/mdp_kms.h | 24 ++++++- drivers/gpu/drm/msm/msm_fb.c | 2 +- drivers/gpu/drm/msm/msm_kms.h | 2 + 7 files changed, 154 insertions(+), 22 deletions(-)
drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h +15 -4
@@ -175,14 +175,25 @@ irqreturn_t mdp4_irq(struct msm_kms *kms);int mdp4_enable_vblank (struct msm_kms *kms,struct drm_crtc *crtc);void mdp4_disable_vblank (struct msm_kms *kms,struct drm_crtc *crtc); +static inline bool pipe_supports_yuv (enum mdp4_pipe pipe) +{ +switch (pipe) { +case VG1 : +case VG2 : +case VG3 : +case VG4 : +return true; +default : +return false; + } +} +static inline uint32_t mdp4_get_formats (enum mdp4_pipe pipe_id,uint32_t *pixel_formats,uint32_t max_formats) { -/* TODO when we have YUV, we need to filter supported formats -* based on pipe_id.. -*/ -return mdp_get_formats (pixel_formats, max_formats); +return mdp_get_formats (pixel_formats, max_formats, + !pipe_supports_yuv (pipe_id)); } void mdp4_plane_install_properties(struct drm_plane *plane,
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +15 -4
@@ -165,14 +165,25 @@ void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);int mdp5_irq_domain_init (struct mdp5_kms *mdp5_kms);void mdp5_irq_domain_fini (struct mdp5_kms *mdp5_kms); +static inline bool pipe_supports_yuv (enum mdp5_pipe pipe) +{ +switch (pipe) { +case SSPP_VIG0 : +case SSPP_VIG1 : +case SSPP_VIG2 : +case SSPP_VIG3 : +return true; +default : +return false; + } +} +static inline uint32_t mdp5_get_formats (enum mdp5_pipe pipe,uint32_t *pixel_formats,uint32_t max_formats) { -/* TODO when we have YUV, we need to filter supported formats -* based on pipe id.. -*/ -return mdp_get_formats (pixel_formats, max_formats); +return mdp_get_formats (pixel_formats, max_formats, + !pipe_supports_yuv (pipe)); } void mdp5_plane_install_properties(struct drm_plane *plane,
drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +0 -2
@@ -18,8 +18,6 @@#include "mdp5_kms.h" -#define MAX_PLANE 4 -struct mdp5_plane {struct drm_plane base;const char *name;
drivers/gpu/drm/msm/mdp/mdp_format.c +98 -10
139 lines not on this page · raw message
drivers/gpu/drm/msm/mdp/mdp_kms.h +23 -1
@@ -88,10 +88,32 @@ struct mdp_format {uint8_t unpack[4 ];bool alpha_enable, unpack_tight;uint8_t cpp, unpack_count; +enum mdp_sspp_fetch_type fetch_type; + enum mdp_chroma_samp_type chroma_sample; };#define to_mdp_format (x) container_of(x, struct mdp_format, base) +#define MDP_FORMAT_IS_YUV (mdp_format) ((mdp_format)->chroma_sample > CHROMA_RGB) -uint32_t mdp_get_formats (uint32_t *formats,uint32_t max_formats); +uint32_t mdp_get_formats (uint32_t *formats,uint32_t max_formats,bool rgb_only);const struct msm_format *mdp_get_format (struct msm_kms *kms,uint32_t format); +enum csc_type { +CSC_RGB2RGB =0 , +CSC_YUV2RGB , +CSC_RGB2YUV , +CSC_YUV2YUV , +CSC_MAX +}; + +struct csc_cfg { +enum csc_type type; +uint32_t matrix[9 ]; +uint32_t pre_bias[3 ]; +uint32_t post_bias[3 ]; +uint32_t pre_clamp[6 ]; +uint32_t post_clamp[6 ]; +}; + +struct csc_cfg *mdp_get_default_csc_cfg (enum csc_type ); +#endif /* __MDP_KMS_H__ */
drivers/gpu/drm/msm/msm_fb.c +1 -1
@@ -24,7 +24,7 @@struct msm_framebuffer {struct drm_framebuffer base;const struct msm_format *format; -struct drm_gem_object *planes[3 ]; +struct drm_gem_object *planes[MAX_PLANE ]; };#define to_msm_framebuffer (x) container_of(x, struct msm_framebuffer, base)
drivers/gpu/drm/msm/msm_kms.h +2 -0
@@ -23,6 +23,8 @@#include "msm_drv.h" +#define MAX_PLANE 4 +/* As there are different display controller blocks depending on the * snapdragon version, the kms support is split out and the appropriate * implementation is loaded at runtime. The kms module is responsible
Signature · 8 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 3/4 drm/msm/mdp5: add NV12 support for MDP5
In reply to Stephane ViauThis change adds the NV12 format support for public planes.
--- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 213 +++++++++++++++++++++++++++--- drivers/gpu/drm/msm/msm_fb.c | 2 +- 2 files changed, 194 insertions(+), 21 deletions(-)
drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +193 -20
@@ -274,6 +274,155 @@ static void set_scanout_locked(struct drm_plane *plane, plane->fb = fb; } +/* Note: mdp5_plane->pipe_lock must be locked */ +static void csc_disable (struct mdp5_kms *mdp5_kms,enum mdp5_pipe pipe) +{ +uint32_t value =mdp5_read (mdp5_kms,REG_MDP5_PIPE_OP_MODE (pipe)) & + ~MDP5_PIPE_OP_MODE_CSC_1_EN ; + +mdp5_write (mdp5_kms,REG_MDP5_PIPE_OP_MODE (pipe), value); +} + +/* Note: mdp5_plane->pipe_lock must be locked */ +static void csc_enable (struct mdp5_kms *mdp5_kms,enum mdp5_pipe pipe, +struct csc_cfg *csc) +{ +uint32_t i, mode =0 ;/* RGB, no CSC */ +uint32_t *matrix; + +if (unlikely (!csc)) +return ; + +if ((csc->type ==CSC_YUV2RGB ) || (CSC_YUV2YUV == csc->type)) + mode |=MDP5_PIPE_OP_MODE_CSC_SRC_DATA_FORMAT (DATA_FORMAT_YUV ); +if ((csc->type ==CSC_RGB2YUV ) || (CSC_YUV2YUV == csc->type)) + mode |=MDP5_PIPE_OP_MODE_CSC_DST_DATA_FORMAT (DATA_FORMAT_YUV ); + mode |=MDP5_PIPE_OP_MODE_CSC_1_EN ; +mdp5_write (mdp5_kms,REG_MDP5_PIPE_OP_MODE (pipe), mode); + + matrix = csc->matrix; +mdp5_write (mdp5_kms,REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_0 (pipe), +MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_11 (matrix[0 ]) | +MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_12 (matrix[1 ])); +mdp5_write (mdp5_kms,REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_1 (pipe), +MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_13 (matrix[2 ]) | +MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_21 (matrix[3 ])); +mdp5_write (mdp5_kms,REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_2 (pipe), +MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_22 (matrix[4 ]) | +MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_23 (matrix[5 ])); +mdp5_write (mdp5_kms,REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_3 (pipe), +MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_31 (matrix[6 ]) | +MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_32 (matrix[7 ])); +mdp5_write (mdp5_kms,REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_4 (pipe), +MDP5_PIPE_CSC_1_MATRIX_COEFF_4_COEFF_33 (matrix[8 ])); + +for (i =0 ; i <ARRAY_SIZE (csc->pre_bias); i++) { +uint32_t *pre_clamp = csc->pre_clamp; +uint32_t *post_clamp = csc->post_clamp; + +mdp5_write (mdp5_kms,REG_MDP5_PIPE_CSC_1_PRE_CLAMP (pipe, i), +MDP5_PIPE_CSC_1_PRE_CLAMP_REG_HIGH (pre_clamp[2 *i+1 ]) | +MDP5_PIPE_CSC_1_PRE_CLAMP_REG_LOW (pre_clamp[2 *i])); + +mdp5_write (mdp5_kms,REG_MDP5_PIPE_CSC_1_POST_CLAMP (pipe, i), +MDP5_PIPE_CSC_1_POST_CLAMP_REG_HIGH (post_clamp[2 *i+1 ]) | +MDP5_PIPE_CSC_1_POST_CLAMP_REG_LOW (post_clamp[2 *i])); + +mdp5_write (mdp5_kms,REG_MDP5_PIPE_CSC_1_PRE_BIAS (pipe, i), +MDP5_PIPE_CSC_1_PRE_BIAS_REG_VALUE (csc->pre_bias[i])); + +mdp5_write (mdp5_kms,REG_MDP5_PIPE_CSC_1_POST_BIAS (pipe, i), +MDP5_PIPE_CSC_1_POST_BIAS_REG_VALUE (csc->post_bias[i])); + } +} + +#define PHASE_STEP_SHIFT 21 +#define DOWN_SCALE_RATIO_MAX 32/* 2^(26-21) */ + +static int calc_phase_step (uint32_t src,uint32_t dst,uint32_t *out_phase) +{ +uint32_t unit; + +if (src ==0 || dst ==0 ) +return -EINVAL ; + +/* +* PHASE_STEP_X/Y is coded on 26 bits (25:0), +* where 2^21 represents the unity "1" in fixed-point hardware design. +* This leaves 5 bits for the integer part (downscale case): +* -> maximum downscale ratio = 0b1_1111 = 31 +*/ +if (src > (dst *DOWN_SCALE_RATIO_MAX )) +return -EOVERFLOW ; + + unit =1 <<PHASE_STEP_SHIFT ; + *out_phase =mult_frac (unit, src, dst); + +return 0 ; +} + +static int calc_scalex_steps (uint32_t pixel_format,uint32_t src,uint32_t dest, +uint32_t phasex_steps[2 ]) +{ +uint32_t phasex_step; +unsigned int hsub; +int ret; + + ret =calc_phase_step (src, dest, &phasex_step); +if (ret) +return ret; + + hsub =drm_format_horz_chroma_subsampling (pixel_format); + + phasex_steps[0 ] = phasex_step; + phasex_steps[1 ] = phasex_step / hsub; + +return 0 ; +} + +static int calc_scaley_steps (uint32_t pixel_format,uint32_t src,uint32_t dest, +uint32_t phasey_steps[2 ]) +{ +uint32_t phasey_step; +unsigned int vsub; +int ret; + + ret =calc_phase_step (src, dest, &phasey_step); +if (ret) +return ret; + + vsub =drm_format_vert_chroma_subsampling (pixel_format); + + phasey_steps[0 ] = phasey_step; + phasey_steps[1 ] = phasey_step / vsub; + +return 0 ; +} + +static uint32_t get_scalex_config (uint32_t src,uint32_t dest) +{ +uint32_t filter; + + filter = (src <= dest) ?SCALE_FILTER_BIL :SCALE_FILTER_PCMN ; + +return MDP5_PIPE_SCALE_CONFIG_SCALEX_EN | +MDP5_PIPE_SCALE_CONFIG_SCALEX_MIN_FILTER (filter) | +MDP5_PIPE_SCALE_CONFIG_SCALEX_CR_FILTER (filter) | +MDP5_PIPE_SCALE_CONFIG_SCALEX_MAX_FILTER (filter); +} + +static uint32_t get_scaley_config (uint32_t src,uint32_t dest) +{ +uint32_t filter; + + filter = (src <= dest) ?SCALE_FILTER_BIL :SCALE_FILTER_PCMN ; + +return MDP5_PIPE_SCALE_CONFIG_SCALEY_EN | +MDP5_PIPE_SCALE_CONFIG_SCALEY_MIN_FILTER (filter) | +MDP5_PIPE_SCALE_CONFIG_SCALEY_CR_FILTER (filter) | +MDP5_PIPE_SCALE_CONFIG_SCALEY_MAX_FILTER (filter); +} + static int mdp5_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, int crtc_x, int crtc_y,
@@ -283,11 +432,14 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, {struct mdp5_plane *mdp5_plane =to_mdp5_plane (plane);struct mdp5_kms *mdp5_kms =get_kms (plane); +struct device *dev = mdp5_kms->dev->dev;enum mdp5_pipe pipe = mdp5_plane->pipe;const struct mdp_format *format;uint32_t nplanes, config =0 ; -uint32_t phasex_step =0 , phasey_step =0 ; +/* below array -> index 0: comp 0/3 ; index 1: comp 1/2 */ +uint32_t phasex_step[2 ] = {0 ,}, phasey_step[2 ] = {0 ,};uint32_t hdecm =0 , vdecm =0 ; +uint32_t pix_format;unsigned long flags;int ret;
@@ -297,6 +449,9 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,if (WARN_ON (nplanes >pipe2nclients (pipe)))return -EINVAL ; + format =to_mdp_format (msm_framebuffer_format (fb)); + pix_format = format->base.pixel_format; +/* src values are in Q16 fixed point, convert to integer: */ src_x = src_x >>16 ; src_y = src_y >>16 ;
@@ -321,14 +476,28 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,*/ mdp5_smp_configure (mdp5_kms->smp, pipe); -if (src_w != crtc_w) { - config |=MDP5_PIPE_SCALE_CONFIG_SCALEX_EN ; -/* TODO calc phasex_step, hdecm */ +/* SCALE is used to both scale and up-sample chroma components */ + +if ((src_w != crtc_w) ||MDP_FORMAT_IS_YUV (format)) { +/* TODO calc hdecm */ + ret =calc_scalex_steps (pix_format, src_w, crtc_w, phasex_step); +if (ret) { +dev_err (dev,"X scaling (%d -> %d) failed: %d\n" , + src_w, crtc_w, ret); +return ret; + } + config |=get_scalex_config (src_w, crtc_w); } -if (src_h != crtc_h) { - config |=MDP5_PIPE_SCALE_CONFIG_SCALEY_EN ; -/* TODO calc phasey_step, vdecm */ +if ((src_h != crtc_h) ||MDP_FORMAT_IS_YUV (format)) { +/* TODO calc vdecm */ + ret =calc_scaley_steps (pix_format, src_h, crtc_h, phasey_step); +if (ret) { +dev_err (dev,"Y scaling (%d -> %d) failed: %d\n" , + src_h, crtc_h, ret); +return ret; + } + config |=get_scaley_config (src_h, crtc_h); }spin_lock_irqsave (&mdp5_plane->pipe_lock, flags);
@@ -353,8 +522,6 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,MDP5_PIPE_OUT_XY_X (crtc_x) | MDP5_PIPE_OUT_XY_Y(crtc_y)); - format =to_mdp_format (msm_framebuffer_format (fb)); - mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_FORMAT(pipe), MDP5_PIPE_SRC_FORMAT_A_BPC(format->bpc_a) | MDP5_PIPE_SRC_FORMAT_R_BPC(format->bpc_r) |
@@ -364,8 +531,8 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,MDP5_PIPE_SRC_FORMAT_CPP (format->cpp -1 ) |MDP5_PIPE_SRC_FORMAT_UNPACK_COUNT (format->unpack_count -1 ) |COND (format->unpack_tight,MDP5_PIPE_SRC_FORMAT_UNPACK_TIGHT ) | -MDP5_PIPE_SRC_FORMAT_NUM_PLANES (nplanes -1 ) | - MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP(CHROMA_RGB)); +MDP5_PIPE_SRC_FORMAT_NUM_PLANES (format->fetch_type) | + MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP(format->chroma_sample)); mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_UNPACK(pipe), MDP5_PIPE_SRC_UNPACK_ELEM0(format->unpack[0]) |
@@ -379,18 +546,24 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,/* not using secure mode: */ mdp5_write (mdp5_kms,REG_MDP5_PIPE_SRC_ADDR_SW_STATUS (pipe),0 ); -mdp5_write (mdp5_kms,REG_MDP5_PIPE_SCALE_PHASE_STEP_X (pipe), phasex_step); -mdp5_write (mdp5_kms,REG_MDP5_PIPE_SCALE_PHASE_STEP_Y (pipe), phasey_step); +mdp5_write (mdp5_kms,REG_MDP5_PIPE_SCALE_PHASE_STEP_X (pipe), + phasex_step[0 ]); +mdp5_write (mdp5_kms,REG_MDP5_PIPE_SCALE_PHASE_STEP_Y (pipe), + phasey_step[0 ]); +mdp5_write (mdp5_kms,REG_MDP5_PIPE_SCALE_CR_PHASE_STEP_X (pipe), + phasex_step[1 ]); +mdp5_write (mdp5_kms,REG_MDP5_PIPE_SCALE_CR_PHASE_STEP_Y (pipe), + phasey_step[1 ]);mdp5_write (mdp5_kms,REG_MDP5_PIPE_DECIMATION (pipe),MDP5_PIPE_DECIMATION_VERT (vdecm) |MDP5_PIPE_DECIMATION_HORZ (hdecm)); -mdp5_write (mdp5_kms,REG_MDP5_PIPE_SCALE_CONFIG (pipe), -MDP5_PIPE_SCALE_CONFIG_SCALEX_MIN_FILTER (SCALE_FILTER_NEAREST ) | -MDP5_PIPE_SCALE_CONFIG_SCALEY_MIN_FILTER (SCALE_FILTER_NEAREST ) | -MDP5_PIPE_SCALE_CONFIG_SCALEX_CR_FILTER (SCALE_FILTER_NEAREST ) | -MDP5_PIPE_SCALE_CONFIG_SCALEY_CR_FILTER (SCALE_FILTER_NEAREST ) | -MDP5_PIPE_SCALE_CONFIG_SCALEX_MAX_FILTER (SCALE_FILTER_NEAREST ) | -MDP5_PIPE_SCALE_CONFIG_SCALEY_MAX_FILTER (SCALE_FILTER_NEAREST )); +mdp5_write (mdp5_kms,REG_MDP5_PIPE_SCALE_CONFIG (pipe), config); + +if (MDP_FORMAT_IS_YUV (format)) +csc_enable (mdp5_kms, pipe, +mdp_get_default_csc_cfg (CSC_YUV2RGB )); +else +csc_disable (mdp5_kms, pipe);set_scanout_locked (plane, fb);
drivers/gpu/drm/msm/msm_fb.c +1 -1
@@ -122,7 +122,7 @@ uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, int id, int plane)struct msm_framebuffer *msm_fb =to_msm_framebuffer (fb);if (!msm_fb->planes[plane])return 0 ; -return msm_gem_iova (msm_fb->planes[plane], id); +return msm_gem_iova (msm_fb->planes[plane], id) + fb->offsets[plane]; }struct drm_gem_object *msm_framebuffer_bo (struct drm_framebuffer *fb,int plane)
Signature · 8 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 4/4 drm/msm/mdp4: add YUV format support
In reply to Stephane ViauFrom: Beeresh Gopal <[email protected]>
The patch add support for YUV frame format
for MDP4 platform.
--- drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 104 +++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 9 deletions(-)
drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c +95 -9
@@ -17,6 +17,8 @@#include "mdp4_kms.h" +#define DOWN_SCALE_MAX 8 +#define UP_SCALE_MAX 8struct mdp4_plane {struct drm_plane base;
@@ -135,10 +137,6 @@ static void mdp4_plane_set_scanout(struct drm_plane *plane,struct mdp4_plane *mdp4_plane =to_mdp4_plane (plane);struct mdp4_kms *mdp4_kms =get_kms (plane);enum mdp4_pipe pipe = mdp4_plane->pipe; -uint32_t iova =msm_framebuffer_iova (fb, mdp4_kms->id,0 ); - -DBG ("%s: set_scanout: %08x (%u)" , mdp4_plane->name, - iova, fb->pitches[0 ]); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_STRIDE_A(pipe), MDP4_PIPE_SRC_STRIDE_A_P0(fb->pitches[0]) |
@@ -148,11 +146,45 @@ static void mdp4_plane_set_scanout(struct drm_plane *plane,MDP4_PIPE_SRC_STRIDE_B_P2 (fb->pitches[2 ]) | MDP4_PIPE_SRC_STRIDE_B_P3(fb->pitches[3])); -mdp4_write (mdp4_kms,REG_MDP4_PIPE_SRCP0_BASE (pipe), iova); +mdp4_write (mdp4_kms,REG_MDP4_PIPE_SRCP0_BASE (pipe), +msm_framebuffer_iova (fb, mdp4_kms->id,0 )); +mdp4_write (mdp4_kms,REG_MDP4_PIPE_SRCP1_BASE (pipe), +msm_framebuffer_iova (fb, mdp4_kms->id,1 )); +mdp4_write (mdp4_kms,REG_MDP4_PIPE_SRCP2_BASE (pipe), +msm_framebuffer_iova (fb, mdp4_kms->id,2 )); +mdp4_write (mdp4_kms,REG_MDP4_PIPE_SRCP3_BASE (pipe), +msm_framebuffer_iova (fb, mdp4_kms->id,3 )); plane->fb = fb; } +static void mdp4_write_csc_config (struct mdp4_kms *mdp4_kms, +enum mdp4_pipe pipe,struct csc_cfg *csc) +{ +int i; + +for (i =0 ; i <ARRAY_SIZE (csc->matrix); i++) { +mdp4_write (mdp4_kms,REG_MDP4_PIPE_CSC_MV (pipe, i), + csc->matrix[i]); + } + +for (i =0 ; i <ARRAY_SIZE (csc->post_bias) ; i++) { +mdp4_write (mdp4_kms,REG_MDP4_PIPE_CSC_PRE_BV (pipe, i), + csc->pre_bias[i]); + +mdp4_write (mdp4_kms,REG_MDP4_PIPE_CSC_POST_BV (pipe, i), + csc->post_bias[i]); + } + +for (i =0 ; i <ARRAY_SIZE (csc->post_clamp) ; i++) { +mdp4_write (mdp4_kms,REG_MDP4_PIPE_CSC_PRE_LV (pipe, i), + csc->pre_clamp[i]); + +mdp4_write (mdp4_kms,REG_MDP4_PIPE_CSC_POST_LV (pipe, i), + csc->post_clamp[i]); + } +} +#define MDP4_VG_PHASE_STEP_DEFAULT 0x20000000 static int mdp4_plane_mode_set(struct drm_plane *plane,
@@ -162,6 +194,7 @@ static int mdp4_plane_mode_set(struct drm_plane *plane, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h) { + struct drm_device *dev = plane->dev;struct mdp4_plane *mdp4_plane =to_mdp4_plane (plane);struct mdp4_kms *mdp4_kms =get_kms (plane);enum mdp4_pipe pipe = mdp4_plane->pipe;
@@ -185,14 +218,59 @@ static int mdp4_plane_mode_set(struct drm_plane *plane, fb->base.id, src_x, src_y, src_w, src_h, crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h); + format =to_mdp_format (msm_framebuffer_format (fb)); + +if (src_w > (crtc_w *DOWN_SCALE_MAX )) { +dev_err (dev->dev,"Width down scaling exceeds limits!\n" ); +return -ERANGE ; + } + +if (src_h > (crtc_h *DOWN_SCALE_MAX )) { +dev_err (dev->dev,"Height down scaling exceeds limits!\n" ); +return -ERANGE ; + } + +if (crtc_w > (src_w *UP_SCALE_MAX )) { +dev_err (dev->dev,"Width up scaling exceeds limits!\n" ); +return -ERANGE ; + } + +if (crtc_h > (src_h *UP_SCALE_MAX )) { +dev_err (dev->dev,"Height up scaling exceeds limits!\n" ); +return -ERANGE ; + } +if (src_w != crtc_w) { +uint32_t sel_unit =SCALE_FIR ; op_mode |=MDP4_PIPE_OP_MODE_SCALEX_EN ; -/* TODO calc phasex_step */ + +if (MDP_FORMAT_IS_YUV (format)) { +if (crtc_w > src_w) + sel_unit =SCALE_PIXEL_RPT ; +else if (crtc_w <= (src_w /4 )) + sel_unit =SCALE_MN_PHASE ; + + op_mode |=MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL (sel_unit); + phasex_step =mult_frac (MDP4_VG_PHASE_STEP_DEFAULT , + src_w, crtc_w); + } }if (src_h != crtc_h) { +uint32_t sel_unit =SCALE_FIR ; op_mode |=MDP4_PIPE_OP_MODE_SCALEY_EN ; -/* TODO calc phasey_step */ + +if (MDP_FORMAT_IS_YUV (format)) { + +if (crtc_h > src_h) + sel_unit =SCALE_PIXEL_RPT ; +else if (crtc_h <= (src_h /4 )) + sel_unit =SCALE_MN_PHASE ; + + op_mode |=MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL (sel_unit); + phasey_step =mult_frac (MDP4_VG_PHASE_STEP_DEFAULT , + src_h, crtc_h); + } } mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_SIZE(pipe),
@@ -213,8 +291,6 @@ static int mdp4_plane_mode_set(struct drm_plane *plane,mdp4_plane_set_scanout (plane, fb); - format =to_mdp_format (msm_framebuffer_format (fb)); - mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_FORMAT(pipe), MDP4_PIPE_SRC_FORMAT_A_BPC(format->bpc_a) | MDP4_PIPE_SRC_FORMAT_R_BPC(format->bpc_r) |
@@ -223,6 +299,8 @@ static int mdp4_plane_mode_set(struct drm_plane *plane,COND (format->alpha_enable,MDP4_PIPE_SRC_FORMAT_ALPHA_ENABLE ) |MDP4_PIPE_SRC_FORMAT_CPP (format->cpp -1 ) |MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT (format->unpack_count -1 ) | +MDP4_PIPE_SRC_FORMAT_FETCH_PLANES (format->fetch_type) | +MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP (format->chroma_sample) | COND(format->unpack_tight, MDP4_PIPE_SRC_FORMAT_UNPACK_TIGHT)); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_UNPACK(pipe),
@@ -231,6 +309,14 @@ static int mdp4_plane_mode_set(struct drm_plane *plane,MDP4_PIPE_SRC_UNPACK_ELEM2 (format->unpack[2 ]) | MDP4_PIPE_SRC_UNPACK_ELEM3(format->unpack[3])); +if (MDP_FORMAT_IS_YUV (format)) { +struct csc_cfg *csc =mdp_get_default_csc_cfg (CSC_YUV2RGB ); + + op_mode |=MDP4_PIPE_OP_MODE_SRC_YCBCR ; + op_mode |=MDP4_PIPE_OP_MODE_CSC_EN ; +mdp4_write_csc_config (mdp4_kms, pipe, csc); + } +mdp4_write (mdp4_kms,REG_MDP4_PIPE_OP_MODE (pipe), op_mode);mdp4_write (mdp4_kms,REG_MDP4_PIPE_PHASEX_STEP (pipe), phasex_step);mdp4_write (mdp4_kms,REG_MDP4_PIPE_PHASEY_STEP (pipe), phasey_step);
Signature · 8 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel