2014-01-07 14:54:33

by Ramkumar Ramachandra

[permalink] [raw]
Subject: [INCOMPLETE PATCH v2 0/4] Get EDID late for VGA switcheroo

Hi Chris et al,

I got this far with creating a generic interface for various
get_edid() functions, but I'm stuck now. Where do I get the specific
i2c_adapter from?

I hope the series is okay otherwise.

Thanks.

Ramkumar Ramachandra (4):
drm/i915: add support for vga_switcheroo reprobe
drm/i915: factor out intel_lvds_get_edid()
drm/i915: change intel_sdvo_get_edid() prototype
drm/i915: introduce intel_connector->reprobe

drivers/gpu/drm/i915/i915_dma.c | 8 ++-
drivers/gpu/drm/i915/intel_crt.c | 1 +
drivers/gpu/drm/i915/intel_dp.c | 1 +
drivers/gpu/drm/i915/intel_drv.h | 6 +++
drivers/gpu/drm/i915/intel_lvds.c | 101 ++++++++++++++++++++++----------------
drivers/gpu/drm/i915/intel_sdvo.c | 17 ++++---
6 files changed, 84 insertions(+), 50 deletions(-)

--
1.8.5.2.229.g4448466


2014-01-07 14:54:45

by Ramkumar Ramachandra

[permalink] [raw]
Subject: [PATCH v2 1/4] drm/i915: add support for vga_switcheroo reprobe

Cc: Andreas Heider <[email protected]>
Cc: Seth Forshee <[email protected]>
Original-patch-by: Andreas Heider <[email protected]>
Signed-off-by: Ramkumar Ramachandra <[email protected]>
---
drivers/gpu/drm/i915/i915_dma.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 5c64842..336a835b 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1265,6 +1265,12 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_
}
}

+static void i915_switcheroo_reprobe(struct pci_dev *pdev)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+ intel_fbdev_output_poll_changed(dev);
+}
+
static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
{
struct drm_device *dev = pci_get_drvdata(pdev);
@@ -1278,7 +1284,7 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev)

static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
.set_gpu_state = i915_switcheroo_set_state,
- .reprobe = NULL,
+ .reprobe = i915_switcheroo_reprobe,
.can_switch = i915_switcheroo_can_switch,
};

--
1.8.5.2.229.g4448466

2014-01-07 14:54:54

by Ramkumar Ramachandra

[permalink] [raw]
Subject: [PATCH v2 3/4] drm/i915: change intel_sdvo_get_edid() prototype

In future patches, we intend to introduce a generic interface to the
various get_edid() functions. All the other get_edid() functions accept
two arguments: a struct drm_connector *, and a struct i2c_adapter *. So,
introduce a second dummy variable in intel_sdvo_get_edid().

Cc: Chris Wilson <[email protected]>
Cc: Andreas Heider <[email protected]>
Cc: Seth Forshee <[email protected]>
Signed-off-by: Ramkumar Ramachandra <[email protected]>
---
drivers/gpu/drm/i915/intel_sdvo.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index a583e8f..beb40e5 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1612,7 +1612,8 @@ intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo)
}

static struct edid *
-intel_sdvo_get_edid(struct drm_connector *connector)
+intel_sdvo_get_edid(struct drm_connector *connector,
+ struct i2c_adapter __maybe_unused *dummy)
{
struct intel_sdvo *sdvo = intel_attached_sdvo(connector);
return drm_get_edid(connector, &sdvo->ddc);
@@ -1636,7 +1637,7 @@ intel_sdvo_tmds_sink_detect(struct drm_connector *connector)
enum drm_connector_status status;
struct edid *edid;

- edid = intel_sdvo_get_edid(connector);
+ edid = intel_sdvo_get_edid(connector, NULL);

if (edid == NULL && intel_sdvo_multifunc_encoder(intel_sdvo)) {
u8 ddc, saved_ddc = intel_sdvo->ddc_bus;
@@ -1647,7 +1648,7 @@ intel_sdvo_tmds_sink_detect(struct drm_connector *connector)
*/
for (ddc = intel_sdvo->ddc_bus >> 1; ddc > 1; ddc >>= 1) {
intel_sdvo->ddc_bus = ddc;
- edid = intel_sdvo_get_edid(connector);
+ edid = intel_sdvo_get_edid(connector, NULL);
if (edid)
break;
}
@@ -1740,7 +1741,7 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
struct edid *edid;

/* if we have an edid check it matches the connection */
- edid = intel_sdvo_get_edid(connector);
+ edid = intel_sdvo_get_edid(connector, NULL);
if (edid == NULL)
edid = intel_sdvo_get_analog_edid(connector);
if (edid != NULL) {
@@ -1777,7 +1778,7 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
connector->base.id, drm_get_connector_name(connector));

/* set the bus switch and get the modes */
- edid = intel_sdvo_get_edid(connector);
+ edid = intel_sdvo_get_edid(connector, NULL);

/*
* Mac mini hack. On this device, the DVI-I connector shares one DDC
@@ -2022,7 +2023,7 @@ static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector)
if (!intel_sdvo->is_hdmi)
return false;

- edid = intel_sdvo_get_edid(connector);
+ edid = intel_sdvo_get_edid(connector, NULL);
if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL)
has_audio = drm_detect_monitor_audio(edid);
kfree(edid);
--
1.8.5.2.229.g4448466

2014-01-07 14:55:05

by Ramkumar Ramachandra

[permalink] [raw]
Subject: [PATCH v2 2/4] drm/i915: factor out intel_lvds_get_edid()

Corresponding to

intel_crt_get_edid()
intel_sdvo_get_edid()
intel_dp_get_edid()

add a intel_lvds_get_edid(). We plan to call this during a
switcheroo-reprobe in later patches.

Cc: Chris Wilson <[email protected]>
Cc: Andreas Heider <[email protected]>
Cc: Seth Forshee <[email protected]>
Signed-off-by: Ramkumar Ramachandra <[email protected]>
---
drivers/gpu/drm/i915/intel_lvds.c | 100 ++++++++++++++++++++++----------------
1 file changed, 57 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index c3b4da7..e7aa285 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -921,6 +921,60 @@ static bool intel_lvds_supported(struct drm_device *dev)
return false;
}

+static struct edid *intel_lvds_get_edid(struct drm_connector *connector,
+ struct i2c_adapter *i2c)
+{
+ struct edid *edid;
+ struct intel_lvds_connector *lvds_connector = to_lvds_connector(connector);
+ struct drm_device *dev = connector->dev;
+ struct drm_display_mode *scan; /* *modes, *bios_mode; */
+ struct drm_display_mode *fixed_mode = NULL;
+
+ /*
+ * Attempt to get the fixed panel mode from DDC. Assume that the
+ * preferred mode is the right one.
+ */
+ edid = drm_get_edid(connector, i2c);
+ if (edid) {
+ if (drm_add_edid_modes(connector, edid)) {
+ drm_mode_connector_update_edid_property(connector,
+ edid);
+ } else {
+ kfree(edid);
+ edid = ERR_PTR(-EINVAL);
+ }
+ } else {
+ edid = ERR_PTR(-ENOENT);
+ }
+ lvds_connector->base.edid = edid;
+
+ if (IS_ERR_OR_NULL(edid)) {
+ /* Didn't get an EDID, so
+ * Set wide sync ranges so we get all modes
+ * handed to valid_mode for checking
+ */
+ connector->display_info.min_vfreq = 0;
+ connector->display_info.max_vfreq = 200;
+ connector->display_info.min_hfreq = 0;
+ connector->display_info.max_hfreq = 200;
+ }
+
+ list_for_each_entry(scan, &connector->probed_modes, head) {
+ if (scan->type & DRM_MODE_TYPE_PREFERRED) {
+ DRM_DEBUG_KMS("using preferred mode from EDID: ");
+ drm_mode_debug_printmodeline(scan);
+
+ fixed_mode = drm_mode_duplicate(dev, scan);
+ if (fixed_mode) {
+ intel_find_lvds_downclock(dev, fixed_mode,
+ connector);
+ return edid;
+ }
+ }
+ }
+ return NULL;
+}
+
/**
* intel_lvds_init - setup LVDS connectors on this device
* @dev: drm device
@@ -937,7 +991,6 @@ void intel_lvds_init(struct drm_device *dev)
struct intel_connector *intel_connector;
struct drm_connector *connector;
struct drm_encoder *encoder;
- struct drm_display_mode *scan; /* *modes, *bios_mode; */
struct drm_display_mode *fixed_mode = NULL;
struct edid *edid;
struct drm_crtc *crtc;
@@ -1036,48 +1089,9 @@ void intel_lvds_init(struct drm_device *dev)
* if closed, act like it's not there for now
*/

- /*
- * Attempt to get the fixed panel mode from DDC. Assume that the
- * preferred mode is the right one.
- */
- edid = drm_get_edid(connector, intel_gmbus_get_adapter(dev_priv, pin));
- if (edid) {
- if (drm_add_edid_modes(connector, edid)) {
- drm_mode_connector_update_edid_property(connector,
- edid);
- } else {
- kfree(edid);
- edid = ERR_PTR(-EINVAL);
- }
- } else {
- edid = ERR_PTR(-ENOENT);
- }
- lvds_connector->base.edid = edid;
-
- if (IS_ERR_OR_NULL(edid)) {
- /* Didn't get an EDID, so
- * Set wide sync ranges so we get all modes
- * handed to valid_mode for checking
- */
- connector->display_info.min_vfreq = 0;
- connector->display_info.max_vfreq = 200;
- connector->display_info.min_hfreq = 0;
- connector->display_info.max_hfreq = 200;
- }
-
- list_for_each_entry(scan, &connector->probed_modes, head) {
- if (scan->type & DRM_MODE_TYPE_PREFERRED) {
- DRM_DEBUG_KMS("using preferred mode from EDID: ");
- drm_mode_debug_printmodeline(scan);
-
- fixed_mode = drm_mode_duplicate(dev, scan);
- if (fixed_mode) {
- intel_find_lvds_downclock(dev, fixed_mode,
- connector);
- goto out;
- }
- }
- }
+ edid = intel_lvds_get_edid(connector, intel_gmbus_get_adapter(dev_priv, pin));
+ if (edid)
+ goto out;

/* Failed to get EDID, what about VBT? */
if (dev_priv->vbt.lfp_lvds_vbt_mode) {
--
1.8.5.2.229.g4448466

2014-01-07 14:55:26

by Ramkumar Ramachandra

[permalink] [raw]
Subject: [PATCH v2 4/4] drm/i915: introduce intel_connector->reprobe

Introduce a struct edid *(*reprobe)(struct drm_connector *, struct
i2c_adapter *) in struct intel_connector to point to various get_edid()
functions.

Cc: Chris Wilson <[email protected]>
Cc: Andreas Heider <[email protected]>
Cc: Seth Forshee <[email protected]>
Signed-off-by: Ramkumar Ramachandra <[email protected]>
---
drivers/gpu/drm/i915/intel_crt.c | 1 +
drivers/gpu/drm/i915/intel_dp.c | 1 +
drivers/gpu/drm/i915/intel_drv.h | 6 ++++++
drivers/gpu/drm/i915/intel_lvds.c | 1 +
drivers/gpu/drm/i915/intel_sdvo.c | 4 ++++
5 files changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index b5b1b9b..4e678fe 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -832,6 +832,7 @@ void intel_crt_init(struct drm_device *dev)
crt->base.get_hw_state = intel_crt_get_hw_state;
}
intel_connector->get_hw_state = intel_connector_get_hw_state;
+ intel_connector->reprobe = intel_crt_get_edid;

drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 30c627c..2f4491c 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3657,6 +3657,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
else
intel_connector->get_hw_state = intel_connector_get_hw_state;
+ intel_connector->reprobe = intel_dp_get_edid;

intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10;
if (HAS_DDI(dev)) {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 79f91f2..6ff89da 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -175,6 +175,12 @@ struct intel_connector {
* and active (i.e. dpms ON state). */
bool (*get_hw_state)(struct intel_connector *);

+ /*
+ * Points to the corresponding get_edid() functions for
+ * LVDS, CRT, SDVO, and DP
+ */
+ struct edid *(*reprobe)(struct drm_connector *, struct i2c_adapter *);
+
/* Panel info for eDP and LVDS */
struct intel_panel panel;

diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index e7aa285..6a7078e 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -1050,6 +1050,7 @@ void intel_lvds_init(struct drm_device *dev)
intel_encoder->get_hw_state = intel_lvds_get_hw_state;
intel_encoder->get_config = intel_lvds_get_config;
intel_connector->get_hw_state = intel_connector_get_hw_state;
+ intel_connector->reprobe = intel_lvds_get_edid;

intel_connector_attach_encoder(intel_connector, intel_encoder);
intel_encoder->type = INTEL_OUTPUT_LVDS;
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index beb40e5..2083993 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2420,6 +2420,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
}

intel_connector = &intel_sdvo_connector->base;
+ intel_connector->reprobe = intel_sdvo_get_edid;
connector = &intel_connector->base;
if (intel_sdvo_get_hotplug_support(intel_sdvo) &
intel_sdvo_connector->output_flag) {
@@ -2462,6 +2463,7 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
return false;

intel_connector = &intel_sdvo_connector->base;
+ intel_connector->reprobe = intel_sdvo_get_edid;
connector = &intel_connector->base;
encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
@@ -2502,6 +2504,7 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
return false;

intel_connector = &intel_sdvo_connector->base;
+ intel_connector->reprobe = intel_sdvo_get_edid;
connector = &intel_connector->base;
intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
encoder->encoder_type = DRM_MODE_ENCODER_DAC;
@@ -2535,6 +2538,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
return false;

intel_connector = &intel_sdvo_connector->base;
+ intel_connector->reprobe = intel_sdvo_get_edid;
connector = &intel_connector->base;
encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
--
1.8.5.2.229.g4448466

2014-01-07 14:57:07

by Ramkumar Ramachandra

[permalink] [raw]
Subject: Re: [INCOMPLETE PATCH v2 0/4] Get EDID late for VGA switcheroo

[Forgot to CC]

On Tue, Jan 7, 2014 at 8:24 PM, Ramkumar Ramachandra <[email protected]> wrote:
> Hi Chris et al,
>
> I got this far with creating a generic interface for various
> get_edid() functions, but I'm stuck now. Where do I get the specific
> i2c_adapter from?
>
> I hope the series is okay otherwise.
>
> Thanks.
>
> Ramkumar Ramachandra (4):
> drm/i915: add support for vga_switcheroo reprobe
> drm/i915: factor out intel_lvds_get_edid()
> drm/i915: change intel_sdvo_get_edid() prototype
> drm/i915: introduce intel_connector->reprobe
>
> drivers/gpu/drm/i915/i915_dma.c | 8 ++-
> drivers/gpu/drm/i915/intel_crt.c | 1 +
> drivers/gpu/drm/i915/intel_dp.c | 1 +
> drivers/gpu/drm/i915/intel_drv.h | 6 +++
> drivers/gpu/drm/i915/intel_lvds.c | 101 ++++++++++++++++++++++----------------
> drivers/gpu/drm/i915/intel_sdvo.c | 17 ++++---
> 6 files changed, 84 insertions(+), 50 deletions(-)
>
> --
> 1.8.5.2.229.g4448466
>