diff options
| author | Clarence Ip <cip@codeaurora.org> | 2016-09-08 14:21:35 -0400 |
|---|---|---|
| committer | Clarence Ip <cip@codeaurora.org> | 2016-10-05 10:54:02 -0400 |
| commit | f651c2aeb81934f534ef7f1817ad8283742be2be (patch) | |
| tree | 82dda03f23d781f5d624f04bcb9f7933c8771e04 | |
| parent | 0043536acfd2dd8890eb58004866e0cf14e73d81 (diff) | |
drm/msm/sde: update scaler property definition and type
Blob properties under DRM require a new blob to be created for
each unique set of incoming data. By changing the scaler property
to accept an incoming user space pointer and using copy_from_user
to explicitly copy out the structure data each time the property
is set, the user space client avoids the need to create new
DRM blob objects when the scaler config needs to be updated.
Change-Id: I07d4d095b69ddd38e2bf03de61ad51714df84adb
Signed-off-by: Clarence Ip <cip@codeaurora.org>
| -rw-r--r-- | drivers/gpu/drm/msm/msm_drv.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_plane.c | 245 | ||||
| -rw-r--r-- | include/uapi/drm/sde_drm.h | 73 |
3 files changed, 101 insertions, 219 deletions
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 136366a58b1a..d51800863294 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -80,7 +80,7 @@ struct msm_file_private { enum msm_mdp_plane_property { /* blob properties, always put these first */ - PLANE_PROP_SCALER, + PLANE_PROP_SCALER_V1, PLANE_PROP_CSC_V1, PLANE_PROP_INFO, diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c index 6e3268608565..34be418a5551 100644 --- a/drivers/gpu/drm/msm/sde/sde_plane.c +++ b/drivers/gpu/drm/msm/sde/sde_plane.c @@ -78,7 +78,6 @@ struct sde_plane { struct sde_hw_pipe *pipe_hw; struct sde_hw_pipe_cfg pipe_cfg; - struct sde_hw_pixel_ext pixel_ext; struct sde_hw_sharp_cfg sharp_cfg; struct sde_hw_scaler3_cfg scaler3_cfg; struct sde_hw_pipe_qos_cfg pipe_qos_cfg; @@ -86,6 +85,9 @@ struct sde_plane { bool is_error; bool is_rt_pipe; + struct sde_hw_pixel_ext pixel_ext; + bool pixel_ext_usr; + struct sde_csc_cfg csc_cfg; struct sde_csc_cfg *csc_usr_ptr; struct sde_csc_cfg *csc_ptr; @@ -601,7 +603,6 @@ static int _sde_plane_setup_scaler2(struct sde_plane *psde, } } else { /* disable scaler */ - SDE_DEBUG("disable scaler\n"); filter[SDE_SSPP_COMP_0] = SDE_SCALE_FILTER_MAX; filter[SDE_SSPP_COMP_1_2] = SDE_SCALE_FILTER_MAX; filter[SDE_SSPP_COMP_3] = SDE_SCALE_FILTER_MAX; @@ -702,47 +703,6 @@ static void _sde_plane_setup_pixel_ext(struct sde_plane *psde, } } -/** - * _sde_plane_verify_blob - verify incoming blob is big enough to contain - * sub-structure - * @blob_ptr: Pointer to start of incoming blob data - * @blob_size: Size of incoming blob data, in bytes - * @sub_ptr: Pointer to start of desired sub-structure - * @sub_size: Required size of sub-structure, in bytes - */ -static int _sde_plane_verify_blob(void *blob_ptr, - size_t blob_size, - void *sub_ptr, - size_t sub_size) -{ - /* - * Use the blob size provided by drm to check if there are enough - * bytes from the start of versioned sub-structures to the end of - * blob data: - * - * e.g., - * blob_ptr --> struct blob_data { - * uint32_t version; - * sub_ptr --> struct blob_data_v1 v1; - * sub_ptr + sub_size --> struct blob_stuff more_stuff; - * blob_ptr + blob_size --> }; - * - * It's important to check the actual number of bytes from the start - * of the sub-structure to the end of the blob data, and not just rely - * on something like, - * - * sizeof(blob) - sizeof(blob->version) >= sizeof(sub-struct) - * - * This is because the start of the sub-structure can vary based on - * how the compiler pads the overall structure. - */ - if (blob_ptr && sub_ptr) - /* return zero if end of blob >= end of sub-struct */ - return ((unsigned char *)blob_ptr + blob_size) < - ((unsigned char *)sub_ptr + sub_size); - return -EINVAL; -} - static inline void _sde_plane_setup_csc(struct sde_plane *psde) { static const struct sde_csc_cfg sde_csc_YUV2RGB_601L = { @@ -781,41 +741,17 @@ static void _sde_plane_setup_scaler(struct sde_plane *psde, const struct sde_format *fmt, struct sde_plane_state *pstate) { - struct sde_hw_pixel_ext *pe = NULL; - struct sde_drm_scaler *sc_u = NULL; - struct sde_drm_scaler_v1 *sc_u1 = NULL; - size_t sc_u_size = 0; + struct sde_hw_pixel_ext *pe; uint32_t chroma_subsmpl_h, chroma_subsmpl_v; - uint32_t tmp; - int i; + uint32_t tmp, i; - if (!psde || !fmt) + if (!psde || !fmt) { + SDE_ERROR("invalid arg(s), plane %d fmt %d state %d\n", + psde != 0, fmt != 0, pstate != 0); return; + } pe = &(psde->pixel_ext); - memset(pe, 0, sizeof(struct sde_hw_pixel_ext)); - - /* get scaler config from user space */ - if (pstate) - sc_u = msm_property_get_blob(&psde->property_info, - pstate->property_blobs, - &sc_u_size, - PLANE_PROP_SCALER); - if (sc_u) { - switch (sc_u->version) { - case SDE_DRM_SCALER_V1: - if (!_sde_plane_verify_blob(sc_u, - sc_u_size, - &sc_u->v1, - sizeof(*sc_u1))) - sc_u1 = &sc_u->v1; - break; - default: - SDE_DEBUG("unrecognized scaler blob v%lld\n", - sc_u->version); - break; - } - } psde->pipe_cfg.horz_decimation = sde_plane_get_property(pstate, PLANE_PROP_H_DECIMATE); @@ -830,9 +766,8 @@ static void _sde_plane_setup_scaler(struct sde_plane *psde, /* update scaler */ if (psde->features & BIT(SDE_SSPP_SCALER_QSEED3)) { - if (sc_u1 && (sc_u1->enable & SDE_DRM_SCALER_SCALER_3)) - SDE_DEBUG("SCALER3 blob detected\n"); - else + if (!psde->pixel_ext_usr) { + /* calculate default config for QSEED3 */ _sde_plane_setup_scaler3(psde, psde->pipe_cfg.src_rect.w, psde->pipe_cfg.src_rect.h, @@ -840,56 +775,23 @@ static void _sde_plane_setup_scaler(struct sde_plane *psde, psde->pipe_cfg.dst_rect.h, &psde->scaler3_cfg, fmt, chroma_subsmpl_h, chroma_subsmpl_v); - } else { - /* always calculate basic scaler config */ - if (sc_u1 && (sc_u1->enable & SDE_DRM_SCALER_SCALER_2)) { - /* populate from user space */ - for (i = 0; i < SDE_MAX_PLANES; i++) { - pe->init_phase_x[i] = sc_u1->init_phase_x[i]; - pe->phase_step_x[i] = sc_u1->phase_step_x[i]; - pe->init_phase_y[i] = sc_u1->init_phase_y[i]; - pe->phase_step_y[i] = sc_u1->phase_step_y[i]; - - pe->horz_filter[i] = sc_u1->horz_filter[i]; - pe->vert_filter[i] = sc_u1->vert_filter[i]; - } - } else { - /* calculate phase steps */ - _sde_plane_setup_scaler2(psde, - psde->pipe_cfg.src_rect.w, - psde->pipe_cfg.dst_rect.w, - pe->phase_step_x, - pe->horz_filter, fmt, chroma_subsmpl_h); - _sde_plane_setup_scaler2(psde, - psde->pipe_cfg.src_rect.h, - psde->pipe_cfg.dst_rect.h, - pe->phase_step_y, - pe->vert_filter, fmt, chroma_subsmpl_v); } - } + } else if (!psde->pixel_ext_usr) { + /* calculate default configuration for QSEED2 */ + memset(pe, 0, sizeof(struct sde_hw_pixel_ext)); + + SDE_DEBUG("default config\n"); + _sde_plane_setup_scaler2(psde, + psde->pipe_cfg.src_rect.w, + psde->pipe_cfg.dst_rect.w, + pe->phase_step_x, + pe->horz_filter, fmt, chroma_subsmpl_h); + _sde_plane_setup_scaler2(psde, + psde->pipe_cfg.src_rect.h, + psde->pipe_cfg.dst_rect.h, + pe->phase_step_y, + pe->vert_filter, fmt, chroma_subsmpl_v); - /* update pixel extensions */ - if (sc_u1 && (sc_u1->enable & SDE_DRM_SCALER_PIX_EXT)) { - /* populate from user space */ - SDE_DEBUG("pixel ext blob detected\n"); - for (i = 0; i < SDE_MAX_PLANES; i++) { - pe->num_ext_pxls_left[i] = sc_u1->lr.num_pxls_start[i]; - pe->num_ext_pxls_right[i] = sc_u1->lr.num_pxls_end[i]; - pe->left_ftch[i] = sc_u1->lr.ftch_start[i]; - pe->right_ftch[i] = sc_u1->lr.ftch_end[i]; - pe->left_rpt[i] = sc_u1->lr.rpt_start[i]; - pe->right_rpt[i] = sc_u1->lr.rpt_end[i]; - pe->roi_w[i] = sc_u1->lr.roi[i]; - - pe->num_ext_pxls_top[i] = sc_u1->tb.num_pxls_start[i]; - pe->num_ext_pxls_btm[i] = sc_u1->tb.num_pxls_end[i]; - pe->top_ftch[i] = sc_u1->tb.ftch_start[i]; - pe->btm_ftch[i] = sc_u1->tb.ftch_end[i]; - pe->top_rpt[i] = sc_u1->tb.rpt_start[i]; - pe->btm_rpt[i] = sc_u1->tb.rpt_end[i]; - pe->roi_h[i] = sc_u1->tb.roi[i]; - } - } else { /* calculate left/right/top/bottom pixel extensions */ tmp = DECIMATED_DIMENSION(psde->pipe_cfg.src_rect.w, psde->pipe_cfg.horz_decimation); @@ -915,32 +817,24 @@ static void _sde_plane_setup_scaler(struct sde_plane *psde, for (i = 0; i < SDE_MAX_PLANES; i++) { if (pe->num_ext_pxls_left[i] >= 0) - pe->left_rpt[i] = - pe->num_ext_pxls_left[i]; + pe->left_rpt[i] = pe->num_ext_pxls_left[i]; else - pe->left_ftch[i] = - pe->num_ext_pxls_left[i]; + pe->left_ftch[i] = pe->num_ext_pxls_left[i]; if (pe->num_ext_pxls_right[i] >= 0) - pe->right_rpt[i] = - pe->num_ext_pxls_right[i]; + pe->right_rpt[i] = pe->num_ext_pxls_right[i]; else - pe->right_ftch[i] = - pe->num_ext_pxls_right[i]; + pe->right_ftch[i] = pe->num_ext_pxls_right[i]; if (pe->num_ext_pxls_top[i] >= 0) - pe->top_rpt[i] = - pe->num_ext_pxls_top[i]; + pe->top_rpt[i] = pe->num_ext_pxls_top[i]; else - pe->top_ftch[i] = - pe->num_ext_pxls_top[i]; + pe->top_ftch[i] = pe->num_ext_pxls_top[i]; if (pe->num_ext_pxls_btm[i] >= 0) - pe->btm_rpt[i] = - pe->num_ext_pxls_btm[i]; + pe->btm_rpt[i] = pe->num_ext_pxls_btm[i]; else - pe->btm_ftch[i] = - pe->num_ext_pxls_btm[i]; + pe->btm_ftch[i] = pe->num_ext_pxls_btm[i]; } } } @@ -1038,7 +932,7 @@ static int _sde_plane_mode_set(struct drm_plane *plane, /* determine what needs to be refreshed */ while ((idx = msm_property_pop_dirty(&psde->property_info)) >= 0) { switch (idx) { - case PLANE_PROP_SCALER: + case PLANE_PROP_SCALER_V1: case PLANE_PROP_H_DECIMATE: case PLANE_PROP_V_DECIMATE: case PLANE_PROP_SRC_CONFIG: @@ -1514,6 +1408,11 @@ static void _sde_plane_install_properties(struct drm_plane *plane, PLANE_PROP_V_DECIMATE); } + if (psde->features & SDE_SSPP_SCALER) { + msm_property_install_volatile_range(&psde->property_info, + "scaler_v1", 0x0, 0, ~0, 0, PLANE_PROP_SCALER_V1); + } + if (psde->features & BIT(SDE_SSPP_CSC)) { msm_property_install_volatile_range(&psde->property_info, "csc_v1", 0x0, 0, ~0, 0, PLANE_PROP_CSC_V1); @@ -1533,10 +1432,6 @@ static void _sde_plane_install_properties(struct drm_plane *plane, msm_property_install_range(&psde->property_info, "color_fill", 0, 0, 0xFFFFFFFF, 0, PLANE_PROP_COLOR_FILL); - if (psde->features & SDE_SSPP_SCALER) - msm_property_install_blob(&psde->property_info, "scaler", 0, - PLANE_PROP_SCALER); - info = kzalloc(sizeof(struct sde_kms_info), GFP_KERNEL); if (!info) return; @@ -1594,6 +1489,7 @@ static inline void _sde_plane_set_csc_v1(struct sde_plane *psde, void *usr_ptr) return; } + /* populate from user space */ for (i = 0; i < SDE_CSC_MATRIX_COEFF_SIZE; ++i) psde->csc_cfg.csc_mv[i] = csc_v1.ctm_coeff[i] >> 16; for (i = 0; i < SDE_CSC_BIAS_SIZE; ++i) { @@ -1607,6 +1503,62 @@ static inline void _sde_plane_set_csc_v1(struct sde_plane *psde, void *usr_ptr) psde->csc_usr_ptr = &psde->csc_cfg; } +static inline void _sde_plane_set_scaler_v1(struct sde_plane *psde, void *usr) +{ + struct sde_drm_scaler_v1 scale_v1; + struct sde_hw_pixel_ext *pe; + int i; + + if (!psde) { + SDE_ERROR("invalid plane\n"); + return; + } + + psde->pixel_ext_usr = false; + if (!usr) { + SDE_DEBUG("scale data removed\n"); + return; + } + + if (copy_from_user(&scale_v1, usr, sizeof(scale_v1))) { + SDE_ERROR("failed to copy scale data\n"); + return; + } + + /* populate from user space */ + pe = &(psde->pixel_ext); + memset(pe, 0, sizeof(struct sde_hw_pixel_ext)); + for (i = 0; i < SDE_MAX_PLANES; i++) { + pe->init_phase_x[i] = scale_v1.init_phase_x[i]; + pe->phase_step_x[i] = scale_v1.phase_step_x[i]; + pe->init_phase_y[i] = scale_v1.init_phase_y[i]; + pe->phase_step_y[i] = scale_v1.phase_step_y[i]; + + pe->horz_filter[i] = scale_v1.horz_filter[i]; + pe->vert_filter[i] = scale_v1.vert_filter[i]; + } + for (i = 0; i < SDE_MAX_PLANES; i++) { + pe->num_ext_pxls_left[i] = scale_v1.lr.num_pxls_start[i]; + pe->num_ext_pxls_right[i] = scale_v1.lr.num_pxls_end[i]; + pe->left_ftch[i] = scale_v1.lr.ftch_start[i]; + pe->right_ftch[i] = scale_v1.lr.ftch_end[i]; + pe->left_rpt[i] = scale_v1.lr.rpt_start[i]; + pe->right_rpt[i] = scale_v1.lr.rpt_end[i]; + pe->roi_w[i] = scale_v1.lr.roi[i]; + + pe->num_ext_pxls_top[i] = scale_v1.tb.num_pxls_start[i]; + pe->num_ext_pxls_btm[i] = scale_v1.tb.num_pxls_end[i]; + pe->top_ftch[i] = scale_v1.tb.ftch_start[i]; + pe->btm_ftch[i] = scale_v1.tb.ftch_end[i]; + pe->top_rpt[i] = scale_v1.tb.rpt_start[i]; + pe->btm_rpt[i] = scale_v1.tb.rpt_end[i]; + pe->roi_h[i] = scale_v1.tb.roi[i]; + } + psde->pixel_ext_usr = true; + + SDE_DEBUG("user property data copied\n"); +} + static int sde_plane_atomic_set_property(struct drm_plane *plane, struct drm_plane_state *state, struct drm_property *property, uint64_t val) @@ -1637,6 +1589,9 @@ static int sde_plane_atomic_set_property(struct drm_plane *plane, case PLANE_PROP_CSC_V1: _sde_plane_set_csc_v1(psde, (void *)val); break; + case PLANE_PROP_SCALER_V1: + _sde_plane_set_scaler_v1(psde, (void *)val); + break; default: /* nothing to do */ break; diff --git a/include/uapi/drm/sde_drm.h b/include/uapi/drm/sde_drm.h index 35b3bc782921..07a02c721da1 100644 --- a/include/uapi/drm/sde_drm.h +++ b/include/uapi/drm/sde_drm.h @@ -1,36 +1,6 @@ #ifndef _SDE_DRM_H_ #define _SDE_DRM_H_ -/* - * Each top level structure is of the following format: - * - * struct { - * uint64_t version; - * union { - * struct version v1; - * ... - * } u; - * - * Each top level structure maintains independent versioning and is defined - * as follows: - * - * #define STRUCTNAME_V1 0x1 - * ... - * #define STRUCTNAME_Vn 0x### - * #define STRUCTNAME_VERSION STRUCTNAME_Vn - * - * Version fields should ALWAYS be declared as type uint64_t. This is because - * 64-bit compilers tend to pad the structure to 64-bit align the start of - * union structure members. Having an explicit 64-bit version helps to maintain - * consistent structure layout between 32-bit and 64-bit compilers. - * - * Updates to the structures UAPI should always define a new sub-structure to - * place within the union, and update STRUCTNAME_VERSION to reference the - * new version number. - * - * User mode code should always set the 'version' field to STRUCTNAME_VERSION. - */ - /* Total number of supported color planes */ #define SDE_MAX_PLANES 4 @@ -105,25 +75,9 @@ struct sde_drm_pix_ext_v1 { }; /** - * Enable mask bits for "scaler" property - * - * @SDE_DRM_SCALER_PIX_EXT: pix ext sub-structures are valid - * @SDE_DRM_SCALER_SCALER_2: scaler 2 sub-structures are valid - * @SDE_DRM_SCALER_SCALER_3: scaler 3 sub-structures are valid - * @SDE_DRM_SCALER_DECIMATE: decimation fields are valid - */ -#define SDE_DRM_SCALER_PIX_EXT 0x1 -#define SDE_DRM_SCALER_SCALER_2 0x2 -#define SDE_DRM_SCALER_SCALER_3 0x4 -#define SDE_DRM_SCALER_DECIMATE 0x8 - -/** * struct sde_drm_scaler_v1 - version 1 of struct sde_drm_scaler - * @enable: Mask of SDE_DRM_SCALER_ bits * @lr: Pixel extension settings for left/right * @tb: Pixel extension settings for top/botton - * @horz_decimate: Horizontal decimation factor - * @vert_decimate: Vertical decimation factor * @init_phase_x: Initial scaler phase values for x * @phase_step_x: Phase step values for x * @init_phase_y: Initial scaler phase values for y @@ -133,23 +87,12 @@ struct sde_drm_pix_ext_v1 { */ struct sde_drm_scaler_v1 { /* - * General definitions - */ - uint32_t enable; - - /* * Pix ext settings */ struct sde_drm_pix_ext_v1 lr; struct sde_drm_pix_ext_v1 tb; /* - * Decimation settings - */ - uint32_t horz_decimate; - uint32_t vert_decimate; - - /* * Phase settings */ int32_t init_phase_x[SDE_MAX_PLANES]; @@ -165,22 +108,6 @@ struct sde_drm_scaler_v1 { uint32_t vert_filter[SDE_MAX_PLANES]; }; -/* Scaler version definition, see top of file for guidelines */ -#define SDE_DRM_SCALER_V1 0x1 -#define SDE_DRM_SCALER_VERSION SDE_DRM_SCALER_V1 - -/** - * struct sde_drm_scaler - scaler structure - * @version: Structure version, set to SDE_DRM_SCALER_VERSION - * @v1: Version 1 of scaler structure - */ -struct sde_drm_scaler { - uint64_t version; - union { - struct sde_drm_scaler_v1 v1; - }; -}; - /* * Define constants for struct sde_drm_csc */ |
