File Index
Files and directories
Sign in
FILE

intel_dvo.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/i915/display/intel_dvo.c C
  1/*
  2 * Copyright 2006 Dave Airlie <airlied@linux.ie>
  3 * Copyright © 2006-2007 Intel Corporation
  4 *
  5 * Permission is hereby granted, free of charge, to any person obtaining a
  6 * copy of this software and associated documentation files (the "Software"),
  7 * to deal in the Software without restriction, including without limitation
  8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9 * and/or sell copies of the Software, and to permit persons to whom the
 10 * Software is furnished to do so, subject to the following conditions:
 11 *
 12 * The above copyright notice and this permission notice (including the next
 13 * paragraph) shall be included in all copies or substantial portions of the
 14 * Software.
 15 *
 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 22 * DEALINGS IN THE SOFTWARE.
 23 *
 24 * Authors:
 25 *	Eric Anholt <eric@anholt.net>
 26 */
 27
 28#include <linux/i2c.h>
 29#include <linux/slab.h>
 30
 31#include <drm/drm_atomic_helper.h>
 32#include <drm/drm_crtc.h>
 33#include <drm/drm_edid.h>
 34#include <drm/drm_print.h>
 35#include <drm/drm_probe_helper.h>
 36
 37#include "intel_connector.h"
 38#include "intel_de.h"
 39#include "intel_display_driver.h"
 40#include "intel_display_regs.h"
 41#include "intel_display_types.h"
 42#include "intel_display_utils.h"
 43#include "intel_dvo.h"
 44#include "intel_dvo_dev.h"
 45#include "intel_dvo_regs.h"
 46#include "intel_gmbus.h"
 47#include "intel_panel.h"
 48
 49#define INTEL_DVO_CHIP_NONE	0
 50#define INTEL_DVO_CHIP_LVDS	1
 51#define INTEL_DVO_CHIP_TMDS	2
 52#define INTEL_DVO_CHIP_TVOUT	4
 53#define INTEL_DVO_CHIP_LVDS_NO_FIXED	5
 54
 55#define SIL164_ADDR	0x38
 56#define CH7xxx_ADDR	0x76
 57#define TFP410_ADDR	0x38
 58#define NS2501_ADDR     0x38
 59
 60static const struct intel_dvo_device intel_dvo_devices[] = {
 61	{
 62		.type = INTEL_DVO_CHIP_TMDS,
 63		.name = "sil164",
 64		.port = PORT_C,
 65		.target_addr = SIL164_ADDR,
 66		.dev_ops = &sil164_ops,
 67	},
 68	{
 69		.type = INTEL_DVO_CHIP_TMDS,
 70		.name = "ch7xxx",
 71		.port = PORT_C,
 72		.target_addr = CH7xxx_ADDR,
 73		.dev_ops = &ch7xxx_ops,
 74	},
 75	{
 76		.type = INTEL_DVO_CHIP_TMDS,
 77		.name = "ch7xxx",
 78		.port = PORT_C,
 79		.target_addr = 0x75, /* For some ch7010 */
 80		.dev_ops = &ch7xxx_ops,
 81	},
 82	{
 83		.type = INTEL_DVO_CHIP_LVDS,
 84		.name = "ivch",
 85		.port = PORT_A,
 86		.target_addr = 0x02, /* Might also be 0x44, 0x84, 0xc4 */
 87		.dev_ops = &ivch_ops,
 88	},
 89	{
 90		.type = INTEL_DVO_CHIP_TMDS,
 91		.name = "tfp410",
 92		.port = PORT_C,
 93		.target_addr = TFP410_ADDR,
 94		.dev_ops = &tfp410_ops,
 95	},
 96	{
 97		.type = INTEL_DVO_CHIP_LVDS,
 98		.name = "ch7017",
 99		.port = PORT_C,
100		.target_addr = 0x75,
101		.gpio = GMBUS_PIN_DPB,
102		.dev_ops = &ch7017_ops,
103	},
104	{
105		.type = INTEL_DVO_CHIP_LVDS_NO_FIXED,
106		.name = "ns2501",
107		.port = PORT_B,
108		.target_addr = NS2501_ADDR,
109		.dev_ops = &ns2501_ops,
110	},
111};
112
113struct intel_dvo {
114	struct intel_encoder base;
115
116	struct intel_dvo_device dev;
117
118	struct intel_connector *attached_connector;
119};
120
121static struct intel_dvo *enc_to_dvo(struct intel_encoder *encoder)
122{
123	return container_of(encoder, struct intel_dvo, base);
124}
125
126static struct intel_dvo *intel_attached_dvo(struct intel_connector *connector)
127{
128	return enc_to_dvo(intel_attached_encoder(connector));
129}
130
131static bool intel_dvo_connector_get_hw_state(struct intel_connector *connector)
132{
133	struct intel_display *display = to_intel_display(connector);
134	struct intel_encoder *encoder = intel_attached_encoder(connector);
135	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
136	enum port port = encoder->port;
137	u32 tmp;
138
139	tmp = intel_de_read(display, DVO(port));
140
141	if (!(tmp & DVO_ENABLE))
142		return false;
143
144	return intel_dvo->dev.dev_ops->get_hw_state(&intel_dvo->dev);
145}
146
147static bool intel_dvo_get_hw_state(struct intel_encoder *encoder,
148				   enum pipe *pipe)
149{
150	struct intel_display *display = to_intel_display(encoder);
151	enum port port = encoder->port;
152	u32 tmp;
153
154	tmp = intel_de_read(display, DVO(port));
155
156	*pipe = REG_FIELD_GET(DVO_PIPE_SEL_MASK, tmp);
157
158	return tmp & DVO_ENABLE;
159}
160
161static void intel_dvo_get_config(struct intel_encoder *encoder,
162				 struct intel_crtc_state *pipe_config)
163{
164	struct intel_display *display = to_intel_display(encoder);
165	enum port port = encoder->port;
166	u32 tmp, flags = 0;
167
168	pipe_config->output_types |= BIT(INTEL_OUTPUT_DVO);
169
170	tmp = intel_de_read(display, DVO(port));
171	if (tmp & DVO_HSYNC_ACTIVE_HIGH)
172		flags |= DRM_MODE_FLAG_PHSYNC;
173	else
174		flags |= DRM_MODE_FLAG_NHSYNC;
175	if (tmp & DVO_VSYNC_ACTIVE_HIGH)
176		flags |= DRM_MODE_FLAG_PVSYNC;
177	else
178		flags |= DRM_MODE_FLAG_NVSYNC;
179
180	pipe_config->hw.adjusted_mode.flags |= flags;
181
182	pipe_config->hw.adjusted_mode.crtc_clock = pipe_config->port_clock;
183}
184
185static void intel_disable_dvo(struct intel_atomic_state *state,
186			      struct intel_encoder *encoder,
187			      const struct intel_crtc_state *old_crtc_state,
188			      const struct drm_connector_state *old_conn_state)
189{
190	struct intel_display *display = to_intel_display(encoder);
191	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
192	enum port port = encoder->port;
193
194	intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false);
195
196	intel_de_rmw(display, DVO(port), DVO_ENABLE, 0);
197	intel_de_posting_read(display, DVO(port));
198}
199
200static void intel_enable_dvo(struct intel_atomic_state *state,
201			     struct intel_encoder *encoder,
202			     const struct intel_crtc_state *pipe_config,
203			     const struct drm_connector_state *conn_state)
204{
205	struct intel_display *display = to_intel_display(encoder);
206	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
207	enum port port = encoder->port;
208
209	intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev,
210					 &pipe_config->hw.mode,
211					 &pipe_config->hw.adjusted_mode);
212
213	intel_de_rmw(display, DVO(port), 0, DVO_ENABLE);
214	intel_de_posting_read(display, DVO(port));
215
216	intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true);
217}
218
219static enum drm_mode_status
220intel_dvo_mode_valid(struct drm_connector *_connector,
221		     const struct drm_display_mode *mode)
222{
223	struct intel_display *display = to_intel_display(_connector->dev);
224	struct intel_connector *connector = to_intel_connector(_connector);
225	struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
226	const struct drm_display_mode *fixed_mode =
227		intel_panel_fixed_mode(connector, mode);
228	int max_dotclk = display->cdclk.max_dotclk_freq;
229	int target_clock = mode->clock;
230	enum drm_mode_status status;
231
232	status = intel_cpu_transcoder_mode_valid(display, mode);
233	if (status != MODE_OK)
234		return status;
235
236	/* XXX: Validate clock range */
237
238	if (fixed_mode) {
239		enum drm_mode_status status;
240
241		status = intel_panel_mode_valid(connector, mode);
242		if (status != MODE_OK)
243			return status;
244
245		target_clock = fixed_mode->clock;
246	}
247
248	if (target_clock > max_dotclk)
249		return MODE_CLOCK_HIGH;
250
251	return intel_dvo->dev.dev_ops->mode_valid(&intel_dvo->dev, mode);
252}
253
254static int intel_dvo_compute_config(struct intel_encoder *encoder,
255				    struct intel_crtc_state *pipe_config,
256				    struct drm_connector_state *conn_state)
257{
258	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
259	struct intel_connector *connector = to_intel_connector(conn_state->connector);
260	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
261	const struct drm_display_mode *fixed_mode =
262		intel_panel_fixed_mode(intel_dvo->attached_connector, adjusted_mode);
263
264	/*
265	 * If we have timings from the BIOS for the panel, put them in
266	 * to the adjusted mode.  The CRTC will be set up for this mode,
267	 * with the panel scaling set up to source from the H/VDisplay
268	 * of the original mode.
269	 */
270	if (fixed_mode) {
271		int ret;
272
273		ret = intel_panel_compute_config(connector, adjusted_mode);
274		if (ret)
275			return ret;
276	}
277
278	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
279		return -EINVAL;
280
281	pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;
282	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
283
284	return 0;
285}
286
287static void intel_dvo_pre_enable(struct intel_atomic_state *state,
288				 struct intel_encoder *encoder,
289				 const struct intel_crtc_state *pipe_config,
290				 const struct drm_connector_state *conn_state)
291{
292	struct intel_display *display = to_intel_display(encoder);
293	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
294	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
295	enum port port = encoder->port;
296	enum pipe pipe = crtc->pipe;
297	u32 dvo_val;
298
299	/* Save the active data order, since I don't know what it should be set to. */
300	dvo_val = intel_de_read(display, DVO(port)) &
301		  (DVO_DEDICATED_INT_ENABLE |
302		   DVO_PRESERVE_MASK | DVO_ACT_DATA_ORDER_MASK);
303	dvo_val |= DVO_DATA_ORDER_FP | DVO_BORDER_ENABLE |
304		   DVO_BLANK_ACTIVE_HIGH;
305
306	dvo_val |= DVO_PIPE_SEL(pipe);
307	dvo_val |= DVO_PIPE_STALL;
308	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
309		dvo_val |= DVO_HSYNC_ACTIVE_HIGH;
310	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
311		dvo_val |= DVO_VSYNC_ACTIVE_HIGH;
312
313	intel_de_write(display, DVO_SRCDIM(port),
314		       DVO_SRCDIM_HORIZONTAL(adjusted_mode->crtc_hdisplay) |
315		       DVO_SRCDIM_VERTICAL(adjusted_mode->crtc_vdisplay));
316	intel_de_write(display, DVO(port), dvo_val);
317}
318
319static enum drm_connector_status
320intel_dvo_detect(struct drm_connector *_connector, bool force)
321{
322	struct intel_display *display = to_intel_display(_connector->dev);
323	struct intel_connector *connector = to_intel_connector(_connector);
324	struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
325
326	drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n",
327		    connector->base.base.id, connector->base.name);
328
329	if (!intel_display_device_enabled(display))
330		return connector_status_disconnected;
331
332	if (!intel_display_driver_check_access(display))
333		return connector->base.status;
334
335	return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev);
336}
337
338static int intel_dvo_get_modes(struct drm_connector *_connector)
339{
340	struct intel_display *display = to_intel_display(_connector->dev);
341	struct intel_connector *connector = to_intel_connector(_connector);
342	int num_modes;
343
344	if (!intel_display_driver_check_access(display))
345		return drm_edid_connector_add_modes(&connector->base);
346
347	/*
348	 * We should probably have an i2c driver get_modes function for those
349	 * devices which will have a fixed set of modes determined by the chip
350	 * (TV-out, for example), but for now with just TMDS and LVDS,
351	 * that's not the case.
352	 */
353	num_modes = intel_ddc_get_modes(&connector->base, connector->base.ddc);
354	if (num_modes)
355		return num_modes;
356
357	return intel_panel_get_modes(connector);
358}
359
360static const struct drm_connector_funcs intel_dvo_connector_funcs = {
361	.detect = intel_dvo_detect,
362	.late_register = intel_connector_register,
363	.early_unregister = intel_connector_unregister,
364	.destroy = intel_connector_destroy,
365	.fill_modes = drm_helper_probe_single_connector_modes,
366	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
367	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
368};
369
370static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = {
371	.mode_valid = intel_dvo_mode_valid,
372	.get_modes = intel_dvo_get_modes,
373};
374
375static void intel_dvo_enc_destroy(struct drm_encoder *encoder)
376{
377	struct intel_dvo *intel_dvo = enc_to_dvo(to_intel_encoder(encoder));
378
379	if (intel_dvo->dev.dev_ops->destroy)
380		intel_dvo->dev.dev_ops->destroy(&intel_dvo->dev);
381
382	intel_encoder_destroy(encoder);
383}
384
385static const struct drm_encoder_funcs intel_dvo_enc_funcs = {
386	.destroy = intel_dvo_enc_destroy,
387};
388
389static int intel_dvo_encoder_type(const struct intel_dvo_device *dvo)
390{
391	switch (dvo->type) {
392	case INTEL_DVO_CHIP_TMDS:
393		return DRM_MODE_ENCODER_TMDS;
394	case INTEL_DVO_CHIP_LVDS_NO_FIXED:
395	case INTEL_DVO_CHIP_LVDS:
396		return DRM_MODE_ENCODER_LVDS;
397	default:
398		MISSING_CASE(dvo->type);
399		return DRM_MODE_ENCODER_NONE;
400	}
401}
402
403static int intel_dvo_connector_type(const struct intel_dvo_device *dvo)
404{
405	switch (dvo->type) {
406	case INTEL_DVO_CHIP_TMDS:
407		return DRM_MODE_CONNECTOR_DVII;
408	case INTEL_DVO_CHIP_LVDS_NO_FIXED:
409	case INTEL_DVO_CHIP_LVDS:
410		return DRM_MODE_CONNECTOR_LVDS;
411	default:
412		MISSING_CASE(dvo->type);
413		return DRM_MODE_CONNECTOR_Unknown;
414	}
415}
416
417static bool intel_dvo_init_dev(struct intel_display *display,
418			       struct intel_dvo *intel_dvo,
419			       const struct intel_dvo_device *dvo)
420{
421	struct i2c_adapter *i2c;
422	u32 dpll[I915_MAX_PIPES];
423	enum pipe pipe;
424	int gpio;
425	bool ret;
426
427	/*
428	 * Allow the I2C driver info to specify the GPIO to be used in
429	 * special cases, but otherwise default to what's defined
430	 * in the spec.
431	 */
432	if (intel_gmbus_is_valid_pin(display, dvo->gpio))
433		gpio = dvo->gpio;
434	else if (dvo->type == INTEL_DVO_CHIP_LVDS)
435		gpio = GMBUS_PIN_SSC;
436	else
437		gpio = GMBUS_PIN_DPB;
438
439	/*
440	 * Set up the I2C bus necessary for the chip we're probing.
441	 * It appears that everything is on GPIOE except for panels
442	 * on i830 laptops, which are on GPIOB (DVOA).
443	 */
444	i2c = intel_gmbus_get_adapter(display, gpio);
445
446	intel_dvo->dev = *dvo;
447
448	/*
449	 * GMBUS NAK handling seems to be unstable, hence let the
450	 * transmitter detection run in bit banging mode for now.
451	 */
452	intel_gmbus_force_bit(i2c, true);
453
454	/*
455	 * ns2501 requires the DVO 2x clock before it will
456	 * respond to i2c accesses, so make sure we have
457	 * the clock enabled before we attempt to initialize
458	 * the device.
459	 */
460	for_each_pipe(display, pipe)
461		dpll[pipe] = intel_de_rmw(display, DPLL(display, pipe), 0,
462					  DPLL_DVO_2X_MODE);
463
464	ret = dvo->dev_ops->init(&intel_dvo->dev, i2c);
465
466	/* restore the DVO 2x clock state to original */
467	for_each_pipe(display, pipe) {
468		intel_de_write(display, DPLL(display, pipe), dpll[pipe]);
469	}
470
471	intel_gmbus_force_bit(i2c, false);
472
473	return ret;
474}
475
476static bool intel_dvo_probe(struct intel_display *display,
477			    struct intel_dvo *intel_dvo)
478{
479	int i;
480
481	/* Now, try to find a controller */
482	for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
483		if (intel_dvo_init_dev(display, intel_dvo,
484				       &intel_dvo_devices[i]))
485			return true;
486	}
487
488	return false;
489}
490
491void intel_dvo_init(struct intel_display *display)
492{
493	struct intel_connector *connector;
494	struct intel_encoder *encoder;
495	struct intel_dvo *intel_dvo;
496
497	intel_dvo = kzalloc(sizeof(*intel_dvo), GFP_KERNEL);
498	if (!intel_dvo)
499		return;
500
501	connector = intel_connector_alloc();
502	if (!connector) {
503		kfree(intel_dvo);
504		return;
505	}
506
507	intel_dvo->attached_connector = connector;
508
509	encoder = &intel_dvo->base;
510
511	encoder->disable = intel_disable_dvo;
512	encoder->enable = intel_enable_dvo;
513	encoder->get_hw_state = intel_dvo_get_hw_state;
514	encoder->get_config = intel_dvo_get_config;
515	encoder->compute_config = intel_dvo_compute_config;
516	encoder->pre_enable = intel_dvo_pre_enable;
517	connector->get_hw_state = intel_dvo_connector_get_hw_state;
518
519	if (!intel_dvo_probe(display, intel_dvo)) {
520		kfree(intel_dvo);
521		intel_connector_free(connector);
522		return;
523	}
524
525	assert_port_valid(display, intel_dvo->dev.port);
526
527	encoder->type = INTEL_OUTPUT_DVO;
528	encoder->power_domain = POWER_DOMAIN_PORT_OTHER;
529	encoder->port = intel_dvo->dev.port;
530	encoder->pipe_mask = ~0;
531
532	if (intel_dvo->dev.type != INTEL_DVO_CHIP_LVDS)
533		encoder->cloneable = BIT(INTEL_OUTPUT_ANALOG) |
534			BIT(INTEL_OUTPUT_DVO);
535
536	drm_encoder_init(display->drm, &encoder->base,
537			 &intel_dvo_enc_funcs,
538			 intel_dvo_encoder_type(&intel_dvo->dev),
539			 "DVO %c", port_name(encoder->port));
540
541	drm_dbg_kms(display->drm, "[ENCODER:%d:%s] detected %s\n",
542		    encoder->base.base.id, encoder->base.name,
543		    intel_dvo->dev.name);
544
545	if (intel_dvo->dev.type == INTEL_DVO_CHIP_TMDS)
546		connector->polled = DRM_CONNECTOR_POLL_CONNECT |
547			DRM_CONNECTOR_POLL_DISCONNECT;
548	connector->base.polled = connector->polled;
549
550	drm_connector_init_with_ddc(display->drm, &connector->base,
551				    &intel_dvo_connector_funcs,
552				    intel_dvo_connector_type(&intel_dvo->dev),
553				    intel_gmbus_get_adapter(display, GMBUS_PIN_DPC));
554
555	drm_connector_helper_add(&connector->base,
556				 &intel_dvo_connector_helper_funcs);
557	connector->base.display_info.subpixel_order = SubPixelHorizontalRGB;
558
559	intel_connector_attach_encoder(connector, encoder);
560
561	if (intel_dvo->dev.type == INTEL_DVO_CHIP_LVDS) {
562		/*
563		 * For our LVDS chipsets, we should hopefully be able
564		 * to dig the fixed panel mode out of the BIOS data.
565		 * However, it's in a different format from the BIOS
566		 * data on chipsets with integrated LVDS (stored in AIM
567		 * headers, likely), so for now, just get the current
568		 * mode being output through DVO.
569		 */
570		intel_panel_add_encoder_fixed_mode(connector, encoder);
571
572		intel_panel_init(connector, NULL);
573	}
574}
~/ Read-only file preview.