File Index
Files and directories
Sign in
FILE

dc-kms.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/imx/dc/dc-kms.c C
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * Copyright 2024 NXP
  4 */
  5
  6#include <linux/of.h>
  7#include <linux/of_graph.h>
  8
  9#include <drm/drm_atomic_helper.h>
 10#include <drm/drm_bridge.h>
 11#include <drm/drm_bridge_connector.h>
 12#include <drm/drm_connector.h>
 13#include <drm/drm_crtc.h>
 14#include <drm/drm_device.h>
 15#include <drm/drm_encoder.h>
 16#include <drm/drm_gem_framebuffer_helper.h>
 17#include <drm/drm_mode_config.h>
 18#include <drm/drm_print.h>
 19#include <drm/drm_probe_helper.h>
 20#include <drm/drm_simple_kms_helper.h>
 21#include <drm/drm_vblank.h>
 22
 23#include "dc-de.h"
 24#include "dc-drv.h"
 25#include "dc-kms.h"
 26
 27static const struct drm_mode_config_funcs dc_drm_mode_config_funcs = {
 28	.fb_create = drm_gem_fb_create,
 29	.atomic_check = drm_atomic_helper_check,
 30	.atomic_commit = drm_atomic_helper_commit,
 31};
 32
 33static int dc_kms_init_encoder_per_crtc(struct dc_drm_device *dc_drm,
 34					int crtc_index)
 35{
 36	struct dc_crtc *dc_crtc = &dc_drm->dc_crtc[crtc_index];
 37	struct drm_device *drm = &dc_drm->base;
 38	struct drm_crtc *crtc = &dc_crtc->base;
 39	struct drm_connector *connector;
 40	struct device *dev = drm->dev;
 41	struct drm_encoder *encoder;
 42	struct drm_bridge *bridge;
 43	int ret;
 44
 45	bridge = devm_drm_of_get_bridge(dev, dc_crtc->de->tc->dev->of_node,
 46					0, 0);
 47	if (IS_ERR(bridge)) {
 48		ret = PTR_ERR(bridge);
 49		if (ret == -ENODEV)
 50			return 0;
 51
 52		return dev_err_probe(dev, ret,
 53				     "failed to find bridge for CRTC%u\n",
 54				     crtc->index);
 55	}
 56
 57	encoder = &dc_drm->encoder[crtc_index];
 58	ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
 59	if (ret) {
 60		dev_err(dev, "failed to initialize encoder for CRTC%u: %d\n",
 61			crtc->index, ret);
 62		return ret;
 63	}
 64
 65	encoder->possible_crtcs = drm_crtc_mask(crtc);
 66
 67	ret = drm_bridge_attach(encoder, bridge, NULL,
 68				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 69	if (ret) {
 70		dev_err(dev,
 71			"failed to attach bridge to encoder for CRTC%u: %d\n",
 72			crtc->index, ret);
 73		return ret;
 74	}
 75
 76	connector = drm_bridge_connector_init(drm, encoder);
 77	if (IS_ERR(connector)) {
 78		ret = PTR_ERR(connector);
 79		dev_err(dev, "failed to init bridge connector for CRTC%u: %d\n",
 80			crtc->index, ret);
 81		return ret;
 82	}
 83
 84	ret = drm_connector_attach_encoder(connector, encoder);
 85	if (ret)
 86		dev_err(dev,
 87			"failed to attach encoder to connector for CRTC%u: %d\n",
 88			crtc->index, ret);
 89
 90	return ret;
 91}
 92
 93int dc_kms_init(struct dc_drm_device *dc_drm)
 94{
 95	struct drm_device *drm = &dc_drm->base;
 96	int ret, i;
 97
 98	ret = drmm_mode_config_init(drm);
 99	if (ret)
100		return ret;
101
102	drm->mode_config.min_width = 60;
103	drm->mode_config.min_height = 60;
104	drm->mode_config.max_width = 8192;
105	drm->mode_config.max_height = 8192;
106	drm->mode_config.funcs = &dc_drm_mode_config_funcs;
107
108	drm->vblank_disable_immediate = true;
109	drm->max_vblank_count = DC_FRAMEGEN_MAX_FRAME_INDEX;
110
111	for (i = 0; i < DC_DISPLAYS; i++) {
112		ret = dc_crtc_init(dc_drm, i);
113		if (ret)
114			return ret;
115
116		ret = dc_kms_init_encoder_per_crtc(dc_drm, i);
117		if (ret)
118			return ret;
119	}
120
121	for (i = 0; i < DC_DISPLAYS; i++) {
122		ret = dc_crtc_post_init(dc_drm, i);
123		if (ret)
124			return ret;
125	}
126
127	ret = drm_vblank_init(drm, DC_DISPLAYS);
128	if (ret) {
129		dev_err(drm->dev, "failed to init vblank support: %d\n", ret);
130		return ret;
131	}
132
133	drm_mode_config_reset(drm);
134
135	drm_kms_helper_poll_init(drm);
136
137	return 0;
138}
139
140void dc_kms_uninit(struct dc_drm_device *dc_drm)
141{
142	drm_kms_helper_poll_fini(&dc_drm->base);
143}
~/ Read-only file preview.