Loading Documentation/devicetree/bindings/display/msm/sde.txt +6 −0 Original line number Diff line number Diff line Loading @@ -424,6 +424,10 @@ Optional properties: for the mixer block. Possible values: "primary" - preferred for primary display "none" - no preference on display - qcom,sde-mixer-cwb-pref: A string array indicating the preferred mixer block. for CWB. Possible values: "cwb" - preferred for cwb "none" - no preference on display - qcom,sde-ctl-display-pref: A string array indicating the preferred display type for the ctl block. Possible values: "primary" - preferred for primary display Loading Loading @@ -523,6 +527,8 @@ Example: 0x00047000 0x0004a000>; qcom,sde-mixer-display-pref = "primary", "none", "none", "none"; qcom,sde-mixer-cwb-pref = "none", "none", "cwb", "none"; qcom,sde-dspp-top-off = <0x1300>; qcom,sde-dspp-off = <0x00055000 0x00057000>; qcom,sde-dspp-ad-off = <0x24000 0x22800>; Loading drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +16 −20 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ static u32 dsi_dsc_rc_buf_thresh[] = {0x0e, 0x1c, 0x2a, 0x38, 0x46, 0x54, * Rate control - Min QP values for each ratio type in dsi_dsc_ratio_type */ static char dsi_dsc_rc_range_min_qp_1_1[][15] = { {0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 13}, {0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 12}, {0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 17}, {0, 4, 9, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 21}, }; Loading @@ -78,7 +78,7 @@ static char dsi_dsc_rc_range_min_qp_1_1_scr1[][15] = { */ static char dsi_dsc_rc_range_max_qp_1_1[][15] = { {4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 11, 12, 13, 13, 15}, {8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 15, 16, 17, 17, 19}, {4, 8, 9, 10, 11, 11, 11, 12, 13, 14, 15, 16, 17, 17, 19}, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 19, 20, 21, 21, 23}, }; Loading @@ -89,7 +89,7 @@ static char dsi_dsc_rc_range_max_qp_1_1[][15] = { static char dsi_dsc_rc_range_max_qp_1_1_scr1[][15] = { {4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13}, {8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17}, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21}, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 20, 23}, }; /* Loading Loading @@ -2062,7 +2062,6 @@ int dsi_dsc_populate_static_param(struct msm_display_dsc_info *dsc) int hrd_delay; int pre_num_extra_mux_bits, num_extra_mux_bits; int slice_bits; int target_bpp_x16; int data; int final_value, final_scale; int ratio_index, mod_offset; Loading Loading @@ -2104,7 +2103,7 @@ int dsi_dsc_populate_static_param(struct msm_display_dsc_info *dsc) } dsc->range_bpg_offset = dsi_dsc_rc_range_bpg_offset; if (bpp == 8) if (bpp <= 10) dsc->initial_offset = 6144; else dsc->initial_offset = 2048; /* bpp = 12 */ Loading @@ -2114,22 +2113,21 @@ int dsi_dsc_populate_static_param(struct msm_display_dsc_info *dsc) else mux_words_size = 48; /* bpc == 8/10 */ dsc->line_buf_depth = bpc + 1; if (bpc == 8) { dsc->line_buf_depth = 9; dsc->input_10_bits = 0; dsc->min_qp_flatness = 3; dsc->max_qp_flatness = 12; dsc->quant_incr_limit0 = 11; dsc->quant_incr_limit1 = 11; } else if (bpc == 10) { /* 10bpc */ dsc->line_buf_depth = 11; dsc->input_10_bits = 1; dsc->min_qp_flatness = 7; dsc->max_qp_flatness = 16; dsc->quant_incr_limit0 = 15; dsc->quant_incr_limit1 = 15; } else { /* 12 bpc */ dsc->line_buf_depth = 9; dsc->input_10_bits = 0; dsc->min_qp_flatness = 11; dsc->max_qp_flatness = 20; Loading @@ -2152,7 +2150,7 @@ int dsi_dsc_populate_static_param(struct msm_display_dsc_info *dsc) break; } dsc->det_thresh_flatness = 7 + 2*(bpc - 8); dsc->det_thresh_flatness = 2 << (bpc - 8); dsc->initial_xmit_delay = dsc->rc_model_size / (2 * bpp); Loading Loading @@ -2191,14 +2189,7 @@ int dsi_dsc_populate_static_param(struct msm_display_dsc_info *dsc) + num_extra_mux_bits); dsc->slice_bpg_offset = DIV_ROUND_UP(data, groups_total); /* bpp * 16 + 0.5 */ data = bpp * 16; data *= 2; data++; data /= 2; target_bpp_x16 = data; data = (dsc->initial_xmit_delay * target_bpp_x16) / 16; data = dsc->initial_xmit_delay * bpp; final_value = dsc->rc_model_size - data + num_extra_mux_bits; final_scale = 8 * dsc->rc_model_size / Loading Loading @@ -3755,14 +3746,19 @@ int dsi_panel_disable(struct dsi_panel *panel) if (!atomic_read(&panel->esd_recovery_pending)) { rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_OFF); if (rc) { pr_err("[%s] failed to send DSI_CMD_SET_OFF cmds, rc=%d\n", /* * Sending panel off commands may fail when DSI * controller is in a bad state. These failures can be * ignored since controller will go for full reset on * subsequent display enable anyway. */ pr_warn_ratelimited("[%s] failed to send DSI_CMD_SET_OFF cmds, rc=%d\n", panel->name, rc); goto error; rc = 0; } } panel->panel_initialized = false; error: mutex_unlock(&panel->panel_lock); return rc; } Loading drivers/gpu/drm/msm/msm_atomic.c +9 −4 Original line number Diff line number Diff line Loading @@ -415,6 +415,7 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev, struct msm_kms *kms = priv->kms; int bridge_enable_count = 0; int i, blank; bool splash = false; SDE_ATRACE_BEGIN("msm_enable"); for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, Loading Loading @@ -474,8 +475,11 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev, DRM_DEBUG_ATOMIC("enabling [ENCODER:%d:%s]\n", encoder->base.id, encoder->name); if (connector->state->crtc && connector->state->crtc->state->active_changed) { if (kms && kms->funcs && kms->funcs->check_for_splash) splash = kms->funcs->check_for_splash(kms); if (splash || (connector->state->crtc && connector->state->crtc->state->active_changed)) { blank = MSM_DRM_BLANK_UNBLANK; notifier_data.data = ␣ notifier_data.id = Loading Loading @@ -532,8 +536,9 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev, encoder->base.id, encoder->name); drm_bridge_enable(encoder->bridge); if (connector->state->crtc && connector->state->crtc->state->active_changed) { if (splash || (connector->state->crtc && connector->state->crtc->state->active_changed)) { DRM_DEBUG_ATOMIC("Notify unblank\n"); msm_drm_notifier_call_chain(MSM_DRM_EVENT_BLANK, ¬ifier_data); Loading drivers/gpu/drm/msm/sde/sde_crtc.c +15 −151 Original line number Diff line number Diff line Loading @@ -87,8 +87,6 @@ static struct sde_crtc_custom_events custom_events[] = { * Default value is set to 1 sec. */ #define CRTC_TIME_PERIOD_CALC_FPS_US 1000000 #define MAX_PERIODICITY 5000000 #define MAX_FRAME_COUNT 300 static inline struct sde_kms *_sde_crtc_get_kms(struct drm_crtc *crtc) { Loading Loading @@ -165,16 +163,6 @@ static void sde_crtc_calc_fps(struct sde_crtc *sde_crtc) sde_crtc->fps_info.last_sampled_time_us = current_time_us; sde_crtc->fps_info.frame_count = 0; } /** * Array indexing is based on sliding window algorithm. * sde_crtc->time_buf has a maximum capacity of MAX_FRAME_COUNT * time slots. As the count increases to MAX_FRAME_COUNT + 1, the * counter loops around and comes back to the first index to store * the next ktime. */ sde_crtc->time_buf[sde_crtc->next_time_index++] = ktime_get(); sde_crtc->next_time_index %= MAX_FRAME_COUNT; } /** Loading Loading @@ -697,131 +685,6 @@ static int _sde_debugfs_fps_status(struct inode *inode, struct file *file) inode->i_private); } static ssize_t set_fps_periodicity(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { struct drm_crtc *crtc; struct sde_crtc *sde_crtc; int res; if (!device || !buf) { SDE_ERROR("invalid input param(s)\n"); return -EAGAIN; } crtc = dev_get_drvdata(device); if (!crtc) return -EINVAL; sde_crtc = to_sde_crtc(crtc); res = kstrtou32(buf, 10, &sde_crtc->fps_info.fps_periodicity); if (res < 0) return res; if (sde_crtc->fps_info.fps_periodicity < 0 || (sde_crtc->fps_info.fps_periodicity)*1000 > MAX_PERIODICITY) sde_crtc->fps_info.fps_periodicity = CRTC_TIME_PERIOD_CALC_FPS_US; else sde_crtc->fps_info.fps_periodicity *= 1000; return count; } static ssize_t fps_periodicity_show(struct device *device, struct device_attribute *attr, char *buf) { struct drm_crtc *crtc; struct sde_crtc *sde_crtc; if (!device || !buf) { SDE_ERROR("invalid input param(s)\n"); return -EAGAIN; } crtc = dev_get_drvdata(device); if (!crtc) return -EINVAL; sde_crtc = to_sde_crtc(crtc); return scnprintf(buf, PAGE_SIZE, "%d\n", (sde_crtc->fps_info.fps_periodicity)/1000); } static ssize_t measured_fps_show(struct device *device, struct device_attribute *attr, char *buf) { struct drm_crtc *crtc; struct sde_crtc *sde_crtc; unsigned int fps_int, fps_decimal; u64 fps = 0, frame_count = 1; ktime_t current_time; int i = 0, time_index; u64 diff_us; if (!device || !buf) { SDE_ERROR("invalid input param(s)\n"); return -EAGAIN; } crtc = dev_get_drvdata(device); if (!crtc) return -EINVAL; sde_crtc = to_sde_crtc(crtc); /** * Whenever the time_index counter comes to zero upon decrementing, * it is set to the last index since it is the next index that we * should check for calculating the buftime. */ time_index = (sde_crtc->next_time_index - 1) < 0 ? MAX_FRAME_COUNT - 1 : (sde_crtc->next_time_index - 1); current_time = ktime_get(); if (sde_crtc->fps_info.fps_periodicity <= MAX_PERIODICITY) { for (; i < MAX_FRAME_COUNT; i++) { u64 ptime = (u64)ktime_to_us(current_time); u64 buftime = (u64) ktime_to_us(sde_crtc->time_buf[time_index]); if (ptime > buftime) { diff_us = (u64)ktime_us_delta(current_time, sde_crtc->time_buf[time_index]); if (diff_us >= (u64) sde_crtc->fps_info.fps_periodicity) { fps = (frame_count) * 1000000 * 10; do_div(fps, diff_us); sde_crtc->fps_info.measured_fps = (unsigned int)fps; break; } } time_index = (time_index - 1) < 0 ? (MAX_FRAME_COUNT - 1) : (time_index - 1); frame_count++; } } if (i == MAX_FRAME_COUNT) { diff_us = (u64)ktime_us_delta(current_time, sde_crtc->time_buf[time_index]); if (diff_us >= sde_crtc->fps_info.fps_periodicity) { fps = (frame_count) * 1000000 * 10; do_div(fps, diff_us); sde_crtc->fps_info.measured_fps = (unsigned int)fps; } } fps_int = (unsigned int) sde_crtc->fps_info.measured_fps; fps_decimal = do_div(fps_int, 10); return scnprintf(buf, PAGE_SIZE, "%d.%d\n", fps_int, fps_decimal); } static ssize_t vsync_event_show(struct device *device, struct device_attribute *attr, char *buf) { Loading @@ -840,13 +703,8 @@ static ssize_t vsync_event_show(struct device *device, } static DEVICE_ATTR_RO(vsync_event); static DEVICE_ATTR(measured_fps, 0444, measured_fps_show, NULL); static DEVICE_ATTR(fps_periodicity_ms, 0644, fps_periodicity_show, set_fps_periodicity); static struct attribute *sde_crtc_dev_attrs[] = { &dev_attr_vsync_event.attr, &dev_attr_measured_fps.attr, &dev_attr_fps_periodicity_ms.attr, NULL }; Loading Loading @@ -945,7 +803,6 @@ static void _sde_crtc_setup_blend_cfg(struct sde_crtc_mixer *mixer, if (fg_alpha != 0xff) { bg_alpha = fg_alpha; blend_op |= SDE_BLEND_FG_MOD_ALPHA | SDE_BLEND_FG_INV_MOD_ALPHA | SDE_BLEND_BG_MOD_ALPHA | SDE_BLEND_BG_INV_MOD_ALPHA; } else { Loading Loading @@ -3267,6 +3124,7 @@ static void _sde_crtc_setup_mixers(struct drm_crtc *crtc) } mutex_unlock(&sde_crtc->crtc_lock); _sde_crtc_check_dest_scaler_data(crtc, crtc->state); } static void _sde_crtc_setup_is_ppsplit(struct drm_crtc_state *state) Loading Loading @@ -6400,14 +6258,6 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_plane *plane) sde_crtc->enabled = false; /* Below parameters are for fps calculation for sysfs node */ sde_crtc->fps_info.fps_periodicity = CRTC_TIME_PERIOD_CALC_FPS_US; sde_crtc->fps_info.frame_count = 0; sde_crtc->time_buf = kmalloc_array(MAX_FRAME_COUNT, sizeof(sde_crtc->time_buf), GFP_KERNEL); memset(sde_crtc->time_buf, 0, sizeof(*(sde_crtc->time_buf))); sde_crtc->next_time_index = 0; INIT_LIST_HEAD(&sde_crtc->frame_event_list); INIT_LIST_HEAD(&sde_crtc->user_event_list); for (i = 0; i < ARRAY_SIZE(sde_crtc->frame_events); i++) { Loading Loading @@ -6509,6 +6359,7 @@ static int _sde_crtc_event_enable(struct sde_kms *kms, unsigned long flags; bool found = false; int ret, i = 0; bool add_event = false; crtc = to_sde_crtc(crtc_drm); spin_lock_irqsave(&crtc->spin_lock, flags); Loading Loading @@ -6558,11 +6409,24 @@ static int _sde_crtc_event_enable(struct sde_kms *kms, } INIT_LIST_HEAD(&node->irq.list); mutex_lock(&crtc->crtc_lock); ret = node->func(crtc_drm, true, &node->irq); if (!ret) { spin_lock_irqsave(&crtc->spin_lock, flags); list_add_tail(&node->list, &crtc->user_event_list); add_event = true; spin_unlock_irqrestore(&crtc->spin_lock, flags); } mutex_unlock(&crtc->crtc_lock); sde_power_resource_enable(&priv->phandle, kms->core_client, false); } if (add_event) return 0; if (!ret) { spin_lock_irqsave(&crtc->spin_lock, flags); list_add_tail(&node->list, &crtc->user_event_list); Loading drivers/gpu/drm/msm/sde/sde_crtc.h +0 −3 Original line number Diff line number Diff line Loading @@ -148,7 +148,6 @@ struct sde_crtc_fps_info { u32 frame_count; ktime_t last_sampled_time_us; u32 measured_fps; u32 fps_periodicity; }; /* Loading Loading @@ -242,7 +241,6 @@ struct sde_crtc { u64 play_count; ktime_t vblank_cb_time; ktime_t vblank_last_cb_time; ktime_t *time_buf; struct sde_crtc_fps_info fps_info; struct device *sysfs_dev; struct kernfs_node *vsync_event_sf; Loading Loading @@ -289,7 +287,6 @@ struct sde_crtc { struct list_head rp_head; u32 plane_mask_old; u32 next_time_index; /* blob for histogram data */ struct drm_property_blob *hist_blob; Loading Loading
Documentation/devicetree/bindings/display/msm/sde.txt +6 −0 Original line number Diff line number Diff line Loading @@ -424,6 +424,10 @@ Optional properties: for the mixer block. Possible values: "primary" - preferred for primary display "none" - no preference on display - qcom,sde-mixer-cwb-pref: A string array indicating the preferred mixer block. for CWB. Possible values: "cwb" - preferred for cwb "none" - no preference on display - qcom,sde-ctl-display-pref: A string array indicating the preferred display type for the ctl block. Possible values: "primary" - preferred for primary display Loading Loading @@ -523,6 +527,8 @@ Example: 0x00047000 0x0004a000>; qcom,sde-mixer-display-pref = "primary", "none", "none", "none"; qcom,sde-mixer-cwb-pref = "none", "none", "cwb", "none"; qcom,sde-dspp-top-off = <0x1300>; qcom,sde-dspp-off = <0x00055000 0x00057000>; qcom,sde-dspp-ad-off = <0x24000 0x22800>; Loading
drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +16 −20 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ static u32 dsi_dsc_rc_buf_thresh[] = {0x0e, 0x1c, 0x2a, 0x38, 0x46, 0x54, * Rate control - Min QP values for each ratio type in dsi_dsc_ratio_type */ static char dsi_dsc_rc_range_min_qp_1_1[][15] = { {0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 13}, {0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 12}, {0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 17}, {0, 4, 9, 9, 11, 11, 11, 11, 11, 11, 13, 13, 13, 15, 21}, }; Loading @@ -78,7 +78,7 @@ static char dsi_dsc_rc_range_min_qp_1_1_scr1[][15] = { */ static char dsi_dsc_rc_range_max_qp_1_1[][15] = { {4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 11, 12, 13, 13, 15}, {8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 15, 16, 17, 17, 19}, {4, 8, 9, 10, 11, 11, 11, 12, 13, 14, 15, 16, 17, 17, 19}, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 19, 20, 21, 21, 23}, }; Loading @@ -89,7 +89,7 @@ static char dsi_dsc_rc_range_max_qp_1_1[][15] = { static char dsi_dsc_rc_range_max_qp_1_1_scr1[][15] = { {4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13}, {8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17}, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 20, 21}, {12, 12, 13, 14, 15, 15, 15, 16, 17, 18, 18, 19, 19, 20, 23}, }; /* Loading Loading @@ -2062,7 +2062,6 @@ int dsi_dsc_populate_static_param(struct msm_display_dsc_info *dsc) int hrd_delay; int pre_num_extra_mux_bits, num_extra_mux_bits; int slice_bits; int target_bpp_x16; int data; int final_value, final_scale; int ratio_index, mod_offset; Loading Loading @@ -2104,7 +2103,7 @@ int dsi_dsc_populate_static_param(struct msm_display_dsc_info *dsc) } dsc->range_bpg_offset = dsi_dsc_rc_range_bpg_offset; if (bpp == 8) if (bpp <= 10) dsc->initial_offset = 6144; else dsc->initial_offset = 2048; /* bpp = 12 */ Loading @@ -2114,22 +2113,21 @@ int dsi_dsc_populate_static_param(struct msm_display_dsc_info *dsc) else mux_words_size = 48; /* bpc == 8/10 */ dsc->line_buf_depth = bpc + 1; if (bpc == 8) { dsc->line_buf_depth = 9; dsc->input_10_bits = 0; dsc->min_qp_flatness = 3; dsc->max_qp_flatness = 12; dsc->quant_incr_limit0 = 11; dsc->quant_incr_limit1 = 11; } else if (bpc == 10) { /* 10bpc */ dsc->line_buf_depth = 11; dsc->input_10_bits = 1; dsc->min_qp_flatness = 7; dsc->max_qp_flatness = 16; dsc->quant_incr_limit0 = 15; dsc->quant_incr_limit1 = 15; } else { /* 12 bpc */ dsc->line_buf_depth = 9; dsc->input_10_bits = 0; dsc->min_qp_flatness = 11; dsc->max_qp_flatness = 20; Loading @@ -2152,7 +2150,7 @@ int dsi_dsc_populate_static_param(struct msm_display_dsc_info *dsc) break; } dsc->det_thresh_flatness = 7 + 2*(bpc - 8); dsc->det_thresh_flatness = 2 << (bpc - 8); dsc->initial_xmit_delay = dsc->rc_model_size / (2 * bpp); Loading Loading @@ -2191,14 +2189,7 @@ int dsi_dsc_populate_static_param(struct msm_display_dsc_info *dsc) + num_extra_mux_bits); dsc->slice_bpg_offset = DIV_ROUND_UP(data, groups_total); /* bpp * 16 + 0.5 */ data = bpp * 16; data *= 2; data++; data /= 2; target_bpp_x16 = data; data = (dsc->initial_xmit_delay * target_bpp_x16) / 16; data = dsc->initial_xmit_delay * bpp; final_value = dsc->rc_model_size - data + num_extra_mux_bits; final_scale = 8 * dsc->rc_model_size / Loading Loading @@ -3755,14 +3746,19 @@ int dsi_panel_disable(struct dsi_panel *panel) if (!atomic_read(&panel->esd_recovery_pending)) { rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_OFF); if (rc) { pr_err("[%s] failed to send DSI_CMD_SET_OFF cmds, rc=%d\n", /* * Sending panel off commands may fail when DSI * controller is in a bad state. These failures can be * ignored since controller will go for full reset on * subsequent display enable anyway. */ pr_warn_ratelimited("[%s] failed to send DSI_CMD_SET_OFF cmds, rc=%d\n", panel->name, rc); goto error; rc = 0; } } panel->panel_initialized = false; error: mutex_unlock(&panel->panel_lock); return rc; } Loading
drivers/gpu/drm/msm/msm_atomic.c +9 −4 Original line number Diff line number Diff line Loading @@ -415,6 +415,7 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev, struct msm_kms *kms = priv->kms; int bridge_enable_count = 0; int i, blank; bool splash = false; SDE_ATRACE_BEGIN("msm_enable"); for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, Loading Loading @@ -474,8 +475,11 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev, DRM_DEBUG_ATOMIC("enabling [ENCODER:%d:%s]\n", encoder->base.id, encoder->name); if (connector->state->crtc && connector->state->crtc->state->active_changed) { if (kms && kms->funcs && kms->funcs->check_for_splash) splash = kms->funcs->check_for_splash(kms); if (splash || (connector->state->crtc && connector->state->crtc->state->active_changed)) { blank = MSM_DRM_BLANK_UNBLANK; notifier_data.data = ␣ notifier_data.id = Loading Loading @@ -532,8 +536,9 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev, encoder->base.id, encoder->name); drm_bridge_enable(encoder->bridge); if (connector->state->crtc && connector->state->crtc->state->active_changed) { if (splash || (connector->state->crtc && connector->state->crtc->state->active_changed)) { DRM_DEBUG_ATOMIC("Notify unblank\n"); msm_drm_notifier_call_chain(MSM_DRM_EVENT_BLANK, ¬ifier_data); Loading
drivers/gpu/drm/msm/sde/sde_crtc.c +15 −151 Original line number Diff line number Diff line Loading @@ -87,8 +87,6 @@ static struct sde_crtc_custom_events custom_events[] = { * Default value is set to 1 sec. */ #define CRTC_TIME_PERIOD_CALC_FPS_US 1000000 #define MAX_PERIODICITY 5000000 #define MAX_FRAME_COUNT 300 static inline struct sde_kms *_sde_crtc_get_kms(struct drm_crtc *crtc) { Loading Loading @@ -165,16 +163,6 @@ static void sde_crtc_calc_fps(struct sde_crtc *sde_crtc) sde_crtc->fps_info.last_sampled_time_us = current_time_us; sde_crtc->fps_info.frame_count = 0; } /** * Array indexing is based on sliding window algorithm. * sde_crtc->time_buf has a maximum capacity of MAX_FRAME_COUNT * time slots. As the count increases to MAX_FRAME_COUNT + 1, the * counter loops around and comes back to the first index to store * the next ktime. */ sde_crtc->time_buf[sde_crtc->next_time_index++] = ktime_get(); sde_crtc->next_time_index %= MAX_FRAME_COUNT; } /** Loading Loading @@ -697,131 +685,6 @@ static int _sde_debugfs_fps_status(struct inode *inode, struct file *file) inode->i_private); } static ssize_t set_fps_periodicity(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { struct drm_crtc *crtc; struct sde_crtc *sde_crtc; int res; if (!device || !buf) { SDE_ERROR("invalid input param(s)\n"); return -EAGAIN; } crtc = dev_get_drvdata(device); if (!crtc) return -EINVAL; sde_crtc = to_sde_crtc(crtc); res = kstrtou32(buf, 10, &sde_crtc->fps_info.fps_periodicity); if (res < 0) return res; if (sde_crtc->fps_info.fps_periodicity < 0 || (sde_crtc->fps_info.fps_periodicity)*1000 > MAX_PERIODICITY) sde_crtc->fps_info.fps_periodicity = CRTC_TIME_PERIOD_CALC_FPS_US; else sde_crtc->fps_info.fps_periodicity *= 1000; return count; } static ssize_t fps_periodicity_show(struct device *device, struct device_attribute *attr, char *buf) { struct drm_crtc *crtc; struct sde_crtc *sde_crtc; if (!device || !buf) { SDE_ERROR("invalid input param(s)\n"); return -EAGAIN; } crtc = dev_get_drvdata(device); if (!crtc) return -EINVAL; sde_crtc = to_sde_crtc(crtc); return scnprintf(buf, PAGE_SIZE, "%d\n", (sde_crtc->fps_info.fps_periodicity)/1000); } static ssize_t measured_fps_show(struct device *device, struct device_attribute *attr, char *buf) { struct drm_crtc *crtc; struct sde_crtc *sde_crtc; unsigned int fps_int, fps_decimal; u64 fps = 0, frame_count = 1; ktime_t current_time; int i = 0, time_index; u64 diff_us; if (!device || !buf) { SDE_ERROR("invalid input param(s)\n"); return -EAGAIN; } crtc = dev_get_drvdata(device); if (!crtc) return -EINVAL; sde_crtc = to_sde_crtc(crtc); /** * Whenever the time_index counter comes to zero upon decrementing, * it is set to the last index since it is the next index that we * should check for calculating the buftime. */ time_index = (sde_crtc->next_time_index - 1) < 0 ? MAX_FRAME_COUNT - 1 : (sde_crtc->next_time_index - 1); current_time = ktime_get(); if (sde_crtc->fps_info.fps_periodicity <= MAX_PERIODICITY) { for (; i < MAX_FRAME_COUNT; i++) { u64 ptime = (u64)ktime_to_us(current_time); u64 buftime = (u64) ktime_to_us(sde_crtc->time_buf[time_index]); if (ptime > buftime) { diff_us = (u64)ktime_us_delta(current_time, sde_crtc->time_buf[time_index]); if (diff_us >= (u64) sde_crtc->fps_info.fps_periodicity) { fps = (frame_count) * 1000000 * 10; do_div(fps, diff_us); sde_crtc->fps_info.measured_fps = (unsigned int)fps; break; } } time_index = (time_index - 1) < 0 ? (MAX_FRAME_COUNT - 1) : (time_index - 1); frame_count++; } } if (i == MAX_FRAME_COUNT) { diff_us = (u64)ktime_us_delta(current_time, sde_crtc->time_buf[time_index]); if (diff_us >= sde_crtc->fps_info.fps_periodicity) { fps = (frame_count) * 1000000 * 10; do_div(fps, diff_us); sde_crtc->fps_info.measured_fps = (unsigned int)fps; } } fps_int = (unsigned int) sde_crtc->fps_info.measured_fps; fps_decimal = do_div(fps_int, 10); return scnprintf(buf, PAGE_SIZE, "%d.%d\n", fps_int, fps_decimal); } static ssize_t vsync_event_show(struct device *device, struct device_attribute *attr, char *buf) { Loading @@ -840,13 +703,8 @@ static ssize_t vsync_event_show(struct device *device, } static DEVICE_ATTR_RO(vsync_event); static DEVICE_ATTR(measured_fps, 0444, measured_fps_show, NULL); static DEVICE_ATTR(fps_periodicity_ms, 0644, fps_periodicity_show, set_fps_periodicity); static struct attribute *sde_crtc_dev_attrs[] = { &dev_attr_vsync_event.attr, &dev_attr_measured_fps.attr, &dev_attr_fps_periodicity_ms.attr, NULL }; Loading Loading @@ -945,7 +803,6 @@ static void _sde_crtc_setup_blend_cfg(struct sde_crtc_mixer *mixer, if (fg_alpha != 0xff) { bg_alpha = fg_alpha; blend_op |= SDE_BLEND_FG_MOD_ALPHA | SDE_BLEND_FG_INV_MOD_ALPHA | SDE_BLEND_BG_MOD_ALPHA | SDE_BLEND_BG_INV_MOD_ALPHA; } else { Loading Loading @@ -3267,6 +3124,7 @@ static void _sde_crtc_setup_mixers(struct drm_crtc *crtc) } mutex_unlock(&sde_crtc->crtc_lock); _sde_crtc_check_dest_scaler_data(crtc, crtc->state); } static void _sde_crtc_setup_is_ppsplit(struct drm_crtc_state *state) Loading Loading @@ -6400,14 +6258,6 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_plane *plane) sde_crtc->enabled = false; /* Below parameters are for fps calculation for sysfs node */ sde_crtc->fps_info.fps_periodicity = CRTC_TIME_PERIOD_CALC_FPS_US; sde_crtc->fps_info.frame_count = 0; sde_crtc->time_buf = kmalloc_array(MAX_FRAME_COUNT, sizeof(sde_crtc->time_buf), GFP_KERNEL); memset(sde_crtc->time_buf, 0, sizeof(*(sde_crtc->time_buf))); sde_crtc->next_time_index = 0; INIT_LIST_HEAD(&sde_crtc->frame_event_list); INIT_LIST_HEAD(&sde_crtc->user_event_list); for (i = 0; i < ARRAY_SIZE(sde_crtc->frame_events); i++) { Loading Loading @@ -6509,6 +6359,7 @@ static int _sde_crtc_event_enable(struct sde_kms *kms, unsigned long flags; bool found = false; int ret, i = 0; bool add_event = false; crtc = to_sde_crtc(crtc_drm); spin_lock_irqsave(&crtc->spin_lock, flags); Loading Loading @@ -6558,11 +6409,24 @@ static int _sde_crtc_event_enable(struct sde_kms *kms, } INIT_LIST_HEAD(&node->irq.list); mutex_lock(&crtc->crtc_lock); ret = node->func(crtc_drm, true, &node->irq); if (!ret) { spin_lock_irqsave(&crtc->spin_lock, flags); list_add_tail(&node->list, &crtc->user_event_list); add_event = true; spin_unlock_irqrestore(&crtc->spin_lock, flags); } mutex_unlock(&crtc->crtc_lock); sde_power_resource_enable(&priv->phandle, kms->core_client, false); } if (add_event) return 0; if (!ret) { spin_lock_irqsave(&crtc->spin_lock, flags); list_add_tail(&node->list, &crtc->user_event_list); Loading
drivers/gpu/drm/msm/sde/sde_crtc.h +0 −3 Original line number Diff line number Diff line Loading @@ -148,7 +148,6 @@ struct sde_crtc_fps_info { u32 frame_count; ktime_t last_sampled_time_us; u32 measured_fps; u32 fps_periodicity; }; /* Loading Loading @@ -242,7 +241,6 @@ struct sde_crtc { u64 play_count; ktime_t vblank_cb_time; ktime_t vblank_last_cb_time; ktime_t *time_buf; struct sde_crtc_fps_info fps_info; struct device *sysfs_dev; struct kernfs_node *vsync_event_sf; Loading Loading @@ -289,7 +287,6 @@ struct sde_crtc { struct list_head rp_head; u32 plane_mask_old; u32 next_time_index; /* blob for histogram data */ struct drm_property_blob *hist_blob; Loading