:Enable 2D Engine in SM501 to hurry up fresh speed!
PATCH 1/1 :Enable 2D Engine in SM501 to hurry up fresh speed!
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
modified: drivers/video/sm501.c
drivers/video/sm501.c +342 -0
@@ -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 definedCONFIG_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
PATCH 1/1 :Enable 2D Engine in SM501 to hurry up fresh speed!
Quoted 2 lines · In message <[email protected]> you wrote:
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.
Your line is way too long.
What exactly is "fresh speed"?
For "consumerism" ?
Quoted 8 lines
commit
02e99b0a871f91fd3598024a2468a059971ef28dParent: 699f05125509249072a0b865c8d35520d97cd501 Author: Ryan Chen <[email protected]> Date: Wed Jul 30 09:45:01 2008 -0400Signed-off-by Ryan Chen <[email protected]>modified:
drivers/video/sm501.c
Please format your patches using git-format-patch and make sure to supply a reasonable comit message.
Your patch adds a lot of code that may or may not be needed on some systems. Please make it optional using a CONFIG_ option.
drivers/video/sm501.c
Quoted 3 lines
drivers/video/sm501.c +0
-0
Please do not set exec permissions on plain source files.
drivers/video/sm501.c line 38
Quoted 8 lines
index 23db02c..f20cf94
drivers/video/sm501.c +1
-0@@ -35,6 +35,7 @@#include <video_fb.h> #include <sm501.h> +#include <asm/io.h>
What is this needed for?
...
Quoted 4 lines
drivers/video/sm501.c +4
-0+/* Program new power mode. */ +static void setPower (unsigned long nGates,unsigned long Clock) +{ +unsigned long gate_reg, clock_reg;
drivers/video/sm501.c static void SmiSetRegs (void) · line 148
Quoted 10 lines
drivers/video/sm501.c +10
-0+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) + {
Coding Style:
switch (control_value) {drivers/video/sm501.c static void SmiSetRegs (void) · line 212
Quoted 2 lines
drivers/video/sm501.c +2
-0+switch (bpp) + {
Ditto...
drivers/video/sm501.c static void SmiSetRegs (void) · line 262
Quoted 5 lines
drivers/video/sm501.c +4
-0+#if definedCONFIG_MULTI_VIDEO_CARD +void *sm501_video_hw_init (void) +#else void *video_hw_init (void) +#endif
This seems to be an unrelated change that should be plit into a separate patch.
Best regards,
Wolfgang Denk
Signature · 6 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de He had quite a powerful intellect, but it was as powerful like a locomotive, and ran on rails and was therefore almost impossible to steer. - Terry Pratchett, _Lords and Ladies_
PATCH 1/1 :Enable 2D Engine in SM501 to hurry up fresh speed!
Hi Wolfgang,
I have modified my patch. New macro "CONFIG_SM501_ENABLE_2DENGINE" be included to specify codes what enable SM501 2D engine. The macro need be declared in config header file.
Why does it need to enable 2D engine? The reason is most of framebuffer contents need be moved in VRAM when screen scrolls up. The work be done by software in current U-Boot for SM501. The patch is to enable 2D engine to do it by hardware without CPU interference.
drivers/video/sm501.c +29 -0
@@ -54,6 +54,48 @@#define write32 (ptrReg, value) \ (*(volatile unsigned int *)(sm501.isaBase + ptrReg) = value) +#ifdef CONFIG_SM501_ENABLE_2DENGINE +/* 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 */
+#endif/* CONFIG_SM501_ENABLE_2DENGINE */
+
GraphicDevice sm501;
/*--------------------------------------------------------------------------
---
@@ -77,11 +119,148 @@ static void SmiSetRegs (void)
}
}
+#ifdef CONFIG_SM501_ENABLE_2DENGINE
+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));
+}
+#endif/* CONFIG_SM501_ENABLE_2DENGINE */
+
/*--------------------------------------------------------------------------
---
* 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;
@@ -125,6 +304,12 @@ void *video_hw_init (void)
/* (see board/RPXClassic/RPXClassic.c) */
board_validate_screen (sm501.isaBase);
+#ifdef CONFIG_SM501_ENABLE_2DENGINE
+ set_current_gate();
+
+ deInit(sm501.winSizeX, sm501.winSizeY, sm501.gdfBytesPP);
+#endif/* CONFIG_SM501_ENABLE_2DENGINE*/
+
/* Clear video memory */
i = sm501.memSize/4;
vm = (unsigned int *)sm501.frameAdrs;
@@ -138,7 +323,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 +336,162 @@ void video_set_lut (
{
}
+#ifdef CONFIG_SM501_ENABLE_2DENGINE
+#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_SM501_ENABLE_2DENGINE*/
#endif /* CONFIG_VIDEO_SM501 */
Best Regards,
Ryan Chen
-----Original Message-----
From: [email protected] [mailto:wd at denx.de]
Sent: Wednesday, July 30, 2008 4:10 PM
To: Ryan CHEN
Cc: u-boot-users at lists.sourceforge.net; Antonio Maria BORNEO
Subject: Re: [U-Boot-Users] [PATCH]:Enable 2D Engine in SM501 to hurry up fresh speed!
Quoted 2 lines · In message <[email protected]> you wrote:
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.
Your line is way too long.
What exactly is "fresh speed"?
For "consumerism" ?
Quoted 8 lines
commit
02e99b0a871f91fd3598024a2468a059971ef28dParent: 699f05125509249072a0b865c8d35520d97cd501 Author: Ryan Chen <[email protected]> Date: Wed Jul 30 09:45:01 2008 -0400Signed-off-by Ryan Chen <[email protected]>modified:
drivers/video/sm501.c
Please format your patches using git-format-patch and make sure to supply a reasonable comit message.
Your patch adds a lot of code that may or may not be needed on some systems. Please make it optional using a CONFIG_ option.
Quoted 2 lines
drivers/video/sm501.c old mode renamed from drivers/video/sm501.c +0
-0100644 new mode 100755
Please do not set exec permissions on plain source files.
drivers/video/sm501.c line 38
Quoted 8 lines
index 23db02c..f20cf94
drivers/video/sm501.c +1
-0@@ -35,6 +35,7 @@#include <video_fb.h> #include <sm501.h> +#include <asm/io.h>
What is this needed for?
...
drivers/video/sm501.c
Quoted 13 lines
drivers/video/sm501.c +13
-0+/* 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) + {
Coding Style:
switch (control_value) {drivers/video/sm501.c
Quoted 2 lines
drivers/video/sm501.c +2
-0+switch (bpp) + {
Ditto...
drivers/video/sm501.c
Quoted 5 lines
drivers/video/sm501.c +4
-0+#if definedCONFIG_MULTI_VIDEO_CARD +void *sm501_video_hw_init (void) +#else void *video_hw_init (void) +#endif
This seems to be an unrelated change that should be plit into a separate patch.
Best regards,
Wolfgang Denk
Signature · 6 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de He had quite a powerful intellect, but it was as powerful like a locomotive, and ran on rails and was therefore almost impossible to steer. - Terry Pratchett, _Lords and Ladies_
PATCH 1/1 :Enable 2D Engine in SM501 to hurry up fresh speed!
Dear Ryan,
Quoted 10 lines · in message <[email protected]> you wrote:
Hi Wolfgang,
I have modified my patch. New macro "CONFIG_SM501_ENABLE_2DENGINE" be included to specify codes what enable SM501 2D engine. The macro need be declared in config header file.
Why does it need to enable 2D engine? The reason is most of framebuffer contents need be moved in VRAM when screen scrolls up. The work be done by software in current U-Boot for SM501. The patch is to enable 2D engine to do it by hardware without CPU interference.Signed-off-by Ryan Chen <[email protected]>
Could you please use git-format-patch to create the patch, and git-send-email to send it? This might avoid problems like the line wrapping - see below.
Also, please spend a few seconds on thinking about which text you want to see in the commit message. As submitted here, the whole text:
Hi Wolfgang,
I have modified my patch. ...
...
would make it into the commit message. I do not think that was your intention. Comments about the patch etc. should go *below* the "---" line that gets inserted by git-format-patch.
Well, but the real problem with your poatch is here:
...
Quoted 2 lines
+#define
FIELD_SIZE(field)(1 +FIELD_END(field)-FIELD_START(field))
^^^^^^^^^^^^^^^^^^^^^^^
Quoted 2 lines
+#define
FIELD_MASK(field)(((1 << (FIELD_SIZE(field)-1)) |
((1 << (FIELD_SIZE(field)-1)) - 1)) <<FIELD_START(field))
^^^^^^^^^^^^^^^^^^^^^^^
Quoted 2 lines
+#define
FIELD_NORMALIZE(reg, field)(((reg) &FIELD_MASK(field)) >>FIELD_START(field))
^^^^^^^^^^^^^^^^^^^^^^^
Quoted 2 lines
+#define
FIELD_DENORMALIZE(field, value)(((value) <<FIELD_START(field)) &FIELD_MASK(field))
^^^^^^^^^^^^^^^^^^^^^^^
Quoted 2 lines
+#define
FIELD_INIT(reg, field, value)FIELD_DENORMALIZE(reg ## _ ##
field, \
^^^^^^^^^^^^^^^^^^^^^^^
Quoted 2 lines
+ reg ## _ ## field
## _ ## value)
^^^^^^^^^^^^^^^^^^^^^^^
Quoted 3 lines
(quoted diff) +2
-0+#define FIELD_INIT_VAL(reg, field, value) \ + (FIELD_DENORMALIZE(reg ## _ ##field, value))
^^^^^^^^^^^^^^^^^^^^^^^
Quoted 3 lines
(quoted diff) +2
-0+#define FIELD_VAL_SET(x, r, f, v) x = x & ~FIELD_MASK(r ## _ ## f) \ + | FIELD_DENORMALIZE(r ## _ ##f, r ## _ ## f ## _ ## v)
^^^^^^^^^^^^^^^^^^^^^^^
And so on - your mailer is wrapping long lines, thus corrupting the patch. It's unusable as is.
Best regards,
Wolfgang Denk
Signature · 5 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de There are always alternatives. -- Spock, "The Galileo Seven", stardate 2822.3
PATCH 1/1 :Enable 2D Engine in SM501 to hurry up fresh speed!
In reply to Ryan CHENQuoted 10 lines · In message <[email protected]> you wrote:
Hi Wolfgang,
I have modified my patch. New macro "CONFIG_SM501_ENABLE_2DENGINE" be included to specify codes what enable SM501 2D engine. The macro need be declared in config header file.
Why does it need to enable 2D engine? The reason is most of framebuffer contents need be moved in VRAM when screen scrolls up. The work be done by software in current U-Boot for SM501. The patch is to enable 2D engine to do it by hardware without CPU interference.Signed-off-by Ryan Chen <[email protected]>
Also note that there are coding style violations: trailing white space, indentation/vertical alignment by spaces instead of TABs, incorrect vertical alignment of "switch" / "case".
Please fix these before you resubmit.
Best regards,
Wolfgang Denk
Signature · 4 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de "At least they're __________EXPERIENCED incompetents"