summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDhaval Patel <pdhaval@quicinc.com>2016-10-10 10:20:36 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-10-10 10:20:36 -0700
commit4d4432a95e90545159e95f7745ee88b97446939c (patch)
treeaaf45ad3e415c47041013d9248cdd3920c352acd /drivers/gpu
parent563b1bceb855d3c51461091d0b038365caf579be (diff)
parentf651c2aeb81934f534ef7f1817ad8283742be2be (diff)
Merge "drm/msm/sde: update scaler property definition and type" into dev/msm-4.4-drm_kms
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h2
-rw-r--r--drivers/gpu/drm/msm/sde/sde_plane.c245
2 files changed, 101 insertions, 146 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;