Skip to content

Commit 021a62a

Browse files
committed
drm/i915: Try to initialize DDI/ICL+ DSI ports for every VBT child device
Try to deal with duplicate child devices for the same DDI port by attempting to initialize them in VBT defined order The first on to succeed for a specific DDI port will be the one we use. We'll also get rid of i915->display.vbt.ports[] here as any conflicts will now be handled at encoder registration time rather than during VBT parsing. Note that intel_bios_encoder_data_lookup() still remaims for pre-DDI DP/HDMI ports as those don't (at least yet) use VBT driven initialization. TODO: DSI dual link handling is sketchy at best v2: Leave intel_bios_encoder_port() to the encoder callback (Jani) Cc: Jani Nikula <[email protected]> Signed-off-by: Ville Syrjälä <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Reviewed-by: Jani Nikula <[email protected]>
1 parent d84b194 commit 021a62a

File tree

8 files changed

+93
-47
lines changed

8 files changed

+93
-47
lines changed

drivers/gpu/drm/i915/display/icl_dsi.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,15 +1933,17 @@ static void icl_dsi_add_properties(struct intel_connector *connector)
19331933
fixed_mode->vdisplay);
19341934
}
19351935

1936-
void icl_dsi_init(struct drm_i915_private *dev_priv)
1936+
void icl_dsi_init(struct drm_i915_private *dev_priv,
1937+
const struct intel_bios_encoder_data *devdata)
19371938
{
19381939
struct intel_dsi *intel_dsi;
19391940
struct intel_encoder *encoder;
19401941
struct intel_connector *intel_connector;
19411942
struct drm_connector *connector;
19421943
enum port port;
19431944

1944-
if (!intel_bios_is_dsi_present(dev_priv, &port))
1945+
port = intel_bios_encoder_port(devdata);
1946+
if (port == PORT_NONE)
19451947
return;
19461948

19471949
intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL);
@@ -1958,6 +1960,8 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
19581960
intel_dsi->attached_connector = intel_connector;
19591961
connector = &intel_connector->base;
19601962

1963+
encoder->devdata = devdata;
1964+
19611965
/* register DSI encoder with DRM subsystem */
19621966
drm_encoder_init(&dev_priv->drm, &encoder->base, &gen11_dsi_encoder_funcs,
19631967
DRM_MODE_ENCODER_DSI, "DSI %c", port_name(port));
@@ -1995,7 +1999,6 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
19951999

19962000
intel_dsi->panel_power_off_time = ktime_get_boottime();
19972001

1998-
encoder->devdata = intel_bios_encoder_data_lookup(dev_priv, port);
19992002
intel_bios_init_panel_late(dev_priv, &intel_connector->panel, encoder->devdata, NULL);
20002003

20012004
mutex_lock(&dev_priv->drm.mode_config.mutex);

drivers/gpu/drm/i915/display/icl_dsi.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
#define __ICL_DSI_H__
88

99
struct drm_i915_private;
10+
struct intel_bios_encoder_data;
1011
struct intel_crtc_state;
1112

12-
void icl_dsi_init(struct drm_i915_private *i915);
13+
void icl_dsi_init(struct drm_i915_private *dev_priv,
14+
const struct intel_bios_encoder_data *devdata);
1315
void icl_dsi_frame_update(struct intel_crtc_state *crtc_state);
1416

1517
#endif /* __ICL_DSI_H__ */

drivers/gpu/drm/i915/display/intel_bios.c

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2374,7 +2374,7 @@ dsi_dvo_port_to_port(struct drm_i915_private *i915, u8 dvo_port)
23742374
}
23752375
}
23762376

2377-
static enum port intel_bios_encoder_port(const struct intel_bios_encoder_data *devdata)
2377+
enum port intel_bios_encoder_port(const struct intel_bios_encoder_data *devdata)
23782378
{
23792379
struct drm_i915_private *i915 = devdata->i915;
23802380
const struct child_device_config *child = &devdata->child;
@@ -2497,7 +2497,7 @@ intel_bios_encoder_supports_edp(const struct intel_bios_encoder_data *devdata)
24972497
devdata->child.device_type & DEVICE_TYPE_INTERNAL_CONNECTOR;
24982498
}
24992499

2500-
static bool
2500+
bool
25012501
intel_bios_encoder_supports_dsi(const struct intel_bios_encoder_data *devdata)
25022502
{
25032503
return devdata->child.device_type & DEVICE_TYPE_MIPI_OUTPUT;
@@ -2556,13 +2556,17 @@ static bool is_port_valid(struct drm_i915_private *i915, enum port port)
25562556
return true;
25572557
}
25582558

2559-
static void print_ddi_port(const struct intel_bios_encoder_data *devdata,
2560-
enum port port)
2559+
static void print_ddi_port(const struct intel_bios_encoder_data *devdata)
25612560
{
25622561
struct drm_i915_private *i915 = devdata->i915;
25632562
const struct child_device_config *child = &devdata->child;
25642563
bool is_dvi, is_hdmi, is_dp, is_edp, is_dsi, is_crt, supports_typec_usb, supports_tbt;
25652564
int dp_boost_level, dp_max_link_rate, hdmi_boost_level, hdmi_level_shift, max_tmds_clock;
2565+
enum port port;
2566+
2567+
port = intel_bios_encoder_port(devdata);
2568+
if (port == PORT_NONE)
2569+
return;
25662570

25672571
is_dvi = intel_bios_encoder_supports_dvi(devdata);
25682572
is_dp = intel_bios_encoder_supports_dp(devdata);
@@ -2639,16 +2643,7 @@ static void parse_ddi_port(struct intel_bios_encoder_data *devdata)
26392643
return;
26402644
}
26412645

2642-
if (i915->display.vbt.ports[port]) {
2643-
drm_dbg_kms(&i915->drm,
2644-
"More than one child device for port %c in VBT, using the first.\n",
2645-
port_name(port));
2646-
return;
2647-
}
2648-
26492646
sanitize_device_type(devdata, port);
2650-
2651-
i915->display.vbt.ports[port] = devdata;
26522647
}
26532648

26542649
static bool has_ddi_port_info(struct drm_i915_private *i915)
@@ -2659,18 +2654,15 @@ static bool has_ddi_port_info(struct drm_i915_private *i915)
26592654
static void parse_ddi_ports(struct drm_i915_private *i915)
26602655
{
26612656
struct intel_bios_encoder_data *devdata;
2662-
enum port port;
26632657

26642658
if (!has_ddi_port_info(i915))
26652659
return;
26662660

26672661
list_for_each_entry(devdata, &i915->display.vbt.display_devices, node)
26682662
parse_ddi_port(devdata);
26692663

2670-
for_each_port(port) {
2671-
if (i915->display.vbt.ports[port])
2672-
print_ddi_port(i915->display.vbt.ports[port], port);
2673-
}
2664+
list_for_each_entry(devdata, &i915->display.vbt.display_devices, node)
2665+
print_ddi_port(devdata);
26742666
}
26752667

26762668
static void
@@ -3595,5 +3587,22 @@ bool intel_bios_encoder_hpd_invert(const struct intel_bios_encoder_data *devdata
35953587
const struct intel_bios_encoder_data *
35963588
intel_bios_encoder_data_lookup(struct drm_i915_private *i915, enum port port)
35973589
{
3598-
return i915->display.vbt.ports[port];
3590+
struct intel_bios_encoder_data *devdata;
3591+
3592+
list_for_each_entry(devdata, &i915->display.vbt.display_devices, node) {
3593+
if (intel_bios_encoder_port(devdata) == port)
3594+
return devdata;
3595+
}
3596+
3597+
return NULL;
3598+
}
3599+
3600+
void intel_bios_for_each_encoder(struct drm_i915_private *i915,
3601+
void (*func)(struct drm_i915_private *i915,
3602+
const struct intel_bios_encoder_data *devdata))
3603+
{
3604+
struct intel_bios_encoder_data *devdata;
3605+
3606+
list_for_each_entry(devdata, &i915->display.vbt.display_devices, node)
3607+
func(i915, devdata);
35993608
}

drivers/gpu/drm/i915/display/intel_bios.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,12 @@ bool intel_bios_encoder_supports_dp(const struct intel_bios_encoder_data *devdat
263263
bool intel_bios_encoder_supports_edp(const struct intel_bios_encoder_data *devdata);
264264
bool intel_bios_encoder_supports_typec_usb(const struct intel_bios_encoder_data *devdata);
265265
bool intel_bios_encoder_supports_tbt(const struct intel_bios_encoder_data *devdata);
266+
bool intel_bios_encoder_supports_dsi(const struct intel_bios_encoder_data *devdata);
266267
bool intel_bios_encoder_supports_dp_dual_mode(const struct intel_bios_encoder_data *devdata);
267268
bool intel_bios_encoder_is_lspcon(const struct intel_bios_encoder_data *devdata);
268269
bool intel_bios_encoder_lane_reversal(const struct intel_bios_encoder_data *devdata);
269270
bool intel_bios_encoder_hpd_invert(const struct intel_bios_encoder_data *devdata);
271+
enum port intel_bios_encoder_port(const struct intel_bios_encoder_data *devdata);
270272
enum aux_ch intel_bios_dp_aux_ch(const struct intel_bios_encoder_data *devdata);
271273
int intel_bios_dp_boost_level(const struct intel_bios_encoder_data *devdata);
272274
int intel_bios_dp_max_lane_count(const struct intel_bios_encoder_data *devdata);
@@ -276,4 +278,8 @@ int intel_bios_hdmi_ddc_pin(const struct intel_bios_encoder_data *devdata);
276278
int intel_bios_hdmi_level_shift(const struct intel_bios_encoder_data *devdata);
277279
int intel_bios_hdmi_max_tmds_clock(const struct intel_bios_encoder_data *devdata);
278280

281+
void intel_bios_for_each_encoder(struct drm_i915_private *i915,
282+
void (*func)(struct drm_i915_private *i915,
283+
const struct intel_bios_encoder_data *devdata));
284+
279285
#endif /* _INTEL_BIOS_H_ */

drivers/gpu/drm/i915/display/intel_ddi.c

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
#include "i915_drv.h"
3434
#include "i915_reg.h"
35+
#include "icl_dsi.h"
3536
#include "intel_audio.h"
3637
#include "intel_audio_regs.h"
3738
#include "intel_backlight.h"
@@ -4684,13 +4685,38 @@ static bool need_aux_ch(struct intel_encoder *encoder, bool init_dp)
46844685
return init_dp || intel_phy_is_tc(i915, phy);
46854686
}
46864687

4687-
void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
4688+
static bool assert_has_icl_dsi(struct drm_i915_private *i915)
4689+
{
4690+
return !drm_WARN(&i915->drm, !IS_ALDERLAKE_P(i915) &&
4691+
!IS_TIGERLAKE(i915) && DISPLAY_VER(i915) != 11,
4692+
"Platform does not support DSI\n");
4693+
}
4694+
4695+
static bool port_in_use(struct drm_i915_private *i915, enum port port)
4696+
{
4697+
struct intel_encoder *encoder;
4698+
4699+
for_each_intel_encoder(&i915->drm, encoder) {
4700+
/* FIXME what about second port for dual link DSI? */
4701+
if (encoder->port == port)
4702+
return true;
4703+
}
4704+
4705+
return false;
4706+
}
4707+
4708+
void intel_ddi_init(struct drm_i915_private *dev_priv,
4709+
const struct intel_bios_encoder_data *devdata)
46884710
{
46894711
struct intel_digital_port *dig_port;
46904712
struct intel_encoder *encoder;
4691-
const struct intel_bios_encoder_data *devdata;
46924713
bool init_hdmi, init_dp;
4693-
enum phy phy = intel_port_to_phy(dev_priv, port);
4714+
enum port port;
4715+
enum phy phy;
4716+
4717+
port = intel_bios_encoder_port(devdata);
4718+
if (port == PORT_NONE)
4719+
return;
46944720

46954721
if (!port_strap_detected(dev_priv, port)) {
46964722
drm_dbg_kms(&dev_priv->drm,
@@ -4701,6 +4727,23 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
47014727
if (!assert_port_valid(dev_priv, port))
47024728
return;
47034729

4730+
if (port_in_use(dev_priv, port)) {
4731+
drm_dbg_kms(&dev_priv->drm,
4732+
"Port %c already claimed\n", port_name(port));
4733+
return;
4734+
}
4735+
4736+
if (intel_bios_encoder_supports_dsi(devdata)) {
4737+
/* BXT/GLK handled elsewhere, for now at least */
4738+
if (!assert_has_icl_dsi(dev_priv))
4739+
return;
4740+
4741+
icl_dsi_init(dev_priv, devdata);
4742+
return;
4743+
}
4744+
4745+
phy = intel_port_to_phy(dev_priv, port);
4746+
47044747
/*
47054748
* On platforms with HTI (aka HDPORT), if it's enabled at boot it may
47064749
* have taken over some of the PHYs and made them unavailable to the
@@ -4713,14 +4756,6 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
47134756
return;
47144757
}
47154758

4716-
devdata = intel_bios_encoder_data_lookup(dev_priv, port);
4717-
if (!devdata) {
4718-
drm_dbg_kms(&dev_priv->drm,
4719-
"VBT says port %c is not present\n",
4720-
port_name(port));
4721-
return;
4722-
}
4723-
47244759
init_hdmi = intel_bios_encoder_supports_dvi(devdata) ||
47254760
intel_bios_encoder_supports_hdmi(devdata);
47264761
init_dp = intel_bios_encoder_supports_dp(devdata);

drivers/gpu/drm/i915/display/intel_ddi.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
struct drm_connector_state;
1212
struct drm_i915_private;
1313
struct intel_atomic_state;
14+
struct intel_bios_encoder_data;
1415
struct intel_connector;
1516
struct intel_crtc;
1617
struct intel_crtc_state;
@@ -50,7 +51,8 @@ void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder,
5051
const struct intel_crtc_state *crtc_state);
5152
void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
5253
enum port port);
53-
void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port);
54+
void intel_ddi_init(struct drm_i915_private *dev_priv,
55+
const struct intel_bios_encoder_data *devdata);
5456
bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe);
5557
void intel_ddi_enable_transcoder_func(struct intel_encoder *encoder,
5658
const struct intel_crtc_state *crtc_state);

drivers/gpu/drm/i915/display/intel_display.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
#include "i915_utils.h"
5454
#include "i9xx_plane.h"
5555
#include "i9xx_wm.h"
56-
#include "icl_dsi.h"
5756
#include "intel_atomic.h"
5857
#include "intel_atomic_plane.h"
5958
#include "intel_audio.h"
@@ -7412,18 +7411,10 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv)
74127411
return;
74137412

74147413
if (HAS_DDI(dev_priv)) {
7415-
enum port port;
7416-
74177414
if (intel_ddi_crt_present(dev_priv))
74187415
intel_crt_init(dev_priv);
74197416

7420-
for_each_port_masked(port, DISPLAY_RUNTIME_INFO(dev_priv)->port_mask)
7421-
intel_ddi_init(dev_priv, port);
7422-
7423-
/* FIXME do something about DSI */
7424-
if (IS_ALDERLAKE_P(dev_priv) || IS_TIGERLAKE(dev_priv) ||
7425-
DISPLAY_VER(dev_priv) == 11)
7426-
icl_dsi_init(dev_priv);
7417+
intel_bios_for_each_encoder(dev_priv, intel_ddi_init);
74277418

74287419
if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
74297420
vlv_dsi_init(dev_priv);

drivers/gpu/drm/i915/display/intel_display_core.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ struct i915_audio_component;
3434
struct i915_hdcp_arbiter;
3535
struct intel_atomic_state;
3636
struct intel_audio_funcs;
37-
struct intel_bios_encoder_data;
3837
struct intel_cdclk_funcs;
3938
struct intel_cdclk_vals;
4039
struct intel_color_funcs;
@@ -219,7 +218,6 @@ struct intel_vbt_data {
219218
struct list_head display_devices;
220219
struct list_head bdb_blocks;
221220

222-
struct intel_bios_encoder_data *ports[I915_MAX_PORTS]; /* Non-NULL if port present. */
223221
struct sdvo_device_mapping {
224222
u8 initialized;
225223
u8 dvo_port;

0 commit comments

Comments
 (0)