← Back to team overview

hybrid-graphics-linux team mailing list archive

Re: RadeonHD+IntelGMA switchable

 

On Tue, 13 Jul 2010, Andreas Demmer wrote:
On Tuesday 13 July 2010 20:42:00 you wrote:
BTW, who is doing that bios remapping during card switch? I just dumped
memory with dd from 0xc0000 and it is intel vga bios. Switched to radeon -
but memory dump shows the same intel bios.

Ah, now we're getting closer to the source of the trouble! :)


Pocking around I figured out the bios is suppied uing ATRM ACPI call in radeon kms driver. I've patched a little radeon & switcheroo to export bios to switcheroo's debugfs so I have it now. Now need to consideer what to do next %)
My patches are attached if someone interested.


BTW, Dave, I see some kind of excessive call in attempt to fetch bios:
radeon_bios.c:431:radeon_get_bios
        r = radeon_atrm_get_bios(rdev);
        if (r == false)
                r = igp_read_bios_from_vram(rdev);
        if (r == false)
                r = radeon_read_bios(rdev);
        if (r == false) {
                r = radeon_read_disabled_bios(rdev);
        }
Here igp_read_bios_from_vram is called and then radeon_read_disabled_bios, but radeon_read_disabled_bios is also calling igp_read_bios_from_vram (line 413)
        if (rdev->flags & RADEON_IS_IGP)
                return igp_read_bios_from_vram(rdev);
or it is a workaround when IGP flag isn't set?


---
 Looking forward to reading yours.
   Ruslan N. Marchenko
--- drivers/gpu/drm/radeon/radeon_bios.c.orig	2010-07-14 18:25:08.017712773 +0200
+++ drivers/gpu/drm/radeon/radeon_bios.c	2010-07-14 18:28:14.938954830 +0200
@@ -465,6 +465,7 @@
 	}
 
 	DRM_DEBUG("%sBIOS detected\n", rdev->is_atom_bios ? "ATOM" : "COM");
+	vga_switcheroo_publish_rom(rdev->bios);
 	return true;
 free_bios:
 	kfree(rdev->bios);
--- drivers/gpu/vga/vga_switcheroo.c.orig	2010-07-14 19:14:42.159588542 +0200
+++ drivers/gpu/vga/vga_switcheroo.c	2010-07-14 19:16:00.517715175 +0200
@@ -48,6 +48,7 @@
 
 	struct dentry *debugfs_root;
 	struct dentry *switch_file;
+	struct dentry *bios_file;
 
 	int registered_clients;
 	struct vga_switcheroo_client clients[VGA_SWITCHEROO_MAX_CLIENTS];
@@ -169,6 +170,26 @@
 }
 EXPORT_SYMBOL(vga_switcheroo_client_fb_set);
 
+static DEFINE_MUTEX(bios_mutex);
+char priv_bios[65536];
+void vga_switcheroo_publish_rom(char *rom)
+{
+	mutex_lock(&bios_mutex);
+	memcpy(priv_bios,rom,65536);
+	mutex_unlock(&bios_mutex);
+}
+EXPORT_SYMBOL(vga_switcheroo_publish_rom);
+static ssize_t vga_switcheroo_read_bios(struct file *file,
+			char __user * buffer, size_t count, loff_t * ppos)
+{
+	ssize_t ret;
+	mutex_lock(&bios_mutex);
+	ret = simple_read_from_buffer(buffer, count, ppos, priv_bios, 65536);
+	mutex_unlock(&bios_mutex);
+	return ret;
+}
+
+
 static int vga_switcheroo_show(struct seq_file *m, void *v)
 {
 	int i;
@@ -371,6 +392,9 @@
 	.read = seq_read,
 	.llseek = seq_lseek,
 	.release = single_release,
+}, vga_switcheroo_dbgfs_rom_fops = {
+	.owner= THIS_MODULE,
+	.read = vga_switcheroo_read_bios,
 };
 
 static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv)
@@ -379,6 +403,10 @@
 		debugfs_remove(priv->switch_file);
 		priv->switch_file = NULL;
 	}
+	if (priv->bios_file) {
+		debugfs_remove(priv->bios_file);
+		priv->bios_file = NULL;
+	}
 	if (priv->debugfs_root) {
 		debugfs_remove(priv->debugfs_root);
 		priv->debugfs_root = NULL;
@@ -403,6 +431,12 @@
 		printk(KERN_ERR "vga_switcheroo: cannot create /sys/kernel/debug/vgaswitcheroo/switch\n");
 		goto fail;
 	}
+	priv->bios_file = debugfs_create_file("bios", 0400,
+						priv->debugfs_root, NULL, &vga_switcheroo_dbgfs_rom_fops);
+	if (!priv->switch_file) {
+		printk(KERN_ERR "vga_switcheroo: cannot create /sys/kernel/debug/vgaswitcheroo/bios\n");
+		goto fail;
+	}
 	return 0;
 fail:
 	vga_switcheroo_debugfs_fini(priv);
--- include/linux/vga_switcheroo.h.orig	2010-07-14 19:17:20.727802755 +0200
+++ include/linux/vga_switcheroo.h	2010-07-14 19:19:28.587762711 +0200
@@ -40,6 +40,7 @@
 
 int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler);
 void vga_switcheroo_unregister_handler(void);
+void vga_switcheroo_publish_rom(char *rom);
 
 int vga_switcheroo_process_delayed_switch(void);
 
@@ -52,6 +53,7 @@
 static inline void vga_switcheroo_client_fb_set(struct pci_dev *dev, struct fb_info *info) {}
 static inline int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) { return 0; }
 static inline void vga_switcheroo_unregister_handler(void) {}
+static inline void vga_switcheroo_publish_rom(char *rom) {}
 static inline int vga_switcheroo_process_delayed_switch(void) { return 0; }
 
 #endif

Follow ups

References