static struct drm_connector_state * sde_connector_atomic_duplicate_state(struct drm_connector *connector) { struct sde_connector *c_conn; struct sde_connector_state *c_state, *c_oldstate; int rc; if (!connector || !connector->state) { SDE_ERROR("invalid connector %pK\n", connector); return NULL; } c_conn = to_sde_connector(connector); c_oldstate = to_sde_connector_state(connector->state); c_state = msm_property_alloc_state(&c_conn->property_info); if (!c_state) { SDE_ERROR("state alloc failed\n"); return NULL; } /* duplicate value helper */ msm_property_duplicate_state(&c_conn->property_info, c_oldstate, c_state, c_state->property_values, 0); /* additional handling for drm framebuffer objects */ if (c_state->out_fb) { drm_framebuffer_reference(c_state->out_fb); rc = msm_framebuffer_prepare(c_state->out_fb, c_state->mmu_id); if (rc) SDE_ERROR("failed to prepare fb, %d\n", rc); } return &c_state->base; }
static int mdp5_plane_prepare_fb(struct drm_plane *plane, struct drm_framebuffer *fb) { struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); struct mdp5_kms *mdp5_kms = get_kms(plane); DBG("%s: prepare: FB[%u]", mdp5_plane->name, fb->base.id); return msm_framebuffer_prepare(fb, mdp5_kms->id); }
static int mdp4_plane_prepare_fb(struct drm_plane *plane, struct drm_plane_state *new_state) { struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); struct mdp4_kms *mdp4_kms = get_kms(plane); struct drm_framebuffer *fb = new_state->fb; if (!fb) return 0; DBG("%s: prepare: FB[%u]", mdp4_plane->name, fb->base.id); return msm_framebuffer_prepare(fb, mdp4_kms->id); }
int msm_atomic_prepare_fb(struct drm_plane *plane, struct drm_plane_state *new_state) { struct msm_drm_private *priv = plane->dev->dev_private; struct msm_kms *kms = priv->kms; struct drm_gem_object *obj; struct msm_gem_object *msm_obj; struct dma_fence *fence; if (!new_state->fb) return 0; obj = msm_framebuffer_bo(new_state->fb, 0); msm_obj = to_msm_bo(obj); fence = reservation_object_get_excl_rcu(msm_obj->resv); drm_atomic_set_fence_for_plane(new_state, fence); return msm_framebuffer_prepare(new_state->fb, kms->aspace); }
static int sde_connector_atomic_set_property(struct drm_connector *connector, struct drm_connector_state *state, struct drm_property *property, uint64_t val) { struct sde_connector *c_conn; struct sde_connector_state *c_state; int idx, rc; if (!connector || !state || !property) { SDE_ERROR("invalid argument(s), conn %pK, state %pK, prp %pK\n", connector, state, property); return -EINVAL; } c_conn = to_sde_connector(connector); c_state = to_sde_connector_state(state); /* generic property handling */ rc = msm_property_atomic_set(&c_conn->property_info, c_state->property_values, 0, property, val); if (rc) goto end; /* connector-specific property handling */ idx = msm_property_index(&c_conn->property_info, property); if (idx == CONNECTOR_PROP_OUT_FB) { /* clear old fb, if present */ if (c_state->out_fb) _sde_connector_destroy_fb(c_conn, c_state); /* convert fb val to drm framebuffer and prepare it */ c_state->out_fb = drm_framebuffer_lookup(connector->dev, val); if (!c_state->out_fb) { SDE_ERROR("failed to look up fb %lld\n", val); rc = -EFAULT; } else { if (c_state->out_fb->flags & DRM_MODE_FB_SECURE) c_state->mmu_id = c_conn->mmu_id[SDE_IOMMU_DOMAIN_SECURE]; else c_state->mmu_id = c_conn->mmu_id[SDE_IOMMU_DOMAIN_UNSECURE]; rc = msm_framebuffer_prepare(c_state->out_fb, c_state->mmu_id); if (rc) SDE_ERROR("prep fb failed, %d\n", rc); } } 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 */ if (!rc && c_conn->ops.set_property) { rc = c_conn->ops.set_property(connector, state, idx, val, c_conn->display); /* potentially clean up out_fb if rc != 0 */ if ((idx == CONNECTOR_PROP_OUT_FB) && rc) _sde_connector_destroy_fb(c_conn, c_state); } end: return rc; }