Loading drivers/gpu/drm/msm/sde/sde_color_processing.c +82 −7 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include "sde_hw_interrupts.h" #include "sde_core_irq.h" #include "dsi_panel.h" #include "sde_hw_color_proc_common_v4.h" struct sde_cp_node { u32 property_id; Loading Loading @@ -93,6 +94,8 @@ static void _sde_cp_crtc_disable_ltm_hist(struct sde_crtc *sde_crtc, struct sde_hw_dspp *hw_dspp, struct sde_hw_cp_cfg *hw_cfg); static void sde_cp_notify_ltm_hist(struct drm_crtc *crtc_drm, void *arg); static void sde_cp_notify_ltm_wb_pb(struct drm_crtc *crtc_drm, void *arg); static void _sde_cp_crtc_update_ltm_roi(struct sde_crtc *sde_crtc, struct sde_hw_cp_cfg *hw_cfg); #define setup_dspp_prop_install_funcs(func) \ do { \ Loading Loading @@ -539,10 +542,12 @@ static int set_ltm_roi_feature(struct sde_hw_dspp *hw_dspp, { int ret = 0; if (!hw_dspp || !hw_dspp->ops.setup_ltm_roi) if (!hw_dspp || !hw_dspp->ops.setup_ltm_roi) { ret = -EINVAL; else } else { hw_dspp->ops.setup_ltm_roi(hw_dspp, hw_cfg); _sde_cp_crtc_update_ltm_roi(hw_crtc, hw_cfg); } return ret; } Loading Loading @@ -2852,6 +2857,7 @@ static void _sde_cp_crtc_disable_ltm_hist(struct sde_crtc *sde_crtc, { unsigned long irq_flags; struct sde_hw_mixer *hw_lm = hw_cfg->mixer_info; u32 i = 0; spin_lock_irqsave(&sde_crtc->ltm_lock, irq_flags); if (!hw_lm->cfg.right_mixer && !sde_crtc->ltm_hist_en) { Loading @@ -2860,6 +2866,11 @@ static void _sde_cp_crtc_disable_ltm_hist(struct sde_crtc *sde_crtc, return; } sde_crtc->ltm_hist_en = false; INIT_LIST_HEAD(&sde_crtc->ltm_buf_free); INIT_LIST_HEAD(&sde_crtc->ltm_buf_busy); for (i = 0; i < sde_crtc->ltm_buffer_cnt; i++) list_add(&sde_crtc->ltm_buffers[i]->node, &sde_crtc->ltm_buf_free); spin_unlock_irqrestore(&sde_crtc->ltm_lock, irq_flags); } Loading @@ -2873,6 +2884,9 @@ static void sde_cp_ltm_hist_interrupt_cb(void *arg, int irq_idx) u64 addr = 0; int idx = -1; unsigned long irq_flags; struct sde_ltm_phase_info phase; struct sde_hw_cp_cfg hw_cfg; struct sde_hw_mixer *hw_lm; if (!sde_crtc) { DRM_ERROR("invalid sde_crtc %pK\n", sde_crtc); Loading Loading @@ -2913,11 +2927,6 @@ static void sde_cp_ltm_hist_interrupt_cb(void *arg, int irq_idx) 0); } INIT_LIST_HEAD(&sde_crtc->ltm_buf_free); INIT_LIST_HEAD(&sde_crtc->ltm_buf_busy); for (i = 0; i < sde_crtc->ltm_buffer_cnt; i++) list_add(&sde_crtc->ltm_buffers[i]->node, &sde_crtc->ltm_buf_free); spin_unlock_irqrestore(&sde_crtc->ltm_lock, irq_flags); return; } Loading Loading @@ -2965,6 +2974,30 @@ static void sde_cp_ltm_hist_interrupt_cb(void *arg, int irq_idx) ((u8 *)sde_crtc->ltm_buffers[idx]->kva + sde_crtc->ltm_buffers[idx]->offset); ltm_data->status_flag = ltm_hist_status; hw_lm = sde_crtc->mixers[0].hw_lm; if (!hw_lm) { DRM_ERROR("invalid layer mixer\n"); return; } hw_cfg.num_of_mixers = num_mixers; hw_cfg.displayh = num_mixers * hw_lm->cfg.out_width; hw_cfg.displayv = hw_lm->cfg.out_height; sde_ltm_get_phase_info(&hw_cfg, &phase); ltm_data->display_h = hw_cfg.displayh; ltm_data->display_v = hw_cfg.displayv; ltm_data->init_h[0] = phase.init_h[LTM_0]; ltm_data->init_h[1] = phase.init_h[LTM_1]; ltm_data->init_v = phase.init_v; ltm_data->inc_v = phase.inc_v; ltm_data->inc_h = phase.inc_h; ltm_data->portrait_en = phase.portrait_en; ltm_data->merge_en = phase.merge_en; ltm_data->cfg_param_01 = sde_crtc->ltm_cfg.cfg_param_01; ltm_data->cfg_param_02 = sde_crtc->ltm_cfg.cfg_param_02; ltm_data->cfg_param_03 = sde_crtc->ltm_cfg.cfg_param_03; ltm_data->cfg_param_04 = sde_crtc->ltm_cfg.cfg_param_04; sde_crtc_event_queue(&sde_crtc->base, sde_cp_notify_ltm_hist, sde_crtc->ltm_buffers[idx], true); spin_unlock_irqrestore(&sde_crtc->ltm_lock, irq_flags); Loading Loading @@ -3188,3 +3221,45 @@ int sde_cp_ltm_wb_pb_interrupt(struct drm_crtc *crtc, bool en, } return ret; } static void _sde_cp_crtc_update_ltm_roi(struct sde_crtc *sde_crtc, struct sde_hw_cp_cfg *hw_cfg) { struct drm_msm_ltm_cfg_param *cfg_param = NULL; /* disable case */ if (!hw_cfg->payload) { memset(&sde_crtc->ltm_cfg, 0, sizeof(struct drm_msm_ltm_cfg_param)); return; } if (hw_cfg->len != sizeof(struct drm_msm_ltm_cfg_param)) { DRM_ERROR("invalid size of payload len %d exp %zd\n", hw_cfg->len, sizeof(struct drm_msm_ltm_cfg_param)); return; } cfg_param = hw_cfg->payload; /* input param exceeds the display width */ if (cfg_param->cfg_param_01 + cfg_param->cfg_param_03 > hw_cfg->displayh) { DRM_DEBUG_DRIVER("invalid input = [%u,%u], displayh = %u\n", cfg_param->cfg_param_01, cfg_param->cfg_param_03, hw_cfg->displayh); /* set the roi width to max register value */ cfg_param->cfg_param_03 = 0xFFFF; } /* input param exceeds the display height */ if (cfg_param->cfg_param_02 + cfg_param->cfg_param_04 > hw_cfg->displayv) { DRM_DEBUG_DRIVER("invalid input = [%u,%u], displayv = %u\n", cfg_param->cfg_param_02, cfg_param->cfg_param_04, hw_cfg->displayv); /* set the roi height to max register value */ cfg_param->cfg_param_04 = 0xFFFF; } sde_crtc->ltm_cfg = *cfg_param; } drivers/gpu/drm/msm/sde/sde_crtc.h +1 −0 Original line number Diff line number Diff line Loading @@ -339,6 +339,7 @@ struct sde_crtc { struct list_head ltm_buf_free; struct list_head ltm_buf_busy; bool ltm_hist_en; struct drm_msm_ltm_cfg_param ltm_cfg; struct mutex ltm_buffer_lock; spinlock_t ltm_lock; }; Loading drivers/gpu/drm/msm/sde/sde_hw_dspp.c +8 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #include <drm/msm_drm_pp.h> #include "sde_hw_mdss.h" Loading Loading @@ -304,6 +304,13 @@ struct sde_hw_dspp *sde_hw_dspp_init(enum sde_dspp idx, sde_dbg_reg_register_dump_range(SDE_DBG_NAME, cfg->name, c->hw.blk_off, c->hw.blk_off + c->hw.length, c->hw.xin_id); if ((cfg->sblk->ltm.id == SDE_DSPP_LTM) && cfg->sblk->ltm.base) { sde_dbg_reg_register_dump_range(SDE_DBG_NAME, "LTM", c->hw.blk_off + cfg->sblk->ltm.base, c->hw.blk_off + cfg->sblk->ltm.base + 0xC4, c->hw.xin_id); } return c; blk_init_error: Loading drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c +6 −4 Original line number Diff line number Diff line Loading @@ -3443,19 +3443,21 @@ void reg_dmav1_setup_ltm_roiv1(struct sde_hw_dspp *ctx, void *cfg) /* input param exceeds the display width */ if (cfg_param->cfg_param_01 + cfg_param->cfg_param_03 > hw_cfg->displayh) { DRM_ERROR("invalid input param = [%u,%u], displayh = %u\n", DRM_DEBUG_DRIVER("invalid input = [%u,%u], displayh = %u\n", cfg_param->cfg_param_01, cfg_param->cfg_param_03, hw_cfg->displayh); return; /* set the roi width to max register value */ cfg_param->cfg_param_03 = 0xFFFF; } /* input param exceeds the display height */ if (cfg_param->cfg_param_02 + cfg_param->cfg_param_04 > hw_cfg->displayv) { DRM_ERROR("invalid input param = [%u,%u], displayv = %u\n", DRM_DEBUG_DRIVER("invalid input = [%u,%u], displayv = %u\n", cfg_param->cfg_param_02, cfg_param->cfg_param_04, hw_cfg->displayv); return; /* set the roi height to max register value */ cfg_param->cfg_param_04 = 0xFFFF; } roi_data[0] = ((cfg_param->cfg_param_02 & 0xFFFF) << 16) | Loading include/uapi/drm/msm_drm_pp.h +14 −0 Original line number Diff line number Diff line Loading @@ -468,12 +468,14 @@ struct drm_msm_ad4_roi_cfg { __u32 factor_out; }; #define LTM_FEATURE_DEF 1 #define LTM_DATA_SIZE_0 32 #define LTM_DATA_SIZE_1 128 #define LTM_DATA_SIZE_2 256 #define LTM_DATA_SIZE_3 33 #define LTM_BUFFER_SIZE 5 #define LTM_GUARD_BYTES 255 #define LTM_BLOCK_SIZE 2 #define LTM_STATS_SAT (1 << 1) #define LTM_STATS_MERGE_SAT (1 << 2) Loading @@ -488,6 +490,18 @@ struct drm_msm_ltm_stats_data { __u32 stats_04[LTM_DATA_SIZE_0]; __u32 stats_05[LTM_DATA_SIZE_0]; __u32 status_flag; __u32 display_h; __u32 display_v; __u32 init_h[LTM_BLOCK_SIZE]; __u32 init_v; __u32 inc_h; __u32 inc_v; __u32 portrait_en; __u32 merge_en; __u32 cfg_param_01; __u32 cfg_param_02; __u32 cfg_param_03; __u32 cfg_param_04; }; /* Loading Loading
drivers/gpu/drm/msm/sde/sde_color_processing.c +82 −7 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include "sde_hw_interrupts.h" #include "sde_core_irq.h" #include "dsi_panel.h" #include "sde_hw_color_proc_common_v4.h" struct sde_cp_node { u32 property_id; Loading Loading @@ -93,6 +94,8 @@ static void _sde_cp_crtc_disable_ltm_hist(struct sde_crtc *sde_crtc, struct sde_hw_dspp *hw_dspp, struct sde_hw_cp_cfg *hw_cfg); static void sde_cp_notify_ltm_hist(struct drm_crtc *crtc_drm, void *arg); static void sde_cp_notify_ltm_wb_pb(struct drm_crtc *crtc_drm, void *arg); static void _sde_cp_crtc_update_ltm_roi(struct sde_crtc *sde_crtc, struct sde_hw_cp_cfg *hw_cfg); #define setup_dspp_prop_install_funcs(func) \ do { \ Loading Loading @@ -539,10 +542,12 @@ static int set_ltm_roi_feature(struct sde_hw_dspp *hw_dspp, { int ret = 0; if (!hw_dspp || !hw_dspp->ops.setup_ltm_roi) if (!hw_dspp || !hw_dspp->ops.setup_ltm_roi) { ret = -EINVAL; else } else { hw_dspp->ops.setup_ltm_roi(hw_dspp, hw_cfg); _sde_cp_crtc_update_ltm_roi(hw_crtc, hw_cfg); } return ret; } Loading Loading @@ -2852,6 +2857,7 @@ static void _sde_cp_crtc_disable_ltm_hist(struct sde_crtc *sde_crtc, { unsigned long irq_flags; struct sde_hw_mixer *hw_lm = hw_cfg->mixer_info; u32 i = 0; spin_lock_irqsave(&sde_crtc->ltm_lock, irq_flags); if (!hw_lm->cfg.right_mixer && !sde_crtc->ltm_hist_en) { Loading @@ -2860,6 +2866,11 @@ static void _sde_cp_crtc_disable_ltm_hist(struct sde_crtc *sde_crtc, return; } sde_crtc->ltm_hist_en = false; INIT_LIST_HEAD(&sde_crtc->ltm_buf_free); INIT_LIST_HEAD(&sde_crtc->ltm_buf_busy); for (i = 0; i < sde_crtc->ltm_buffer_cnt; i++) list_add(&sde_crtc->ltm_buffers[i]->node, &sde_crtc->ltm_buf_free); spin_unlock_irqrestore(&sde_crtc->ltm_lock, irq_flags); } Loading @@ -2873,6 +2884,9 @@ static void sde_cp_ltm_hist_interrupt_cb(void *arg, int irq_idx) u64 addr = 0; int idx = -1; unsigned long irq_flags; struct sde_ltm_phase_info phase; struct sde_hw_cp_cfg hw_cfg; struct sde_hw_mixer *hw_lm; if (!sde_crtc) { DRM_ERROR("invalid sde_crtc %pK\n", sde_crtc); Loading Loading @@ -2913,11 +2927,6 @@ static void sde_cp_ltm_hist_interrupt_cb(void *arg, int irq_idx) 0); } INIT_LIST_HEAD(&sde_crtc->ltm_buf_free); INIT_LIST_HEAD(&sde_crtc->ltm_buf_busy); for (i = 0; i < sde_crtc->ltm_buffer_cnt; i++) list_add(&sde_crtc->ltm_buffers[i]->node, &sde_crtc->ltm_buf_free); spin_unlock_irqrestore(&sde_crtc->ltm_lock, irq_flags); return; } Loading Loading @@ -2965,6 +2974,30 @@ static void sde_cp_ltm_hist_interrupt_cb(void *arg, int irq_idx) ((u8 *)sde_crtc->ltm_buffers[idx]->kva + sde_crtc->ltm_buffers[idx]->offset); ltm_data->status_flag = ltm_hist_status; hw_lm = sde_crtc->mixers[0].hw_lm; if (!hw_lm) { DRM_ERROR("invalid layer mixer\n"); return; } hw_cfg.num_of_mixers = num_mixers; hw_cfg.displayh = num_mixers * hw_lm->cfg.out_width; hw_cfg.displayv = hw_lm->cfg.out_height; sde_ltm_get_phase_info(&hw_cfg, &phase); ltm_data->display_h = hw_cfg.displayh; ltm_data->display_v = hw_cfg.displayv; ltm_data->init_h[0] = phase.init_h[LTM_0]; ltm_data->init_h[1] = phase.init_h[LTM_1]; ltm_data->init_v = phase.init_v; ltm_data->inc_v = phase.inc_v; ltm_data->inc_h = phase.inc_h; ltm_data->portrait_en = phase.portrait_en; ltm_data->merge_en = phase.merge_en; ltm_data->cfg_param_01 = sde_crtc->ltm_cfg.cfg_param_01; ltm_data->cfg_param_02 = sde_crtc->ltm_cfg.cfg_param_02; ltm_data->cfg_param_03 = sde_crtc->ltm_cfg.cfg_param_03; ltm_data->cfg_param_04 = sde_crtc->ltm_cfg.cfg_param_04; sde_crtc_event_queue(&sde_crtc->base, sde_cp_notify_ltm_hist, sde_crtc->ltm_buffers[idx], true); spin_unlock_irqrestore(&sde_crtc->ltm_lock, irq_flags); Loading Loading @@ -3188,3 +3221,45 @@ int sde_cp_ltm_wb_pb_interrupt(struct drm_crtc *crtc, bool en, } return ret; } static void _sde_cp_crtc_update_ltm_roi(struct sde_crtc *sde_crtc, struct sde_hw_cp_cfg *hw_cfg) { struct drm_msm_ltm_cfg_param *cfg_param = NULL; /* disable case */ if (!hw_cfg->payload) { memset(&sde_crtc->ltm_cfg, 0, sizeof(struct drm_msm_ltm_cfg_param)); return; } if (hw_cfg->len != sizeof(struct drm_msm_ltm_cfg_param)) { DRM_ERROR("invalid size of payload len %d exp %zd\n", hw_cfg->len, sizeof(struct drm_msm_ltm_cfg_param)); return; } cfg_param = hw_cfg->payload; /* input param exceeds the display width */ if (cfg_param->cfg_param_01 + cfg_param->cfg_param_03 > hw_cfg->displayh) { DRM_DEBUG_DRIVER("invalid input = [%u,%u], displayh = %u\n", cfg_param->cfg_param_01, cfg_param->cfg_param_03, hw_cfg->displayh); /* set the roi width to max register value */ cfg_param->cfg_param_03 = 0xFFFF; } /* input param exceeds the display height */ if (cfg_param->cfg_param_02 + cfg_param->cfg_param_04 > hw_cfg->displayv) { DRM_DEBUG_DRIVER("invalid input = [%u,%u], displayv = %u\n", cfg_param->cfg_param_02, cfg_param->cfg_param_04, hw_cfg->displayv); /* set the roi height to max register value */ cfg_param->cfg_param_04 = 0xFFFF; } sde_crtc->ltm_cfg = *cfg_param; }
drivers/gpu/drm/msm/sde/sde_crtc.h +1 −0 Original line number Diff line number Diff line Loading @@ -339,6 +339,7 @@ struct sde_crtc { struct list_head ltm_buf_free; struct list_head ltm_buf_busy; bool ltm_hist_en; struct drm_msm_ltm_cfg_param ltm_cfg; struct mutex ltm_buffer_lock; spinlock_t ltm_lock; }; Loading
drivers/gpu/drm/msm/sde/sde_hw_dspp.c +8 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #include <drm/msm_drm_pp.h> #include "sde_hw_mdss.h" Loading Loading @@ -304,6 +304,13 @@ struct sde_hw_dspp *sde_hw_dspp_init(enum sde_dspp idx, sde_dbg_reg_register_dump_range(SDE_DBG_NAME, cfg->name, c->hw.blk_off, c->hw.blk_off + c->hw.length, c->hw.xin_id); if ((cfg->sblk->ltm.id == SDE_DSPP_LTM) && cfg->sblk->ltm.base) { sde_dbg_reg_register_dump_range(SDE_DBG_NAME, "LTM", c->hw.blk_off + cfg->sblk->ltm.base, c->hw.blk_off + cfg->sblk->ltm.base + 0xC4, c->hw.xin_id); } return c; blk_init_error: Loading
drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c +6 −4 Original line number Diff line number Diff line Loading @@ -3443,19 +3443,21 @@ void reg_dmav1_setup_ltm_roiv1(struct sde_hw_dspp *ctx, void *cfg) /* input param exceeds the display width */ if (cfg_param->cfg_param_01 + cfg_param->cfg_param_03 > hw_cfg->displayh) { DRM_ERROR("invalid input param = [%u,%u], displayh = %u\n", DRM_DEBUG_DRIVER("invalid input = [%u,%u], displayh = %u\n", cfg_param->cfg_param_01, cfg_param->cfg_param_03, hw_cfg->displayh); return; /* set the roi width to max register value */ cfg_param->cfg_param_03 = 0xFFFF; } /* input param exceeds the display height */ if (cfg_param->cfg_param_02 + cfg_param->cfg_param_04 > hw_cfg->displayv) { DRM_ERROR("invalid input param = [%u,%u], displayv = %u\n", DRM_DEBUG_DRIVER("invalid input = [%u,%u], displayv = %u\n", cfg_param->cfg_param_02, cfg_param->cfg_param_04, hw_cfg->displayv); return; /* set the roi height to max register value */ cfg_param->cfg_param_04 = 0xFFFF; } roi_data[0] = ((cfg_param->cfg_param_02 & 0xFFFF) << 16) | Loading
include/uapi/drm/msm_drm_pp.h +14 −0 Original line number Diff line number Diff line Loading @@ -468,12 +468,14 @@ struct drm_msm_ad4_roi_cfg { __u32 factor_out; }; #define LTM_FEATURE_DEF 1 #define LTM_DATA_SIZE_0 32 #define LTM_DATA_SIZE_1 128 #define LTM_DATA_SIZE_2 256 #define LTM_DATA_SIZE_3 33 #define LTM_BUFFER_SIZE 5 #define LTM_GUARD_BYTES 255 #define LTM_BLOCK_SIZE 2 #define LTM_STATS_SAT (1 << 1) #define LTM_STATS_MERGE_SAT (1 << 2) Loading @@ -488,6 +490,18 @@ struct drm_msm_ltm_stats_data { __u32 stats_04[LTM_DATA_SIZE_0]; __u32 stats_05[LTM_DATA_SIZE_0]; __u32 status_flag; __u32 display_h; __u32 display_v; __u32 init_h[LTM_BLOCK_SIZE]; __u32 init_v; __u32 inc_h; __u32 inc_v; __u32 portrait_en; __u32 merge_en; __u32 cfg_param_01; __u32 cfg_param_02; __u32 cfg_param_03; __u32 cfg_param_04; }; /* Loading