Loading drivers/gpu/drm/msm/dsi-staging/dsi_display.c +88 −11 Original line number Diff line number Diff line Loading @@ -3982,7 +3982,7 @@ int dsi_display_get_info(struct msm_display_info *info, void *disp) return rc; } int dsi_display_get_mode_count(struct dsi_display *display, static int dsi_display_get_mode_count_no_lock(struct dsi_display *display, u32 *count) { struct dsi_dfps_capabilities dfps_caps; Loading @@ -3994,15 +3994,13 @@ int dsi_display_get_mode_count(struct dsi_display *display, return -EINVAL; } mutex_lock(&display->display_lock); *count = display->panel->num_timing_nodes; rc = dsi_panel_get_dfps_caps(display->panel, &dfps_caps); if (rc) { pr_err("[%s] failed to get dfps caps from panel\n", display->name); goto done; return rc; } num_dfps_rates = !dfps_caps.dfps_support ? 1 : Loading @@ -4012,7 +4010,22 @@ int dsi_display_get_mode_count(struct dsi_display *display, /* Inflate num_of_modes by fps in dfps */ *count = display->panel->num_timing_nodes * num_dfps_rates; done: return 0; } int dsi_display_get_mode_count(struct dsi_display *display, u32 *count) { int rc; if (!display || !display->panel) { pr_err("invalid display:%d panel:%d\n", display != NULL, display ? display->panel != NULL : 0); return -EINVAL; } mutex_lock(&display->display_lock); rc = dsi_display_get_mode_count_no_lock(display, count); mutex_unlock(&display->display_lock); return 0; Loading @@ -4025,20 +4038,36 @@ void dsi_display_put_mode(struct dsi_display *display, } int dsi_display_get_modes(struct dsi_display *display, struct dsi_display_mode *modes) struct dsi_display_mode **out_modes) { struct dsi_dfps_capabilities dfps_caps; u32 num_dfps_rates, panel_mode_count; u32 num_dfps_rates, panel_mode_count, total_mode_count; u32 mode_idx, array_idx = 0; int i, rc = 0; int i, rc = -EINVAL; if (!display || !modes) { if (!display || !out_modes) { pr_err("Invalid params\n"); return -EINVAL; } *out_modes = NULL; mutex_lock(&display->display_lock); rc = dsi_display_get_mode_count_no_lock(display, &total_mode_count); if (rc) goto error; /* free any previously probed modes */ kfree(display->modes); display->modes = kcalloc(total_mode_count, sizeof(*display->modes), GFP_KERNEL); if (!display->modes) { rc = -ENOMEM; goto error; } rc = dsi_panel_get_dfps_caps(display->panel, &dfps_caps); if (rc) { pr_err("[%s] failed to get dfps caps from panel\n", Loading Loading @@ -4079,12 +4108,14 @@ int dsi_display_get_modes(struct dsi_display *display, } for (i = 0; i < num_dfps_rates; i++) { struct dsi_display_mode *sub_mode = &modes[array_idx]; struct dsi_display_mode *sub_mode = &display->modes[array_idx]; u32 curr_refresh_rate; if (!sub_mode) { pr_err("invalid mode data\n"); return -EFAULT; rc = -EFAULT; goto error; } memcpy(sub_mode, &panel_mode, sizeof(panel_mode)); Loading @@ -4108,11 +4139,57 @@ int dsi_display_get_modes(struct dsi_display *display, } } *out_modes = display->modes; rc = 0; error: if (rc) kfree(display->modes); mutex_unlock(&display->display_lock); return rc; } int dsi_display_find_mode(struct dsi_display *display, const struct dsi_display_mode *cmp, struct dsi_display_mode **out_mode) { u32 count, i; int rc; if (!display || !out_mode) return -EINVAL; *out_mode = NULL; rc = dsi_display_get_mode_count(display, &count); if (rc) return rc; mutex_lock(&display->display_lock); for (i = 0; i < count; i++) { struct dsi_display_mode *m = &display->modes[i]; if (cmp->timing.v_active == m->timing.v_active && cmp->timing.h_active == m->timing.h_active && cmp->timing.refresh_rate == m->timing.refresh_rate) { *out_mode = m; rc = 0; break; } } mutex_unlock(&display->display_lock); if (!*out_mode) { pr_err("[%s] failed to find mode for v_active %u h_active %u rate %u\n", display->name, cmp->timing.v_active, cmp->timing.h_active, cmp->timing.refresh_rate); rc = -ENOENT; } return rc; } /** * dsi_display_validate_mode_vrr() - Validate if varaible refresh case. * @display: DSI display handle. Loading drivers/gpu/drm/msm/dsi-staging/dsi_display.h +17 −5 Original line number Diff line number Diff line Loading @@ -135,6 +135,7 @@ struct dsi_display_clk_info { * @ctrl: Controller information for DSI display. * @panel: Handle to DSI panel. * @panel_of: pHandle to DSI panel. * @modes: Array of probed DSI modes * @type: DSI display type. * @clk_master_idx: The master controller for controlling clocks. This is an * index into the ctrl[MAX_DSI_CTRLS_PER_DISPLAY] array. Loading Loading @@ -178,6 +179,8 @@ struct dsi_display { struct dsi_panel *panel; struct device_node *panel_of; struct dsi_display_mode *modes; enum dsi_display_type type; u32 clk_master_idx; u32 cmd_master_idx; Loading Loading @@ -304,15 +307,13 @@ int dsi_display_get_mode_count(struct dsi_display *display, u32 *count); /** * dsi_display_get_modes() - get modes supported by display * @display: Handle to display. * @modes; Pointer to array of modes. Memory allocated should be * big enough to store (count * struct dsi_display_mode) * elements. If modes pointer is NULL, number of modes will * be stored in the memory pointed to by count. * @modes; Output param, list of DSI modes. Number of modes matches * count returned by dsi_display_get_mode_count * * Return: error code. */ int dsi_display_get_modes(struct dsi_display *display, struct dsi_display_mode *modes); struct dsi_display_mode **modes); /** * dsi_display_put_mode() - free up mode created for the display Loading @@ -324,6 +325,17 @@ int dsi_display_get_modes(struct dsi_display *display, void dsi_display_put_mode(struct dsi_display *display, struct dsi_display_mode *mode); /** * dsi_display_find_mode() - retrieve cached DSI mode given relevant params * @display: Handle to display. * @cmp: Mode to use as comparison to find original * @out_mode: Output parameter, pointer to retrieved mode * * Return: error code. */ int dsi_display_find_mode(struct dsi_display *display, const struct dsi_display_mode *cmp, struct dsi_display_mode **out_mode); /** * dsi_display_validate_mode() - validates if mode is supported by display * @display: Handle to display. Loading drivers/gpu/drm/msm/dsi-staging/dsi_display_test.c +1 −9 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ static void dsi_display_test_work(struct work_struct *work) struct dsi_display *display; struct dsi_display_mode *modes; u32 count = 0; u32 size = 0; int rc = 0; test = container_of(work, struct dsi_display_test, test_work); Loading @@ -40,14 +39,7 @@ static void dsi_display_test_work(struct work_struct *work) goto test_fail; } size = count * sizeof(*modes); modes = kzalloc(size, GFP_KERNEL); if (!modes) { rc = -ENOMEM; goto test_fail; } rc = dsi_display_get_modes(display, modes); rc = dsi_display_get_modes(display, &modes); if (rc) { pr_err("failed to get modes, rc=%d\n", rc); goto test_fail_free_modes; Loading drivers/gpu/drm/msm/dsi-staging/dsi_drm.c +24 −14 Original line number Diff line number Diff line Loading @@ -268,7 +268,8 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge, { int rc = 0; struct dsi_bridge *c_bridge = to_dsi_bridge(bridge); struct dsi_display_mode dsi_mode, cur_dsi_mode; struct dsi_display *display; struct dsi_display_mode dsi_mode, cur_dsi_mode, *panel_dsi_mode; struct drm_display_mode cur_mode; struct drm_crtc_state *crtc_state; Loading @@ -279,8 +280,26 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge, return false; } display = c_bridge->display; if (!display) { pr_err("Invalid params\n"); return false; } convert_to_dsi_mode(mode, &dsi_mode); /* * retrieve dsi mode from dsi driver's cache since not safe to take * the drm mode config mutex in all paths */ rc = dsi_display_find_mode(display, &dsi_mode, &panel_dsi_mode); if (rc) return rc; /* propagate the private info to the adjusted_mode derived dsi mode */ dsi_mode.priv_info = panel_dsi_mode->priv_info; dsi_mode.dsi_mode_flags = panel_dsi_mode->dsi_mode_flags; rc = dsi_display_validate_mode(c_bridge->display, &dsi_mode, DSI_VALIDATE_FLAG_ALLOW_ADJUST); if (rc) { Loading @@ -307,6 +326,7 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge, dsi_mode.dsi_mode_flags |= DSI_MODE_FLAG_DMS; } /* convert back to drm mode, propagating the private info & flags */ dsi_convert_to_drm_mode(&dsi_mode, adjusted_mode); return true; Loading Loading @@ -540,7 +560,6 @@ int dsi_connector_get_modes(struct drm_connector *connector, void *display) { u32 count = 0; u32 size = 0; struct dsi_display_mode *modes = NULL; struct drm_display_mode drm_mode; int rc, i; Loading @@ -556,21 +575,14 @@ int dsi_connector_get_modes(struct drm_connector *connector, rc = dsi_display_get_mode_count(display, &count); if (rc) { pr_err("failed to get num of modes, rc=%d\n", rc); goto error; } size = count * sizeof(*modes); modes = kzalloc(size, GFP_KERNEL); if (!modes) { count = 0; goto end; } rc = dsi_display_get_modes(display, modes); rc = dsi_display_get_modes(display, &modes); if (rc) { pr_err("failed to get modes, rc=%d\n", rc); count = 0; goto error; goto end; } for (i = 0; i < count; i++) { Loading @@ -584,14 +596,12 @@ int dsi_connector_get_modes(struct drm_connector *connector, drm_mode.hdisplay, drm_mode.vdisplay); count = -ENOMEM; goto error; goto end; } m->width_mm = connector->display_info.width_mm; m->height_mm = connector->display_info.height_mm; drm_mode_probed_add(connector, m); } error: kfree(modes); end: pr_debug("MODE COUNT =%d\n\n", count); return count; Loading drivers/gpu/drm/msm/sde/sde_encoder.c +0 −27 Original line number Diff line number Diff line Loading @@ -780,24 +780,6 @@ void sde_encoder_helper_split_config( } } static void _sde_encoder_adjust_mode(struct drm_connector *connector, struct drm_display_mode *adj_mode) { struct drm_display_mode *cur_mode; if (!connector || !adj_mode) return; list_for_each_entry(cur_mode, &connector->modes, head) { if (cur_mode->vdisplay == adj_mode->vdisplay && cur_mode->hdisplay == adj_mode->hdisplay && cur_mode->vrefresh == adj_mode->vrefresh) { adj_mode->private = cur_mode->private; adj_mode->private_flags |= cur_mode->private_flags; } } } static int sde_encoder_virt_atomic_check( struct drm_encoder *drm_enc, struct drm_crtc_state *crtc_state, Loading Loading @@ -833,15 +815,6 @@ static int sde_encoder_virt_atomic_check( SDE_EVT32(DRMID(drm_enc), drm_atomic_crtc_needs_modeset(crtc_state)); /* * display drivers may populate private fields of the drm display mode * structure while registering possible modes of a connector with DRM. * These private fields are not populated back while DRM invokes * the mode_set callbacks. This module retrieves and populates the * private fields of the given mode. */ _sde_encoder_adjust_mode(conn_state->connector, adj_mode); /* perform atomic check on the first physical encoder (master) */ for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; Loading Loading
drivers/gpu/drm/msm/dsi-staging/dsi_display.c +88 −11 Original line number Diff line number Diff line Loading @@ -3982,7 +3982,7 @@ int dsi_display_get_info(struct msm_display_info *info, void *disp) return rc; } int dsi_display_get_mode_count(struct dsi_display *display, static int dsi_display_get_mode_count_no_lock(struct dsi_display *display, u32 *count) { struct dsi_dfps_capabilities dfps_caps; Loading @@ -3994,15 +3994,13 @@ int dsi_display_get_mode_count(struct dsi_display *display, return -EINVAL; } mutex_lock(&display->display_lock); *count = display->panel->num_timing_nodes; rc = dsi_panel_get_dfps_caps(display->panel, &dfps_caps); if (rc) { pr_err("[%s] failed to get dfps caps from panel\n", display->name); goto done; return rc; } num_dfps_rates = !dfps_caps.dfps_support ? 1 : Loading @@ -4012,7 +4010,22 @@ int dsi_display_get_mode_count(struct dsi_display *display, /* Inflate num_of_modes by fps in dfps */ *count = display->panel->num_timing_nodes * num_dfps_rates; done: return 0; } int dsi_display_get_mode_count(struct dsi_display *display, u32 *count) { int rc; if (!display || !display->panel) { pr_err("invalid display:%d panel:%d\n", display != NULL, display ? display->panel != NULL : 0); return -EINVAL; } mutex_lock(&display->display_lock); rc = dsi_display_get_mode_count_no_lock(display, count); mutex_unlock(&display->display_lock); return 0; Loading @@ -4025,20 +4038,36 @@ void dsi_display_put_mode(struct dsi_display *display, } int dsi_display_get_modes(struct dsi_display *display, struct dsi_display_mode *modes) struct dsi_display_mode **out_modes) { struct dsi_dfps_capabilities dfps_caps; u32 num_dfps_rates, panel_mode_count; u32 num_dfps_rates, panel_mode_count, total_mode_count; u32 mode_idx, array_idx = 0; int i, rc = 0; int i, rc = -EINVAL; if (!display || !modes) { if (!display || !out_modes) { pr_err("Invalid params\n"); return -EINVAL; } *out_modes = NULL; mutex_lock(&display->display_lock); rc = dsi_display_get_mode_count_no_lock(display, &total_mode_count); if (rc) goto error; /* free any previously probed modes */ kfree(display->modes); display->modes = kcalloc(total_mode_count, sizeof(*display->modes), GFP_KERNEL); if (!display->modes) { rc = -ENOMEM; goto error; } rc = dsi_panel_get_dfps_caps(display->panel, &dfps_caps); if (rc) { pr_err("[%s] failed to get dfps caps from panel\n", Loading Loading @@ -4079,12 +4108,14 @@ int dsi_display_get_modes(struct dsi_display *display, } for (i = 0; i < num_dfps_rates; i++) { struct dsi_display_mode *sub_mode = &modes[array_idx]; struct dsi_display_mode *sub_mode = &display->modes[array_idx]; u32 curr_refresh_rate; if (!sub_mode) { pr_err("invalid mode data\n"); return -EFAULT; rc = -EFAULT; goto error; } memcpy(sub_mode, &panel_mode, sizeof(panel_mode)); Loading @@ -4108,11 +4139,57 @@ int dsi_display_get_modes(struct dsi_display *display, } } *out_modes = display->modes; rc = 0; error: if (rc) kfree(display->modes); mutex_unlock(&display->display_lock); return rc; } int dsi_display_find_mode(struct dsi_display *display, const struct dsi_display_mode *cmp, struct dsi_display_mode **out_mode) { u32 count, i; int rc; if (!display || !out_mode) return -EINVAL; *out_mode = NULL; rc = dsi_display_get_mode_count(display, &count); if (rc) return rc; mutex_lock(&display->display_lock); for (i = 0; i < count; i++) { struct dsi_display_mode *m = &display->modes[i]; if (cmp->timing.v_active == m->timing.v_active && cmp->timing.h_active == m->timing.h_active && cmp->timing.refresh_rate == m->timing.refresh_rate) { *out_mode = m; rc = 0; break; } } mutex_unlock(&display->display_lock); if (!*out_mode) { pr_err("[%s] failed to find mode for v_active %u h_active %u rate %u\n", display->name, cmp->timing.v_active, cmp->timing.h_active, cmp->timing.refresh_rate); rc = -ENOENT; } return rc; } /** * dsi_display_validate_mode_vrr() - Validate if varaible refresh case. * @display: DSI display handle. Loading
drivers/gpu/drm/msm/dsi-staging/dsi_display.h +17 −5 Original line number Diff line number Diff line Loading @@ -135,6 +135,7 @@ struct dsi_display_clk_info { * @ctrl: Controller information for DSI display. * @panel: Handle to DSI panel. * @panel_of: pHandle to DSI panel. * @modes: Array of probed DSI modes * @type: DSI display type. * @clk_master_idx: The master controller for controlling clocks. This is an * index into the ctrl[MAX_DSI_CTRLS_PER_DISPLAY] array. Loading Loading @@ -178,6 +179,8 @@ struct dsi_display { struct dsi_panel *panel; struct device_node *panel_of; struct dsi_display_mode *modes; enum dsi_display_type type; u32 clk_master_idx; u32 cmd_master_idx; Loading Loading @@ -304,15 +307,13 @@ int dsi_display_get_mode_count(struct dsi_display *display, u32 *count); /** * dsi_display_get_modes() - get modes supported by display * @display: Handle to display. * @modes; Pointer to array of modes. Memory allocated should be * big enough to store (count * struct dsi_display_mode) * elements. If modes pointer is NULL, number of modes will * be stored in the memory pointed to by count. * @modes; Output param, list of DSI modes. Number of modes matches * count returned by dsi_display_get_mode_count * * Return: error code. */ int dsi_display_get_modes(struct dsi_display *display, struct dsi_display_mode *modes); struct dsi_display_mode **modes); /** * dsi_display_put_mode() - free up mode created for the display Loading @@ -324,6 +325,17 @@ int dsi_display_get_modes(struct dsi_display *display, void dsi_display_put_mode(struct dsi_display *display, struct dsi_display_mode *mode); /** * dsi_display_find_mode() - retrieve cached DSI mode given relevant params * @display: Handle to display. * @cmp: Mode to use as comparison to find original * @out_mode: Output parameter, pointer to retrieved mode * * Return: error code. */ int dsi_display_find_mode(struct dsi_display *display, const struct dsi_display_mode *cmp, struct dsi_display_mode **out_mode); /** * dsi_display_validate_mode() - validates if mode is supported by display * @display: Handle to display. Loading
drivers/gpu/drm/msm/dsi-staging/dsi_display_test.c +1 −9 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ static void dsi_display_test_work(struct work_struct *work) struct dsi_display *display; struct dsi_display_mode *modes; u32 count = 0; u32 size = 0; int rc = 0; test = container_of(work, struct dsi_display_test, test_work); Loading @@ -40,14 +39,7 @@ static void dsi_display_test_work(struct work_struct *work) goto test_fail; } size = count * sizeof(*modes); modes = kzalloc(size, GFP_KERNEL); if (!modes) { rc = -ENOMEM; goto test_fail; } rc = dsi_display_get_modes(display, modes); rc = dsi_display_get_modes(display, &modes); if (rc) { pr_err("failed to get modes, rc=%d\n", rc); goto test_fail_free_modes; Loading
drivers/gpu/drm/msm/dsi-staging/dsi_drm.c +24 −14 Original line number Diff line number Diff line Loading @@ -268,7 +268,8 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge, { int rc = 0; struct dsi_bridge *c_bridge = to_dsi_bridge(bridge); struct dsi_display_mode dsi_mode, cur_dsi_mode; struct dsi_display *display; struct dsi_display_mode dsi_mode, cur_dsi_mode, *panel_dsi_mode; struct drm_display_mode cur_mode; struct drm_crtc_state *crtc_state; Loading @@ -279,8 +280,26 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge, return false; } display = c_bridge->display; if (!display) { pr_err("Invalid params\n"); return false; } convert_to_dsi_mode(mode, &dsi_mode); /* * retrieve dsi mode from dsi driver's cache since not safe to take * the drm mode config mutex in all paths */ rc = dsi_display_find_mode(display, &dsi_mode, &panel_dsi_mode); if (rc) return rc; /* propagate the private info to the adjusted_mode derived dsi mode */ dsi_mode.priv_info = panel_dsi_mode->priv_info; dsi_mode.dsi_mode_flags = panel_dsi_mode->dsi_mode_flags; rc = dsi_display_validate_mode(c_bridge->display, &dsi_mode, DSI_VALIDATE_FLAG_ALLOW_ADJUST); if (rc) { Loading @@ -307,6 +326,7 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge, dsi_mode.dsi_mode_flags |= DSI_MODE_FLAG_DMS; } /* convert back to drm mode, propagating the private info & flags */ dsi_convert_to_drm_mode(&dsi_mode, adjusted_mode); return true; Loading Loading @@ -540,7 +560,6 @@ int dsi_connector_get_modes(struct drm_connector *connector, void *display) { u32 count = 0; u32 size = 0; struct dsi_display_mode *modes = NULL; struct drm_display_mode drm_mode; int rc, i; Loading @@ -556,21 +575,14 @@ int dsi_connector_get_modes(struct drm_connector *connector, rc = dsi_display_get_mode_count(display, &count); if (rc) { pr_err("failed to get num of modes, rc=%d\n", rc); goto error; } size = count * sizeof(*modes); modes = kzalloc(size, GFP_KERNEL); if (!modes) { count = 0; goto end; } rc = dsi_display_get_modes(display, modes); rc = dsi_display_get_modes(display, &modes); if (rc) { pr_err("failed to get modes, rc=%d\n", rc); count = 0; goto error; goto end; } for (i = 0; i < count; i++) { Loading @@ -584,14 +596,12 @@ int dsi_connector_get_modes(struct drm_connector *connector, drm_mode.hdisplay, drm_mode.vdisplay); count = -ENOMEM; goto error; goto end; } m->width_mm = connector->display_info.width_mm; m->height_mm = connector->display_info.height_mm; drm_mode_probed_add(connector, m); } error: kfree(modes); end: pr_debug("MODE COUNT =%d\n\n", count); return count; Loading
drivers/gpu/drm/msm/sde/sde_encoder.c +0 −27 Original line number Diff line number Diff line Loading @@ -780,24 +780,6 @@ void sde_encoder_helper_split_config( } } static void _sde_encoder_adjust_mode(struct drm_connector *connector, struct drm_display_mode *adj_mode) { struct drm_display_mode *cur_mode; if (!connector || !adj_mode) return; list_for_each_entry(cur_mode, &connector->modes, head) { if (cur_mode->vdisplay == adj_mode->vdisplay && cur_mode->hdisplay == adj_mode->hdisplay && cur_mode->vrefresh == adj_mode->vrefresh) { adj_mode->private = cur_mode->private; adj_mode->private_flags |= cur_mode->private_flags; } } } static int sde_encoder_virt_atomic_check( struct drm_encoder *drm_enc, struct drm_crtc_state *crtc_state, Loading Loading @@ -833,15 +815,6 @@ static int sde_encoder_virt_atomic_check( SDE_EVT32(DRMID(drm_enc), drm_atomic_crtc_needs_modeset(crtc_state)); /* * display drivers may populate private fields of the drm display mode * structure while registering possible modes of a connector with DRM. * These private fields are not populated back while DRM invokes * the mode_set callbacks. This module retrieves and populates the * private fields of the given mode. */ _sde_encoder_adjust_mode(conn_state->connector, adj_mode); /* perform atomic check on the first physical encoder (master) */ for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; Loading