Loading drivers/gpu/drm/msm-lease/msm_lease_drv.c +81 −15 Original line number Diff line number Diff line /* Copyright (c) 2019, The Linux Foundation. All rights reserved. /* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017 Keith Packard <keithp@keithp.com> * * This program is free software; you can redistribute it and/or modify Loading Loading @@ -322,7 +322,7 @@ static long msm_lease_ioctl(struct file *filp, } static int msm_lease_add_connector(struct drm_device *dev, const char *name, u32 *object_ids, int *object_count, struct drm_plane *primary) u32 *object_ids, int *object_count) { struct drm_connector *connector; struct drm_encoder *encoder; Loading Loading @@ -373,10 +373,6 @@ static int msm_lease_add_connector(struct drm_device *dev, const char *name, if (_obj_is_leased(crtc->base.id, object_ids, *object_count)) continue; /* re-initialize crtc primary for legacy set_mode */ crtc->primary = primary; primary->crtc = crtc; crtc_id = crtc->base.id; break; } Loading @@ -397,8 +393,7 @@ static int msm_lease_add_connector(struct drm_device *dev, const char *name, } static int msm_lease_add_plane(struct drm_device *dev, const char *name, u32 *object_ids, int *object_count, struct drm_plane **planes, int *plane_count) u32 *object_ids, int *object_count) { struct drm_plane *plane, *added_plane; int plane_id = -1; Loading Loading @@ -429,18 +424,83 @@ static int msm_lease_add_plane(struct drm_device *dev, const char *name, } object_ids[(*object_count)++] = plane_id; planes[(*plane_count)++] = added_plane; return 0; } static void msm_lease_fixup_crtc_primary(struct drm_device *dev, u32 *object_ids, int object_count) { struct drm_mode_object *obj; struct drm_plane *planes[MAX_LEASE_OBJECT_COUNT]; struct drm_crtc *crtcs[MAX_LEASE_OBJECT_COUNT]; struct drm_plane *plane; struct drm_crtc *crtc; int i, plane_count = 0, crtc_count = 0; /* get all the leased crtcs and planes */ for (i = 0; i < object_count; i++) { obj = drm_mode_object_find(dev, NULL, object_ids[i], DRM_MODE_OBJECT_ANY); if (!obj) continue; if (obj->type == DRM_MODE_OBJECT_PLANE) planes[plane_count++] = obj_to_plane(obj); else if (obj->type == DRM_MODE_OBJECT_CRTC) crtcs[crtc_count++] = obj_to_crtc(obj); } /* reset previous primary planes */ for (i = 0; i < plane_count; i++) { if (planes[i]->type == DRM_PLANE_TYPE_PRIMARY) { drm_for_each_crtc(crtc, dev) { if (crtc->primary == planes[i]) { crtc->primary = NULL; planes[i]->crtc = NULL; break; } } planes[i]->type = DRM_PLANE_TYPE_OVERLAY; dev->mode_config.num_overlay_plane++; } } /* setup new primary planes */ for (i = 0; i < crtc_count; i++) { if (crtcs[i]->primary) { crtcs[i]->primary->type = DRM_PLANE_TYPE_OVERLAY; dev->mode_config.num_overlay_plane++; } crtcs[i]->primary = planes[i]; planes[i]->crtc = crtcs[i]; planes[i]->type = DRM_PLANE_TYPE_PRIMARY; dev->mode_config.num_overlay_plane--; } /* assign primary planes for reset crtcs */ drm_for_each_crtc(crtc, dev) { if (crtc->primary) continue; drm_for_each_plane(plane, dev) { if (plane->type == DRM_PLANE_TYPE_OVERLAY) { crtc->primary = plane; plane->type = DRM_PLANE_TYPE_PRIMARY; plane->crtc = crtc; dev->mode_config.num_overlay_plane--; break; } } } } static int msm_lease_parse_objs(struct drm_device *dev, struct device_node *of_node, u32 *object_ids, int *object_count) { const char *name; struct drm_plane *planes[MAX_LEASE_OBJECT_COUNT]; int count, rc, i, plane_count = 0; int count, rc, i; count = of_property_count_strings(of_node, "qcom,lease-planes"); if (!count) { Loading @@ -452,8 +512,7 @@ static int msm_lease_parse_objs(struct drm_device *dev, of_property_read_string_index(of_node, "qcom,lease-planes", i, &name); rc = msm_lease_add_plane(dev, name, object_ids, object_count, planes, &plane_count); object_ids, object_count); if (rc) return rc; } Loading @@ -464,12 +523,16 @@ static int msm_lease_parse_objs(struct drm_device *dev, return -EINVAL; } if (count > *object_count) { DRM_ERROR("connectors are more than planes\n"); return -EINVAL; } for (i = 0; i < count; i++) { of_property_read_string_index(of_node, "qcom,lease-connectors", i, &name); rc = msm_lease_add_connector(dev, name, object_ids, object_count, i < plane_count ? planes[i] : planes[0]); object_ids, object_count); if (rc) return rc; } Loading Loading @@ -577,6 +640,9 @@ static int msm_lease_probe(struct platform_device *pdev) memcpy(lease_drv->object_ids, object_ids, sizeof(u32) * object_count); list_add_tail(&lease_drv->head, &g_lease_list); /* fixup crtcs' primary planes */ msm_lease_fixup_crtc_primary(master_ddev, object_ids, object_count); /* hook open/close function */ if (!g_master_open && !g_master_postclose) { g_master_open = master_ddev->driver->open; Loading drivers/gpu/drm/msm/shd/shd_drm.c +49 −1 Original line number Diff line number Diff line Loading @@ -170,6 +170,7 @@ static int shd_display_init_base_crtc(struct drm_device *dev, { struct drm_crtc *crtc = NULL; struct msm_drm_private *priv; struct drm_plane *primary; int crtc_idx; int i; Loading @@ -193,6 +194,23 @@ static int shd_display_init_base_crtc(struct drm_device *dev, return -ENOENT; } if (priv->num_planes >= MAX_PLANES) return -ENOENT; /* create dummy primary plane for base crtc */ primary = sde_plane_init(dev, SSPP_DMA0, true, 0, 0); if (IS_ERR(primary)) return -ENOMEM; priv->planes[priv->num_planes++] = primary; if (primary->funcs->reset) primary->funcs->reset(primary); SDE_DEBUG("create dummay plane%d free plane%d\n", DRMID(primary), DRMID(crtc->primary)); crtc->primary = primary; primary->crtc = crtc; /* disable crtc from other encoders */ for (i = 0; i < priv->num_encoders; i++) { if (priv->encoders[i] != base->encoder) Loading Loading @@ -721,6 +739,7 @@ static int shd_drm_obj_init(struct shd_display *display) struct msm_drm_private *priv; struct drm_device *dev; struct drm_crtc *crtc; struct drm_plane *primary; struct drm_encoder *encoder; struct drm_connector *connector; struct sde_crtc *sde_crtc; Loading Loading @@ -752,6 +771,35 @@ static int shd_drm_obj_init(struct shd_display *display) goto end; } /* search plane that doesn't belong to any crtc */ primary = NULL; for (i = 0; i < priv->num_planes; i++) { bool found = false; drm_for_each_crtc(crtc, dev) { if (crtc->primary == priv->planes[i]) { found = true; break; } } if (!found) { primary = priv->planes[i]; if (primary->type == DRM_PLANE_TYPE_OVERLAY) dev->mode_config.num_overlay_plane--; primary->type = DRM_PLANE_TYPE_PRIMARY; break; } } if (!primary) { SDE_ERROR("failed to find primary plane\n"); rc = -ENOENT; goto end; } SDE_DEBUG("find primary plane %d\n", DRMID(primary)); memset(&info, 0x0, sizeof(info)); rc = shd_connector_get_info(NULL, &info, display); if (rc) { Loading Loading @@ -795,7 +843,7 @@ static int shd_drm_obj_init(struct shd_display *display) SDE_DEBUG("create connector %d\n", DRMID(connector)); crtc = sde_crtc_init(dev, priv->planes[0]); crtc = sde_crtc_init(dev, primary); if (IS_ERR(crtc)) { rc = PTR_ERR(crtc); goto end; Loading Loading
drivers/gpu/drm/msm-lease/msm_lease_drv.c +81 −15 Original line number Diff line number Diff line /* Copyright (c) 2019, The Linux Foundation. All rights reserved. /* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017 Keith Packard <keithp@keithp.com> * * This program is free software; you can redistribute it and/or modify Loading Loading @@ -322,7 +322,7 @@ static long msm_lease_ioctl(struct file *filp, } static int msm_lease_add_connector(struct drm_device *dev, const char *name, u32 *object_ids, int *object_count, struct drm_plane *primary) u32 *object_ids, int *object_count) { struct drm_connector *connector; struct drm_encoder *encoder; Loading Loading @@ -373,10 +373,6 @@ static int msm_lease_add_connector(struct drm_device *dev, const char *name, if (_obj_is_leased(crtc->base.id, object_ids, *object_count)) continue; /* re-initialize crtc primary for legacy set_mode */ crtc->primary = primary; primary->crtc = crtc; crtc_id = crtc->base.id; break; } Loading @@ -397,8 +393,7 @@ static int msm_lease_add_connector(struct drm_device *dev, const char *name, } static int msm_lease_add_plane(struct drm_device *dev, const char *name, u32 *object_ids, int *object_count, struct drm_plane **planes, int *plane_count) u32 *object_ids, int *object_count) { struct drm_plane *plane, *added_plane; int plane_id = -1; Loading Loading @@ -429,18 +424,83 @@ static int msm_lease_add_plane(struct drm_device *dev, const char *name, } object_ids[(*object_count)++] = plane_id; planes[(*plane_count)++] = added_plane; return 0; } static void msm_lease_fixup_crtc_primary(struct drm_device *dev, u32 *object_ids, int object_count) { struct drm_mode_object *obj; struct drm_plane *planes[MAX_LEASE_OBJECT_COUNT]; struct drm_crtc *crtcs[MAX_LEASE_OBJECT_COUNT]; struct drm_plane *plane; struct drm_crtc *crtc; int i, plane_count = 0, crtc_count = 0; /* get all the leased crtcs and planes */ for (i = 0; i < object_count; i++) { obj = drm_mode_object_find(dev, NULL, object_ids[i], DRM_MODE_OBJECT_ANY); if (!obj) continue; if (obj->type == DRM_MODE_OBJECT_PLANE) planes[plane_count++] = obj_to_plane(obj); else if (obj->type == DRM_MODE_OBJECT_CRTC) crtcs[crtc_count++] = obj_to_crtc(obj); } /* reset previous primary planes */ for (i = 0; i < plane_count; i++) { if (planes[i]->type == DRM_PLANE_TYPE_PRIMARY) { drm_for_each_crtc(crtc, dev) { if (crtc->primary == planes[i]) { crtc->primary = NULL; planes[i]->crtc = NULL; break; } } planes[i]->type = DRM_PLANE_TYPE_OVERLAY; dev->mode_config.num_overlay_plane++; } } /* setup new primary planes */ for (i = 0; i < crtc_count; i++) { if (crtcs[i]->primary) { crtcs[i]->primary->type = DRM_PLANE_TYPE_OVERLAY; dev->mode_config.num_overlay_plane++; } crtcs[i]->primary = planes[i]; planes[i]->crtc = crtcs[i]; planes[i]->type = DRM_PLANE_TYPE_PRIMARY; dev->mode_config.num_overlay_plane--; } /* assign primary planes for reset crtcs */ drm_for_each_crtc(crtc, dev) { if (crtc->primary) continue; drm_for_each_plane(plane, dev) { if (plane->type == DRM_PLANE_TYPE_OVERLAY) { crtc->primary = plane; plane->type = DRM_PLANE_TYPE_PRIMARY; plane->crtc = crtc; dev->mode_config.num_overlay_plane--; break; } } } } static int msm_lease_parse_objs(struct drm_device *dev, struct device_node *of_node, u32 *object_ids, int *object_count) { const char *name; struct drm_plane *planes[MAX_LEASE_OBJECT_COUNT]; int count, rc, i, plane_count = 0; int count, rc, i; count = of_property_count_strings(of_node, "qcom,lease-planes"); if (!count) { Loading @@ -452,8 +512,7 @@ static int msm_lease_parse_objs(struct drm_device *dev, of_property_read_string_index(of_node, "qcom,lease-planes", i, &name); rc = msm_lease_add_plane(dev, name, object_ids, object_count, planes, &plane_count); object_ids, object_count); if (rc) return rc; } Loading @@ -464,12 +523,16 @@ static int msm_lease_parse_objs(struct drm_device *dev, return -EINVAL; } if (count > *object_count) { DRM_ERROR("connectors are more than planes\n"); return -EINVAL; } for (i = 0; i < count; i++) { of_property_read_string_index(of_node, "qcom,lease-connectors", i, &name); rc = msm_lease_add_connector(dev, name, object_ids, object_count, i < plane_count ? planes[i] : planes[0]); object_ids, object_count); if (rc) return rc; } Loading Loading @@ -577,6 +640,9 @@ static int msm_lease_probe(struct platform_device *pdev) memcpy(lease_drv->object_ids, object_ids, sizeof(u32) * object_count); list_add_tail(&lease_drv->head, &g_lease_list); /* fixup crtcs' primary planes */ msm_lease_fixup_crtc_primary(master_ddev, object_ids, object_count); /* hook open/close function */ if (!g_master_open && !g_master_postclose) { g_master_open = master_ddev->driver->open; Loading
drivers/gpu/drm/msm/shd/shd_drm.c +49 −1 Original line number Diff line number Diff line Loading @@ -170,6 +170,7 @@ static int shd_display_init_base_crtc(struct drm_device *dev, { struct drm_crtc *crtc = NULL; struct msm_drm_private *priv; struct drm_plane *primary; int crtc_idx; int i; Loading @@ -193,6 +194,23 @@ static int shd_display_init_base_crtc(struct drm_device *dev, return -ENOENT; } if (priv->num_planes >= MAX_PLANES) return -ENOENT; /* create dummy primary plane for base crtc */ primary = sde_plane_init(dev, SSPP_DMA0, true, 0, 0); if (IS_ERR(primary)) return -ENOMEM; priv->planes[priv->num_planes++] = primary; if (primary->funcs->reset) primary->funcs->reset(primary); SDE_DEBUG("create dummay plane%d free plane%d\n", DRMID(primary), DRMID(crtc->primary)); crtc->primary = primary; primary->crtc = crtc; /* disable crtc from other encoders */ for (i = 0; i < priv->num_encoders; i++) { if (priv->encoders[i] != base->encoder) Loading Loading @@ -721,6 +739,7 @@ static int shd_drm_obj_init(struct shd_display *display) struct msm_drm_private *priv; struct drm_device *dev; struct drm_crtc *crtc; struct drm_plane *primary; struct drm_encoder *encoder; struct drm_connector *connector; struct sde_crtc *sde_crtc; Loading Loading @@ -752,6 +771,35 @@ static int shd_drm_obj_init(struct shd_display *display) goto end; } /* search plane that doesn't belong to any crtc */ primary = NULL; for (i = 0; i < priv->num_planes; i++) { bool found = false; drm_for_each_crtc(crtc, dev) { if (crtc->primary == priv->planes[i]) { found = true; break; } } if (!found) { primary = priv->planes[i]; if (primary->type == DRM_PLANE_TYPE_OVERLAY) dev->mode_config.num_overlay_plane--; primary->type = DRM_PLANE_TYPE_PRIMARY; break; } } if (!primary) { SDE_ERROR("failed to find primary plane\n"); rc = -ENOENT; goto end; } SDE_DEBUG("find primary plane %d\n", DRMID(primary)); memset(&info, 0x0, sizeof(info)); rc = shd_connector_get_info(NULL, &info, display); if (rc) { Loading Loading @@ -795,7 +843,7 @@ static int shd_drm_obj_init(struct shd_display *display) SDE_DEBUG("create connector %d\n", DRMID(connector)); crtc = sde_crtc_init(dev, priv->planes[0]); crtc = sde_crtc_init(dev, primary); if (IS_ERR(crtc)) { rc = PTR_ERR(crtc); goto end; Loading