Hi all, 
This patch is to enable 2D Engine in SM501 video chip to hurry up fresh speed. 
It change some 2D Engine registers and could obviously fasten screen scroll up. 
I think it's reasonable to do it for consumerism.


commit 02e99b0a871f91fd3598024a2468a059971ef28d
Parent: 699f05125509249072a0b865c8d35520d97cd501
Author: Ryan Chen <[EMAIL PROTECTED]>
Date:   Wed Jul 30 09:45:01 2008 -0400

    Signed-off-by: Ryan Chen <[EMAIL PROTECTED]>
    
        modified:   drivers/video/sm501.c

diff --git a/drivers/video/sm501.c b/drivers/video/sm501.c
old mode 100644
new mode 100755
index 23db02c..f20cf94
--- a/drivers/video/sm501.c
+++ b/drivers/video/sm501.c
@@ -35,6 +35,7 @@
 
 #include <video_fb.h>
 #include <sm501.h>
+#include <asm/io.h>
 
 #define read8(ptrReg)                \
     *(volatile unsigned char *)(sm501.isaBase + ptrReg)
@@ -54,6 +55,46 @@
 #define write32(ptrReg, value) \
     (*(volatile unsigned int *)(sm501.isaBase + ptrReg) = value)
 
+/* Register Macroes*/
+#define _F_START(f)             (0 ? f)
+#define _F_END(f)               (1 ? f)
+#define _F_SIZE(f)              (1 + _F_END(f) - _F_START(f))
+#define _F_MASK(f)              (((1 << _F_SIZE(f)) - 1) << _F_START(f))
+#define _F_NORMALIZE(v, f)      (((v) & _F_MASK(f)) >> _F_START(f))
+#define _F_DENORMALIZE(v, f)    (((v) << _F_START(f)) & _F_MASK(f))
+#define FIELD_GET(x, reg, field) \
+( \
+    _F_NORMALIZE((x), reg ## _ ## field) \
+)
+#define FIELD_SET(x, reg, field, value) \
+( \
+    (x & ~_F_MASK(reg ## _ ## field)) \
+    | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \
+)
+#define FIELD_VALUE(x, reg, field, value) \
+( \
+    (x & ~_F_MASK(reg ## _ ## field)) \
+    | _F_DENORMALIZE(value, reg ## _ ## field) \
+)
+#define FIELD_CLEAR(reg, field) \
+( \
+    ~ _F_MASK(reg ## _ ## field) \
+)
+#define FIELD_START(field)              (0 ? field)
+#define FIELD_END(field)                (1 ? field)
+#define FIELD_SIZE(field)               (1 + FIELD_END(field) - 
FIELD_START(field))
+#define FIELD_MASK(field)               (((1 << (FIELD_SIZE(field)-1)) | ((1 
<< (FIELD_SIZE(field)-1)) - 1)) << FIELD_START(field))
+#define FIELD_NORMALIZE(reg, field)     (((reg) & FIELD_MASK(field)) >> 
FIELD_START(field))
+#define FIELD_DENORMALIZE(field, value) (((value) << FIELD_START(field)) & 
FIELD_MASK(field))
+#define FIELD_INIT(reg, field, value)   FIELD_DENORMALIZE(reg ## _ ## field, \
+                                                          reg ## _ ## field ## 
_ ## value)
+#define FIELD_INIT_VAL(reg, field, value) \
+                                        (FIELD_DENORMALIZE(reg ## _ ## field, 
value))
+#define FIELD_VAL_SET(x, r, f, v)       x = x & ~FIELD_MASK(r ## _ ## f) \
+                                              | FIELD_DENORMALIZE(r ## _ ## f, 
r ## _ ## f ## _ ## v)
+
+#define SM501_TIMEOUT          20000   /* 20 ms */
+
 GraphicDevice sm501;
 
 /*-----------------------------------------------------------------------------
@@ -77,11 +118,148 @@ static void SmiSetRegs (void)
        }
 }
 
+static void set_current_gate(void)
+{
+       unsigned long value, gate;
+       /* change to mode0 */
+       value = read32(POWER_MODE_CTRL);
+       value = FIELD_SET(value, POWER_MODE_CTRL, MODE, MODE0);
+       write32(POWER_MODE_CTRL, value);
+
+       /* Don't forget to set up power mode0 gate properly. */
+       gate = read32(CURRENT_POWER_GATE);
+       gate = FIELD_SET(gate, CURRENT_POWER_GATE, 2D,  ENABLE);
+       write32(POWER_MODE0_GATE, gate);        
+}
+
+/* Program new power mode. */
+static void setPower(unsigned long nGates, unsigned long Clock)
+{
+       unsigned long gate_reg, clock_reg;
+       unsigned long control_value;
+       u32 i;
+
+       /*  Get current power mode. */
+       control_value = FIELD_GET(read32(POWER_MODE_CTRL),
+               POWER_MODE_CTRL,
+               MODE);
+
+       switch (control_value)
+       {
+               case POWER_MODE_CTRL_MODE_MODE0:
+               /* Switch from mode 0 to mode 1.*/
+               gate_reg = POWER_MODE1_GATE;
+               clock_reg = POWER_MODE1_CLOCK;
+               control_value = FIELD_SET(control_value,
+                       POWER_MODE_CTRL, MODE, MODE1);
+               break;
+
+               case POWER_MODE_CTRL_MODE_MODE1:
+               case POWER_MODE_CTRL_MODE_SLEEP:
+               /* Switch from mode 1 or sleep to mode 0.*/
+               gate_reg = POWER_MODE0_GATE;
+               clock_reg = POWER_MODE0_CLOCK;
+               control_value = FIELD_SET(control_value, POWER_MODE_CTRL, MODE, 
MODE0);
+               break;
+
+               default:
+               /* Invalid mode */
+               return;
+       }
+
+       /* Program new power mode. */
+       write32(gate_reg, nGates);
+       write32(clock_reg, Clock);
+       write32(POWER_MODE_CTRL, control_value);
+
+       /* When returning from sleep, wait until finished. */
+       i = SM501_TIMEOUT;
+       while ((FIELD_GET(read32(POWER_MODE_CTRL), POWER_MODE_CTRL, \
+               SLEEP_STATUS) == POWER_MODE_CTRL_SLEEP_STATUS_ACTIVE) && (i != 
0)) {
+               udelay(1);
+               i--;
+       }
+       if(i == 0) {
+               printf("setPower Timeout!\n");
+       }
+}
+
+static void deInit(unsigned int nModeWidth, unsigned int nModeHeight, unsigned 
int bpp)
+{
+       unsigned int gate, clock;
+       /* Get current power configuration*/
+       gate  = read32(CURRENT_POWER_GATE);
+       clock = read32(CURRENT_POWER_CLOCK);
+       /* Enable 2D Drawing Engine */
+       gate = FIELD_SET(gate, CURRENT_POWER_GATE, 2D, ENABLE);
+       setPower(gate, clock);
+
+       write32((DE_REGISTER_OFFSET + DE_CLIP_TL), \
+               FIELD_VALUE(0, DE_CLIP_TL, TOP,     0) | \
+               FIELD_SET  (0, DE_CLIP_TL, STATUS,  DISABLE) | \
+               FIELD_SET  (0, DE_CLIP_TL, INHIBIT, OUTSIDE) | \
+               FIELD_VALUE(0, DE_CLIP_TL, LEFT,    0));
+
+       write32((DE_REGISTER_OFFSET + DE_PITCH), \
+               FIELD_VALUE(0, DE_PITCH, DESTINATION, nModeWidth) | 
+               FIELD_VALUE(0, DE_PITCH, SOURCE, nModeWidth));
+
+       write32((DE_REGISTER_OFFSET + DE_WINDOW_WIDTH), \
+               FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, nModeWidth) | \
+               FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, nModeWidth));
+
+       switch (bpp)
+       {
+               case 1:
+               write32((DE_REGISTER_OFFSET + DE_STRETCH_FORMAT), \
+                       FIELD_SET  (0, DE_STRETCH_FORMAT, PATTERN_XY, NORMAL) | 
\
+                       FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_Y, 0) | \
+                       FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, 0) | \
+                       FIELD_SET  (0, DE_STRETCH_FORMAT, PIXEL_FORMAT, 8) | \
+                       FIELD_SET  (0, DE_STRETCH_FORMAT, ADDRESSING, XY) | \
+                       FIELD_VALUE(0, DE_STRETCH_FORMAT, SOURCE_HEIGHT, 3));
+               break;
+
+               case 4:
+               write32((DE_REGISTER_OFFSET + DE_STRETCH_FORMAT), \
+                       FIELD_SET  (0, DE_STRETCH_FORMAT, PATTERN_XY, NORMAL) | 
\
+                       FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_Y, 0) | \
+                       FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, 0) | \
+                       FIELD_SET  (0, DE_STRETCH_FORMAT, PIXEL_FORMAT, 32) | \
+                       FIELD_SET  (0, DE_STRETCH_FORMAT, ADDRESSING, XY) | \
+                       FIELD_VALUE(0, DE_STRETCH_FORMAT, SOURCE_HEIGHT, 3));
+               break;
+
+               case 2:
+               default:
+               write32((DE_REGISTER_OFFSET + DE_STRETCH_FORMAT), \
+                       FIELD_SET  (0, DE_STRETCH_FORMAT, PATTERN_XY, NORMAL) | 
\
+                       FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_Y, 0) | \
+                       FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, 0) | \
+                       FIELD_SET  (0, DE_STRETCH_FORMAT, PIXEL_FORMAT, 16) | \
+                       FIELD_SET  (0, DE_STRETCH_FORMAT, ADDRESSING, XY) | \
+                       FIELD_VALUE(0, DE_STRETCH_FORMAT, SOURCE_HEIGHT, 3));
+               break;
+       }
+
+       write32((DE_REGISTER_OFFSET + DE_MASKS), \
+               FIELD_VALUE(0, DE_MASKS, BYTE_MASK, 0xFFFF) | \
+               FIELD_VALUE(0, DE_MASKS, BIT_MASK,  0xFFFF));
+       write32((DE_REGISTER_OFFSET + DE_COLOR_COMPARE_MASK), \
+               FIELD_VALUE(0, DE_COLOR_COMPARE_MASK, MASKS, 0xFFFFFF));
+       write32((DE_REGISTER_OFFSET + DE_COLOR_COMPARE), \
+               FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, 0xFFFFFF));
+}
+
 /*-----------------------------------------------------------------------------
  * video_hw_init --
  *-----------------------------------------------------------------------------
  */
+#if defined CONFIG_MULTI_VIDEO_CARD
+void *sm501_video_hw_init (void)
+#else
 void *video_hw_init (void)
+#endif
 {
        unsigned int *vm, i;
 
@@ -124,6 +302,10 @@ void *video_hw_init (void)
 
        /* (see board/RPXClassic/RPXClassic.c) */
        board_validate_screen (sm501.isaBase);
+       
+       set_current_gate();
+       
+       deInit(sm501.winSizeX, sm501.winSizeY, sm501.gdfBytesPP);
 
        /* Clear video memory */
        i = sm501.memSize/4;
@@ -138,7 +320,11 @@ void *video_hw_init (void)
  * video_set_lut --
  *-----------------------------------------------------------------------------
  */
+#if defined CONFIG_MULTI_VIDEO_CARD
+void sm501_video_set_lut (
+#else
 void video_set_lut (
+#endif
        unsigned int index,           /* color number */
        unsigned char r,              /* red */
        unsigned char g,              /* green */
@@ -147,4 +333,160 @@ void video_set_lut (
 {
 }
 
+#if defined CONFIG_MULTI_VIDEO_CARD
+void sm501_video_hw_bitblt (
+#else
+void video_hw_bitblt (
+#endif
+       unsigned int bpp,             /* bytes per pixel */
+       unsigned int src_x,           /* source pos x */
+       unsigned int src_y,           /* source pos y */
+       unsigned int dst_x,           /* dest pos x */
+       unsigned int dst_y,           /* dest pos y */
+       unsigned int dim_x,           /* frame width */
+       unsigned int dim_y            /* frame height */
+       )
+{
+       u8 nDirection = 0;
+       u32 de_ctrl = 0;
+       u32 i;
+
+       /* clear 2d interrupt */
+       write32((DE_REGISTER_OFFSET + DE_STATUS), read32(DE_REGISTER_OFFSET + 
DE_STATUS) &~ 0x1);
+       write32((DE_REGISTER_OFFSET + DE_PITCH), FIELD_VALUE(0, DE_PITCH, 
DESTINATION, dim_x) | \
+               FIELD_VALUE(0, DE_PITCH, SOURCE, dim_x));
+       write32((DE_REGISTER_OFFSET + DE_WINDOW_WIDTH), FIELD_VALUE(0, 
DE_WINDOW_WIDTH, \
+               DESTINATION, dim_x) | FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, 
dim_x));
+       write32((DE_REGISTER_OFFSET + DE_WINDOW_SOURCE_BASE), FIELD_VALUE(0, 
DE_WINDOW_SOURCE_BASE, \
+               ADDRESS, 0));
+       write32((DE_REGISTER_OFFSET + DE_WINDOW_DESTINATION_BASE), 
FIELD_VALUE(0, \
+               DE_WINDOW_DESTINATION_BASE, ADDRESS, 0));
+       if (src_y < dst_y) {
+               /* +----------+
+               |S         |
+               |   +----------+
+               |   |      |   |
+               |   |      |   |
+               +---|------+   |
+               |         D|
+               +----------+ */
+               nDirection = BOTTOM_TO_TOP;
+       } else if (src_y > dst_y) {
+               /* +----------+
+               |D         |
+               |   +----------+
+               |   |      |   |
+               |   |      |   |
+               +---|------+   |
+               |         S|
+               +----------+ */
+               nDirection = TOP_TO_BOTTOM;
+       } else {
+               /* nSrcY == nDestY */
+               if (src_x <= dst_x) {
+                       /* +------+---+------+
+                       |S     |   |     D|
+                       |      |   |      |
+                       |      |   |      |
+                       |      |   |      |
+                       +------+---+------+ */
+                       nDirection = RIGHT_TO_LEFT;
+               } else {
+                       /* nSrcX > nDestX */
+                       /* +------+---+------+
+                       |D     |   |     S|
+                       |      |   |      |
+                       |      |   |      |
+                       |      |   |      |
+                       +------+---+------+ */
+                       nDirection = LEFT_TO_RIGHT;
+               }
+       }
+
+       if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) {
+               src_x += dim_x - 1;
+               src_y += dim_y - 1;
+               dst_x += dim_x - 1;
+               dst_y += dim_y - 1;
+       } 
+
+       write32((DE_REGISTER_OFFSET + DE_SOURCE), \
+               FIELD_SET  (0, DE_SOURCE, WRAP, DISABLE) | \
+               FIELD_VALUE(0, DE_SOURCE, X_K1, src_x)| \
+               FIELD_VALUE(0, DE_SOURCE, Y_K2, src_y));
+       write32((DE_REGISTER_OFFSET + DE_DESTINATION), \
+               FIELD_SET  (0, DE_DESTINATION, WRAP, DISABLE) | \
+               FIELD_VALUE(0, DE_DESTINATION, X,    dst_x)  | \
+               FIELD_VALUE(0, DE_DESTINATION, Y,    dst_y));
+       write32((DE_REGISTER_OFFSET + DE_DIMENSION), \
+               FIELD_VALUE(0, DE_DIMENSION, X,    dim_x) | \
+               FIELD_VALUE(0, DE_DIMENSION, Y_ET, dim_y));
+       de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, 0x0c) | \
+               FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | \
+               FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) | \
+               ((nDirection == 1) ? FIELD_SET(0, DE_CONTROL, 
DIRECTION,RIGHT_TO_LEFT):  \
+               FIELD_SET(0, DE_CONTROL, DIRECTION,LEFT_TO_RIGHT)) | \
+               FIELD_SET(0, DE_CONTROL, STATUS, START);
+       write32((DE_REGISTER_OFFSET + DE_CONTROL), de_ctrl);
+       
+       i  = SM501_TIMEOUT;
+       while(((read32(DE_REGISTER_OFFSET + DE_STATUS) & 0x1) == 0x0) && (i != 
0)) {
+               udelay(1);
+               i--;
+       }
+       if(i == 0) {
+               printf("sm501_video_hw_rectfill Timeout!\n");
+       }
+       /* clear 2d interrupt */
+       write32((DE_REGISTER_OFFSET + DE_STATUS), read32(DE_REGISTER_OFFSET + 
DE_STATUS) &~ 0x1);
+}
+
+#if defined CONFIG_MULTI_VIDEO_CARD
+void sm501_video_hw_rectfill (
+#else
+void video_hw_rectfill (
+#endif
+       unsigned int bpp,             /* bytes per pixel */
+       unsigned int dst_x,           /* dest pos x */
+       unsigned int dst_y,           /* dest pos y */
+       unsigned int dim_x,           /* frame width */
+       unsigned int dim_y,           /* frame height */
+       unsigned int color            /* fill color */
+       )
+{
+       u32 i;
+
+       /* clear 2d interrupt */
+       write32((DE_REGISTER_OFFSET + DE_STATUS), read32(DE_REGISTER_OFFSET + 
DE_STATUS) &~ 0x1);
+       write32((DE_REGISTER_OFFSET + DE_WINDOW_DESTINATION_BASE), \
+               FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, 0));
+       write32((DE_REGISTER_OFFSET + DE_FOREGROUND), color);
+       write32((DE_REGISTER_OFFSET + DE_DESTINATION),  \
+               FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | \
+               FIELD_VALUE(0, DE_DESTINATION, X, dst_x) | \
+               FIELD_VALUE(0, DE_DESTINATION, Y, dst_y));
+
+       write32((DE_REGISTER_OFFSET + DE_DIMENSION), \
+               FIELD_VALUE(0, DE_DIMENSION, X, dim_x + 1) | \
+               FIELD_VALUE(0, DE_DIMENSION, Y_ET, dim_y + 1));
+
+       write32((DE_REGISTER_OFFSET + DE_CONTROL), \
+               FIELD_SET  (0, DE_CONTROL, STATUS, START) | \
+               FIELD_SET  (0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | \
+               FIELD_SET  (0, DE_CONTROL, LAST_PIXEL, OFF) | \
+               FIELD_SET  (0, DE_CONTROL, COMMAND, RECTANGLE_FILL) | \
+               FIELD_SET  (0, DE_CONTROL, ROP_SELECT, ROP2) | \
+               FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C));
+
+       i  = SM501_TIMEOUT;
+       while(((read32(DE_REGISTER_OFFSET + DE_STATUS) & 0x1) == 0x0) && (i != 
0)) {
+               udelay(1);
+               i--;
+       }
+       if(i == 0) {
+               printf("sm501_video_hw_rectfill Timeout!\n");
+       }
+       /* clear 2d interrupt */
+       write32((DE_REGISTER_OFFSET + DE_STATUS), read32(DE_REGISTER_OFFSET + 
DE_STATUS) &~ 0x1);
+}
 #endif /* CONFIG_VIDEO_SM501 */

Best Regards,
Ryan Chen


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
U-Boot-Users mailing list
U-Boot-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/u-boot-users

Reply via email to