2 * Copyright (C) 2012 Avionic Design GmbH
3 * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
10 #include <linux/of_gpio.h>
12 #include <drm/drm_panel.h>
15 static int tegra_connector_get_modes(struct drm_connector
*connector
)
17 struct tegra_output
*output
= connector_to_output(connector
);
18 struct edid
*edid
= NULL
;
22 * If the panel provides one or more modes, use them exclusively and
23 * ignore any other means of obtaining a mode.
26 err
= output
->panel
->funcs
->get_modes(output
->panel
);
32 edid
= kmemdup(output
->edid
, sizeof(*edid
), GFP_KERNEL
);
34 edid
= drm_get_edid(connector
, output
->ddc
);
36 drm_mode_connector_update_edid_property(connector
, edid
);
39 err
= drm_add_edid_modes(connector
, edid
);
46 static int tegra_connector_mode_valid(struct drm_connector
*connector
,
47 struct drm_display_mode
*mode
)
49 struct tegra_output
*output
= connector_to_output(connector
);
50 enum drm_mode_status status
= MODE_OK
;
53 err
= tegra_output_check_mode(output
, mode
, &status
);
60 static struct drm_encoder
*
61 tegra_connector_best_encoder(struct drm_connector
*connector
)
63 struct tegra_output
*output
= connector_to_output(connector
);
65 return &output
->encoder
;
68 static const struct drm_connector_helper_funcs connector_helper_funcs
= {
69 .get_modes
= tegra_connector_get_modes
,
70 .mode_valid
= tegra_connector_mode_valid
,
71 .best_encoder
= tegra_connector_best_encoder
,
74 static enum drm_connector_status
75 tegra_connector_detect(struct drm_connector
*connector
, bool force
)
77 struct tegra_output
*output
= connector_to_output(connector
);
78 enum drm_connector_status status
= connector_status_unknown
;
80 if (gpio_is_valid(output
->hpd_gpio
)) {
81 if (gpio_get_value(output
->hpd_gpio
) == 0)
82 status
= connector_status_disconnected
;
84 status
= connector_status_connected
;
87 status
= connector_status_disconnected
;
89 status
= connector_status_connected
;
91 if (connector
->connector_type
== DRM_MODE_CONNECTOR_LVDS
)
92 status
= connector_status_connected
;
98 static void drm_connector_clear(struct drm_connector
*connector
)
100 memset(connector
, 0, sizeof(*connector
));
103 static void tegra_connector_destroy(struct drm_connector
*connector
)
105 drm_sysfs_connector_remove(connector
);
106 drm_connector_cleanup(connector
);
107 drm_connector_clear(connector
);
110 static const struct drm_connector_funcs connector_funcs
= {
111 .dpms
= drm_helper_connector_dpms
,
112 .detect
= tegra_connector_detect
,
113 .fill_modes
= drm_helper_probe_single_connector_modes
,
114 .destroy
= tegra_connector_destroy
,
117 static void drm_encoder_clear(struct drm_encoder
*encoder
)
119 memset(encoder
, 0, sizeof(*encoder
));
122 static void tegra_encoder_destroy(struct drm_encoder
*encoder
)
124 drm_encoder_cleanup(encoder
);
125 drm_encoder_clear(encoder
);
128 static const struct drm_encoder_funcs encoder_funcs
= {
129 .destroy
= tegra_encoder_destroy
,
132 static void tegra_encoder_dpms(struct drm_encoder
*encoder
, int mode
)
134 struct tegra_output
*output
= encoder_to_output(encoder
);
135 struct drm_panel
*panel
= output
->panel
;
137 if (mode
!= DRM_MODE_DPMS_ON
) {
138 drm_panel_disable(panel
);
139 tegra_output_disable(output
);
141 tegra_output_enable(output
);
142 drm_panel_enable(panel
);
146 static bool tegra_encoder_mode_fixup(struct drm_encoder
*encoder
,
147 const struct drm_display_mode
*mode
,
148 struct drm_display_mode
*adjusted
)
153 static void tegra_encoder_prepare(struct drm_encoder
*encoder
)
157 static void tegra_encoder_commit(struct drm_encoder
*encoder
)
161 static void tegra_encoder_mode_set(struct drm_encoder
*encoder
,
162 struct drm_display_mode
*mode
,
163 struct drm_display_mode
*adjusted
)
165 struct tegra_output
*output
= encoder_to_output(encoder
);
168 err
= tegra_output_enable(output
);
170 dev_err(encoder
->dev
->dev
, "tegra_output_enable(): %d\n", err
);
173 static const struct drm_encoder_helper_funcs encoder_helper_funcs
= {
174 .dpms
= tegra_encoder_dpms
,
175 .mode_fixup
= tegra_encoder_mode_fixup
,
176 .prepare
= tegra_encoder_prepare
,
177 .commit
= tegra_encoder_commit
,
178 .mode_set
= tegra_encoder_mode_set
,
181 static irqreturn_t
hpd_irq(int irq
, void *data
)
183 struct tegra_output
*output
= data
;
185 drm_helper_hpd_irq_event(output
->connector
.dev
);
190 int tegra_output_probe(struct tegra_output
*output
)
192 struct device_node
*ddc
, *panel
;
193 enum of_gpio_flags flags
;
196 if (!output
->of_node
)
197 output
->of_node
= output
->dev
->of_node
;
199 panel
= of_parse_phandle(output
->of_node
, "nvidia,panel", 0);
201 output
->panel
= of_drm_find_panel(panel
);
203 return -EPROBE_DEFER
;
208 output
->edid
= of_get_property(output
->of_node
, "nvidia,edid", &size
);
210 ddc
= of_parse_phandle(output
->of_node
, "nvidia,ddc-i2c-bus", 0);
212 output
->ddc
= of_find_i2c_adapter_by_node(ddc
);
222 output
->hpd_gpio
= of_get_named_gpio_flags(output
->of_node
,
223 "nvidia,hpd-gpio", 0,
225 if (gpio_is_valid(output
->hpd_gpio
)) {
228 err
= gpio_request_one(output
->hpd_gpio
, GPIOF_DIR_IN
,
229 "HDMI hotplug detect");
231 dev_err(output
->dev
, "gpio_request_one(): %d\n", err
);
235 err
= gpio_to_irq(output
->hpd_gpio
);
237 dev_err(output
->dev
, "gpio_to_irq(): %d\n", err
);
238 gpio_free(output
->hpd_gpio
);
242 output
->hpd_irq
= err
;
244 flags
= IRQF_TRIGGER_RISING
| IRQF_TRIGGER_FALLING
|
247 err
= request_threaded_irq(output
->hpd_irq
, NULL
, hpd_irq
,
248 flags
, "hpd", output
);
250 dev_err(output
->dev
, "failed to request IRQ#%u: %d\n",
251 output
->hpd_irq
, err
);
252 gpio_free(output
->hpd_gpio
);
256 output
->connector
.polled
= DRM_CONNECTOR_POLL_HPD
;
262 int tegra_output_remove(struct tegra_output
*output
)
264 if (gpio_is_valid(output
->hpd_gpio
)) {
265 free_irq(output
->hpd_irq
, output
);
266 gpio_free(output
->hpd_gpio
);
270 put_device(&output
->ddc
->dev
);
275 int tegra_output_init(struct drm_device
*drm
, struct tegra_output
*output
)
277 int connector
, encoder
;
279 switch (output
->type
) {
280 case TEGRA_OUTPUT_RGB
:
281 connector
= DRM_MODE_CONNECTOR_LVDS
;
282 encoder
= DRM_MODE_ENCODER_LVDS
;
285 case TEGRA_OUTPUT_HDMI
:
286 connector
= DRM_MODE_CONNECTOR_HDMIA
;
287 encoder
= DRM_MODE_ENCODER_TMDS
;
290 case TEGRA_OUTPUT_DSI
:
291 connector
= DRM_MODE_CONNECTOR_DSI
;
292 encoder
= DRM_MODE_ENCODER_DSI
;
296 connector
= DRM_MODE_CONNECTOR_Unknown
;
297 encoder
= DRM_MODE_ENCODER_NONE
;
301 drm_connector_init(drm
, &output
->connector
, &connector_funcs
,
303 drm_connector_helper_add(&output
->connector
, &connector_helper_funcs
);
304 output
->connector
.dpms
= DRM_MODE_DPMS_OFF
;
307 drm_panel_attach(output
->panel
, &output
->connector
);
309 drm_encoder_init(drm
, &output
->encoder
, &encoder_funcs
, encoder
);
310 drm_encoder_helper_add(&output
->encoder
, &encoder_helper_funcs
);
312 drm_mode_connector_attach_encoder(&output
->connector
, &output
->encoder
);
313 drm_sysfs_connector_add(&output
->connector
);
315 output
->encoder
.possible_crtcs
= 0x3;
320 int tegra_output_exit(struct tegra_output
*output
)