Loading drivers/gpu/drm/msm/sde/sde_color_processing.c +4 −20 Original line number Diff line number Diff line Loading @@ -526,7 +526,7 @@ static void sde_cp_crtc_install_enum_property(struct drm_crtc *crtc, } static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node, struct sde_crtc *sde_crtc, u32 last_feature) struct sde_crtc *sde_crtc) { struct sde_hw_cp_cfg hw_cfg; struct sde_hw_mixer *hw_lm; Loading @@ -541,16 +541,13 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node, hw_cfg.num_of_mixers = sde_crtc->num_mixers; hw_cfg.displayh = sde_crtc->base.mode.hdisplay; hw_cfg.displayv = sde_crtc->base.mode.vdisplay; hw_cfg.last_feature = 0; for (i = 0; i < num_mixers && !ret; i++) { hw_lm = sde_crtc->mixers[i].hw_lm; hw_dspp = sde_crtc->mixers[i].hw_dspp; hw_cfg.ctl = sde_crtc->mixers[i].hw_ctl; hw_cfg.mixer_info = hw_lm; if (i == num_mixers - 1) hw_cfg.last_feature = last_feature; else hw_cfg.last_feature = 0; switch (prop_node->feature) { case SDE_CP_CRTC_DSPP_VLUT: if (!hw_dspp || !hw_dspp->ops.setup_vlut) { Loading Loading @@ -724,7 +721,6 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc) struct sde_hw_ctl *ctl; uint32_t flush_mask = 0; u32 num_mixers = 0, i = 0; u32 num_of_features; if (!crtc || !crtc->dev) { DRM_ERROR("invalid crtc %pK dev %pK\n", crtc, Loading Loading @@ -757,15 +753,9 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc) set_dspp_flush = true; } num_of_features = 0; list_for_each_entry(prop_node, &sde_crtc->dirty_list, dirty_list) num_of_features++; list_for_each_entry_safe(prop_node, n, &sde_crtc->dirty_list, dirty_list) { num_of_features--; sde_cp_crtc_setfeature(prop_node, sde_crtc, (num_of_features == 0)); sde_cp_crtc_setfeature(prop_node, sde_crtc); /* Set the flush flag to true */ if (prop_node->is_dspp_feature) set_dspp_flush = true; Loading @@ -773,16 +763,10 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc) set_lm_flush = true; } num_of_features = 0; list_for_each_entry(prop_node, &sde_crtc->ad_dirty, dirty_list) num_of_features++; list_for_each_entry_safe(prop_node, n, &sde_crtc->ad_dirty, dirty_list) { num_of_features--; set_dspp_flush = true; sde_cp_crtc_setfeature(prop_node, sde_crtc, (num_of_features == 0)); sde_cp_crtc_setfeature(prop_node, sde_crtc); } for (i = 0; i < num_mixers; i++) { Loading drivers/gpu/drm/msm/sde/sde_crtc.c +1 −0 Original line number Diff line number Diff line Loading @@ -2459,6 +2459,7 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg) sde_plane_set_revalidate(plane, true); drm_modeset_unlock_crtc(crtc); sde_cp_crtc_suspend(crtc); } mutex_unlock(&sde_crtc->crtc_lock); Loading drivers/gpu/drm/msm/sde/sde_hw_ctl.c +6 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ #include "sde_hw_ctl.h" #include "sde_dbg.h" #include "sde_kms.h" #include "sde_reg_dma.h" #define CTL_LAYER(lm) \ (((lm) == LM_5) ? (0x024) : (((lm) - LM_0) * 0x004)) Loading Loading @@ -111,6 +112,11 @@ static u32 sde_hw_ctl_get_pending_flush(struct sde_hw_ctl *ctx) static inline void sde_hw_ctl_trigger_flush(struct sde_hw_ctl *ctx) { struct sde_hw_reg_dma_ops *ops = sde_reg_dma_get_ops(); if (ops && ops->last_command) ops->last_command(ctx, DMA_CTL_QUEUE0); SDE_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask); } Loading drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1.c +86 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ (cfg)->dma_buf->index) #define REG_DMA_DECODE_SEL 0x180AC060 #define REG_DMA_LAST_CMD 0x180AC004 #define SINGLE_REG_WRITE_OPCODE (BIT(28)) #define REL_ADDR_OPCODE (BIT(27)) #define HW_INDEX_REG_WRITE_OPCODE (BIT(28) | BIT(29)) Loading @@ -58,6 +59,7 @@ #define WRAP_MIN_SIZE 2 #define WRAP_MAX_SIZE (BIT(4) - 1) #define MAX_DWORDS_SZ (BIT(14) - 1) #define REG_DMA_HEADERS_BUFFER_SZ (sizeof(u32) * 128) typedef int (*reg_dma_internal_ops) (struct sde_reg_dma_setup_ops_cfg *cfg); Loading Loading @@ -93,17 +95,20 @@ static int validate_dma_cfg(struct sde_reg_dma_setup_ops_cfg *cfg); static int validate_write_decode_sel(struct sde_reg_dma_setup_ops_cfg *cfg); static int validate_write_reg(struct sde_reg_dma_setup_ops_cfg *cfg); static int validate_write_multi_lut_reg(struct sde_reg_dma_setup_ops_cfg *cfg); static int validate_last_cmd(struct sde_reg_dma_setup_ops_cfg *cfg); static int write_decode_sel(struct sde_reg_dma_setup_ops_cfg *cfg); static int write_single_reg(struct sde_reg_dma_setup_ops_cfg *cfg); static int write_multi_reg_index(struct sde_reg_dma_setup_ops_cfg *cfg); static int write_multi_reg_inc(struct sde_reg_dma_setup_ops_cfg *cfg); static int write_multi_lut_reg(struct sde_reg_dma_setup_ops_cfg *cfg); static int write_last_cmd(struct sde_reg_dma_setup_ops_cfg *cfg); static int reset_reg_dma_buffer_v1(struct sde_reg_dma_buffer *lut_buf); static int check_support_v1(enum sde_reg_dma_features feature, enum sde_reg_dma_blk blk, bool *is_supported); static int setup_payload_v1(struct sde_reg_dma_setup_ops_cfg *cfg); static int kick_off_v1(struct sde_reg_dma_kickoff_cfg *cfg); static int reset_v1(struct sde_hw_ctl *ctl); static int last_cmd_v1(struct sde_hw_ctl *ctl, enum sde_reg_dma_queue q); static struct sde_reg_dma_buffer *alloc_reg_dma_buf_v1(u32 size); static int dealloc_reg_dma_v1(struct sde_reg_dma_buffer *lut_buf); Loading @@ -123,6 +128,8 @@ static reg_dma_internal_ops validate_dma_op_params[REG_DMA_SETUP_OPS_MAX] = { [REG_BLK_WRITE_MULTIPLE] = validate_write_multi_lut_reg, }; static struct sde_reg_dma_buffer *last_cmd_buf; static void get_decode_sel(unsigned long blk, u32 *decode_sel) { int i = 0; Loading Loading @@ -474,6 +481,11 @@ int init_v1(struct sde_hw_reg_dma *cfg) return -EINVAL; reg_dma = cfg; if (!last_cmd_buf) { last_cmd_buf = alloc_reg_dma_buf_v1(REG_DMA_HEADERS_BUFFER_SZ); if (IS_ERR_OR_NULL(last_cmd_buf)) return -EINVAL; } reg_dma->ops.check_support = check_support_v1; reg_dma->ops.setup_payload = setup_payload_v1; reg_dma->ops.kick_off = kick_off_v1; Loading @@ -481,6 +493,7 @@ int init_v1(struct sde_hw_reg_dma *cfg) reg_dma->ops.alloc_reg_dma_buf = alloc_reg_dma_buf_v1; reg_dma->ops.dealloc_reg_dma = dealloc_reg_dma_v1; reg_dma->ops.reset_reg_dma_buf = reset_reg_dma_buffer_v1; reg_dma->ops.last_command = last_cmd_v1; reg_dma_ctl_queue_off[CTL_0] = REG_DMA_CTL0_QUEUE_0_CMD0_OFF; for (i = CTL_1; i < ARRAY_SIZE(reg_dma_ctl_queue_off); i++) Loading Loading @@ -648,3 +661,76 @@ static int reset_reg_dma_buffer_v1(struct sde_reg_dma_buffer *lut_buf) lut_buf->next_op_allowed = DECODE_SEL_OP; return 0; } static int validate_last_cmd(struct sde_reg_dma_setup_ops_cfg *cfg) { u32 remain_len, write_len; remain_len = BUFFER_SPACE_LEFT(cfg); write_len = sizeof(u32); if (remain_len < write_len) { DRM_ERROR("buffer is full sz %d needs %d bytes\n", remain_len, write_len); return -EINVAL; } return 0; } static int write_last_cmd(struct sde_reg_dma_setup_ops_cfg *cfg) { u32 *loc = NULL; loc = (u32 *)((u8 *)cfg->dma_buf->vaddr + cfg->dma_buf->index); loc[0] = REG_DMA_LAST_CMD; loc[1] = BIT(0); cfg->dma_buf->index = sizeof(u32) * 2; cfg->dma_buf->ops_completed = REG_WRITE_OP | DECODE_SEL_OP; cfg->dma_buf->next_op_allowed = REG_WRITE_OP; return 0; } static int last_cmd_v1(struct sde_hw_ctl *ctl, enum sde_reg_dma_queue q) { struct sde_reg_dma_setup_ops_cfg cfg; struct sde_reg_dma_kickoff_cfg kick_off; if (!last_cmd_buf || !ctl || q >= DMA_CTL_QUEUE_MAX) { DRM_ERROR("invalid param buf %pK ctl %pK q %d\n", last_cmd_buf, ctl, q); return -EINVAL; } cfg.dma_buf = last_cmd_buf; reset_reg_dma_buffer_v1(last_cmd_buf); if (validate_last_cmd(&cfg)) { DRM_ERROR("validate buf failed\n"); return -EINVAL; } if (write_last_cmd(&cfg)) { DRM_ERROR("write buf failed\n"); return -EINVAL; } kick_off.ctl = ctl; kick_off.queue_select = q; kick_off.trigger_mode = WRITE_IMMEDIATE; kick_off.last_command = 1; kick_off.op = REG_DMA_WRITE; kick_off.dma_buf = last_cmd_buf; if (kick_off_v1(&kick_off)) { DRM_ERROR("kick off last cmd failed\n"); return -EINVAL; } return 0; } void deinit_v1(void) { if (last_cmd_buf) dealloc_reg_dma_v1(last_cmd_buf); last_cmd_buf = NULL; } drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1.h +4 −0 Original line number Diff line number Diff line Loading @@ -20,4 +20,8 @@ */ int init_v1(struct sde_hw_reg_dma *reg_dma); /** * deinit_v1() - free up any resources allocated during the v1 reg dma init */ void deinit_v1(void); #endif /* _SDE_HW_REG_DMA_V1_H */ Loading
drivers/gpu/drm/msm/sde/sde_color_processing.c +4 −20 Original line number Diff line number Diff line Loading @@ -526,7 +526,7 @@ static void sde_cp_crtc_install_enum_property(struct drm_crtc *crtc, } static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node, struct sde_crtc *sde_crtc, u32 last_feature) struct sde_crtc *sde_crtc) { struct sde_hw_cp_cfg hw_cfg; struct sde_hw_mixer *hw_lm; Loading @@ -541,16 +541,13 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node, hw_cfg.num_of_mixers = sde_crtc->num_mixers; hw_cfg.displayh = sde_crtc->base.mode.hdisplay; hw_cfg.displayv = sde_crtc->base.mode.vdisplay; hw_cfg.last_feature = 0; for (i = 0; i < num_mixers && !ret; i++) { hw_lm = sde_crtc->mixers[i].hw_lm; hw_dspp = sde_crtc->mixers[i].hw_dspp; hw_cfg.ctl = sde_crtc->mixers[i].hw_ctl; hw_cfg.mixer_info = hw_lm; if (i == num_mixers - 1) hw_cfg.last_feature = last_feature; else hw_cfg.last_feature = 0; switch (prop_node->feature) { case SDE_CP_CRTC_DSPP_VLUT: if (!hw_dspp || !hw_dspp->ops.setup_vlut) { Loading Loading @@ -724,7 +721,6 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc) struct sde_hw_ctl *ctl; uint32_t flush_mask = 0; u32 num_mixers = 0, i = 0; u32 num_of_features; if (!crtc || !crtc->dev) { DRM_ERROR("invalid crtc %pK dev %pK\n", crtc, Loading Loading @@ -757,15 +753,9 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc) set_dspp_flush = true; } num_of_features = 0; list_for_each_entry(prop_node, &sde_crtc->dirty_list, dirty_list) num_of_features++; list_for_each_entry_safe(prop_node, n, &sde_crtc->dirty_list, dirty_list) { num_of_features--; sde_cp_crtc_setfeature(prop_node, sde_crtc, (num_of_features == 0)); sde_cp_crtc_setfeature(prop_node, sde_crtc); /* Set the flush flag to true */ if (prop_node->is_dspp_feature) set_dspp_flush = true; Loading @@ -773,16 +763,10 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc) set_lm_flush = true; } num_of_features = 0; list_for_each_entry(prop_node, &sde_crtc->ad_dirty, dirty_list) num_of_features++; list_for_each_entry_safe(prop_node, n, &sde_crtc->ad_dirty, dirty_list) { num_of_features--; set_dspp_flush = true; sde_cp_crtc_setfeature(prop_node, sde_crtc, (num_of_features == 0)); sde_cp_crtc_setfeature(prop_node, sde_crtc); } for (i = 0; i < num_mixers; i++) { Loading
drivers/gpu/drm/msm/sde/sde_crtc.c +1 −0 Original line number Diff line number Diff line Loading @@ -2459,6 +2459,7 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg) sde_plane_set_revalidate(plane, true); drm_modeset_unlock_crtc(crtc); sde_cp_crtc_suspend(crtc); } mutex_unlock(&sde_crtc->crtc_lock); Loading
drivers/gpu/drm/msm/sde/sde_hw_ctl.c +6 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ #include "sde_hw_ctl.h" #include "sde_dbg.h" #include "sde_kms.h" #include "sde_reg_dma.h" #define CTL_LAYER(lm) \ (((lm) == LM_5) ? (0x024) : (((lm) - LM_0) * 0x004)) Loading Loading @@ -111,6 +112,11 @@ static u32 sde_hw_ctl_get_pending_flush(struct sde_hw_ctl *ctx) static inline void sde_hw_ctl_trigger_flush(struct sde_hw_ctl *ctx) { struct sde_hw_reg_dma_ops *ops = sde_reg_dma_get_ops(); if (ops && ops->last_command) ops->last_command(ctx, DMA_CTL_QUEUE0); SDE_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask); } Loading
drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1.c +86 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ (cfg)->dma_buf->index) #define REG_DMA_DECODE_SEL 0x180AC060 #define REG_DMA_LAST_CMD 0x180AC004 #define SINGLE_REG_WRITE_OPCODE (BIT(28)) #define REL_ADDR_OPCODE (BIT(27)) #define HW_INDEX_REG_WRITE_OPCODE (BIT(28) | BIT(29)) Loading @@ -58,6 +59,7 @@ #define WRAP_MIN_SIZE 2 #define WRAP_MAX_SIZE (BIT(4) - 1) #define MAX_DWORDS_SZ (BIT(14) - 1) #define REG_DMA_HEADERS_BUFFER_SZ (sizeof(u32) * 128) typedef int (*reg_dma_internal_ops) (struct sde_reg_dma_setup_ops_cfg *cfg); Loading Loading @@ -93,17 +95,20 @@ static int validate_dma_cfg(struct sde_reg_dma_setup_ops_cfg *cfg); static int validate_write_decode_sel(struct sde_reg_dma_setup_ops_cfg *cfg); static int validate_write_reg(struct sde_reg_dma_setup_ops_cfg *cfg); static int validate_write_multi_lut_reg(struct sde_reg_dma_setup_ops_cfg *cfg); static int validate_last_cmd(struct sde_reg_dma_setup_ops_cfg *cfg); static int write_decode_sel(struct sde_reg_dma_setup_ops_cfg *cfg); static int write_single_reg(struct sde_reg_dma_setup_ops_cfg *cfg); static int write_multi_reg_index(struct sde_reg_dma_setup_ops_cfg *cfg); static int write_multi_reg_inc(struct sde_reg_dma_setup_ops_cfg *cfg); static int write_multi_lut_reg(struct sde_reg_dma_setup_ops_cfg *cfg); static int write_last_cmd(struct sde_reg_dma_setup_ops_cfg *cfg); static int reset_reg_dma_buffer_v1(struct sde_reg_dma_buffer *lut_buf); static int check_support_v1(enum sde_reg_dma_features feature, enum sde_reg_dma_blk blk, bool *is_supported); static int setup_payload_v1(struct sde_reg_dma_setup_ops_cfg *cfg); static int kick_off_v1(struct sde_reg_dma_kickoff_cfg *cfg); static int reset_v1(struct sde_hw_ctl *ctl); static int last_cmd_v1(struct sde_hw_ctl *ctl, enum sde_reg_dma_queue q); static struct sde_reg_dma_buffer *alloc_reg_dma_buf_v1(u32 size); static int dealloc_reg_dma_v1(struct sde_reg_dma_buffer *lut_buf); Loading @@ -123,6 +128,8 @@ static reg_dma_internal_ops validate_dma_op_params[REG_DMA_SETUP_OPS_MAX] = { [REG_BLK_WRITE_MULTIPLE] = validate_write_multi_lut_reg, }; static struct sde_reg_dma_buffer *last_cmd_buf; static void get_decode_sel(unsigned long blk, u32 *decode_sel) { int i = 0; Loading Loading @@ -474,6 +481,11 @@ int init_v1(struct sde_hw_reg_dma *cfg) return -EINVAL; reg_dma = cfg; if (!last_cmd_buf) { last_cmd_buf = alloc_reg_dma_buf_v1(REG_DMA_HEADERS_BUFFER_SZ); if (IS_ERR_OR_NULL(last_cmd_buf)) return -EINVAL; } reg_dma->ops.check_support = check_support_v1; reg_dma->ops.setup_payload = setup_payload_v1; reg_dma->ops.kick_off = kick_off_v1; Loading @@ -481,6 +493,7 @@ int init_v1(struct sde_hw_reg_dma *cfg) reg_dma->ops.alloc_reg_dma_buf = alloc_reg_dma_buf_v1; reg_dma->ops.dealloc_reg_dma = dealloc_reg_dma_v1; reg_dma->ops.reset_reg_dma_buf = reset_reg_dma_buffer_v1; reg_dma->ops.last_command = last_cmd_v1; reg_dma_ctl_queue_off[CTL_0] = REG_DMA_CTL0_QUEUE_0_CMD0_OFF; for (i = CTL_1; i < ARRAY_SIZE(reg_dma_ctl_queue_off); i++) Loading Loading @@ -648,3 +661,76 @@ static int reset_reg_dma_buffer_v1(struct sde_reg_dma_buffer *lut_buf) lut_buf->next_op_allowed = DECODE_SEL_OP; return 0; } static int validate_last_cmd(struct sde_reg_dma_setup_ops_cfg *cfg) { u32 remain_len, write_len; remain_len = BUFFER_SPACE_LEFT(cfg); write_len = sizeof(u32); if (remain_len < write_len) { DRM_ERROR("buffer is full sz %d needs %d bytes\n", remain_len, write_len); return -EINVAL; } return 0; } static int write_last_cmd(struct sde_reg_dma_setup_ops_cfg *cfg) { u32 *loc = NULL; loc = (u32 *)((u8 *)cfg->dma_buf->vaddr + cfg->dma_buf->index); loc[0] = REG_DMA_LAST_CMD; loc[1] = BIT(0); cfg->dma_buf->index = sizeof(u32) * 2; cfg->dma_buf->ops_completed = REG_WRITE_OP | DECODE_SEL_OP; cfg->dma_buf->next_op_allowed = REG_WRITE_OP; return 0; } static int last_cmd_v1(struct sde_hw_ctl *ctl, enum sde_reg_dma_queue q) { struct sde_reg_dma_setup_ops_cfg cfg; struct sde_reg_dma_kickoff_cfg kick_off; if (!last_cmd_buf || !ctl || q >= DMA_CTL_QUEUE_MAX) { DRM_ERROR("invalid param buf %pK ctl %pK q %d\n", last_cmd_buf, ctl, q); return -EINVAL; } cfg.dma_buf = last_cmd_buf; reset_reg_dma_buffer_v1(last_cmd_buf); if (validate_last_cmd(&cfg)) { DRM_ERROR("validate buf failed\n"); return -EINVAL; } if (write_last_cmd(&cfg)) { DRM_ERROR("write buf failed\n"); return -EINVAL; } kick_off.ctl = ctl; kick_off.queue_select = q; kick_off.trigger_mode = WRITE_IMMEDIATE; kick_off.last_command = 1; kick_off.op = REG_DMA_WRITE; kick_off.dma_buf = last_cmd_buf; if (kick_off_v1(&kick_off)) { DRM_ERROR("kick off last cmd failed\n"); return -EINVAL; } return 0; } void deinit_v1(void) { if (last_cmd_buf) dealloc_reg_dma_v1(last_cmd_buf); last_cmd_buf = NULL; }
drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1.h +4 −0 Original line number Diff line number Diff line Loading @@ -20,4 +20,8 @@ */ int init_v1(struct sde_hw_reg_dma *reg_dma); /** * deinit_v1() - free up any resources allocated during the v1 reg dma init */ void deinit_v1(void); #endif /* _SDE_HW_REG_DMA_V1_H */