Loading drivers/gpu/drm/msm/Makefile +1 −0 Original line number Original line Diff line number Diff line Loading @@ -37,6 +37,7 @@ msm-y := \ sde/sde_encoder_phys_vid.o \ sde/sde_encoder_phys_vid.o \ sde/sde_encoder_phys_cmd.o \ sde/sde_encoder_phys_cmd.o \ sde/sde_irq.o \ sde/sde_irq.o \ sde/sde_rm.o \ sde/sde_kms_utils.o \ sde/sde_kms_utils.o \ sde/sde_kms.o \ sde/sde_kms.o \ sde/sde_plane.o \ sde/sde_plane.o \ Loading drivers/gpu/drm/msm/sde/sde_connector.c +6 −0 Original line number Original line Diff line number Diff line Loading @@ -253,6 +253,12 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector, } } } } if (idx == CONNECTOR_PROP_TOPOLOGY_CONTROL) { rc = sde_rm_check_property_topctl(val); if (rc) SDE_ERROR("invalid topology_control: 0x%llX\n", val); } /* check for custom property handling */ /* check for custom property handling */ if (!rc && c_conn->ops.set_property) { if (!rc && c_conn->ops.set_property) { rc = c_conn->ops.set_property(connector, rc = c_conn->ops.set_property(connector, Loading drivers/gpu/drm/msm/sde/sde_crtc.c +63 −136 Original line number Original line Diff line number Diff line Loading @@ -42,116 +42,6 @@ static struct sde_kms *get_kms(struct drm_crtc *crtc) return to_sde_kms(priv->kms); return to_sde_kms(priv->kms); } } static int sde_crtc_reserve_hw_resources(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc = to_sde_crtc(crtc); struct sde_kms *sde_kms = get_kms(crtc); struct sde_encoder_hw_resources enc_hw_res; const struct sde_hw_res_map *plat_hw_res_map; enum sde_lm unused_lm_id[CRTC_DUAL_MIXERS] = {0}; enum sde_lm lm_idx; int i, unused_lm_count = 0; if (!sde_kms) { DBG("[%s] invalid kms", __func__); return -EINVAL; } if (!sde_kms->mmio) return -EINVAL; /* Get unused LMs */ for (i = sde_kms->catalog->mixer_count - 1; i >= 0; --i) { if (!sde_rm_get_mixer(sde_kms, LM(i))) { unused_lm_id[unused_lm_count++] = LM(i); if (unused_lm_count == CRTC_DUAL_MIXERS) break; } } /* query encoder resources */ sde_encoder_get_hw_resources(sde_crtc->mixers[0].encoder, &enc_hw_res); /* parse encoder hw resources, find CTL paths */ for (i = CTL_0; i <= sde_kms->catalog->ctl_count; i++) { WARN_ON(sde_crtc->num_ctls > CRTC_DUAL_MIXERS); if (enc_hw_res.ctls[i]) { struct sde_crtc_mixer *mixer = &sde_crtc->mixers[sde_crtc->num_ctls]; mixer->hw_ctl = sde_rm_get_ctl_path(sde_kms, i); if (IS_ERR_OR_NULL(mixer->hw_ctl)) { DRM_ERROR("Invalid ctl_path\n"); return PTR_ERR(mixer->hw_ctl); } sde_crtc->num_ctls++; } } /* shortcut this process if encoder has no ctl paths */ if (!sde_crtc->num_ctls) return 0; /* * Get default LMs if specified in platform config * other wise acquire the free LMs */ for (i = INTF_0; i <= sde_kms->catalog->intf_count; i++) { if (enc_hw_res.intfs[i]) { struct sde_crtc_mixer *mixer = &sde_crtc->mixers[sde_crtc->num_mixers]; plat_hw_res_map = sde_rm_get_res_map(sde_kms, i, SDE_NONE); lm_idx = plat_hw_res_map->lm; if (!lm_idx && unused_lm_count) lm_idx = unused_lm_id[--unused_lm_count]; DBG("intf %d acquiring lm %d", i, lm_idx); mixer->hw_lm = sde_rm_acquire_mixer(sde_kms, lm_idx); if (IS_ERR_OR_NULL(mixer->hw_lm)) { DRM_ERROR("Invalid mixer\n"); return -EACCES; } sde_crtc->num_mixers++; } } /* * Get default LMs if specified in platform config, * otherwise acquire the free LMs. */ for (i = WB_0; i < WB_MAX; i++) { if (enc_hw_res.wbs[i]) { struct sde_crtc_mixer *mixer = &sde_crtc->mixers[sde_crtc->num_mixers]; plat_hw_res_map = sde_rm_get_res_map(sde_kms, SDE_NONE, i); lm_idx = plat_hw_res_map->lm; if (!lm_idx && unused_lm_count) lm_idx = unused_lm_id[--unused_lm_count]; DBG("wb %d acquiring lm %d", i, lm_idx); mixer->hw_lm = sde_rm_acquire_mixer(sde_kms, lm_idx); if (IS_ERR_OR_NULL(mixer->hw_lm)) { DRM_ERROR("Invalid mixer\n"); return -EACCES; } sde_crtc->num_mixers++; } } DBG("control paths %d, num_mixers %d, lm[0] %d, ctl[0] %d ", sde_crtc->num_ctls, sde_crtc->num_mixers, sde_crtc->mixers[0].hw_lm->idx, sde_crtc->mixers[0].hw_ctl->idx); if (sde_crtc->num_mixers > 1) DBG("lm[1] %d, ctl[1], %d", sde_crtc->mixers[1].hw_lm->idx, sde_crtc->mixers[1].hw_ctl->idx); return 0; } static void sde_crtc_destroy(struct drm_crtc *crtc) static void sde_crtc_destroy(struct drm_crtc *crtc) { { struct sde_crtc *sde_crtc = to_sde_crtc(crtc); struct sde_crtc *sde_crtc = to_sde_crtc(crtc); Loading Loading @@ -561,6 +451,66 @@ static void _sde_crtc_wait_for_fences(struct drm_crtc *crtc) } } } } static void _sde_crtc_setup_mixer_for_encoder( struct drm_crtc *crtc, struct drm_encoder *enc) { struct sde_crtc *sde_crtc = to_sde_crtc(crtc); struct sde_kms *sde_kms = get_kms(crtc); struct sde_rm *rm = &sde_kms->rm; struct sde_crtc_mixer *mixer; int i; struct sde_rm_hw_iter lm_iter, ctl_iter; sde_rm_init_hw_iter(&lm_iter, enc->base.id, SDE_HW_BLK_LM); sde_rm_init_hw_iter(&ctl_iter, enc->base.id, SDE_HW_BLK_CTL); /* Set up the mixer for this encoder, checking all channels */ for (i = sde_crtc->num_mixers; i < ARRAY_SIZE(sde_crtc->mixers); i++) { mixer = &sde_crtc->mixers[i]; /* Add mixer if reservation exists on (encoder, chan) */ if (!sde_rm_get_hw(rm, &lm_iter)) break; mixer->hw_lm = (struct sde_hw_mixer *)lm_iter.hw; /* CTL may be null, not necessarily 1:1 with LM */ (void) sde_rm_get_hw(rm, &ctl_iter); mixer->hw_ctl = (struct sde_hw_ctl *)ctl_iter.hw; mixer->flush_mask = 0; mixer->encoder = enc; sde_crtc->num_mixers++; SDE_DEBUG("setup mixer %d: lm %d\n", i, mixer->hw_lm->idx); if (mixer->hw_ctl) { sde_crtc->num_ctls++; SDE_DEBUG("setup mixer %d: ctl %d\n", i, mixer->hw_ctl->idx); } } } static void _sde_crtc_setup_mixers(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc = to_sde_crtc(crtc); struct drm_encoder *enc; sde_crtc->num_ctls = 0; sde_crtc->num_mixers = 0; memset(sde_crtc->mixers, 0, sizeof(sde_crtc->mixers)); /* Check for mixers on all encoders attached to this crtc */ list_for_each_entry(enc, &crtc->dev->mode_config.encoder_list, head) { if (enc->crtc != crtc) continue; _sde_crtc_setup_mixer_for_encoder(crtc, enc); } } static void sde_crtc_atomic_begin(struct drm_crtc *crtc, static void sde_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) struct drm_crtc_state *old_crtc_state) { { Loading @@ -579,6 +529,8 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, sde_crtc = to_sde_crtc(crtc); sde_crtc = to_sde_crtc(crtc); dev = crtc->dev; dev = crtc->dev; _sde_crtc_setup_mixers(crtc); if (sde_crtc->event) { if (sde_crtc->event) { WARN_ON(sde_crtc->event); WARN_ON(sde_crtc->event); } else { } else { Loading Loading @@ -832,7 +784,6 @@ static void sde_crtc_enable(struct drm_crtc *crtc) struct sde_hw_mixer_cfg cfg; struct sde_hw_mixer_cfg cfg; u32 mixer_width; u32 mixer_width; int i; int i; int rc; if (!crtc) { if (!crtc) { DRM_ERROR("invalid crtc\n"); DRM_ERROR("invalid crtc\n"); Loading @@ -851,20 +802,7 @@ static void sde_crtc_enable(struct drm_crtc *crtc) drm_mode_debug_printmodeline(mode); drm_mode_debug_printmodeline(mode); /* /* Update LMs for dual mode: mixer_width = half mode width */ * reserve mixer(s) if not already avaialable * if dual mode, mixer_width = half mode width * program mode configuration on mixer(s) */ if ((sde_crtc->num_ctls == 0) || (sde_crtc->num_mixers == 0)) { rc = sde_crtc_reserve_hw_resources(crtc); if (rc) { DRM_ERROR("error reserving HW resource for CRTC\n"); return; } } if (sde_crtc->num_mixers == CRTC_DUAL_MIXERS) if (sde_crtc->num_mixers == CRTC_DUAL_MIXERS) mixer_width = mode->hdisplay >> 1; mixer_width = mode->hdisplay >> 1; else else Loading Loading @@ -1200,7 +1138,6 @@ static void _sde_crtc_init_debugfs(struct sde_crtc *sde_crtc, /* initialize crtc */ /* initialize crtc */ struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_encoder *encoder, struct drm_plane *plane, struct drm_plane *plane, int drm_crtc_id) int drm_crtc_id) { { Loading @@ -1208,7 +1145,6 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct sde_crtc *sde_crtc = NULL; struct sde_crtc *sde_crtc = NULL; struct msm_drm_private *priv = NULL; struct msm_drm_private *priv = NULL; struct sde_kms *kms = NULL; struct sde_kms *kms = NULL; int i, rc; priv = dev->dev_private; priv = dev->dev_private; kms = to_sde_kms(priv->kms); kms = to_sde_kms(priv->kms); Loading @@ -1229,15 +1165,6 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev, drm_crtc_helper_add(crtc, &sde_crtc_helper_funcs); drm_crtc_helper_add(crtc, &sde_crtc_helper_funcs); plane->crtc = crtc; plane->crtc = crtc; for (i = 0; i < ARRAY_SIZE(sde_crtc->mixers); i++) sde_crtc->mixers[i].encoder = encoder; rc = sde_crtc_reserve_hw_resources(crtc); if (rc) { DRM_ERROR(" error reserving HW resource for this CRTC\n"); return ERR_PTR(-EINVAL); } /* save user friendly CRTC name for later */ /* save user friendly CRTC name for later */ snprintf(sde_crtc->name, SDE_CRTC_NAME_SIZE, "crtc%u", crtc->base.id); snprintf(sde_crtc->name, SDE_CRTC_NAME_SIZE, "crtc%u", crtc->base.id); Loading drivers/gpu/drm/msm/sde/sde_crtc.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -62,6 +62,7 @@ struct sde_crtc_mixer { struct sde_crtc { struct sde_crtc { struct drm_crtc base; struct drm_crtc base; char name[SDE_CRTC_NAME_SIZE]; char name[SDE_CRTC_NAME_SIZE]; int drm_crtc_id; int drm_crtc_id; spinlock_t lm_lock; /* protect registers */ spinlock_t lm_lock; /* protect registers */ Loading drivers/gpu/drm/msm/sde/sde_encoder.c +69 −76 Original line number Original line Diff line number Diff line Loading @@ -70,6 +70,8 @@ struct sde_encoder_virt { spinlock_t spin_lock; spinlock_t spin_lock; uint32_t bus_scaling_client; uint32_t bus_scaling_client; uint32_t display_num_of_h_tiles; unsigned int num_phys_encs; unsigned int num_phys_encs; struct sde_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL]; struct sde_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL]; struct sde_encoder_phys *cur_master; struct sde_encoder_phys *cur_master; Loading Loading @@ -155,14 +157,15 @@ static void bs_set(struct sde_encoder_virt *sde_enc, int idx) #endif #endif void sde_encoder_get_hw_resources(struct drm_encoder *drm_enc, void sde_encoder_get_hw_resources(struct drm_encoder *drm_enc, struct sde_encoder_hw_resources *hw_res) struct sde_encoder_hw_resources *hw_res, struct drm_connector_state *conn_state) { { struct sde_encoder_virt *sde_enc = NULL; struct sde_encoder_virt *sde_enc = NULL; int i = 0; int i = 0; DBG(""); DBG(""); if (!hw_res || !drm_enc) { if (!hw_res || !drm_enc || !conn_state) { DRM_ERROR("Invalid pointer"); DRM_ERROR("Invalid pointer"); return; return; } } Loading @@ -171,11 +174,13 @@ void sde_encoder_get_hw_resources(struct drm_encoder *drm_enc, /* Query resources used by phys encs, expected to be without overlap */ /* Query resources used by phys encs, expected to be without overlap */ memset(hw_res, 0, sizeof(*hw_res)); memset(hw_res, 0, sizeof(*hw_res)); hw_res->display_num_of_h_tiles = sde_enc->display_num_of_h_tiles; for (i = 0; i < sde_enc->num_phys_encs; i++) { for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; if (phys && phys->ops.get_hw_resources) if (phys && phys->ops.get_hw_resources) phys->ops.get_hw_resources(phys, hw_res); phys->ops.get_hw_resources(phys, hw_res, conn_state); } } } } Loading Loading @@ -231,54 +236,14 @@ static void sde_encoder_destroy(struct drm_encoder *drm_enc) kfree(sde_enc); kfree(sde_enc); } } static bool sde_encoder_virt_mode_fixup(struct drm_encoder *drm_enc, static int sde_encoder_virt_atomic_check( const struct drm_display_mode *mode, struct drm_encoder *drm_enc, struct drm_display_mode *adj_mode) { struct sde_encoder_virt *sde_enc = NULL; int i = 0; bool ret = true; DBG(""); if (!drm_enc) { DRM_ERROR("Invalid pointer"); return false; } sde_enc = to_sde_encoder_virt(drm_enc); MSM_EVT(drm_enc->dev, 0, 0); for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; if (phys && phys->ops.mode_fixup) { ret = phys->ops.mode_fixup(phys, mode, adj_mode); if (!ret) { DRM_ERROR("Mode unsupported, phys_enc %d\n", i); break; } if (sde_enc->num_phys_encs > 1) { DBG("ModeFix only checking 1 phys_enc"); break; } } } /* Call to populate mode->crtc* information required by framework */ drm_mode_set_crtcinfo(adj_mode, 0); MSM_EVT(drm_enc->dev, adj_mode->flags, adj_mode->private_flags); return ret; } static int sde_encoder_virt_atomic_check(struct drm_encoder *drm_enc, struct drm_crtc_state *crtc_state, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) struct drm_connector_state *conn_state) { { struct sde_encoder_virt *sde_enc = NULL; struct sde_encoder_virt *sde_enc; struct msm_drm_private *priv; struct sde_kms *sde_kms; const struct drm_display_mode *mode; const struct drm_display_mode *mode; struct drm_display_mode *adj_mode; struct drm_display_mode *adj_mode; int i = 0; int i = 0; Loading @@ -292,6 +257,8 @@ static int sde_encoder_virt_atomic_check(struct drm_encoder *drm_enc, } } sde_enc = to_sde_encoder_virt(drm_enc); sde_enc = to_sde_encoder_virt(drm_enc); priv = drm_enc->dev->dev_private; sde_kms = to_sde_kms(priv->kms); mode = &crtc_state->mode; mode = &crtc_state->mode; adj_mode = &crtc_state->adjusted_mode; adj_mode = &crtc_state->adjusted_mode; MSM_EVT(drm_enc->dev, 0, 0); MSM_EVT(drm_enc->dev, 0, 0); Loading @@ -300,23 +267,25 @@ static int sde_encoder_virt_atomic_check(struct drm_encoder *drm_enc, for (i = 0; i < sde_enc->num_phys_encs; i++) { for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; if (phys && phys->ops.atomic_check) { if (phys && phys->ops.atomic_check) ret = phys->ops.atomic_check(phys, crtc_state, ret = phys->ops.atomic_check(phys, crtc_state, conn_state); conn_state); if (ret) else if (phys && phys->ops.mode_fixup) DRM_ERROR("Mode unsupported, phys_enc %d.%d\n", if (!phys->ops.mode_fixup(phys, mode, adj_mode)) drm_enc->base.id, i); break; } else if (phys && phys->ops.mode_fixup) { if (!phys->ops.mode_fixup(phys, mode, adj_mode)) { DRM_ERROR("Mode unsupported, phys_enc %d.%d\n", drm_enc->base.id, i); ret = -EINVAL; ret = -EINVAL; } if (ret) { SDE_ERROR("enc %d mode unsupported, phys %d\n", drm_enc->base.id, i); break; break; } } } } /* Reserve dynamic resources now. Indicating AtomicTest phase */ if (!ret) ret = sde_rm_reserve(&sde_kms->rm, drm_enc, crtc_state, conn_state, true); /* Call to populate mode->crtc* information required by framework */ /* Call to populate mode->crtc* information required by framework */ drm_mode_set_crtcinfo(adj_mode, 0); drm_mode_set_crtcinfo(adj_mode, 0); Loading @@ -329,8 +298,12 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, struct drm_display_mode *mode, struct drm_display_mode *mode, struct drm_display_mode *adj_mode) struct drm_display_mode *adj_mode) { { struct sde_encoder_virt *sde_enc = NULL; struct sde_encoder_virt *sde_enc; int i = 0; struct msm_drm_private *priv; struct sde_kms *sde_kms; struct list_head *connector_list; struct drm_connector *conn = NULL, *conn_iter; int i = 0, ret; DBG(""); DBG(""); Loading @@ -340,8 +313,31 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, } } sde_enc = to_sde_encoder_virt(drm_enc); sde_enc = to_sde_encoder_virt(drm_enc); priv = drm_enc->dev->dev_private; sde_kms = to_sde_kms(priv->kms); connector_list = &sde_kms->dev->mode_config.connector_list; MSM_EVT(drm_enc->dev, 0, 0); MSM_EVT(drm_enc->dev, 0, 0); list_for_each_entry(conn_iter, connector_list, head) if (conn_iter->encoder == drm_enc) conn = conn_iter; if (!conn) { SDE_ERROR("enc %d failed to find attached connector\n", drm_enc->base.id); return; } /* Reserve dynamic resources now. Indicating non-AtomicTest phase */ ret = sde_rm_reserve(&sde_kms->rm, drm_enc, drm_enc->crtc->state, conn->state, false); if (ret) { SDE_ERROR("enc %d failed to reserve hw resources, ret %d\n", drm_enc->base.id, ret); return; } for (i = 0; i < sde_enc->num_phys_encs; i++) { for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; Loading Loading @@ -390,6 +386,8 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) { { struct sde_encoder_virt *sde_enc = NULL; struct sde_encoder_virt *sde_enc = NULL; struct msm_drm_private *priv; struct sde_kms *sde_kms; int i = 0; int i = 0; DBG(""); DBG(""); Loading @@ -400,6 +398,9 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) } } sde_enc = to_sde_encoder_virt(drm_enc); sde_enc = to_sde_encoder_virt(drm_enc); priv = drm_enc->dev->dev_private; sde_kms = to_sde_kms(priv->kms); MSM_EVT(drm_enc->dev, 0, 0); MSM_EVT(drm_enc->dev, 0, 0); for (i = 0; i < sde_enc->num_phys_encs; i++) { for (i = 0; i < sde_enc->num_phys_encs; i++) { Loading @@ -413,10 +414,11 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) DBG("clear phys enc master"); DBG("clear phys enc master"); bs_set(sde_enc, 0); bs_set(sde_enc, 0); sde_rm_release(&sde_kms->rm, drm_enc); } } static const struct drm_encoder_helper_funcs sde_encoder_helper_funcs = { static const struct drm_encoder_helper_funcs sde_encoder_helper_funcs = { .mode_fixup = sde_encoder_virt_mode_fixup, .mode_set = sde_encoder_virt_mode_set, .mode_set = sde_encoder_virt_mode_set, .disable = sde_encoder_virt_disable, .disable = sde_encoder_virt_disable, .enable = sde_encoder_virt_enable, .enable = sde_encoder_virt_enable, Loading Loading @@ -699,6 +701,8 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc, WARN_ON(disp_info->num_of_h_tiles < 1); WARN_ON(disp_info->num_of_h_tiles < 1); sde_enc->display_num_of_h_tiles = disp_info->num_of_h_tiles; DBG("dsi_info->num_of_h_tiles %d", disp_info->num_of_h_tiles); DBG("dsi_info->num_of_h_tiles %d", disp_info->num_of_h_tiles); for (i = 0; i < disp_info->num_of_h_tiles && !ret; i++) { for (i = 0; i < disp_info->num_of_h_tiles && !ret; i++) { Loading @@ -707,7 +711,6 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc, * h_tile_instance_ids[2] = {0, 1}; DSI0 = left, DSI1 = right * h_tile_instance_ids[2] = {0, 1}; DSI0 = left, DSI1 = right * h_tile_instance_ids[2] = {1, 0}; DSI1 = left, DSI0 = right * h_tile_instance_ids[2] = {1, 0}; DSI1 = left, DSI0 = right */ */ const struct sde_hw_res_map *hw_res_map = NULL; u32 controller_id = disp_info->h_tile_instance[i]; u32 controller_id = disp_info->h_tile_instance[i]; if (disp_info->num_of_h_tiles > 1) { if (disp_info->num_of_h_tiles > 1) { Loading @@ -723,6 +726,7 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc, i, controller_id, phys_params.split_role); i, controller_id, phys_params.split_role); if (intf_type == INTF_WB) { if (intf_type == INTF_WB) { phys_params.intf_idx = INTF_MAX; phys_params.wb_idx = sde_encoder_get_wb( phys_params.wb_idx = sde_encoder_get_wb( sde_kms->catalog, sde_kms->catalog, intf_type, controller_id); intf_type, controller_id); Loading @@ -733,6 +737,7 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc, ret = -EINVAL; ret = -EINVAL; } } } else { } else { phys_params.wb_idx = WB_MAX; phys_params.intf_idx = sde_encoder_get_intf( phys_params.intf_idx = sde_encoder_get_intf( sde_kms->catalog, intf_type, sde_kms->catalog, intf_type, controller_id); controller_id); Loading @@ -744,18 +749,6 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc, } } } } hw_res_map = sde_rm_get_res_map(sde_kms, phys_params.intf_idx, phys_params.wb_idx); if (IS_ERR_OR_NULL(hw_res_map)) { DRM_ERROR("failed to get hw_res_map: %ld\n", PTR_ERR(hw_res_map)); ret = -EINVAL; } else { phys_params.pp_idx = hw_res_map->pp; phys_params.ctl_idx = hw_res_map->ctl; phys_params.cdm_idx = hw_res_map->cdm; } if (!ret) { if (!ret) { if (intf_type == INTF_WB) if (intf_type == INTF_WB) ret = sde_encoder_virt_add_phys_enc_wb(sde_enc, ret = sde_encoder_virt_add_phys_enc_wb(sde_enc, Loading Loading
drivers/gpu/drm/msm/Makefile +1 −0 Original line number Original line Diff line number Diff line Loading @@ -37,6 +37,7 @@ msm-y := \ sde/sde_encoder_phys_vid.o \ sde/sde_encoder_phys_vid.o \ sde/sde_encoder_phys_cmd.o \ sde/sde_encoder_phys_cmd.o \ sde/sde_irq.o \ sde/sde_irq.o \ sde/sde_rm.o \ sde/sde_kms_utils.o \ sde/sde_kms_utils.o \ sde/sde_kms.o \ sde/sde_kms.o \ sde/sde_plane.o \ sde/sde_plane.o \ Loading
drivers/gpu/drm/msm/sde/sde_connector.c +6 −0 Original line number Original line Diff line number Diff line Loading @@ -253,6 +253,12 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector, } } } } if (idx == CONNECTOR_PROP_TOPOLOGY_CONTROL) { rc = sde_rm_check_property_topctl(val); if (rc) SDE_ERROR("invalid topology_control: 0x%llX\n", val); } /* check for custom property handling */ /* check for custom property handling */ if (!rc && c_conn->ops.set_property) { if (!rc && c_conn->ops.set_property) { rc = c_conn->ops.set_property(connector, rc = c_conn->ops.set_property(connector, Loading
drivers/gpu/drm/msm/sde/sde_crtc.c +63 −136 Original line number Original line Diff line number Diff line Loading @@ -42,116 +42,6 @@ static struct sde_kms *get_kms(struct drm_crtc *crtc) return to_sde_kms(priv->kms); return to_sde_kms(priv->kms); } } static int sde_crtc_reserve_hw_resources(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc = to_sde_crtc(crtc); struct sde_kms *sde_kms = get_kms(crtc); struct sde_encoder_hw_resources enc_hw_res; const struct sde_hw_res_map *plat_hw_res_map; enum sde_lm unused_lm_id[CRTC_DUAL_MIXERS] = {0}; enum sde_lm lm_idx; int i, unused_lm_count = 0; if (!sde_kms) { DBG("[%s] invalid kms", __func__); return -EINVAL; } if (!sde_kms->mmio) return -EINVAL; /* Get unused LMs */ for (i = sde_kms->catalog->mixer_count - 1; i >= 0; --i) { if (!sde_rm_get_mixer(sde_kms, LM(i))) { unused_lm_id[unused_lm_count++] = LM(i); if (unused_lm_count == CRTC_DUAL_MIXERS) break; } } /* query encoder resources */ sde_encoder_get_hw_resources(sde_crtc->mixers[0].encoder, &enc_hw_res); /* parse encoder hw resources, find CTL paths */ for (i = CTL_0; i <= sde_kms->catalog->ctl_count; i++) { WARN_ON(sde_crtc->num_ctls > CRTC_DUAL_MIXERS); if (enc_hw_res.ctls[i]) { struct sde_crtc_mixer *mixer = &sde_crtc->mixers[sde_crtc->num_ctls]; mixer->hw_ctl = sde_rm_get_ctl_path(sde_kms, i); if (IS_ERR_OR_NULL(mixer->hw_ctl)) { DRM_ERROR("Invalid ctl_path\n"); return PTR_ERR(mixer->hw_ctl); } sde_crtc->num_ctls++; } } /* shortcut this process if encoder has no ctl paths */ if (!sde_crtc->num_ctls) return 0; /* * Get default LMs if specified in platform config * other wise acquire the free LMs */ for (i = INTF_0; i <= sde_kms->catalog->intf_count; i++) { if (enc_hw_res.intfs[i]) { struct sde_crtc_mixer *mixer = &sde_crtc->mixers[sde_crtc->num_mixers]; plat_hw_res_map = sde_rm_get_res_map(sde_kms, i, SDE_NONE); lm_idx = plat_hw_res_map->lm; if (!lm_idx && unused_lm_count) lm_idx = unused_lm_id[--unused_lm_count]; DBG("intf %d acquiring lm %d", i, lm_idx); mixer->hw_lm = sde_rm_acquire_mixer(sde_kms, lm_idx); if (IS_ERR_OR_NULL(mixer->hw_lm)) { DRM_ERROR("Invalid mixer\n"); return -EACCES; } sde_crtc->num_mixers++; } } /* * Get default LMs if specified in platform config, * otherwise acquire the free LMs. */ for (i = WB_0; i < WB_MAX; i++) { if (enc_hw_res.wbs[i]) { struct sde_crtc_mixer *mixer = &sde_crtc->mixers[sde_crtc->num_mixers]; plat_hw_res_map = sde_rm_get_res_map(sde_kms, SDE_NONE, i); lm_idx = plat_hw_res_map->lm; if (!lm_idx && unused_lm_count) lm_idx = unused_lm_id[--unused_lm_count]; DBG("wb %d acquiring lm %d", i, lm_idx); mixer->hw_lm = sde_rm_acquire_mixer(sde_kms, lm_idx); if (IS_ERR_OR_NULL(mixer->hw_lm)) { DRM_ERROR("Invalid mixer\n"); return -EACCES; } sde_crtc->num_mixers++; } } DBG("control paths %d, num_mixers %d, lm[0] %d, ctl[0] %d ", sde_crtc->num_ctls, sde_crtc->num_mixers, sde_crtc->mixers[0].hw_lm->idx, sde_crtc->mixers[0].hw_ctl->idx); if (sde_crtc->num_mixers > 1) DBG("lm[1] %d, ctl[1], %d", sde_crtc->mixers[1].hw_lm->idx, sde_crtc->mixers[1].hw_ctl->idx); return 0; } static void sde_crtc_destroy(struct drm_crtc *crtc) static void sde_crtc_destroy(struct drm_crtc *crtc) { { struct sde_crtc *sde_crtc = to_sde_crtc(crtc); struct sde_crtc *sde_crtc = to_sde_crtc(crtc); Loading Loading @@ -561,6 +451,66 @@ static void _sde_crtc_wait_for_fences(struct drm_crtc *crtc) } } } } static void _sde_crtc_setup_mixer_for_encoder( struct drm_crtc *crtc, struct drm_encoder *enc) { struct sde_crtc *sde_crtc = to_sde_crtc(crtc); struct sde_kms *sde_kms = get_kms(crtc); struct sde_rm *rm = &sde_kms->rm; struct sde_crtc_mixer *mixer; int i; struct sde_rm_hw_iter lm_iter, ctl_iter; sde_rm_init_hw_iter(&lm_iter, enc->base.id, SDE_HW_BLK_LM); sde_rm_init_hw_iter(&ctl_iter, enc->base.id, SDE_HW_BLK_CTL); /* Set up the mixer for this encoder, checking all channels */ for (i = sde_crtc->num_mixers; i < ARRAY_SIZE(sde_crtc->mixers); i++) { mixer = &sde_crtc->mixers[i]; /* Add mixer if reservation exists on (encoder, chan) */ if (!sde_rm_get_hw(rm, &lm_iter)) break; mixer->hw_lm = (struct sde_hw_mixer *)lm_iter.hw; /* CTL may be null, not necessarily 1:1 with LM */ (void) sde_rm_get_hw(rm, &ctl_iter); mixer->hw_ctl = (struct sde_hw_ctl *)ctl_iter.hw; mixer->flush_mask = 0; mixer->encoder = enc; sde_crtc->num_mixers++; SDE_DEBUG("setup mixer %d: lm %d\n", i, mixer->hw_lm->idx); if (mixer->hw_ctl) { sde_crtc->num_ctls++; SDE_DEBUG("setup mixer %d: ctl %d\n", i, mixer->hw_ctl->idx); } } } static void _sde_crtc_setup_mixers(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc = to_sde_crtc(crtc); struct drm_encoder *enc; sde_crtc->num_ctls = 0; sde_crtc->num_mixers = 0; memset(sde_crtc->mixers, 0, sizeof(sde_crtc->mixers)); /* Check for mixers on all encoders attached to this crtc */ list_for_each_entry(enc, &crtc->dev->mode_config.encoder_list, head) { if (enc->crtc != crtc) continue; _sde_crtc_setup_mixer_for_encoder(crtc, enc); } } static void sde_crtc_atomic_begin(struct drm_crtc *crtc, static void sde_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) struct drm_crtc_state *old_crtc_state) { { Loading @@ -579,6 +529,8 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, sde_crtc = to_sde_crtc(crtc); sde_crtc = to_sde_crtc(crtc); dev = crtc->dev; dev = crtc->dev; _sde_crtc_setup_mixers(crtc); if (sde_crtc->event) { if (sde_crtc->event) { WARN_ON(sde_crtc->event); WARN_ON(sde_crtc->event); } else { } else { Loading Loading @@ -832,7 +784,6 @@ static void sde_crtc_enable(struct drm_crtc *crtc) struct sde_hw_mixer_cfg cfg; struct sde_hw_mixer_cfg cfg; u32 mixer_width; u32 mixer_width; int i; int i; int rc; if (!crtc) { if (!crtc) { DRM_ERROR("invalid crtc\n"); DRM_ERROR("invalid crtc\n"); Loading @@ -851,20 +802,7 @@ static void sde_crtc_enable(struct drm_crtc *crtc) drm_mode_debug_printmodeline(mode); drm_mode_debug_printmodeline(mode); /* /* Update LMs for dual mode: mixer_width = half mode width */ * reserve mixer(s) if not already avaialable * if dual mode, mixer_width = half mode width * program mode configuration on mixer(s) */ if ((sde_crtc->num_ctls == 0) || (sde_crtc->num_mixers == 0)) { rc = sde_crtc_reserve_hw_resources(crtc); if (rc) { DRM_ERROR("error reserving HW resource for CRTC\n"); return; } } if (sde_crtc->num_mixers == CRTC_DUAL_MIXERS) if (sde_crtc->num_mixers == CRTC_DUAL_MIXERS) mixer_width = mode->hdisplay >> 1; mixer_width = mode->hdisplay >> 1; else else Loading Loading @@ -1200,7 +1138,6 @@ static void _sde_crtc_init_debugfs(struct sde_crtc *sde_crtc, /* initialize crtc */ /* initialize crtc */ struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_encoder *encoder, struct drm_plane *plane, struct drm_plane *plane, int drm_crtc_id) int drm_crtc_id) { { Loading @@ -1208,7 +1145,6 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct sde_crtc *sde_crtc = NULL; struct sde_crtc *sde_crtc = NULL; struct msm_drm_private *priv = NULL; struct msm_drm_private *priv = NULL; struct sde_kms *kms = NULL; struct sde_kms *kms = NULL; int i, rc; priv = dev->dev_private; priv = dev->dev_private; kms = to_sde_kms(priv->kms); kms = to_sde_kms(priv->kms); Loading @@ -1229,15 +1165,6 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev, drm_crtc_helper_add(crtc, &sde_crtc_helper_funcs); drm_crtc_helper_add(crtc, &sde_crtc_helper_funcs); plane->crtc = crtc; plane->crtc = crtc; for (i = 0; i < ARRAY_SIZE(sde_crtc->mixers); i++) sde_crtc->mixers[i].encoder = encoder; rc = sde_crtc_reserve_hw_resources(crtc); if (rc) { DRM_ERROR(" error reserving HW resource for this CRTC\n"); return ERR_PTR(-EINVAL); } /* save user friendly CRTC name for later */ /* save user friendly CRTC name for later */ snprintf(sde_crtc->name, SDE_CRTC_NAME_SIZE, "crtc%u", crtc->base.id); snprintf(sde_crtc->name, SDE_CRTC_NAME_SIZE, "crtc%u", crtc->base.id); Loading
drivers/gpu/drm/msm/sde/sde_crtc.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -62,6 +62,7 @@ struct sde_crtc_mixer { struct sde_crtc { struct sde_crtc { struct drm_crtc base; struct drm_crtc base; char name[SDE_CRTC_NAME_SIZE]; char name[SDE_CRTC_NAME_SIZE]; int drm_crtc_id; int drm_crtc_id; spinlock_t lm_lock; /* protect registers */ spinlock_t lm_lock; /* protect registers */ Loading
drivers/gpu/drm/msm/sde/sde_encoder.c +69 −76 Original line number Original line Diff line number Diff line Loading @@ -70,6 +70,8 @@ struct sde_encoder_virt { spinlock_t spin_lock; spinlock_t spin_lock; uint32_t bus_scaling_client; uint32_t bus_scaling_client; uint32_t display_num_of_h_tiles; unsigned int num_phys_encs; unsigned int num_phys_encs; struct sde_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL]; struct sde_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL]; struct sde_encoder_phys *cur_master; struct sde_encoder_phys *cur_master; Loading Loading @@ -155,14 +157,15 @@ static void bs_set(struct sde_encoder_virt *sde_enc, int idx) #endif #endif void sde_encoder_get_hw_resources(struct drm_encoder *drm_enc, void sde_encoder_get_hw_resources(struct drm_encoder *drm_enc, struct sde_encoder_hw_resources *hw_res) struct sde_encoder_hw_resources *hw_res, struct drm_connector_state *conn_state) { { struct sde_encoder_virt *sde_enc = NULL; struct sde_encoder_virt *sde_enc = NULL; int i = 0; int i = 0; DBG(""); DBG(""); if (!hw_res || !drm_enc) { if (!hw_res || !drm_enc || !conn_state) { DRM_ERROR("Invalid pointer"); DRM_ERROR("Invalid pointer"); return; return; } } Loading @@ -171,11 +174,13 @@ void sde_encoder_get_hw_resources(struct drm_encoder *drm_enc, /* Query resources used by phys encs, expected to be without overlap */ /* Query resources used by phys encs, expected to be without overlap */ memset(hw_res, 0, sizeof(*hw_res)); memset(hw_res, 0, sizeof(*hw_res)); hw_res->display_num_of_h_tiles = sde_enc->display_num_of_h_tiles; for (i = 0; i < sde_enc->num_phys_encs; i++) { for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; if (phys && phys->ops.get_hw_resources) if (phys && phys->ops.get_hw_resources) phys->ops.get_hw_resources(phys, hw_res); phys->ops.get_hw_resources(phys, hw_res, conn_state); } } } } Loading Loading @@ -231,54 +236,14 @@ static void sde_encoder_destroy(struct drm_encoder *drm_enc) kfree(sde_enc); kfree(sde_enc); } } static bool sde_encoder_virt_mode_fixup(struct drm_encoder *drm_enc, static int sde_encoder_virt_atomic_check( const struct drm_display_mode *mode, struct drm_encoder *drm_enc, struct drm_display_mode *adj_mode) { struct sde_encoder_virt *sde_enc = NULL; int i = 0; bool ret = true; DBG(""); if (!drm_enc) { DRM_ERROR("Invalid pointer"); return false; } sde_enc = to_sde_encoder_virt(drm_enc); MSM_EVT(drm_enc->dev, 0, 0); for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; if (phys && phys->ops.mode_fixup) { ret = phys->ops.mode_fixup(phys, mode, adj_mode); if (!ret) { DRM_ERROR("Mode unsupported, phys_enc %d\n", i); break; } if (sde_enc->num_phys_encs > 1) { DBG("ModeFix only checking 1 phys_enc"); break; } } } /* Call to populate mode->crtc* information required by framework */ drm_mode_set_crtcinfo(adj_mode, 0); MSM_EVT(drm_enc->dev, adj_mode->flags, adj_mode->private_flags); return ret; } static int sde_encoder_virt_atomic_check(struct drm_encoder *drm_enc, struct drm_crtc_state *crtc_state, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) struct drm_connector_state *conn_state) { { struct sde_encoder_virt *sde_enc = NULL; struct sde_encoder_virt *sde_enc; struct msm_drm_private *priv; struct sde_kms *sde_kms; const struct drm_display_mode *mode; const struct drm_display_mode *mode; struct drm_display_mode *adj_mode; struct drm_display_mode *adj_mode; int i = 0; int i = 0; Loading @@ -292,6 +257,8 @@ static int sde_encoder_virt_atomic_check(struct drm_encoder *drm_enc, } } sde_enc = to_sde_encoder_virt(drm_enc); sde_enc = to_sde_encoder_virt(drm_enc); priv = drm_enc->dev->dev_private; sde_kms = to_sde_kms(priv->kms); mode = &crtc_state->mode; mode = &crtc_state->mode; adj_mode = &crtc_state->adjusted_mode; adj_mode = &crtc_state->adjusted_mode; MSM_EVT(drm_enc->dev, 0, 0); MSM_EVT(drm_enc->dev, 0, 0); Loading @@ -300,23 +267,25 @@ static int sde_encoder_virt_atomic_check(struct drm_encoder *drm_enc, for (i = 0; i < sde_enc->num_phys_encs; i++) { for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; if (phys && phys->ops.atomic_check) { if (phys && phys->ops.atomic_check) ret = phys->ops.atomic_check(phys, crtc_state, ret = phys->ops.atomic_check(phys, crtc_state, conn_state); conn_state); if (ret) else if (phys && phys->ops.mode_fixup) DRM_ERROR("Mode unsupported, phys_enc %d.%d\n", if (!phys->ops.mode_fixup(phys, mode, adj_mode)) drm_enc->base.id, i); break; } else if (phys && phys->ops.mode_fixup) { if (!phys->ops.mode_fixup(phys, mode, adj_mode)) { DRM_ERROR("Mode unsupported, phys_enc %d.%d\n", drm_enc->base.id, i); ret = -EINVAL; ret = -EINVAL; } if (ret) { SDE_ERROR("enc %d mode unsupported, phys %d\n", drm_enc->base.id, i); break; break; } } } } /* Reserve dynamic resources now. Indicating AtomicTest phase */ if (!ret) ret = sde_rm_reserve(&sde_kms->rm, drm_enc, crtc_state, conn_state, true); /* Call to populate mode->crtc* information required by framework */ /* Call to populate mode->crtc* information required by framework */ drm_mode_set_crtcinfo(adj_mode, 0); drm_mode_set_crtcinfo(adj_mode, 0); Loading @@ -329,8 +298,12 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, struct drm_display_mode *mode, struct drm_display_mode *mode, struct drm_display_mode *adj_mode) struct drm_display_mode *adj_mode) { { struct sde_encoder_virt *sde_enc = NULL; struct sde_encoder_virt *sde_enc; int i = 0; struct msm_drm_private *priv; struct sde_kms *sde_kms; struct list_head *connector_list; struct drm_connector *conn = NULL, *conn_iter; int i = 0, ret; DBG(""); DBG(""); Loading @@ -340,8 +313,31 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, } } sde_enc = to_sde_encoder_virt(drm_enc); sde_enc = to_sde_encoder_virt(drm_enc); priv = drm_enc->dev->dev_private; sde_kms = to_sde_kms(priv->kms); connector_list = &sde_kms->dev->mode_config.connector_list; MSM_EVT(drm_enc->dev, 0, 0); MSM_EVT(drm_enc->dev, 0, 0); list_for_each_entry(conn_iter, connector_list, head) if (conn_iter->encoder == drm_enc) conn = conn_iter; if (!conn) { SDE_ERROR("enc %d failed to find attached connector\n", drm_enc->base.id); return; } /* Reserve dynamic resources now. Indicating non-AtomicTest phase */ ret = sde_rm_reserve(&sde_kms->rm, drm_enc, drm_enc->crtc->state, conn->state, false); if (ret) { SDE_ERROR("enc %d failed to reserve hw resources, ret %d\n", drm_enc->base.id, ret); return; } for (i = 0; i < sde_enc->num_phys_encs; i++) { for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; Loading Loading @@ -390,6 +386,8 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) { { struct sde_encoder_virt *sde_enc = NULL; struct sde_encoder_virt *sde_enc = NULL; struct msm_drm_private *priv; struct sde_kms *sde_kms; int i = 0; int i = 0; DBG(""); DBG(""); Loading @@ -400,6 +398,9 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) } } sde_enc = to_sde_encoder_virt(drm_enc); sde_enc = to_sde_encoder_virt(drm_enc); priv = drm_enc->dev->dev_private; sde_kms = to_sde_kms(priv->kms); MSM_EVT(drm_enc->dev, 0, 0); MSM_EVT(drm_enc->dev, 0, 0); for (i = 0; i < sde_enc->num_phys_encs; i++) { for (i = 0; i < sde_enc->num_phys_encs; i++) { Loading @@ -413,10 +414,11 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) DBG("clear phys enc master"); DBG("clear phys enc master"); bs_set(sde_enc, 0); bs_set(sde_enc, 0); sde_rm_release(&sde_kms->rm, drm_enc); } } static const struct drm_encoder_helper_funcs sde_encoder_helper_funcs = { static const struct drm_encoder_helper_funcs sde_encoder_helper_funcs = { .mode_fixup = sde_encoder_virt_mode_fixup, .mode_set = sde_encoder_virt_mode_set, .mode_set = sde_encoder_virt_mode_set, .disable = sde_encoder_virt_disable, .disable = sde_encoder_virt_disable, .enable = sde_encoder_virt_enable, .enable = sde_encoder_virt_enable, Loading Loading @@ -699,6 +701,8 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc, WARN_ON(disp_info->num_of_h_tiles < 1); WARN_ON(disp_info->num_of_h_tiles < 1); sde_enc->display_num_of_h_tiles = disp_info->num_of_h_tiles; DBG("dsi_info->num_of_h_tiles %d", disp_info->num_of_h_tiles); DBG("dsi_info->num_of_h_tiles %d", disp_info->num_of_h_tiles); for (i = 0; i < disp_info->num_of_h_tiles && !ret; i++) { for (i = 0; i < disp_info->num_of_h_tiles && !ret; i++) { Loading @@ -707,7 +711,6 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc, * h_tile_instance_ids[2] = {0, 1}; DSI0 = left, DSI1 = right * h_tile_instance_ids[2] = {0, 1}; DSI0 = left, DSI1 = right * h_tile_instance_ids[2] = {1, 0}; DSI1 = left, DSI0 = right * h_tile_instance_ids[2] = {1, 0}; DSI1 = left, DSI0 = right */ */ const struct sde_hw_res_map *hw_res_map = NULL; u32 controller_id = disp_info->h_tile_instance[i]; u32 controller_id = disp_info->h_tile_instance[i]; if (disp_info->num_of_h_tiles > 1) { if (disp_info->num_of_h_tiles > 1) { Loading @@ -723,6 +726,7 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc, i, controller_id, phys_params.split_role); i, controller_id, phys_params.split_role); if (intf_type == INTF_WB) { if (intf_type == INTF_WB) { phys_params.intf_idx = INTF_MAX; phys_params.wb_idx = sde_encoder_get_wb( phys_params.wb_idx = sde_encoder_get_wb( sde_kms->catalog, sde_kms->catalog, intf_type, controller_id); intf_type, controller_id); Loading @@ -733,6 +737,7 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc, ret = -EINVAL; ret = -EINVAL; } } } else { } else { phys_params.wb_idx = WB_MAX; phys_params.intf_idx = sde_encoder_get_intf( phys_params.intf_idx = sde_encoder_get_intf( sde_kms->catalog, intf_type, sde_kms->catalog, intf_type, controller_id); controller_id); Loading @@ -744,18 +749,6 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc, } } } } hw_res_map = sde_rm_get_res_map(sde_kms, phys_params.intf_idx, phys_params.wb_idx); if (IS_ERR_OR_NULL(hw_res_map)) { DRM_ERROR("failed to get hw_res_map: %ld\n", PTR_ERR(hw_res_map)); ret = -EINVAL; } else { phys_params.pp_idx = hw_res_map->pp; phys_params.ctl_idx = hw_res_map->ctl; phys_params.cdm_idx = hw_res_map->cdm; } if (!ret) { if (!ret) { if (intf_type == INTF_WB) if (intf_type == INTF_WB) ret = sde_encoder_virt_add_phys_enc_wb(sde_enc, ret = sde_encoder_virt_add_phys_enc_wb(sde_enc, Loading