diff options
16 files changed, 3089 insertions, 68 deletions
| diff --git a/target/linux/ps3/patches-2.6.28/0001-powerpc-ps3-Fix-memory-leak-in-device-init.patch b/target/linux/ps3/patches-2.6.28/0001-powerpc-ps3-Fix-memory-leak-in-device-init.patch new file mode 100644 index 000000000..624be88c3 --- /dev/null +++ b/target/linux/ps3/patches-2.6.28/0001-powerpc-ps3-Fix-memory-leak-in-device-init.patch @@ -0,0 +1,82 @@ +From d4ad304841a9790d4fa35e51d6aa9baeba631559 Mon Sep 17 00:00:00 2001 +From: Masakazu Mokuno <mokuno@sm.sony.co.jp> +Date: Thu, 30 Oct 2008 08:17:18 +0000 +Subject: [PATCH] powerpc/ps3: Fix memory leak in device init + +Free dynamically allocated device data structures when device registration +fails.  This fixes memory leakage when the registration fails. + +Signed-off-by: Masakazu Mokuno <mokuno@sm.sony.co.jp> +Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> +Signed-off-by: Paul Mackerras <paulus@samba.org> +--- + arch/powerpc/platforms/ps3/device-init.c |   29 ++++++++++++++++++++++++----- + 1 files changed, 24 insertions(+), 5 deletions(-) + +diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c +index ffdd8e9..43816da 100644 +--- a/arch/powerpc/platforms/ps3/device-init.c ++++ b/arch/powerpc/platforms/ps3/device-init.c +@@ -314,11 +314,17 @@ static int __init ps3_setup_vuart_device(enum ps3_match_id match_id, +  + 	result = ps3_system_bus_device_register(&p->dev); +  +-	if (result) ++	if (result) { + 		pr_debug("%s:%d ps3_system_bus_device_register failed\n", + 			__func__, __LINE__); +- ++		goto fail_device_register; ++	} + 	pr_debug(" <- %s:%d\n", __func__, __LINE__); ++	return 0; ++ ++fail_device_register: ++	kfree(p); ++	pr_debug(" <- %s:%d fail\n", __func__, __LINE__); + 	return result; + } +  +@@ -463,11 +469,17 @@ static int __init ps3_register_sound_devices(void) +  + 	result = ps3_system_bus_device_register(&p->dev); +  +-	if (result) ++	if (result) { + 		pr_debug("%s:%d ps3_system_bus_device_register failed\n", + 			__func__, __LINE__); +- ++		goto fail_device_register; ++	} + 	pr_debug(" <- %s:%d\n", __func__, __LINE__); ++	return 0; ++ ++fail_device_register: ++	kfree(p); ++	pr_debug(" <- %s:%d failed\n", __func__, __LINE__); + 	return result; + } +  +@@ -491,11 +503,18 @@ static int __init ps3_register_graphics_devices(void) +  + 	result = ps3_system_bus_device_register(&p->dev); +  +-	if (result) ++	if (result) { + 		pr_debug("%s:%d ps3_system_bus_device_register failed\n", + 			__func__, __LINE__); ++		goto fail_device_register; ++	} +  + 	pr_debug(" <- %s:%d\n", __func__, __LINE__); ++	return 0; ++ ++fail_device_register: ++	kfree(p); ++	pr_debug(" <- %s:%d failed\n", __func__, __LINE__); + 	return result; + } +  +--  +1.6.0.4 + diff --git a/target/linux/ps3/patches-2.6.28/0002-powerpc-ps3-Replace-the-flip_ctl-logic-in-ps3av-and.patch b/target/linux/ps3/patches-2.6.28/0002-powerpc-ps3-Replace-the-flip_ctl-logic-in-ps3av-and.patch index 40cf93dac..bef448ff4 100644 --- a/target/linux/ps3/patches-2.6.28/0002-powerpc-ps3-Replace-the-flip_ctl-logic-in-ps3av-and.patch +++ b/target/linux/ps3/patches-2.6.28/0002-powerpc-ps3-Replace-the-flip_ctl-logic-in-ps3av-and.patch @@ -1,7 +1,7 @@  From 9b82f3e61758ed897200f0244b63a77c1791bcba Mon Sep 17 00:00:00 2001  From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>  Date: Thu, 30 Oct 2008 08:12:58 +0000 -Subject: powerpc/ps3: Replace the flip_ctl logic in ps3av and ps3fb by a mutex +Subject: [PATCH] powerpc/ps3: Replace the flip_ctl logic in ps3av and ps3fb by a mutex  Introduce ps3_gpu_mutex to synchronizes GPU-related operations, like:    - invoking the L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT command using the diff --git a/target/linux/ps3/patches-2.6.28/0003-powerpc-ps3-Quiet-dmesg-output.patch b/target/linux/ps3/patches-2.6.28/0003-powerpc-ps3-Quiet-dmesg-output.patch new file mode 100644 index 000000000..e1dac390d --- /dev/null +++ b/target/linux/ps3/patches-2.6.28/0003-powerpc-ps3-Quiet-dmesg-output.patch @@ -0,0 +1,30 @@ +From 62d80749addc969803a173573889f9b01d2459e1 Mon Sep 17 00:00:00 2001 +From: Geoff Levand <geoffrey.levand@am.sony.com> +Date: Wed, 3 Dec 2008 13:52:15 +0000 +Subject: [PATCH] powerpc/ps3: Quiet dmesg output + +Change the debug message in dma_sb_region_create() from +pr_info() to DBG() to quiet the dmesg output. + +Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> +Signed-off-by: Paul Mackerras <paulus@samba.org> +--- + arch/powerpc/platforms/ps3/mm.c |    2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c +index 3a58ffa..a4d49dd 100644 +--- a/arch/powerpc/platforms/ps3/mm.c ++++ b/arch/powerpc/platforms/ps3/mm.c +@@ -649,7 +649,7 @@ static int dma_sb_region_create(struct ps3_dma_region *r) + { + 	int result; +  +-	pr_info(" -> %s:%d:\n", __func__, __LINE__); ++	DBG(" -> %s:%d:\n", __func__, __LINE__); +  + 	BUG_ON(!r); +  +--  +1.6.0.4 + diff --git a/target/linux/ps3/patches-2.6.28/0003-powerpc-ps3-Add-sub-match-id-modalias-support.patch b/target/linux/ps3/patches-2.6.28/0004-powerpc-ps3-Add-sub-match-id-modalias-support.patch index 5f42184cf..80446272c 100644 --- a/target/linux/ps3/patches-2.6.28/0003-powerpc-ps3-Add-sub-match-id-modalias-support.patch +++ b/target/linux/ps3/patches-2.6.28/0004-powerpc-ps3-Add-sub-match-id-modalias-support.patch @@ -1,7 +1,7 @@  From 46d01492b2c50791b9b66f9b9154ac8d25acaeb9 Mon Sep 17 00:00:00 2001  From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>  Date: Wed, 3 Dec 2008 13:52:21 +0000 -Subject: powerpc/ps3: Add sub-match id modalias support +Subject: [PATCH] powerpc/ps3: Add sub-match id modalias support  commit 059e4938f8b060b10c4352e6c45739473bc73267 ("powerpc/ps3: Add a sub-match  id to ps3_system_bus") forgot to update the module alias support: diff --git a/target/linux/ps3/patches-2.6.28/0005-mtd-ps3vram-Add-ps3vram-driver-for-accessing-video.patch b/target/linux/ps3/patches-2.6.28/0005-mtd-ps3vram-Add-ps3vram-driver-for-accessing-video.patch deleted file mode 100644 index 3c5efa618..000000000 --- a/target/linux/ps3/patches-2.6.28/0005-mtd-ps3vram-Add-ps3vram-driver-for-accessing-video.patch +++ /dev/null @@ -1,29 +0,0 @@ -From cffb4add03b1fc83026b06dc3664279cfbf70155 Mon Sep 17 00:00:00 2001 -From: Jim Paris <jim@jtan.com> -Date: Tue, 6 Jan 2009 11:32:10 +0000 -Subject: [PATCH] mtd/ps3vram: Add ps3vram driver for accessing video RAM as MTD - -Add ps3vram driver, which exposes unused video RAM on the PS3 as a MTD -device suitable for storage or swap.  Fast data transfer is achieved -using a local cache in system RAM and DMA transfers via the GPU. - -Signed-off-by: Vivien Chappelier <vivien.chappelier@free.fr> -Signed-off-by: Jim Paris <jim@jtan.com> -Acked-by: Geoff Levand <geoffrey.levand@am.sony.com> -Acked-by: David Woodhouse <David.Woodhouse@intel.com> -Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> ---- - arch/powerpc/include/asm/ps3.h           |    1 + - -diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h -index cff30c0..66b6505 100644 ---- a/arch/powerpc/include/asm/ps3.h -+++ b/arch/powerpc/include/asm/ps3.h -@@ -320,6 +320,7 @@ enum ps3_match_id { -  - enum ps3_match_sub_id { - 	PS3_MATCH_SUB_ID_GPU_FB		= 1, -+	PS3_MATCH_SUB_ID_GPU_RAMDISK	= 2, - }; -  - #define PS3_MODULE_ALIAS_EHCI		"ps3:1:0" diff --git a/target/linux/ps3/patches-2.6.28/0005-powerpc-struct-device-replace-bus_id-with-dev_nam.patch b/target/linux/ps3/patches-2.6.28/0005-powerpc-struct-device-replace-bus_id-with-dev_nam.patch new file mode 100644 index 000000000..82af1a303 --- /dev/null +++ b/target/linux/ps3/patches-2.6.28/0005-powerpc-struct-device-replace-bus_id-with-dev_nam.patch @@ -0,0 +1,237 @@ +From aab0d375e01d8c16e7e5b9bd915dfaa0a815418f Mon Sep 17 00:00:00 2001 +From: Kay Sievers <kay.sievers@vrfy.org> +Date: Thu, 4 Dec 2008 10:02:56 -0800 +Subject: [PATCH] powerpc: struct device - replace bus_id with dev_name(), dev_set_name() + +Acked-by: Geoff Levand <geoffrey.levand@am.sony.com> +Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +Signed-off-by: Paul Mackerras <paulus@samba.org> +--- + arch/powerpc/kernel/ibmebus.c             |    2 +- + arch/powerpc/kernel/of_device.c           |   18 +++++++----------- + arch/powerpc/kernel/vio.c                 |   12 ++++++------ + arch/powerpc/platforms/85xx/mpc85xx_mds.c |    6 +++--- + arch/powerpc/platforms/ps3/system-bus.c   |   28 ++++++++++++---------------- + 5 files changed, 29 insertions(+), 37 deletions(-) + +diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c +index 7c65377..6e3f624 100644 +--- a/arch/powerpc/kernel/ibmebus.c ++++ b/arch/powerpc/kernel/ibmebus.c +@@ -47,7 +47,7 @@ + #include <asm/abs_addr.h> +  + static struct device ibmebus_bus_device = { /* fake "parent" device */ +-	.bus_id = "ibmebus", ++	.init_name = "ibmebus", + }; +  + struct bus_type ibmebus_bus_type; +diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c +index f3c9cae..fa983a5 100644 +--- a/arch/powerpc/kernel/of_device.c ++++ b/arch/powerpc/kernel/of_device.c +@@ -14,7 +14,6 @@ static void of_device_make_bus_id(struct of_device *dev) + { + 	static atomic_t bus_no_reg_magic; + 	struct device_node *node = dev->node; +-	char *name = dev->dev.bus_id; + 	const u32 *reg; + 	u64 addr; + 	int magic; +@@ -27,14 +26,12 @@ static void of_device_make_bus_id(struct of_device *dev) + 	reg = of_get_property(node, "dcr-reg", NULL); + 	if (reg) { + #ifdef CONFIG_PPC_DCR_NATIVE +-		snprintf(name, BUS_ID_SIZE, "d%x.%s", +-			 *reg, node->name); ++		dev_set_name(&dev->dev, "d%x.%s", *reg, node->name); + #else /* CONFIG_PPC_DCR_NATIVE */ + 		addr = of_translate_dcr_address(node, *reg, NULL); + 		if (addr != OF_BAD_ADDR) { +-			snprintf(name, BUS_ID_SIZE, +-				 "D%llx.%s", (unsigned long long)addr, +-				 node->name); ++			dev_set_name(&dev->dev, "D%llx.%s", ++				     (unsigned long long)addr, node->name); + 			return; + 		} + #endif /* !CONFIG_PPC_DCR_NATIVE */ +@@ -48,9 +45,8 @@ static void of_device_make_bus_id(struct of_device *dev) + 	if (reg) { + 		addr = of_translate_address(node, reg); + 		if (addr != OF_BAD_ADDR) { +-			snprintf(name, BUS_ID_SIZE, +-				 "%llx.%s", (unsigned long long)addr, +-				 node->name); ++			dev_set_name(&dev->dev, "%llx.%s", ++				     (unsigned long long)addr, node->name); + 			return; + 		} + 	} +@@ -60,7 +56,7 @@ static void of_device_make_bus_id(struct of_device *dev) + 	 * counter (and pray...) + 	 */ + 	magic = atomic_add_return(1, &bus_no_reg_magic); +-	snprintf(name, BUS_ID_SIZE, "%s.%d", node->name, magic - 1); ++	dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1); + } +  + struct of_device *of_device_alloc(struct device_node *np, +@@ -80,7 +76,7 @@ struct of_device *of_device_alloc(struct device_node *np, + 	dev->dev.archdata.of_node = np; +  + 	if (bus_id) +-		strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); ++		dev_set_name(&dev->dev, bus_id); + 	else + 		of_device_make_bus_id(dev); +  +diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c +index a11e6bc..94aa7b0 100644 +--- a/arch/powerpc/kernel/vio.c ++++ b/arch/powerpc/kernel/vio.c +@@ -41,9 +41,9 @@ + static struct bus_type vio_bus_type; +  + static struct vio_dev vio_bus_device  = { /* fake "parent" device */ +-	.name = vio_bus_device.dev.bus_id, ++	.name = "vio", + 	.type = "", +-	.dev.bus_id = "vio", ++	.dev.init_name = "vio", + 	.dev.bus = &vio_bus_type, + }; +  +@@ -1216,7 +1216,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) +  + 	viodev->irq = irq_of_parse_and_map(of_node, 0); +  +-	snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address); ++	dev_set_name(&viodev->dev, "%x", *unit_address); + 	viodev->name = of_node->name; + 	viodev->type = of_node->type; + 	viodev->unit_address = *unit_address; +@@ -1243,7 +1243,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) + 	/* register with generic device framework */ + 	if (device_register(&viodev->dev)) { + 		printk(KERN_ERR "%s: failed to register device %s\n", +-				__func__, viodev->dev.bus_id); ++				__func__, dev_name(&viodev->dev)); + 		/* XXX free TCE table */ + 		kfree(viodev); + 		return NULL; +@@ -1400,13 +1400,13 @@ static struct vio_dev *vio_find_name(const char *name) + struct vio_dev *vio_find_node(struct device_node *vnode) + { + 	const uint32_t *unit_address; +-	char kobj_name[BUS_ID_SIZE]; ++	char kobj_name[20]; +  + 	/* construct the kobject name from the device node */ + 	unit_address = of_get_property(vnode, "reg", NULL); + 	if (!unit_address) + 		return NULL; +-	snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address); ++	snprintf(kobj_name, sizeof(kobj_name), "%x", *unit_address); +  + 	return vio_find_name(kobj_name); + } +diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c +index d3da1e6..ee0d229 100644 +--- a/arch/powerpc/platforms/ps3/system-bus.c ++++ b/arch/powerpc/platforms/ps3/system-bus.c +@@ -31,7 +31,7 @@ + #include "platform.h" +  + static struct device ps3_system_bus = { +-	.bus_id = "ps3_system", ++	.init_name = "ps3_system", + }; +  + /* FIXME: need device usage counters! */ +@@ -356,12 +356,12 @@ static int ps3_system_bus_match(struct device *_dev, + 	if (result) + 		pr_info("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): match\n", + 			__func__, __LINE__, +-			dev->match_id, dev->match_sub_id, dev->core.bus_id, ++			dev->match_id, dev->match_sub_id, dev_name(&dev->core), + 			drv->match_id, drv->match_sub_id, drv->core.name); + 	else + 		pr_debug("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): miss\n", + 			__func__, __LINE__, +-			dev->match_id, dev->match_sub_id, dev->core.bus_id, ++			dev->match_id, dev->match_sub_id, dev_name(&dev->core), + 			drv->match_id, drv->match_sub_id, drv->core.name); +  + 	return result; +@@ -383,9 +383,9 @@ static int ps3_system_bus_probe(struct device *_dev) + 		result = drv->probe(dev); + 	else + 		pr_debug("%s:%d: %s no probe method\n", __func__, __LINE__, +-			dev->core.bus_id); ++			dev_name(&dev->core)); +  +-	pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id); ++	pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core)); + 	return result; + } +  +@@ -407,7 +407,7 @@ static int ps3_system_bus_remove(struct device *_dev) + 		dev_dbg(&dev->core, "%s:%d %s: no remove method\n", + 			__func__, __LINE__, drv->core.name); +  +-	pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id); ++	pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core)); + 	return result; + } +  +@@ -432,7 +432,7 @@ static void ps3_system_bus_shutdown(struct device *_dev) + 	BUG_ON(!drv); +  + 	dev_dbg(&dev->core, "%s:%d: %s -> %s\n", __func__, __LINE__, +-		dev->core.bus_id, drv->core.name); ++		dev_name(&dev->core), drv->core.name); +  + 	if (drv->shutdown) + 		drv->shutdown(dev); +@@ -744,22 +744,18 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) + 	switch (dev->dev_type) { + 	case PS3_DEVICE_TYPE_IOC0: + 		dev->core.archdata.dma_ops = &ps3_ioc0_dma_ops; +-		snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), +-			"ioc0_%02x", ++dev_ioc0_count); ++		dev_set_name(&dev->core, "ioc0_%02x", ++dev_ioc0_count); + 		break; + 	case PS3_DEVICE_TYPE_SB: + 		dev->core.archdata.dma_ops = &ps3_sb_dma_ops; +-		snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), +-			"sb_%02x", ++dev_sb_count); ++		dev_set_name(&dev->core, "sb_%02x", ++dev_sb_count); +  + 		break; + 	case PS3_DEVICE_TYPE_VUART: +-		snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), +-			"vuart_%02x", ++dev_vuart_count); ++		dev_set_name(&dev->core, "vuart_%02x", ++dev_vuart_count); + 		break; + 	case PS3_DEVICE_TYPE_LPM: +-		snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), +-			"lpm_%02x", ++dev_lpm_count); ++		dev_set_name(&dev->core, "lpm_%02x", ++dev_lpm_count); + 		break; + 	default: + 		BUG(); +@@ -768,7 +764,7 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) + 	dev->core.archdata.of_node = NULL; + 	set_dev_node(&dev->core, 0); +  +-	pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id); ++	pr_debug("%s:%d add %s\n", __func__, __LINE__, dev_name(&dev->core)); +  + 	result = device_register(&dev->core); + 	return result; +--  +1.6.0.4 + diff --git a/target/linux/ps3/patches-2.6.28/0006-powerpc-Remove-default-kexec-crash_kernel-ops-assig.patch b/target/linux/ps3/patches-2.6.28/0006-powerpc-Remove-default-kexec-crash_kernel-ops-assig.patch new file mode 100644 index 000000000..5b76c85a7 --- /dev/null +++ b/target/linux/ps3/patches-2.6.28/0006-powerpc-Remove-default-kexec-crash_kernel-ops-assig.patch @@ -0,0 +1,187 @@ +From 5be8554875bf3a1a42b7f04d5999b36e7c2fa88b Mon Sep 17 00:00:00 2001 +From: Anton Vorontsov <avorontsov@ru.mvista.com> +Date: Tue, 16 Dec 2008 06:23:08 +0000 +Subject: [PATCH] powerpc: Remove default kexec/crash_kernel ops assignments + +Default ops are implicit now. + +Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> +Signed-off-by: Paul Mackerras <paulus@samba.org> +--- + arch/powerpc/platforms/cell/celleb_setup.c     |    9 --------- + arch/powerpc/platforms/cell/setup.c            |    6 ------ + arch/powerpc/platforms/embedded6xx/c2k.c       |    6 ------ + arch/powerpc/platforms/embedded6xx/prpmc2800.c |    6 ------ + arch/powerpc/platforms/maple/setup.c           |    6 ------ + arch/powerpc/platforms/powermac/setup.c        |    6 ------ + arch/powerpc/platforms/ps3/setup.c             |    4 ---- + 7 files changed, 0 insertions(+), 43 deletions(-) + +diff --git a/arch/powerpc/platforms/cell/celleb_setup.c b/arch/powerpc/platforms/cell/celleb_setup.c +index b11cb30..07c234f 100644 +--- a/arch/powerpc/platforms/cell/celleb_setup.c ++++ b/arch/powerpc/platforms/cell/celleb_setup.c +@@ -45,7 +45,6 @@ + #include <asm/mmu.h> + #include <asm/processor.h> + #include <asm/io.h> +-#include <asm/kexec.h> + #include <asm/prom.h> + #include <asm/machdep.h> + #include <asm/cputable.h> +@@ -226,9 +225,6 @@ define_machine(celleb_beat) { + 	.pci_setup_phb		= celleb_setup_phb, + #ifdef CONFIG_KEXEC + 	.kexec_cpu_down		= beat_kexec_cpu_down, +-	.machine_kexec		= default_machine_kexec, +-	.machine_kexec_prepare	= default_machine_kexec_prepare, +-	.machine_crash_shutdown	= default_machine_crash_shutdown, + #endif + }; +  +@@ -248,9 +244,4 @@ define_machine(celleb_native) { + 	.pci_probe_mode 	= celleb_pci_probe_mode, + 	.pci_setup_phb		= celleb_setup_phb, + 	.init_IRQ		= celleb_init_IRQ_native, +-#ifdef CONFIG_KEXEC +-	.machine_kexec		= default_machine_kexec, +-	.machine_kexec_prepare	= default_machine_kexec_prepare, +-	.machine_crash_shutdown	= default_machine_crash_shutdown, +-#endif + }; +diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c +index ab721b5..5930536 100644 +--- a/arch/powerpc/platforms/cell/setup.c ++++ b/arch/powerpc/platforms/cell/setup.c +@@ -35,7 +35,6 @@ + #include <asm/mmu.h> + #include <asm/processor.h> + #include <asm/io.h> +-#include <asm/kexec.h> + #include <asm/pgtable.h> + #include <asm/prom.h> + #include <asm/rtas.h> +@@ -289,9 +288,4 @@ define_machine(cell) { + 	.progress		= cell_progress, + 	.init_IRQ       	= cell_init_irq, + 	.pci_setup_phb		= cell_setup_phb, +-#ifdef CONFIG_KEXEC +-	.machine_kexec		= default_machine_kexec, +-	.machine_kexec_prepare	= default_machine_kexec_prepare, +-	.machine_crash_shutdown	= default_machine_crash_shutdown, +-#endif + }; +diff --git a/arch/powerpc/platforms/embedded6xx/c2k.c b/arch/powerpc/platforms/embedded6xx/c2k.c +index 32ba0fa..8cab573 100644 +--- a/arch/powerpc/platforms/embedded6xx/c2k.c ++++ b/arch/powerpc/platforms/embedded6xx/c2k.c +@@ -20,7 +20,6 @@ + #include <linux/seq_file.h> + #include <linux/time.h> + #include <linux/of.h> +-#include <linux/kexec.h> +  + #include <asm/machdep.h> + #include <asm/prom.h> +@@ -147,9 +146,4 @@ define_machine(c2k) { + 	.get_irq		= mv64x60_get_irq, + 	.restart		= c2k_restart, + 	.calibrate_decr		= generic_calibrate_decr, +-#ifdef CONFIG_KEXEC +-	.machine_kexec		= default_machine_kexec, +-	.machine_kexec_prepare	= default_machine_kexec_prepare, +-	.machine_crash_shutdown	= default_machine_crash_shutdown, +-#endif + }; +diff --git a/arch/powerpc/platforms/embedded6xx/prpmc2800.c b/arch/powerpc/platforms/embedded6xx/prpmc2800.c +index 4c485e9..670035f 100644 +--- a/arch/powerpc/platforms/embedded6xx/prpmc2800.c ++++ b/arch/powerpc/platforms/embedded6xx/prpmc2800.c +@@ -19,7 +19,6 @@ + #include <asm/prom.h> + #include <asm/system.h> + #include <asm/time.h> +-#include <asm/kexec.h> +  + #include <mm/mmu_decl.h> +  +@@ -155,9 +154,4 @@ define_machine(prpmc2800){ + 	.get_irq		= mv64x60_get_irq, + 	.restart		= prpmc2800_restart, + 	.calibrate_decr		= generic_calibrate_decr, +-#ifdef CONFIG_KEXEC +-	.machine_kexec		= default_machine_kexec, +-	.machine_kexec_prepare	= default_machine_kexec_prepare, +-	.machine_crash_shutdown	= default_machine_crash_shutdown, +-#endif + }; +diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c +index d4c61c3..bfd60e4 100644 +--- a/arch/powerpc/platforms/maple/setup.c ++++ b/arch/powerpc/platforms/maple/setup.c +@@ -50,7 +50,6 @@ + #include <asm/system.h> + #include <asm/pgtable.h> + #include <asm/io.h> +-#include <asm/kexec.h> + #include <asm/pci-bridge.h> + #include <asm/iommu.h> + #include <asm/machdep.h> +@@ -335,9 +334,4 @@ define_machine(maple) { +       	.calibrate_decr		= generic_calibrate_decr, + 	.progress		= maple_progress, + 	.power_save		= power4_idle, +-#ifdef CONFIG_KEXEC +-	.machine_kexec		= default_machine_kexec, +-	.machine_kexec_prepare	= default_machine_kexec_prepare, +-	.machine_crash_shutdown	= default_machine_crash_shutdown, +-#endif + }; +diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c +index 1293772..9b78f53 100644 +--- a/arch/powerpc/platforms/powermac/setup.c ++++ b/arch/powerpc/platforms/powermac/setup.c +@@ -60,7 +60,6 @@ + #include <asm/system.h> + #include <asm/pgtable.h> + #include <asm/io.h> +-#include <asm/kexec.h> + #include <asm/pci-bridge.h> + #include <asm/ohare.h> + #include <asm/mediabay.h> +@@ -738,11 +737,6 @@ define_machine(powermac) { + 	.pci_probe_mode		= pmac_pci_probe_mode, + 	.power_save		= power4_idle, + 	.enable_pmcs		= power4_enable_pmcs, +-#ifdef CONFIG_KEXEC +-	.machine_kexec		= default_machine_kexec, +-	.machine_kexec_prepare	= default_machine_kexec_prepare, +-	.machine_crash_shutdown	= default_machine_crash_shutdown, +-#endif + #endif /* CONFIG_PPC64 */ + #ifdef CONFIG_PPC32 + 	.pcibios_enable_device_hook = pmac_pci_enable_device_hook, +diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c +index bfc33fb..35f3e85 100644 +--- a/arch/powerpc/platforms/ps3/setup.c ++++ b/arch/powerpc/platforms/ps3/setup.c +@@ -23,7 +23,6 @@ + #include <linux/fs.h> + #include <linux/root_dev.h> + #include <linux/console.h> +-#include <linux/kexec.h> + #include <linux/bootmem.h> +  + #include <asm/machdep.h> +@@ -281,8 +280,5 @@ define_machine(ps3) { + 	.halt				= ps3_halt, + #if defined(CONFIG_KEXEC) + 	.kexec_cpu_down			= ps3_kexec_cpu_down, +-	.machine_kexec			= default_machine_kexec, +-	.machine_kexec_prepare		= default_machine_kexec_prepare, +-	.machine_crash_shutdown		= default_machine_crash_shutdown, + #endif + }; +--  +1.6.0.4 + diff --git a/target/linux/ps3/patches-2.6.28/0007-mtd-ps3vram-Add-ps3vram-driver-for-accessing-video.patch b/target/linux/ps3/patches-2.6.28/0007-mtd-ps3vram-Add-ps3vram-driver-for-accessing-video.patch new file mode 100644 index 000000000..9278afe5c --- /dev/null +++ b/target/linux/ps3/patches-2.6.28/0007-mtd-ps3vram-Add-ps3vram-driver-for-accessing-video.patch @@ -0,0 +1,920 @@ +From cffb4add03b1fc83026b06dc3664279cfbf70155 Mon Sep 17 00:00:00 2001 +From: Jim Paris <jim@jtan.com> +Date: Tue, 6 Jan 2009 11:32:10 +0000 +Subject: [PATCH] mtd/ps3vram: Add ps3vram driver for accessing video RAM as MTD + +Add ps3vram driver, which exposes unused video RAM on the PS3 as a MTD +device suitable for storage or swap.  Fast data transfer is achieved +using a local cache in system RAM and DMA transfers via the GPU. + +Signed-off-by: Vivien Chappelier <vivien.chappelier@free.fr> +Signed-off-by: Jim Paris <jim@jtan.com> +Acked-by: Geoff Levand <geoffrey.levand@am.sony.com> +Acked-by: David Woodhouse <David.Woodhouse@intel.com> +Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> +--- + MAINTAINERS                              |    6 + + arch/powerpc/include/asm/ps3.h           |    1 + + arch/powerpc/platforms/ps3/device-init.c |   37 ++ + drivers/mtd/devices/Kconfig              |    7 + + drivers/mtd/devices/Makefile             |    1 + + drivers/mtd/devices/ps3vram.c            |  776 ++++++++++++++++++++++++++++++ + 6 files changed, 828 insertions(+), 0 deletions(-) + create mode 100644 drivers/mtd/devices/ps3vram.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index a018844..246878f 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -3484,6 +3484,12 @@ L:	linuxppc-dev@ozlabs.org + L:	cbe-oss-dev@ozlabs.org + S:	Supported +  ++PS3VRAM DRIVER ++P:	Jim Paris ++M:	jim@jtan.com ++L:	cbe-oss-dev@ozlabs.org ++S:	Maintained ++ + PVRUSB2 VIDEO4LINUX DRIVER + P:	Mike Isely + M:	isely@pobox.com +diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h +index cff30c0..66b6505 100644 +--- a/arch/powerpc/include/asm/ps3.h ++++ b/arch/powerpc/include/asm/ps3.h +@@ -320,6 +320,7 @@ enum ps3_match_id { +  + enum ps3_match_sub_id { + 	PS3_MATCH_SUB_ID_GPU_FB		= 1, ++	PS3_MATCH_SUB_ID_GPU_RAMDISK	= 2, + }; +  + #define PS3_MODULE_ALIAS_EHCI		"ps3:1:0" +diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c +index dbc124e..ca71a12 100644 +--- a/arch/powerpc/platforms/ps3/device-init.c ++++ b/arch/powerpc/platforms/ps3/device-init.c +@@ -518,6 +518,41 @@ fail_device_register: + 	return result; + } +  ++static int __init ps3_register_ramdisk_device(void) ++{ ++	int result; ++	struct layout { ++		struct ps3_system_bus_device dev; ++	} *p; ++ ++	pr_debug(" -> %s:%d\n", __func__, __LINE__); ++ ++	p = kzalloc(sizeof(struct layout), GFP_KERNEL); ++ ++	if (!p) ++		return -ENOMEM; ++ ++	p->dev.match_id = PS3_MATCH_ID_GPU; ++	p->dev.match_sub_id = PS3_MATCH_SUB_ID_GPU_RAMDISK; ++	p->dev.dev_type = PS3_DEVICE_TYPE_IOC0; ++ ++	result = ps3_system_bus_device_register(&p->dev); ++ ++	if (result) { ++		pr_debug("%s:%d ps3_system_bus_device_register failed\n", ++			__func__, __LINE__); ++		goto fail_device_register; ++	} ++ ++	pr_debug(" <- %s:%d\n", __func__, __LINE__); ++	return 0; ++ ++fail_device_register: ++	kfree(p); ++	pr_debug(" <- %s:%d failed\n", __func__, __LINE__); ++	return result; ++} ++ + /** +  * ps3_setup_dynamic_device - Setup a dynamic device from the repository +  */ +@@ -946,6 +981,8 @@ static int __init ps3_register_devices(void) +  + 	ps3_register_lpm_devices(); +  ++	ps3_register_ramdisk_device(); ++ + 	pr_debug(" <- %s:%d\n", __func__, __LINE__); + 	return 0; + } +diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig +index 6fde0a2..bc33200 100644 +--- a/drivers/mtd/devices/Kconfig ++++ b/drivers/mtd/devices/Kconfig +@@ -120,6 +120,13 @@ config MTD_PHRAM + 	  doesn't have access to, memory beyond the mem=xxx limit, nvram, + 	  memory on the video card, etc... +  ++config MTD_PS3VRAM ++	tristate "PS3 video RAM" ++	depends on FB_PS3 ++	help ++	  This driver allows you to use excess PS3 video RAM as volatile ++	  storage or system swap. ++ + config MTD_LART + 	tristate "28F160xx flash driver for LART" + 	depends on SA1100_LART +diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile +index 0993d5c..e51521d 100644 +--- a/drivers/mtd/devices/Makefile ++++ b/drivers/mtd/devices/Makefile +@@ -16,3 +16,4 @@ obj-$(CONFIG_MTD_LART)		+= lart.o + obj-$(CONFIG_MTD_BLOCK2MTD)	+= block2mtd.o + obj-$(CONFIG_MTD_DATAFLASH)	+= mtd_dataflash.o + obj-$(CONFIG_MTD_M25P80)	+= m25p80.o ++obj-$(CONFIG_MTD_PS3VRAM)	+= ps3vram.o +diff --git a/drivers/mtd/devices/ps3vram.c b/drivers/mtd/devices/ps3vram.c +new file mode 100644 +index 0000000..26a4b57 +--- /dev/null ++++ b/drivers/mtd/devices/ps3vram.c +@@ -0,0 +1,776 @@ ++/** ++ * ps3vram - Use extra PS3 video ram as MTD block device. ++ * ++ * Copyright (c) 2007-2008 Jim Paris <jim@jtan.com> ++ * Added support RSX DMA Vivien Chappelier <vivien.chappelier@free.fr> ++ */ ++ ++#include <linux/io.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/list.h> ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/slab.h> ++#include <linux/version.h> ++#include <linux/gfp.h> ++#include <linux/delay.h> ++#include <linux/mtd/mtd.h> ++ ++#include <asm/lv1call.h> ++#include <asm/ps3.h> ++ ++#define DEVICE_NAME		"ps3vram" ++ ++#define XDR_BUF_SIZE (2 * 1024 * 1024) /* XDR buffer (must be 1MiB aligned) */ ++#define XDR_IOIF 0x0c000000 ++ ++#define FIFO_BASE XDR_IOIF ++#define FIFO_SIZE (64 * 1024) ++ ++#define DMA_PAGE_SIZE (4 * 1024) ++ ++#define CACHE_PAGE_SIZE (256 * 1024) ++#define CACHE_PAGE_COUNT ((XDR_BUF_SIZE - FIFO_SIZE) / CACHE_PAGE_SIZE) ++ ++#define CACHE_OFFSET CACHE_PAGE_SIZE ++#define FIFO_OFFSET 0 ++ ++#define CTRL_PUT 0x10 ++#define CTRL_GET 0x11 ++#define CTRL_TOP 0x15 ++ ++#define UPLOAD_SUBCH	1 ++#define DOWNLOAD_SUBCH	2 ++ ++#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN	0x0000030c ++#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY	0x00000104 ++ ++#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601 ++ ++struct mtd_info ps3vram_mtd; ++ ++#define CACHE_PAGE_PRESENT 1 ++#define CACHE_PAGE_DIRTY   2 ++ ++#define dbg(fmt, args...)	\ ++	pr_debug("%s:%d " fmt "\n", __func__, __LINE__, ## args) ++ ++struct ps3vram_tag { ++	unsigned int address; ++	unsigned int flags; ++}; ++ ++struct ps3vram_cache { ++	unsigned int page_count; ++	unsigned int page_size; ++	struct ps3vram_tag *tags; ++}; ++ ++struct ps3vram_priv { ++	uint64_t memory_handle; ++	uint64_t context_handle; ++	uint8_t *base; ++	uint32_t *ctrl; ++	uint32_t *reports; ++	uint8_t *xdr_buf; ++ ++	uint32_t *fifo_base; ++	uint32_t *fifo_ptr; ++ ++	struct ps3vram_cache cache; ++ ++	/* Used to serialize cache/DMA operations */ ++	struct mutex lock; ++}; ++ ++#define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */ ++#define DMA_NOTIFIER_OFFSET_BASE 0x1000     /* first DMA notifier offset */ ++#define DMA_NOTIFIER_SIZE        0x40 ++ ++#define NUM_NOTIFIERS		16 ++ ++#define NOTIFIER 7	/* notifier used for completion report */ ++ ++/* A trailing '-' means to subtract off ps3fb_videomemory.size */ ++char *size = "256M-"; ++module_param(size, charp, 0); ++MODULE_PARM_DESC(size, "memory size"); ++ ++static inline uint32_t *ps3vram_get_notifier(uint32_t *reports, int notifier) ++{ ++	return (void *) reports + ++		DMA_NOTIFIER_OFFSET_BASE + ++		DMA_NOTIFIER_SIZE * notifier; ++} ++ ++static void ps3vram_notifier_reset(struct mtd_info *mtd) ++{ ++	int i; ++	struct ps3vram_priv *priv = mtd->priv; ++	uint32_t *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); ++	for (i = 0; i < 4; i++) ++		notify[i] = 0xffffffff; ++} ++ ++static int ps3vram_notifier_wait(struct mtd_info *mtd, int timeout_ms) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++	uint32_t *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); ++ ++	timeout_ms *= 1000; ++ ++	do { ++		if (notify[3] == 0) ++			return 0; ++ ++		if (timeout_ms) ++			udelay(1); ++	} while (timeout_ms--); ++ ++	return -1; ++} ++ ++static void ps3vram_dump_ring(struct mtd_info *mtd) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++	uint32_t *fifo; ++ ++	pr_info("PUT = %08x GET = %08x\n", priv->ctrl[CTRL_PUT], ++		priv->ctrl[CTRL_GET]); ++	for (fifo = priv->fifo_base; fifo < priv->fifo_ptr; fifo++) ++		pr_info("%p: %08x\n", fifo, *fifo); ++} ++ ++static void ps3vram_dump_reports(struct mtd_info *mtd) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++	int i; ++ ++	for (i = 0; i < NUM_NOTIFIERS; i++) { ++		uint32_t *n = ps3vram_get_notifier(priv->reports, i); ++		pr_info("%p: %08x\n", n, *n); ++	} ++} ++ ++static void ps3vram_init_ring(struct mtd_info *mtd) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++ ++	priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; ++	priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET; ++} ++ ++static int ps3vram_wait_ring(struct mtd_info *mtd, int timeout) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++ ++	/* wait until setup commands are processed */ ++	timeout *= 1000; ++	while (--timeout) { ++		if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET]) ++			break; ++		udelay(1); ++	} ++	if (timeout == 0) { ++		pr_err("FIFO timeout (%08x/%08x/%08x)\n", priv->ctrl[CTRL_PUT], ++		       priv->ctrl[CTRL_GET], priv->ctrl[CTRL_TOP]); ++		return -ETIMEDOUT; ++	} ++ ++	return 0; ++} ++ ++static inline void ps3vram_out_ring(struct ps3vram_priv *priv, uint32_t data) ++{ ++	*(priv->fifo_ptr)++ = data; ++} ++ ++static inline void ps3vram_begin_ring(struct ps3vram_priv *priv, uint32_t chan, ++				      uint32_t tag, uint32_t size) ++{ ++	ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag); ++} ++ ++static void ps3vram_rewind_ring(struct mtd_info *mtd) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++	u64 status; ++ ++	ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET)); ++ ++	priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; ++ ++	/* asking the HV for a blit will kick the fifo */ ++	status = lv1_gpu_context_attribute(priv->context_handle, ++					   L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, ++					   0, 0, 0, 0); ++	if (status) ++		pr_err("ps3vram: lv1_gpu_context_attribute FB_BLIT failed\n"); ++ ++	priv->fifo_ptr = priv->fifo_base; ++} ++ ++static void ps3vram_fire_ring(struct mtd_info *mtd) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++	u64 status; ++ ++	mutex_lock(&ps3_gpu_mutex); ++ ++	priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET + ++		(priv->fifo_ptr - priv->fifo_base) * sizeof(uint32_t); ++ ++	/* asking the HV for a blit will kick the fifo */ ++	status = lv1_gpu_context_attribute(priv->context_handle, ++					   L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, ++					   0, 0, 0, 0); ++	if (status) ++		pr_err("ps3vram: lv1_gpu_context_attribute FB_BLIT failed\n"); ++ ++	if ((priv->fifo_ptr - priv->fifo_base) * sizeof(uint32_t) > ++	    FIFO_SIZE - 1024) { ++		dbg("fifo full, rewinding"); ++		ps3vram_wait_ring(mtd, 200); ++		ps3vram_rewind_ring(mtd); ++	} ++ ++	mutex_unlock(&ps3_gpu_mutex); ++} ++ ++static void ps3vram_bind(struct mtd_info *mtd) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++ ++	ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1); ++	ps3vram_out_ring(priv, 0x31337303); ++	ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x180, 3); ++	ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER); ++	ps3vram_out_ring(priv, 0xfeed0001);	/* DMA system RAM instance */ ++	ps3vram_out_ring(priv, 0xfeed0000);     /* DMA video RAM instance */ ++ ++	ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0, 1); ++	ps3vram_out_ring(priv, 0x3137c0de); ++	ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x180, 3); ++	ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER); ++	ps3vram_out_ring(priv, 0xfeed0000);	/* DMA video RAM instance */ ++	ps3vram_out_ring(priv, 0xfeed0001);	/* DMA system RAM instance */ ++ ++	ps3vram_fire_ring(mtd); ++} ++ ++static int ps3vram_upload(struct mtd_info *mtd, unsigned int src_offset, ++			  unsigned int dst_offset, int len, int count) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++ ++	ps3vram_begin_ring(priv, UPLOAD_SUBCH, ++			   NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); ++	ps3vram_out_ring(priv, XDR_IOIF + src_offset); ++	ps3vram_out_ring(priv, dst_offset); ++	ps3vram_out_ring(priv, len); ++	ps3vram_out_ring(priv, len); ++	ps3vram_out_ring(priv, len); ++	ps3vram_out_ring(priv, count); ++	ps3vram_out_ring(priv, (1 << 8) | 1); ++	ps3vram_out_ring(priv, 0); ++ ++	ps3vram_notifier_reset(mtd); ++	ps3vram_begin_ring(priv, UPLOAD_SUBCH, ++			   NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); ++	ps3vram_out_ring(priv, 0); ++	ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x100, 1); ++	ps3vram_out_ring(priv, 0); ++	ps3vram_fire_ring(mtd); ++	if (ps3vram_notifier_wait(mtd, 200) < 0) { ++		pr_err("notifier timeout\n"); ++		ps3vram_dump_ring(mtd); ++		ps3vram_dump_reports(mtd); ++		return -1; ++	} ++ ++	return 0; ++} ++ ++static int ps3vram_download(struct mtd_info *mtd, unsigned int src_offset, ++			    unsigned int dst_offset, int len, int count) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++ ++	ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, ++			   NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); ++	ps3vram_out_ring(priv, src_offset); ++	ps3vram_out_ring(priv, XDR_IOIF + dst_offset); ++	ps3vram_out_ring(priv, len); ++	ps3vram_out_ring(priv, len); ++	ps3vram_out_ring(priv, len); ++	ps3vram_out_ring(priv, count); ++	ps3vram_out_ring(priv, (1 << 8) | 1); ++	ps3vram_out_ring(priv, 0); ++ ++	ps3vram_notifier_reset(mtd); ++	ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, ++			   NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); ++	ps3vram_out_ring(priv, 0); ++	ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x100, 1); ++	ps3vram_out_ring(priv, 0); ++	ps3vram_fire_ring(mtd); ++	if (ps3vram_notifier_wait(mtd, 200) < 0) { ++		pr_err("notifier timeout\n"); ++		ps3vram_dump_ring(mtd); ++		ps3vram_dump_reports(mtd); ++		return -1; ++	} ++ ++	return 0; ++} ++ ++static void ps3vram_cache_evict(struct mtd_info *mtd, int entry) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++	struct ps3vram_cache *cache = &priv->cache; ++ ++	if (cache->tags[entry].flags & CACHE_PAGE_DIRTY) { ++		dbg("flushing %d : 0x%08x", entry, cache->tags[entry].address); ++		if (ps3vram_upload(mtd, ++				   CACHE_OFFSET + entry * cache->page_size, ++				   cache->tags[entry].address, ++				   DMA_PAGE_SIZE, ++				   cache->page_size / DMA_PAGE_SIZE) < 0) { ++			pr_err("failed to upload from 0x%x to 0x%x size 0x%x\n", ++			       entry * cache->page_size, ++			       cache->tags[entry].address, ++			       cache->page_size); ++		} ++		cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY; ++	} ++} ++ ++static void ps3vram_cache_load(struct mtd_info *mtd, int entry, ++			       unsigned int address) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++	struct ps3vram_cache *cache = &priv->cache; ++ ++	dbg("fetching %d : 0x%08x", entry, address); ++	if (ps3vram_download(mtd, ++			     address, ++			     CACHE_OFFSET + entry * cache->page_size, ++			     DMA_PAGE_SIZE, ++			     cache->page_size / DMA_PAGE_SIZE) < 0) { ++		pr_err("failed to download from 0x%x to 0x%x size 0x%x\n", ++		       address, ++		       entry * cache->page_size, ++		       cache->page_size); ++	} ++ ++	cache->tags[entry].address = address; ++	cache->tags[entry].flags |= CACHE_PAGE_PRESENT; ++} ++ ++ ++static void ps3vram_cache_flush(struct mtd_info *mtd) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++	struct ps3vram_cache *cache = &priv->cache; ++	int i; ++ ++	dbg("FLUSH"); ++	for (i = 0; i < cache->page_count; i++) { ++		ps3vram_cache_evict(mtd, i); ++		cache->tags[i].flags = 0; ++	} ++} ++ ++static unsigned int ps3vram_cache_match(struct mtd_info *mtd, loff_t address) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++	struct ps3vram_cache *cache = &priv->cache; ++	unsigned int base; ++	unsigned int offset; ++	int i; ++	static int counter; ++ ++	offset = (unsigned int) (address & (cache->page_size - 1)); ++	base = (unsigned int) (address - offset); ++ ++	/* fully associative check */ ++	for (i = 0; i < cache->page_count; i++) { ++		if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) && ++		    cache->tags[i].address == base) { ++			dbg("found entry %d : 0x%08x", ++			    i, cache->tags[i].address); ++			return i; ++		} ++	} ++ ++	/* choose a random entry */ ++	i = (jiffies + (counter++)) % cache->page_count; ++	dbg("using cache entry %d", i); ++ ++	ps3vram_cache_evict(mtd, i); ++	ps3vram_cache_load(mtd, i, base); ++ ++	return i; ++} ++ ++static int ps3vram_cache_init(struct mtd_info *mtd) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++ ++	pr_info("creating cache: %d entries, %d bytes pages\n", ++	       CACHE_PAGE_COUNT, CACHE_PAGE_SIZE); ++ ++	priv->cache.page_count = CACHE_PAGE_COUNT; ++	priv->cache.page_size = CACHE_PAGE_SIZE; ++	priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) * ++				   CACHE_PAGE_COUNT, GFP_KERNEL); ++	if (priv->cache.tags == NULL) { ++		pr_err("could not allocate cache tags\n"); ++		return -ENOMEM; ++	} ++ ++	return 0; ++} ++ ++static void ps3vram_cache_cleanup(struct mtd_info *mtd) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++ ++	ps3vram_cache_flush(mtd); ++	kfree(priv->cache.tags); ++} ++ ++static int ps3vram_erase(struct mtd_info *mtd, struct erase_info *instr) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++ ++	if (instr->addr + instr->len > mtd->size) ++		return -EINVAL; ++ ++	mutex_lock(&priv->lock); ++ ++	ps3vram_cache_flush(mtd); ++ ++	/* Set bytes to 0xFF */ ++	memset(priv->base + instr->addr, 0xFF, instr->len); ++ ++	mutex_unlock(&priv->lock); ++ ++	instr->state = MTD_ERASE_DONE; ++	mtd_erase_callback(instr); ++ ++	return 0; ++} ++ ++ ++static int ps3vram_read(struct mtd_info *mtd, loff_t from, size_t len, ++			size_t *retlen, u_char *buf) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++	unsigned int cached, count; ++ ++	dbg("from = 0x%08x len = 0x%zx", (unsigned int) from, len); ++ ++	if (from >= mtd->size) ++		return -EINVAL; ++ ++	if (len > mtd->size - from) ++		len = mtd->size - from; ++ ++	/* Copy from vram to buf */ ++	count = len; ++	while (count) { ++		unsigned int offset, avail; ++		unsigned int entry; ++ ++		offset = (unsigned int) (from & (priv->cache.page_size - 1)); ++		avail  = priv->cache.page_size - offset; ++ ++		mutex_lock(&priv->lock); ++ ++		entry = ps3vram_cache_match(mtd, from); ++		cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; ++ ++		dbg("from=%08x cached=%08x offset=%08x avail=%08x count=%08x", ++		    (unsigned)from, cached, offset, avail, count); ++ ++		if (avail > count) ++			avail = count; ++		memcpy(buf, priv->xdr_buf + cached, avail); ++ ++		mutex_unlock(&priv->lock); ++ ++		buf += avail; ++		count -= avail; ++		from += avail; ++	} ++ ++	*retlen = len; ++	return 0; ++} ++ ++static int ps3vram_write(struct mtd_info *mtd, loff_t to, size_t len, ++			 size_t *retlen, const u_char *buf) ++{ ++	struct ps3vram_priv *priv = mtd->priv; ++	unsigned int cached, count; ++ ++	if (to >= mtd->size) ++		return -EINVAL; ++ ++	if (len > mtd->size - to) ++		len = mtd->size - to; ++ ++	/* Copy from buf to vram */ ++	count = len; ++	while (count) { ++		unsigned int offset, avail; ++		unsigned int entry; ++ ++		offset = (unsigned int) (to & (priv->cache.page_size - 1)); ++		avail  = priv->cache.page_size - offset; ++ ++		mutex_lock(&priv->lock); ++ ++		entry = ps3vram_cache_match(mtd, to); ++		cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; ++ ++		dbg("to=%08x cached=%08x offset=%08x avail=%08x count=%08x", ++		    (unsigned) to, cached, offset, avail, count); ++ ++		if (avail > count) ++			avail = count; ++		memcpy(priv->xdr_buf + cached, buf, avail); ++ ++		priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY; ++ ++		mutex_unlock(&priv->lock); ++ ++		buf += avail; ++		count -= avail; ++		to += avail; ++	} ++ ++	*retlen = len; ++	return 0; ++} ++ ++static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) ++{ ++	struct ps3vram_priv *priv; ++	uint64_t status; ++	uint64_t ddr_lpar, ctrl_lpar, info_lpar, reports_lpar; ++	int64_t ddr_size; ++	uint64_t reports_size; ++	int ret = -ENOMEM; ++	char *rest; ++ ++	ret = -EIO; ++	ps3vram_mtd.priv = kzalloc(sizeof(struct ps3vram_priv), GFP_KERNEL); ++	if (!ps3vram_mtd.priv) ++		goto out; ++	priv = ps3vram_mtd.priv; ++ ++	mutex_init(&priv->lock); ++ ++	/* Allocate XDR buffer (1MiB aligned) */ ++	priv->xdr_buf = (uint8_t *) __get_free_pages(GFP_KERNEL, ++						     get_order(XDR_BUF_SIZE)); ++	if (priv->xdr_buf == NULL) { ++		pr_err("ps3vram: could not allocate XDR buffer\n"); ++		ret = -ENOMEM; ++		goto out_free_priv; ++	} ++ ++	/* Put FIFO at begginning of XDR buffer */ ++	priv->fifo_base = (uint32_t *) (priv->xdr_buf + FIFO_OFFSET); ++	priv->fifo_ptr = priv->fifo_base; ++ ++	/* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */ ++	if (ps3_open_hv_device(dev)) { ++		pr_err("ps3vram: ps3_open_hv_device failed\n"); ++		ret = -EAGAIN; ++		goto out_close_gpu; ++	} ++ ++	/* Request memory */ ++	status = -1; ++	ddr_size = memparse(size, &rest); ++	if (*rest == '-') ++		ddr_size -= ps3fb_videomemory.size; ++	ddr_size = ALIGN(ddr_size, 1024*1024); ++	if (ddr_size <= 0) { ++		printk(KERN_ERR "ps3vram: specified size is too small\n"); ++		ret = -EINVAL; ++		goto out_close_gpu; ++	} ++ ++	while (ddr_size > 0) { ++		status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0, ++						 &priv->memory_handle, ++						 &ddr_lpar); ++		if (status == 0) ++			break; ++		ddr_size -= 1024*1024; ++	} ++	if (status != 0 || ddr_size <= 0) { ++		pr_err("ps3vram: lv1_gpu_memory_allocate failed\n"); ++		ret = -ENOMEM; ++		goto out_free_xdr_buf; ++	} ++	pr_info("ps3vram: allocated %u MiB of DDR memory\n", ++		(unsigned int) (ddr_size / 1024 / 1024)); ++ ++	/* Request context */ ++	status = lv1_gpu_context_allocate(priv->memory_handle, ++					  0, ++					  &priv->context_handle, ++					  &ctrl_lpar, ++					  &info_lpar, ++					  &reports_lpar, ++					  &reports_size); ++	if (status) { ++		pr_err("ps3vram: lv1_gpu_context_allocate failed\n"); ++		ret = -ENOMEM; ++		goto out_free_memory; ++	} ++ ++	/* Map XDR buffer to RSX */ ++	status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, ++				       ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)), ++				       XDR_BUF_SIZE, 0); ++	if (status) { ++		pr_err("ps3vram: lv1_gpu_context_iomap failed\n"); ++		ret = -ENOMEM; ++		goto out_free_context; ++	} ++ ++	priv->base = ioremap(ddr_lpar, ddr_size); ++	if (!priv->base) { ++		pr_err("ps3vram: ioremap failed\n"); ++		ret = -ENOMEM; ++		goto out_free_context; ++	} ++ ++	priv->ctrl = ioremap(ctrl_lpar, 64 * 1024); ++	if (!priv->ctrl) { ++		pr_err("ps3vram: ioremap failed\n"); ++		ret = -ENOMEM; ++		goto out_unmap_vram; ++	} ++ ++	priv->reports = ioremap(reports_lpar, reports_size); ++	if (!priv->reports) { ++		pr_err("ps3vram: ioremap failed\n"); ++		ret = -ENOMEM; ++		goto out_unmap_ctrl; ++	} ++ ++	mutex_lock(&ps3_gpu_mutex); ++	ps3vram_init_ring(&ps3vram_mtd); ++	mutex_unlock(&ps3_gpu_mutex); ++ ++	ps3vram_mtd.name = "ps3vram"; ++	ps3vram_mtd.size = ddr_size; ++	ps3vram_mtd.flags = MTD_CAP_RAM; ++	ps3vram_mtd.erase = ps3vram_erase; ++	ps3vram_mtd.point = NULL; ++	ps3vram_mtd.unpoint = NULL; ++	ps3vram_mtd.read = ps3vram_read; ++	ps3vram_mtd.write = ps3vram_write; ++	ps3vram_mtd.owner = THIS_MODULE; ++	ps3vram_mtd.type = MTD_RAM; ++	ps3vram_mtd.erasesize = CACHE_PAGE_SIZE; ++	ps3vram_mtd.writesize = 1; ++ ++	ps3vram_bind(&ps3vram_mtd); ++ ++	mutex_lock(&ps3_gpu_mutex); ++	ret = ps3vram_wait_ring(&ps3vram_mtd, 100); ++	mutex_unlock(&ps3_gpu_mutex); ++	if (ret < 0) { ++		pr_err("failed to initialize channels\n"); ++		ret = -ETIMEDOUT; ++		goto out_unmap_reports; ++	} ++ ++	ps3vram_cache_init(&ps3vram_mtd); ++ ++	if (add_mtd_device(&ps3vram_mtd)) { ++		pr_err("ps3vram: failed to register device\n"); ++		ret = -EAGAIN; ++		goto out_cache_cleanup; ++	} ++ ++	pr_info("ps3vram mtd device registered, %lu bytes\n", ddr_size); ++	return 0; ++ ++out_cache_cleanup: ++	ps3vram_cache_cleanup(&ps3vram_mtd); ++out_unmap_reports: ++	iounmap(priv->reports); ++out_unmap_ctrl: ++	iounmap(priv->ctrl); ++out_unmap_vram: ++	iounmap(priv->base); ++out_free_context: ++	lv1_gpu_context_free(priv->context_handle); ++out_free_memory: ++	lv1_gpu_memory_free(priv->memory_handle); ++out_close_gpu: ++	ps3_close_hv_device(dev); ++out_free_xdr_buf: ++	free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); ++out_free_priv: ++	kfree(ps3vram_mtd.priv); ++	ps3vram_mtd.priv = NULL; ++out: ++	return ret; ++} ++ ++static int ps3vram_shutdown(struct ps3_system_bus_device *dev) ++{ ++	struct ps3vram_priv *priv; ++ ++	priv = ps3vram_mtd.priv; ++ ++	del_mtd_device(&ps3vram_mtd); ++	ps3vram_cache_cleanup(&ps3vram_mtd); ++	iounmap(priv->reports); ++	iounmap(priv->ctrl); ++	iounmap(priv->base); ++	lv1_gpu_context_free(priv->context_handle); ++	lv1_gpu_memory_free(priv->memory_handle); ++	ps3_close_hv_device(dev); ++	free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); ++	kfree(priv); ++	return 0; ++} ++ ++static struct ps3_system_bus_driver ps3vram_driver = { ++	.match_id	= PS3_MATCH_ID_GPU, ++	.match_sub_id	= PS3_MATCH_SUB_ID_GPU_RAMDISK, ++	.core.name	= DEVICE_NAME, ++	.core.owner	= THIS_MODULE, ++	.probe		= ps3vram_probe, ++	.remove		= ps3vram_shutdown, ++	.shutdown	= ps3vram_shutdown, ++}; ++ ++static int __init ps3vram_init(void) ++{ ++	return ps3_system_bus_driver_register(&ps3vram_driver); ++} ++ ++static void __exit ps3vram_exit(void) ++{ ++	ps3_system_bus_driver_unregister(&ps3vram_driver); ++} ++ ++module_init(ps3vram_init); ++module_exit(ps3vram_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Jim Paris <jim@jtan.com>"); ++MODULE_DESCRIPTION("MTD driver for PS3 video RAM"); +--  +1.6.0.4 + diff --git a/target/linux/ps3/patches-2.6.28/0006-mtd-ps3vram-Add-modalias-support-to-the-ps3vram-dri.patch b/target/linux/ps3/patches-2.6.28/0008-mtd-ps3vram-Add-modalias-support-to-the-ps3vram-dri.patch index 243c186a9..f769c9c18 100644 --- a/target/linux/ps3/patches-2.6.28/0006-mtd-ps3vram-Add-modalias-support-to-the-ps3vram-dri.patch +++ b/target/linux/ps3/patches-2.6.28/0008-mtd-ps3vram-Add-modalias-support-to-the-ps3vram-dri.patch @@ -10,6 +10,8 @@ Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>  Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>  ---   arch/powerpc/include/asm/ps3.h |    1 + + drivers/mtd/devices/ps3vram.c  |    1 + + 2 files changed, 2 insertions(+), 0 deletions(-)  diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h  index 66b6505..eead5c6 100644 @@ -23,3 +25,15 @@ index 66b6505..eead5c6 100644   #define PS3_MODULE_ALIAS_LPM		"ps3:11:0"   enum ps3_system_bus_device_type { +diff --git a/drivers/mtd/devices/ps3vram.c b/drivers/mtd/devices/ps3vram.c +index 26a4b57..22f381f 100644 +--- a/drivers/mtd/devices/ps3vram.c ++++ b/drivers/mtd/devices/ps3vram.c +@@ -774,3 +774,4 @@ module_exit(ps3vram_exit); + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Jim Paris <jim@jtan.com>"); + MODULE_DESCRIPTION("MTD driver for PS3 video RAM"); ++MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK); +--  +1.6.0.4 + diff --git a/target/linux/ps3/patches-2.6.28/0009-mtd-ps3vram-Remove-ps3vram-debug-routines.patch b/target/linux/ps3/patches-2.6.28/0009-mtd-ps3vram-Remove-ps3vram-debug-routines.patch new file mode 100644 index 000000000..7c949e653 --- /dev/null +++ b/target/linux/ps3/patches-2.6.28/0009-mtd-ps3vram-Remove-ps3vram-debug-routines.patch @@ -0,0 +1,78 @@ +From e7dd54cf17714c22665ad74b720f40fb64b3c565 Mon Sep 17 00:00:00 2001 +From: Geoff Levand <geoffrey.levand@am.sony.com> +Date: Tue, 6 Jan 2009 11:32:15 +0000 +Subject: [PATCH] mtd/ps3vram: Remove ps3vram debug routines + +Remove the ps3vram debug routines ps3vram_dump_ring() and +ps3vram_dump_reports().  These routines are not needed. + +Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> +Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> +--- + drivers/mtd/devices/ps3vram.c |   29 ----------------------------- + 1 files changed, 0 insertions(+), 29 deletions(-) + +diff --git a/drivers/mtd/devices/ps3vram.c b/drivers/mtd/devices/ps3vram.c +index 22f381f..18ca521 100644 +--- a/drivers/mtd/devices/ps3vram.c ++++ b/drivers/mtd/devices/ps3vram.c +@@ -87,9 +87,6 @@ struct ps3vram_priv { + #define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */ + #define DMA_NOTIFIER_OFFSET_BASE 0x1000     /* first DMA notifier offset */ + #define DMA_NOTIFIER_SIZE        0x40 +- +-#define NUM_NOTIFIERS		16 +- + #define NOTIFIER 7	/* notifier used for completion report */ +  + /* A trailing '-' means to subtract off ps3fb_videomemory.size */ +@@ -131,28 +128,6 @@ static int ps3vram_notifier_wait(struct mtd_info *mtd, int timeout_ms) + 	return -1; + } +  +-static void ps3vram_dump_ring(struct mtd_info *mtd) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +-	uint32_t *fifo; +- +-	pr_info("PUT = %08x GET = %08x\n", priv->ctrl[CTRL_PUT], +-		priv->ctrl[CTRL_GET]); +-	for (fifo = priv->fifo_base; fifo < priv->fifo_ptr; fifo++) +-		pr_info("%p: %08x\n", fifo, *fifo); +-} +- +-static void ps3vram_dump_reports(struct mtd_info *mtd) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +-	int i; +- +-	for (i = 0; i < NUM_NOTIFIERS; i++) { +-		uint32_t *n = ps3vram_get_notifier(priv->reports, i); +-		pr_info("%p: %08x\n", n, *n); +-	} +-} +- + static void ps3vram_init_ring(struct mtd_info *mtd) + { + 	struct ps3vram_priv *priv = mtd->priv; +@@ -284,8 +259,6 @@ static int ps3vram_upload(struct mtd_info *mtd, unsigned int src_offset, + 	ps3vram_fire_ring(mtd); + 	if (ps3vram_notifier_wait(mtd, 200) < 0) { + 		pr_err("notifier timeout\n"); +-		ps3vram_dump_ring(mtd); +-		ps3vram_dump_reports(mtd); + 		return -1; + 	} +  +@@ -317,8 +290,6 @@ static int ps3vram_download(struct mtd_info *mtd, unsigned int src_offset, + 	ps3vram_fire_ring(mtd); + 	if (ps3vram_notifier_wait(mtd, 200) < 0) { + 		pr_err("notifier timeout\n"); +-		ps3vram_dump_ring(mtd); +-		ps3vram_dump_reports(mtd); + 		return -1; + 	} +  +--  +1.6.0.4 + diff --git a/target/linux/ps3/patches-2.6.28/0010-mtd-ps3vram-Cleanup-ps3vram-driver-messages.patch b/target/linux/ps3/patches-2.6.28/0010-mtd-ps3vram-Cleanup-ps3vram-driver-messages.patch new file mode 100644 index 000000000..91eb76572 --- /dev/null +++ b/target/linux/ps3/patches-2.6.28/0010-mtd-ps3vram-Cleanup-ps3vram-driver-messages.patch @@ -0,0 +1,362 @@ +From f259d74e030faab15b95fb4bb56d7f424773c278 Mon Sep 17 00:00:00 2001 +From: Geoff Levand <geoffrey.levand@am.sony.com> +Date: Tue, 6 Jan 2009 11:32:21 +0000 +Subject: [PATCH] mtd/ps3vram: Cleanup ps3vram driver messages + +Cleanup the ps3vram driver messages.  Add a new struct device pointer +variable dev to struct ps3vram_priv and use dev_dbg(), pr_dbg(), etc. +where appropriate. + +Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> +Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> +--- + drivers/mtd/devices/ps3vram.c |  116 ++++++++++++++++++++++++----------------- + 1 files changed, 68 insertions(+), 48 deletions(-) + +diff --git a/drivers/mtd/devices/ps3vram.c b/drivers/mtd/devices/ps3vram.c +index 18ca521..f5cc290 100644 +--- a/drivers/mtd/devices/ps3vram.c ++++ b/drivers/mtd/devices/ps3vram.c +@@ -53,9 +53,6 @@ struct mtd_info ps3vram_mtd; + #define CACHE_PAGE_PRESENT 1 + #define CACHE_PAGE_DIRTY   2 +  +-#define dbg(fmt, args...)	\ +-	pr_debug("%s:%d " fmt "\n", __func__, __LINE__, ## args) +- + struct ps3vram_tag { + 	unsigned int address; + 	unsigned int flags; +@@ -78,6 +75,7 @@ struct ps3vram_priv { + 	uint32_t *fifo_base; + 	uint32_t *fifo_ptr; +  ++	struct device *dev; + 	struct ps3vram_cache cache; +  + 	/* Used to serialize cache/DMA operations */ +@@ -148,8 +146,9 @@ static int ps3vram_wait_ring(struct mtd_info *mtd, int timeout) + 		udelay(1); + 	} + 	if (timeout == 0) { +-		pr_err("FIFO timeout (%08x/%08x/%08x)\n", priv->ctrl[CTRL_PUT], +-		       priv->ctrl[CTRL_GET], priv->ctrl[CTRL_TOP]); ++		dev_dbg(priv->dev, "%s:%d: FIFO timeout (%08x/%08x/%08x)\n", ++			__func__, __LINE__, priv->ctrl[CTRL_PUT], ++			priv->ctrl[CTRL_GET], priv->ctrl[CTRL_TOP]); + 		return -ETIMEDOUT; + 	} +  +@@ -181,7 +180,8 @@ static void ps3vram_rewind_ring(struct mtd_info *mtd) + 					   L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, + 					   0, 0, 0, 0); + 	if (status) +-		pr_err("ps3vram: lv1_gpu_context_attribute FB_BLIT failed\n"); ++		dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n", ++			__func__, __LINE__); +  + 	priv->fifo_ptr = priv->fifo_base; + } +@@ -201,11 +201,13 @@ static void ps3vram_fire_ring(struct mtd_info *mtd) + 					   L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, + 					   0, 0, 0, 0); + 	if (status) +-		pr_err("ps3vram: lv1_gpu_context_attribute FB_BLIT failed\n"); ++		dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n", ++			__func__, __LINE__); +  + 	if ((priv->fifo_ptr - priv->fifo_base) * sizeof(uint32_t) > + 	    FIFO_SIZE - 1024) { +-		dbg("fifo full, rewinding"); ++		dev_dbg(priv->dev, "%s:%d: fifo full, rewinding\n", __func__, ++			__LINE__); + 		ps3vram_wait_ring(mtd, 200); + 		ps3vram_rewind_ring(mtd); + 	} +@@ -258,7 +260,8 @@ static int ps3vram_upload(struct mtd_info *mtd, unsigned int src_offset, + 	ps3vram_out_ring(priv, 0); + 	ps3vram_fire_ring(mtd); + 	if (ps3vram_notifier_wait(mtd, 200) < 0) { +-		pr_err("notifier timeout\n"); ++		dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__, ++			__LINE__); + 		return -1; + 	} +  +@@ -289,7 +292,8 @@ static int ps3vram_download(struct mtd_info *mtd, unsigned int src_offset, + 	ps3vram_out_ring(priv, 0); + 	ps3vram_fire_ring(mtd); + 	if (ps3vram_notifier_wait(mtd, 200) < 0) { +-		pr_err("notifier timeout\n"); ++		dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__, ++			__LINE__); + 		return -1; + 	} +  +@@ -302,16 +306,17 @@ static void ps3vram_cache_evict(struct mtd_info *mtd, int entry) + 	struct ps3vram_cache *cache = &priv->cache; +  + 	if (cache->tags[entry].flags & CACHE_PAGE_DIRTY) { +-		dbg("flushing %d : 0x%08x", entry, cache->tags[entry].address); ++		dev_dbg(priv->dev, "%s:%d: flushing %d : 0x%08x\n", __func__, ++			__LINE__, entry, cache->tags[entry].address); + 		if (ps3vram_upload(mtd, + 				   CACHE_OFFSET + entry * cache->page_size, + 				   cache->tags[entry].address, + 				   DMA_PAGE_SIZE, + 				   cache->page_size / DMA_PAGE_SIZE) < 0) { +-			pr_err("failed to upload from 0x%x to 0x%x size 0x%x\n", +-			       entry * cache->page_size, +-			       cache->tags[entry].address, +-			       cache->page_size); ++			dev_dbg(priv->dev, "%s:%d: failed to upload from " ++				"0x%x to 0x%x size 0x%x\n", __func__, __LINE__, ++				entry * cache->page_size, ++				cache->tags[entry].address, cache->page_size); + 		} + 		cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY; + 	} +@@ -323,16 +328,16 @@ static void ps3vram_cache_load(struct mtd_info *mtd, int entry, + 	struct ps3vram_priv *priv = mtd->priv; + 	struct ps3vram_cache *cache = &priv->cache; +  +-	dbg("fetching %d : 0x%08x", entry, address); ++	dev_dbg(priv->dev, "%s:%d: fetching %d : 0x%08x\n", __func__, __LINE__, ++		entry, address); + 	if (ps3vram_download(mtd, + 			     address, + 			     CACHE_OFFSET + entry * cache->page_size, + 			     DMA_PAGE_SIZE, + 			     cache->page_size / DMA_PAGE_SIZE) < 0) { +-		pr_err("failed to download from 0x%x to 0x%x size 0x%x\n", +-		       address, +-		       entry * cache->page_size, +-		       cache->page_size); ++		dev_err(priv->dev, "%s:%d: failed to download from " ++			"0x%x to 0x%x size 0x%x\n", __func__, __LINE__, address, ++			entry * cache->page_size, cache->page_size); + 	} +  + 	cache->tags[entry].address = address; +@@ -346,7 +351,7 @@ static void ps3vram_cache_flush(struct mtd_info *mtd) + 	struct ps3vram_cache *cache = &priv->cache; + 	int i; +  +-	dbg("FLUSH"); ++	dev_dbg(priv->dev, "%s:%d: FLUSH\n", __func__, __LINE__); + 	for (i = 0; i < cache->page_count; i++) { + 		ps3vram_cache_evict(mtd, i); + 		cache->tags[i].flags = 0; +@@ -369,15 +374,15 @@ static unsigned int ps3vram_cache_match(struct mtd_info *mtd, loff_t address) + 	for (i = 0; i < cache->page_count; i++) { + 		if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) && + 		    cache->tags[i].address == base) { +-			dbg("found entry %d : 0x%08x", +-			    i, cache->tags[i].address); ++			dev_dbg(priv->dev, "%s:%d: found entry %d : 0x%08x\n", ++				__func__, __LINE__, i, cache->tags[i].address); + 			return i; + 		} + 	} +  + 	/* choose a random entry */ + 	i = (jiffies + (counter++)) % cache->page_count; +-	dbg("using cache entry %d", i); ++	dev_dbg(priv->dev, "%s:%d: using entry %d\n", __func__, __LINE__, i); +  + 	ps3vram_cache_evict(mtd, i); + 	ps3vram_cache_load(mtd, i, base); +@@ -389,18 +394,19 @@ static int ps3vram_cache_init(struct mtd_info *mtd) + { + 	struct ps3vram_priv *priv = mtd->priv; +  +-	pr_info("creating cache: %d entries, %d bytes pages\n", +-	       CACHE_PAGE_COUNT, CACHE_PAGE_SIZE); +- + 	priv->cache.page_count = CACHE_PAGE_COUNT; + 	priv->cache.page_size = CACHE_PAGE_SIZE; + 	priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) * + 				   CACHE_PAGE_COUNT, GFP_KERNEL); + 	if (priv->cache.tags == NULL) { +-		pr_err("could not allocate cache tags\n"); ++		dev_err(priv->dev, "%s:%d: could not allocate cache tags\n", ++			__func__, __LINE__); + 		return -ENOMEM; + 	} +  ++	dev_info(priv->dev, "created ram cache: %d entries, %d KiB each\n", ++		CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024); ++ + 	return 0; + } +  +@@ -434,14 +440,14 @@ static int ps3vram_erase(struct mtd_info *mtd, struct erase_info *instr) + 	return 0; + } +  +- + static int ps3vram_read(struct mtd_info *mtd, loff_t from, size_t len, + 			size_t *retlen, u_char *buf) + { + 	struct ps3vram_priv *priv = mtd->priv; + 	unsigned int cached, count; +  +-	dbg("from = 0x%08x len = 0x%zx", (unsigned int) from, len); ++	dev_dbg(priv->dev, "%s:%d: from=0x%08x len=0x%zx\n", __func__, __LINE__, ++		(unsigned int)from, len); +  + 	if (from >= mtd->size) + 		return -EINVAL; +@@ -463,8 +469,9 @@ static int ps3vram_read(struct mtd_info *mtd, loff_t from, size_t len, + 		entry = ps3vram_cache_match(mtd, from); + 		cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; +  +-		dbg("from=%08x cached=%08x offset=%08x avail=%08x count=%08x", +-		    (unsigned)from, cached, offset, avail, count); ++		dev_dbg(priv->dev, "%s:%d: from=%08x cached=%08x offset=%08x " ++			"avail=%08x count=%08x\n", __func__, __LINE__, ++			(unsigned int)from, cached, offset, avail, count); +  + 		if (avail > count) + 			avail = count; +@@ -507,8 +514,9 @@ static int ps3vram_write(struct mtd_info *mtd, loff_t to, size_t len, + 		entry = ps3vram_cache_match(mtd, to); + 		cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; +  +-		dbg("to=%08x cached=%08x offset=%08x avail=%08x count=%08x", +-		    (unsigned) to, cached, offset, avail, count); ++		dev_dbg(priv->dev, "%s:%d: to=%08x cached=%08x offset=%08x " ++			"avail=%08x count=%08x\n", __func__, __LINE__, ++			(unsigned int)to, cached, offset, avail, count); +  + 		if (avail > count) + 			avail = count; +@@ -544,12 +552,14 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) + 	priv = ps3vram_mtd.priv; +  + 	mutex_init(&priv->lock); ++	priv->dev = &dev->core; +  + 	/* Allocate XDR buffer (1MiB aligned) */ + 	priv->xdr_buf = (uint8_t *) __get_free_pages(GFP_KERNEL, + 						     get_order(XDR_BUF_SIZE)); + 	if (priv->xdr_buf == NULL) { +-		pr_err("ps3vram: could not allocate XDR buffer\n"); ++		dev_dbg(&dev->core, "%s:%d: could not allocate XDR buffer\n", ++			__func__, __LINE__); + 		ret = -ENOMEM; + 		goto out_free_priv; + 	} +@@ -560,7 +570,8 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) +  + 	/* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */ + 	if (ps3_open_hv_device(dev)) { +-		pr_err("ps3vram: ps3_open_hv_device failed\n"); ++		dev_err(&dev->core, "%s:%d: ps3_open_hv_device failed\n", ++			__func__, __LINE__); + 		ret = -EAGAIN; + 		goto out_close_gpu; + 	} +@@ -572,7 +583,8 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) + 		ddr_size -= ps3fb_videomemory.size; + 	ddr_size = ALIGN(ddr_size, 1024*1024); + 	if (ddr_size <= 0) { +-		printk(KERN_ERR "ps3vram: specified size is too small\n"); ++		dev_err(&dev->core, "%s:%d: specified size is too small\n", ++			__func__, __LINE__); + 		ret = -EINVAL; + 		goto out_close_gpu; + 	} +@@ -586,12 +598,11 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) + 		ddr_size -= 1024*1024; + 	} + 	if (status != 0 || ddr_size <= 0) { +-		pr_err("ps3vram: lv1_gpu_memory_allocate failed\n"); ++		dev_err(&dev->core, "%s:%d: lv1_gpu_memory_allocate failed\n", ++			__func__, __LINE__); + 		ret = -ENOMEM; + 		goto out_free_xdr_buf; + 	} +-	pr_info("ps3vram: allocated %u MiB of DDR memory\n", +-		(unsigned int) (ddr_size / 1024 / 1024)); +  + 	/* Request context */ + 	status = lv1_gpu_context_allocate(priv->memory_handle, +@@ -602,7 +613,8 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) + 					  &reports_lpar, + 					  &reports_size); + 	if (status) { +-		pr_err("ps3vram: lv1_gpu_context_allocate failed\n"); ++		dev_err(&dev->core, "%s:%d: lv1_gpu_context_allocate failed\n", ++			__func__, __LINE__); + 		ret = -ENOMEM; + 		goto out_free_memory; + 	} +@@ -612,28 +624,32 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) + 				       ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)), + 				       XDR_BUF_SIZE, 0); + 	if (status) { +-		pr_err("ps3vram: lv1_gpu_context_iomap failed\n"); ++		dev_err(&dev->core, "%s:%d: lv1_gpu_context_iomap failed\n", ++			__func__, __LINE__); + 		ret = -ENOMEM; + 		goto out_free_context; + 	} +  + 	priv->base = ioremap(ddr_lpar, ddr_size); + 	if (!priv->base) { +-		pr_err("ps3vram: ioremap failed\n"); ++		dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, ++			__LINE__); + 		ret = -ENOMEM; + 		goto out_free_context; + 	} +  + 	priv->ctrl = ioremap(ctrl_lpar, 64 * 1024); + 	if (!priv->ctrl) { +-		pr_err("ps3vram: ioremap failed\n"); ++		dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, ++			__LINE__); + 		ret = -ENOMEM; + 		goto out_unmap_vram; + 	} +  + 	priv->reports = ioremap(reports_lpar, reports_size); + 	if (!priv->reports) { +-		pr_err("ps3vram: ioremap failed\n"); ++		dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, ++			__LINE__); + 		ret = -ENOMEM; + 		goto out_unmap_ctrl; + 	} +@@ -661,7 +677,8 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) + 	ret = ps3vram_wait_ring(&ps3vram_mtd, 100); + 	mutex_unlock(&ps3_gpu_mutex); + 	if (ret < 0) { +-		pr_err("failed to initialize channels\n"); ++		dev_err(&dev->core, "%s:%d: failed to initialize channels\n", ++			__func__, __LINE__); + 		ret = -ETIMEDOUT; + 		goto out_unmap_reports; + 	} +@@ -669,12 +686,15 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) + 	ps3vram_cache_init(&ps3vram_mtd); +  + 	if (add_mtd_device(&ps3vram_mtd)) { +-		pr_err("ps3vram: failed to register device\n"); ++		dev_err(&dev->core, "%s:%d: add_mtd_device failed\n", ++			__func__, __LINE__); + 		ret = -EAGAIN; + 		goto out_cache_cleanup; + 	} +  +-	pr_info("ps3vram mtd device registered, %lu bytes\n", ddr_size); ++	dev_info(&dev->core, "reserved %u MiB of gpu memory\n", ++		(unsigned int)(ddr_size / 1024 / 1024)); ++ + 	return 0; +  + out_cache_cleanup: +--  +1.6.0.4 + diff --git a/target/linux/ps3/patches-2.6.28/0011-mtd-ps3vram-Use-proper-kernel-types.patch b/target/linux/ps3/patches-2.6.28/0011-mtd-ps3vram-Use-proper-kernel-types.patch new file mode 100644 index 000000000..126854696 --- /dev/null +++ b/target/linux/ps3/patches-2.6.28/0011-mtd-ps3vram-Use-proper-kernel-types.patch @@ -0,0 +1,163 @@ +From 993e62e674ba670341f11f60398446bb37a88e8b Mon Sep 17 00:00:00 2001 +From: Geoff Levand <geoffrey.levand@am.sony.com> +Date: Tue, 6 Jan 2009 11:32:28 +0000 +Subject: [PATCH] mtd/ps3vram: Use proper kernel types + +Replace the use of stdint.h types with kernel types +in the ps3vram driver. + +Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> +Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> +--- + drivers/mtd/devices/ps3vram.c |   56 ++++++++++++++++++++++------------------- + 1 files changed, 30 insertions(+), 26 deletions(-) + +diff --git a/drivers/mtd/devices/ps3vram.c b/drivers/mtd/devices/ps3vram.c +index f5cc290..91cc2af 100644 +--- a/drivers/mtd/devices/ps3vram.c ++++ b/drivers/mtd/devices/ps3vram.c +@@ -65,15 +65,15 @@ struct ps3vram_cache { + }; +  + struct ps3vram_priv { +-	uint64_t memory_handle; +-	uint64_t context_handle; +-	uint8_t *base; +-	uint32_t *ctrl; +-	uint32_t *reports; +-	uint8_t *xdr_buf; ++	u64 memory_handle; ++	u64 context_handle; ++	u32 *ctrl; ++	u32 *reports; ++	u8 *base; ++	u8 *xdr_buf; +  +-	uint32_t *fifo_base; +-	uint32_t *fifo_ptr; ++	u32 *fifo_base; ++	u32 *fifo_ptr; +  + 	struct device *dev; + 	struct ps3vram_cache cache; +@@ -92,7 +92,7 @@ char *size = "256M-"; + module_param(size, charp, 0); + MODULE_PARM_DESC(size, "memory size"); +  +-static inline uint32_t *ps3vram_get_notifier(uint32_t *reports, int notifier) ++static u32 *ps3vram_get_notifier(u32 *reports, int notifier) + { + 	return (void *) reports + + 		DMA_NOTIFIER_OFFSET_BASE + +@@ -102,8 +102,9 @@ static inline uint32_t *ps3vram_get_notifier(uint32_t *reports, int notifier) + static void ps3vram_notifier_reset(struct mtd_info *mtd) + { + 	int i; ++ + 	struct ps3vram_priv *priv = mtd->priv; +-	uint32_t *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); ++	u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); + 	for (i = 0; i < 4; i++) + 		notify[i] = 0xffffffff; + } +@@ -111,7 +112,7 @@ static void ps3vram_notifier_reset(struct mtd_info *mtd) + static int ps3vram_notifier_wait(struct mtd_info *mtd, int timeout_ms) + { + 	struct ps3vram_priv *priv = mtd->priv; +-	uint32_t *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); ++	u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); +  + 	timeout_ms *= 1000; +  +@@ -155,13 +156,13 @@ static int ps3vram_wait_ring(struct mtd_info *mtd, int timeout) + 	return 0; + } +  +-static inline void ps3vram_out_ring(struct ps3vram_priv *priv, uint32_t data) ++static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data) + { + 	*(priv->fifo_ptr)++ = data; + } +  +-static inline void ps3vram_begin_ring(struct ps3vram_priv *priv, uint32_t chan, +-				      uint32_t tag, uint32_t size) ++static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan, ++				      u32 tag, u32 size) + { + 	ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag); + } +@@ -194,7 +195,7 @@ static void ps3vram_fire_ring(struct mtd_info *mtd) + 	mutex_lock(&ps3_gpu_mutex); +  + 	priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET + +-		(priv->fifo_ptr - priv->fifo_base) * sizeof(uint32_t); ++		(priv->fifo_ptr - priv->fifo_base) * sizeof(u32); +  + 	/* asking the HV for a blit will kick the fifo */ + 	status = lv1_gpu_context_attribute(priv->context_handle, +@@ -204,8 +205,8 @@ static void ps3vram_fire_ring(struct mtd_info *mtd) + 		dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n", + 			__func__, __LINE__); +  +-	if ((priv->fifo_ptr - priv->fifo_base) * sizeof(uint32_t) > +-	    FIFO_SIZE - 1024) { ++	if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) > ++		FIFO_SIZE - 1024) { + 		dev_dbg(priv->dev, "%s:%d: fifo full, rewinding\n", __func__, + 			__LINE__); + 		ps3vram_wait_ring(mtd, 200); +@@ -538,10 +539,13 @@ static int ps3vram_write(struct mtd_info *mtd, loff_t to, size_t len, + static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) + { + 	struct ps3vram_priv *priv; +-	uint64_t status; +-	uint64_t ddr_lpar, ctrl_lpar, info_lpar, reports_lpar; +-	int64_t ddr_size; +-	uint64_t reports_size; ++	int status; ++	u64 ddr_lpar; ++	u64 ctrl_lpar; ++	u64 info_lpar; ++	u64 reports_lpar; ++	u64 ddr_size; ++	u64 reports_size; + 	int ret = -ENOMEM; + 	char *rest; +  +@@ -555,8 +559,8 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) + 	priv->dev = &dev->core; +  + 	/* Allocate XDR buffer (1MiB aligned) */ +-	priv->xdr_buf = (uint8_t *) __get_free_pages(GFP_KERNEL, +-						     get_order(XDR_BUF_SIZE)); ++	priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL, ++		get_order(XDR_BUF_SIZE)); + 	if (priv->xdr_buf == NULL) { + 		dev_dbg(&dev->core, "%s:%d: could not allocate XDR buffer\n", + 			__func__, __LINE__); +@@ -565,7 +569,7 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) + 	} +  + 	/* Put FIFO at begginning of XDR buffer */ +-	priv->fifo_base = (uint32_t *) (priv->xdr_buf + FIFO_OFFSET); ++	priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET); + 	priv->fifo_ptr = priv->fifo_base; +  + 	/* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */ +@@ -593,11 +597,11 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) + 		status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0, + 						 &priv->memory_handle, + 						 &ddr_lpar); +-		if (status == 0) ++		if (!status) + 			break; + 		ddr_size -= 1024*1024; + 	} +-	if (status != 0 || ddr_size <= 0) { ++	if (status || ddr_size <= 0) { + 		dev_err(&dev->core, "%s:%d: lv1_gpu_memory_allocate failed\n", + 			__func__, __LINE__); + 		ret = -ENOMEM; +--  +1.6.0.4 + diff --git a/target/linux/ps3/patches-2.6.28/0012-mtd-ps3vram-Use-msleep-in-waits.patch b/target/linux/ps3/patches-2.6.28/0012-mtd-ps3vram-Use-msleep-in-waits.patch new file mode 100644 index 000000000..0f235094c --- /dev/null +++ b/target/linux/ps3/patches-2.6.28/0012-mtd-ps3vram-Use-msleep-in-waits.patch @@ -0,0 +1,87 @@ +From 60c0c5987b0996a7c7c4c6d90f63ed413c368a71 Mon Sep 17 00:00:00 2001 +From: Geoff Levand <geoffrey.levand@am.sony.com> +Date: Wed, 7 Jan 2009 17:22:02 -0800 +Subject: [PATCH] mtd/ps3vram: Use msleep in waits + +Replace the use of udelay() with msleep() in the looping wait routines +ps3vram_notifier_wait() and ps3vram_wait_ring(). + +Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> +Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> +--- + drivers/mtd/devices/ps3vram.c |   42 +++++++++++++++++----------------------- + 1 files changed, 18 insertions(+), 24 deletions(-) + +diff --git a/drivers/mtd/devices/ps3vram.c b/drivers/mtd/devices/ps3vram.c +index 91cc2af..d592414 100644 +--- a/drivers/mtd/devices/ps3vram.c ++++ b/drivers/mtd/devices/ps3vram.c +@@ -109,22 +109,19 @@ static void ps3vram_notifier_reset(struct mtd_info *mtd) + 		notify[i] = 0xffffffff; + } +  +-static int ps3vram_notifier_wait(struct mtd_info *mtd, int timeout_ms) ++static int ps3vram_notifier_wait(struct mtd_info *mtd, unsigned int timeout_ms) + { + 	struct ps3vram_priv *priv = mtd->priv; + 	u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); +- +-	timeout_ms *= 1000; ++	unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); +  + 	do { +-		if (notify[3] == 0) ++		if (!notify[3]) + 			return 0; ++		msleep(1); ++	} while (time_before(jiffies, timeout)); +  +-		if (timeout_ms) +-			udelay(1); +-	} while (timeout_ms--); +- +-	return -1; ++	return -ETIMEDOUT; + } +  + static void ps3vram_init_ring(struct mtd_info *mtd) +@@ -135,25 +132,22 @@ static void ps3vram_init_ring(struct mtd_info *mtd) + 	priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET; + } +  +-static int ps3vram_wait_ring(struct mtd_info *mtd, int timeout) ++static int ps3vram_wait_ring(struct mtd_info *mtd, unsigned int timeout_ms) + { + 	struct ps3vram_priv *priv = mtd->priv; ++	unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); +  +-	/* wait until setup commands are processed */ +-	timeout *= 1000; +-	while (--timeout) { ++	do { + 		if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET]) +-			break; +-		udelay(1); +-	} +-	if (timeout == 0) { +-		dev_dbg(priv->dev, "%s:%d: FIFO timeout (%08x/%08x/%08x)\n", +-			__func__, __LINE__, priv->ctrl[CTRL_PUT], +-			priv->ctrl[CTRL_GET], priv->ctrl[CTRL_TOP]); +-		return -ETIMEDOUT; +-	} ++			return 0; ++		msleep(1); ++	} while (time_before(jiffies, timeout)); +  +-	return 0; ++	dev_dbg(priv->dev, "%s:%d: FIFO timeout (%08x/%08x/%08x)\n", __func__, ++		__LINE__, priv->ctrl[CTRL_PUT], priv->ctrl[CTRL_GET], ++		priv->ctrl[CTRL_TOP]); ++ ++	return -ETIMEDOUT; + } +  + static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data) +--  +1.6.0.4 + diff --git a/target/linux/ps3/patches-2.6.28/0013-mtd-ps3vram-Use-_PAGE_NO_CACHE-in-memory-ioremap.patch b/target/linux/ps3/patches-2.6.28/0013-mtd-ps3vram-Use-_PAGE_NO_CACHE-in-memory-ioremap.patch new file mode 100644 index 000000000..b3047e16a --- /dev/null +++ b/target/linux/ps3/patches-2.6.28/0013-mtd-ps3vram-Use-_PAGE_NO_CACHE-in-memory-ioremap.patch @@ -0,0 +1,78 @@ +From 2efd72af0f18860927084df618f7419c82f69be3 Mon Sep 17 00:00:00 2001 +From: Geoff Levand <geoffrey.levand@am.sony.com> +Date: Wed, 7 Jan 2009 17:22:07 -0800 +Subject: [PATCH] mtd/ps3vram: Use _PAGE_NO_CACHE in memory ioremap + +Use _PAGE_NO_CACHE for gpu memory ioremap.  Also, +add __iomem attribute to gpu memory pointer and +change use of memset() to memset_io(). + +Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> +Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> +--- + drivers/mtd/devices/ps3vram.c |   14 ++++++++------ + 1 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/drivers/mtd/devices/ps3vram.c b/drivers/mtd/devices/ps3vram.c +index d592414..d21e9be 100644 +--- a/drivers/mtd/devices/ps3vram.c ++++ b/drivers/mtd/devices/ps3vram.c +@@ -6,6 +6,7 @@ +  */ +  + #include <linux/io.h> ++#include <linux/mm.h> + #include <linux/init.h> + #include <linux/kernel.h> + #include <linux/list.h> +@@ -69,7 +70,7 @@ struct ps3vram_priv { + 	u64 context_handle; + 	u32 *ctrl; + 	u32 *reports; +-	u8 *base; ++	u8 __iomem *ddr_base; + 	u8 *xdr_buf; +  + 	u32 *fifo_base; +@@ -425,7 +426,7 @@ static int ps3vram_erase(struct mtd_info *mtd, struct erase_info *instr) + 	ps3vram_cache_flush(mtd); +  + 	/* Set bytes to 0xFF */ +-	memset(priv->base + instr->addr, 0xFF, instr->len); ++	memset_io(priv->ddr_base + instr->addr, 0xFF, instr->len); +  + 	mutex_unlock(&priv->lock); +  +@@ -628,8 +629,9 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) + 		goto out_free_context; + 	} +  +-	priv->base = ioremap(ddr_lpar, ddr_size); +-	if (!priv->base) { ++	priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE); ++ ++	if (!priv->ddr_base) { + 		dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, + 			__LINE__); + 		ret = -ENOMEM; +@@ -702,7 +704,7 @@ out_unmap_reports: + out_unmap_ctrl: + 	iounmap(priv->ctrl); + out_unmap_vram: +-	iounmap(priv->base); ++	iounmap(priv->ddr_base); + out_free_context: + 	lv1_gpu_context_free(priv->context_handle); + out_free_memory: +@@ -728,7 +730,7 @@ static int ps3vram_shutdown(struct ps3_system_bus_device *dev) + 	ps3vram_cache_cleanup(&ps3vram_mtd); + 	iounmap(priv->reports); + 	iounmap(priv->ctrl); +-	iounmap(priv->base); ++	iounmap(priv->ddr_base); + 	lv1_gpu_context_free(priv->context_handle); + 	lv1_gpu_memory_free(priv->memory_handle); + 	ps3_close_hv_device(dev); +--  +1.6.0.4 + diff --git a/target/linux/ps3/patches-2.6.28/0014-powerpc-ps3-Move-ps3_mm_add_memory-to-device_initca.patch b/target/linux/ps3/patches-2.6.28/0014-powerpc-ps3-Move-ps3_mm_add_memory-to-device_initca.patch new file mode 100644 index 000000000..ad2a6caad --- /dev/null +++ b/target/linux/ps3/patches-2.6.28/0014-powerpc-ps3-Move-ps3_mm_add_memory-to-device_initca.patch @@ -0,0 +1,36 @@ +From 0047656e2a97d4452dd7df9e52591a7afe21a263 Mon Sep 17 00:00:00 2001 +From: Geoff Levand <geoffrey.levand@am.sony.com> +Date: Thu, 12 Feb 2009 12:36:16 +0000 +Subject: [PATCH] powerpc/ps3: Move ps3_mm_add_memory to device_initcall + +Change the PS3 hotplug memory routine ps3_mm_add_memory() from +a core_initcall to a device_initcall. + +core_initcall routines run before the powerpc topology_init() +startup routine, which is a subsys_initcall, resulting in +failure of ps3_mm_add_memory() when CONFIG_NUMA=y.  When +ps3_mm_add_memory() fails the system will boot with just the +128 MiB of boot memory + +Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> +Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> +--- + arch/powerpc/platforms/ps3/mm.c |    2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c +index 67de6bf..d281cc0 100644 +--- a/arch/powerpc/platforms/ps3/mm.c ++++ b/arch/powerpc/platforms/ps3/mm.c +@@ -328,7 +328,7 @@ static int __init ps3_mm_add_memory(void) + 	return result; + } +  +-core_initcall(ps3_mm_add_memory); ++device_initcall(ps3_mm_add_memory); +  + /*============================================================================*/ + /* dma routines                                                               */ +--  +1.6.0.4 + diff --git a/target/linux/ps3/patches-2.6.28/0010-ps3vram-ng.patch b/target/linux/ps3/patches-2.6.28/0015-ps3-block-Replace-mtd-ps3vram-by-block-ps3vram.patch index 8c29d8040..51642ea61 100644 --- a/target/linux/ps3/patches-2.6.28/0010-ps3vram-ng.patch +++ b/target/linux/ps3/patches-2.6.28/0015-ps3-block-Replace-mtd-ps3vram-by-block-ps3vram.patch @@ -1,10 +1,10 @@ -From d7ddc1aaee1ff6dd6a73bd3663b6c390800e0500 Mon Sep 17 00:00:00 2001 +From f507cd22035fdadd5dbb476dd05e9e7ee21c3b84 Mon Sep 17 00:00:00 2001  From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com> -Date: Wed, 25 Feb 2009 18:32:10 +0100 +Date: Fri, 6 Mar 2009 02:54:09 +0000  Subject: [PATCH] ps3/block: Replace mtd/ps3vram by block/ps3vram -Convert the PS3 Video RAM Storage Driver from a MTD driver to a plain block -device driver, as requested by Arnd Bergmann. +Convert the PS3 Video RAM Storage Driver from an MTD driver to a plain block +device driver.  The ps3vram driver exposes unused video RAM on the PS3 as a block device  suitable for storage or swap.  Fast data transfer is achieved using a local @@ -13,44 +13,16 @@ cache in system RAM and DMA transfers via the GPU.  The new driver is ca. 50% faster for reading, and ca. 10% for writing.  Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com> -Acked-by: Jens Axboe <axboe@kernel.dk>  Acked-by: Geoff Levand <geoffrey.levand@am.sony.com> -Cc: Arnd Bergmann <arnd@arndb.de> -Cc: David Woodhouse <David.Woodhouse@intel.com> -Cc: Vivien Chappelier <vivien.chappelier@free.fr> -Cc: Jim Paris <jim@jtan.com> - -Notes: - -The MTD-based PS3 Video RAM Storage Driver was integrated into the mainline -kernel in 2.6.29-rc1. - -Ideally, we think it would be best if the existing MTD-based ps3vram driver -would be replaced by the new block-based ps3vram driver before 2.6.29 is -released. This would relieve the burden of supporting two different swap space -schemes on PS3 (swap on /dev/mtdblock0 vs. /dev/ps3vram) from the distro -maintainer's shoulders, as in that case there would never have been a stable -kernel version containing the MTD-based ps3vram driver. - -Changes since previous submission (Wed, 4 Mar 2009 14:57:20 +0100 (CET)): -  - Use blk_queue_make_request() to get rid of the thread -  - Add a mutex (cfr. the old driver), as ps3vram_make_request() may be called -    concurrently -    TO DO (after 2.6.29): use a spinlock and a list to queue requests while the -    driver is busy -  - Remove the old MTD-based ps3vram driver and rename ps3vram-ng to ps3vram -  - Make PS3_VRAM depend on FB_PS3=y and m for now -    ps3vram relies on ps3fb being initialized first. The easiest way to do this -    is by making ps3vram modular, and ps3fb builtin -  - Remove the dependency on ps3fb_videomemory.size -    The loop to reduce ddr_size until it succeeds does the right thing anyway, -    and a few MiB of DDR RAM are reserved by the hypervisor -  - lv1 return codes can be int -  - Correct a few debug annotations +Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>  ---   arch/powerpc/platforms/ps3/Kconfig |    7 +   drivers/block/Makefile             |    1 +   drivers/block/ps3vram.c            |  865 ++++++++++++++++++++++++++++++++++++ + drivers/mtd/devices/Kconfig        |    7 - + drivers/mtd/devices/Makefile       |    1 - + drivers/mtd/devices/ps3vram.c      |  768 -------------------------------- + 6 files changed, 873 insertions(+), 776 deletions(-)   create mode 100644 drivers/block/ps3vram.c   delete mode 100644 drivers/mtd/devices/ps3vram.c @@ -955,3 +927,807 @@ index 0000000..393ed67  +MODULE_DESCRIPTION("PS3 Video RAM Storage Driver");  +MODULE_AUTHOR("Sony Corporation");  +MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK); +diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig +index bc33200..6fde0a2 100644 +--- a/drivers/mtd/devices/Kconfig ++++ b/drivers/mtd/devices/Kconfig +@@ -120,13 +120,6 @@ config MTD_PHRAM + 	  doesn't have access to, memory beyond the mem=xxx limit, nvram, + 	  memory on the video card, etc... +  +-config MTD_PS3VRAM +-	tristate "PS3 video RAM" +-	depends on FB_PS3 +-	help +-	  This driver allows you to use excess PS3 video RAM as volatile +-	  storage or system swap. +- + config MTD_LART + 	tristate "28F160xx flash driver for LART" + 	depends on SA1100_LART +diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile +index e51521d..0993d5c 100644 +--- a/drivers/mtd/devices/Makefile ++++ b/drivers/mtd/devices/Makefile +@@ -16,4 +16,3 @@ obj-$(CONFIG_MTD_LART)		+= lart.o + obj-$(CONFIG_MTD_BLOCK2MTD)	+= block2mtd.o + obj-$(CONFIG_MTD_DATAFLASH)	+= mtd_dataflash.o + obj-$(CONFIG_MTD_M25P80)	+= m25p80.o +-obj-$(CONFIG_MTD_PS3VRAM)	+= ps3vram.o +diff --git a/drivers/mtd/devices/ps3vram.c b/drivers/mtd/devices/ps3vram.c +deleted file mode 100644 +index d21e9be..0000000 +--- a/drivers/mtd/devices/ps3vram.c ++++ /dev/null +@@ -1,768 +0,0 @@ +-/** +- * ps3vram - Use extra PS3 video ram as MTD block device. +- * +- * Copyright (c) 2007-2008 Jim Paris <jim@jtan.com> +- * Added support RSX DMA Vivien Chappelier <vivien.chappelier@free.fr> +- */ +- +-#include <linux/io.h> +-#include <linux/mm.h> +-#include <linux/init.h> +-#include <linux/kernel.h> +-#include <linux/list.h> +-#include <linux/module.h> +-#include <linux/moduleparam.h> +-#include <linux/slab.h> +-#include <linux/version.h> +-#include <linux/gfp.h> +-#include <linux/delay.h> +-#include <linux/mtd/mtd.h> +- +-#include <asm/lv1call.h> +-#include <asm/ps3.h> +- +-#define DEVICE_NAME		"ps3vram" +- +-#define XDR_BUF_SIZE (2 * 1024 * 1024) /* XDR buffer (must be 1MiB aligned) */ +-#define XDR_IOIF 0x0c000000 +- +-#define FIFO_BASE XDR_IOIF +-#define FIFO_SIZE (64 * 1024) +- +-#define DMA_PAGE_SIZE (4 * 1024) +- +-#define CACHE_PAGE_SIZE (256 * 1024) +-#define CACHE_PAGE_COUNT ((XDR_BUF_SIZE - FIFO_SIZE) / CACHE_PAGE_SIZE) +- +-#define CACHE_OFFSET CACHE_PAGE_SIZE +-#define FIFO_OFFSET 0 +- +-#define CTRL_PUT 0x10 +-#define CTRL_GET 0x11 +-#define CTRL_TOP 0x15 +- +-#define UPLOAD_SUBCH	1 +-#define DOWNLOAD_SUBCH	2 +- +-#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN	0x0000030c +-#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY	0x00000104 +- +-#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601 +- +-struct mtd_info ps3vram_mtd; +- +-#define CACHE_PAGE_PRESENT 1 +-#define CACHE_PAGE_DIRTY   2 +- +-struct ps3vram_tag { +-	unsigned int address; +-	unsigned int flags; +-}; +- +-struct ps3vram_cache { +-	unsigned int page_count; +-	unsigned int page_size; +-	struct ps3vram_tag *tags; +-}; +- +-struct ps3vram_priv { +-	u64 memory_handle; +-	u64 context_handle; +-	u32 *ctrl; +-	u32 *reports; +-	u8 __iomem *ddr_base; +-	u8 *xdr_buf; +- +-	u32 *fifo_base; +-	u32 *fifo_ptr; +- +-	struct device *dev; +-	struct ps3vram_cache cache; +- +-	/* Used to serialize cache/DMA operations */ +-	struct mutex lock; +-}; +- +-#define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */ +-#define DMA_NOTIFIER_OFFSET_BASE 0x1000     /* first DMA notifier offset */ +-#define DMA_NOTIFIER_SIZE        0x40 +-#define NOTIFIER 7	/* notifier used for completion report */ +- +-/* A trailing '-' means to subtract off ps3fb_videomemory.size */ +-char *size = "256M-"; +-module_param(size, charp, 0); +-MODULE_PARM_DESC(size, "memory size"); +- +-static u32 *ps3vram_get_notifier(u32 *reports, int notifier) +-{ +-	return (void *) reports + +-		DMA_NOTIFIER_OFFSET_BASE + +-		DMA_NOTIFIER_SIZE * notifier; +-} +- +-static void ps3vram_notifier_reset(struct mtd_info *mtd) +-{ +-	int i; +- +-	struct ps3vram_priv *priv = mtd->priv; +-	u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); +-	for (i = 0; i < 4; i++) +-		notify[i] = 0xffffffff; +-} +- +-static int ps3vram_notifier_wait(struct mtd_info *mtd, unsigned int timeout_ms) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +-	u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); +-	unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); +- +-	do { +-		if (!notify[3]) +-			return 0; +-		msleep(1); +-	} while (time_before(jiffies, timeout)); +- +-	return -ETIMEDOUT; +-} +- +-static void ps3vram_init_ring(struct mtd_info *mtd) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +- +-	priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; +-	priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET; +-} +- +-static int ps3vram_wait_ring(struct mtd_info *mtd, unsigned int timeout_ms) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +-	unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); +- +-	do { +-		if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET]) +-			return 0; +-		msleep(1); +-	} while (time_before(jiffies, timeout)); +- +-	dev_dbg(priv->dev, "%s:%d: FIFO timeout (%08x/%08x/%08x)\n", __func__, +-		__LINE__, priv->ctrl[CTRL_PUT], priv->ctrl[CTRL_GET], +-		priv->ctrl[CTRL_TOP]); +- +-	return -ETIMEDOUT; +-} +- +-static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data) +-{ +-	*(priv->fifo_ptr)++ = data; +-} +- +-static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan, +-				      u32 tag, u32 size) +-{ +-	ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag); +-} +- +-static void ps3vram_rewind_ring(struct mtd_info *mtd) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +-	u64 status; +- +-	ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET)); +- +-	priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; +- +-	/* asking the HV for a blit will kick the fifo */ +-	status = lv1_gpu_context_attribute(priv->context_handle, +-					   L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, +-					   0, 0, 0, 0); +-	if (status) +-		dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n", +-			__func__, __LINE__); +- +-	priv->fifo_ptr = priv->fifo_base; +-} +- +-static void ps3vram_fire_ring(struct mtd_info *mtd) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +-	u64 status; +- +-	mutex_lock(&ps3_gpu_mutex); +- +-	priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET + +-		(priv->fifo_ptr - priv->fifo_base) * sizeof(u32); +- +-	/* asking the HV for a blit will kick the fifo */ +-	status = lv1_gpu_context_attribute(priv->context_handle, +-					   L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, +-					   0, 0, 0, 0); +-	if (status) +-		dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n", +-			__func__, __LINE__); +- +-	if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) > +-		FIFO_SIZE - 1024) { +-		dev_dbg(priv->dev, "%s:%d: fifo full, rewinding\n", __func__, +-			__LINE__); +-		ps3vram_wait_ring(mtd, 200); +-		ps3vram_rewind_ring(mtd); +-	} +- +-	mutex_unlock(&ps3_gpu_mutex); +-} +- +-static void ps3vram_bind(struct mtd_info *mtd) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +- +-	ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1); +-	ps3vram_out_ring(priv, 0x31337303); +-	ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x180, 3); +-	ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER); +-	ps3vram_out_ring(priv, 0xfeed0001);	/* DMA system RAM instance */ +-	ps3vram_out_ring(priv, 0xfeed0000);     /* DMA video RAM instance */ +- +-	ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0, 1); +-	ps3vram_out_ring(priv, 0x3137c0de); +-	ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x180, 3); +-	ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER); +-	ps3vram_out_ring(priv, 0xfeed0000);	/* DMA video RAM instance */ +-	ps3vram_out_ring(priv, 0xfeed0001);	/* DMA system RAM instance */ +- +-	ps3vram_fire_ring(mtd); +-} +- +-static int ps3vram_upload(struct mtd_info *mtd, unsigned int src_offset, +-			  unsigned int dst_offset, int len, int count) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +- +-	ps3vram_begin_ring(priv, UPLOAD_SUBCH, +-			   NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); +-	ps3vram_out_ring(priv, XDR_IOIF + src_offset); +-	ps3vram_out_ring(priv, dst_offset); +-	ps3vram_out_ring(priv, len); +-	ps3vram_out_ring(priv, len); +-	ps3vram_out_ring(priv, len); +-	ps3vram_out_ring(priv, count); +-	ps3vram_out_ring(priv, (1 << 8) | 1); +-	ps3vram_out_ring(priv, 0); +- +-	ps3vram_notifier_reset(mtd); +-	ps3vram_begin_ring(priv, UPLOAD_SUBCH, +-			   NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); +-	ps3vram_out_ring(priv, 0); +-	ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x100, 1); +-	ps3vram_out_ring(priv, 0); +-	ps3vram_fire_ring(mtd); +-	if (ps3vram_notifier_wait(mtd, 200) < 0) { +-		dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__, +-			__LINE__); +-		return -1; +-	} +- +-	return 0; +-} +- +-static int ps3vram_download(struct mtd_info *mtd, unsigned int src_offset, +-			    unsigned int dst_offset, int len, int count) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +- +-	ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, +-			   NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); +-	ps3vram_out_ring(priv, src_offset); +-	ps3vram_out_ring(priv, XDR_IOIF + dst_offset); +-	ps3vram_out_ring(priv, len); +-	ps3vram_out_ring(priv, len); +-	ps3vram_out_ring(priv, len); +-	ps3vram_out_ring(priv, count); +-	ps3vram_out_ring(priv, (1 << 8) | 1); +-	ps3vram_out_ring(priv, 0); +- +-	ps3vram_notifier_reset(mtd); +-	ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, +-			   NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); +-	ps3vram_out_ring(priv, 0); +-	ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x100, 1); +-	ps3vram_out_ring(priv, 0); +-	ps3vram_fire_ring(mtd); +-	if (ps3vram_notifier_wait(mtd, 200) < 0) { +-		dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__, +-			__LINE__); +-		return -1; +-	} +- +-	return 0; +-} +- +-static void ps3vram_cache_evict(struct mtd_info *mtd, int entry) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +-	struct ps3vram_cache *cache = &priv->cache; +- +-	if (cache->tags[entry].flags & CACHE_PAGE_DIRTY) { +-		dev_dbg(priv->dev, "%s:%d: flushing %d : 0x%08x\n", __func__, +-			__LINE__, entry, cache->tags[entry].address); +-		if (ps3vram_upload(mtd, +-				   CACHE_OFFSET + entry * cache->page_size, +-				   cache->tags[entry].address, +-				   DMA_PAGE_SIZE, +-				   cache->page_size / DMA_PAGE_SIZE) < 0) { +-			dev_dbg(priv->dev, "%s:%d: failed to upload from " +-				"0x%x to 0x%x size 0x%x\n", __func__, __LINE__, +-				entry * cache->page_size, +-				cache->tags[entry].address, cache->page_size); +-		} +-		cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY; +-	} +-} +- +-static void ps3vram_cache_load(struct mtd_info *mtd, int entry, +-			       unsigned int address) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +-	struct ps3vram_cache *cache = &priv->cache; +- +-	dev_dbg(priv->dev, "%s:%d: fetching %d : 0x%08x\n", __func__, __LINE__, +-		entry, address); +-	if (ps3vram_download(mtd, +-			     address, +-			     CACHE_OFFSET + entry * cache->page_size, +-			     DMA_PAGE_SIZE, +-			     cache->page_size / DMA_PAGE_SIZE) < 0) { +-		dev_err(priv->dev, "%s:%d: failed to download from " +-			"0x%x to 0x%x size 0x%x\n", __func__, __LINE__, address, +-			entry * cache->page_size, cache->page_size); +-	} +- +-	cache->tags[entry].address = address; +-	cache->tags[entry].flags |= CACHE_PAGE_PRESENT; +-} +- +- +-static void ps3vram_cache_flush(struct mtd_info *mtd) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +-	struct ps3vram_cache *cache = &priv->cache; +-	int i; +- +-	dev_dbg(priv->dev, "%s:%d: FLUSH\n", __func__, __LINE__); +-	for (i = 0; i < cache->page_count; i++) { +-		ps3vram_cache_evict(mtd, i); +-		cache->tags[i].flags = 0; +-	} +-} +- +-static unsigned int ps3vram_cache_match(struct mtd_info *mtd, loff_t address) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +-	struct ps3vram_cache *cache = &priv->cache; +-	unsigned int base; +-	unsigned int offset; +-	int i; +-	static int counter; +- +-	offset = (unsigned int) (address & (cache->page_size - 1)); +-	base = (unsigned int) (address - offset); +- +-	/* fully associative check */ +-	for (i = 0; i < cache->page_count; i++) { +-		if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) && +-		    cache->tags[i].address == base) { +-			dev_dbg(priv->dev, "%s:%d: found entry %d : 0x%08x\n", +-				__func__, __LINE__, i, cache->tags[i].address); +-			return i; +-		} +-	} +- +-	/* choose a random entry */ +-	i = (jiffies + (counter++)) % cache->page_count; +-	dev_dbg(priv->dev, "%s:%d: using entry %d\n", __func__, __LINE__, i); +- +-	ps3vram_cache_evict(mtd, i); +-	ps3vram_cache_load(mtd, i, base); +- +-	return i; +-} +- +-static int ps3vram_cache_init(struct mtd_info *mtd) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +- +-	priv->cache.page_count = CACHE_PAGE_COUNT; +-	priv->cache.page_size = CACHE_PAGE_SIZE; +-	priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) * +-				   CACHE_PAGE_COUNT, GFP_KERNEL); +-	if (priv->cache.tags == NULL) { +-		dev_err(priv->dev, "%s:%d: could not allocate cache tags\n", +-			__func__, __LINE__); +-		return -ENOMEM; +-	} +- +-	dev_info(priv->dev, "created ram cache: %d entries, %d KiB each\n", +-		CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024); +- +-	return 0; +-} +- +-static void ps3vram_cache_cleanup(struct mtd_info *mtd) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +- +-	ps3vram_cache_flush(mtd); +-	kfree(priv->cache.tags); +-} +- +-static int ps3vram_erase(struct mtd_info *mtd, struct erase_info *instr) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +- +-	if (instr->addr + instr->len > mtd->size) +-		return -EINVAL; +- +-	mutex_lock(&priv->lock); +- +-	ps3vram_cache_flush(mtd); +- +-	/* Set bytes to 0xFF */ +-	memset_io(priv->ddr_base + instr->addr, 0xFF, instr->len); +- +-	mutex_unlock(&priv->lock); +- +-	instr->state = MTD_ERASE_DONE; +-	mtd_erase_callback(instr); +- +-	return 0; +-} +- +-static int ps3vram_read(struct mtd_info *mtd, loff_t from, size_t len, +-			size_t *retlen, u_char *buf) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +-	unsigned int cached, count; +- +-	dev_dbg(priv->dev, "%s:%d: from=0x%08x len=0x%zx\n", __func__, __LINE__, +-		(unsigned int)from, len); +- +-	if (from >= mtd->size) +-		return -EINVAL; +- +-	if (len > mtd->size - from) +-		len = mtd->size - from; +- +-	/* Copy from vram to buf */ +-	count = len; +-	while (count) { +-		unsigned int offset, avail; +-		unsigned int entry; +- +-		offset = (unsigned int) (from & (priv->cache.page_size - 1)); +-		avail  = priv->cache.page_size - offset; +- +-		mutex_lock(&priv->lock); +- +-		entry = ps3vram_cache_match(mtd, from); +-		cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; +- +-		dev_dbg(priv->dev, "%s:%d: from=%08x cached=%08x offset=%08x " +-			"avail=%08x count=%08x\n", __func__, __LINE__, +-			(unsigned int)from, cached, offset, avail, count); +- +-		if (avail > count) +-			avail = count; +-		memcpy(buf, priv->xdr_buf + cached, avail); +- +-		mutex_unlock(&priv->lock); +- +-		buf += avail; +-		count -= avail; +-		from += avail; +-	} +- +-	*retlen = len; +-	return 0; +-} +- +-static int ps3vram_write(struct mtd_info *mtd, loff_t to, size_t len, +-			 size_t *retlen, const u_char *buf) +-{ +-	struct ps3vram_priv *priv = mtd->priv; +-	unsigned int cached, count; +- +-	if (to >= mtd->size) +-		return -EINVAL; +- +-	if (len > mtd->size - to) +-		len = mtd->size - to; +- +-	/* Copy from buf to vram */ +-	count = len; +-	while (count) { +-		unsigned int offset, avail; +-		unsigned int entry; +- +-		offset = (unsigned int) (to & (priv->cache.page_size - 1)); +-		avail  = priv->cache.page_size - offset; +- +-		mutex_lock(&priv->lock); +- +-		entry = ps3vram_cache_match(mtd, to); +-		cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; +- +-		dev_dbg(priv->dev, "%s:%d: to=%08x cached=%08x offset=%08x " +-			"avail=%08x count=%08x\n", __func__, __LINE__, +-			(unsigned int)to, cached, offset, avail, count); +- +-		if (avail > count) +-			avail = count; +-		memcpy(priv->xdr_buf + cached, buf, avail); +- +-		priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY; +- +-		mutex_unlock(&priv->lock); +- +-		buf += avail; +-		count -= avail; +-		to += avail; +-	} +- +-	*retlen = len; +-	return 0; +-} +- +-static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) +-{ +-	struct ps3vram_priv *priv; +-	int status; +-	u64 ddr_lpar; +-	u64 ctrl_lpar; +-	u64 info_lpar; +-	u64 reports_lpar; +-	u64 ddr_size; +-	u64 reports_size; +-	int ret = -ENOMEM; +-	char *rest; +- +-	ret = -EIO; +-	ps3vram_mtd.priv = kzalloc(sizeof(struct ps3vram_priv), GFP_KERNEL); +-	if (!ps3vram_mtd.priv) +-		goto out; +-	priv = ps3vram_mtd.priv; +- +-	mutex_init(&priv->lock); +-	priv->dev = &dev->core; +- +-	/* Allocate XDR buffer (1MiB aligned) */ +-	priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL, +-		get_order(XDR_BUF_SIZE)); +-	if (priv->xdr_buf == NULL) { +-		dev_dbg(&dev->core, "%s:%d: could not allocate XDR buffer\n", +-			__func__, __LINE__); +-		ret = -ENOMEM; +-		goto out_free_priv; +-	} +- +-	/* Put FIFO at begginning of XDR buffer */ +-	priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET); +-	priv->fifo_ptr = priv->fifo_base; +- +-	/* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */ +-	if (ps3_open_hv_device(dev)) { +-		dev_err(&dev->core, "%s:%d: ps3_open_hv_device failed\n", +-			__func__, __LINE__); +-		ret = -EAGAIN; +-		goto out_close_gpu; +-	} +- +-	/* Request memory */ +-	status = -1; +-	ddr_size = memparse(size, &rest); +-	if (*rest == '-') +-		ddr_size -= ps3fb_videomemory.size; +-	ddr_size = ALIGN(ddr_size, 1024*1024); +-	if (ddr_size <= 0) { +-		dev_err(&dev->core, "%s:%d: specified size is too small\n", +-			__func__, __LINE__); +-		ret = -EINVAL; +-		goto out_close_gpu; +-	} +- +-	while (ddr_size > 0) { +-		status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0, +-						 &priv->memory_handle, +-						 &ddr_lpar); +-		if (!status) +-			break; +-		ddr_size -= 1024*1024; +-	} +-	if (status || ddr_size <= 0) { +-		dev_err(&dev->core, "%s:%d: lv1_gpu_memory_allocate failed\n", +-			__func__, __LINE__); +-		ret = -ENOMEM; +-		goto out_free_xdr_buf; +-	} +- +-	/* Request context */ +-	status = lv1_gpu_context_allocate(priv->memory_handle, +-					  0, +-					  &priv->context_handle, +-					  &ctrl_lpar, +-					  &info_lpar, +-					  &reports_lpar, +-					  &reports_size); +-	if (status) { +-		dev_err(&dev->core, "%s:%d: lv1_gpu_context_allocate failed\n", +-			__func__, __LINE__); +-		ret = -ENOMEM; +-		goto out_free_memory; +-	} +- +-	/* Map XDR buffer to RSX */ +-	status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, +-				       ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)), +-				       XDR_BUF_SIZE, 0); +-	if (status) { +-		dev_err(&dev->core, "%s:%d: lv1_gpu_context_iomap failed\n", +-			__func__, __LINE__); +-		ret = -ENOMEM; +-		goto out_free_context; +-	} +- +-	priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE); +- +-	if (!priv->ddr_base) { +-		dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, +-			__LINE__); +-		ret = -ENOMEM; +-		goto out_free_context; +-	} +- +-	priv->ctrl = ioremap(ctrl_lpar, 64 * 1024); +-	if (!priv->ctrl) { +-		dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, +-			__LINE__); +-		ret = -ENOMEM; +-		goto out_unmap_vram; +-	} +- +-	priv->reports = ioremap(reports_lpar, reports_size); +-	if (!priv->reports) { +-		dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, +-			__LINE__); +-		ret = -ENOMEM; +-		goto out_unmap_ctrl; +-	} +- +-	mutex_lock(&ps3_gpu_mutex); +-	ps3vram_init_ring(&ps3vram_mtd); +-	mutex_unlock(&ps3_gpu_mutex); +- +-	ps3vram_mtd.name = "ps3vram"; +-	ps3vram_mtd.size = ddr_size; +-	ps3vram_mtd.flags = MTD_CAP_RAM; +-	ps3vram_mtd.erase = ps3vram_erase; +-	ps3vram_mtd.point = NULL; +-	ps3vram_mtd.unpoint = NULL; +-	ps3vram_mtd.read = ps3vram_read; +-	ps3vram_mtd.write = ps3vram_write; +-	ps3vram_mtd.owner = THIS_MODULE; +-	ps3vram_mtd.type = MTD_RAM; +-	ps3vram_mtd.erasesize = CACHE_PAGE_SIZE; +-	ps3vram_mtd.writesize = 1; +- +-	ps3vram_bind(&ps3vram_mtd); +- +-	mutex_lock(&ps3_gpu_mutex); +-	ret = ps3vram_wait_ring(&ps3vram_mtd, 100); +-	mutex_unlock(&ps3_gpu_mutex); +-	if (ret < 0) { +-		dev_err(&dev->core, "%s:%d: failed to initialize channels\n", +-			__func__, __LINE__); +-		ret = -ETIMEDOUT; +-		goto out_unmap_reports; +-	} +- +-	ps3vram_cache_init(&ps3vram_mtd); +- +-	if (add_mtd_device(&ps3vram_mtd)) { +-		dev_err(&dev->core, "%s:%d: add_mtd_device failed\n", +-			__func__, __LINE__); +-		ret = -EAGAIN; +-		goto out_cache_cleanup; +-	} +- +-	dev_info(&dev->core, "reserved %u MiB of gpu memory\n", +-		(unsigned int)(ddr_size / 1024 / 1024)); +- +-	return 0; +- +-out_cache_cleanup: +-	ps3vram_cache_cleanup(&ps3vram_mtd); +-out_unmap_reports: +-	iounmap(priv->reports); +-out_unmap_ctrl: +-	iounmap(priv->ctrl); +-out_unmap_vram: +-	iounmap(priv->ddr_base); +-out_free_context: +-	lv1_gpu_context_free(priv->context_handle); +-out_free_memory: +-	lv1_gpu_memory_free(priv->memory_handle); +-out_close_gpu: +-	ps3_close_hv_device(dev); +-out_free_xdr_buf: +-	free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); +-out_free_priv: +-	kfree(ps3vram_mtd.priv); +-	ps3vram_mtd.priv = NULL; +-out: +-	return ret; +-} +- +-static int ps3vram_shutdown(struct ps3_system_bus_device *dev) +-{ +-	struct ps3vram_priv *priv; +- +-	priv = ps3vram_mtd.priv; +- +-	del_mtd_device(&ps3vram_mtd); +-	ps3vram_cache_cleanup(&ps3vram_mtd); +-	iounmap(priv->reports); +-	iounmap(priv->ctrl); +-	iounmap(priv->ddr_base); +-	lv1_gpu_context_free(priv->context_handle); +-	lv1_gpu_memory_free(priv->memory_handle); +-	ps3_close_hv_device(dev); +-	free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); +-	kfree(priv); +-	return 0; +-} +- +-static struct ps3_system_bus_driver ps3vram_driver = { +-	.match_id	= PS3_MATCH_ID_GPU, +-	.match_sub_id	= PS3_MATCH_SUB_ID_GPU_RAMDISK, +-	.core.name	= DEVICE_NAME, +-	.core.owner	= THIS_MODULE, +-	.probe		= ps3vram_probe, +-	.remove		= ps3vram_shutdown, +-	.shutdown	= ps3vram_shutdown, +-}; +- +-static int __init ps3vram_init(void) +-{ +-	return ps3_system_bus_driver_register(&ps3vram_driver); +-} +- +-static void __exit ps3vram_exit(void) +-{ +-	ps3_system_bus_driver_unregister(&ps3vram_driver); +-} +- +-module_init(ps3vram_init); +-module_exit(ps3vram_exit); +- +-MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Jim Paris <jim@jtan.com>"); +-MODULE_DESCRIPTION("MTD driver for PS3 video RAM"); +-MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK); +--  +1.6.0.4 + | 
