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 err = output->panel->funcs->get_modes(output->panel);
28 edid = kmemdup(output->edid, sizeof(*edid), GFP_KERNEL);
30 edid = drm_get_edid(connector, output->ddc);
32 drm_mode_connector_update_edid_property(connector, edid);
35 err = drm_add_edid_modes(connector, edid);
42 static int tegra_connector_mode_valid(struct drm_connector *connector,
43 struct drm_display_mode *mode)
45 struct tegra_output *output = connector_to_output(connector);
46 enum drm_mode_status status = MODE_OK;
49 err = tegra_output_check_mode(output, mode, &status);
56 static struct drm_encoder *
57 tegra_connector_best_encoder(struct drm_connector *connector)
59 struct tegra_output *output = connector_to_output(connector);
61 return &output->encoder;
64 static const struct drm_connector_helper_funcs connector_helper_funcs = {
65 .get_modes = tegra_connector_get_modes,
66 .mode_valid = tegra_connector_mode_valid,
67 .best_encoder = tegra_connector_best_encoder,
70 static enum drm_connector_status
71 tegra_connector_detect(struct drm_connector *connector, bool force)
73 struct tegra_output *output = connector_to_output(connector);
74 enum drm_connector_status status = connector_status_unknown;
76 if (gpio_is_valid(output->hpd_gpio)) {
77 if (gpio_get_value(output->hpd_gpio) == 0)
78 status = connector_status_disconnected;
80 status = connector_status_connected;
83 status = connector_status_disconnected;
85 status = connector_status_connected;
87 if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
88 status = connector_status_connected;
94 static void drm_connector_clear(struct drm_connector *connector)
96 memset(connector, 0, sizeof(*connector));
99 static void tegra_connector_destroy(struct drm_connector *connector)
101 drm_sysfs_connector_remove(connector);
102 drm_connector_cleanup(connector);
103 drm_connector_clear(connector);
106 static const struct drm_connector_funcs connector_funcs = {
107 .dpms = drm_helper_connector_dpms,
108 .detect = tegra_connector_detect,
109 .fill_modes = drm_helper_probe_single_connector_modes,
110 .destroy = tegra_connector_destroy,
113 static void drm_encoder_clear(struct drm_encoder *encoder)
115 memset(encoder, 0, sizeof(*encoder));
118 static void tegra_encoder_destroy(struct drm_encoder *encoder)
120 drm_encoder_cleanup(encoder);
121 drm_encoder_clear(encoder);
124 static const struct drm_encoder_funcs encoder_funcs = {
125 .destroy = tegra_encoder_destroy,
128 static void tegra_encoder_dpms(struct drm_encoder *encoder, int mode)
130 struct tegra_output *output = encoder_to_output(encoder);
131 struct drm_panel *panel = output->panel;
133 if (panel && panel->funcs) {
134 if (mode != DRM_MODE_DPMS_ON)
135 drm_panel_disable(panel);
137 drm_panel_enable(panel);
141 static bool tegra_encoder_mode_fixup(struct drm_encoder *encoder,
142 const struct drm_display_mode *mode,
143 struct drm_display_mode *adjusted)
148 static void tegra_encoder_prepare(struct drm_encoder *encoder)
152 static void tegra_encoder_commit(struct drm_encoder *encoder)
156 static void tegra_encoder_mode_set(struct drm_encoder *encoder,
157 struct drm_display_mode *mode,
158 struct drm_display_mode *adjusted)
160 struct tegra_output *output = encoder_to_output(encoder);
163 err = tegra_output_enable(output);
165 dev_err(encoder->dev->dev, "tegra_output_enable(): %d\n", err);
168 static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
169 .dpms = tegra_encoder_dpms,
170 .mode_fixup = tegra_encoder_mode_fixup,
171 .prepare = tegra_encoder_prepare,
172 .commit = tegra_encoder_commit,
173 .mode_set = tegra_encoder_mode_set,
176 static irqreturn_t hpd_irq(int irq, void *data)
178 struct tegra_output *output = data;
180 drm_helper_hpd_irq_event(output->connector.dev);
185 int tegra_output_probe(struct tegra_output *output)
187 struct device_node *ddc, *panel;
188 enum of_gpio_flags flags;
192 if (!output->of_node)
193 output->of_node = output->dev->of_node;
195 panel = of_parse_phandle(output->of_node, "nvidia,panel", 0);
197 output->panel = of_drm_find_panel(panel);
199 return -EPROBE_DEFER;
204 output->edid = of_get_property(output->of_node, "nvidia,edid", &size);
206 ddc = of_parse_phandle(output->of_node, "nvidia,ddc-i2c-bus", 0);
208 output->ddc = of_find_i2c_adapter_by_node(ddc);
218 output->hpd_gpio = of_get_named_gpio_flags(output->of_node,
219 "nvidia,hpd-gpio", 0,
221 if (gpio_is_valid(output->hpd_gpio)) {
224 err = gpio_request_one(output->hpd_gpio, GPIOF_DIR_IN,
225 "HDMI hotplug detect");
227 dev_err(output->dev, "gpio_request_one(): %d\n", err);
231 err = gpio_to_irq(output->hpd_gpio);
233 dev_err(output->dev, "gpio_to_irq(): %d\n", err);
234 gpio_free(output->hpd_gpio);
238 output->hpd_irq = err;
240 flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
243 err = request_threaded_irq(output->hpd_irq, NULL, hpd_irq,
244 flags, "hpd", output);
246 dev_err(output->dev, "failed to request IRQ#%u: %d\n",
247 output->hpd_irq, err);
248 gpio_free(output->hpd_gpio);
252 output->connector.polled = DRM_CONNECTOR_POLL_HPD;
258 int tegra_output_remove(struct tegra_output *output)
260 if (gpio_is_valid(output->hpd_gpio)) {
261 free_irq(output->hpd_irq, output);
262 gpio_free(output->hpd_gpio);
266 put_device(&output->ddc->dev);
271 int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
273 int connector, encoder;
275 switch (output->type) {
276 case TEGRA_OUTPUT_RGB:
277 connector = DRM_MODE_CONNECTOR_LVDS;
278 encoder = DRM_MODE_ENCODER_LVDS;
281 case TEGRA_OUTPUT_HDMI:
282 connector = DRM_MODE_CONNECTOR_HDMIA;
283 encoder = DRM_MODE_ENCODER_TMDS;
287 connector = DRM_MODE_CONNECTOR_Unknown;
288 encoder = DRM_MODE_ENCODER_NONE;
292 drm_connector_init(drm, &output->connector, &connector_funcs,
294 drm_connector_helper_add(&output->connector, &connector_helper_funcs);
295 output->connector.dpms = DRM_MODE_DPMS_OFF;
298 drm_panel_attach(output->panel, &output->connector);
300 drm_encoder_init(drm, &output->encoder, &encoder_funcs, encoder);
301 drm_encoder_helper_add(&output->encoder, &encoder_helper_funcs);
303 drm_mode_connector_attach_encoder(&output->connector, &output->encoder);
304 drm_sysfs_connector_add(&output->connector);
306 output->encoder.possible_crtcs = 0x3;
311 int tegra_output_exit(struct tegra_output *output)