Loading Documentation/devicetree/bindings/fb/mdss-mdp.txt +28 −0 Original line number Diff line number Diff line Loading @@ -577,6 +577,25 @@ Subnode properties: -- qcom,mdss-dspp-pgc-off: This 32 bit value provides the offset to PGC block from the DSPP base address. - qcom,mdss-scaler-offsets: A node that lists the offsets of scaler blocks from base module. -- qcom,mdss-vig-scaler-off: This 32 bit value provides the offset to vig scaler from vig pipe base. -- qcom,mdss-vig-scaler-lut-off: This 32 bit value provides the offset to vig scaler lut from vig pipe base. -- qcom,mdss-has-dest-scaler: Boolean property to indicate the presence of destination scaler block. -- qcom,mdss-dest-block-off: This 32 bit value provides the offset from mdp base to destination scaler block. -- qcom,mdss-dest-scaler-off: Array containing offsets of destination scalar modules from the scaler block. -- qcom,mdss-dest-scaler-lut-off: Array containing offsets of destination scaler lut tables from scalar block. - qcom,mdss-has-separate-rotator: Boolean property to indicate support of indpendent rotator. Indpendent rotator has separate DMA pipe working in block mode only. - smmu_mdp_***: Child nodes representing the mdss smmu virtual devices. Mandatory smmu v2 and not required for smmu v1. Loading Loading @@ -777,6 +796,15 @@ Example: qcom,mdss-dspp-pgc-off = <0x17C0>; }; qcom,mdss-scaler-offsets { qcom,mdss-vig-scaler-off = <0xA00>; qcom,mdss-vig-scaler-lut-off = <0xB00>; qcom,mdss-has-dest-scaler; qcom,mdss-dest-block-off = <0x00061000>; qcom,mdss-dest-scaler-off = <0x800 0x1000>; qcom,mdss-dest-scaler-lut-off = <0x900 0x1100>; }; qcom,mdss-reg-bus { /* Reg Bus Scale Settings */ qcom,msm-bus,name = "mdss_reg"; Loading drivers/video/msm/mdss/mdss.h +24 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,7 @@ enum mdss_hw_quirk { MDSS_QUIRK_DSC_2SLICE_PU_THRPUT, MDSS_QUIRK_DMA_BI_DIR, MDSS_QUIRK_MIN_BUS_VOTE, MDSS_QUIRK_FMT_PACK_PATTERN, MDSS_QUIRK_MAX, }; Loading @@ -168,6 +169,8 @@ enum mdss_hw_capabilities { MDSS_CAPS_SCM_RESTORE_NOT_REQUIRED, MDSS_CAPS_3D_MUX_UNDERRUN_RECOVERY_SUPPORTED, MDSS_CAPS_MIXER_1_FOR_WB, MDSS_CAPS_QSEED3, MDSS_CAPS_DEST_SCALER, MDSS_CAPS_MAX, }; Loading Loading @@ -198,6 +201,24 @@ struct mdss_smmu_client { bool handoff_pending; }; struct mdss_mdp_qseed3_lut_tbl { bool valid; u32 *dir_lut; u32 *cir_lut; u32 *sep_lut; }; struct mdss_scaler_block { u32 vig_scaler_off; u32 vig_scaler_lut_off; u32 has_dest_scaler; char __iomem *dest_base; u32 ndest_scalers; u32 *dest_scaler_off; u32 *dest_scaler_lut_off; struct mdss_mdp_qseed3_lut_tbl lut_tbl; }; struct mdss_data_type; struct mdss_smmu_ops { Loading Loading @@ -290,6 +311,7 @@ struct mdss_data_type { bool has_pixel_ram; bool needs_hist_vote; bool has_ubwc; bool has_wb_ubwc; u32 default_ot_rd_limit; u32 default_ot_wr_limit; Loading Loading @@ -458,7 +480,9 @@ struct mdss_data_type { u32 bcolor0; u32 bcolor1; u32 bcolor2; struct mdss_scaler_block *scaler_off; }; extern struct mdss_data_type *mdss_res; struct irq_info { Loading drivers/video/msm/mdss/mdss_fb.c +118 −26 Original line number Diff line number Diff line Loading @@ -4148,6 +4148,114 @@ static int mdss_fb_display_commit(struct fb_info *info, return ret; } /** * __mdss_fb_copy_pixel_ext() - copy pixel extension payload * @src: pixel extn structure * @dest: Qseed3/pixel extn common payload * * Function copies the pixel extension parameters into the scale data structure, * this is required to allow using the scale_v2 data structure for both * QSEED2 and QSEED3 */ static void __mdss_fb_copy_pixel_ext(struct mdp_scale_data *src, struct mdp_scale_data_v2 *dest) { if (!src || !dest) return; memcpy(dest->init_phase_x, src->init_phase_x, sizeof(src->init_phase_x)); memcpy(dest->phase_step_x, src->phase_step_x, sizeof(src->init_phase_x)); memcpy(dest->init_phase_y, src->init_phase_y, sizeof(src->init_phase_x)); memcpy(dest->phase_step_y, src->phase_step_y, sizeof(src->init_phase_x)); memcpy(dest->num_ext_pxls_left, src->num_ext_pxls_left, sizeof(src->num_ext_pxls_left)); memcpy(dest->num_ext_pxls_right, src->num_ext_pxls_right, sizeof(src->num_ext_pxls_right)); memcpy(dest->num_ext_pxls_top, src->num_ext_pxls_top, sizeof(src->num_ext_pxls_top)); memcpy(dest->num_ext_pxls_btm, src->num_ext_pxls_btm, sizeof(src->num_ext_pxls_btm)); memcpy(dest->left_ftch, src->left_ftch, sizeof(src->left_ftch)); memcpy(dest->left_rpt, src->left_rpt, sizeof(src->left_rpt)); memcpy(dest->right_ftch, src->right_ftch, sizeof(src->right_ftch)); memcpy(dest->right_rpt, src->right_rpt, sizeof(src->right_rpt)); memcpy(dest->top_rpt, src->top_rpt, sizeof(src->top_rpt)); memcpy(dest->btm_rpt, src->btm_rpt, sizeof(src->btm_rpt)); memcpy(dest->top_ftch, src->top_ftch, sizeof(src->top_ftch)); memcpy(dest->btm_ftch, src->btm_ftch, sizeof(src->btm_ftch)); memcpy(dest->roi_w, src->roi_w, sizeof(src->roi_w)); } static int __mdss_fb_scaler_handler(struct mdp_input_layer *layer) { int ret = 0; struct mdp_scale_data *pixel_ext = NULL; struct mdp_scale_data_v2 *scale = NULL; if ((layer->flags & MDP_LAYER_ENABLE_PIXEL_EXT) && (layer->flags & MDP_LAYER_ENABLE_QSEED3_SCALE)) { pr_err("Invalid flag configuration for scaler, %x\n", layer->flags); ret = -EINVAL; goto err; } if (layer->flags & MDP_LAYER_ENABLE_PIXEL_EXT) { scale = kzalloc(sizeof(struct mdp_scale_data_v2), GFP_KERNEL); pixel_ext = kzalloc(sizeof(struct mdp_scale_data), GFP_KERNEL); if (!scale || !pixel_ext) { mdss_mdp_free_layer_pp_info(layer); ret = -ENOMEM; goto err; } ret = copy_from_user(pixel_ext, layer->scale, sizeof(struct mdp_scale_data)); if (ret) { mdss_mdp_free_layer_pp_info(layer); ret = -EFAULT; goto err; } __mdss_fb_copy_pixel_ext(pixel_ext, scale); layer->scale = scale; } else if (layer->flags & MDP_LAYER_ENABLE_QSEED3_SCALE) { scale = kzalloc(sizeof(struct mdp_scale_data_v2), GFP_KERNEL); if (!scale) { mdss_mdp_free_layer_pp_info(layer); ret = -ENOMEM; goto err; } ret = copy_from_user(scale, layer->scale, sizeof(struct mdp_scale_data_v2)); if (ret) { mdss_mdp_free_layer_pp_info(layer); ret = -EFAULT; goto err; } layer->scale = scale; } else { layer->scale = NULL; } kfree(pixel_ext); return ret; err: kfree(pixel_ext); kfree(scale); layer->scale = NULL; return ret; } static int mdss_fb_atomic_commit_ioctl(struct fb_info *info, unsigned long *argp, struct file *file) { Loading @@ -4156,7 +4264,6 @@ static int mdss_fb_atomic_commit_ioctl(struct fb_info *info, u32 buffer_size, layer_count; struct mdp_input_layer *layer, *layer_list = NULL; struct mdp_input_layer __user *input_layer_list; struct mdp_scale_data *scale; struct mdp_output_layer *output_layer = NULL; struct mdp_output_layer __user *output_layer_user; Loading Loading @@ -4209,7 +4316,6 @@ static int mdss_fb_atomic_commit_ioctl(struct fb_info *info, for (i = 0; i < layer_count; i++) { layer = &layer_list[i]; scale = NULL; if (!(layer->flags & MDP_LAYER_PP)) { layer->pp_info = NULL; Loading @@ -4222,32 +4328,18 @@ static int mdss_fb_atomic_commit_ioctl(struct fb_info *info, } } if (!(layer->flags & MDP_LAYER_ENABLE_PIXEL_EXT)) { layer->scale = NULL; continue; } scale = kzalloc(sizeof(struct mdp_scale_data), GFP_KERNEL); if (!scale) { pr_err("unable to allocate memory for overlays\n"); mdss_mdp_free_layer_pp_info(layer); ret = -ENOMEM; goto err; } ret = copy_from_user(scale, layer->scale, sizeof(struct mdp_scale_data)); if ((layer->flags & MDP_LAYER_ENABLE_PIXEL_EXT) || (layer->flags & MDP_LAYER_ENABLE_QSEED3_SCALE)) { ret = __mdss_fb_scaler_handler(layer); if (ret) { pr_err("layer list copy from user failed, scale = %p\n", layer->scale); kfree(scale); scale = NULL; mdss_mdp_free_layer_pp_info(layer); ret = -EFAULT; pr_err("failure to copy scale params for layer %d, ret = %d\n", i, ret); goto err; } layer->scale = scale; } else { layer->scale = NULL; } } } Loading Loading
Documentation/devicetree/bindings/fb/mdss-mdp.txt +28 −0 Original line number Diff line number Diff line Loading @@ -577,6 +577,25 @@ Subnode properties: -- qcom,mdss-dspp-pgc-off: This 32 bit value provides the offset to PGC block from the DSPP base address. - qcom,mdss-scaler-offsets: A node that lists the offsets of scaler blocks from base module. -- qcom,mdss-vig-scaler-off: This 32 bit value provides the offset to vig scaler from vig pipe base. -- qcom,mdss-vig-scaler-lut-off: This 32 bit value provides the offset to vig scaler lut from vig pipe base. -- qcom,mdss-has-dest-scaler: Boolean property to indicate the presence of destination scaler block. -- qcom,mdss-dest-block-off: This 32 bit value provides the offset from mdp base to destination scaler block. -- qcom,mdss-dest-scaler-off: Array containing offsets of destination scalar modules from the scaler block. -- qcom,mdss-dest-scaler-lut-off: Array containing offsets of destination scaler lut tables from scalar block. - qcom,mdss-has-separate-rotator: Boolean property to indicate support of indpendent rotator. Indpendent rotator has separate DMA pipe working in block mode only. - smmu_mdp_***: Child nodes representing the mdss smmu virtual devices. Mandatory smmu v2 and not required for smmu v1. Loading Loading @@ -777,6 +796,15 @@ Example: qcom,mdss-dspp-pgc-off = <0x17C0>; }; qcom,mdss-scaler-offsets { qcom,mdss-vig-scaler-off = <0xA00>; qcom,mdss-vig-scaler-lut-off = <0xB00>; qcom,mdss-has-dest-scaler; qcom,mdss-dest-block-off = <0x00061000>; qcom,mdss-dest-scaler-off = <0x800 0x1000>; qcom,mdss-dest-scaler-lut-off = <0x900 0x1100>; }; qcom,mdss-reg-bus { /* Reg Bus Scale Settings */ qcom,msm-bus,name = "mdss_reg"; Loading
drivers/video/msm/mdss/mdss.h +24 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,7 @@ enum mdss_hw_quirk { MDSS_QUIRK_DSC_2SLICE_PU_THRPUT, MDSS_QUIRK_DMA_BI_DIR, MDSS_QUIRK_MIN_BUS_VOTE, MDSS_QUIRK_FMT_PACK_PATTERN, MDSS_QUIRK_MAX, }; Loading @@ -168,6 +169,8 @@ enum mdss_hw_capabilities { MDSS_CAPS_SCM_RESTORE_NOT_REQUIRED, MDSS_CAPS_3D_MUX_UNDERRUN_RECOVERY_SUPPORTED, MDSS_CAPS_MIXER_1_FOR_WB, MDSS_CAPS_QSEED3, MDSS_CAPS_DEST_SCALER, MDSS_CAPS_MAX, }; Loading Loading @@ -198,6 +201,24 @@ struct mdss_smmu_client { bool handoff_pending; }; struct mdss_mdp_qseed3_lut_tbl { bool valid; u32 *dir_lut; u32 *cir_lut; u32 *sep_lut; }; struct mdss_scaler_block { u32 vig_scaler_off; u32 vig_scaler_lut_off; u32 has_dest_scaler; char __iomem *dest_base; u32 ndest_scalers; u32 *dest_scaler_off; u32 *dest_scaler_lut_off; struct mdss_mdp_qseed3_lut_tbl lut_tbl; }; struct mdss_data_type; struct mdss_smmu_ops { Loading Loading @@ -290,6 +311,7 @@ struct mdss_data_type { bool has_pixel_ram; bool needs_hist_vote; bool has_ubwc; bool has_wb_ubwc; u32 default_ot_rd_limit; u32 default_ot_wr_limit; Loading Loading @@ -458,7 +480,9 @@ struct mdss_data_type { u32 bcolor0; u32 bcolor1; u32 bcolor2; struct mdss_scaler_block *scaler_off; }; extern struct mdss_data_type *mdss_res; struct irq_info { Loading
drivers/video/msm/mdss/mdss_fb.c +118 −26 Original line number Diff line number Diff line Loading @@ -4148,6 +4148,114 @@ static int mdss_fb_display_commit(struct fb_info *info, return ret; } /** * __mdss_fb_copy_pixel_ext() - copy pixel extension payload * @src: pixel extn structure * @dest: Qseed3/pixel extn common payload * * Function copies the pixel extension parameters into the scale data structure, * this is required to allow using the scale_v2 data structure for both * QSEED2 and QSEED3 */ static void __mdss_fb_copy_pixel_ext(struct mdp_scale_data *src, struct mdp_scale_data_v2 *dest) { if (!src || !dest) return; memcpy(dest->init_phase_x, src->init_phase_x, sizeof(src->init_phase_x)); memcpy(dest->phase_step_x, src->phase_step_x, sizeof(src->init_phase_x)); memcpy(dest->init_phase_y, src->init_phase_y, sizeof(src->init_phase_x)); memcpy(dest->phase_step_y, src->phase_step_y, sizeof(src->init_phase_x)); memcpy(dest->num_ext_pxls_left, src->num_ext_pxls_left, sizeof(src->num_ext_pxls_left)); memcpy(dest->num_ext_pxls_right, src->num_ext_pxls_right, sizeof(src->num_ext_pxls_right)); memcpy(dest->num_ext_pxls_top, src->num_ext_pxls_top, sizeof(src->num_ext_pxls_top)); memcpy(dest->num_ext_pxls_btm, src->num_ext_pxls_btm, sizeof(src->num_ext_pxls_btm)); memcpy(dest->left_ftch, src->left_ftch, sizeof(src->left_ftch)); memcpy(dest->left_rpt, src->left_rpt, sizeof(src->left_rpt)); memcpy(dest->right_ftch, src->right_ftch, sizeof(src->right_ftch)); memcpy(dest->right_rpt, src->right_rpt, sizeof(src->right_rpt)); memcpy(dest->top_rpt, src->top_rpt, sizeof(src->top_rpt)); memcpy(dest->btm_rpt, src->btm_rpt, sizeof(src->btm_rpt)); memcpy(dest->top_ftch, src->top_ftch, sizeof(src->top_ftch)); memcpy(dest->btm_ftch, src->btm_ftch, sizeof(src->btm_ftch)); memcpy(dest->roi_w, src->roi_w, sizeof(src->roi_w)); } static int __mdss_fb_scaler_handler(struct mdp_input_layer *layer) { int ret = 0; struct mdp_scale_data *pixel_ext = NULL; struct mdp_scale_data_v2 *scale = NULL; if ((layer->flags & MDP_LAYER_ENABLE_PIXEL_EXT) && (layer->flags & MDP_LAYER_ENABLE_QSEED3_SCALE)) { pr_err("Invalid flag configuration for scaler, %x\n", layer->flags); ret = -EINVAL; goto err; } if (layer->flags & MDP_LAYER_ENABLE_PIXEL_EXT) { scale = kzalloc(sizeof(struct mdp_scale_data_v2), GFP_KERNEL); pixel_ext = kzalloc(sizeof(struct mdp_scale_data), GFP_KERNEL); if (!scale || !pixel_ext) { mdss_mdp_free_layer_pp_info(layer); ret = -ENOMEM; goto err; } ret = copy_from_user(pixel_ext, layer->scale, sizeof(struct mdp_scale_data)); if (ret) { mdss_mdp_free_layer_pp_info(layer); ret = -EFAULT; goto err; } __mdss_fb_copy_pixel_ext(pixel_ext, scale); layer->scale = scale; } else if (layer->flags & MDP_LAYER_ENABLE_QSEED3_SCALE) { scale = kzalloc(sizeof(struct mdp_scale_data_v2), GFP_KERNEL); if (!scale) { mdss_mdp_free_layer_pp_info(layer); ret = -ENOMEM; goto err; } ret = copy_from_user(scale, layer->scale, sizeof(struct mdp_scale_data_v2)); if (ret) { mdss_mdp_free_layer_pp_info(layer); ret = -EFAULT; goto err; } layer->scale = scale; } else { layer->scale = NULL; } kfree(pixel_ext); return ret; err: kfree(pixel_ext); kfree(scale); layer->scale = NULL; return ret; } static int mdss_fb_atomic_commit_ioctl(struct fb_info *info, unsigned long *argp, struct file *file) { Loading @@ -4156,7 +4264,6 @@ static int mdss_fb_atomic_commit_ioctl(struct fb_info *info, u32 buffer_size, layer_count; struct mdp_input_layer *layer, *layer_list = NULL; struct mdp_input_layer __user *input_layer_list; struct mdp_scale_data *scale; struct mdp_output_layer *output_layer = NULL; struct mdp_output_layer __user *output_layer_user; Loading Loading @@ -4209,7 +4316,6 @@ static int mdss_fb_atomic_commit_ioctl(struct fb_info *info, for (i = 0; i < layer_count; i++) { layer = &layer_list[i]; scale = NULL; if (!(layer->flags & MDP_LAYER_PP)) { layer->pp_info = NULL; Loading @@ -4222,32 +4328,18 @@ static int mdss_fb_atomic_commit_ioctl(struct fb_info *info, } } if (!(layer->flags & MDP_LAYER_ENABLE_PIXEL_EXT)) { layer->scale = NULL; continue; } scale = kzalloc(sizeof(struct mdp_scale_data), GFP_KERNEL); if (!scale) { pr_err("unable to allocate memory for overlays\n"); mdss_mdp_free_layer_pp_info(layer); ret = -ENOMEM; goto err; } ret = copy_from_user(scale, layer->scale, sizeof(struct mdp_scale_data)); if ((layer->flags & MDP_LAYER_ENABLE_PIXEL_EXT) || (layer->flags & MDP_LAYER_ENABLE_QSEED3_SCALE)) { ret = __mdss_fb_scaler_handler(layer); if (ret) { pr_err("layer list copy from user failed, scale = %p\n", layer->scale); kfree(scale); scale = NULL; mdss_mdp_free_layer_pp_info(layer); ret = -EFAULT; pr_err("failure to copy scale params for layer %d, ret = %d\n", i, ret); goto err; } layer->scale = scale; } else { layer->scale = NULL; } } } Loading