Loading msm/sde/sde_crtc.c +4 −2 Original line number Diff line number Diff line Loading @@ -852,7 +852,8 @@ static int _sde_crtc_set_lm_roi(struct drm_crtc *crtc, * hence, crtc roi must match the mixer dimensions. */ if (crtc_state->num_ds_enabled || sde_rm_topology_is_3dmux_dsc(&sde_kms->rm, state)) { sde_rm_topology_is_group(&sde_kms->rm, state, SDE_RM_TOPOLOGY_GROUP_3DMERGE_DSC)) { if (memcmp(lm_roi, lm_bounds, sizeof(struct sde_rect))) { SDE_ERROR("Unsupported: Dest scaler/3d mux DSC + PU\n"); return -EINVAL; Loading Loading @@ -4815,7 +4816,8 @@ static int _sde_crtc_check_plane_layout(struct drm_crtc *crtc, return -EINVAL; } if (!sde_rm_topology_is_quad_pipe(&kms->rm, crtc_state)) if (!sde_rm_topology_is_group(&kms->rm, crtc_state, SDE_RM_TOPOLOGY_GROUP_QUADPIPE)) return 0; drm_atomic_crtc_state_for_each_plane(plane, crtc_state) { Loading msm/sde/sde_rm.c +60 −67 Original line number Diff line number Diff line Loading @@ -2121,84 +2121,77 @@ int sde_rm_update_topology(struct sde_rm *rm, return ret; } bool sde_rm_topology_is_quad_pipe(struct sde_rm *rm, struct drm_crtc_state *state) bool sde_rm_topology_is_group(struct sde_rm *rm, struct drm_crtc_state *state, enum sde_rm_topology_group group) { int i; int i, ret = 0; struct sde_crtc_state *cstate; uint64_t topology = SDE_RM_TOPOLOGY_NONE; if ((!rm) || (!state)) { pr_err("invalid arguments: rm:%d state:%d\n", rm == NULL, state == NULL); struct drm_connector *conn; struct drm_connector_state *conn_state; struct msm_display_topology topology; enum sde_rm_topology_name name; if ((!rm) || (!state) || (!state->state)) { pr_err("invalid arguments: rm:%d state:%d atomic state:%d\n", !rm, !state, state ? (!state->state) : 0); return false; } cstate = to_sde_crtc_state(state); for (i = 0; i < cstate->num_connectors; i++) { struct drm_connector *conn = cstate->connectors[i]; topology = sde_connector_get_topology_name(conn); if (TOPOLOGY_QUADPIPE_MERGE_MODE(topology)) return true; conn = cstate->connectors[i]; if (!conn) { SDE_DEBUG("invalid connector\n"); continue; } return false; conn_state = drm_atomic_get_connector_state(state->state, conn); if (!conn_state) { SDE_DEBUG("%s invalid connector state\n", conn->name); continue; } bool sde_rm_topology_is_dual_pipe(struct sde_rm *rm, struct drm_crtc_state *state) { int i; struct sde_crtc_state *cstate; uint64_t topology = SDE_RM_TOPOLOGY_NONE; if ((!rm) || (!state)) { pr_err("invalid arguments: rm:%d state:%d\n", rm == NULL, state == NULL); return false; ret = sde_connector_state_get_topology(conn_state, &topology); if (ret) { SDE_DEBUG("%s invalid topology\n", conn->name); continue; } cstate = to_sde_crtc_state(state); for (i = 0; i < cstate->num_connectors; i++) { struct drm_connector *conn = cstate->connectors[i]; topology = sde_connector_get_topology_name(conn); if (TOPOLOGY_DUALPIPE_MERGE_MODE(topology)) name = sde_rm_get_topology_name(rm, topology); switch (group) { case SDE_RM_TOPOLOGY_GROUP_SINGLEPIPE: if (TOPOLOGY_SINGLEPIPE_MODE(name)) return true; } return false; } bool sde_rm_topology_is_3dmux_dsc(struct sde_rm *rm, struct drm_crtc_state *state) { int i; struct sde_crtc_state *cstate; uint64_t topology = SDE_RM_TOPOLOGY_NONE; const struct sde_rm_topology_def *def; int num_lm, num_enc; if ((!rm) || (!state)) { pr_err("invalid arguments: rm:%d state:%d\n", rm == NULL, state == NULL); break; case SDE_RM_TOPOLOGY_GROUP_DUALPIPE: if (TOPOLOGY_DUALPIPE_MODE(name)) return true; break; case SDE_RM_TOPOLOGY_GROUP_QUADPIPE: if (TOPOLOGY_QUADPIPE_MODE(name)) return true; break; case SDE_RM_TOPOLOGY_GROUP_3DMERGE: if (topology.num_lm > topology.num_intf && !topology.num_enc) return true; break; case SDE_RM_TOPOLOGY_GROUP_3DMERGE_DSC: if (topology.num_lm > topology.num_enc && topology.num_enc) return true; break; case SDE_RM_TOPOLOGY_GROUP_DSCMERGE: if (topology.num_lm == topology.num_enc && topology.num_enc) return true; break; default: SDE_ERROR("invalid topology group\n"); return false; } cstate = to_sde_crtc_state(state); for (i = 0; i < cstate->num_connectors; i++) { struct drm_connector *conn = cstate->connectors[i]; topology = sde_connector_get_topology_name(conn); def = sde_rm_topology_get_topology_def(rm, topology); num_lm = def->num_lm; num_enc = def->num_comp_enc; if (num_lm > num_enc && num_enc) return true; } return false; Loading msm/sde/sde_rm.h +42 −32 Original line number Diff line number Diff line Loading @@ -14,18 +14,25 @@ #define SINGLE_CTL 1 #define DUAL_CTL 2 #define TOPOLOGY_QUADPIPE_MERGE_MODE(x) \ #define TOPOLOGY_SINGLEPIPE_MODE(x) \ (x == SDE_RM_TOPOLOGY_SINGLEPIPE ||\ x == SDE_RM_TOPOLOGY_SINGLEPIPE_DSC ||\ x == SDE_RM_TOPOLOGY_SINGLEPIPE_VDC) #define TOPOLOGY_DUALPIPE_MODE(x) \ (x == SDE_RM_TOPOLOGY_DUALPIPE ||\ x == SDE_RM_TOPOLOGY_DUALPIPE_DSC ||\ x == SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE ||\ x == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE ||\ x == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_VDC ||\ x == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC) #define TOPOLOGY_QUADPIPE_MODE(x) \ (x == SDE_RM_TOPOLOGY_QUADPIPE_3DMERGE ||\ x == SDE_RM_TOPOLOGY_QUADPIPE_3DMERGE_DSC ||\ x == SDE_RM_TOPOLOGY_QUADPIPE_DSCMERGE ||\ x == SDE_RM_TOPOLOGY_QUADPIPE_DSC4HSMERGE) #define TOPOLOGY_DUALPIPE_MERGE_MODE(x) \ (x == SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE || \ x == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE || \ x == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_VDC || \ x == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC) /** * enum sde_rm_topology_name - HW resource use case in use by connector * @SDE_RM_TOPOLOGY_NONE: No topology in use currently Loading Loading @@ -63,6 +70,27 @@ enum sde_rm_topology_name { SDE_RM_TOPOLOGY_MAX, }; /** * enum sde_rm_topology_group - Topology group selection * @SDE_RM_TOPOLOGY_GROUP_NONE: No topology group in use currently * @SDE_RM_TOPOLOGY_GROUP_SINGLEPIPE: Any topology that uses 1 LM * @SDE_RM_TOPOLOGY_GROUP_DUALPIPE: Any topology that uses 2 LM * @SDE_RM_TOPOLOGY_GROUP_QUADPIPE: Any topology that uses 4 LM * @SDE_RM_TOPOLOGY_GROUP_3DMERGE: Any topology that uses 3D merge only * @SDE_RM_TOPOLOGY_GROUP_3DMERGE_DSC: Any topology that uses 3D merge + DSC * @SDE_RM_TOPOLOGY_GROUP_DSCMERGE: Any topology that uses DSC merge */ enum sde_rm_topology_group { SDE_RM_TOPOLOGY_GROUP_NONE = 0, SDE_RM_TOPOLOGY_GROUP_SINGLEPIPE, SDE_RM_TOPOLOGY_GROUP_DUALPIPE, SDE_RM_TOPOLOGY_GROUP_QUADPIPE, SDE_RM_TOPOLOGY_GROUP_3DMERGE, SDE_RM_TOPOLOGY_GROUP_3DMERGE_DSC, SDE_RM_TOPOLOGY_GROUP_DSCMERGE, SDE_RM_TOPOLOGY_GROUP_MAX, }; /** * enum sde_rm_topology_control - HW resource use case in use by connector * @SDE_RM_TOPCTL_RESERVE_LOCK: If set, in AtomicTest phase, after a successful Loading Loading @@ -350,34 +378,16 @@ static inline int sde_rm_topology_get_num_lm(struct sde_rm *rm, } /** * sde_rm_topology_is_dual_pipe - check if the topology used * is a dual-pipe mode one * @rm: SDE Resource Manager handle * @state: drm state of the crtc * @return: true if attached connector is in dual-pipe mode */ bool sde_rm_topology_is_dual_pipe(struct sde_rm *rm, struct drm_crtc_state *state); /** * sde_rm_topology_is_3dmux_dsc - check if the topology used * is a 3dmerge dsc mode one * @rm: SDE Resource Manager handle * @state: drm state of the crtc * @return: true if attached connector is in 3DMERGE DSC mode */ bool sde_rm_topology_is_3dmux_dsc(struct sde_rm *rm, struct drm_crtc_state *state); /** * sde_rm_topology_is_quad_pipe - check if the topology used * is a quad-pipe mode one * sde_rm_topology_is_group - check if the topology in use * is part of the requested group * @rm: SDE Resource Manager handle * @state: drm state of the crtc * @return: true if attached connector is in quad-pipe mode * @group: topology group to check * @return: true if attached connector is in the topology group */ bool sde_rm_topology_is_quad_pipe(struct sde_rm *rm, struct drm_crtc_state *state); bool sde_rm_topology_is_group(struct sde_rm *rm, struct drm_crtc_state *state, enum sde_rm_topology_group group); /** * sde_rm_ext_blk_create_reserve - Create external HW blocks Loading Loading
msm/sde/sde_crtc.c +4 −2 Original line number Diff line number Diff line Loading @@ -852,7 +852,8 @@ static int _sde_crtc_set_lm_roi(struct drm_crtc *crtc, * hence, crtc roi must match the mixer dimensions. */ if (crtc_state->num_ds_enabled || sde_rm_topology_is_3dmux_dsc(&sde_kms->rm, state)) { sde_rm_topology_is_group(&sde_kms->rm, state, SDE_RM_TOPOLOGY_GROUP_3DMERGE_DSC)) { if (memcmp(lm_roi, lm_bounds, sizeof(struct sde_rect))) { SDE_ERROR("Unsupported: Dest scaler/3d mux DSC + PU\n"); return -EINVAL; Loading Loading @@ -4815,7 +4816,8 @@ static int _sde_crtc_check_plane_layout(struct drm_crtc *crtc, return -EINVAL; } if (!sde_rm_topology_is_quad_pipe(&kms->rm, crtc_state)) if (!sde_rm_topology_is_group(&kms->rm, crtc_state, SDE_RM_TOPOLOGY_GROUP_QUADPIPE)) return 0; drm_atomic_crtc_state_for_each_plane(plane, crtc_state) { Loading
msm/sde/sde_rm.c +60 −67 Original line number Diff line number Diff line Loading @@ -2121,84 +2121,77 @@ int sde_rm_update_topology(struct sde_rm *rm, return ret; } bool sde_rm_topology_is_quad_pipe(struct sde_rm *rm, struct drm_crtc_state *state) bool sde_rm_topology_is_group(struct sde_rm *rm, struct drm_crtc_state *state, enum sde_rm_topology_group group) { int i; int i, ret = 0; struct sde_crtc_state *cstate; uint64_t topology = SDE_RM_TOPOLOGY_NONE; if ((!rm) || (!state)) { pr_err("invalid arguments: rm:%d state:%d\n", rm == NULL, state == NULL); struct drm_connector *conn; struct drm_connector_state *conn_state; struct msm_display_topology topology; enum sde_rm_topology_name name; if ((!rm) || (!state) || (!state->state)) { pr_err("invalid arguments: rm:%d state:%d atomic state:%d\n", !rm, !state, state ? (!state->state) : 0); return false; } cstate = to_sde_crtc_state(state); for (i = 0; i < cstate->num_connectors; i++) { struct drm_connector *conn = cstate->connectors[i]; topology = sde_connector_get_topology_name(conn); if (TOPOLOGY_QUADPIPE_MERGE_MODE(topology)) return true; conn = cstate->connectors[i]; if (!conn) { SDE_DEBUG("invalid connector\n"); continue; } return false; conn_state = drm_atomic_get_connector_state(state->state, conn); if (!conn_state) { SDE_DEBUG("%s invalid connector state\n", conn->name); continue; } bool sde_rm_topology_is_dual_pipe(struct sde_rm *rm, struct drm_crtc_state *state) { int i; struct sde_crtc_state *cstate; uint64_t topology = SDE_RM_TOPOLOGY_NONE; if ((!rm) || (!state)) { pr_err("invalid arguments: rm:%d state:%d\n", rm == NULL, state == NULL); return false; ret = sde_connector_state_get_topology(conn_state, &topology); if (ret) { SDE_DEBUG("%s invalid topology\n", conn->name); continue; } cstate = to_sde_crtc_state(state); for (i = 0; i < cstate->num_connectors; i++) { struct drm_connector *conn = cstate->connectors[i]; topology = sde_connector_get_topology_name(conn); if (TOPOLOGY_DUALPIPE_MERGE_MODE(topology)) name = sde_rm_get_topology_name(rm, topology); switch (group) { case SDE_RM_TOPOLOGY_GROUP_SINGLEPIPE: if (TOPOLOGY_SINGLEPIPE_MODE(name)) return true; } return false; } bool sde_rm_topology_is_3dmux_dsc(struct sde_rm *rm, struct drm_crtc_state *state) { int i; struct sde_crtc_state *cstate; uint64_t topology = SDE_RM_TOPOLOGY_NONE; const struct sde_rm_topology_def *def; int num_lm, num_enc; if ((!rm) || (!state)) { pr_err("invalid arguments: rm:%d state:%d\n", rm == NULL, state == NULL); break; case SDE_RM_TOPOLOGY_GROUP_DUALPIPE: if (TOPOLOGY_DUALPIPE_MODE(name)) return true; break; case SDE_RM_TOPOLOGY_GROUP_QUADPIPE: if (TOPOLOGY_QUADPIPE_MODE(name)) return true; break; case SDE_RM_TOPOLOGY_GROUP_3DMERGE: if (topology.num_lm > topology.num_intf && !topology.num_enc) return true; break; case SDE_RM_TOPOLOGY_GROUP_3DMERGE_DSC: if (topology.num_lm > topology.num_enc && topology.num_enc) return true; break; case SDE_RM_TOPOLOGY_GROUP_DSCMERGE: if (topology.num_lm == topology.num_enc && topology.num_enc) return true; break; default: SDE_ERROR("invalid topology group\n"); return false; } cstate = to_sde_crtc_state(state); for (i = 0; i < cstate->num_connectors; i++) { struct drm_connector *conn = cstate->connectors[i]; topology = sde_connector_get_topology_name(conn); def = sde_rm_topology_get_topology_def(rm, topology); num_lm = def->num_lm; num_enc = def->num_comp_enc; if (num_lm > num_enc && num_enc) return true; } return false; Loading
msm/sde/sde_rm.h +42 −32 Original line number Diff line number Diff line Loading @@ -14,18 +14,25 @@ #define SINGLE_CTL 1 #define DUAL_CTL 2 #define TOPOLOGY_QUADPIPE_MERGE_MODE(x) \ #define TOPOLOGY_SINGLEPIPE_MODE(x) \ (x == SDE_RM_TOPOLOGY_SINGLEPIPE ||\ x == SDE_RM_TOPOLOGY_SINGLEPIPE_DSC ||\ x == SDE_RM_TOPOLOGY_SINGLEPIPE_VDC) #define TOPOLOGY_DUALPIPE_MODE(x) \ (x == SDE_RM_TOPOLOGY_DUALPIPE ||\ x == SDE_RM_TOPOLOGY_DUALPIPE_DSC ||\ x == SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE ||\ x == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE ||\ x == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_VDC ||\ x == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC) #define TOPOLOGY_QUADPIPE_MODE(x) \ (x == SDE_RM_TOPOLOGY_QUADPIPE_3DMERGE ||\ x == SDE_RM_TOPOLOGY_QUADPIPE_3DMERGE_DSC ||\ x == SDE_RM_TOPOLOGY_QUADPIPE_DSCMERGE ||\ x == SDE_RM_TOPOLOGY_QUADPIPE_DSC4HSMERGE) #define TOPOLOGY_DUALPIPE_MERGE_MODE(x) \ (x == SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE || \ x == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE || \ x == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_VDC || \ x == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC) /** * enum sde_rm_topology_name - HW resource use case in use by connector * @SDE_RM_TOPOLOGY_NONE: No topology in use currently Loading Loading @@ -63,6 +70,27 @@ enum sde_rm_topology_name { SDE_RM_TOPOLOGY_MAX, }; /** * enum sde_rm_topology_group - Topology group selection * @SDE_RM_TOPOLOGY_GROUP_NONE: No topology group in use currently * @SDE_RM_TOPOLOGY_GROUP_SINGLEPIPE: Any topology that uses 1 LM * @SDE_RM_TOPOLOGY_GROUP_DUALPIPE: Any topology that uses 2 LM * @SDE_RM_TOPOLOGY_GROUP_QUADPIPE: Any topology that uses 4 LM * @SDE_RM_TOPOLOGY_GROUP_3DMERGE: Any topology that uses 3D merge only * @SDE_RM_TOPOLOGY_GROUP_3DMERGE_DSC: Any topology that uses 3D merge + DSC * @SDE_RM_TOPOLOGY_GROUP_DSCMERGE: Any topology that uses DSC merge */ enum sde_rm_topology_group { SDE_RM_TOPOLOGY_GROUP_NONE = 0, SDE_RM_TOPOLOGY_GROUP_SINGLEPIPE, SDE_RM_TOPOLOGY_GROUP_DUALPIPE, SDE_RM_TOPOLOGY_GROUP_QUADPIPE, SDE_RM_TOPOLOGY_GROUP_3DMERGE, SDE_RM_TOPOLOGY_GROUP_3DMERGE_DSC, SDE_RM_TOPOLOGY_GROUP_DSCMERGE, SDE_RM_TOPOLOGY_GROUP_MAX, }; /** * enum sde_rm_topology_control - HW resource use case in use by connector * @SDE_RM_TOPCTL_RESERVE_LOCK: If set, in AtomicTest phase, after a successful Loading Loading @@ -350,34 +378,16 @@ static inline int sde_rm_topology_get_num_lm(struct sde_rm *rm, } /** * sde_rm_topology_is_dual_pipe - check if the topology used * is a dual-pipe mode one * @rm: SDE Resource Manager handle * @state: drm state of the crtc * @return: true if attached connector is in dual-pipe mode */ bool sde_rm_topology_is_dual_pipe(struct sde_rm *rm, struct drm_crtc_state *state); /** * sde_rm_topology_is_3dmux_dsc - check if the topology used * is a 3dmerge dsc mode one * @rm: SDE Resource Manager handle * @state: drm state of the crtc * @return: true if attached connector is in 3DMERGE DSC mode */ bool sde_rm_topology_is_3dmux_dsc(struct sde_rm *rm, struct drm_crtc_state *state); /** * sde_rm_topology_is_quad_pipe - check if the topology used * is a quad-pipe mode one * sde_rm_topology_is_group - check if the topology in use * is part of the requested group * @rm: SDE Resource Manager handle * @state: drm state of the crtc * @return: true if attached connector is in quad-pipe mode * @group: topology group to check * @return: true if attached connector is in the topology group */ bool sde_rm_topology_is_quad_pipe(struct sde_rm *rm, struct drm_crtc_state *state); bool sde_rm_topology_is_group(struct sde_rm *rm, struct drm_crtc_state *state, enum sde_rm_topology_group group); /** * sde_rm_ext_blk_create_reserve - Create external HW blocks Loading