Loading drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c +33 −23 Original line number Diff line number Diff line Loading @@ -840,21 +840,24 @@ int dsi_ctrl_pixel_format_to_bpp(enum dsi_pixel_format dst_format) } static int dsi_ctrl_update_link_freqs(struct dsi_ctrl *dsi_ctrl, struct dsi_host_config *config, void *clk_handle) struct dsi_host_config *config, void *clk_handle, struct dsi_display_mode *mode) { int rc = 0; u32 num_of_lanes = 0; u32 bpp; u64 refresh_rate = TICKS_IN_MICRO_SECOND; u32 bpp, frame_time_us; u64 h_period, v_period, bit_rate, pclk_rate, bit_rate_per_lane, byte_clk_rate, byte_intf_clk_rate; struct dsi_host_common_cfg *host_cfg = &config->common_config; struct dsi_split_link_config *split_link = &host_cfg->split_link; struct dsi_mode_info *timing = &config->video_timing; u32 bits_per_symbol = 16, num_of_symbols = 7; /* For Cphy */ u64 dsi_transfer_time_us = mode->priv_info->dsi_transfer_time_us; u64 min_dsi_clk_hz = mode->priv_info->min_dsi_clk_hz; /* Get bits per pxl in desitnation format */ /* Get bits per pxl in desitination format */ bpp = dsi_ctrl_pixel_format_to_bpp(host_cfg->dst_format); frame_time_us = mult_frac(1000, 1000, (timing->refresh_rate)); if (host_cfg->data_lanes & DSI_DATA_LANE_0) num_of_lanes++; Loading @@ -868,25 +871,20 @@ static int dsi_ctrl_update_link_freqs(struct dsi_ctrl *dsi_ctrl, if (split_link->split_link_enabled) num_of_lanes = split_link->lanes_per_sublink; if (config->bit_clk_rate_hz_override == 0) { if (config->panel_mode == DSI_OP_CMD_MODE) { h_period = DSI_H_ACTIVE_DSC(timing); h_period += timing->overlap_pixels; v_period = timing->v_active; config->common_config.num_data_lanes = num_of_lanes; config->common_config.bpp = bpp; do_div(refresh_rate, timing->mdp_transfer_time_us); if (config->bit_clk_rate_hz_override != 0) { bit_rate = config->bit_clk_rate_hz_override * num_of_lanes; } else if (config->panel_mode == DSI_OP_CMD_MODE) { /* Calculate the bit rate needed to match dsi transfer time */ bit_rate = min_dsi_clk_hz * frame_time_us; do_div(bit_rate, dsi_transfer_time_us); bit_rate = bit_rate * num_of_lanes; } else { h_period = DSI_H_TOTAL_DSC(timing); v_period = DSI_V_TOTAL(timing); refresh_rate = timing->refresh_rate; } bit_rate = h_period * v_period * refresh_rate * bpp; } else { bit_rate = config->bit_clk_rate_hz_override * num_of_lanes; if (host_cfg->phy_type == DSI_PHY_TYPE_CPHY) { bit_rate *= bits_per_symbol; do_div(bit_rate, num_of_symbols); } bit_rate = h_period * v_period * timing->refresh_rate * bpp; } pclk_rate = bit_rate; Loading Loading @@ -1748,7 +1746,7 @@ static int dsi_enable_io_clamp(struct dsi_ctrl *dsi_ctrl, static int dsi_ctrl_dts_parse(struct dsi_ctrl *dsi_ctrl, struct device_node *of_node) { u32 index = 0; u32 index = 0, frame_threshold_time_us = 0; int rc = 0; if (!dsi_ctrl || !of_node) { Loading Loading @@ -1777,6 +1775,15 @@ static int dsi_ctrl_dts_parse(struct dsi_ctrl *dsi_ctrl, dsi_ctrl->split_link_supported = of_property_read_bool(of_node, "qcom,split-link-supported"); rc = of_property_read_u32(of_node, "frame-threshold-time-us", &frame_threshold_time_us); if (rc) { pr_debug("frame-threshold-time not specified, defaulting\n"); frame_threshold_time_us = 2666; } dsi_ctrl->frame_threshold_time_us = frame_threshold_time_us; return 0; } Loading Loading @@ -2935,6 +2942,7 @@ int dsi_ctrl_host_deinit(struct dsi_ctrl *dsi_ctrl) * dsi_ctrl_update_host_config() - update dsi host configuration * @dsi_ctrl: DSI controller handle. * @config: DSI host configuration. * @mode: DSI host mode selected. * @flags: dsi_mode_flags modifying the behavior * * Updates driver with new Host configuration to use for host initialization. Loading @@ -2945,6 +2953,7 @@ int dsi_ctrl_host_deinit(struct dsi_ctrl *dsi_ctrl) */ int dsi_ctrl_update_host_config(struct dsi_ctrl *ctrl, struct dsi_host_config *config, struct dsi_display_mode *mode, int flags, void *clk_handle) { int rc = 0; Loading @@ -2968,7 +2977,8 @@ int dsi_ctrl_update_host_config(struct dsi_ctrl *ctrl, * for dynamic clk switch case link frequence would * be updated dsi_display_dynamic_clk_switch(). */ rc = dsi_ctrl_update_link_freqs(ctrl, config, clk_handle); rc = dsi_ctrl_update_link_freqs(ctrl, config, clk_handle, mode); if (rc) { pr_err("[%s] failed to update link frequencies, rc=%d\n", ctrl->name, rc); Loading drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h +8 −1 Original line number Diff line number Diff line /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -230,6 +230,9 @@ struct dsi_ctrl_interrupts { * @debugfs_root: Root for debugfs entries. * @misr_enable: Frame MISR enable/disable * @misr_cache: Cached Frame MISR value * @frame_threshold_time_us: Frame threshold time in microseconds, where * dsi data lane will be idle i.e from pingpong done to * next TE for command mode. * @phy_isolation_enabled: A boolean property allows to isolate the phy from * dsi controller and run only dsi controller. * @null_insertion_enabled: A boolean property to allow dsi controller to Loading Loading @@ -282,6 +285,8 @@ struct dsi_ctrl { bool misr_enable; u32 misr_cache; u32 frame_threshold_time_us; /* Check for spurious interrupts */ unsigned long jiffies_start; unsigned int error_interrupt_count; Loading Loading @@ -352,6 +357,7 @@ int dsi_ctrl_validate_timing(struct dsi_ctrl *dsi_ctrl, * dsi_ctrl_update_host_config() - update dsi host configuration * @dsi_ctrl: DSI controller handle. * @config: DSI host configuration. * @mode: DSI host mode selected. * @flags: dsi_mode_flags modifying the behavior * @clk_handle: Clock handle for DSI clocks * Loading @@ -363,6 +369,7 @@ int dsi_ctrl_validate_timing(struct dsi_ctrl *dsi_ctrl, */ int dsi_ctrl_update_host_config(struct dsi_ctrl *dsi_ctrl, struct dsi_host_config *config, struct dsi_display_mode *mode, int flags, void *clk_handle); /** Loading drivers/gpu/drm/msm/dsi-staging/dsi_defs.h +12 −0 Original line number Diff line number Diff line Loading @@ -410,8 +410,10 @@ struct dsi_panel_cmd_set { * @v_sync_polarity: Polarity of VSYNC (false is active low). * @refresh_rate: Refresh rate in Hz. * @clk_rate_hz: DSI bit clock rate per lane in Hz. * @min_dsi_clk_hz: Min DSI bit clock to transfer in vsync time. * @mdp_transfer_time_us: Specifies the mdp transfer time for command mode * panels in microseconds. * @dsi_transfer_time_us: Specifies dsi transfer time for command mode. * @overlap_pixels: overlap pixels for certain panels. * @dsc_enabled: DSC compression enabled. * @dsc: DSC compression configuration. Loading @@ -433,7 +435,9 @@ struct dsi_mode_info { u32 refresh_rate; u64 clk_rate_hz; u64 min_dsi_clk_hz; u32 mdp_transfer_time_us; u32 dsi_transfer_time_us; u32 overlap_pixels; bool dsc_enabled; struct msm_display_dsc_info *dsc; Loading @@ -456,6 +460,8 @@ struct dsi_split_link_config { * struct dsi_host_common_cfg - Host configuration common to video and cmd mode * @dst_format: Destination pixel format. * @data_lanes: Physical data lanes to be enabled. * @num_data_lanes: Number of physical data lanes. * @bpp: Number of bits per pixel. * @en_crc_check: Enable CRC checks. * @en_ecc_check: Enable ECC checks. * @te_mode: Source for TE signalling. Loading Loading @@ -485,6 +491,8 @@ struct dsi_split_link_config { struct dsi_host_common_cfg { enum dsi_pixel_format dst_format; enum dsi_data_lanes data_lanes; u8 num_data_lanes; u8 bpp; bool en_crc_check; bool en_ecc_check; enum dsi_te_mode te_mode; Loading Loading @@ -589,7 +597,9 @@ struct dsi_host_config { * @panel_prefill_lines: Panel prefill lines for RSC * @mdp_transfer_time_us: Specifies the mdp transfer time for command mode * panels in microseconds. * @dsi_transfer_time_us: Specifies the dsi transfer time for cmd panels. * @clk_rate_hz: DSI bit clock per lane in hz. * @min_dsi_clk_hz: Min dsi clk per lane to transfer frame in vsync time. * @overlap_pixels: overlap pixels for certain panels. * @topology: Topology selected for the panel * @dsc: DSC compression info Loading @@ -606,7 +616,9 @@ struct dsi_display_mode_priv_info { u32 panel_jitter_denom; u32 panel_prefill_lines; u32 mdp_transfer_time_us; u32 dsi_transfer_time_us; u64 clk_rate_hz; u64 min_dsi_clk_hz; u32 overlap_pixels; struct msm_display_topology topology; Loading drivers/gpu/drm/msm/dsi-staging/dsi_display.c +29 −2 Original line number Diff line number Diff line Loading @@ -4570,7 +4570,7 @@ static int dsi_display_set_mode_sub(struct dsi_display *display, display_for_each_ctrl(i, display) { ctrl = &display->ctrl[i]; rc = dsi_ctrl_update_host_config(ctrl->ctrl, &display->config, mode->dsi_mode_flags, &display->config, mode, mode->dsi_mode_flags, display->dsi_clk_handle); if (rc) { pr_err("failed to update ctrl config\n"); Loading Loading @@ -4618,7 +4618,8 @@ static int dsi_display_set_mode_sub(struct dsi_display *display, display_for_each_ctrl(i, display) { ctrl = &display->ctrl[i]; rc = dsi_ctrl_update_host_config(ctrl->ctrl, &display->config, mode->dsi_mode_flags, display->dsi_clk_handle); mode, mode->dsi_mode_flags, display->dsi_clk_handle); if (rc) { pr_err("[%s] failed to update ctrl config, rc=%d\n", display->name, rc); Loading Loading @@ -6266,6 +6267,7 @@ int dsi_display_get_modes(struct dsi_display *display, struct dsi_display_mode **out_modes) { struct dsi_dfps_capabilities dfps_caps; struct dsi_display_ctrl *ctrl; struct dsi_host_common_cfg *host = &display->panel->host_config; bool is_split_link, is_cmd_mode; u32 num_dfps_rates, timing_mode_count, display_mode_count; Loading @@ -6279,6 +6281,7 @@ int dsi_display_get_modes(struct dsi_display *display, } *out_modes = NULL; ctrl = &display->ctrl[0]; mutex_lock(&display->display_lock); Loading Loading @@ -6308,6 +6311,7 @@ int dsi_display_get_modes(struct dsi_display *display, for (mode_idx = 0; mode_idx < timing_mode_count; mode_idx++) { struct dsi_display_mode display_mode; int topology_override = NO_OVERRIDE; u32 frame_threshold_us = ctrl->ctrl->frame_threshold_time_us; if (display->cmdline_timing == mode_idx) topology_override = display->cmdline_topology; Loading @@ -6328,6 +6332,22 @@ int dsi_display_get_modes(struct dsi_display *display, num_dfps_rates = ((!dfps_caps.dfps_support || is_cmd_mode) ? 1 : dfps_caps.dfps_list_len); /* Calculate dsi frame transfer time */ if (is_cmd_mode) { dsi_panel_calc_dsi_transfer_time( &display->panel->host_config, &display_mode, frame_threshold_us); display_mode.priv_info->dsi_transfer_time_us = display_mode.timing.dsi_transfer_time_us; display_mode.priv_info->min_dsi_clk_hz = display_mode.timing.min_dsi_clk_hz; display_mode.priv_info->mdp_transfer_time_us = display_mode.priv_info->dsi_transfer_time_us; display_mode.timing.mdp_transfer_time_us = display_mode.timing.dsi_transfer_time_us; } is_split_link = host->split_link.split_link_enabled; sublinks_count = host->split_link.num_sublinks; if (is_split_link && sublinks_count > 1) { Loading Loading @@ -6656,6 +6676,7 @@ int dsi_display_set_mode(struct dsi_display *display, { int rc = 0; struct dsi_display_mode adj_mode; struct dsi_mode_info timing; if (!display || !mode || !display->panel) { pr_err("Invalid params\n"); Loading @@ -6665,6 +6686,7 @@ int dsi_display_set_mode(struct dsi_display *display, mutex_lock(&display->display_lock); adj_mode = *mode; timing = adj_mode.timing; adjust_timing_by_ctrl_count(display, &adj_mode); /*For dynamic DSI setting, use specified clock rate */ Loading Loading @@ -6692,6 +6714,11 @@ int dsi_display_set_mode(struct dsi_display *display, } } pr_info("mdp_transfer_time_us=%d us\n", adj_mode.priv_info->mdp_transfer_time_us); pr_info("hactive= %d, vactive= %d, fps=%d", timing.h_active, timing.v_active, timing.refresh_rate); memcpy(display->panel->cur_mode, &adj_mode, sizeof(adj_mode)); error: mutex_unlock(&display->display_lock); Loading drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +91 −20 Original line number Diff line number Diff line Loading @@ -35,8 +35,6 @@ #define DSI_PANEL_DEFAULT_LABEL "Default dsi panel" #define DEFAULT_MDP_TRANSFER_TIME 14000 #define DEFAULT_PANEL_JITTER_NUMERATOR 2 #define DEFAULT_PANEL_JITTER_DENOMINATOR 1 #define DEFAULT_PANEL_JITTER_ARRAY_SIZE 2 Loading Loading @@ -851,7 +849,7 @@ static int dsi_panel_parse_timing(struct dsi_mode_info *mode, &mode->mdp_transfer_time_us); if (rc) { pr_debug("fallback to default mdp-transfer-time-us\n"); mode->mdp_transfer_time_us = DEFAULT_MDP_TRANSFER_TIME; mode->mdp_transfer_time_us = 0; } display_mode->priv_info->mdp_transfer_time_us = mode->mdp_transfer_time_us; Loading Loading @@ -967,6 +965,8 @@ static int dsi_panel_parse_pixel_format(struct dsi_host_common_cfg *host, return rc; } host->bpp = bpp; switch (bpp) { case 3: fmt = DSI_PIXEL_FORMAT_RGB111; Loading Loading @@ -1007,6 +1007,7 @@ static int dsi_panel_parse_lane_states(struct dsi_host_common_cfg *host, { int rc = 0; bool lane_enabled; u32 num_of_lanes = 0; lane_enabled = utils->read_bool(utils->data, "qcom,mdss-dsi-lane-0-state"); Loading @@ -1024,6 +1025,17 @@ static int dsi_panel_parse_lane_states(struct dsi_host_common_cfg *host, "qcom,mdss-dsi-lane-3-state"); host->data_lanes |= (lane_enabled ? DSI_DATA_LANE_3 : 0); if (host->data_lanes & DSI_DATA_LANE_0) num_of_lanes++; if (host->data_lanes & DSI_DATA_LANE_1) num_of_lanes++; if (host->data_lanes & DSI_DATA_LANE_2) num_of_lanes++; if (host->data_lanes & DSI_DATA_LANE_3) num_of_lanes++; host->num_data_lanes = num_of_lanes; if (host->data_lanes == 0) { pr_err("[%s] No data lanes are enabled, rc=%d\n", name, rc); rc = -EINVAL; Loading Loading @@ -2543,9 +2555,6 @@ static int dsi_panel_parse_phy_timing(struct dsi_display_mode *mode, u32 len, i; int rc = 0; struct dsi_display_mode_priv_info *priv_info; u64 h_period, v_period; u64 refresh_rate = TICKS_IN_MICRO_SECOND; struct dsi_mode_info *timing = NULL; u64 pixel_clk_khz; if (!mode || !mode->priv_info) Loading @@ -2569,21 +2578,18 @@ static int dsi_panel_parse_phy_timing(struct dsi_display_mode *mode, priv_info->phy_timing_len = len; }; timing = &mode->timing; if (panel_mode == DSI_OP_CMD_MODE) { h_period = DSI_H_ACTIVE_DSC(timing); v_period = timing->v_active; do_div(refresh_rate, priv_info->mdp_transfer_time_us); } else { h_period = DSI_H_TOTAL_DSC(timing); v_period = DSI_V_TOTAL(timing); refresh_rate = timing->refresh_rate; } pixel_clk_khz = h_period * v_period * refresh_rate; if (panel_mode == DSI_OP_VIDEO_MODE) { /* * For command mode we update the pclk as part of * function dsi_panel_calc_dsi_transfer_time( ) * as we set it based on dsi clock or mdp transfer time. */ pixel_clk_khz = (DSI_H_TOTAL_DSC(&mode->timing) * DSI_V_TOTAL(&mode->timing) * mode->timing.refresh_rate); do_div(pixel_clk_khz, 1000); mode->pixel_clk_khz = pixel_clk_khz; } return rc; } Loading Loading @@ -3616,6 +3622,71 @@ void dsi_panel_put_mode(struct dsi_display_mode *mode) kfree(mode->priv_info); } void dsi_panel_calc_dsi_transfer_time(struct dsi_host_common_cfg *config, struct dsi_display_mode *mode, u32 frame_threshold_us) { u32 frame_time_us, nslices; u64 min_bitclk_hz, total_active_pixels, bits_per_line, pclk_rate_hz, dsi_transfer_time_us, pixel_clk_khz; struct msm_display_dsc_info *dsc = mode->timing.dsc; struct dsi_mode_info *timing = &mode->timing; struct dsi_display_mode *display_mode; /* Packet overlead in bits,2 bytes header + 2 bytes checksum * + 1 byte dcs data command. */ const u32 packet_overhead = 56; display_mode = container_of(timing, struct dsi_display_mode, timing); frame_time_us = mult_frac(1000, 1000, (timing->refresh_rate)); if (timing->dsc_enabled) { nslices = (timing->h_active)/(dsc->slice_width); /* (slice width x bit-per-pixel + packet overhead) x * number of slices x height x fps / lane */ bits_per_line = ((dsc->slice_width * dsc->bpp) + packet_overhead) * nslices; bits_per_line = bits_per_line / (config->num_data_lanes); min_bitclk_hz = (bits_per_line * timing->v_active * timing->refresh_rate); } else { total_active_pixels = ((DSI_H_ACTIVE_DSC(timing) * timing->v_active)); /* calculate the actual bitclk needed to transfer the frame */ min_bitclk_hz = (total_active_pixels * (timing->refresh_rate) * (config->bpp)); do_div(min_bitclk_hz, config->num_data_lanes); } timing->min_dsi_clk_hz = min_bitclk_hz; if (timing->clk_rate_hz) { /* adjust the transfer time proportionately for bit clk*/ dsi_transfer_time_us = frame_time_us * min_bitclk_hz; do_div(dsi_transfer_time_us, timing->clk_rate_hz); timing->dsi_transfer_time_us = dsi_transfer_time_us; } else if (mode->priv_info->mdp_transfer_time_us) { timing->dsi_transfer_time_us = mode->priv_info->mdp_transfer_time_us; } else { timing->dsi_transfer_time_us = frame_time_us - frame_threshold_us; } /* Calculate pclk_khz to update modeinfo */ pclk_rate_hz = min_bitclk_hz * frame_time_us; do_div(pclk_rate_hz, timing->dsi_transfer_time_us); pixel_clk_khz = pclk_rate_hz * config->num_data_lanes; do_div(pixel_clk_khz, config->bpp); display_mode->pixel_clk_khz = pixel_clk_khz; display_mode->pixel_clk_khz = display_mode->pixel_clk_khz / 1000; } int dsi_panel_get_mode(struct dsi_panel *panel, u32 index, struct dsi_display_mode *mode, int topology_override) Loading Loading
drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c +33 −23 Original line number Diff line number Diff line Loading @@ -840,21 +840,24 @@ int dsi_ctrl_pixel_format_to_bpp(enum dsi_pixel_format dst_format) } static int dsi_ctrl_update_link_freqs(struct dsi_ctrl *dsi_ctrl, struct dsi_host_config *config, void *clk_handle) struct dsi_host_config *config, void *clk_handle, struct dsi_display_mode *mode) { int rc = 0; u32 num_of_lanes = 0; u32 bpp; u64 refresh_rate = TICKS_IN_MICRO_SECOND; u32 bpp, frame_time_us; u64 h_period, v_period, bit_rate, pclk_rate, bit_rate_per_lane, byte_clk_rate, byte_intf_clk_rate; struct dsi_host_common_cfg *host_cfg = &config->common_config; struct dsi_split_link_config *split_link = &host_cfg->split_link; struct dsi_mode_info *timing = &config->video_timing; u32 bits_per_symbol = 16, num_of_symbols = 7; /* For Cphy */ u64 dsi_transfer_time_us = mode->priv_info->dsi_transfer_time_us; u64 min_dsi_clk_hz = mode->priv_info->min_dsi_clk_hz; /* Get bits per pxl in desitnation format */ /* Get bits per pxl in desitination format */ bpp = dsi_ctrl_pixel_format_to_bpp(host_cfg->dst_format); frame_time_us = mult_frac(1000, 1000, (timing->refresh_rate)); if (host_cfg->data_lanes & DSI_DATA_LANE_0) num_of_lanes++; Loading @@ -868,25 +871,20 @@ static int dsi_ctrl_update_link_freqs(struct dsi_ctrl *dsi_ctrl, if (split_link->split_link_enabled) num_of_lanes = split_link->lanes_per_sublink; if (config->bit_clk_rate_hz_override == 0) { if (config->panel_mode == DSI_OP_CMD_MODE) { h_period = DSI_H_ACTIVE_DSC(timing); h_period += timing->overlap_pixels; v_period = timing->v_active; config->common_config.num_data_lanes = num_of_lanes; config->common_config.bpp = bpp; do_div(refresh_rate, timing->mdp_transfer_time_us); if (config->bit_clk_rate_hz_override != 0) { bit_rate = config->bit_clk_rate_hz_override * num_of_lanes; } else if (config->panel_mode == DSI_OP_CMD_MODE) { /* Calculate the bit rate needed to match dsi transfer time */ bit_rate = min_dsi_clk_hz * frame_time_us; do_div(bit_rate, dsi_transfer_time_us); bit_rate = bit_rate * num_of_lanes; } else { h_period = DSI_H_TOTAL_DSC(timing); v_period = DSI_V_TOTAL(timing); refresh_rate = timing->refresh_rate; } bit_rate = h_period * v_period * refresh_rate * bpp; } else { bit_rate = config->bit_clk_rate_hz_override * num_of_lanes; if (host_cfg->phy_type == DSI_PHY_TYPE_CPHY) { bit_rate *= bits_per_symbol; do_div(bit_rate, num_of_symbols); } bit_rate = h_period * v_period * timing->refresh_rate * bpp; } pclk_rate = bit_rate; Loading Loading @@ -1748,7 +1746,7 @@ static int dsi_enable_io_clamp(struct dsi_ctrl *dsi_ctrl, static int dsi_ctrl_dts_parse(struct dsi_ctrl *dsi_ctrl, struct device_node *of_node) { u32 index = 0; u32 index = 0, frame_threshold_time_us = 0; int rc = 0; if (!dsi_ctrl || !of_node) { Loading Loading @@ -1777,6 +1775,15 @@ static int dsi_ctrl_dts_parse(struct dsi_ctrl *dsi_ctrl, dsi_ctrl->split_link_supported = of_property_read_bool(of_node, "qcom,split-link-supported"); rc = of_property_read_u32(of_node, "frame-threshold-time-us", &frame_threshold_time_us); if (rc) { pr_debug("frame-threshold-time not specified, defaulting\n"); frame_threshold_time_us = 2666; } dsi_ctrl->frame_threshold_time_us = frame_threshold_time_us; return 0; } Loading Loading @@ -2935,6 +2942,7 @@ int dsi_ctrl_host_deinit(struct dsi_ctrl *dsi_ctrl) * dsi_ctrl_update_host_config() - update dsi host configuration * @dsi_ctrl: DSI controller handle. * @config: DSI host configuration. * @mode: DSI host mode selected. * @flags: dsi_mode_flags modifying the behavior * * Updates driver with new Host configuration to use for host initialization. Loading @@ -2945,6 +2953,7 @@ int dsi_ctrl_host_deinit(struct dsi_ctrl *dsi_ctrl) */ int dsi_ctrl_update_host_config(struct dsi_ctrl *ctrl, struct dsi_host_config *config, struct dsi_display_mode *mode, int flags, void *clk_handle) { int rc = 0; Loading @@ -2968,7 +2977,8 @@ int dsi_ctrl_update_host_config(struct dsi_ctrl *ctrl, * for dynamic clk switch case link frequence would * be updated dsi_display_dynamic_clk_switch(). */ rc = dsi_ctrl_update_link_freqs(ctrl, config, clk_handle); rc = dsi_ctrl_update_link_freqs(ctrl, config, clk_handle, mode); if (rc) { pr_err("[%s] failed to update link frequencies, rc=%d\n", ctrl->name, rc); Loading
drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h +8 −1 Original line number Diff line number Diff line /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -230,6 +230,9 @@ struct dsi_ctrl_interrupts { * @debugfs_root: Root for debugfs entries. * @misr_enable: Frame MISR enable/disable * @misr_cache: Cached Frame MISR value * @frame_threshold_time_us: Frame threshold time in microseconds, where * dsi data lane will be idle i.e from pingpong done to * next TE for command mode. * @phy_isolation_enabled: A boolean property allows to isolate the phy from * dsi controller and run only dsi controller. * @null_insertion_enabled: A boolean property to allow dsi controller to Loading Loading @@ -282,6 +285,8 @@ struct dsi_ctrl { bool misr_enable; u32 misr_cache; u32 frame_threshold_time_us; /* Check for spurious interrupts */ unsigned long jiffies_start; unsigned int error_interrupt_count; Loading Loading @@ -352,6 +357,7 @@ int dsi_ctrl_validate_timing(struct dsi_ctrl *dsi_ctrl, * dsi_ctrl_update_host_config() - update dsi host configuration * @dsi_ctrl: DSI controller handle. * @config: DSI host configuration. * @mode: DSI host mode selected. * @flags: dsi_mode_flags modifying the behavior * @clk_handle: Clock handle for DSI clocks * Loading @@ -363,6 +369,7 @@ int dsi_ctrl_validate_timing(struct dsi_ctrl *dsi_ctrl, */ int dsi_ctrl_update_host_config(struct dsi_ctrl *dsi_ctrl, struct dsi_host_config *config, struct dsi_display_mode *mode, int flags, void *clk_handle); /** Loading
drivers/gpu/drm/msm/dsi-staging/dsi_defs.h +12 −0 Original line number Diff line number Diff line Loading @@ -410,8 +410,10 @@ struct dsi_panel_cmd_set { * @v_sync_polarity: Polarity of VSYNC (false is active low). * @refresh_rate: Refresh rate in Hz. * @clk_rate_hz: DSI bit clock rate per lane in Hz. * @min_dsi_clk_hz: Min DSI bit clock to transfer in vsync time. * @mdp_transfer_time_us: Specifies the mdp transfer time for command mode * panels in microseconds. * @dsi_transfer_time_us: Specifies dsi transfer time for command mode. * @overlap_pixels: overlap pixels for certain panels. * @dsc_enabled: DSC compression enabled. * @dsc: DSC compression configuration. Loading @@ -433,7 +435,9 @@ struct dsi_mode_info { u32 refresh_rate; u64 clk_rate_hz; u64 min_dsi_clk_hz; u32 mdp_transfer_time_us; u32 dsi_transfer_time_us; u32 overlap_pixels; bool dsc_enabled; struct msm_display_dsc_info *dsc; Loading @@ -456,6 +460,8 @@ struct dsi_split_link_config { * struct dsi_host_common_cfg - Host configuration common to video and cmd mode * @dst_format: Destination pixel format. * @data_lanes: Physical data lanes to be enabled. * @num_data_lanes: Number of physical data lanes. * @bpp: Number of bits per pixel. * @en_crc_check: Enable CRC checks. * @en_ecc_check: Enable ECC checks. * @te_mode: Source for TE signalling. Loading Loading @@ -485,6 +491,8 @@ struct dsi_split_link_config { struct dsi_host_common_cfg { enum dsi_pixel_format dst_format; enum dsi_data_lanes data_lanes; u8 num_data_lanes; u8 bpp; bool en_crc_check; bool en_ecc_check; enum dsi_te_mode te_mode; Loading Loading @@ -589,7 +597,9 @@ struct dsi_host_config { * @panel_prefill_lines: Panel prefill lines for RSC * @mdp_transfer_time_us: Specifies the mdp transfer time for command mode * panels in microseconds. * @dsi_transfer_time_us: Specifies the dsi transfer time for cmd panels. * @clk_rate_hz: DSI bit clock per lane in hz. * @min_dsi_clk_hz: Min dsi clk per lane to transfer frame in vsync time. * @overlap_pixels: overlap pixels for certain panels. * @topology: Topology selected for the panel * @dsc: DSC compression info Loading @@ -606,7 +616,9 @@ struct dsi_display_mode_priv_info { u32 panel_jitter_denom; u32 panel_prefill_lines; u32 mdp_transfer_time_us; u32 dsi_transfer_time_us; u64 clk_rate_hz; u64 min_dsi_clk_hz; u32 overlap_pixels; struct msm_display_topology topology; Loading
drivers/gpu/drm/msm/dsi-staging/dsi_display.c +29 −2 Original line number Diff line number Diff line Loading @@ -4570,7 +4570,7 @@ static int dsi_display_set_mode_sub(struct dsi_display *display, display_for_each_ctrl(i, display) { ctrl = &display->ctrl[i]; rc = dsi_ctrl_update_host_config(ctrl->ctrl, &display->config, mode->dsi_mode_flags, &display->config, mode, mode->dsi_mode_flags, display->dsi_clk_handle); if (rc) { pr_err("failed to update ctrl config\n"); Loading Loading @@ -4618,7 +4618,8 @@ static int dsi_display_set_mode_sub(struct dsi_display *display, display_for_each_ctrl(i, display) { ctrl = &display->ctrl[i]; rc = dsi_ctrl_update_host_config(ctrl->ctrl, &display->config, mode->dsi_mode_flags, display->dsi_clk_handle); mode, mode->dsi_mode_flags, display->dsi_clk_handle); if (rc) { pr_err("[%s] failed to update ctrl config, rc=%d\n", display->name, rc); Loading Loading @@ -6266,6 +6267,7 @@ int dsi_display_get_modes(struct dsi_display *display, struct dsi_display_mode **out_modes) { struct dsi_dfps_capabilities dfps_caps; struct dsi_display_ctrl *ctrl; struct dsi_host_common_cfg *host = &display->panel->host_config; bool is_split_link, is_cmd_mode; u32 num_dfps_rates, timing_mode_count, display_mode_count; Loading @@ -6279,6 +6281,7 @@ int dsi_display_get_modes(struct dsi_display *display, } *out_modes = NULL; ctrl = &display->ctrl[0]; mutex_lock(&display->display_lock); Loading Loading @@ -6308,6 +6311,7 @@ int dsi_display_get_modes(struct dsi_display *display, for (mode_idx = 0; mode_idx < timing_mode_count; mode_idx++) { struct dsi_display_mode display_mode; int topology_override = NO_OVERRIDE; u32 frame_threshold_us = ctrl->ctrl->frame_threshold_time_us; if (display->cmdline_timing == mode_idx) topology_override = display->cmdline_topology; Loading @@ -6328,6 +6332,22 @@ int dsi_display_get_modes(struct dsi_display *display, num_dfps_rates = ((!dfps_caps.dfps_support || is_cmd_mode) ? 1 : dfps_caps.dfps_list_len); /* Calculate dsi frame transfer time */ if (is_cmd_mode) { dsi_panel_calc_dsi_transfer_time( &display->panel->host_config, &display_mode, frame_threshold_us); display_mode.priv_info->dsi_transfer_time_us = display_mode.timing.dsi_transfer_time_us; display_mode.priv_info->min_dsi_clk_hz = display_mode.timing.min_dsi_clk_hz; display_mode.priv_info->mdp_transfer_time_us = display_mode.priv_info->dsi_transfer_time_us; display_mode.timing.mdp_transfer_time_us = display_mode.timing.dsi_transfer_time_us; } is_split_link = host->split_link.split_link_enabled; sublinks_count = host->split_link.num_sublinks; if (is_split_link && sublinks_count > 1) { Loading Loading @@ -6656,6 +6676,7 @@ int dsi_display_set_mode(struct dsi_display *display, { int rc = 0; struct dsi_display_mode adj_mode; struct dsi_mode_info timing; if (!display || !mode || !display->panel) { pr_err("Invalid params\n"); Loading @@ -6665,6 +6686,7 @@ int dsi_display_set_mode(struct dsi_display *display, mutex_lock(&display->display_lock); adj_mode = *mode; timing = adj_mode.timing; adjust_timing_by_ctrl_count(display, &adj_mode); /*For dynamic DSI setting, use specified clock rate */ Loading Loading @@ -6692,6 +6714,11 @@ int dsi_display_set_mode(struct dsi_display *display, } } pr_info("mdp_transfer_time_us=%d us\n", adj_mode.priv_info->mdp_transfer_time_us); pr_info("hactive= %d, vactive= %d, fps=%d", timing.h_active, timing.v_active, timing.refresh_rate); memcpy(display->panel->cur_mode, &adj_mode, sizeof(adj_mode)); error: mutex_unlock(&display->display_lock); Loading
drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +91 −20 Original line number Diff line number Diff line Loading @@ -35,8 +35,6 @@ #define DSI_PANEL_DEFAULT_LABEL "Default dsi panel" #define DEFAULT_MDP_TRANSFER_TIME 14000 #define DEFAULT_PANEL_JITTER_NUMERATOR 2 #define DEFAULT_PANEL_JITTER_DENOMINATOR 1 #define DEFAULT_PANEL_JITTER_ARRAY_SIZE 2 Loading Loading @@ -851,7 +849,7 @@ static int dsi_panel_parse_timing(struct dsi_mode_info *mode, &mode->mdp_transfer_time_us); if (rc) { pr_debug("fallback to default mdp-transfer-time-us\n"); mode->mdp_transfer_time_us = DEFAULT_MDP_TRANSFER_TIME; mode->mdp_transfer_time_us = 0; } display_mode->priv_info->mdp_transfer_time_us = mode->mdp_transfer_time_us; Loading Loading @@ -967,6 +965,8 @@ static int dsi_panel_parse_pixel_format(struct dsi_host_common_cfg *host, return rc; } host->bpp = bpp; switch (bpp) { case 3: fmt = DSI_PIXEL_FORMAT_RGB111; Loading Loading @@ -1007,6 +1007,7 @@ static int dsi_panel_parse_lane_states(struct dsi_host_common_cfg *host, { int rc = 0; bool lane_enabled; u32 num_of_lanes = 0; lane_enabled = utils->read_bool(utils->data, "qcom,mdss-dsi-lane-0-state"); Loading @@ -1024,6 +1025,17 @@ static int dsi_panel_parse_lane_states(struct dsi_host_common_cfg *host, "qcom,mdss-dsi-lane-3-state"); host->data_lanes |= (lane_enabled ? DSI_DATA_LANE_3 : 0); if (host->data_lanes & DSI_DATA_LANE_0) num_of_lanes++; if (host->data_lanes & DSI_DATA_LANE_1) num_of_lanes++; if (host->data_lanes & DSI_DATA_LANE_2) num_of_lanes++; if (host->data_lanes & DSI_DATA_LANE_3) num_of_lanes++; host->num_data_lanes = num_of_lanes; if (host->data_lanes == 0) { pr_err("[%s] No data lanes are enabled, rc=%d\n", name, rc); rc = -EINVAL; Loading Loading @@ -2543,9 +2555,6 @@ static int dsi_panel_parse_phy_timing(struct dsi_display_mode *mode, u32 len, i; int rc = 0; struct dsi_display_mode_priv_info *priv_info; u64 h_period, v_period; u64 refresh_rate = TICKS_IN_MICRO_SECOND; struct dsi_mode_info *timing = NULL; u64 pixel_clk_khz; if (!mode || !mode->priv_info) Loading @@ -2569,21 +2578,18 @@ static int dsi_panel_parse_phy_timing(struct dsi_display_mode *mode, priv_info->phy_timing_len = len; }; timing = &mode->timing; if (panel_mode == DSI_OP_CMD_MODE) { h_period = DSI_H_ACTIVE_DSC(timing); v_period = timing->v_active; do_div(refresh_rate, priv_info->mdp_transfer_time_us); } else { h_period = DSI_H_TOTAL_DSC(timing); v_period = DSI_V_TOTAL(timing); refresh_rate = timing->refresh_rate; } pixel_clk_khz = h_period * v_period * refresh_rate; if (panel_mode == DSI_OP_VIDEO_MODE) { /* * For command mode we update the pclk as part of * function dsi_panel_calc_dsi_transfer_time( ) * as we set it based on dsi clock or mdp transfer time. */ pixel_clk_khz = (DSI_H_TOTAL_DSC(&mode->timing) * DSI_V_TOTAL(&mode->timing) * mode->timing.refresh_rate); do_div(pixel_clk_khz, 1000); mode->pixel_clk_khz = pixel_clk_khz; } return rc; } Loading Loading @@ -3616,6 +3622,71 @@ void dsi_panel_put_mode(struct dsi_display_mode *mode) kfree(mode->priv_info); } void dsi_panel_calc_dsi_transfer_time(struct dsi_host_common_cfg *config, struct dsi_display_mode *mode, u32 frame_threshold_us) { u32 frame_time_us, nslices; u64 min_bitclk_hz, total_active_pixels, bits_per_line, pclk_rate_hz, dsi_transfer_time_us, pixel_clk_khz; struct msm_display_dsc_info *dsc = mode->timing.dsc; struct dsi_mode_info *timing = &mode->timing; struct dsi_display_mode *display_mode; /* Packet overlead in bits,2 bytes header + 2 bytes checksum * + 1 byte dcs data command. */ const u32 packet_overhead = 56; display_mode = container_of(timing, struct dsi_display_mode, timing); frame_time_us = mult_frac(1000, 1000, (timing->refresh_rate)); if (timing->dsc_enabled) { nslices = (timing->h_active)/(dsc->slice_width); /* (slice width x bit-per-pixel + packet overhead) x * number of slices x height x fps / lane */ bits_per_line = ((dsc->slice_width * dsc->bpp) + packet_overhead) * nslices; bits_per_line = bits_per_line / (config->num_data_lanes); min_bitclk_hz = (bits_per_line * timing->v_active * timing->refresh_rate); } else { total_active_pixels = ((DSI_H_ACTIVE_DSC(timing) * timing->v_active)); /* calculate the actual bitclk needed to transfer the frame */ min_bitclk_hz = (total_active_pixels * (timing->refresh_rate) * (config->bpp)); do_div(min_bitclk_hz, config->num_data_lanes); } timing->min_dsi_clk_hz = min_bitclk_hz; if (timing->clk_rate_hz) { /* adjust the transfer time proportionately for bit clk*/ dsi_transfer_time_us = frame_time_us * min_bitclk_hz; do_div(dsi_transfer_time_us, timing->clk_rate_hz); timing->dsi_transfer_time_us = dsi_transfer_time_us; } else if (mode->priv_info->mdp_transfer_time_us) { timing->dsi_transfer_time_us = mode->priv_info->mdp_transfer_time_us; } else { timing->dsi_transfer_time_us = frame_time_us - frame_threshold_us; } /* Calculate pclk_khz to update modeinfo */ pclk_rate_hz = min_bitclk_hz * frame_time_us; do_div(pclk_rate_hz, timing->dsi_transfer_time_us); pixel_clk_khz = pclk_rate_hz * config->num_data_lanes; do_div(pixel_clk_khz, config->bpp); display_mode->pixel_clk_khz = pixel_clk_khz; display_mode->pixel_clk_khz = display_mode->pixel_clk_khz / 1000; } int dsi_panel_get_mode(struct dsi_panel *panel, u32 index, struct dsi_display_mode *mode, int topology_override) Loading