blob: bcc09e5212e3ed3262f9536110a607ca8d39e2a0 [file] [log] [blame]
Mike Rapoport67088d42015-09-22 12:01:16 +03001#include <linux/module.h>
2#include <linux/kernel.h>
3#include <linux/errno.h>
4#include <linux/string.h>
5#include <linux/mm.h>
6#include <linux/slab.h>
7#include <linux/delay.h>
8#include <linux/fb.h>
9#include <linux/ioport.h>
10#include <linux/init.h>
11#include <linux/pci.h>
12#include <linux/vmalloc.h>
13#include <linux/pagemap.h>
Sudip Mukherjee81dee672015-03-03 16:21:06 +053014#include <linux/console.h>
Mike Rapoport67088d42015-09-22 12:01:16 +030015#include <linux/platform_device.h>
16#include <linux/screen_info.h>
Sudip Mukherjee81dee672015-03-03 16:21:06 +053017
18#include "sm750.h"
19#include "sm750_accel.h"
20#include "sm750_help.h"
Greg Donaldeb0f4272015-06-18 15:06:56 -050021static inline void write_dpr(struct lynx_accel *accel, int offset, u32 regValue)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053022{
Isaac Assegaib5d63972015-06-02 03:14:27 -070023 writel(regValue, accel->dprBase + offset);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053024}
25
Greg Donaldeb0f4272015-06-18 15:06:56 -050026static inline u32 read_dpr(struct lynx_accel *accel, int offset)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053027{
28 return readl(accel->dprBase + offset);
29}
30
Greg Donaldeb0f4272015-06-18 15:06:56 -050031static inline void write_dpPort(struct lynx_accel *accel, u32 data)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053032{
Isaac Assegaib5d63972015-06-02 03:14:27 -070033 writel(data, accel->dpPortBase);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053034}
35
Greg Donaldeb0f4272015-06-18 15:06:56 -050036void hw_de_init(struct lynx_accel *accel)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053037{
38 /* setup 2d engine registers */
Isaac Assegaib5d63972015-06-02 03:14:27 -070039 u32 reg, clr;
Juston Li919ca7c2015-07-14 21:14:43 -070040
Isaac Assegaib5d63972015-06-02 03:14:27 -070041 write_dpr(accel, DE_MASKS, 0xFFFFFFFF);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053042
43 /* dpr1c */
Isaac Assegaib5d63972015-06-02 03:14:27 -070044 reg = FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, NORMAL)|
45 FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_Y, 0)|
46 FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, 0)|
47 FIELD_SET(0, DE_STRETCH_FORMAT, ADDRESSING, XY)|
48 FIELD_VALUE(0, DE_STRETCH_FORMAT, SOURCE_HEIGHT, 3);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053049
Isaac Assegaib5d63972015-06-02 03:14:27 -070050 clr = FIELD_CLEAR(DE_STRETCH_FORMAT, PATTERN_XY)&
51 FIELD_CLEAR(DE_STRETCH_FORMAT, PATTERN_Y)&
52 FIELD_CLEAR(DE_STRETCH_FORMAT, PATTERN_X)&
53 FIELD_CLEAR(DE_STRETCH_FORMAT, ADDRESSING)&
54 FIELD_CLEAR(DE_STRETCH_FORMAT, SOURCE_HEIGHT);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053055
Matej Vasekfbb8c962016-01-25 16:02:33 +010056 /* DE_STRETCH bpp format need be initialized in setMode routine */
Isaac Assegaib5d63972015-06-02 03:14:27 -070057 write_dpr(accel, DE_STRETCH_FORMAT, (read_dpr(accel, DE_STRETCH_FORMAT) & clr) | reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053058
59 /* disable clipping and transparent */
Juston Li5ee35ea2015-06-12 03:17:22 -070060 write_dpr(accel, DE_CLIP_TL, 0); /* dpr2c */
61 write_dpr(accel, DE_CLIP_BR, 0); /* dpr30 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +053062
Juston Li5ee35ea2015-06-12 03:17:22 -070063 write_dpr(accel, DE_COLOR_COMPARE_MASK, 0); /* dpr24 */
Isaac Assegaib5d63972015-06-02 03:14:27 -070064 write_dpr(accel, DE_COLOR_COMPARE, 0);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053065
Mike Rapoporte2e22582016-02-15 19:54:00 +020066 clr = DE_CONTROL_TRANSPARENCY | DE_CONTROL_TRANSPARENCY_MATCH |
67 DE_CONTROL_TRANSPARENCY_SELECT;
Sudip Mukherjee81dee672015-03-03 16:21:06 +053068
69 /* dpr0c */
Mike Rapoporte2e22582016-02-15 19:54:00 +020070 write_dpr(accel, DE_CONTROL, read_dpr(accel, DE_CONTROL) & ~clr);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053071}
72
73/* set2dformat only be called from setmode functions
74 * but if you need dual framebuffer driver,need call set2dformat
75 * every time you use 2d function */
76
Greg Donaldeb0f4272015-06-18 15:06:56 -050077void hw_set2dformat(struct lynx_accel *accel, int fmt)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053078{
79 u32 reg;
Juston Li919ca7c2015-07-14 21:14:43 -070080
Sudip Mukherjee81dee672015-03-03 16:21:06 +053081 /* fmt=0,1,2 for 8,16,32,bpp on sm718/750/502 */
Isaac Assegaib5d63972015-06-02 03:14:27 -070082 reg = read_dpr(accel, DE_STRETCH_FORMAT);
83 reg = FIELD_VALUE(reg, DE_STRETCH_FORMAT, PIXEL_FORMAT, fmt);
84 write_dpr(accel, DE_STRETCH_FORMAT, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053085}
86
Greg Donaldeb0f4272015-06-18 15:06:56 -050087int hw_fillrect(struct lynx_accel *accel,
Isaac Assegaib5d63972015-06-02 03:14:27 -070088 u32 base, u32 pitch, u32 Bpp,
89 u32 x, u32 y, u32 width, u32 height,
90 u32 color, u32 rop)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053091{
92 u32 deCtrl;
93
Juston Li259fef32015-07-14 21:14:45 -070094 if (accel->de_wait() != 0) {
Sudip Mukherjee81dee672015-03-03 16:21:06 +053095 /* int time wait and always busy,seems hardware
96 * got something error */
Hari Prasath Gujulan Elango7211f6f2015-06-24 16:51:21 +000097 pr_debug("De engine always busy\n");
Sudip Mukherjee81dee672015-03-03 16:21:06 +053098 return -1;
99 }
100
Juston Li5ee35ea2015-06-12 03:17:22 -0700101 write_dpr(accel, DE_WINDOW_DESTINATION_BASE, base); /* dpr40 */
Isaac Assegaib5d63972015-06-02 03:14:27 -0700102 write_dpr(accel, DE_PITCH,
103 FIELD_VALUE(0, DE_PITCH, DESTINATION, pitch/Bpp)|
Juston Li5ee35ea2015-06-12 03:17:22 -0700104 FIELD_VALUE(0, DE_PITCH, SOURCE, pitch/Bpp)); /* dpr10 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530105
Isaac Assegaib5d63972015-06-02 03:14:27 -0700106 write_dpr(accel, DE_WINDOW_WIDTH,
107 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, pitch/Bpp)|
Juston Li5ee35ea2015-06-12 03:17:22 -0700108 FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, pitch/Bpp)); /* dpr44 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530109
Juston Li5ee35ea2015-06-12 03:17:22 -0700110 write_dpr(accel, DE_FOREGROUND, color); /* DPR14 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530111
Isaac Assegaib5d63972015-06-02 03:14:27 -0700112 write_dpr(accel, DE_DESTINATION,
Mike Rapoportaeaab182016-02-15 19:53:58 +0200113 ((x << DE_DESTINATION_X_SHIFT) & DE_DESTINATION_X_MASK) |
114 (y & DE_DESTINATION_Y_MASK)); /* dpr4 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530115
Isaac Assegaib5d63972015-06-02 03:14:27 -0700116 write_dpr(accel, DE_DIMENSION,
Mike Rapoport0fab34b2016-02-15 19:53:59 +0200117 ((width << DE_DIMENSION_X_SHIFT) & DE_DIMENSION_X_MASK) |
118 (height & DE_DIMENSION_Y_ET_MASK)); /* dpr8 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530119
Mike Rapoporte2e22582016-02-15 19:54:00 +0200120 deCtrl = DE_CONTROL_STATUS | DE_CONTROL_LAST_PIXEL |
121 DE_CONTROL_COMMAND_RECTANGLE_FILL | DE_CONTROL_ROP_SELECT |
122 (rop & DE_CONTROL_ROP_MASK); /* dpr0xc */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530123
Isaac Assegaib5d63972015-06-02 03:14:27 -0700124 write_dpr(accel, DE_CONTROL, deCtrl);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530125 return 0;
126}
127
128int hw_copyarea(
Greg Donaldeb0f4272015-06-18 15:06:56 -0500129struct lynx_accel *accel,
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530130unsigned int sBase, /* Address of source: offset in frame buffer */
131unsigned int sPitch, /* Pitch value of source surface in BYTE */
132unsigned int sx,
133unsigned int sy, /* Starting coordinate of source surface */
134unsigned int dBase, /* Address of destination: offset in frame buffer */
135unsigned int dPitch, /* Pitch value of destination surface in BYTE */
136unsigned int Bpp, /* Color depth of destination surface */
137unsigned int dx,
138unsigned int dy, /* Starting coordinate of destination surface */
139unsigned int width,
140unsigned int height, /* width and height of rectangle in pixel value */
141unsigned int rop2) /* ROP value */
142{
Juston Li78376532015-07-14 21:14:30 -0700143 unsigned int nDirection, de_ctrl;
144 int opSign;
Juston Li40403c12015-07-14 21:14:48 -0700145
Juston Li78376532015-07-14 21:14:30 -0700146 nDirection = LEFT_TO_RIGHT;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530147 /* Direction of ROP2 operation: 1 = Left to Right, (-1) = Right to Left */
Juston Li78376532015-07-14 21:14:30 -0700148 opSign = 1;
149 de_ctrl = 0;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530150
Juston Li78376532015-07-14 21:14:30 -0700151 /* If source and destination are the same surface, need to check for overlay cases */
Juston Li259fef32015-07-14 21:14:45 -0700152 if (sBase == dBase && sPitch == dPitch) {
Juston Li78376532015-07-14 21:14:30 -0700153 /* Determine direction of operation */
Juston Li259fef32015-07-14 21:14:45 -0700154 if (sy < dy) {
Juston Li78376532015-07-14 21:14:30 -0700155 /* +----------+
156 |S |
157 | +----------+
158 | | | |
159 | | | |
160 +---|------+ |
161 | D|
162 +----------+ */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530163
Juston Li78376532015-07-14 21:14:30 -0700164 nDirection = BOTTOM_TO_TOP;
Juston Li259fef32015-07-14 21:14:45 -0700165 } else if (sy > dy) {
Juston Li78376532015-07-14 21:14:30 -0700166 /* +----------+
167 |D |
168 | +----------+
169 | | | |
170 | | | |
171 +---|------+ |
172 | S|
173 +----------+ */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530174
Juston Li78376532015-07-14 21:14:30 -0700175 nDirection = TOP_TO_BOTTOM;
Juston Li259fef32015-07-14 21:14:45 -0700176 } else {
Juston Li78376532015-07-14 21:14:30 -0700177 /* sy == dy */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530178
Juston Li259fef32015-07-14 21:14:45 -0700179 if (sx <= dx) {
Juston Li78376532015-07-14 21:14:30 -0700180 /* +------+---+------+
181 |S | | D|
182 | | | |
183 | | | |
184 | | | |
185 +------+---+------+ */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530186
Juston Li78376532015-07-14 21:14:30 -0700187 nDirection = RIGHT_TO_LEFT;
Juston Li259fef32015-07-14 21:14:45 -0700188 } else {
Juston Li78376532015-07-14 21:14:30 -0700189 /* sx > dx */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530190
Juston Li78376532015-07-14 21:14:30 -0700191 /* +------+---+------+
192 |D | | S|
193 | | | |
194 | | | |
195 | | | |
196 +------+---+------+ */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530197
Juston Li78376532015-07-14 21:14:30 -0700198 nDirection = LEFT_TO_RIGHT;
199 }
200 }
201 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530202
Juston Li259fef32015-07-14 21:14:45 -0700203 if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) {
Juston Li78376532015-07-14 21:14:30 -0700204 sx += width - 1;
205 sy += height - 1;
206 dx += width - 1;
207 dy += height - 1;
208 opSign = (-1);
209 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530210
Juston Li78376532015-07-14 21:14:30 -0700211 /* Note:
212 DE_FOREGROUND are DE_BACKGROUND are don't care.
213 DE_COLOR_COMPARE and DE_COLOR_COMPARE_MAKS are set by set deSetTransparency().
214 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530215
Juston Li78376532015-07-14 21:14:30 -0700216 /* 2D Source Base.
217 It is an address offset (128 bit aligned) from the beginning of frame buffer.
218 */
219 write_dpr(accel, DE_WINDOW_SOURCE_BASE, sBase); /* dpr40 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530220
Juston Li78376532015-07-14 21:14:30 -0700221 /* 2D Destination Base.
222 It is an address offset (128 bit aligned) from the beginning of frame buffer.
223 */
224 write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dBase); /* dpr44 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530225
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530226 /* Program pitch (distance between the 1st points of two adjacent lines).
227 Note that input pitch is BYTE value, but the 2D Pitch register uses
Carlos E. Garcia69e98df2015-04-24 09:40:42 -0400228 pixel values. Need Byte to pixel conversion.
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530229 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530230 {
Isaac Assegaib5d63972015-06-02 03:14:27 -0700231 write_dpr(accel, DE_PITCH,
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530232 FIELD_VALUE(0, DE_PITCH, DESTINATION, (dPitch/Bpp)) |
Juston Li5ee35ea2015-06-12 03:17:22 -0700233 FIELD_VALUE(0, DE_PITCH, SOURCE, (sPitch/Bpp))); /* dpr10 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530234 }
235
236 /* Screen Window width in Pixels.
237 2D engine uses this value to calculate the linear address in frame buffer for a given point.
238 */
Juston Li78376532015-07-14 21:14:30 -0700239 write_dpr(accel, DE_WINDOW_WIDTH,
240 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, (dPitch/Bpp)) |
241 FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, (sPitch/Bpp))); /* dpr3c */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530242
Juston Li7b05cbe2015-07-14 21:14:47 -0700243 if (accel->de_wait() != 0)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530244 return -1;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530245
Juston Li78376532015-07-14 21:14:30 -0700246 {
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530247
Juston Li78376532015-07-14 21:14:30 -0700248 write_dpr(accel, DE_SOURCE,
Mike Rapoportcf6d8f02016-02-15 19:53:57 +0200249 ((sx << DE_SOURCE_X_K1_SHIFT) & DE_SOURCE_X_K1_MASK) |
250 (sy & DE_SOURCE_Y_K2_MASK)); /* dpr0 */
Juston Li78376532015-07-14 21:14:30 -0700251 write_dpr(accel, DE_DESTINATION,
Mike Rapoportaeaab182016-02-15 19:53:58 +0200252 ((dx << DE_DESTINATION_X_SHIFT) & DE_DESTINATION_X_MASK) |
253 (dy & DE_DESTINATION_Y_MASK)); /* dpr04 */
Juston Li78376532015-07-14 21:14:30 -0700254 write_dpr(accel, DE_DIMENSION,
Mike Rapoport0fab34b2016-02-15 19:53:59 +0200255 ((width << DE_DIMENSION_X_SHIFT) & DE_DIMENSION_X_MASK) |
256 (height & DE_DIMENSION_Y_ET_MASK)); /* dpr08 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530257
Mike Rapoporte2e22582016-02-15 19:54:00 +0200258 de_ctrl = (rop2 & DE_CONTROL_ROP_MASK) | DE_CONTROL_ROP_SELECT |
259 ((nDirection == RIGHT_TO_LEFT) ? DE_CONTROL_DIRECTION : 0) |
260 DE_CONTROL_COMMAND_BITBLT | DE_CONTROL_STATUS;
Juston Li78376532015-07-14 21:14:30 -0700261 write_dpr(accel, DE_CONTROL, de_ctrl); /* dpr0c */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530262
Juston Li78376532015-07-14 21:14:30 -0700263 }
264
265 return 0;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530266}
267
Greg Donaldeb0f4272015-06-18 15:06:56 -0500268static unsigned int deGetTransparency(struct lynx_accel *accel)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530269{
Juston Li78376532015-07-14 21:14:30 -0700270 unsigned int de_ctrl;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530271
Juston Li78376532015-07-14 21:14:30 -0700272 de_ctrl = read_dpr(accel, DE_CONTROL);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530273
Mike Rapoporte2e22582016-02-15 19:54:00 +0200274 de_ctrl &= (DE_CONTROL_TRANSPARENCY_MATCH |
275 DE_CONTROL_TRANSPARENCY_SELECT | DE_CONTROL_TRANSPARENCY);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530276
Juston Li78376532015-07-14 21:14:30 -0700277 return de_ctrl;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530278}
279
Greg Kroah-Hartman7c6f3fd2015-03-10 22:03:01 +0100280int hw_imageblit(struct lynx_accel *accel,
281 const char *pSrcbuf, /* pointer to start of source buffer in system memory */
282 u32 srcDelta, /* Pitch value (in bytes) of the source buffer, +ive means top down and -ive mean button up */
283 u32 startBit, /* Mono data can start at any bit in a byte, this value should be 0 to 7 */
284 u32 dBase, /* Address of destination: offset in frame buffer */
285 u32 dPitch, /* Pitch value of destination surface in BYTE */
286 u32 bytePerPixel, /* Color depth of destination surface */
287 u32 dx,
288 u32 dy, /* Starting coordinate of destination surface */
289 u32 width,
Matej Vasekfbb8c962016-01-25 16:02:33 +0100290 u32 height, /* width and height of rectangle in pixel value */
Greg Kroah-Hartman7c6f3fd2015-03-10 22:03:01 +0100291 u32 fColor, /* Foreground color (corresponding to a 1 in the monochrome data */
292 u32 bColor, /* Background color (corresponding to a 0 in the monochrome data */
293 u32 rop2) /* ROP value */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530294{
Juston Li78376532015-07-14 21:14:30 -0700295 unsigned int ulBytesPerScan;
296 unsigned int ul4BytesPerScan;
297 unsigned int ulBytesRemain;
298 unsigned int de_ctrl = 0;
299 unsigned char ajRemain[4];
300 int i, j;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530301
Juston Li78376532015-07-14 21:14:30 -0700302 startBit &= 7; /* Just make sure the start bit is within legal range */
303 ulBytesPerScan = (width + startBit + 7) / 8;
304 ul4BytesPerScan = ulBytesPerScan & ~3;
305 ulBytesRemain = ulBytesPerScan & 3;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530306
Juston Li7b05cbe2015-07-14 21:14:47 -0700307 if (accel->de_wait() != 0)
Juston Li78376532015-07-14 21:14:30 -0700308 return -1;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530309
Juston Li78376532015-07-14 21:14:30 -0700310 /* 2D Source Base.
311 Use 0 for HOST Blt.
312 */
313 write_dpr(accel, DE_WINDOW_SOURCE_BASE, 0);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530314
Juston Li78376532015-07-14 21:14:30 -0700315 /* 2D Destination Base.
316 It is an address offset (128 bit aligned) from the beginning of frame buffer.
317 */
318 write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dBase);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530319 /* Program pitch (distance between the 1st points of two adjacent lines).
320 Note that input pitch is BYTE value, but the 2D Pitch register uses
Carlos E. Garcia69e98df2015-04-24 09:40:42 -0400321 pixel values. Need Byte to pixel conversion.
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530322 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530323 {
Isaac Assegaib5d63972015-06-02 03:14:27 -0700324 write_dpr(accel, DE_PITCH,
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530325 FIELD_VALUE(0, DE_PITCH, DESTINATION, dPitch/bytePerPixel) |
Juston Li5ee35ea2015-06-12 03:17:22 -0700326 FIELD_VALUE(0, DE_PITCH, SOURCE, dPitch/bytePerPixel)); /* dpr10 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530327 }
328
Juston Li78376532015-07-14 21:14:30 -0700329 /* Screen Window width in Pixels.
330 2D engine uses this value to calculate the linear address in frame buffer for a given point.
331 */
332 write_dpr(accel, DE_WINDOW_WIDTH,
333 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, (dPitch/bytePerPixel)) |
334 FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, (dPitch/bytePerPixel)));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530335
Juston Li78376532015-07-14 21:14:30 -0700336 /* Note: For 2D Source in Host Write, only X_K1_MONO field is needed, and Y_K2 field is not used.
337 For mono bitmap, use startBit for X_K1. */
338 write_dpr(accel, DE_SOURCE,
Mike Rapoportcf6d8f02016-02-15 19:53:57 +0200339 (startBit << DE_SOURCE_X_K1_SHIFT) &
340 DE_SOURCE_X_K1_MONO_MASK); /* dpr00 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530341
Juston Li78376532015-07-14 21:14:30 -0700342 write_dpr(accel, DE_DESTINATION,
Mike Rapoportaeaab182016-02-15 19:53:58 +0200343 ((dx << DE_DESTINATION_X_SHIFT) & DE_DESTINATION_X_MASK) |
344 (dy & DE_DESTINATION_Y_MASK)); /* dpr04 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530345
Juston Li78376532015-07-14 21:14:30 -0700346 write_dpr(accel, DE_DIMENSION,
Mike Rapoport0fab34b2016-02-15 19:53:59 +0200347 ((width << DE_DIMENSION_X_SHIFT) & DE_DIMENSION_X_MASK) |
348 (height & DE_DIMENSION_Y_ET_MASK)); /* dpr08 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530349
Juston Li78376532015-07-14 21:14:30 -0700350 write_dpr(accel, DE_FOREGROUND, fColor);
351 write_dpr(accel, DE_BACKGROUND, bColor);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530352
Mike Rapoporte2e22582016-02-15 19:54:00 +0200353 de_ctrl = (rop2 & DE_CONTROL_ROP_MASK) |
354 DE_CONTROL_ROP_SELECT | DE_CONTROL_COMMAND_HOST_WRITE |
355 DE_CONTROL_HOST | DE_CONTROL_STATUS;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530356
Isaac Assegaib5d63972015-06-02 03:14:27 -0700357 write_dpr(accel, DE_CONTROL, de_ctrl | deGetTransparency(accel));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530358
Juston Li78376532015-07-14 21:14:30 -0700359 /* Write MONO data (line by line) to 2D Engine data port */
Juston Li259fef32015-07-14 21:14:45 -0700360 for (i = 0; i < height; i++) {
Juston Li78376532015-07-14 21:14:30 -0700361 /* For each line, send the data in chunks of 4 bytes */
Juston Li7b05cbe2015-07-14 21:14:47 -0700362 for (j = 0; j < (ul4BytesPerScan/4); j++)
Juston Li78376532015-07-14 21:14:30 -0700363 write_dpPort(accel, *(unsigned int *)(pSrcbuf + (j * 4)));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530364
Juston Li259fef32015-07-14 21:14:45 -0700365 if (ulBytesRemain) {
Juston Li78376532015-07-14 21:14:30 -0700366 memcpy(ajRemain, pSrcbuf+ul4BytesPerScan, ulBytesRemain);
367 write_dpPort(accel, *(unsigned int *)ajRemain);
368 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530369
Juston Li78376532015-07-14 21:14:30 -0700370 pSrcbuf += srcDelta;
371 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530372
Juston Li78376532015-07-14 21:14:30 -0700373 return 0;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530374}
375