2 * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
4 * Parts of this file were based on sources as follows:
6 * Copyright (c) 2006-2008 Intel Corporation
7 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
8 * Copyright (C) 2011 Texas Instruments
10 * This program is free software and is provided to you under the terms of the
11 * GNU General Public License version 2 as published by the Free Software
12 * Foundation, and any use by you of this program is subject to the terms of
18 * pl111_drm_connector.c
19 * Implementation of the connector functions for PL111 DRM
21 #include <linux/amba/clcd-regs.h>
22 #include <linux/version.h>
23 #include <linux/shmem_fs.h>
24 #include <linux/dma-buf.h>
27 #include <drm/drm_atomic_helper.h>
28 #include <drm/drm_crtc_helper.h>
29 #include <drm/drm_of.h>
30 #include <drm/drm_panel.h>
32 #include "pl111_drm.h"
34 static void pl111_connector_destroy(struct drm_connector *connector)
36 struct pl111_drm_connector *pl111_connector =
37 to_pl111_connector(connector);
39 if (pl111_connector->panel)
40 drm_panel_detach(pl111_connector->panel);
42 drm_connector_unregister(connector);
43 drm_connector_cleanup(connector);
46 static enum drm_connector_status pl111_connector_detect(struct drm_connector
47 *connector, bool force)
49 struct pl111_drm_connector *pl111_connector =
50 to_pl111_connector(connector);
52 return (pl111_connector->panel ?
53 connector_status_connected :
54 connector_status_disconnected);
57 static int pl111_connector_helper_get_modes(struct drm_connector *connector)
59 struct pl111_drm_connector *pl111_connector =
60 to_pl111_connector(connector);
62 if (!pl111_connector->panel)
65 return drm_panel_get_modes(pl111_connector->panel);
68 const struct drm_connector_funcs connector_funcs = {
69 .fill_modes = drm_helper_probe_single_connector_modes,
70 .destroy = pl111_connector_destroy,
71 .detect = pl111_connector_detect,
72 .reset = drm_atomic_helper_connector_reset,
73 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
74 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
77 const struct drm_connector_helper_funcs connector_helper_funcs = {
78 .get_modes = pl111_connector_helper_get_modes,
81 /* Walks the OF graph to find the panel node and then asks DRM to look
84 static struct drm_panel *pl111_get_panel(struct device *dev)
86 struct device_node *endpoint, *panel_node;
87 struct device_node *np = dev->of_node;
88 struct drm_panel *panel;
90 endpoint = of_graph_get_next_endpoint(np, NULL);
92 dev_err(dev, "no endpoint to fetch panel\n");
96 /* don't proceed if we have an endpoint but no panel_node tied to it */
97 panel_node = of_graph_get_remote_port_parent(endpoint);
98 of_node_put(endpoint);
100 dev_err(dev, "no valid panel node\n");
104 panel = of_drm_find_panel(panel_node);
105 of_node_put(panel_node);
110 int pl111_connector_init(struct drm_device *dev)
112 struct pl111_drm_dev_private *priv = dev->dev_private;
113 struct pl111_drm_connector *pl111_connector = &priv->connector;
114 struct drm_connector *connector = &pl111_connector->connector;
116 drm_connector_init(dev, connector, &connector_funcs,
117 DRM_MODE_CONNECTOR_DPI);
118 drm_connector_helper_add(connector, &connector_helper_funcs);
120 pl111_connector->panel = pl111_get_panel(dev->dev);
121 if (pl111_connector->panel)
122 drm_panel_attach(pl111_connector->panel, connector);