1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2012 Avionic Design GmbH
4 * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
7 #include <drm/drm_atomic_helper.h>
8 #include <drm/drm_panel.h>
13 #include <media/cec-notifier.h>
15 int tegra_output_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 cec_notifier_set_phys_addr_from_edid(output
->cec
, edid
);
37 drm_connector_update_edid_property(connector
, edid
);
40 err
= drm_add_edid_modes(connector
, edid
);
47 enum drm_connector_status
48 tegra_output_connector_detect(struct drm_connector
*connector
, bool force
)
50 struct tegra_output
*output
= connector_to_output(connector
);
51 enum drm_connector_status status
= connector_status_unknown
;
53 if (gpio_is_valid(output
->hpd_gpio
)) {
54 if (output
->hpd_gpio_flags
& OF_GPIO_ACTIVE_LOW
) {
55 if (gpio_get_value(output
->hpd_gpio
) != 0)
56 status
= connector_status_disconnected
;
58 status
= connector_status_connected
;
60 if (gpio_get_value(output
->hpd_gpio
) == 0)
61 status
= connector_status_disconnected
;
63 status
= connector_status_connected
;
67 status
= connector_status_disconnected
;
69 status
= connector_status_connected
;
72 if (status
!= connector_status_connected
)
73 cec_notifier_phys_addr_invalidate(output
->cec
);
78 void tegra_output_connector_destroy(struct drm_connector
*connector
)
80 drm_connector_unregister(connector
);
81 drm_connector_cleanup(connector
);
84 void tegra_output_encoder_destroy(struct drm_encoder
*encoder
)
86 drm_encoder_cleanup(encoder
);
89 static irqreturn_t
hpd_irq(int irq
, void *data
)
91 struct tegra_output
*output
= data
;
93 if (output
->connector
.dev
)
94 drm_helper_hpd_irq_event(output
->connector
.dev
);
99 int tegra_output_probe(struct tegra_output
*output
)
101 struct device_node
*ddc
, *panel
;
104 if (!output
->of_node
)
105 output
->of_node
= output
->dev
->of_node
;
107 panel
= of_parse_phandle(output
->of_node
, "nvidia,panel", 0);
109 output
->panel
= of_drm_find_panel(panel
);
110 if (IS_ERR(output
->panel
))
111 return PTR_ERR(output
->panel
);
116 output
->edid
= of_get_property(output
->of_node
, "nvidia,edid", &size
);
118 ddc
= of_parse_phandle(output
->of_node
, "nvidia,ddc-i2c-bus", 0);
120 output
->ddc
= of_find_i2c_adapter_by_node(ddc
);
130 output
->hpd_gpio
= of_get_named_gpio_flags(output
->of_node
,
131 "nvidia,hpd-gpio", 0,
132 &output
->hpd_gpio_flags
);
133 if (gpio_is_valid(output
->hpd_gpio
)) {
136 err
= gpio_request_one(output
->hpd_gpio
, GPIOF_DIR_IN
,
137 "HDMI hotplug detect");
139 dev_err(output
->dev
, "gpio_request_one(): %d\n", err
);
143 err
= gpio_to_irq(output
->hpd_gpio
);
145 dev_err(output
->dev
, "gpio_to_irq(): %d\n", err
);
146 gpio_free(output
->hpd_gpio
);
150 output
->hpd_irq
= err
;
152 flags
= IRQF_TRIGGER_RISING
| IRQF_TRIGGER_FALLING
|
155 err
= request_threaded_irq(output
->hpd_irq
, NULL
, hpd_irq
,
156 flags
, "hpd", output
);
158 dev_err(output
->dev
, "failed to request IRQ#%u: %d\n",
159 output
->hpd_irq
, err
);
160 gpio_free(output
->hpd_gpio
);
164 output
->connector
.polled
= DRM_CONNECTOR_POLL_HPD
;
167 * Disable the interrupt until the connector has been
168 * initialized to avoid a race in the hotplug interrupt
171 disable_irq(output
->hpd_irq
);
174 output
->cec
= cec_notifier_get(output
->dev
);
181 void tegra_output_remove(struct tegra_output
*output
)
184 cec_notifier_put(output
->cec
);
186 if (gpio_is_valid(output
->hpd_gpio
)) {
187 free_irq(output
->hpd_irq
, output
);
188 gpio_free(output
->hpd_gpio
);
192 put_device(&output
->ddc
->dev
);
195 int tegra_output_init(struct drm_device
*drm
, struct tegra_output
*output
)
200 err
= drm_panel_attach(output
->panel
, &output
->connector
);
206 * The connector is now registered and ready to receive hotplug events
207 * so the hotplug interrupt can be enabled.
209 if (gpio_is_valid(output
->hpd_gpio
))
210 enable_irq(output
->hpd_irq
);
215 void tegra_output_exit(struct tegra_output
*output
)
218 * The connector is going away, so the interrupt must be disabled to
219 * prevent the hotplug interrupt handler from potentially crashing.
221 if (gpio_is_valid(output
->hpd_gpio
))
222 disable_irq(output
->hpd_irq
);
225 drm_panel_detach(output
->panel
);
228 void tegra_output_find_possible_crtcs(struct tegra_output
*output
,
229 struct drm_device
*drm
)
231 struct device
*dev
= output
->dev
;
232 struct drm_crtc
*crtc
;
233 unsigned int mask
= 0;
235 drm_for_each_crtc(crtc
, drm
) {
236 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
238 if (tegra_dc_has_output(dc
, dev
))
239 mask
|= drm_crtc_mask(crtc
);
243 dev_warn(dev
, "missing output definition for heads in DT\n");
247 output
->encoder
.possible_crtcs
= mask
;