LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [patch 00/11] ps3av/3fb patches for 2.6.25
From: Geert Uytterhoeven @ 2008-01-25 15:06 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton, linux-fbdev-devel
  Cc: linuxppc-dev, cbe-oss-dev

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1432 bytes --]

	Hi Tony, Andrew,

Hare are the ps3av/fb patches for 2.6.25:
  [1] ps3av: ps3av_get_scanmode() and ps3av_get_refresh_rate() are unused
  [2] ps3: Use symbolic names for video modes
  [3] ps3fb: Kill PS3FB_FULL_MODE_BIT
  [4] ps3fb: Inline macros that are used only once
  [5] ps3fb: Kill ps3fb_res[]
  [6] ps3fb: Make frame buffer offsets unsigned int
  [7] ps3fb: Add support for configurable black borders
  [8] ps3fb: Reorganize modedb handling
  [9] ps3fb: Round up video modes
  [10] ps3fb: Cleanup sweep
  [11] ps3fb: Fix modedb typos

Patches 1-9 have been sent for review on Mon, 26 Nov 2007. They haven't
changed in the mean time, except for rebasing and minor editing of patch
descriptions.
Patches 10-11 are new, but not very complex, and tested in ps3-linux.git since
a while.

Please apply for 2.6.25. Thanks a lot!

With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 01/11] ps3av: ps3av_get_scanmode() and ps3av_get_refresh_rate() are unused
From: Geert Uytterhoeven @ 2008-01-25 15:06 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton, linux-fbdev-devel
  Cc: Geert Uytterhoeven, linuxppc-dev, cbe-oss-dev
In-Reply-To: <20080125150623.202631389@vixen.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 4361 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3av: ps3av_get_scanmode() and ps3av_get_refresh_rate() are unused, so remove
them

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/ps3/ps3av.c         |   58 +++++++++-----------------------------------
 include/asm-powerpc/ps3av.h |    2 -
 2 files changed, 13 insertions(+), 47 deletions(-)

--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -78,23 +78,21 @@ static const struct avset_video_mode {
 	u32 aspect;
 	u32 x;
 	u32 y;
-	u32 interlace;
-	u32 freq;
 } video_mode_table[] = {
 	{     0, }, /* auto */
-	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480I,       A_N,  720,  480, 1, 60},
-	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480P,       A_N,  720,  480, 0, 60},
-	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_60HZ,  A_N, 1280,  720, 0, 60},
-	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_60HZ, A_W, 1920, 1080, 1, 60},
-	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_60HZ, A_W, 1920, 1080, 0, 60},
-	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576I,       A_N,  720,  576, 1, 50},
-	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576P,       A_N,  720,  576, 0, 50},
-	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_50HZ,  A_N, 1280,  720, 0, 50},
-	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_50HZ, A_W, 1920, 1080, 1, 50},
-	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_50HZ, A_W, 1920, 1080, 0, 50},
-	{  RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WXGA,       A_W, 1280,  768, 0, 60},
-	{  RGB8, XRGB, PS3AV_CMD_VIDEO_VID_SXGA,       A_N, 1280, 1024, 0, 60},
-	{  RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WUXGA,      A_W, 1920, 1200, 0, 60},
+	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480I,       A_N,  720,  480},
+	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480P,       A_N,  720,  480},
+	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_60HZ,  A_N, 1280,  720},
+	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_60HZ, A_W, 1920, 1080},
+	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_60HZ, A_W, 1920, 1080},
+	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576I,       A_N,  720,  576},
+	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576P,       A_N,  720,  576},
+	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_50HZ,  A_N, 1280,  720},
+	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_50HZ, A_W, 1920, 1080},
+	{YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_50HZ, A_W, 1920, 1080},
+	{  RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WXGA,       A_W, 1280,  768},
+	{  RGB8, XRGB, PS3AV_CMD_VIDEO_VID_SXGA,       A_N, 1280, 1024},
+	{  RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WUXGA,      A_W, 1920, 1200},
 };
 
 /* supported CIDs */
@@ -889,36 +887,6 @@ int ps3av_get_mode(void)
 
 EXPORT_SYMBOL_GPL(ps3av_get_mode);
 
-int ps3av_get_scanmode(int id)
-{
-	int size;
-
-	id = id & PS3AV_MODE_MASK;
-	size = ARRAY_SIZE(video_mode_table);
-	if (id > size - 1 || id < 0) {
-		printk(KERN_ERR "%s: invalid mode %d\n", __func__, id);
-		return -EINVAL;
-	}
-	return video_mode_table[id].interlace;
-}
-
-EXPORT_SYMBOL_GPL(ps3av_get_scanmode);
-
-int ps3av_get_refresh_rate(int id)
-{
-	int size;
-
-	id = id & PS3AV_MODE_MASK;
-	size = ARRAY_SIZE(video_mode_table);
-	if (id > size - 1 || id < 0) {
-		printk(KERN_ERR "%s: invalid mode %d\n", __func__, id);
-		return -EINVAL;
-	}
-	return video_mode_table[id].freq;
-}
-
-EXPORT_SYMBOL_GPL(ps3av_get_refresh_rate);
-
 /* get resolution by video_mode */
 int ps3av_video_mode2res(u32 id, u32 *xres, u32 *yres)
 {
--- a/include/asm-powerpc/ps3av.h
+++ b/include/asm-powerpc/ps3av.h
@@ -713,8 +713,6 @@ extern int ps3av_set_video_mode(u32);
 extern int ps3av_set_audio_mode(u32, u32, u32, u32, u32);
 extern int ps3av_get_auto_mode(void);
 extern int ps3av_get_mode(void);
-extern int ps3av_get_scanmode(int);
-extern int ps3av_get_refresh_rate(int);
 extern int ps3av_video_mode2res(u32, u32 *, u32 *);
 extern int ps3av_video_mute(int);
 extern int ps3av_audio_mute(int);

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 02/11] ps3: Use symbolic names for video modes
From: Geert Uytterhoeven @ 2008-01-25 15:06 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton, linux-fbdev-devel
  Cc: Geert Uytterhoeven, linuxppc-dev, cbe-oss-dev
In-Reply-To: <20080125150623.202631389@vixen.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 8019 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3: Use symbolic names for video modes

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/ps3/ps3av.c         |   39 ++++++++++++++++++++-------------------
 drivers/video/ps3fb.c       |   17 ++++++++++-------
 include/asm-powerpc/ps3av.h |   41 ++++++++++++++++++++++++++++++-----------
 3 files changed, 60 insertions(+), 37 deletions(-)

--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -542,7 +542,7 @@ static void ps3av_set_videomode_packet(u
 
 static void ps3av_set_videomode_cont(u32 id, u32 old_id)
 {
-	static int vesa = 0;
+	static int vesa;
 	int res;
 
 	/* video signal off */
@@ -552,9 +552,9 @@ static void ps3av_set_videomode_cont(u32
 	 * AV backend needs non-VESA mode setting at least one time
 	 * when VESA mode is used.
 	 */
-	if (vesa == 0 && (id & PS3AV_MODE_MASK) >= 11) {
+	if (vesa == 0 && (id & PS3AV_MODE_MASK) >= PS3AV_MODE_WXGA) {
 		/* vesa mode */
-		ps3av_set_videomode_packet(2);	/* 480P */
+		ps3av_set_videomode_packet(PS3AV_MODE_480P);
 	}
 	vesa = 1;
 
@@ -594,20 +594,21 @@ static const struct {
 	unsigned mask : 19;
 	unsigned id :  4;
 } ps3av_preferred_modes[] = {
-	{ .mask = PS3AV_RESBIT_WUXGA		<< SHIFT_VESA,	.id = 13 },
-	{ .mask = PS3AV_RESBIT_1920x1080P	<< SHIFT_60,	.id = 5 },
-	{ .mask = PS3AV_RESBIT_1920x1080P	<< SHIFT_50,	.id = 10 },
-	{ .mask = PS3AV_RESBIT_1920x1080I	<< SHIFT_60,	.id = 4 },
-	{ .mask = PS3AV_RESBIT_1920x1080I	<< SHIFT_50,	.id = 9 },
-	{ .mask = PS3AV_RESBIT_SXGA		<< SHIFT_VESA,	.id = 12 },
-	{ .mask = PS3AV_RESBIT_WXGA		<< SHIFT_VESA,	.id = 11 },
-	{ .mask = PS3AV_RESBIT_1280x720P	<< SHIFT_60,	.id = 3 },
-	{ .mask = PS3AV_RESBIT_1280x720P	<< SHIFT_50,	.id = 8 },
-	{ .mask = PS3AV_RESBIT_720x480P		<< SHIFT_60,	.id = 2 },
-	{ .mask = PS3AV_RESBIT_720x576P		<< SHIFT_50,	.id = 7 },
+	{ PS3AV_RESBIT_WUXGA      << SHIFT_VESA, PS3AV_MODE_WUXGA   },
+	{ PS3AV_RESBIT_1920x1080P << SHIFT_60,   PS3AV_MODE_1080P60 },
+	{ PS3AV_RESBIT_1920x1080P << SHIFT_50,   PS3AV_MODE_1080P50 },
+	{ PS3AV_RESBIT_1920x1080I << SHIFT_60,   PS3AV_MODE_1080I60 },
+	{ PS3AV_RESBIT_1920x1080I << SHIFT_50,   PS3AV_MODE_1080I50 },
+	{ PS3AV_RESBIT_SXGA       << SHIFT_VESA, PS3AV_MODE_SXGA    },
+	{ PS3AV_RESBIT_WXGA       << SHIFT_VESA, PS3AV_MODE_WXGA    },
+	{ PS3AV_RESBIT_1280x720P  << SHIFT_60,   PS3AV_MODE_720P60  },
+	{ PS3AV_RESBIT_1280x720P  << SHIFT_50,   PS3AV_MODE_720P50  },
+	{ PS3AV_RESBIT_720x480P   << SHIFT_60,   PS3AV_MODE_480P    },
+	{ PS3AV_RESBIT_720x576P   << SHIFT_50,   PS3AV_MODE_576P    },
 };
 
-static int ps3av_resbit2id(u32 res_50, u32 res_60, u32 res_vesa)
+static enum ps3av_mode_num ps3av_resbit2id(u32 res_50, u32 res_60,
+					   u32 res_vesa)
 {
 	unsigned int i;
 	u32 res_all;
@@ -636,9 +637,9 @@ static int ps3av_resbit2id(u32 res_50, u
 	return 0;
 }
 
-static int ps3av_hdmi_get_id(struct ps3av_info_monitor *info)
+static enum ps3av_mode_num ps3av_hdmi_get_id(struct ps3av_info_monitor *info)
 {
-	int id;
+	enum ps3av_mode_num id;
 
 	if (safe_mode)
 		return PS3AV_DEFAULT_HDMI_MODE_ID_REG_60;
@@ -852,7 +853,7 @@ int ps3av_set_video_mode(u32 id)
 
 	/* auto mode */
 	option = id & ~PS3AV_MODE_MASK;
-	if ((id & PS3AV_MODE_MASK) == 0) {
+	if ((id & PS3AV_MODE_MASK) == PS3AV_MODE_AUTO) {
 		id = ps3av_auto_videomode(&ps3av->av_hw_conf);
 		if (id < 1) {
 			printk(KERN_ERR "%s: invalid id :%d\n", __func__, id);
@@ -958,7 +959,7 @@ static int ps3av_probe(struct ps3_system
 		return -ENOMEM;
 
 	mutex_init(&ps3av->mutex);
-	ps3av->ps3av_mode = 0;
+	ps3av->ps3av_mode = PS3AV_MODE_AUTO;
 	ps3av->dev = dev;
 
 	INIT_WORK(&ps3av->work, ps3avd);
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -338,7 +338,7 @@ static int ps3fb_get_res_table(u32 xres,
 static unsigned int ps3fb_find_mode(const struct fb_var_screeninfo *var,
 				    u32 *ddr_line_length, u32 *xdr_line_length)
 {
-	unsigned int i, mode;
+	unsigned int i, fi, mode;
 
 	for (i = 0; i < ARRAY_SIZE(ps3fb_modedb); i++)
 		if (var->xres == ps3fb_modedb[i].xres &&
@@ -359,7 +359,8 @@ static unsigned int ps3fb_find_mode(cons
 
 found:
 	/* Cropped broadcast modes use the full line length */
-	*ddr_line_length = ps3fb_modedb[i < 10 ? i + 13 : i].xres * BPP;
+	fi = i < PS3AV_MODE_1080P50 ? i + PS3AV_MODE_WUXGA : i;
+	*ddr_line_length = ps3fb_modedb[fi].xres * BPP;
 
 	if (ps3_compare_firmware_version(1, 9, 0) >= 0) {
 		*xdr_line_length = GPU_ALIGN_UP(max(var->xres,
@@ -370,7 +371,9 @@ found:
 		*xdr_line_length = *ddr_line_length;
 
 	/* Full broadcast modes have the full mode bit set */
-	mode = i > 12 ? (i - 12) | PS3FB_FULL_MODE_BIT : i + 1;
+	mode = i+1;
+	if (mode > PS3AV_MODE_WUXGA)
+		mode = (mode - PS3AV_MODE_WUXGA) | PS3FB_FULL_MODE_BIT;
 
 	pr_debug("ps3fb_find_mode: mode %u\n", mode);
 
@@ -382,14 +385,14 @@ static const struct fb_videomode *ps3fb_
 	u32 mode = id & PS3AV_MODE_MASK;
 	u32 flags;
 
-	if (mode < 1 || mode > 13)
+	if (mode < PS3AV_MODE_480I || mode > PS3AV_MODE_WUXGA)
 		return NULL;
 
 	flags = id & ~PS3AV_MODE_MASK;
 
-	if (mode <= 10 && flags & PS3FB_FULL_MODE_BIT) {
+	if (mode <= PS3AV_MODE_1080P50 && flags & PS3FB_FULL_MODE_BIT) {
 		/* Full broadcast mode */
-		return &ps3fb_modedb[mode + 12];
+		return &ps3fb_modedb[mode + PS3AV_MODE_WUXGA - 1];
 	}
 
 	return &ps3fb_modedb[mode - 1];
@@ -1080,7 +1083,7 @@ static int __devinit ps3fb_probe(struct 
 
 	if (!ps3fb_mode)
 		ps3fb_mode = ps3av_get_mode();
-	dev_dbg(&dev->core, "ps3av_mode:%d\n", ps3fb_mode);
+	dev_dbg(&dev->core, "ps3fb_mode: %d\n", ps3fb_mode);
 
 	if (ps3fb_mode > 0 &&
 	    !ps3av_video_mode2res(ps3fb_mode, &xres, &yres)) {
--- a/include/asm-powerpc/ps3av.h
+++ b/include/asm-powerpc/ps3av.h
@@ -310,19 +310,25 @@
 #define PS3AV_MONITOR_TYPE_HDMI			1	/* HDMI */
 #define PS3AV_MONITOR_TYPE_DVI			2	/* DVI */
 
-#define PS3AV_DEFAULT_HDMI_MODE_ID_REG_60	2	/* 480p */
-#define PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_60	1	/* 480i */
-#define PS3AV_DEFAULT_HDMI_MODE_ID_REG_50	7	/* 576p */
-#define PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50	6	/* 576i */
-
-#define PS3AV_REGION_60				0x01
-#define PS3AV_REGION_50				0x02
-#define PS3AV_REGION_RGB			0x10
-
-#define get_status(buf)				(((__u32 *)buf)[2])
-#define PS3AV_HDR_SIZE				4	/* version + size */
 
 /* for video mode */
+enum ps3av_mode_num {
+	PS3AV_MODE_AUTO				= 0,
+	PS3AV_MODE_480I				= 1,
+	PS3AV_MODE_480P				= 2,
+	PS3AV_MODE_720P60			= 3,
+	PS3AV_MODE_1080I60			= 4,
+	PS3AV_MODE_1080P60			= 5,
+	PS3AV_MODE_576I				= 6,
+	PS3AV_MODE_576P				= 7,
+	PS3AV_MODE_720P50			= 8,
+	PS3AV_MODE_1080I50			= 9,
+	PS3AV_MODE_1080P50			= 10,
+	PS3AV_MODE_WXGA				= 11,
+	PS3AV_MODE_SXGA				= 12,
+	PS3AV_MODE_WUXGA			= 13,
+};
+
 #define PS3AV_MODE_MASK				0x000F
 #define PS3AV_MODE_HDCP_OFF			0x1000	/* Retail PS3 product doesn't support this */
 #define PS3AV_MODE_DITHER			0x0800
@@ -333,6 +339,19 @@
 #define PS3AV_MODE_RGB				0x0020
 
 
+#define PS3AV_DEFAULT_HDMI_MODE_ID_REG_60	PS3AV_MODE_480P
+#define PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_60	PS3AV_MODE_480I
+#define PS3AV_DEFAULT_HDMI_MODE_ID_REG_50	PS3AV_MODE_576P
+#define PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50	PS3AV_MODE_576I
+
+#define PS3AV_REGION_60				0x01
+#define PS3AV_REGION_50				0x02
+#define PS3AV_REGION_RGB			0x10
+
+#define get_status(buf)				(((__u32 *)buf)[2])
+#define PS3AV_HDR_SIZE				4	/* version + size */
+
+
 /** command packet structure **/
 struct ps3av_send_hdr {
 	u16 version;

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 03/11] ps3fb: Kill PS3FB_FULL_MODE_BIT
From: Geert Uytterhoeven @ 2008-01-25 15:06 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton, linux-fbdev-devel
  Cc: Geert Uytterhoeven, linuxppc-dev, cbe-oss-dev
In-Reply-To: <20080125150623.202631389@vixen.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 2170 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3fb: Kill PS3FB_FULL_MODE_BIT, use PS3AV_MODE_FULL instead

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/ps3fb.c |    8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -57,8 +57,6 @@
 #define GPU_ALIGN_UP(x)				_ALIGN_UP((x), 64)
 #define GPU_MAX_LINE_LENGTH			(65536 - 64)
 
-#define PS3FB_FULL_MODE_BIT			0x80
-
 #define GPU_INTR_STATUS_VSYNC_0			0	/* vsync on head A */
 #define GPU_INTR_STATUS_VSYNC_1			1	/* vsync on head B */
 #define GPU_INTR_STATUS_FLIP_0			3	/* flip head A */
@@ -310,7 +308,7 @@ static int ps3fb_get_res_table(u32 xres,
 	unsigned int i;
 	u32 x, y, f;
 
-	full_mode = (mode & PS3FB_FULL_MODE_BIT) ? PS3FB_RES_FULL : 0;
+	full_mode = (mode & PS3AV_MODE_FULL) ? PS3FB_RES_FULL : 0;
 	for (i = 0;; i++) {
 		x = ps3fb_res[i].xres;
 		y = ps3fb_res[i].yres;
@@ -373,7 +371,7 @@ found:
 	/* Full broadcast modes have the full mode bit set */
 	mode = i+1;
 	if (mode > PS3AV_MODE_WUXGA)
-		mode = (mode - PS3AV_MODE_WUXGA) | PS3FB_FULL_MODE_BIT;
+		mode = (mode - PS3AV_MODE_WUXGA) | PS3AV_MODE_FULL;
 
 	pr_debug("ps3fb_find_mode: mode %u\n", mode);
 
@@ -390,7 +388,7 @@ static const struct fb_videomode *ps3fb_
 
 	flags = id & ~PS3AV_MODE_MASK;
 
-	if (mode <= PS3AV_MODE_1080P50 && flags & PS3FB_FULL_MODE_BIT) {
+	if (mode <= PS3AV_MODE_1080P50 && flags & PS3AV_MODE_FULL) {
 		/* Full broadcast mode */
 		return &ps3fb_modedb[mode + PS3AV_MODE_WUXGA - 1];
 	}

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 04/11] ps3fb: Inline macros that are used only once
From: Geert Uytterhoeven @ 2008-01-25 15:06 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton, linux-fbdev-devel
  Cc: Geert Uytterhoeven, linuxppc-dev, cbe-oss-dev
In-Reply-To: <20080125150623.202631389@vixen.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 2028 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3fb: inline the X_OFF(), Y_OFF(), WIDTH(), HEIGHT(), and VP_OFF() macros,
as they're used in one place only

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/ps3fb.c |   12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -287,15 +287,8 @@ static const struct fb_videomode ps3fb_m
 #define HEAD_A
 #define HEAD_B
 
-#define X_OFF(i)	(ps3fb_res[i].xoff)	/* left/right margin (pixel) */
-#define Y_OFF(i)	(ps3fb_res[i].yoff)	/* top/bottom margin (pixel) */
-#define WIDTH(i)	(ps3fb_res[i].xres)	/* width of FB */
-#define HEIGHT(i)	(ps3fb_res[i].yres)	/* height of FB */
 #define BPP		4			/* number of bytes per pixel */
 
-/* Start of the virtual frame buffer (relative to fullscreen ) */
-#define VP_OFF(i)	((WIDTH(i) * Y_OFF(i) + X_OFF(i)) * BPP)
-
 
 static int ps3fb_mode;
 module_param(ps3fb_mode, int, 0);
@@ -611,7 +604,10 @@ static int ps3fb_set_par(struct fb_info 
 
 	par->width = info->var.xres;
 	par->height = info->var.yres;
-	offset = VP_OFF(i);
+
+	/* Start of the virtual frame buffer (relative to fullscreen) */
+	offset = ps3fb_res[i].yoff * ddr_line_length + ps3fb_res[i].xoff * BPP;
+
 	par->fb_offset = GPU_ALIGN_UP(offset);
 	par->full_offset = par->fb_offset - offset;
 	par->pan_offset = info->var.yoffset * xdr_line_length +

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 05/11] ps3fb: Kill ps3fb_res
From: Geert Uytterhoeven @ 2008-01-25 15:06 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton, linux-fbdev-devel
  Cc: Geert Uytterhoeven, linuxppc-dev, cbe-oss-dev
In-Reply-To: <20080125150623.202631389@vixen.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 7875 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3fb: kill ps3fb_res[], as all information it contains can be obtained in
some other way.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/ps3fb.c |  108 ++++++++++----------------------------------------
 1 file changed, 22 insertions(+), 86 deletions(-)

--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -134,42 +134,17 @@ static struct ps3fb_priv ps3fb;
 struct ps3fb_par {
 	u32 pseudo_palette[16];
 	int mode_id, new_mode_id;
-	int res_index;
 	unsigned int num_frames;	/* num of frame buffers */
 	unsigned int width;
 	unsigned int height;
+	unsigned int ddr_line_length;
+	unsigned int ddr_frame_size;
+	unsigned int xdr_frame_size;
 	unsigned long full_offset;	/* start of fullscreen DDR fb */
 	unsigned long fb_offset;	/* start of actual DDR fb */
 	unsigned long pan_offset;
 };
 
-struct ps3fb_res_table {
-	u32 xres;
-	u32 yres;
-	u32 xoff;
-	u32 yoff;
-	u32 type;
-};
-#define PS3FB_RES_FULL 1
-static const struct ps3fb_res_table ps3fb_res[] = {
-	/* res_x,y   margin_x,y  full */
-	{  720,  480,  72,  48 , 0},
-	{  720,  576,  72,  58 , 0},
-	{ 1280,  720,  78,  38 , 0},
-	{ 1920, 1080, 116,  58 , 0},
-	/* full mode */
-	{  720,  480,   0,   0 , PS3FB_RES_FULL},
-	{  720,  576,   0,   0 , PS3FB_RES_FULL},
-	{ 1280,  720,   0,   0 , PS3FB_RES_FULL},
-	{ 1920, 1080,   0,   0 , PS3FB_RES_FULL},
-	/* vesa: normally full mode */
-	{ 1280,  768,   0,   0 , 0},
-	{ 1280, 1024,   0,   0 , 0},
-	{ 1920, 1200,   0,   0 , 0},
-	{    0,    0,   0,   0 , 0} };
-
-/* default resolution */
-#define GPU_RES_INDEX	0		/* 720 x 480 */
 
 static const struct fb_videomode ps3fb_modedb[] = {
     /* 60 Hz broadcast modes (modes "1" to "5") */
@@ -295,37 +270,6 @@ module_param(ps3fb_mode, int, 0);
 
 static char *mode_option __devinitdata;
 
-static int ps3fb_get_res_table(u32 xres, u32 yres, int mode)
-{
-	int full_mode;
-	unsigned int i;
-	u32 x, y, f;
-
-	full_mode = (mode & PS3AV_MODE_FULL) ? PS3FB_RES_FULL : 0;
-	for (i = 0;; i++) {
-		x = ps3fb_res[i].xres;
-		y = ps3fb_res[i].yres;
-		f = ps3fb_res[i].type;
-
-		if (!x) {
-			pr_debug("ERROR: ps3fb_get_res_table()\n");
-			return -1;
-		}
-
-		if (full_mode == PS3FB_RES_FULL && f != PS3FB_RES_FULL)
-			continue;
-
-		if (x == xres && (yres == 0 || y == yres))
-			break;
-
-		x = x - 2 * ps3fb_res[i].xoff;
-		y = y - 2 * ps3fb_res[i].yoff;
-		if (x == xres && (yres == 0 || y == yres))
-			break;
-	}
-	return i;
-}
-
 static unsigned int ps3fb_find_mode(const struct fb_var_screeninfo *var,
 				    u32 *ddr_line_length, u32 *xdr_line_length)
 {
@@ -433,8 +377,7 @@ static void ps3fb_sync_image(struct devi
 static int ps3fb_sync(struct fb_info *info, u32 frame)
 {
 	struct ps3fb_par *par = info->par;
-	int i, error = 0;
-	u32 ddr_line_length, xdr_line_length;
+	int error = 0;
 	u64 ddr_base, xdr_base;
 
 	if (frame > par->num_frames - 1) {
@@ -444,16 +387,13 @@ static int ps3fb_sync(struct fb_info *in
 		goto out;
 	}
 
-	i = par->res_index;
-	xdr_line_length = info->fix.line_length;
-	ddr_line_length = ps3fb_res[i].xres * BPP;
-	xdr_base = frame * info->var.yres_virtual * xdr_line_length;
-	ddr_base = frame * ps3fb_res[i].yres * ddr_line_length;
+	xdr_base = frame * par->xdr_frame_size;
+	ddr_base = frame * par->ddr_frame_size;
 
 	ps3fb_sync_image(info->device, ddr_base + par->full_offset,
 			 ddr_base + par->fb_offset, xdr_base + par->pan_offset,
-			 par->width, par->height, ddr_line_length,
-			 xdr_line_length);
+			 par->width, par->height, par->ddr_line_length,
+			 info->fix.line_length);
 
 out:
 	return error;
@@ -572,8 +512,9 @@ static int ps3fb_set_par(struct fb_info 
 {
 	struct ps3fb_par *par = info->par;
 	unsigned int mode, ddr_line_length, xdr_line_length, lines, maxlines;
-	int i;
+	unsigned int ddr_xoff, ddr_yoff;
 	unsigned long offset;
+	const struct fb_videomode *vmode;
 	u64 dst;
 
 	dev_dbg(info->device, "xres:%d xv:%d yres:%d yv:%d clock:%d\n",
@@ -584,8 +525,7 @@ static int ps3fb_set_par(struct fb_info 
 	if (!mode)
 		return -EINVAL;
 
-	i = ps3fb_get_res_table(info->var.xres, info->var.yres, mode);
-	par->res_index = i;
+	vmode = ps3fb_default_mode(mode | PS3AV_MODE_FULL);
 
 	info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
 	info->fix.smem_len = ps3fb.xdr_size;
@@ -595,9 +535,12 @@ static int ps3fb_set_par(struct fb_info 
 
 	info->screen_base = (char __iomem *)ps3fb.xdr_ea;
 
+	par->ddr_line_length = ddr_line_length;
+	par->ddr_frame_size = vmode->yres * ddr_line_length;
+	par->xdr_frame_size = info->var.yres_virtual * xdr_line_length;
+
 	par->num_frames = ps3fb.xdr_size /
-			  max(ps3fb_res[i].yres * ddr_line_length,
-			      info->var.yres_virtual * xdr_line_length);
+			  max(par->ddr_frame_size, par->xdr_frame_size);
 
 	/* Keep the special bits we cannot set using fb_var_screeninfo */
 	par->new_mode_id = (par->new_mode_id & ~PS3AV_MODE_MASK) | mode;
@@ -606,7 +549,9 @@ static int ps3fb_set_par(struct fb_info 
 	par->height = info->var.yres;
 
 	/* Start of the virtual frame buffer (relative to fullscreen) */
-	offset = ps3fb_res[i].yoff * ddr_line_length + ps3fb_res[i].xoff * BPP;
+	ddr_xoff = info->var.left_margin - vmode->left_margin;
+	ddr_yoff = info->var.upper_margin - vmode->upper_margin;
+	offset = ddr_yoff * ddr_line_length + ddr_xoff * BPP;
 
 	par->fb_offset = GPU_ALIGN_UP(offset);
 	par->full_offset = par->fb_offset - offset;
@@ -625,13 +570,13 @@ static int ps3fb_set_par(struct fb_info 
 	memset(ps3fb.xdr_ea, 0, ps3fb.xdr_size);
 
 	/* Clear DDR frame buffer memory */
-	lines = ps3fb_res[i].yres * par->num_frames;
+	lines = vmode->yres * par->num_frames;
 	if (par->full_offset)
 		lines++;
 	maxlines = ps3fb.xdr_size / ddr_line_length;
 	for (dst = 0; lines; dst += maxlines * ddr_line_length) {
 		unsigned int l = min(lines, maxlines);
-		ps3fb_sync_image(info->device, 0, dst, 0, ps3fb_res[i].xres, l,
+		ps3fb_sync_image(info->device, 0, dst, 0, vmode->xres, l,
 				 ddr_line_length, ddr_line_length);
 		lines -= l;
 	}
@@ -1052,14 +997,13 @@ static int __devinit ps3fb_probe(struct 
 	struct fb_info *info;
 	struct ps3fb_par *par;
 	int retval = -ENOMEM;
-	u32 xres, yres;
 	u64 ddr_lpar = 0;
 	u64 lpar_dma_control = 0;
 	u64 lpar_driver_info = 0;
 	u64 lpar_reports = 0;
 	u64 lpar_reports_size = 0;
 	u64 xdr_lpar;
-	int status, res_index;
+	int status;
 	struct task_struct *task;
 	unsigned long max_ps3fb_size;
 
@@ -1079,13 +1023,6 @@ static int __devinit ps3fb_probe(struct 
 		ps3fb_mode = ps3av_get_mode();
 	dev_dbg(&dev->core, "ps3fb_mode: %d\n", ps3fb_mode);
 
-	if (ps3fb_mode > 0 &&
-	    !ps3av_video_mode2res(ps3fb_mode, &xres, &yres)) {
-		res_index = ps3fb_get_res_table(xres, yres, ps3fb_mode);
-		dev_dbg(&dev->core, "res_index:%d\n", res_index);
-	} else
-		res_index = GPU_RES_INDEX;
-
 	atomic_set(&ps3fb.f_count, -1);	/* fbcon opens ps3fb */
 	atomic_set(&ps3fb.ext_flip, 0);	/* for flip with vsync */
 	init_waitqueue_head(&ps3fb.wait_vsync);
@@ -1158,7 +1095,6 @@ static int __devinit ps3fb_probe(struct 
 	par = info->par;
 	par->mode_id = ~ps3fb_mode;	/* != ps3fb_mode, to trigger change */
 	par->new_mode_id = ps3fb_mode;
-	par->res_index = res_index;
 	par->num_frames = 1;
 
 	info->screen_base = (char __iomem *)ps3fb.xdr_ea;

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 06/11] ps3fb: Make frame buffer offsets unsigned int
From: Geert Uytterhoeven @ 2008-01-25 15:06 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton, linux-fbdev-devel
  Cc: Geert Uytterhoeven, linuxppc-dev, cbe-oss-dev
In-Reply-To: <20080125150623.202631389@vixen.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1730 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3fb: Frame buffer offsets don't have to be `unsigned long', `unsigned int' is
sufficient

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/ps3fb.c |    9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -140,9 +140,9 @@ struct ps3fb_par {
 	unsigned int ddr_line_length;
 	unsigned int ddr_frame_size;
 	unsigned int xdr_frame_size;
-	unsigned long full_offset;	/* start of fullscreen DDR fb */
-	unsigned long fb_offset;	/* start of actual DDR fb */
-	unsigned long pan_offset;
+	unsigned int full_offset;	/* start of fullscreen DDR fb */
+	unsigned int fb_offset;		/* start of actual DDR fb */
+	unsigned int pan_offset;
 };
 
 
@@ -512,8 +512,7 @@ static int ps3fb_set_par(struct fb_info 
 {
 	struct ps3fb_par *par = info->par;
 	unsigned int mode, ddr_line_length, xdr_line_length, lines, maxlines;
-	unsigned int ddr_xoff, ddr_yoff;
-	unsigned long offset;
+	unsigned int ddr_xoff, ddr_yoff, offset;
 	const struct fb_videomode *vmode;
 	u64 dst;
 

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 07/11] ps3fb: Add support for configurable black borders
From: Geert Uytterhoeven @ 2008-01-25 15:06 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton, linux-fbdev-devel
  Cc: Geert Uytterhoeven, linuxppc-dev, cbe-oss-dev
In-Reply-To: <20080125150623.202631389@vixen.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 4173 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3fb: Allow all video modes where the visible resolution plus the black
borders matches a native resolution

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
--
 drivers/video/ps3fb.c |   69 +++++++++++++++++++++++++++++++++++---------------
 1 file changed, 49 insertions(+), 20 deletions(-)

--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -270,32 +270,57 @@ module_param(ps3fb_mode, int, 0);
 
 static char *mode_option __devinitdata;
 
-static unsigned int ps3fb_find_mode(const struct fb_var_screeninfo *var,
+static int ps3fb_cmp_mode(const struct fb_videomode *vmode,
+			  const struct fb_var_screeninfo *var)
+{
+	/* resolution + black border must match a native resolution */
+	if (vmode->left_margin + vmode->xres + vmode->right_margin !=
+	    var->left_margin + var->xres + var->right_margin ||
+	    vmode->upper_margin + vmode->yres + vmode->lower_margin !=
+	    var->upper_margin + var->yres + var->lower_margin)
+		return -1;
+
+	/* minimum limits for margins */
+	if (vmode->left_margin > var->left_margin ||
+	    vmode->right_margin > var->right_margin ||
+	    vmode->upper_margin > var->upper_margin ||
+	    vmode->lower_margin > var->lower_margin)
+		return -1;
+
+	/* these fields must match exactly */
+	if (vmode->pixclock != var->pixclock ||
+	    vmode->hsync_len != var->hsync_len ||
+	    vmode->vsync_len != var->vsync_len ||
+	    vmode->sync != var->sync ||
+	    vmode->vmode != (var->vmode & FB_VMODE_MASK))
+		return -1;
+
+	return 0;
+}
+
+static unsigned int ps3fb_find_mode(struct fb_var_screeninfo *var,
 				    u32 *ddr_line_length, u32 *xdr_line_length)
 {
-	unsigned int i, fi, mode;
+	unsigned int i, mode;
 
-	for (i = 0; i < ARRAY_SIZE(ps3fb_modedb); i++)
-		if (var->xres == ps3fb_modedb[i].xres &&
-		    var->yres == ps3fb_modedb[i].yres &&
-		    var->pixclock == ps3fb_modedb[i].pixclock &&
-		    var->hsync_len == ps3fb_modedb[i].hsync_len &&
-		    var->vsync_len == ps3fb_modedb[i].vsync_len &&
-		    var->left_margin == ps3fb_modedb[i].left_margin &&
-		    var->right_margin == ps3fb_modedb[i].right_margin &&
-		    var->upper_margin == ps3fb_modedb[i].upper_margin &&
-		    var->lower_margin == ps3fb_modedb[i].lower_margin &&
-		    var->sync == ps3fb_modedb[i].sync &&
-		    (var->vmode & FB_VMODE_MASK) == ps3fb_modedb[i].vmode)
+	for (i = PS3AV_MODE_1080P50; i < ARRAY_SIZE(ps3fb_modedb); i++)
+		if (!ps3fb_cmp_mode(&ps3fb_modedb[i], var))
 			goto found;
 
 	pr_debug("ps3fb_find_mode: mode not found\n");
 	return 0;
 
 found:
-	/* Cropped broadcast modes use the full line length */
-	fi = i < PS3AV_MODE_1080P50 ? i + PS3AV_MODE_WUXGA : i;
-	*ddr_line_length = ps3fb_modedb[fi].xres * BPP;
+	*ddr_line_length = ps3fb_modedb[i].xres * BPP;
+
+	if (!var->xres) {
+		var->xres = 1;
+		var->right_margin--;
+	}
+	if (!var->yres) {
+		var->yres = 1;
+		var->lower_margin--;
+	}
 
 	if (ps3_compare_firmware_version(1, 9, 0) >= 0) {
 		*xdr_line_length = GPU_ALIGN_UP(max(var->xres,
@@ -305,10 +330,14 @@ found:
 	} else
 		*xdr_line_length = *ddr_line_length;
 
-	/* Full broadcast modes have the full mode bit set */
 	mode = i+1;
-	if (mode > PS3AV_MODE_WUXGA)
-		mode = (mode - PS3AV_MODE_WUXGA) | PS3AV_MODE_FULL;
+	if (mode > PS3AV_MODE_WUXGA) {
+		mode -= PS3AV_MODE_WUXGA;
+		/* Full broadcast modes have the full mode bit set */
+		if (ps3fb_modedb[i].xres == var->xres &&
+		    ps3fb_modedb[i].yres == var->yres)
+			mode |= PS3AV_MODE_FULL;
+	}
 
 	pr_debug("ps3fb_find_mode: mode %u\n", mode);
 

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 08/11] ps3fb: Reorganize modedb handling
From: Geert Uytterhoeven @ 2008-01-25 15:06 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton, linux-fbdev-devel
  Cc: Geert Uytterhoeven, linuxppc-dev, cbe-oss-dev
In-Reply-To: <20080125150623.202631389@vixen.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 6596 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3fb: Reorganize modedb handling:
  - Reorder the video modes in ps3fb_modedb, for easier indexing using
    PS3AV_MODE_* numbers,
  - Introduce ps3fb_native_vmode(), to convert from native (PS3AV_MODE_*) mode
    numbers to struct fb_videomode *,
  - Rename and move ps3fb_default_mode() to ps3fb_vmode().

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/ps3fb.c |  116 +++++++++++++++++++++++++-------------------------
 1 file changed, 60 insertions(+), 56 deletions(-)

--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -146,6 +146,8 @@ struct ps3fb_par {
 };
 
 
+#define FIRST_NATIVE_MODE_INDEX	10
+
 static const struct fb_videomode ps3fb_modedb[] = {
     /* 60 Hz broadcast modes (modes "1" to "5") */
     {
@@ -193,24 +195,7 @@ static const struct fb_videomode ps3fb_m
         FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
     },
 
-    /* VESA modes (modes "11" to "13") */
-    {
-	/* WXGA */
-	"wxga", 60, 1280, 768, 12924, 160, 24, 29, 3, 136, 6,
-	0, FB_VMODE_NONINTERLACED,
-	FB_MODE_IS_VESA
-    }, {
-	/* SXGA */
-	"sxga", 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
-	FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED,
-	FB_MODE_IS_VESA
-    }, {
-	/* WUXGA */
-	"wuxga", 60, 1920, 1200, 6494, 80, 48, 26, 3, 32, 6,
-	FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED,
-	FB_MODE_IS_VESA
-    },
-
+    [FIRST_NATIVE_MODE_INDEX] =
     /* 60 Hz broadcast modes (full resolution versions of modes "1" to "5") */
     {
 	/* 480if */
@@ -255,6 +240,24 @@ static const struct fb_videomode ps3fb_m
 	/* 1080pf */
 	"1080pf", 50, 1920, 1080, 6734, 148, 484, 36, 4, 88, 5,
 	FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
+    },
+
+    /* VESA modes (modes "11" to "13") */
+    {
+	/* WXGA */
+	"wxga", 60, 1280, 768, 12924, 160, 24, 29, 3, 136, 6,
+	0, FB_VMODE_NONINTERLACED,
+	FB_MODE_IS_VESA
+    }, {
+	/* SXGA */
+	"sxga", 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
+	FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED,
+	FB_MODE_IS_VESA
+    }, {
+	/* WUXGA */
+	"wuxga", 60, 1920, 1200, 6494, 80, 48, 26, 3, 32, 6,
+	FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED,
+	FB_MODE_IS_VESA
     }
 };
 
@@ -298,20 +301,43 @@ static int ps3fb_cmp_mode(const struct f
 	return 0;
 }
 
+static const struct fb_videomode *ps3fb_native_vmode(enum ps3av_mode_num id)
+{
+	return &ps3fb_modedb[FIRST_NATIVE_MODE_INDEX + id - 1];
+}
+
+static const struct fb_videomode *ps3fb_vmode(int id)
+{
+	u32 mode = id & PS3AV_MODE_MASK;
+
+	if (mode < PS3AV_MODE_480I || mode > PS3AV_MODE_WUXGA)
+		return NULL;
+
+	if (mode <= PS3AV_MODE_1080P50 && !(id & PS3AV_MODE_FULL)) {
+		/* Non-fullscreen broadcast mode */
+		return &ps3fb_modedb[mode - 1];
+	}
+
+	return ps3fb_native_vmode(mode);
+}
+
 static unsigned int ps3fb_find_mode(struct fb_var_screeninfo *var,
 				    u32 *ddr_line_length, u32 *xdr_line_length)
 {
-	unsigned int i, mode;
+	unsigned int id;
+	const struct fb_videomode *vmode;
 
-	for (i = PS3AV_MODE_1080P50; i < ARRAY_SIZE(ps3fb_modedb); i++)
-		if (!ps3fb_cmp_mode(&ps3fb_modedb[i], var))
+	for (id = PS3AV_MODE_480I; id <= PS3AV_MODE_WUXGA; id++) {
+		vmode = ps3fb_native_vmode(id);
+		if (!ps3fb_cmp_mode(vmode, var))
 			goto found;
+	}
 
-	pr_debug("ps3fb_find_mode: mode not found\n");
+	pr_debug("%s: mode not found\n", __func__);
 	return 0;
 
 found:
-	*ddr_line_length = ps3fb_modedb[i].xres * BPP;
+	*ddr_line_length = vmode->xres * BPP;
 
 	if (!var->xres) {
 		var->xres = 1;
@@ -330,36 +356,14 @@ found:
 	} else
 		*xdr_line_length = *ddr_line_length;
 
-	mode = i+1;
-	if (mode > PS3AV_MODE_WUXGA) {
-		mode -= PS3AV_MODE_WUXGA;
+	if (vmode->sync & FB_SYNC_BROADCAST) {
 		/* Full broadcast modes have the full mode bit set */
-		if (ps3fb_modedb[i].xres == var->xres &&
-		    ps3fb_modedb[i].yres == var->yres)
-			mode |= PS3AV_MODE_FULL;
-	}
-
-	pr_debug("ps3fb_find_mode: mode %u\n", mode);
-
-	return mode;
-}
-
-static const struct fb_videomode *ps3fb_default_mode(int id)
-{
-	u32 mode = id & PS3AV_MODE_MASK;
-	u32 flags;
-
-	if (mode < PS3AV_MODE_480I || mode > PS3AV_MODE_WUXGA)
-		return NULL;
-
-	flags = id & ~PS3AV_MODE_MASK;
-
-	if (mode <= PS3AV_MODE_1080P50 && flags & PS3AV_MODE_FULL) {
-		/* Full broadcast mode */
-		return &ps3fb_modedb[mode + PS3AV_MODE_WUXGA - 1];
+		if (vmode->xres == var->xres && vmode->yres == var->yres)
+			id |= PS3AV_MODE_FULL;
 	}
 
-	return &ps3fb_modedb[mode - 1];
+	pr_debug("%s: mode %u\n", __func__, id);
+	return id;
 }
 
 static void ps3fb_sync_image(struct device *dev, u64 frame_offset,
@@ -553,7 +557,7 @@ static int ps3fb_set_par(struct fb_info 
 	if (!mode)
 		return -EINVAL;
 
-	vmode = ps3fb_default_mode(mode | PS3AV_MODE_FULL);
+	vmode = ps3fb_native_vmode(mode & PS3AV_MODE_MASK);
 
 	info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
 	info->fix.smem_len = ps3fb.xdr_size;
@@ -767,7 +771,7 @@ static int ps3fb_ioctl(struct fb_info *i
 	case PS3FB_IOCTL_SETMODE:
 		{
 			struct ps3fb_par *par = info->par;
-			const struct fb_videomode *mode;
+			const struct fb_videomode *vmode;
 			struct fb_var_screeninfo var;
 
 			if (copy_from_user(&val, argp, sizeof(val)))
@@ -780,10 +784,10 @@ static int ps3fb_ioctl(struct fb_info *i
 			}
 			dev_dbg(info->device, "PS3FB_IOCTL_SETMODE:%x\n", val);
 			retval = -EINVAL;
-			mode = ps3fb_default_mode(val);
-			if (mode) {
+			vmode = ps3fb_vmode(val);
+			if (vmode) {
 				var = info->var;
-				fb_videomode_to_var(&var, mode);
+				fb_videomode_to_var(&var, vmode);
 				acquire_console_sem();
 				info->flags |= FBINFO_MISC_USEREVENT;
 				/* Force, in case only special bits changed */
@@ -1141,7 +1145,7 @@ static int __devinit ps3fb_probe(struct 
 
 	if (!fb_find_mode(&info->var, info, mode_option, ps3fb_modedb,
 			  ARRAY_SIZE(ps3fb_modedb),
-			  ps3fb_default_mode(par->new_mode_id), 32)) {
+			  ps3fb_vmode(par->new_mode_id), 32)) {
 		retval = -EINVAL;
 		goto err_fb_dealloc;
 	}

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 09/11] ps3fb: Round up video modes
From: Geert Uytterhoeven @ 2008-01-25 15:06 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton, linux-fbdev-devel
  Cc: Geert Uytterhoeven, linuxppc-dev, cbe-oss-dev
In-Reply-To: <20080125150623.202631389@vixen.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 7808 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3fb: Round up arbitrary video modes until they fit (if possible)

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/ps3fb.c |  160 +++++++++++++++++++++++++++++++++++---------------
 1 file changed, 114 insertions(+), 46 deletions(-)

--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -276,29 +276,49 @@ static char *mode_option __devinitdata;
 static int ps3fb_cmp_mode(const struct fb_videomode *vmode,
 			  const struct fb_var_screeninfo *var)
 {
-	/* resolution + black border must match a native resolution */
-	if (vmode->left_margin + vmode->xres + vmode->right_margin !=
-	    var->left_margin + var->xres + var->right_margin ||
-	    vmode->upper_margin + vmode->yres + vmode->lower_margin !=
-	    var->upper_margin + var->yres + var->lower_margin)
+	long xres, yres, left_margin, right_margin, upper_margin, lower_margin;
+	long dx, dy;
+
+	/* maximum values */
+	if (var->xres > vmode->xres || var->yres > vmode->yres ||
+	    var->pixclock > vmode->pixclock ||
+	    var->hsync_len > vmode->hsync_len ||
+	    var->vsync_len > vmode->vsync_len)
 		return -1;
 
-	/* minimum limits for margins */
-	if (vmode->left_margin > var->left_margin ||
-	    vmode->right_margin > var->right_margin ||
-	    vmode->upper_margin > var->upper_margin ||
-	    vmode->lower_margin > var->lower_margin)
+	/* progressive/interlaced must match */
+	if ((var->vmode & FB_VMODE_MASK) != vmode->vmode)
 		return -1;
 
-	/* these fields must match exactly */
-	if (vmode->pixclock != var->pixclock ||
-	    vmode->hsync_len != var->hsync_len ||
-	    vmode->vsync_len != var->vsync_len ||
-	    vmode->sync != var->sync ||
-	    vmode->vmode != (var->vmode & FB_VMODE_MASK))
+	/* minimum resolution */
+	xres = max(var->xres, 1U);
+	yres = max(var->yres, 1U);
+
+	/* minimum margins */
+	left_margin = max(var->left_margin, vmode->left_margin);
+	right_margin = max(var->right_margin, vmode->right_margin);
+	upper_margin = max(var->upper_margin, vmode->upper_margin);
+	lower_margin = max(var->lower_margin, vmode->lower_margin);
+
+	/* resolution + margins may not exceed native parameters */
+	dx = ((long)vmode->left_margin + (long)vmode->xres +
+	      (long)vmode->right_margin) -
+	     (left_margin + xres + right_margin);
+	if (dx < 0)
 		return -1;
 
-	return 0;
+	dy = ((long)vmode->upper_margin + (long)vmode->yres +
+	      (long)vmode->lower_margin) -
+	     (upper_margin + yres + lower_margin);
+	if (dy < 0)
+		return -1;
+
+	/* exact match */
+	if (!dx && !dy)
+		return 0;
+
+	/* resolution difference */
+	return (vmode->xres - xres) * (vmode->yres - yres);
 }
 
 static const struct fb_videomode *ps3fb_native_vmode(enum ps3av_mode_num id)
@@ -324,33 +344,96 @@ static const struct fb_videomode *ps3fb_
 static unsigned int ps3fb_find_mode(struct fb_var_screeninfo *var,
 				    u32 *ddr_line_length, u32 *xdr_line_length)
 {
-	unsigned int id;
+	unsigned int id, best_id;
+	int diff, best_diff;
 	const struct fb_videomode *vmode;
+	long gap;
 
+	best_id = 0;
+	best_diff = INT_MAX;
+	pr_debug("%s: wanted %u [%u] %u x %u [%u] %u\n", __func__,
+		 var->left_margin, var->xres, var->right_margin,
+		 var->upper_margin, var->yres, var->lower_margin);
 	for (id = PS3AV_MODE_480I; id <= PS3AV_MODE_WUXGA; id++) {
 		vmode = ps3fb_native_vmode(id);
-		if (!ps3fb_cmp_mode(vmode, var))
-			goto found;
+		diff = ps3fb_cmp_mode(vmode, var);
+		pr_debug("%s: mode %u: %u [%u] %u x %u [%u] %u: diff = %d\n",
+			 __func__, id, vmode->left_margin, vmode->xres,
+			 vmode->right_margin, vmode->upper_margin,
+			 vmode->yres, vmode->lower_margin, diff);
+		if (diff < 0)
+			continue;
+		if (diff < best_diff) {
+			best_id = id;
+			if (!diff)
+				break;
+			best_diff = diff;
+		}
 	}
 
-	pr_debug("%s: mode not found\n", __func__);
-	return 0;
+	if (!best_id) {
+		pr_debug("%s: no suitable mode found\n", __func__);
+		return 0;
+	}
+
+	id = best_id;
+	vmode = ps3fb_native_vmode(id);
 
-found:
 	*ddr_line_length = vmode->xres * BPP;
 
-	if (!var->xres) {
+	/* minimum resolution */
+	if (!var->xres)
 		var->xres = 1;
-		var->right_margin--;
-	}
-	if (!var->yres) {
+	if (!var->yres)
 		var->yres = 1;
-		var->lower_margin--;
-	}
+
+	/* minimum virtual resolution */
+	if (var->xres_virtual < var->xres)
+		var->xres_virtual = var->xres;
+	if (var->yres_virtual < var->yres)
+		var->yres_virtual = var->yres;
+
+	/* minimum margins */
+	if (var->left_margin < vmode->left_margin)
+		var->left_margin = vmode->left_margin;
+	if (var->right_margin < vmode->right_margin)
+		var->right_margin = vmode->right_margin;
+	if (var->upper_margin < vmode->upper_margin)
+		var->upper_margin = vmode->upper_margin;
+	if (var->lower_margin < vmode->lower_margin)
+		var->lower_margin = vmode->lower_margin;
+
+	/* extra margins */
+	gap = ((long)vmode->left_margin + (long)vmode->xres +
+	       (long)vmode->right_margin) -
+	      ((long)var->left_margin + (long)var->xres +
+	       (long)var->right_margin);
+	if (gap > 0) {
+		var->left_margin += gap/2;
+		var->right_margin += (gap+1)/2;
+		pr_debug("%s: rounded up H to %u [%u] %u\n", __func__,
+			 var->left_margin, var->xres, var->right_margin);
+	}
+
+	gap = ((long)vmode->upper_margin + (long)vmode->yres +
+	       (long)vmode->lower_margin) -
+	      ((long)var->upper_margin + (long)var->yres +
+	       (long)var->lower_margin);
+	if (gap > 0) {
+		var->upper_margin += gap/2;
+		var->lower_margin += (gap+1)/2;
+		pr_debug("%s: rounded up V to %u [%u] %u\n", __func__,
+			 var->upper_margin, var->yres, var->lower_margin);
+	}
+
+	/* fixed fields */
+	var->pixclock = vmode->pixclock;
+	var->hsync_len = vmode->hsync_len;
+	var->vsync_len = vmode->vsync_len;
+	var->sync = vmode->sync;
 
 	if (ps3_compare_firmware_version(1, 9, 0) >= 0) {
-		*xdr_line_length = GPU_ALIGN_UP(max(var->xres,
-						    var->xres_virtual) * BPP);
+		*xdr_line_length = GPU_ALIGN_UP(var->xres_virtual * BPP);
 		if (*xdr_line_length > GPU_MAX_LINE_LENGTH)
 			*xdr_line_length = GPU_MAX_LINE_LENGTH;
 	} else
@@ -465,22 +548,11 @@ static int ps3fb_check_var(struct fb_var
 	u32 xdr_line_length, ddr_line_length;
 	int mode;
 
-	dev_dbg(info->device, "var->xres:%u info->var.xres:%u\n", var->xres,
-		info->var.xres);
-	dev_dbg(info->device, "var->yres:%u info->var.yres:%u\n", var->yres,
-		info->var.yres);
-
-	/* FIXME For now we do exact matches only */
 	mode = ps3fb_find_mode(var, &ddr_line_length, &xdr_line_length);
 	if (!mode)
 		return -EINVAL;
 
 	/* Virtual screen */
-	if (var->xres_virtual < var->xres)
-		var->xres_virtual = var->xres;
-	if (var->yres_virtual < var->yres)
-		var->yres_virtual = var->yres;
-
 	if (var->xres_virtual > xdr_line_length / BPP) {
 		dev_dbg(info->device,
 			"Horizontal virtual screen size too large\n");
@@ -549,10 +621,6 @@ static int ps3fb_set_par(struct fb_info 
 	const struct fb_videomode *vmode;
 	u64 dst;
 
-	dev_dbg(info->device, "xres:%d xv:%d yres:%d yv:%d clock:%d\n",
-		info->var.xres, info->var.xres_virtual,
-		info->var.yres, info->var.yres_virtual, info->var.pixclock);
-
 	mode = ps3fb_find_mode(&info->var, &ddr_line_length, &xdr_line_length);
 	if (!mode)
 		return -EINVAL;

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 10/11] ps3fb: Cleanup sweep
From: Geert Uytterhoeven @ 2008-01-25 15:06 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton, linux-fbdev-devel
  Cc: Geert Uytterhoeven, linuxppc-dev, cbe-oss-dev
In-Reply-To: <20080125150623.202631389@vixen.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 7104 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3fb: cleanup sweep:
  - Kill ps3fb_priv.xdr_ea and ps3fb_priv.xdr_size, use info->screen_base and
    info->fix.smem_len instead.
  - Kill superfluous assignments to info->fix.smem_start, info->fix.smem_len,
    and info->screen_base in ps3fb_set_par(). Their values never change.
  - Add sparse annotations to casts to kill address space warnings

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/ps3fb.c |   64 +++++++++++++++++++++-----------------------------
 1 file changed, 27 insertions(+), 37 deletions(-)

--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -116,8 +116,6 @@ struct ps3fb_priv {
 	unsigned int irq_no;
 
 	u64 context_handle, memory_handle;
-	void *xdr_ea;
-	size_t xdr_size;
 	struct gpu_driver_info *dinfo;
 
 	u64 vblank_count;	/* frame count */
@@ -598,7 +596,7 @@ static int ps3fb_check_var(struct fb_var
 	}
 
 	/* Memory limit */
-	if (var->yres_virtual * xdr_line_length > ps3fb.xdr_size) {
+	if (var->yres_virtual * xdr_line_length > info->fix.smem_len) {
 		dev_dbg(info->device, "Not enough memory\n");
 		return -ENOMEM;
 	}
@@ -627,19 +625,15 @@ static int ps3fb_set_par(struct fb_info 
 
 	vmode = ps3fb_native_vmode(mode & PS3AV_MODE_MASK);
 
-	info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
-	info->fix.smem_len = ps3fb.xdr_size;
 	info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0;
 	info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0;
 	info->fix.line_length = xdr_line_length;
 
-	info->screen_base = (char __iomem *)ps3fb.xdr_ea;
-
 	par->ddr_line_length = ddr_line_length;
 	par->ddr_frame_size = vmode->yres * ddr_line_length;
 	par->xdr_frame_size = info->var.yres_virtual * xdr_line_length;
 
-	par->num_frames = ps3fb.xdr_size /
+	par->num_frames = info->fix.smem_len /
 			  max(par->ddr_frame_size, par->xdr_frame_size);
 
 	/* Keep the special bits we cannot set using fb_var_screeninfo */
@@ -667,13 +661,13 @@ static int ps3fb_set_par(struct fb_info 
 	}
 
 	/* Clear XDR frame buffer memory */
-	memset(ps3fb.xdr_ea, 0, ps3fb.xdr_size);
+	memset((void __force *)info->screen_base, 0, info->fix.smem_len);
 
 	/* Clear DDR frame buffer memory */
 	lines = vmode->yres * par->num_frames;
 	if (par->full_offset)
 		lines++;
-	maxlines = ps3fb.xdr_size / ddr_line_length;
+	maxlines = info->fix.smem_len / ddr_line_length;
 	for (dst = 0; lines; dst += maxlines * ddr_line_length) {
 		unsigned int l = min(lines, maxlines);
 		ps3fb_sync_image(info->device, 0, dst, 0, vmode->xres, l,
@@ -1017,10 +1011,9 @@ static int ps3fb_xdr_settings(u64 xdr_lp
 			__func__, status);
 		return -ENXIO;
 	}
-	dev_dbg(dev,
-		"video:%p xdr_ea:%p ioif:%lx lpar:%lx phys:%lx size:%lx\n",
-		ps3fb_videomemory.address, ps3fb.xdr_ea, GPU_IOIF, xdr_lpar,
-		virt_to_abs(ps3fb.xdr_ea), ps3fb_videomemory.size);
+	dev_dbg(dev, "video:%p ioif:%lx lpar:%lx size:%lx\n",
+		ps3fb_videomemory.address, GPU_IOIF, xdr_lpar,
+		ps3fb_videomemory.size);
 
 	status = lv1_gpu_context_attribute(ps3fb.context_handle,
 					   L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP,
@@ -1103,6 +1096,7 @@ static int __devinit ps3fb_probe(struct 
 	u64 lpar_reports = 0;
 	u64 lpar_reports_size = 0;
 	u64 xdr_lpar;
+	void *fb_start;
 	int status;
 	struct task_struct *task;
 	unsigned long max_ps3fb_size;
@@ -1158,7 +1152,7 @@ static int __devinit ps3fb_probe(struct 
 	}
 
 	/* vsync interrupt */
-	ps3fb.dinfo = ioremap(lpar_driver_info, 128 * 1024);
+	ps3fb.dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024);
 	if (!ps3fb.dinfo) {
 		dev_err(&dev->core, "%s: ioremap failed\n", __func__);
 		goto err_gpu_context_free;
@@ -1168,22 +1162,10 @@ static int __devinit ps3fb_probe(struct 
 	if (retval)
 		goto err_iounmap_dinfo;
 
-	/* XDR frame buffer */
-	ps3fb.xdr_ea = ps3fb_videomemory.address;
-	xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb.xdr_ea));
-
 	/* Clear memory to prevent kernel info leakage into userspace */
-	memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
-
-	/*
-	 * The GPU command buffer is at the start of video memory
-	 * As we don't use the full command buffer, we can put the actual
-	 * frame buffer at offset GPU_FB_START and save some precious XDR
-	 * memory
-	 */
-	ps3fb.xdr_ea += GPU_FB_START;
-	ps3fb.xdr_size = ps3fb_videomemory.size - GPU_FB_START;
+	memset(ps3fb_videomemory.address, 0, ps3fb_videomemory.size);
 
+	xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address));
 	retval = ps3fb_xdr_settings(xdr_lpar, &dev->core);
 	if (retval)
 		goto err_free_irq;
@@ -1197,12 +1179,20 @@ static int __devinit ps3fb_probe(struct 
 	par->new_mode_id = ps3fb_mode;
 	par->num_frames = 1;
 
-	info->screen_base = (char __iomem *)ps3fb.xdr_ea;
 	info->fbops = &ps3fb_ops;
-
 	info->fix = ps3fb_fix;
-	info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
-	info->fix.smem_len = ps3fb.xdr_size;
+
+	/*
+	 * The GPU command buffer is at the start of video memory
+	 * As we don't use the full command buffer, we can put the actual
+	 * frame buffer at offset GPU_FB_START and save some precious XDR
+	 * memory
+	 */
+	fb_start = ps3fb_videomemory.address + GPU_FB_START;
+	info->screen_base = (char __force __iomem *)fb_start;
+	info->fix.smem_start = virt_to_abs(fb_start);
+	info->fix.smem_len = ps3fb_videomemory.size - GPU_FB_START;
+
 	info->pseudo_palette = par->pseudo_palette;
 	info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST |
 		      FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
@@ -1227,9 +1217,9 @@ static int __devinit ps3fb_probe(struct 
 
 	dev->core.driver_data = info;
 
-	dev_info(info->device, "%s %s, using %lu KiB of video memory\n",
+	dev_info(info->device, "%s %s, using %u KiB of video memory\n",
 		 dev_driver_string(info->dev), info->dev->bus_id,
-		 ps3fb.xdr_size >> 10);
+		 info->fix.smem_len >> 10);
 
 	task = kthread_run(ps3fbd, info, DEVICE_NAME);
 	if (IS_ERR(task)) {
@@ -1252,7 +1242,7 @@ err_free_irq:
 	free_irq(ps3fb.irq_no, &dev->core);
 	ps3_irq_plug_destroy(ps3fb.irq_no);
 err_iounmap_dinfo:
-	iounmap((u8 __iomem *)ps3fb.dinfo);
+	iounmap((u8 __force __iomem *)ps3fb.dinfo);
 err_gpu_context_free:
 	lv1_gpu_context_free(ps3fb.context_handle);
 err_gpu_memory_free:
@@ -1287,7 +1277,7 @@ static int ps3fb_shutdown(struct ps3_sys
 		framebuffer_release(info);
 		info = dev->core.driver_data = NULL;
 	}
-	iounmap((u8 __iomem *)ps3fb.dinfo);
+	iounmap((u8 __force __iomem *)ps3fb.dinfo);
 
 	status = lv1_gpu_context_free(ps3fb.context_handle);
 	if (status)

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 11/11] ps3fb: Fix modedb typos
From: Geert Uytterhoeven @ 2008-01-25 15:06 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton, linux-fbdev-devel
  Cc: Geert Uytterhoeven, linuxppc-dev, cbe-oss-dev
In-Reply-To: <20080125150623.202631389@vixen.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1621 bytes --]

From: Geoff Levand <geoffrey.levand@am.sony.com>

ps3fb: Fix modedb typos

Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/ps3fb.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -184,7 +184,7 @@ static const struct fb_videomode ps3fb_m
         "720p", 50, 1124, 644, 13468, 298, 478, 57, 44, 80, 5,
         FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
     },    {
-        /* 1080 */
+        /* 1080i */
         "1080i", 50, 1688, 964, 13468, 264, 600, 94, 62, 88, 5,
         FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
     },    {
@@ -232,7 +232,7 @@ static const struct fb_videomode ps3fb_m
 	FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
     }, {
 	/* 1080if */
-	"1080f", 50, 1920, 1080, 13468, 148, 484, 36, 4, 88, 5,
+	"1080if", 50, 1920, 1080, 13468, 148, 484, 36, 4, 88, 5,
 	FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
     }, {
 	/* 1080pf */

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* Re: ml310 kernel2.6 booting problems
From: Grant Likely @ 2008-01-25 15:17 UTC (permalink / raw)
  To: greenlean; +Cc: linuxppc-embedded
In-Reply-To: <15087192.post@talk.nabble.com>

On 1/25/08, greenlean <jmgomez@atc.ugr.es> wrote:
>
> I'm also having some problem with my systemace file system. I'm working with
> secretlab git, and I try to mount the CF card with xsysace and with xsa, but
> in both cases it can't mount the rootfs:
>
> Linux/PPC load: console=ttyS0,9600 root=/dev/xsa3 rw
> :
> :
> :
> [    2.777706] xsysace xsysace.0: Xilinx SystemACE revision 1.0.12
> [    2.849967] xsysace xsysace.0: capacity: 986320 sectors
> [    2.913383]  xsa: unknown partition table

You're definitely not having a filesystem problem; it's a partition
table problem.  Either the partition table is corrupt or the kernel
doesn't understand the type of partition table, or the system ace
isn't able to read the CF correctly (hardware problem).

g.

> :
> :
> [    3.398810] Please append a correct "root=" boot option; here are the
> availa:
> [    3.499476] fe00     493160 xsa (driver?)
> [    3.547926] Kernel panic - not syncing: VFS: Unable to mount root fs on
> unkn)
>
> Does this mean that I have configured incorrectly the file system options in
> the kernel??
> I have read that the solution to this is to change the DOS/FAT/NT Filesystem
> option to the below configuration:
>
>       <*> Second extended fs support
> DOS/FAT/NT Filesystems
>        < > MSDOS fs support
>        < > VFAT (Windows-95) fs support
>        < > NTFS file system support
>   [*] Advanced partition selection
>          [*]   PC BIOS (MSDOS partition tables) support
> I've already tested this configuration:
>
>       <*> Second extended fs support
> DOS/FAT/NT Filesystems
>        <*> MSDOS fs support
>        <*> VFAT (Windows-95) fs support
>        < > NTFS file system support
>   [] Advanced partition selection
>
>
> My CF card has the following structure:
>
> Disco /dev/sdc: 521 MB, 521773056 bytes
> 16 cabezas, 63 sectores/pistas, 1011 cilindros
> Unidades = cilindros de 1008 * 512 = 516096 bytes
> Disk identifier: 0x00000000
>
> Disposit. Inicio    Comienzo      Fin      Bloques  Id  Sistema
> /dev/sdc1               1         400      201568+   6  FAT16
> /dev/sdc2             401         500       50400   82  Linux swap / Solaris
> /dev/sdc3             501        1011      257544   83  Linux
>
> I'm also wondering if I should use xsysace or xsa, because I have search in
> the file xsysace.c for the name of the device and It is named as xsysace. Am
> I right, and should I use xsysace? Or this name isn't related with the /dev
> file??
> $ grep xsysace xsysace.c
>
>         .name = "xsysace",
>         ace_major = register_blkdev(ace_major, "xsysace");
>                 printk(KERN_WARNING "xsysace: register_blkdev() failed\n");
>         unregister_blkdev(ace_major, "xsysace");
>
> I'm going to reformat my CF card and test it,maybe the partition table is
> corrupted, but fdisk is not saying anything at all.
>
> Thanks
>
>
> Grant Likely-2 wrote:
> >
> > On 1/16/08, Joachim Meyer <Jogi95@web.de> wrote:
> >> Hi
> >>
> >> I made an Ace file with my Kernel and load it with the Flash Card.
> >> I made the Initial release CF image on the card and copied my ace file in
> >> an folder, from which I boot with the DIP-Switch.
> >> If I used
> >> "console=ttyUL0 ,9600 root=/dev/xsysace/disc0/part2 rw "
> >
> > try root=/dev/xsa2
> > Also, the ',9600' is unnecessary with the uartlite.
> >
> >>
> >> I tried to use this:
> >> "console=ttyUL0 ,9600 root=fe02 rw"
> >> and with this, after making ace-file etc. I get:
> >> [   12.862678] EXT3 FS on xsa2, internal journal
> >> [   12.899229] EXT3-fs: recovery complete.
> >> [   12.982635] EXT3-fs: mounted filesystem with ordered data mode.
> >> [   13.038505] VFS: Mounted root (ext3 filesystem).
> >> [   13.094113] Freeing unused kernel memory: 96k init
> >> [   13.159079] Warning: unable to open an initial console.
> >
> > You're probably missing the /dev/console device file
> >
> > g.
> >
> > --
> > Grant Likely, B.Sc., P.Eng.
> > Secret Lab Technologies Ltd.
> > _______________________________________________
> > Linuxppc-embedded mailing list
> > Linuxppc-embedded@ozlabs.org
> > https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> >
> >
>
> --
> View this message in context: http://www.nabble.com/ml310-kernel2.6-booting-problems-tp14881983p15087192.html
> Sent from the linuxppc-embedded mailing list archive at Nabble.com.
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>


-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* Re: [PATCHv3 7/7] [POWERPC] Move definition of buffer descriptor to cpm.h
From: Kumar Gala @ 2008-01-25 15:56 UTC (permalink / raw)
  To: Jochen Friedrich; +Cc: Scott Wood, Kernel, Linux, linuxppc-dev list
In-Reply-To: <4798ACA5.5050106@scram.de>

On Thu, 24 Jan 2008, Jochen Friedrich wrote:

> Buffer descriptors are used by both CPM1 and CPM2. Move the definitions
> from the cpm dependent include file to common cpm.h
>
> Signed-off-by: Jochen Friedrich <jochen@scram.de>
> ---
> include/asm-powerpc/cpm.h  |   73 ++++++++++++++++++++++++++++++++++++++++++++
> include/asm-powerpc/cpm1.h |   65 ---------------------------------------
> include/asm-powerpc/cpm2.h |   64 --------------------------------------
> 3 files changed, 73 insertions(+), 129 deletions(-)
>

applied.

- k

^ permalink raw reply

* Re: [PATCH for-2.6.25] [POWERPC] Rename commproc to cpm1 and cpm2_common.c to cpm2.c
From: Kumar Gala @ 2008-01-25 15:56 UTC (permalink / raw)
  To: Jochen Friedrich
  Cc: Kernel, Linux, linuxppc-dev list, netdev@vger.kernel.org,
	Scott Wood, Garzik, Jeff
In-Reply-To: <4799F2CE.309@scram.de>

On Fri, 25 Jan 2008, Jochen Friedrich wrote:

> Rename commproc.[ch] to cpm1.[ch] to be more consistent with cpm2. Also
> rename cpm2_common.c to cpm2.c as suggested by Scott Wood. Adjust the
> includes accordingly.
>
> Signed-off-by: Jochen Friedrich <jochen@scram.de>
> ---
>  arch/powerpc/platforms/8xx/ep88xc.c           |    1 +
>  arch/powerpc/platforms/8xx/mpc86xads_setup.c  |    2 +-
>  arch/powerpc/platforms/8xx/mpc885ads_setup.c  |    2 +-
>  arch/powerpc/sysdev/Makefile                  |    4 ++--
>  arch/powerpc/sysdev/{commproc.c => cpm1.c}    |    4 ++--
>  arch/powerpc/sysdev/{cpm2_common.c => cpm2.c} |    3 +--
>  arch/powerpc/sysdev/micropatch.c              |    2 +-
>  arch/ppc/8260_io/enet.c                       |    2 +-
>  arch/ppc/8xx_io/commproc.c                    |    2 +-
>  arch/ppc/8xx_io/enet.c                        |    6 +++---
>  arch/ppc/8xx_io/fec.c                         |    2 +-
>  arch/ppc/8xx_io/micropatch.c                  |    2 +-
>  arch/ppc/boot/simple/iic.c                    |    2 +-
>  arch/ppc/boot/simple/m8xx_tty.c               |    2 +-
>  arch/ppc/kernel/ppc_ksyms.c                   |    2 +-
>  arch/ppc/platforms/mpc866ads_setup.c          |    2 +-
>  arch/ppc/platforms/mpc885ads_setup.c          |    2 +-
>  arch/ppc/syslib/mpc8xx_devices.c              |    2 +-
>  arch/ppc/xmon/start_8xx.c                     |    2 +-
>  drivers/net/fec_8xx/fec_8xx-netta.c           |    2 +-
>  drivers/net/fec_8xx/fec_main.c                |    2 +-
>  drivers/net/fec_8xx/fec_mii.c                 |    2 +-
>  drivers/net/fs_enet/fs_enet.h                 |    2 +-
>  drivers/net/fs_enet/mac-fec.c                 |    2 +-
>  drivers/net/fs_enet/mac-scc.c                 |    2 +-
>  drivers/serial/cpm_uart/cpm_uart_cpm1.h       |    2 +-
>  include/asm-powerpc/{commproc.h => cpm1.h}    |    8 ++++----
>  include/asm-ppc/{commproc.h => cpm1.h}        |    8 ++++----
>  28 files changed, 38 insertions(+), 38 deletions(-)
>  rename arch/powerpc/sysdev/{commproc.c => cpm1.c} (99%)
>  rename arch/powerpc/sysdev/{cpm2_common.c => cpm2.c} (99%)
>  rename include/asm-powerpc/{commproc.h => cpm1.h} (99%)
>  rename include/asm-ppc/{commproc.h => cpm1.h} (99%)
>

applied.

- k

^ permalink raw reply

* Re: [PATCH] mpc834x_mds: Convert device tree source to dts-v1
From: Kumar Gala @ 2008-01-25 15:57 UTC (permalink / raw)
  To: Paul Gortmaker; +Cc: linuxppc-dev
In-Reply-To: <1201242129-13417-1-git-send-email-paul.gortmaker@windriver.com>

On Fri, 25 Jan 2008, Paul Gortmaker wrote:

> Move mpc834x_mds device tree source forward to dts-v1 format.  Nothing
> too complex in this one, so it boils down to just adding a bunch of 0x
> in the right places and converting clock speeds to decimal.
>
> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
> ---
>  arch/powerpc/boot/dts/mpc834x_mds.dts |  254 +++++++++++++++++----------------
>  1 files changed, 128 insertions(+), 126 deletions(-)
>

applied.  I fixed up things so that interrupts use decimal.

- k

^ permalink raw reply

* Re: [PATCH 4/9] enable FSL SATA driver config for Freescale SoCs
From: Kumar Gala @ 2008-01-25 16:04 UTC (permalink / raw)
  To: Kim Phillips; +Cc: linuxppc-dev, Jerry Huang
In-Reply-To: <20080124204621.2c09359e.kim.phillips@freescale.com>


On Jan 24, 2008, at 8:46 PM, Kim Phillips wrote:

> The mpc8315 shares the same SATA controller as the mpc837x,
> and likelihood is that future SoCs from Freescale will also.
>
> Signed-off-by: Jerry Huang <Chang-Ming.Huang@freescale.com>
> Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
> ---
> Kumar, let me know if you want me to post this to the ata list (I'm
> assuming it's not necessary).

It is necessary so they are aware.  CC jgarizk, but we'll take it via  
powerpc.

- k

^ permalink raw reply

* Re: [PATCH] [NET]: Remove PowerPC code from fec.c
From: Jochen Friedrich @ 2008-01-25 16:04 UTC (permalink / raw)
  To: Frans Pop
  Cc: linux-m68k, netdev, linux-kernel, linuxppc-dev, geert, gerg,
	scottwood, jgarzik
In-Reply-To: <E1JIQpQ-0006Xj-RR@faramir.fjphome.nl>

Hi Frans,

> Jochen Friedrich wrote:
>> +++ b/drivers/net/fec.c
>> @@ -23,6 +23,9 @@
>>   *
>>   * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
>>   * Copyright (c) 2004-2006 Macq Electronique SA.
>> + *
>> + * This driver is now only used on ColdFire processors. Remove conditional
>> + * Powerpc code. 
>>   */
> 
> This comment makes sense for a changelog, but IMO it makes no sense at all
> to add it to the file.

I just added it to clarify this code is now only used on m68knommu (Coldfire).
The comments on top are mailny about MPC860T CPUs (PowerPC), however the driver is no
longer used for these CPUs.

Maybe the wording should be changed to:

This driver is now only used on ColdFire (m68knommu) processors. Conditional
PowerPC code has been removed.

Thanks,
Jochen

^ permalink raw reply

* [RFC][PATCH] remove section mappinng
From: Badari Pulavarty @ 2008-01-25 16:05 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: anton, Paul Mackerras, linux-mm

Hi Paul/Ben/Anton,

As part of making memory remove working on ppc64, I need the code to
remove htab mappings for the section of the memory.

Here is the code I cooked up, it seems to be working fine.
But I have concerns where I need your help.

In order to invalidate htab entries, we need to find the "slot".
But I can only find the hpte group. Is it okay to invalidate the
first entry in the group ? Do I need to invalidate the entire group ?

Please help, as I would like to push this for 2.6.25/2.6.26.

Thanks,
Badari

For memory remove, we need to remove htab mapping. 

Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com>
---
 arch/powerpc/mm/hash_utils_64.c |   32 ++++++++++++++++++++++++++++++++
 include/asm-powerpc/sparsemem.h |    1 +
 2 files changed, 33 insertions(+)

Index: linux-2.6.24-rc8/arch/powerpc/mm/hash_utils_64.c
===================================================================
--- linux-2.6.24-rc8.orig/arch/powerpc/mm/hash_utils_64.c	2008-01-17 09:47:37.000000000 -0800
+++ linux-2.6.24-rc8/arch/powerpc/mm/hash_utils_64.c	2008-01-25 07:57:48.000000000 -0800
@@ -191,6 +191,33 @@ int htab_bolt_mapping(unsigned long vsta
 	return ret < 0 ? ret : 0;
 }
 
+static void htab_remove_mapping(unsigned long vstart, unsigned long vend,
+		      int psize, int ssize)
+{
+	unsigned long vaddr;
+	unsigned int step, shift;
+
+	shift = mmu_psize_defs[psize].shift;
+	step = 1 << shift;
+
+	for (vaddr = vstart; vaddr < vend; vaddr += step) {
+		unsigned long hash, hpteg;
+		unsigned long vsid = get_kernel_vsid(vaddr, ssize);
+		unsigned long va = hpt_va(vaddr, vsid, ssize);
+
+		hash = hpt_hash(va, shift, ssize);
+		hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
+
+		/*
+		 * HELP - how do I find the slot ? Is it okay to
+		 * invalidates only first entry ? Do I need to
+		 * remove entire group instead ?
+		 */
+		BUG_ON(!ppc_md.hpte_invalidate);
+		ppc_md.hpte_invalidate(hpteg, va, psize, ssize, 0);
+	}
+}
+
 static int __init htab_dt_scan_seg_sizes(unsigned long node,
 					 const char *uname, int depth,
 					 void *data)
@@ -436,6 +463,11 @@ void create_section_mapping(unsigned lon
 			_PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX,
 			mmu_linear_psize, mmu_kernel_ssize));
 }
+
+void remove_section_mapping(unsigned long start, unsigned long end)
+{
+	htab_remove_mapping(start, end, mmu_linear_psize, mmu_kernel_ssize);
+}
 #endif /* CONFIG_MEMORY_HOTPLUG */
 
 static inline void make_bl(unsigned int *insn_addr, void *func)
Index: linux-2.6.24-rc8/include/asm-powerpc/sparsemem.h
===================================================================
--- linux-2.6.24-rc8.orig/include/asm-powerpc/sparsemem.h	2008-01-15 20:22:48.000000000 -0800
+++ linux-2.6.24-rc8/include/asm-powerpc/sparsemem.h	2008-01-24 16:20:17.000000000 -0800
@@ -20,6 +20,7 @@
 
 #ifdef CONFIG_MEMORY_HOTPLUG
 extern void create_section_mapping(unsigned long start, unsigned long end);
+extern void remove_section_mapping(unsigned long start, unsigned long end);
 #ifdef CONFIG_NUMA
 extern int hot_add_scn_to_nid(unsigned long scn_addr);
 #else

^ permalink raw reply

* Re: [PATCH v2] [POWERPC] 85xx: Port STX GP3 board over from arch/ppc
From: Scott Wood @ 2008-01-25 16:08 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <Pine.LNX.4.64.0801242245390.22024@blarg.am.freescale.net>

On Thu, Jan 24, 2008 at 10:47:21PM -0600, Kumar Gala wrote:
> +	soc8560@fdf00000 {

soc@fdf00000

-Scott
> +		cpm@919c0 {
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			compatible = "fsl,mpc8560-cpm", "fsl,cpm2";

This is also a simple-bus.

> +static struct of_device_id __initdata of_bus_ids[] = {
> +	{ .name = "soc", },
> +	{ .type = "soc", },
> +	{ .name = "cpm", },
> +	{ .name = "localbus", },
> +	{ .compatible = "simple-bus", },
> +	{},
> +};

You should be able to get rid of the others besides simple-bus (there may
have been some confusion in what you asked over IRC yesterday -- I
thought you were talking about compatible in the device tree, not here).

-Scott

^ permalink raw reply

* Reminder: removal of arch/ppc
From: Kumar Gala @ 2008-01-25 16:55 UTC (permalink / raw)
  To: linuxppc-dev list, linuxppc-embedded

Just a reminder that the plan is to remove arch/ppc this summer (June  
2008).  The following boards still existing over in arch/ppc.  Some of  
them have been ported over to arch/powerpc.  If you care about one of  
these boards and its not ported speak up (it helps if you have access  
to the board).  Also, if you know a given board is free to die of  
bitrot let us know so we know not to worry about it:

	PREP
	PQ2ADS
	TQM8260
	CPCI690
	EV64260
	CHESTNUT
	LOPEC
	KATANA
	HDPU
	MVME5100
	PAL4
	POWERPMC250
	PPLUS
	PRPMC750
	PRPMC800
	RADSTONE_PPC7D
	SANDPOINT
	SBC82xx
	SPRUCE
	LITE5200
	EV64360
	MPC86XADS
	MPC885ADS
	ADS8272

4xx:
	BAMBOO
	CPCI405
	EBONY
	EP405
	BUBINGA
	LUAN
	YUCCA
	OCOTEA
	REDWOOD_5
	REDWOOD_6
	SYCAMORE
	TAISHAN
	WALNUT
	XILINX_ML300
	XILINX_ML403

- k

^ permalink raw reply

* [PATCH 0/2] IB/ehca: PMA support and a minor fix
From: Joachim Fenkes @ 2008-01-25 20:11 UTC (permalink / raw)
  To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier, OF-EWG
  Cc: Stefan Roscher, Christoph Raisch

This patchset will fix a minor issue and then add support for Performance
MADs, which redirects all PMA queries to the actual PMA QP.

[1/2] adds a missing query_pma_attr()
[2/2] adds PMA redirection code

The patches will apply, in order, on top of Roland's for-2.6.25 branch.
Please review them and apply for 2.6.25 if you think they're okay.

Thanks and regards,
  Joachim

-- 
Joachim Fenkes  --  eHCA Linux Driver Developer and Hardware Tamer
IBM Deutschland Entwicklung GmbH  --  Dept. 3627 (I/O Firmware Dev. 2)
Schoenaicher Strasse 220  --  71032 Boeblingen  --  Germany
eMail: fenkes@de.ibm.com

^ permalink raw reply

* [PATCH 2/2] IB/ehca: Add PMA support
From: Joachim Fenkes @ 2008-01-25 20:18 UTC (permalink / raw)
  To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier, OF-EWG
  Cc: Stefan Roscher, Christoph Raisch
In-Reply-To: <200801252111.11915.fenkes@de.ibm.com>

From: Hoang-Nam Nguyen <hnguyen@de.ibm.com>

This patch enables ehca to redirect any PMA queries to the
actual PMA QP.

Signed-off-by: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
Reviewed-by: Joachim Fenkes <fenkes@de.ibm.com>
Reviewed-by: Christoph Raisch <raisch@de.ibm.com>
---
 drivers/infiniband/hw/ehca/ehca_classes.h |    1 +
 drivers/infiniband/hw/ehca/ehca_iverbs.h  |    5 ++
 drivers/infiniband/hw/ehca/ehca_main.c    |    2 +-
 drivers/infiniband/hw/ehca/ehca_sqp.c     |   91 +++++++++++++++++++++++++++++
 4 files changed, 98 insertions(+), 1 deletions(-)

diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index f281d16..92cce8a 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -101,6 +101,7 @@ struct ehca_sport {
 	spinlock_t mod_sqp_lock;
 	enum ib_port_state port_state;
 	struct ehca_sma_attr saved_attr;
+	u32 pma_qp_nr;
 };
 
 #define HCA_CAP_MR_PGSIZE_4K  0x80000000
diff --git a/drivers/infiniband/hw/ehca/ehca_iverbs.h b/drivers/infiniband/hw/ehca/ehca_iverbs.h
index c469bfd..a8a2ea5 100644
--- a/drivers/infiniband/hw/ehca/ehca_iverbs.h
+++ b/drivers/infiniband/hw/ehca/ehca_iverbs.h
@@ -187,6 +187,11 @@ int ehca_dealloc_ucontext(struct ib_ucontext *context);
 
 int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
 
+int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
+		     struct ib_wc *in_wc, struct ib_grh *in_grh,
+		     struct ib_mad *in_mad,
+		     struct ib_mad *out_mad);
+
 void ehca_poll_eqs(unsigned long data);
 
 int ehca_calc_ipd(struct ehca_shca *shca, int port,
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 0fe0c84..33b5bac 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -472,7 +472,7 @@ int ehca_init_device(struct ehca_shca *shca)
 	shca->ib_device.dealloc_fmr	    = ehca_dealloc_fmr;
 	shca->ib_device.attach_mcast	    = ehca_attach_mcast;
 	shca->ib_device.detach_mcast	    = ehca_detach_mcast;
-	/* shca->ib_device.process_mad	    = ehca_process_mad;	    */
+	shca->ib_device.process_mad	    = ehca_process_mad;
 	shca->ib_device.mmap		    = ehca_mmap;
 
 	if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) {
diff --git a/drivers/infiniband/hw/ehca/ehca_sqp.c b/drivers/infiniband/hw/ehca/ehca_sqp.c
index 79e72b2..706d97a 100644
--- a/drivers/infiniband/hw/ehca/ehca_sqp.c
+++ b/drivers/infiniband/hw/ehca/ehca_sqp.c
@@ -39,12 +39,18 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <rdma/ib_mad.h>
 
 #include "ehca_classes.h"
 #include "ehca_tools.h"
 #include "ehca_iverbs.h"
 #include "hcp_if.h"
 
+#define IB_MAD_STATUS_REDIRECT		__constant_htons(0x0002)
+#define IB_MAD_STATUS_UNSUP_VERSION	__constant_htons(0x0004)
+#define IB_MAD_STATUS_UNSUP_METHOD	__constant_htons(0x0008)
+
+#define IB_PMA_CLASS_PORT_INFO		__constant_htons(0x0001)
 
 /**
  * ehca_define_sqp - Defines special queue pair 1 (GSI QP). When special queue
@@ -83,6 +89,9 @@ u64 ehca_define_sqp(struct ehca_shca *shca,
 				 port, ret);
 			return ret;
 		}
+		shca->sport[port - 1].pma_qp_nr = pma_qp_nr;
+		ehca_dbg(&shca->ib_device, "port=%x pma_qp_nr=%x",
+			 port, pma_qp_nr);
 		break;
 	default:
 		ehca_err(&shca->ib_device, "invalid qp_type=%x",
@@ -109,3 +118,85 @@ u64 ehca_define_sqp(struct ehca_shca *shca,
 
 	return H_SUCCESS;
 }
+
+struct ib_perf {
+	struct ib_mad_hdr mad_hdr;
+	u8 reserved[40];
+	u8 data[192];
+} __attribute__ ((packed));
+
+
+static int ehca_process_perf(struct ib_device *ibdev, u8 port_num,
+			     struct ib_mad *in_mad, struct ib_mad *out_mad)
+{
+	struct ib_perf *in_perf = (struct ib_perf *)in_mad;
+	struct ib_perf *out_perf = (struct ib_perf *)out_mad;
+	struct ib_class_port_info *poi =
+		(struct ib_class_port_info *)out_perf->data;
+	struct ehca_shca *shca =
+		container_of(ibdev, struct ehca_shca, ib_device);
+	struct ehca_sport *sport = &shca->sport[port_num - 1];
+
+	ehca_dbg(ibdev, "method=%x", in_perf->mad_hdr.method);
+
+	*out_mad = *in_mad;
+
+	if (in_perf->mad_hdr.class_version != 1) {
+		ehca_warn(ibdev, "Unsupported class_version=%x",
+			  in_perf->mad_hdr.class_version);
+		out_perf->mad_hdr.status = IB_MAD_STATUS_UNSUP_VERSION;
+		goto perf_reply;
+	}
+
+	switch (in_perf->mad_hdr.method) {
+	case IB_MGMT_METHOD_GET:
+	case IB_MGMT_METHOD_SET:
+		/* set class port info for redirection */
+		out_perf->mad_hdr.attr_id = IB_PMA_CLASS_PORT_INFO;
+		out_perf->mad_hdr.status = IB_MAD_STATUS_REDIRECT;
+		memset(poi, 0, sizeof(*poi));
+		poi->base_version = 1;
+		poi->class_version = 1;
+		poi->resp_time_value = 18;
+		poi->redirect_lid = sport->saved_attr.lid;
+		poi->redirect_qp = sport->pma_qp_nr;
+		poi->redirect_qkey = IB_QP1_QKEY;
+		poi->redirect_pkey = IB_DEFAULT_PKEY_FULL;
+
+		ehca_dbg(ibdev, "ehca_pma_lid=%x ehca_pma_qp=%x",
+			 sport->saved_attr.lid, sport->pma_qp_nr);
+		break;
+
+	case IB_MGMT_METHOD_GET_RESP:
+		return IB_MAD_RESULT_FAILURE;
+
+	default:
+		out_perf->mad_hdr.status = IB_MAD_STATUS_UNSUP_METHOD;
+		break;
+	}
+
+perf_reply:
+	out_perf->mad_hdr.method = IB_MGMT_METHOD_GET_RESP;
+
+	return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY;
+}
+
+int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
+		     struct ib_wc *in_wc, struct ib_grh *in_grh,
+		     struct ib_mad *in_mad,
+		     struct ib_mad *out_mad)
+{
+	int ret;
+
+	if (!port_num || port_num > ibdev->phys_port_cnt)
+		return IB_MAD_RESULT_FAILURE;
+
+	/* accept only pma request */
+	if (in_mad->mad_hdr.mgmt_class != IB_MGMT_CLASS_PERF_MGMT)
+		return IB_MAD_RESULT_SUCCESS;
+
+	ehca_dbg(ibdev, "port_num=%x src_qp=%x", port_num, in_wc->src_qp);
+	ret = ehca_process_perf(ibdev, port_num, in_mad, out_mad);
+
+	return ret;
+}
-- 
1.5.2

^ permalink raw reply related

* [PATCHv3 2.6.25] i2c: adds support for i2c bus on Freescale CPM1/CPM2 controllers
From: Jochen Friedrich @ 2008-01-25 17:11 UTC (permalink / raw)
  To: Scott Wood; +Cc: Kernel, Linux, linuxppc-dev list, Linux I2C, Jean Delvare

Using the port of 2.4 code from Vitaly Bordug <vitb@kernel.crashing.org>
and the actual algorithm used by the i2c driver of the DBox code on
cvs.tuxboc.org from Tmbinc, Gillem (htoa@gmx.net). Renamed i2c-rpx.c and
i2c-algo-8xx.c to i2c-cpm.c and converted the driver to an
of_platform_driver.

Signed-off-by: Jochen Friedrich <jochen@scram.de>
---
 arch/powerpc/boot/dts/mpc8272ads.dts         |   10 +
 arch/powerpc/boot/dts/mpc866ads.dts          |   10 +
 arch/powerpc/boot/dts/mpc885ads.dts          |   10 +
 arch/powerpc/platforms/8xx/mpc885ads_setup.c |    5 +
 drivers/i2c/busses/Kconfig                   |   10 +
 drivers/i2c/busses/Makefile                  |    1 +
 drivers/i2c/busses/i2c-cpm.c                 |  759 ++++++++++++++++++++++++++
 7 files changed, 805 insertions(+), 0 deletions(-)
 create mode 100644 drivers/i2c/busses/i2c-cpm.c

diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts
index 7285ca1..7273996 100644
--- a/arch/powerpc/boot/dts/mpc8272ads.dts
+++ b/arch/powerpc/boot/dts/mpc8272ads.dts
@@ -215,6 +215,16 @@
 				linux,network-index = <1>;
 				fsl,cpm-command = <16200300>;
 			};
+
+			i2c@11860 {
+				compatible = "fsl,mpc8248-i2c",
+					     "fsl,cpm2-i2c",
+					     "fsl,cpm-i2c";
+				reg = <11860 20 8afc 2>;
+				interrupts = <1 8>;
+				interrupt-parent = <&PIC>;
+				fsl,cpm-command = <29600000>;
+			};
 		};
 
 		PIC: interrupt-controller@10c00 {
diff --git a/arch/powerpc/boot/dts/mpc866ads.dts b/arch/powerpc/boot/dts/mpc866ads.dts
index daf9433..80c08bf 100644
--- a/arch/powerpc/boot/dts/mpc866ads.dts
+++ b/arch/powerpc/boot/dts/mpc866ads.dts
@@ -169,6 +169,16 @@
 				fsl,cpm-command = <0000>;
 				linux,network-index = <1>;
 			};
+
+			i2c@860 {
+				compatible = "fsl,mpc866-i2c",
+					     "fsl,cpm1-i2c",
+					     "fsl,cpm-i2c";
+				reg = <860 20 3c80 30>;
+				interrupts = <10 3>;
+				interrupt-parent = <&Cpm_pic>;
+				fsl,cpm-command = <0010>;
+			};
 		};
 	};
 
diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts
index 8848e63..fd9c9d7 100644
--- a/arch/powerpc/boot/dts/mpc885ads.dts
+++ b/arch/powerpc/boot/dts/mpc885ads.dts
@@ -213,6 +213,16 @@
 				fsl,cpm-command = <0080>;
 				linux,network-index = <2>;
 			};
+
+			i2c@860 {
+				compatible = "fsl,mpc885-i2c",
+					     "fsl,cpm1-i2c",
+					     "fsl,cpm-i2c";
+				reg = <860 20 3c80 30>;
+				interrupts = <10>;
+				interrupt-parent = <&CPM_PIC>;
+				fsl,cpm-command = <0010>;
+			};
 		};
 	};
 
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index f39447b..1e7d056 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -157,6 +157,11 @@ static struct cpm_pin mpc885ads_pins[] = {
 	{CPM_PORTE, 28, CPM_PIN_OUTPUT},
 	{CPM_PORTE, 29, CPM_PIN_OUTPUT},
 #endif
+	/* I2C */
+#ifdef CONFIG_I2C_8XX
+	{CPM_PORTB, 26, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
+	{CPM_PORTB, 27, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
+#endif
 };
 
 static void __init init_ioports(void)
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index c466c6c..5950172 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -114,6 +114,16 @@ config I2C_BLACKFIN_TWI_CLK_KHZ
 	help
 	  The unit of the TWI clock is kHz.
 
+config I2C_CPM
+	tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)"
+	depends on (CPM1 || CPM2) && I2C && PPC_OF
+	help
+	  This supports the use of the I2C interface on Freescale
+	  processors with CPM1 or CPM2.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-cpm.
+
 config I2C_DAVINCI
 	tristate "DaVinci I2C driver"
 	depends on ARCH_DAVINCI
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 81d43c2..a395555 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
 obj-$(CONFIG_I2C_AT91)		+= i2c-at91.o
 obj-$(CONFIG_I2C_AU1550)	+= i2c-au1550.o
 obj-$(CONFIG_I2C_BLACKFIN_TWI)	+= i2c-bfin-twi.o
+obj-$(CONFIG_I2C_CPM)		+= i2c-cpm.o
 obj-$(CONFIG_I2C_DAVINCI)	+= i2c-davinci.o
 obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
 obj-$(CONFIG_I2C_GPIO)		+= i2c-gpio.o
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
new file mode 100644
index 0000000..7191427
--- /dev/null
+++ b/drivers/i2c/busses/i2c-cpm.c
@@ -0,0 +1,759 @@
+/*
+ * Freescale CPM1/CPM2 I2C interface.
+ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
+ *
+ * moved into proper i2c interface;
+ * Brad Parker (brad@heeltoe.com)
+ *
+ * (C) 2007 Montavista Software, Inc.
+ * Vitaly Bordug <vitb@kernel.crashing.org>
+ *
+ * RPX lite specific parts of the i2c interface
+ * Update:  There actually isn't anything RPXLite-specific about this module.
+ * This should work for most any CPM board.  The console messages have been
+ * changed to eliminate RPXLite references.
+ *
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * moved into proper i2c interface; separated out platform specific
+ * parts into i2c-8xx.c
+ * Brad Parker (brad@heeltoe.com)
+ *
+ * Parts from dbox2_i2c.c (cvs.tuxbox.org)
+ * (C) 2000-2001 Tmbinc, Gillem (htoa@gmx.net)
+ *
+ * (C) 2007 Montavista Software, Inc.
+ * Vitaly Bordug <vitb@kernel.crashing.org>
+ *
+ * Converted to of_platform_device. Renamed to i2c-cpm.c.
+ * (C) 2007 Jochen Friedrich <jochen@scram.de>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/stddef.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/time.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <sysdev/fsl_soc.h>
+#include <asm/cpm.h>
+
+/*
+ * Wait for patch from Jon Smirl
+ * #include "powerpc-common.h"
+ */
+
+/* Try to define this if you have an older CPU (earlier than rev D4) */
+/* However, better use a GPIO based bitbang driver in this case :/   */
+#undef	I2C_CHIP_ERRATA
+
+#define CPM_MAX_READ    513
+#define CPM_MAXBD       4
+
+#define CPM_CR_INIT_TRX		(0x00)
+#define CPM_CR_CLOSE_RXBD	(0x07)
+
+#define I2C_EB			(0x10) /* Big endian mode */
+
+/* I2C parameter RAM. */
+struct i2c_ram {
+	ushort  rbase;		/* Rx Buffer descriptor base address */
+	ushort  tbase;		/* Tx Buffer descriptor base address */
+	u_char  rfcr;		/* Rx function code */
+	u_char  tfcr;		/* Tx function code */
+	ushort  mrblr;		/* Max receive buffer length */
+	uint    rstate;		/* Internal */
+	uint    rdp;		/* Internal */
+	ushort  rbptr;		/* Rx Buffer descriptor pointer */
+	ushort  rbc;		/* Internal */
+	uint    rxtmp;		/* Internal */
+	uint    tstate;		/* Internal */
+	uint    tdp;		/* Internal */
+	ushort  tbptr;		/* Tx Buffer descriptor pointer */
+	ushort  tbc;		/* Internal */
+	uint    txtmp;		/* Internal */
+	char    res1[4];	/* Reserved */
+	ushort  rpbase;		/* Relocation pointer */
+	char    res2[2];	/* Reserved */
+};
+
+/* I2C Registers */
+struct i2c_reg {
+	u8	i2mod;
+	u8	res1[3];
+	u8	i2add;
+	u8	res2[3];
+	u8	i2brg;
+	u8	res3[3];
+	u8	i2com;
+	u8	res4[3];
+	u8	i2cer;
+	u8	res5[3];
+	u8	i2cmr;
+};
+
+struct cpm_i2c {
+	char *base;
+	struct of_device *ofdev;
+	struct i2c_adapter adap;
+	uint dp_addr;
+	int version; /* CPM1=1, CPM2=2 */
+	int irq;
+	int cp_command;
+	struct i2c_reg __iomem *i2c_reg;
+	struct i2c_ram __iomem *i2c_ram;
+	u16 i2c_addr;
+	wait_queue_head_t i2c_wait;
+	struct mutex i2c_mutex; /* Protects I2C CPM */
+	u_char *txbuf[CPM_MAXBD];
+	u_char *rxbuf[CPM_MAXBD];
+	u32 txdma[CPM_MAXBD];
+	u32 rxdma[CPM_MAXBD];
+};
+
+static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id)
+{
+	struct cpm_i2c *cpm;
+	struct i2c_reg __iomem *i2c_reg;
+	struct i2c_adapter *adap = dev_id;
+	int i;
+
+	cpm = i2c_get_adapdata(dev_id);
+	i2c_reg = cpm->i2c_reg;
+
+	/* Clear interrupt. */
+	i = in_8(&i2c_reg->i2cer);
+	out_8(&i2c_reg->i2cer, i);
+
+	dev_dbg(&adap->dev, "Interrupt: %x\n", i);
+
+	/* Get 'me going again. */
+	wake_up_interruptible(&cpm->i2c_wait);
+
+	return i ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static void cpm_reset_i2c_params(struct cpm_i2c *cpm)
+{
+	struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+
+	/* Set up the IIC parameters in the parameter ram. */
+	out_be16(&i2c_ram->tbase, cpm->dp_addr);
+	out_be16(&i2c_ram->rbase, cpm->dp_addr + sizeof(cbd_t) * CPM_MAXBD);
+
+	out_8(&i2c_ram->tfcr, I2C_EB);
+	out_8(&i2c_ram->rfcr, I2C_EB);
+
+	out_be16(&i2c_ram->mrblr, CPM_MAX_READ);
+
+	out_be32(&i2c_ram->rstate, 0);
+	out_be32(&i2c_ram->rdp, 0);
+	out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase));
+	out_be16(&i2c_ram->rbc, 0);
+	out_be32(&i2c_ram->rxtmp, 0);
+	out_be32(&i2c_ram->tstate, 0);
+	out_be32(&i2c_ram->tdp, 0);
+	out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase));
+	out_be16(&i2c_ram->tbc, 0);
+	out_be32(&i2c_ram->txtmp, 0);
+}
+
+static void cpm_i2c_force_close(struct i2c_adapter *adap)
+{
+	struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+	struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg;
+
+	dev_dbg(&adap->dev, "cpm_i2c_force_close()\n");
+
+	cpm_command(cpm->cp_command, CPM_CR_CLOSE_RXBD);
+
+	out_8(&i2c_reg->i2cmr, 0x00);	/* Disable all interrupts */
+	out_8(&i2c_reg->i2cer, 0xff);
+}
+
+static void cpm_i2c_parse_message(struct i2c_adapter *adap,
+	struct i2c_msg *pmsg, int num, int tx, int rx)
+{
+	cbd_t *tbdf, *rbdf;
+	u_char addr;
+	u_char *tb;
+	u_char *rb;
+	struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+	struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+	int i, dscan;
+
+	tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+	rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+	/*
+	 * This chip can't do zero length writes. However, the i2c core uses
+	 * them to scan for devices. The best we can do is to convert them
+	 * into 1 byte reads
+	 */
+
+	dscan = ((pmsg->len == 0) && (num == 1));
+
+	addr = pmsg->addr << 1;
+	if ((pmsg->flags & I2C_M_RD) || dscan)
+		addr |= 1;
+
+	tb = cpm->txbuf[tx];
+	rb = cpm->rxbuf[rx];
+
+	/* Align read buffer */
+	rb = (u_char *) (((ulong) rb + 1) & ~1);
+
+	if ((pmsg->flags & I2C_M_RD) || dscan) {
+		/*
+		 * To read, we need an empty buffer of the proper length.
+		 * All that is used is the first byte for address, the remainder
+		 * is just used for timing (and doesn't really have to exist).
+		 */
+		tb[0] = addr;		/* Device address byte w/rw flag */
+
+		dev_dbg(&adap->dev, "cpm_i2c_read(abyte=0x%x)\n", addr);
+
+		if (dscan)
+			tbdf[tx].cbd_datlen = 2;
+		else
+			tbdf[tx].cbd_datlen = pmsg->len + 1;
+
+		tbdf[tx].cbd_sc = 0;
+
+		if (!(pmsg->flags & I2C_M_NOSTART))
+			tbdf[tx].cbd_sc |= BD_I2C_START;
+		if (tx + 1 == num)
+			tbdf[tx].cbd_sc |= BD_SC_LAST | BD_SC_WRAP;
+
+		rbdf[rx].cbd_datlen = 0;
+		rbdf[rx].cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
+
+		if (rx + 1 == CPM_MAXBD)
+			tbdf[rx].cbd_sc |= BD_SC_WRAP;
+
+		eieio();
+		tbdf[tx].cbd_sc |= BD_SC_READY;
+	} else {
+		tb[0] = addr;		/* Device address byte w/rw flag */
+		for (i = 0; i < pmsg->len; i++)
+			tb[i+1] = pmsg->buf[i];
+
+		dev_dbg(&adap->dev, "cpm_iic_write(abyte=0x%x)\n", addr);
+
+		tbdf[tx].cbd_datlen = pmsg->len + 1;
+		tbdf[tx].cbd_sc = 0;
+
+		if (!(pmsg->flags & I2C_M_NOSTART))
+			tbdf[tx].cbd_sc |= BD_I2C_START;
+
+		if (tx + 1 == num)
+			tbdf[tx].cbd_sc |= BD_SC_LAST | BD_SC_WRAP;
+
+		eieio();
+		tbdf[tx].cbd_sc |= BD_SC_READY | BD_SC_INTRPT;
+
+		dev_dbg(&adap->dev, "tx sc %d %04x\n",
+			tx, tbdf[tx].cbd_sc);
+	}
+}
+
+static int cpm_i2c_check_message(struct i2c_adapter *adap,
+	struct i2c_msg *pmsg, int tx, int rx)
+{
+	cbd_t *tbdf, *rbdf;
+	u_char *tb;
+	u_char *rb;
+	struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+	struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+	int i;
+
+	tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+	rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+	tb = cpm->txbuf[tx];
+	rb = cpm->rxbuf[rx];
+
+	/* Align read buffer */
+	rb = (u_char *) (((uint) rb + 1) & ~1);
+
+	if (pmsg->flags & I2C_M_RD) {
+		dev_dbg(&adap->dev, "rx sc %04x, rx sc %04x\n",
+			tbdf[tx].cbd_sc, rbdf[rx].cbd_sc);
+
+		if (tbdf[tx].cbd_sc & BD_SC_NAK) {
+			dev_dbg(&adap->dev, "IIC read; No ack\n");
+
+			if (pmsg->flags & I2C_M_IGNORE_NAK)
+				return 0;
+			else
+				return -EIO;
+		}
+		if (rbdf[rx].cbd_sc & BD_SC_EMPTY) {
+			dev_dbg(&adap->dev,
+				"IIC read; complete but rbuf empty\n");
+			return -EREMOTEIO;
+		}
+		if (rbdf[rx].cbd_sc & BD_SC_OV) {
+			dev_dbg(&adap->dev, "IIC read; Overrun\n");
+			return -EREMOTEIO;
+		}
+		for (i = 0; i < pmsg->len; i++)
+			pmsg->buf[i] = rb[i];
+	} else {
+		dev_dbg(&adap->dev, "tx sc %d %04x\n", tx, tbdf[tx].cbd_sc);
+
+		if (tbdf[tx].cbd_sc & BD_SC_NAK) {
+			dev_dbg(&adap->dev, "IIC write; No ack\n");
+
+			if (pmsg->flags & I2C_M_IGNORE_NAK)
+				return 0;
+			else
+				return -EIO;
+		}
+		if (tbdf[tx].cbd_sc & BD_SC_UN) {
+			dev_dbg(&adap->dev, "IIC write; Underrun\n");
+			return -EIO;
+		}
+		if (tbdf[tx].cbd_sc & BD_SC_CL) {
+			dev_dbg(&adap->dev, "IIC write; Collision\n");
+			return -EIO;
+		}
+	}
+	return 0;
+}
+
+static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+	struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+	struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg;
+	struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+	struct i2c_msg *pmsg, *rmsg;
+	int ret, i;
+	int tptr;
+	int rptr;
+	cbd_t *tbdf, *rbdf;
+
+	if (num > CPM_MAXBD)
+		return -EINVAL;
+
+	/* Check if we have any oversized READ requests */
+	for (i = 0; i < num; i++) {
+		pmsg = &msgs[i];
+		if (pmsg->len >= CPM_MAX_READ)
+			return -EINVAL;
+	}
+
+	mutex_lock(&cpm->i2c_mutex);
+
+	/* Reset to use first buffer */
+	out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase));
+	out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase));
+
+	tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+	rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+	tptr = 0;
+	rptr = 0;
+
+	while (tptr < num) {
+		pmsg = &msgs[tptr];
+		dev_dbg(&adap->dev, "i2c-algo-cpm.o: " "R: %d T: %d\n",
+			rptr, tptr);
+
+		cpm_i2c_parse_message(adap, pmsg, num, tptr, rptr);
+		if (pmsg->flags & I2C_M_RD)
+			rptr++;
+		tptr++;
+	}
+	/* Start transfer now */
+	/* Chip bug, set enable here */
+	out_8(&i2c_reg->i2cmr, 0x13);	/* Enable RX/TX/Error interupts */
+	out_8(&i2c_reg->i2cer, 0xff);	/* Clear interrupt status */
+	out_8(&i2c_reg->i2mod, in_8(&i2c_reg->i2mod) | 1);	/* Enable */
+	/* Begin transmission */
+	out_8(&i2c_reg->i2com, in_8(&i2c_reg->i2com) | 0x80);
+
+	tptr = 0;
+	rptr = 0;
+
+	while (tptr < num) {
+		/* Check for outstanding messages */
+		dev_dbg(&adap->dev, "test ready.\n");
+		if (!(tbdf[tptr].cbd_sc & BD_SC_READY)) {
+			dev_dbg(&adap->dev, "ready.\n");
+			rmsg = &msgs[tptr];
+			ret = cpm_i2c_check_message(adap, rmsg, tptr, rptr);
+			tptr++;
+			if (rmsg->flags & I2C_M_RD)
+				rptr++;
+			if (ret)
+				goto out_err;
+		} else {
+			dev_dbg(&adap->dev, "not ready.\n");
+			ret = wait_event_interruptible_timeout(cpm->i2c_wait,
+				!(tbdf[tptr].cbd_sc & BD_SC_READY), 1 * HZ);
+			if (ret == 0) {
+				ret = -EREMOTEIO;
+				dev_dbg(&adap->dev, "I2C read: timeout!\n");
+				goto out_err;
+			}
+		}
+	}
+#ifdef I2C_CHIP_ERRATA
+	/*
+	 * Chip errata, clear enable. This is not needed on rev D4 CPUs.
+	 * Disabling I2C too early may cause too short stop condition
+	 */
+	udelay(4);
+	out_8(&i2c_reg->i2mod, in_8(&i2c_reg->i2mod) | ~1);
+#endif
+	mutex_unlock(&cpm->i2c_mutex);
+	return (num);
+
+out_err:
+	cpm_i2c_force_close(adap);
+#ifdef I2C_CHIP_ERRATA
+	/*
+	 * Chip errata, clear enable. This is not needed on rev D4 CPUs.
+	 */
+	out_8(&i2c_reg->i2mod, in_8(&i2c_reg->i2mod) | ~1);
+#endif
+	mutex_unlock(&cpm->i2c_mutex);
+	return ret;
+}
+
+static u32 cpm_i2c_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+/* -----exported algorithm data: -------------------------------------	*/
+
+static const struct i2c_algorithm cpm_i2c_algo = {
+	.master_xfer = cpm_i2c_xfer,
+	.functionality = cpm_i2c_func,
+};
+
+static const struct i2c_adapter cpm_ops = {
+	.owner		= THIS_MODULE,
+	.name		= "i2c-cpm",
+	.id		= I2C_HW_MPC8XX_EPON,
+	.algo		= &cpm_i2c_algo,
+	.class		= I2C_CLASS_HWMON,
+};
+
+static int cpm_i2c_setup(struct cpm_i2c *cpm)
+{
+	struct of_device *ofdev = cpm->ofdev;
+	const u32 *data;
+	int len, ret, i;
+	void __iomem *i2c_base;
+	cbd_t *tbdf, *rbdf;
+	unsigned char brg;
+
+	pr_debug("i2c-cpm: cpm_i2c_setup()\n");
+
+	init_waitqueue_head(&cpm->i2c_wait);
+	mutex_init(&cpm->i2c_mutex);
+
+	cpm->irq = of_irq_to_resource(ofdev->node, 0, NULL);
+	if (cpm->irq == NO_IRQ)
+		return -EINVAL;
+
+	/* Install interrupt handler. */
+	ret = request_irq(cpm->irq, cpm_i2c_interrupt, 0, "cpm_i2c",
+			  &cpm->adap);
+	if (ret)
+		goto out_irq;
+
+	/* IIC parameter RAM */
+	i2c_base = of_iomap(ofdev->node, 1);
+	if (i2c_base == NULL) {
+		ret = -EINVAL;
+		goto out_irq;
+	}
+
+	if (of_device_is_compatible(ofdev->node, "fsl,cpm1-i2c")) {
+
+		/* Check for and use a microcode relocation patch. */
+		cpm->i2c_ram = i2c_base;
+		cpm->i2c_addr = in_be16(&cpm->i2c_ram->rpbase);
+
+		/*
+		 * Maybe should use cpm_muram_alloc instead of hardcoding
+		 * this in micropatch.c
+		 */
+		if (cpm->i2c_addr) {
+			cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr);
+			iounmap(i2c_base);
+		}
+
+		cpm->version = 1;
+
+	} else if (of_device_is_compatible(ofdev->node, "fsl,cpm2-i2c")) {
+		cpm->i2c_addr = cpm_muram_alloc(sizeof(struct i2c_ram), 64);
+		cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr);
+		out_be16(i2c_base, cpm->i2c_addr);
+		iounmap(i2c_base);
+
+		cpm->version = 2;
+
+	} else {
+		iounmap(i2c_base);
+		ret = -EINVAL;
+		goto out_irq;
+	}
+
+	/* I2C control/status registers */
+	cpm->i2c_reg = of_iomap(ofdev->node, 0);
+	if (cpm->i2c_reg == NULL) {
+		ret = -EINVAL;
+		goto out_ram;
+	}
+
+	data = of_get_property(ofdev->node, "fsl,cpm-command", &len);
+	if (!data || len != 4) {
+		ret = -EINVAL;
+		goto out_reg;
+	}
+	cpm->cp_command = *data;
+
+	data = of_get_property(ofdev->node, "linux,i2c-class", &len);
+	if (data && len == 4)
+		cpm->adap.class = *data;
+
+	/*
+	 * Allocate space for CPM_MAXBD transmit and receive buffer
+	 * descriptors in the DP ram.
+	 */
+	cpm->dp_addr = cpm_muram_alloc(sizeof(cbd_t) * 2 * CPM_MAXBD, 8);
+	if (!cpm->dp_addr) {
+		ret = -ENOMEM;
+		goto out_reg;
+	}
+
+	/* Initialize Tx/Rx parameters. */
+
+	cpm_reset_i2c_params(cpm);
+
+	pr_debug("i2c-cpm: i2c_ram %x, dp_addr 0x%x\n", (uint) cpm->i2c_ram,
+		cpm->dp_addr);
+	pr_debug("i2c-cpm: tbase %d, rbase %d\n",
+		in_be16(&cpm->i2c_ram->tbase), in_be16(&cpm->i2c_ram->rbase));
+
+	tbdf = (cbd_t *) cpm_muram_addr(in_be16(&cpm->i2c_ram->tbase));
+	rbdf = (cbd_t *) cpm_muram_addr(in_be16(&cpm->i2c_ram->rbase));
+
+	/* Allocate TX and RX buffers */
+
+	for (i = 0; i < CPM_MAXBD; i++) {
+		cpm->rxbuf[i] = dma_alloc_coherent(
+			NULL, CPM_MAX_READ + 1, &cpm->rxdma[i], GFP_KERNEL);
+		if (!cpm->rxbuf[i]) {
+			ret = -ENOMEM;
+			goto out_muram;
+		}
+		rbdf[i].cbd_bufaddr = ((cpm->rxdma[i] + 1) & ~1);
+		cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent(
+			NULL, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL);
+		if (!cpm->txbuf[i]) {
+			ret = -ENOMEM;
+			goto out_muram;
+		}
+		tbdf[i].cbd_bufaddr = cpm->txdma[i];
+	}
+
+	cpm_command(cpm->cp_command, CPM_CR_INIT_TRX);
+
+	/*
+	 * Select an invalid address. Just make sure we don't use loopback mode
+	 */
+	out_8(&cpm->i2c_reg->i2add, 0xfe);
+
+	/* Make clock run at 60 kHz. */
+
+	brg = get_brgfreq() / (32 * 2 * 60000) - 3;
+	out_8(&cpm->i2c_reg->i2brg, brg);
+
+	out_8(&cpm->i2c_reg->i2mod, 0x00);
+	out_8(&cpm->i2c_reg->i2com, 0x01);	/* Master mode */
+
+	/* Disable interrupts. */
+	out_8(&cpm->i2c_reg->i2cmr, 0);
+	out_8(&cpm->i2c_reg->i2cer, 0xff);
+
+	return 0;
+
+out_muram:
+	for (i = 0; i < CPM_MAXBD; i++) {
+		if (cpm->rxbuf[i])
+			dma_free_coherent(NULL, CPM_MAX_READ + 1,
+				cpm->rxbuf[i], cpm->rxdma[i]);
+		if (cpm->txbuf[i])
+			dma_free_coherent(NULL, CPM_MAX_READ + 1,
+				cpm->txbuf[i], cpm->txdma[i]);
+	}
+	cpm_muram_free(cpm->dp_addr);
+out_reg:
+	iounmap(cpm->i2c_reg);
+out_ram:
+	if ((cpm->version == 1) && (!cpm->i2c_addr))
+		iounmap(cpm->i2c_ram);
+	if (cpm->version == 2)
+		cpm_muram_free(cpm->i2c_addr);
+out_irq:
+	free_irq(cpm->irq, &cpm->adap);
+	return ret;
+}
+
+static void cpm_i2c_shutdown(struct cpm_i2c *cpm)
+{
+	int i;
+
+	/* Shut down I2C. */
+	out_8(&cpm->i2c_reg->i2mod, in_8(&cpm->i2c_reg->i2mod) | ~1);
+
+	/* Disable interrupts */
+	out_8(&cpm->i2c_reg->i2cmr, 0);
+	out_8(&cpm->i2c_reg->i2cer, 0xff);
+
+	free_irq(cpm->irq, &cpm->adap);
+
+	/* Free all memory */
+	for (i = 0; i < CPM_MAXBD; i++) {
+		dma_free_coherent(NULL, CPM_MAX_READ + 1,
+			cpm->rxbuf[i], cpm->rxdma[i]);
+		dma_free_coherent(NULL, CPM_MAX_READ + 1,
+			cpm->txbuf[i], cpm->txdma[i]);
+	}
+
+	cpm_muram_free(cpm->dp_addr);
+	iounmap(cpm->i2c_reg);
+
+	if ((cpm->version == 1) && (!cpm->i2c_addr))
+		iounmap(cpm->i2c_ram);
+	if (cpm->version == 2)
+		cpm_muram_free(cpm->i2c_addr);
+
+	return;
+}
+
+static int __devinit cpm_i2c_probe(struct of_device *ofdev,
+			 const struct of_device_id *match)
+{
+	int result;
+	struct cpm_i2c *cpm;
+
+	cpm = kzalloc(sizeof(struct cpm_i2c), GFP_KERNEL);
+	if (!cpm)
+		return -ENOMEM;
+
+	cpm->ofdev = ofdev;
+
+	dev_set_drvdata(&ofdev->dev, cpm);
+
+	cpm->adap = cpm_ops;
+	i2c_set_adapdata(&cpm->adap, cpm);
+	cpm->adap.dev.parent = &ofdev->dev;
+
+	result = cpm_i2c_setup(cpm);
+	if (result) {
+		printk(KERN_ERR "i2c-cpm: Unable to init hardware\n");
+		goto out;
+	}
+
+	/* register new adapter to i2c module... */
+
+	result = i2c_add_adapter(&cpm->adap);
+	if (result < 0) {
+		printk(KERN_ERR "i2c-cpm: Unable to register with I2C\n");
+		goto out2;
+	}
+
+	pr_debug("i2c-cpm: hw routines for %s registered.\n", cpm->adap.name);
+
+	/*
+	 * Wait for patch from Jon Smirl
+	 * of_register_i2c_devices(&cpm->adap, ofdev->node);
+	 */
+
+	return 0;
+out2:
+	cpm_i2c_shutdown(cpm);
+out:
+	dev_set_drvdata(&ofdev->dev, NULL);
+	kfree(cpm);
+
+	return result;
+}
+
+static int __devexit cpm_i2c_remove(struct of_device *ofdev)
+{
+	struct cpm_i2c *cpm = dev_get_drvdata(&ofdev->dev);
+
+	i2c_del_adapter(&cpm->adap);
+
+	cpm_i2c_shutdown(cpm);
+
+	dev_set_drvdata(&ofdev->dev, NULL);
+	kfree(cpm);
+
+	return 0;
+}
+
+static const struct of_device_id cpm_i2c_match[] = {
+	{
+		.compatible = "fsl,cpm-i2c",
+	},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, cpm_i2c_match);
+
+static struct of_platform_driver cpm_i2c_driver = {
+	.match_table	= cpm_i2c_match,
+	.probe		= cpm_i2c_probe,
+	.remove		= __devexit_p(cpm_i2c_remove),
+	.driver		= {
+		.name	= "fsl-i2c-cpm",
+		.owner	= THIS_MODULE,
+	}
+};
+
+static int __init cpm_i2c_init(void)
+{
+	return of_register_platform_driver(&cpm_i2c_driver);
+}
+
+static void __exit cpm_i2c_exit(void)
+{
+	of_unregister_platform_driver(&cpm_i2c_driver);
+}
+
+module_init(cpm_i2c_init);
+module_exit(cpm_i2c_exit);
+
+MODULE_AUTHOR("Dan Malek <dmalek@jlc.net>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for CPM boards");
+MODULE_LICENSE("GPL");
-- 
1.5.3.8

^ permalink raw reply related

* Re: [PATCH 5/5] [POWERPC] fsl_soc, legacy_serial: add support for "soc" compatible matching
From: Anton Vorontsov @ 2008-01-25 17:26 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Scott Wood, linuxppc-dev list, Yoder Stuart
In-Reply-To: <20080125171355.GA9879@localhost.localdomain>

On Fri, Jan 25, 2008 at 08:13:55PM +0300, Anton Vorontsov wrote:
[...]
> My thinking:
> 
> Freescale soc register space: "fsl,soc"
> generic soc device: "soc" (or maybe "linux,soc" better?)
> 
> I know, Scott Wood is pushing "xxxx-immr" thing forward... but
> I don't like that name because SOC isn't only device with the
> Internal Memory Mapped Registers. (Think of QE placed outside
> of "soc"/"immr" node).
> 
> Though, "soc" by itself is fully unfortunate name. QE is the
> part of SOC too, as we used to call it when speaking of hardware.
> But logically we divide things for "core soc" and "core soc's
> companion/communication/offload modules", i.e. QE/CPMs/...
> 
> We can remove that ambiguity by moving QE/CPMs nodes inside
> the soc node. Then indeed -immr would be the best compatible for
> the "soc" node.

Oh, and yes, I'm aware that CPM's IMMRs are relocatable, and
that's [most probably] why we have CPMs outside of soc node.
So, my point is that that -immr name is too vague, so in my
opinion we should avoid using it.

-- 
Anton Vorontsov
email: cbou@mail.ru
backup email: ya-cbou@yandex.ru
irc://irc.freenode.net/bd2

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox