Skip to content

Instantly share code, notes, and snippets.

@Drakulix
Created July 21, 2014 09:52
Show Gist options
  • Save Drakulix/d3013d7834db53f04b2f to your computer and use it in GitHub Desktop.
Save Drakulix/d3013d7834db53f04b2f to your computer and use it in GitHub Desktop.
linux-kernel-patch-apple-gmux-retina-macbookpro10,1
diff -rupN linux-3.15.6/drivers/gpu/drm/i915/intel_display.c linux-3.15.6_patched/drivers/gpu/drm/i915/intel_display.c
--- linux-3.15.6/drivers/gpu/drm/i915/intel_display.c 2014-07-18 01:23:31.000000000 +0200
+++ linux-3.15.6_patched/drivers/gpu/drm/i915/intel_display.c 2014-07-20 22:50:29.000000000 +0200
@@ -40,6 +40,8 @@
#include <drm/drm_dp_helper.h>
#include <drm/drm_crtc_helper.h>
#include <linux/dma_remapping.h>
+//PATCH [0/1]
+#include <linux/vga_switcheroo.h>
static void intel_increase_pllclock(struct drm_crtc *crtc);
static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on);
@@ -10707,8 +10709,16 @@ static void intel_setup_outputs(struct d
struct intel_encoder *encoder;
bool dpd_is_edp = false;
- intel_lvds_init(dev);
-
+ /*
+ Patch [0/1]: Switch apple-gmux so lvds is detectable
+ */
+ vga_switcheroo_lock_dcc(dev->pdev);
+ intel_lvds_init(dev);
+ vga_switcheroo_unlock_dcc(dev->pdev);
+ /*
+ Patch [0/1]: End
+ */
+
if (!IS_ULT(dev))
intel_crt_init(dev);
diff -rupN linux-3.15.6/drivers/gpu/vga/vga_switcheroo.c linux-3.15.6_patched/drivers/gpu/vga/vga_switcheroo.c
--- linux-3.15.6/drivers/gpu/vga/vga_switcheroo.c 2014-07-18 01:23:31.000000000 +0200
+++ linux-3.15.6_patched/drivers/gpu/vga/vga_switcheroo.c 2014-07-20 23:06:21.000000000 +0200
@@ -43,6 +43,7 @@ struct vga_switcheroo_client {
};
static DEFINE_MUTEX(vgasr_mutex);
+static DEFINE_MUTEX(vgasr_dcc_mutex);
struct vgasr_priv {
@@ -579,6 +580,64 @@ err:
}
EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);
+/*
+ Patch [0/1]: Functions to switch the mux on driver initialization
+ */
+
+int vga_switcheroo_lock_dcc(struct pci_dev *pdev)
+{
+ int client_id = -1;
+ int i;
+
+ mutex_lock(&vgasr_mutex);
+ for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
+ if (vgasr_priv.clients[i].pdev == pdev)
+ client_id = vgasr_priv.clients[i].id;
+ }
+
+ if (vgasr_priv.handler && vgasr_priv.handler->switchddc) {
+ //small hack, in case the intel card is not registered yet
+ if (client_id == -1)
+ client_id = VGA_SWITCHEROO_IGD;
+
+ mutex_unlock(&vgasr_mutex);
+ mutex_lock(&vgasr_dcc_mutex);
+ return vgasr_priv->switchddc(client_id);
+ }
+
+ mutex_unlock(&vgasr_mutex);
+ return 0;
+
+}
+EXPORT_SYMBOL(vga_switcheroo_lock_dcc);
+
+void vga_switcheroo_unlock_dcc(struct pci_dev *pdev)
+{
+ int client_id = -1;
+ int i;
+
+ mutex_lock(&vgasr_mutex);
+ for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
+ if (vgasr_priv.clients[i].active)
+ client_id = vgasr_priv.clients[i].id;
+ }
+
+ f (vgasr_priv.handler && vgasr_priv.handler->switchddc) {
+ //small hack, in case the nvidia card is not registered yet
+ if (client_id == -1)
+ client_id = VGA_SWITCHEROO_DIS;
+
+ vgasr_priv->switchddc(client_id);
+ }
+
+ mutex_unlock(&vgasr_mutex);
+ mutex_unlock(&vgasr_dcc_mutex);
+}
+
+/*
+ Patch [0/1]: End
+ */
+
static void vga_switcheroo_power_switch(struct pci_dev *pdev, enum vga_switcheroo_state state)
{
struct vga_switcheroo_client *client;
diff -rupN linux-3.15.6/drivers/platform/x86/apple-gmux.c linux-3.15.6_patched/drivers/platform/x86/apple-gmux.c
--- linux-3.15.6/drivers/platform/x86/apple-gmux.c 2014-07-18 01:23:31.000000000 +0200
+++ linux-3.15.6_patched/drivers/platform/x86/apple-gmux.c 2014-07-20 23:16:54.000000000 +0200
@@ -286,6 +286,20 @@ static int gmux_switchto(enum vga_switch
return 0;
}
+/*
+ PATCH [0/1]: Custom Callback to switch DCC during lvds initialization
+ */
+static int gmux_switchdcc(enum vga_switcheroo_client_id id)
+{
+ if (id == VGA_SWITCHEROO_IGD) {
+ gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 1);
+ } else {
+ gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 2);
+ }
+
+ return 0;
+}
+
static int gmux_set_discrete_state(struct apple_gmux_data *gmux_data,
enum vga_switcheroo_state state)
{
@@ -346,6 +360,10 @@ gmux_active_client(struct apple_gmux_dat
static struct vga_switcheroo_handler gmux_handler = {
.switchto = gmux_switchto,
+ /*
+ PATCH [0/1]: register custom callback
+ */
+ .switchdcc = gmux_switchdcc,
.power_state = gmux_set_power_state,
.get_client_id = gmux_get_client_id,
};
diff -rupN linux-3.15.6/include/linux/vga_switcheroo.h linux-3.15.6_patched/include/linux/vga_switcheroo.h
--- linux-3.15.6/include/linux/vga_switcheroo.h 2014-07-18 01:23:31.000000000 +0200
+++ linux-3.15.6_patched/include/linux/vga_switcheroo.h 2014-07-20 23:10:08.000000000 +0200
@@ -30,6 +30,10 @@ enum vga_switcheroo_client_id {
struct vga_switcheroo_handler {
int (*switchto)(enum vga_switcheroo_client_id id);
+ /*
+ Patch [0/1]: Callback to switch the mux on driver initialization
+ */
+ int (*switchdcc)(enum vga_switcheroo_client_id id);
int (*power_state)(enum vga_switcheroo_client_id id,
enum vga_switcheroo_state state);
int (*init)(void);
@@ -65,6 +69,13 @@ void vga_switcheroo_set_dynamic_switch(s
int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain);
int vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev, struct dev_pm_domain *domain);
+
+/*
+ Patch [0/1]: Functions to switch the mux on driver initialization
+ */
+int vga_switcheroo_lock_dcc(struct pci_dev *dev);
+void vga_switcheroo_unlock_dcc(struct pci_dev *dev);
+
#else
static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment