drivers/gpu/drm/tidss/tidss_kms.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/tidss/tidss_kms.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/tidss/tidss_kms.c
Extension
.c
Size
7952 bytes
Lines
294
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct pipe {
		u32 hw_videoport;
		struct drm_bridge *bridge;
		u32 enc_type;
	};

	const struct dispc_features *feat = tidss->feat;
	u32 max_vps = feat->num_vps;
	u32 max_planes = feat->num_vids;

	struct pipe pipes[TIDSS_MAX_PORTS];
	u32 num_pipes = 0;
	u32 crtc_mask;

	/* first find all the connected panels & bridges */

	for (i = 0; i < max_vps; i++) {
		struct drm_panel *panel;
		struct drm_bridge *bridge;
		u32 enc_type = DRM_MODE_ENCODER_NONE;
		int ret;

		ret = drm_of_find_panel_or_bridge(dev->of_node, i, 0,
						  &panel, &bridge);
		if (ret == -ENODEV) {
			dev_dbg(dev, "no panel/bridge for port %d\n", i);
			continue;
		} else if (ret) {
			return dev_err_probe(dev, ret, "port %d probe failed\n", i);
		}

		if (panel) {
			u32 conn_type;

			dev_dbg(dev, "Setting up panel for port %d\n", i);

			switch (feat->vp_bus_type[i]) {
			case DISPC_VP_OLDI_AM65X:
				enc_type = DRM_MODE_ENCODER_LVDS;
				conn_type = DRM_MODE_CONNECTOR_LVDS;
				break;
			case DISPC_VP_DPI:
				enc_type = DRM_MODE_ENCODER_DPI;
				conn_type = DRM_MODE_CONNECTOR_DPI;
				break;
			default:
				WARN_ON(1);
				return -EINVAL;
			}

			if (panel->connector_type != conn_type) {
				dev_err(dev,
					"%s: Panel %s has incompatible connector type for vp%d (%d != %d)\n",
					 __func__, dev_name(panel->dev), i,
					 panel->connector_type, conn_type);
				return -EINVAL;
			}

			bridge = devm_drm_panel_bridge_add(dev, panel);
			if (IS_ERR(bridge)) {
				dev_err(dev,
					"failed to set up panel bridge for port %d\n",
					i);
				return PTR_ERR(bridge);
			}
		}

		pipes[num_pipes].hw_videoport = i;
		pipes[num_pipes].bridge = bridge;
		pipes[num_pipes].enc_type = enc_type;
		num_pipes++;
	}

	/* all planes can be on any crtc */
	crtc_mask = (1 << num_pipes) - 1;

	/* then create a plane, a crtc and an encoder for each panel/bridge */

	for (i = 0; i < num_pipes; ++i) {
		struct tidss_plane *tplane;
		struct tidss_crtc *tcrtc;
		u32 hw_plane_id = feat->vid_order[tidss->num_planes];
		int ret;

		tplane = tidss_plane_create(tidss, hw_plane_id,
					    DRM_PLANE_TYPE_PRIMARY, crtc_mask,
					    fourccs, fourccs_len);
		if (IS_ERR(tplane)) {
			dev_err(tidss->dev, "plane create failed\n");
			return PTR_ERR(tplane);

Annotation

Implementation Notes