Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.11-rc2 482 lines 15 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2019 Laurent Pinchart <laurent.pinchart@ideasonboard.com> 4 */ 5 6#include <linux/kernel.h> 7#include <linux/module.h> 8#include <linux/of.h> 9#include <linux/property.h> 10#include <linux/slab.h> 11 12#include <drm/drm_atomic_state_helper.h> 13#include <drm/drm_bridge.h> 14#include <drm/drm_bridge_connector.h> 15#include <drm/drm_connector.h> 16#include <drm/drm_device.h> 17#include <drm/drm_edid.h> 18#include <drm/drm_managed.h> 19#include <drm/drm_modeset_helper_vtables.h> 20#include <drm/drm_probe_helper.h> 21#include <drm/display/drm_hdmi_state_helper.h> 22 23/** 24 * DOC: overview 25 * 26 * The DRM bridge connector helper object provides a DRM connector 27 * implementation that wraps a chain of &struct drm_bridge. The connector 28 * operations are fully implemented based on the operations of the bridges in 29 * the chain, and don't require any intervention from the display controller 30 * driver at runtime. 31 * 32 * To use the helper, display controller drivers create a bridge connector with 33 * a call to drm_bridge_connector_init(). This associates the newly created 34 * connector with the chain of bridges passed to the function and registers it 35 * with the DRM device. At that point the connector becomes fully usable, no 36 * further operation is needed. 37 * 38 * The DRM bridge connector operations are implemented based on the operations 39 * provided by the bridges in the chain. Each connector operation is delegated 40 * to the bridge closest to the connector (at the end of the chain) that 41 * provides the relevant functionality. 42 * 43 * To make use of this helper, all bridges in the chain shall report bridge 44 * operation flags (&drm_bridge->ops) and bridge output type 45 * (&drm_bridge->type), as well as the DRM_BRIDGE_ATTACH_NO_CONNECTOR attach 46 * flag (none of the bridges shall create a DRM connector directly). 47 */ 48 49/** 50 * struct drm_bridge_connector - A connector backed by a chain of bridges 51 */ 52struct drm_bridge_connector { 53 /** 54 * @base: The base DRM connector 55 */ 56 struct drm_connector base; 57 /** 58 * @encoder: 59 * 60 * The encoder at the start of the bridges chain. 61 */ 62 struct drm_encoder *encoder; 63 /** 64 * @bridge_edid: 65 * 66 * The last bridge in the chain (closest to the connector) that provides 67 * EDID read support, if any (see &DRM_BRIDGE_OP_EDID). 68 */ 69 struct drm_bridge *bridge_edid; 70 /** 71 * @bridge_hpd: 72 * 73 * The last bridge in the chain (closest to the connector) that provides 74 * hot-plug detection notification, if any (see &DRM_BRIDGE_OP_HPD). 75 */ 76 struct drm_bridge *bridge_hpd; 77 /** 78 * @bridge_detect: 79 * 80 * The last bridge in the chain (closest to the connector) that provides 81 * connector detection, if any (see &DRM_BRIDGE_OP_DETECT). 82 */ 83 struct drm_bridge *bridge_detect; 84 /** 85 * @bridge_modes: 86 * 87 * The last bridge in the chain (closest to the connector) that provides 88 * connector modes detection, if any (see &DRM_BRIDGE_OP_MODES). 89 */ 90 struct drm_bridge *bridge_modes; 91 /** 92 * @bridge_hdmi: 93 * 94 * The bridge in the chain that implements necessary support for the 95 * HDMI connector infrastructure, if any (see &DRM_BRIDGE_OP_HDMI). 96 */ 97 struct drm_bridge *bridge_hdmi; 98}; 99 100#define to_drm_bridge_connector(x) \ 101 container_of(x, struct drm_bridge_connector, base) 102 103/* ----------------------------------------------------------------------------- 104 * Bridge Connector Hot-Plug Handling 105 */ 106 107static void drm_bridge_connector_hpd_notify(struct drm_connector *connector, 108 enum drm_connector_status status) 109{ 110 struct drm_bridge_connector *bridge_connector = 111 to_drm_bridge_connector(connector); 112 struct drm_bridge *bridge; 113 114 /* Notify all bridges in the pipeline of hotplug events. */ 115 drm_for_each_bridge_in_chain(bridge_connector->encoder, bridge) { 116 if (bridge->funcs->hpd_notify) 117 bridge->funcs->hpd_notify(bridge, status); 118 } 119} 120 121static void drm_bridge_connector_handle_hpd(struct drm_bridge_connector *drm_bridge_connector, 122 enum drm_connector_status status) 123{ 124 struct drm_connector *connector = &drm_bridge_connector->base; 125 struct drm_device *dev = connector->dev; 126 127 mutex_lock(&dev->mode_config.mutex); 128 connector->status = status; 129 mutex_unlock(&dev->mode_config.mutex); 130 131 drm_bridge_connector_hpd_notify(connector, status); 132 133 drm_kms_helper_connector_hotplug_event(connector); 134} 135 136static void drm_bridge_connector_hpd_cb(void *cb_data, 137 enum drm_connector_status status) 138{ 139 drm_bridge_connector_handle_hpd(cb_data, status); 140} 141 142static void drm_bridge_connector_oob_hotplug_event(struct drm_connector *connector, 143 enum drm_connector_status status) 144{ 145 struct drm_bridge_connector *bridge_connector = 146 to_drm_bridge_connector(connector); 147 148 drm_bridge_connector_handle_hpd(bridge_connector, status); 149} 150 151static void drm_bridge_connector_enable_hpd(struct drm_connector *connector) 152{ 153 struct drm_bridge_connector *bridge_connector = 154 to_drm_bridge_connector(connector); 155 struct drm_bridge *hpd = bridge_connector->bridge_hpd; 156 157 if (hpd) 158 drm_bridge_hpd_enable(hpd, drm_bridge_connector_hpd_cb, 159 bridge_connector); 160} 161 162static void drm_bridge_connector_disable_hpd(struct drm_connector *connector) 163{ 164 struct drm_bridge_connector *bridge_connector = 165 to_drm_bridge_connector(connector); 166 struct drm_bridge *hpd = bridge_connector->bridge_hpd; 167 168 if (hpd) 169 drm_bridge_hpd_disable(hpd); 170} 171 172/* ----------------------------------------------------------------------------- 173 * Bridge Connector Functions 174 */ 175 176static enum drm_connector_status 177drm_bridge_connector_detect(struct drm_connector *connector, bool force) 178{ 179 struct drm_bridge_connector *bridge_connector = 180 to_drm_bridge_connector(connector); 181 struct drm_bridge *detect = bridge_connector->bridge_detect; 182 enum drm_connector_status status; 183 184 if (detect) { 185 status = detect->funcs->detect(detect); 186 187 drm_bridge_connector_hpd_notify(connector, status); 188 } else { 189 switch (connector->connector_type) { 190 case DRM_MODE_CONNECTOR_DPI: 191 case DRM_MODE_CONNECTOR_LVDS: 192 case DRM_MODE_CONNECTOR_DSI: 193 case DRM_MODE_CONNECTOR_eDP: 194 status = connector_status_connected; 195 break; 196 default: 197 status = connector_status_unknown; 198 break; 199 } 200 } 201 202 return status; 203} 204 205static void drm_bridge_connector_debugfs_init(struct drm_connector *connector, 206 struct dentry *root) 207{ 208 struct drm_bridge_connector *bridge_connector = 209 to_drm_bridge_connector(connector); 210 struct drm_encoder *encoder = bridge_connector->encoder; 211 struct drm_bridge *bridge; 212 213 list_for_each_entry(bridge, &encoder->bridge_chain, chain_node) { 214 if (bridge->funcs->debugfs_init) 215 bridge->funcs->debugfs_init(bridge, root); 216 } 217} 218 219static const struct drm_connector_funcs drm_bridge_connector_funcs = { 220 .reset = drm_atomic_helper_connector_reset, 221 .detect = drm_bridge_connector_detect, 222 .fill_modes = drm_helper_probe_single_connector_modes, 223 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 224 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 225 .debugfs_init = drm_bridge_connector_debugfs_init, 226 .oob_hotplug_event = drm_bridge_connector_oob_hotplug_event, 227}; 228 229/* ----------------------------------------------------------------------------- 230 * Bridge Connector Helper Functions 231 */ 232 233static int drm_bridge_connector_get_modes_edid(struct drm_connector *connector, 234 struct drm_bridge *bridge) 235{ 236 enum drm_connector_status status; 237 const struct drm_edid *drm_edid; 238 int n; 239 240 status = drm_bridge_connector_detect(connector, false); 241 if (status != connector_status_connected) 242 goto no_edid; 243 244 drm_edid = drm_bridge_edid_read(bridge, connector); 245 if (!drm_edid_valid(drm_edid)) { 246 drm_edid_free(drm_edid); 247 goto no_edid; 248 } 249 250 drm_edid_connector_update(connector, drm_edid); 251 n = drm_edid_connector_add_modes(connector); 252 253 drm_edid_free(drm_edid); 254 return n; 255 256no_edid: 257 drm_edid_connector_update(connector, NULL); 258 return 0; 259} 260 261static int drm_bridge_connector_get_modes(struct drm_connector *connector) 262{ 263 struct drm_bridge_connector *bridge_connector = 264 to_drm_bridge_connector(connector); 265 struct drm_bridge *bridge; 266 267 /* 268 * If display exposes EDID, then we parse that in the normal way to 269 * build table of supported modes. 270 */ 271 bridge = bridge_connector->bridge_edid; 272 if (bridge) 273 return drm_bridge_connector_get_modes_edid(connector, bridge); 274 275 /* 276 * Otherwise if the display pipeline reports modes (e.g. with a fixed 277 * resolution panel or an analog TV output), query it. 278 */ 279 bridge = bridge_connector->bridge_modes; 280 if (bridge) 281 return bridge->funcs->get_modes(bridge, connector); 282 283 /* 284 * We can't retrieve modes, which can happen for instance for a DVI or 285 * VGA output with the DDC bus unconnected. The KMS core will add the 286 * default modes. 287 */ 288 return 0; 289} 290 291static const struct drm_connector_helper_funcs drm_bridge_connector_helper_funcs = { 292 .get_modes = drm_bridge_connector_get_modes, 293 /* No need for .mode_valid(), the bridges are checked by the core. */ 294 .enable_hpd = drm_bridge_connector_enable_hpd, 295 .disable_hpd = drm_bridge_connector_disable_hpd, 296}; 297 298static enum drm_mode_status 299drm_bridge_connector_tmds_char_rate_valid(const struct drm_connector *connector, 300 const struct drm_display_mode *mode, 301 unsigned long long tmds_rate) 302{ 303 struct drm_bridge_connector *bridge_connector = 304 to_drm_bridge_connector(connector); 305 struct drm_bridge *bridge; 306 307 bridge = bridge_connector->bridge_hdmi; 308 if (!bridge) 309 return MODE_ERROR; 310 311 if (bridge->funcs->hdmi_tmds_char_rate_valid) 312 return bridge->funcs->hdmi_tmds_char_rate_valid(bridge, mode, tmds_rate); 313 else 314 return MODE_OK; 315} 316 317static int drm_bridge_connector_clear_infoframe(struct drm_connector *connector, 318 enum hdmi_infoframe_type type) 319{ 320 struct drm_bridge_connector *bridge_connector = 321 to_drm_bridge_connector(connector); 322 struct drm_bridge *bridge; 323 324 bridge = bridge_connector->bridge_hdmi; 325 if (!bridge) 326 return -EINVAL; 327 328 return bridge->funcs->hdmi_clear_infoframe(bridge, type); 329} 330 331static int drm_bridge_connector_write_infoframe(struct drm_connector *connector, 332 enum hdmi_infoframe_type type, 333 const u8 *buffer, size_t len) 334{ 335 struct drm_bridge_connector *bridge_connector = 336 to_drm_bridge_connector(connector); 337 struct drm_bridge *bridge; 338 339 bridge = bridge_connector->bridge_hdmi; 340 if (!bridge) 341 return -EINVAL; 342 343 return bridge->funcs->hdmi_write_infoframe(bridge, type, buffer, len); 344} 345 346static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = { 347 .tmds_char_rate_valid = drm_bridge_connector_tmds_char_rate_valid, 348 .clear_infoframe = drm_bridge_connector_clear_infoframe, 349 .write_infoframe = drm_bridge_connector_write_infoframe, 350}; 351 352/* ----------------------------------------------------------------------------- 353 * Bridge Connector Initialisation 354 */ 355 356/** 357 * drm_bridge_connector_init - Initialise a connector for a chain of bridges 358 * @drm: the DRM device 359 * @encoder: the encoder where the bridge chain starts 360 * 361 * Allocate, initialise and register a &drm_bridge_connector with the @drm 362 * device. The connector is associated with a chain of bridges that starts at 363 * the @encoder. All bridges in the chain shall report bridge operation flags 364 * (&drm_bridge->ops) and bridge output type (&drm_bridge->type), and none of 365 * them may create a DRM connector directly. 366 * 367 * Returns a pointer to the new connector on success, or a negative error 368 * pointer otherwise. 369 */ 370struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, 371 struct drm_encoder *encoder) 372{ 373 struct drm_bridge_connector *bridge_connector; 374 struct drm_connector *connector; 375 struct i2c_adapter *ddc = NULL; 376 struct drm_bridge *bridge, *panel_bridge = NULL; 377 unsigned int supported_formats = BIT(HDMI_COLORSPACE_RGB); 378 unsigned int max_bpc = 8; 379 int connector_type; 380 int ret; 381 382 bridge_connector = drmm_kzalloc(drm, sizeof(*bridge_connector), GFP_KERNEL); 383 if (!bridge_connector) 384 return ERR_PTR(-ENOMEM); 385 386 bridge_connector->encoder = encoder; 387 388 /* 389 * TODO: Handle doublescan_allowed, stereo_allowed and 390 * ycbcr_420_allowed. 391 */ 392 connector = &bridge_connector->base; 393 connector->interlace_allowed = true; 394 395 /* 396 * Initialise connector status handling. First locate the furthest 397 * bridges in the pipeline that support HPD and output detection. Then 398 * initialise the connector polling mode, using HPD if available and 399 * falling back to polling if supported. If neither HPD nor output 400 * detection are available, we don't support hotplug detection at all. 401 */ 402 connector_type = DRM_MODE_CONNECTOR_Unknown; 403 drm_for_each_bridge_in_chain(encoder, bridge) { 404 if (!bridge->interlace_allowed) 405 connector->interlace_allowed = false; 406 407 if (bridge->ops & DRM_BRIDGE_OP_EDID) 408 bridge_connector->bridge_edid = bridge; 409 if (bridge->ops & DRM_BRIDGE_OP_HPD) 410 bridge_connector->bridge_hpd = bridge; 411 if (bridge->ops & DRM_BRIDGE_OP_DETECT) 412 bridge_connector->bridge_detect = bridge; 413 if (bridge->ops & DRM_BRIDGE_OP_MODES) 414 bridge_connector->bridge_modes = bridge; 415 if (bridge->ops & DRM_BRIDGE_OP_HDMI) { 416 if (bridge_connector->bridge_hdmi) 417 return ERR_PTR(-EBUSY); 418 if (!bridge->funcs->hdmi_write_infoframe || 419 !bridge->funcs->hdmi_clear_infoframe) 420 return ERR_PTR(-EINVAL); 421 422 bridge_connector->bridge_hdmi = bridge; 423 424 if (bridge->supported_formats) 425 supported_formats = bridge->supported_formats; 426 if (bridge->max_bpc) 427 max_bpc = bridge->max_bpc; 428 } 429 430 if (!drm_bridge_get_next_bridge(bridge)) 431 connector_type = bridge->type; 432 433#ifdef CONFIG_OF 434 if (!drm_bridge_get_next_bridge(bridge) && 435 bridge->of_node) 436 connector->fwnode = fwnode_handle_get(of_fwnode_handle(bridge->of_node)); 437#endif 438 439 if (bridge->ddc) 440 ddc = bridge->ddc; 441 442 if (drm_bridge_is_panel(bridge)) 443 panel_bridge = bridge; 444 } 445 446 if (connector_type == DRM_MODE_CONNECTOR_Unknown) { 447 kfree(bridge_connector); 448 return ERR_PTR(-EINVAL); 449 } 450 451 if (bridge_connector->bridge_hdmi) 452 ret = drmm_connector_hdmi_init(drm, connector, 453 bridge_connector->bridge_hdmi->vendor, 454 bridge_connector->bridge_hdmi->product, 455 &drm_bridge_connector_funcs, 456 &drm_bridge_connector_hdmi_funcs, 457 connector_type, ddc, 458 supported_formats, 459 max_bpc); 460 else 461 ret = drmm_connector_init(drm, connector, 462 &drm_bridge_connector_funcs, 463 connector_type, ddc); 464 if (ret) { 465 kfree(bridge_connector); 466 return ERR_PTR(ret); 467 } 468 469 drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs); 470 471 if (bridge_connector->bridge_hpd) 472 connector->polled = DRM_CONNECTOR_POLL_HPD; 473 else if (bridge_connector->bridge_detect) 474 connector->polled = DRM_CONNECTOR_POLL_CONNECT 475 | DRM_CONNECTOR_POLL_DISCONNECT; 476 477 if (panel_bridge) 478 drm_panel_bridge_set_orientation(connector, panel_bridge); 479 480 return connector; 481} 482EXPORT_SYMBOL_GPL(drm_bridge_connector_init);