Finally got my Macbookpro8,2 booting successfully under EFI using the integrated Intel card with the Radeon switched off. I'm running linux-mainline (3.0 final) with the LVDS dual channel patch applied.
I've attached the dual channel patch and my grub.cfg. I'm booting using the Apple bootloader straight into grub. I copied grub.efi to /dev/sda1/EFI/BOOT/BOOTX64.EFI (Mac book partition).
Thanks to Sloth and others on the forum for the info!
grub.cfg
Code:
insmod efi_gop
insmod font
insmod part_gpt
insmod part_msdos
insmod part_gpt
insmod ext2
if [ -s $prefix/grubenv ]; then
load_env
fi
set debug=video
if [ "${prev_saved_entry}" ]; then
set saved_entry="${prev_saved_entry}"
save_env saved_entry
set prev_saved_entry=
save_env prev_saved_entry
set boot_once=true
fi
function savedefault {
if [ -z "${boot_once}" ]; then
saved_entry="${chosen}"
save_env saved_entry
fi
}
set menu_color_normal=light-blue/black
set menu_color_highlight=light-cyan/blue
if loadfont ${prefix}/unicode.pf2
then
insmod gfxterm
set gfxmode=auto
set gfxpayload=keep
terminal_output gfxterm
fi
terminal_input console
terminal_output gfxterm
set timeout=15
menuentry 'Arch Linux vmlinuz26-mainline Fallback' --class archlinux --class gnu-linux --class gnu --class os {
set root=(hd0,gpt3)
fix_video
loadbios /vbios.bin /int10.bin
outb 0x728 1
outb 0x710 2
outb 0x740 2
outb 0x750 0
echo 'Loading Linux vmlinuz-linux-mainline ...'
linux /vmlinuz-linux-mainline root=/dev/sda5 rootfstype=ext4 ro i915.lvds_channels=2
echo 'Loading initial ramdisk ...'
initrd /initramfs-linux-mainline-fallback.img
}
if [ -f $prefix/custom.cfg ]; then
source $prefix/custom.cfg;
fi
Patch
Code:
diff -rupN linux-3.0/drivers/gpu/drm/i915/i915_drv.c linux-3.0-lvds//drivers/gpu/drm/i915/i915_drv.c
--- linux-3.0/drivers/gpu/drm/i915/i915_drv.c 2011-07-21 20:17:23.000000000 -0600
+++ linux-3.0-lvds//drivers/gpu/drm/i915/i915_drv.c 2011-07-23 19:09:40.485052832 -0600
@@ -70,6 +70,10 @@ module_param_named(vbt_sdvo_panel_type,
static bool i915_try_reset = true;
module_param_named(reset, i915_try_reset, bool, 0600);
+unsigned int i915_lvds_channels = 0;
+module_param_named(lvds_channels, i915_lvds_channels, int, 0600);
+MODULE_PARM_DESC(lvds_channels, "LVDS channels in use: 0=(default) probe hardware 1=single 2=dual");
+
static struct drm_driver driver;
extern int intel_agp_enabled;
diff -rupN linux-3.0/drivers/gpu/drm/i915/i915_drv.h linux-3.0-lvds//drivers/gpu/drm/i915/i915_drv.h
--- linux-3.0/drivers/gpu/drm/i915/i915_drv.h 2011-07-21 20:17:23.000000000 -0600
+++ linux-3.0-lvds//drivers/gpu/drm/i915/i915_drv.h 2011-07-23 19:10:27.611535702 -0600
@@ -990,6 +990,7 @@ extern unsigned int i915_fbpercrtc;
extern int i915_panel_ignore_lid;
extern unsigned int i915_powersave;
extern unsigned int i915_semaphores;
+extern unsigned int i915_lvds_channels;
extern unsigned int i915_lvds_downclock;
extern unsigned int i915_panel_use_ssc;
extern int i915_vbt_sdvo_panel_type;
diff -rupN linux-3.0/drivers/gpu/drm/i915/intel_display.c linux-3.0-lvds//drivers/gpu/drm/i915/intel_display.c
--- linux-3.0/drivers/gpu/drm/i915/intel_display.c 2011-07-21 20:17:23.000000000 -0600
+++ linux-3.0-lvds//drivers/gpu/drm/i915/intel_display.c 2011-07-23 19:15:35.153669618 -0600
@@ -354,6 +354,17 @@ static const intel_limit_t intel_limits_
.find_pll = intel_find_pll_ironlake_dp,
};
+static bool intel_lvds_is_dual_channel_mode(struct drm_i915_private *dev_priv,
+ int lvds_reg)
+{
+ /* Did the user specify the number of channels? */
+ if (i915_lvds_channels)
+ return i915_lvds_channels == 2;
+
+ /* No, let's probe the current status of the hardware instead. */
+ return (I915_READ(lvds_reg) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP;
+}
+
static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc,
int refclk)
{
@@ -362,8 +373,7 @@ static const intel_limit_t *intel_ironla
const intel_limit_t *limit;
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
- if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) ==
- LVDS_CLKB_POWER_UP) {
+ if (intel_lvds_is_dual_channel_mode(dev_priv, PCH_LVDS)) {
/* LVDS dual channel */
if (refclk == 100000)
limit = &intel_limits_ironlake_dual_lvds_100m;
@@ -391,8 +401,7 @@ static const intel_limit_t *intel_g4x_li
const intel_limit_t *limit;
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
- if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
- LVDS_CLKB_POWER_UP)
+ if (intel_lvds_is_dual_channel_mode(dev_priv, LVDS))
/* LVDS with dual channel */
limit = &intel_limits_g4x_dual_channel_lvds;
else
@@ -523,14 +532,7 @@ intel_find_best_PLL(const intel_limit_t
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
(I915_READ(LVDS)) != 0) {
- /*
- * For LVDS, if the panel is on, just rely on its current
- * settings for dual-channel. We haven't figured out how to
- * reliably set up different single/dual channel state, if we
- * even can.
- */
- if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
- LVDS_CLKB_POWER_UP)
+ if (intel_lvds_is_dual_channel_mode(dev_priv, LVDS))
clock.p2 = limit->p2.p2_fast;
else
clock.p2 = limit->p2.p2_slow;
@@ -594,8 +596,7 @@ intel_g4x_find_best_PLL(const intel_limi
lvds_reg = PCH_LVDS;
else
lvds_reg = LVDS;
- if ((I915_READ(lvds_reg) & LVDS_CLKB_POWER_MASK) ==
- LVDS_CLKB_POWER_UP)
+ if (intel_lvds_is_dual_channel_mode(dev_priv, lvds_reg))
clock.p2 = limit->p2.p2_fast;
else
clock.p2 = limit->p2.p2_slow;
@@ -4961,7 +4962,7 @@ static int ironlake_crtc_mode_set(struct
if (is_lvds) {
if ((intel_panel_use_ssc(dev_priv) &&
dev_priv->lvds_ssc_freq == 100) ||
- (I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP)
+ intel_lvds_is_dual_channel_mode(dev_priv, PCH_LVDS))
factor = 25;
} else if (is_sdvo && is_tv)
factor = 20;
Bookmarks