Loading drivers/gpu/drm/msm/sde/sde_connector.c +23 −6 Original line number Diff line number Diff line Loading @@ -955,6 +955,7 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector, struct sde_connector *c_conn; struct sde_connector_state *c_state; int idx, rc; uint64_t fence_fd; if (!connector || !state || !property) { SDE_ERROR("invalid argument(s), conn %pK, state %pK, prp %pK\n", Loading Loading @@ -993,14 +994,30 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector, c_conn->fb_kmap); } break; default: break; case CONNECTOR_PROP_RETIRE_FENCE: rc = sde_fence_create(&c_conn->retire_fence, &fence_fd, 0); if (rc) { SDE_ERROR("fence create failed rc:%d\n", rc); goto end; } if (idx == CONNECTOR_PROP_ROI_V1) { rc = copy_to_user((uint64_t __user *)val, &fence_fd, sizeof(uint64_t)); if (rc) { SDE_ERROR("copy to user failed rc:%d\n", rc); /* fence will be released with timeline update */ put_unused_fd(fence_fd); rc = -EFAULT; goto end; } break; case CONNECTOR_PROP_ROI_V1: rc = _sde_connector_set_roi_v1(c_conn, c_state, (void *)val); if (rc) SDE_ERROR_CONN(c_conn, "invalid roi_v1, rc: %d\n", rc); break; default: break; } if (idx == CONNECTOR_PROP_HDR_METADATA) { Loading Loading @@ -1701,8 +1718,8 @@ struct drm_connector *sde_connector_init(struct drm_device *dev, msm_property_install_volatile_range(&c_conn->property_info, "hdr_metadata", 0x0, 0, ~0, 0, CONNECTOR_PROP_HDR_METADATA); msm_property_install_range(&c_conn->property_info, "RETIRE_FENCE", 0x0, 0, INR_OPEN_MAX, 0, CONNECTOR_PROP_RETIRE_FENCE); msm_property_install_volatile_range(&c_conn->property_info, "RETIRE_FENCE", 0x0, 0, ~0, 0, CONNECTOR_PROP_RETIRE_FENCE); msm_property_install_range(&c_conn->property_info, "autorefresh", 0x0, 0, AUTOREFRESH_MAX_FRAME_CNT, 0, Loading drivers/gpu/drm/msm/sde/sde_crtc.c +76 −51 Original line number Diff line number Diff line Loading @@ -4803,8 +4803,8 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc, "input_fence_timeout", 0x0, 0, SDE_CRTC_MAX_INPUT_FENCE_TIMEOUT, SDE_CRTC_INPUT_FENCE_TIMEOUT, CRTC_PROP_INPUT_FENCE_TIMEOUT); msm_property_install_range(&sde_crtc->property_info, "output_fence", 0x0, 0, INR_OPEN_MAX, 0, CRTC_PROP_OUTPUT_FENCE); msm_property_install_volatile_range(&sde_crtc->property_info, "output_fence", 0x0, 0, ~0, 0, CRTC_PROP_OUTPUT_FENCE); msm_property_install_range(&sde_crtc->property_info, "output_fence_offset", 0x0, 0, 1, 0, Loading Loading @@ -4976,6 +4976,47 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc, kfree(info); } static int _sde_crtc_get_output_fence(struct drm_crtc *crtc, const struct drm_crtc_state *state, uint64_t *val) { struct drm_encoder *encoder; struct sde_crtc *sde_crtc; struct sde_crtc_state *cstate; uint32_t offset, i; bool conn_offset = 0, is_cmd = true; sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(state); for (i = 0; i < cstate->num_connectors; ++i) { conn_offset = sde_connector_needs_offset(cstate->connectors[i]); if (conn_offset) break; } /** * set the cmd flag only when all the encoders attached * to the crtc are in cmd mode. Consider all other cases * as video mode. */ drm_for_each_encoder(encoder, crtc->dev) { if (encoder->crtc == crtc) is_cmd = sde_encoder_check_mode(encoder, MSM_DISPLAY_CAP_CMD_MODE); } offset = sde_crtc_get_property(cstate, CRTC_PROP_OUTPUT_FENCE_OFFSET); /** * set the offset to 0 only for cmd mode panels, so * the release fence for the current frame can be * triggered right after PP_DONE interrupt. */ offset = is_cmd ? 0 : (offset + conn_offset); return sde_fence_create(&sde_crtc->output_fence, val, offset); } /** * sde_crtc_atomic_set_property - atomically set a crtc drm property * @crtc: Pointer to drm crtc structure Loading @@ -4992,6 +5033,7 @@ static int sde_crtc_atomic_set_property(struct drm_crtc *crtc, struct sde_crtc *sde_crtc; struct sde_crtc_state *cstate; int idx, ret; uint64_t fence_fd; if (!crtc || !state || !property) { SDE_ERROR("invalid argument(s)\n"); Loading Loading @@ -5044,6 +5086,22 @@ static int sde_crtc_atomic_set_property(struct drm_crtc *crtc, cstate->bw_control = true; cstate->bw_split_vote = true; break; case CRTC_PROP_OUTPUT_FENCE: ret = _sde_crtc_get_output_fence(crtc, state, &fence_fd); if (ret) { SDE_ERROR("fence create failed rc:%d\n", ret); goto exit; } ret = copy_to_user((uint64_t __user *)val, &fence_fd, sizeof(uint64_t)); if (ret) { SDE_ERROR("copy to user failed rc:%d\n", ret); put_unused_fd(fence_fd); ret = -EFAULT; goto exit; } break; default: /* nothing to do */ break; Loading Loading @@ -5090,62 +5148,29 @@ static int sde_crtc_atomic_get_property(struct drm_crtc *crtc, { struct sde_crtc *sde_crtc; struct sde_crtc_state *cstate; struct drm_encoder *encoder; int i, ret = -EINVAL; bool conn_offset = 0; bool is_cmd = true; int ret = -EINVAL, i; if (!crtc || !state) { SDE_ERROR("invalid argument(s)\n"); } else { sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(state); for (i = 0; i < cstate->num_connectors; ++i) { conn_offset = sde_connector_needs_offset( cstate->connectors[i]); if (conn_offset) break; goto end; } /** * set the cmd flag only when all the encoders attached * to the crtc are in cmd mode. Consider all other cases * as video mode. */ drm_for_each_encoder(encoder, crtc->dev) { if (encoder->crtc == crtc) is_cmd = sde_encoder_check_mode(encoder, MSM_DISPLAY_CAP_CMD_MODE); } sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(state); i = msm_property_index(&sde_crtc->property_info, property); if (i == CRTC_PROP_OUTPUT_FENCE) { uint32_t offset = sde_crtc_get_property(cstate, CRTC_PROP_OUTPUT_FENCE_OFFSET); /** * set the offset to 0 only for cmd mode panels, so * the release fence for the current frame can be * triggered right after PP_DONE interrupt. */ offset = is_cmd ? 0 : (offset + conn_offset); ret = sde_fence_create(&sde_crtc->output_fence, val, offset); if (ret) SDE_ERROR("fence create failed\n"); ret = _sde_crtc_get_output_fence(crtc, state, val); } else { ret = msm_property_atomic_get(&sde_crtc->property_info, &cstate->property_state, property, val); &cstate->property_state, property, val); if (ret) ret = sde_cp_crtc_get_property(crtc, property, val); ret = sde_cp_crtc_get_property(crtc, property, val); } if (ret) DRM_ERROR("get property failed\n"); } end: return ret; } Loading Loading
drivers/gpu/drm/msm/sde/sde_connector.c +23 −6 Original line number Diff line number Diff line Loading @@ -955,6 +955,7 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector, struct sde_connector *c_conn; struct sde_connector_state *c_state; int idx, rc; uint64_t fence_fd; if (!connector || !state || !property) { SDE_ERROR("invalid argument(s), conn %pK, state %pK, prp %pK\n", Loading Loading @@ -993,14 +994,30 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector, c_conn->fb_kmap); } break; default: break; case CONNECTOR_PROP_RETIRE_FENCE: rc = sde_fence_create(&c_conn->retire_fence, &fence_fd, 0); if (rc) { SDE_ERROR("fence create failed rc:%d\n", rc); goto end; } if (idx == CONNECTOR_PROP_ROI_V1) { rc = copy_to_user((uint64_t __user *)val, &fence_fd, sizeof(uint64_t)); if (rc) { SDE_ERROR("copy to user failed rc:%d\n", rc); /* fence will be released with timeline update */ put_unused_fd(fence_fd); rc = -EFAULT; goto end; } break; case CONNECTOR_PROP_ROI_V1: rc = _sde_connector_set_roi_v1(c_conn, c_state, (void *)val); if (rc) SDE_ERROR_CONN(c_conn, "invalid roi_v1, rc: %d\n", rc); break; default: break; } if (idx == CONNECTOR_PROP_HDR_METADATA) { Loading Loading @@ -1701,8 +1718,8 @@ struct drm_connector *sde_connector_init(struct drm_device *dev, msm_property_install_volatile_range(&c_conn->property_info, "hdr_metadata", 0x0, 0, ~0, 0, CONNECTOR_PROP_HDR_METADATA); msm_property_install_range(&c_conn->property_info, "RETIRE_FENCE", 0x0, 0, INR_OPEN_MAX, 0, CONNECTOR_PROP_RETIRE_FENCE); msm_property_install_volatile_range(&c_conn->property_info, "RETIRE_FENCE", 0x0, 0, ~0, 0, CONNECTOR_PROP_RETIRE_FENCE); msm_property_install_range(&c_conn->property_info, "autorefresh", 0x0, 0, AUTOREFRESH_MAX_FRAME_CNT, 0, Loading
drivers/gpu/drm/msm/sde/sde_crtc.c +76 −51 Original line number Diff line number Diff line Loading @@ -4803,8 +4803,8 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc, "input_fence_timeout", 0x0, 0, SDE_CRTC_MAX_INPUT_FENCE_TIMEOUT, SDE_CRTC_INPUT_FENCE_TIMEOUT, CRTC_PROP_INPUT_FENCE_TIMEOUT); msm_property_install_range(&sde_crtc->property_info, "output_fence", 0x0, 0, INR_OPEN_MAX, 0, CRTC_PROP_OUTPUT_FENCE); msm_property_install_volatile_range(&sde_crtc->property_info, "output_fence", 0x0, 0, ~0, 0, CRTC_PROP_OUTPUT_FENCE); msm_property_install_range(&sde_crtc->property_info, "output_fence_offset", 0x0, 0, 1, 0, Loading Loading @@ -4976,6 +4976,47 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc, kfree(info); } static int _sde_crtc_get_output_fence(struct drm_crtc *crtc, const struct drm_crtc_state *state, uint64_t *val) { struct drm_encoder *encoder; struct sde_crtc *sde_crtc; struct sde_crtc_state *cstate; uint32_t offset, i; bool conn_offset = 0, is_cmd = true; sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(state); for (i = 0; i < cstate->num_connectors; ++i) { conn_offset = sde_connector_needs_offset(cstate->connectors[i]); if (conn_offset) break; } /** * set the cmd flag only when all the encoders attached * to the crtc are in cmd mode. Consider all other cases * as video mode. */ drm_for_each_encoder(encoder, crtc->dev) { if (encoder->crtc == crtc) is_cmd = sde_encoder_check_mode(encoder, MSM_DISPLAY_CAP_CMD_MODE); } offset = sde_crtc_get_property(cstate, CRTC_PROP_OUTPUT_FENCE_OFFSET); /** * set the offset to 0 only for cmd mode panels, so * the release fence for the current frame can be * triggered right after PP_DONE interrupt. */ offset = is_cmd ? 0 : (offset + conn_offset); return sde_fence_create(&sde_crtc->output_fence, val, offset); } /** * sde_crtc_atomic_set_property - atomically set a crtc drm property * @crtc: Pointer to drm crtc structure Loading @@ -4992,6 +5033,7 @@ static int sde_crtc_atomic_set_property(struct drm_crtc *crtc, struct sde_crtc *sde_crtc; struct sde_crtc_state *cstate; int idx, ret; uint64_t fence_fd; if (!crtc || !state || !property) { SDE_ERROR("invalid argument(s)\n"); Loading Loading @@ -5044,6 +5086,22 @@ static int sde_crtc_atomic_set_property(struct drm_crtc *crtc, cstate->bw_control = true; cstate->bw_split_vote = true; break; case CRTC_PROP_OUTPUT_FENCE: ret = _sde_crtc_get_output_fence(crtc, state, &fence_fd); if (ret) { SDE_ERROR("fence create failed rc:%d\n", ret); goto exit; } ret = copy_to_user((uint64_t __user *)val, &fence_fd, sizeof(uint64_t)); if (ret) { SDE_ERROR("copy to user failed rc:%d\n", ret); put_unused_fd(fence_fd); ret = -EFAULT; goto exit; } break; default: /* nothing to do */ break; Loading Loading @@ -5090,62 +5148,29 @@ static int sde_crtc_atomic_get_property(struct drm_crtc *crtc, { struct sde_crtc *sde_crtc; struct sde_crtc_state *cstate; struct drm_encoder *encoder; int i, ret = -EINVAL; bool conn_offset = 0; bool is_cmd = true; int ret = -EINVAL, i; if (!crtc || !state) { SDE_ERROR("invalid argument(s)\n"); } else { sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(state); for (i = 0; i < cstate->num_connectors; ++i) { conn_offset = sde_connector_needs_offset( cstate->connectors[i]); if (conn_offset) break; goto end; } /** * set the cmd flag only when all the encoders attached * to the crtc are in cmd mode. Consider all other cases * as video mode. */ drm_for_each_encoder(encoder, crtc->dev) { if (encoder->crtc == crtc) is_cmd = sde_encoder_check_mode(encoder, MSM_DISPLAY_CAP_CMD_MODE); } sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(state); i = msm_property_index(&sde_crtc->property_info, property); if (i == CRTC_PROP_OUTPUT_FENCE) { uint32_t offset = sde_crtc_get_property(cstate, CRTC_PROP_OUTPUT_FENCE_OFFSET); /** * set the offset to 0 only for cmd mode panels, so * the release fence for the current frame can be * triggered right after PP_DONE interrupt. */ offset = is_cmd ? 0 : (offset + conn_offset); ret = sde_fence_create(&sde_crtc->output_fence, val, offset); if (ret) SDE_ERROR("fence create failed\n"); ret = _sde_crtc_get_output_fence(crtc, state, val); } else { ret = msm_property_atomic_get(&sde_crtc->property_info, &cstate->property_state, property, val); &cstate->property_state, property, val); if (ret) ret = sde_cp_crtc_get_property(crtc, property, val); ret = sde_cp_crtc_get_property(crtc, property, val); } if (ret) DRM_ERROR("get property failed\n"); } end: return ret; } Loading