blob: 38adae6b5d83848efc2a23c79ae553abc384741e [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"
Greg Donaldeb0f4272015-06-18 15:06:56 -050020static inline void write_dpr(struct lynx_accel *accel, int offset, u32 regValue)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053021{
Isaac Assegaib5d63972015-06-02 03:14:27 -070022 writel(regValue, accel->dprBase + offset);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053023}
24
Greg Donaldeb0f4272015-06-18 15:06:56 -050025static inline u32 read_dpr(struct lynx_accel *accel, int offset)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053026{
27 return readl(accel->dprBase + offset);
28}
29
Greg Donaldeb0f4272015-06-18 15:06:56 -050030static inline void write_dpPort(struct lynx_accel *accel, u32 data)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053031{
Isaac Assegaib5d63972015-06-02 03:14:27 -070032 writel(data, accel->dpPortBase);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053033}
34
Greg Donaldeb0f4272015-06-18 15:06:56 -050035void hw_de_init(struct lynx_accel *accel)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053036{
37 /* setup 2d engine registers */
Isaac Assegaib5d63972015-06-02 03:14:27 -070038 u32 reg, clr;
Juston Li919ca7c2015-07-14 21:14:43 -070039
Isaac Assegaib5d63972015-06-02 03:14:27 -070040 write_dpr(accel, DE_MASKS, 0xFFFFFFFF);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053041
42 /* dpr1c */
Mike Rapoportf7a61fd2016-02-15 19:54:02 +020043 reg = 0x3;
Sudip Mukherjee81dee672015-03-03 16:21:06 +053044
Mike Rapoportf7a61fd2016-02-15 19:54:02 +020045 clr = DE_STRETCH_FORMAT_PATTERN_XY | DE_STRETCH_FORMAT_PATTERN_Y_MASK |
46 DE_STRETCH_FORMAT_PATTERN_X_MASK |
47 DE_STRETCH_FORMAT_ADDRESSING_MASK |
48 DE_STRETCH_FORMAT_SOURCE_HEIGHT_MASK;
Sudip Mukherjee81dee672015-03-03 16:21:06 +053049
Matej Vasekfbb8c962016-01-25 16:02:33 +010050 /* DE_STRETCH bpp format need be initialized in setMode routine */
Mike Rapoportf7a61fd2016-02-15 19:54:02 +020051 write_dpr(accel, DE_STRETCH_FORMAT,
52 (read_dpr(accel, DE_STRETCH_FORMAT) & ~clr) | reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053053
54 /* disable clipping and transparent */
Juston Li5ee35ea2015-06-12 03:17:22 -070055 write_dpr(accel, DE_CLIP_TL, 0); /* dpr2c */
56 write_dpr(accel, DE_CLIP_BR, 0); /* dpr30 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +053057
Juston Li5ee35ea2015-06-12 03:17:22 -070058 write_dpr(accel, DE_COLOR_COMPARE_MASK, 0); /* dpr24 */
Isaac Assegaib5d63972015-06-02 03:14:27 -070059 write_dpr(accel, DE_COLOR_COMPARE, 0);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053060
Mike Rapoporte2e22582016-02-15 19:54:00 +020061 clr = DE_CONTROL_TRANSPARENCY | DE_CONTROL_TRANSPARENCY_MATCH |
62 DE_CONTROL_TRANSPARENCY_SELECT;
Sudip Mukherjee81dee672015-03-03 16:21:06 +053063
64 /* dpr0c */
Mike Rapoporte2e22582016-02-15 19:54:00 +020065 write_dpr(accel, DE_CONTROL, read_dpr(accel, DE_CONTROL) & ~clr);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053066}
67
68/* set2dformat only be called from setmode functions
69 * but if you need dual framebuffer driver,need call set2dformat
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -070070 * every time you use 2d function
71 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +053072
Greg Donaldeb0f4272015-06-18 15:06:56 -050073void hw_set2dformat(struct lynx_accel *accel, int fmt)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053074{
75 u32 reg;
Juston Li919ca7c2015-07-14 21:14:43 -070076
Sudip Mukherjee81dee672015-03-03 16:21:06 +053077 /* fmt=0,1,2 for 8,16,32,bpp on sm718/750/502 */
Isaac Assegaib5d63972015-06-02 03:14:27 -070078 reg = read_dpr(accel, DE_STRETCH_FORMAT);
Mike Rapoportf7a61fd2016-02-15 19:54:02 +020079 reg &= ~DE_STRETCH_FORMAT_PIXEL_FORMAT_MASK;
80 reg |= ((fmt << DE_STRETCH_FORMAT_PIXEL_FORMAT_SHIFT) &
81 DE_STRETCH_FORMAT_PIXEL_FORMAT_MASK);
Isaac Assegaib5d63972015-06-02 03:14:27 -070082 write_dpr(accel, DE_STRETCH_FORMAT, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053083}
84
Greg Donaldeb0f4272015-06-18 15:06:56 -050085int hw_fillrect(struct lynx_accel *accel,
Isaac Assegaib5d63972015-06-02 03:14:27 -070086 u32 base, u32 pitch, u32 Bpp,
87 u32 x, u32 y, u32 width, u32 height,
88 u32 color, u32 rop)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053089{
90 u32 deCtrl;
91
Juston Li259fef32015-07-14 21:14:45 -070092 if (accel->de_wait() != 0) {
Sudip Mukherjee81dee672015-03-03 16:21:06 +053093 /* int time wait and always busy,seems hardware
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -070094 * got something error
95 */
Hari Prasath Gujulan Elango7211f6f2015-06-24 16:51:21 +000096 pr_debug("De engine always busy\n");
Sudip Mukherjee81dee672015-03-03 16:21:06 +053097 return -1;
98 }
99
Juston Li5ee35ea2015-06-12 03:17:22 -0700100 write_dpr(accel, DE_WINDOW_DESTINATION_BASE, base); /* dpr40 */
Isaac Assegaib5d63972015-06-02 03:14:27 -0700101 write_dpr(accel, DE_PITCH,
Mike Rapoport71240802016-02-15 19:54:01 +0200102 ((pitch / Bpp << DE_PITCH_DESTINATION_SHIFT) &
103 DE_PITCH_DESTINATION_MASK) |
104 (pitch / Bpp & DE_PITCH_SOURCE_MASK)); /* dpr10 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530105
Isaac Assegaib5d63972015-06-02 03:14:27 -0700106 write_dpr(accel, DE_WINDOW_WIDTH,
Mike Rapoport8bac9c82016-02-15 19:54:03 +0200107 ((pitch / Bpp << DE_WINDOW_WIDTH_DST_SHIFT) &
108 DE_WINDOW_WIDTH_DST_MASK) |
109 (pitch / Bpp & DE_WINDOW_WIDTH_SRC_MASK)); /* dpr44 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530110
Juston Li5ee35ea2015-06-12 03:17:22 -0700111 write_dpr(accel, DE_FOREGROUND, color); /* DPR14 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530112
Isaac Assegaib5d63972015-06-02 03:14:27 -0700113 write_dpr(accel, DE_DESTINATION,
Mike Rapoportaeaab182016-02-15 19:53:58 +0200114 ((x << DE_DESTINATION_X_SHIFT) & DE_DESTINATION_X_MASK) |
115 (y & DE_DESTINATION_Y_MASK)); /* dpr4 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530116
Isaac Assegaib5d63972015-06-02 03:14:27 -0700117 write_dpr(accel, DE_DIMENSION,
Mike Rapoport0fab34b2016-02-15 19:53:59 +0200118 ((width << DE_DIMENSION_X_SHIFT) & DE_DIMENSION_X_MASK) |
119 (height & DE_DIMENSION_Y_ET_MASK)); /* dpr8 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530120
Mike Rapoporte2e22582016-02-15 19:54:00 +0200121 deCtrl = DE_CONTROL_STATUS | DE_CONTROL_LAST_PIXEL |
122 DE_CONTROL_COMMAND_RECTANGLE_FILL | DE_CONTROL_ROP_SELECT |
123 (rop & DE_CONTROL_ROP_MASK); /* dpr0xc */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530124
Isaac Assegaib5d63972015-06-02 03:14:27 -0700125 write_dpr(accel, DE_CONTROL, deCtrl);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530126 return 0;
127}
128
129int hw_copyarea(
Greg Donaldeb0f4272015-06-18 15:06:56 -0500130struct lynx_accel *accel,
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530131unsigned int sBase, /* Address of source: offset in frame buffer */
132unsigned int sPitch, /* Pitch value of source surface in BYTE */
133unsigned int sx,
134unsigned int sy, /* Starting coordinate of source surface */
135unsigned int dBase, /* Address of destination: offset in frame buffer */
136unsigned int dPitch, /* Pitch value of destination surface in BYTE */
137unsigned int Bpp, /* Color depth of destination surface */
138unsigned int dx,
139unsigned int dy, /* Starting coordinate of destination surface */
140unsigned int width,
141unsigned int height, /* width and height of rectangle in pixel value */
142unsigned int rop2) /* ROP value */
143{
Juston Li78376532015-07-14 21:14:30 -0700144 unsigned int nDirection, de_ctrl;
145 int opSign;
Juston Li40403c12015-07-14 21:14:48 -0700146
Juston Li78376532015-07-14 21:14:30 -0700147 nDirection = LEFT_TO_RIGHT;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530148 /* Direction of ROP2 operation: 1 = Left to Right, (-1) = Right to Left */
Juston Li78376532015-07-14 21:14:30 -0700149 opSign = 1;
150 de_ctrl = 0;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530151
Juston Li78376532015-07-14 21:14:30 -0700152 /* If source and destination are the same surface, need to check for overlay cases */
Juston Li259fef32015-07-14 21:14:45 -0700153 if (sBase == dBase && sPitch == dPitch) {
Juston Li78376532015-07-14 21:14:30 -0700154 /* Determine direction of operation */
Juston Li259fef32015-07-14 21:14:45 -0700155 if (sy < dy) {
Juston Li78376532015-07-14 21:14:30 -0700156 /* +----------+
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -0700157 * |S |
158 * | +----------+
159 * | | | |
160 * | | | |
161 * +---|------+ |
162 * | D|
163 * +----------+
164 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530165
Juston Li78376532015-07-14 21:14:30 -0700166 nDirection = BOTTOM_TO_TOP;
Juston Li259fef32015-07-14 21:14:45 -0700167 } else if (sy > dy) {
Juston Li78376532015-07-14 21:14:30 -0700168 /* +----------+
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -0700169 * |D |
170 * | +----------+
171 * | | | |
172 * | | | |
173 * +---|------+ |
174 * | S|
175 * +----------+
176 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530177
Juston Li78376532015-07-14 21:14:30 -0700178 nDirection = TOP_TO_BOTTOM;
Juston Li259fef32015-07-14 21:14:45 -0700179 } else {
Juston Li78376532015-07-14 21:14:30 -0700180 /* sy == dy */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530181
Juston Li259fef32015-07-14 21:14:45 -0700182 if (sx <= dx) {
Juston Li78376532015-07-14 21:14:30 -0700183 /* +------+---+------+
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -0700184 * |S | | D|
185 * | | | |
186 * | | | |
187 * | | | |
188 * +------+---+------+
189 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530190
Juston Li78376532015-07-14 21:14:30 -0700191 nDirection = RIGHT_TO_LEFT;
Juston Li259fef32015-07-14 21:14:45 -0700192 } else {
Juston Li78376532015-07-14 21:14:30 -0700193 /* sx > dx */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530194
Juston Li78376532015-07-14 21:14:30 -0700195 /* +------+---+------+
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -0700196 * |D | | S|
197 * | | | |
198 * | | | |
199 * | | | |
200 * +------+---+------+
201 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530202
Juston Li78376532015-07-14 21:14:30 -0700203 nDirection = LEFT_TO_RIGHT;
204 }
205 }
206 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530207
Juston Li259fef32015-07-14 21:14:45 -0700208 if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) {
Juston Li78376532015-07-14 21:14:30 -0700209 sx += width - 1;
210 sy += height - 1;
211 dx += width - 1;
212 dy += height - 1;
213 opSign = (-1);
214 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530215
Juston Li78376532015-07-14 21:14:30 -0700216 /* Note:
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -0700217 * DE_FOREGROUND are DE_BACKGROUND are don't care.
218 * DE_COLOR_COMPARE and DE_COLOR_COMPARE_MAKS
219 * are set by set deSetTransparency().
Juston Li78376532015-07-14 21:14:30 -0700220 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530221
Juston Li78376532015-07-14 21:14:30 -0700222 /* 2D Source Base.
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -0700223 * It is an address offset (128 bit aligned)
224 * from the beginning of frame buffer.
Juston Li78376532015-07-14 21:14:30 -0700225 */
226 write_dpr(accel, DE_WINDOW_SOURCE_BASE, sBase); /* dpr40 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530227
Juston Li78376532015-07-14 21:14:30 -0700228 /* 2D Destination Base.
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -0700229 * It is an address offset (128 bit aligned)
230 * from the beginning of frame buffer.
Juston Li78376532015-07-14 21:14:30 -0700231 */
232 write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dBase); /* dpr44 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530233
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530234 /* Program pitch (distance between the 1st points of two adjacent lines).
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -0700235 * Note that input pitch is BYTE value, but the 2D Pitch register uses
236 * pixel values. Need Byte to pixel conversion.
237 */
Mike Rapoport71240802016-02-15 19:54:01 +0200238 write_dpr(accel, DE_PITCH,
239 ((dPitch / Bpp << DE_PITCH_DESTINATION_SHIFT) &
240 DE_PITCH_DESTINATION_MASK) |
241 (sPitch / Bpp & DE_PITCH_SOURCE_MASK)); /* dpr10 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530242
243 /* Screen Window width in Pixels.
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -0700244 * 2D engine uses this value to calculate the linear address in frame buffer
245 * for a given point.
246 */
Juston Li78376532015-07-14 21:14:30 -0700247 write_dpr(accel, DE_WINDOW_WIDTH,
Mike Rapoport8bac9c82016-02-15 19:54:03 +0200248 ((dPitch / Bpp << DE_WINDOW_WIDTH_DST_SHIFT) &
249 DE_WINDOW_WIDTH_DST_MASK) |
250 (sPitch / Bpp & DE_WINDOW_WIDTH_SRC_MASK)); /* dpr3c */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530251
Juston Li7b05cbe2015-07-14 21:14:47 -0700252 if (accel->de_wait() != 0)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530253 return -1;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530254
Juston Li78376532015-07-14 21:14:30 -0700255 {
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530256
Juston Li78376532015-07-14 21:14:30 -0700257 write_dpr(accel, DE_SOURCE,
Mike Rapoportcf6d8f02016-02-15 19:53:57 +0200258 ((sx << DE_SOURCE_X_K1_SHIFT) & DE_SOURCE_X_K1_MASK) |
259 (sy & DE_SOURCE_Y_K2_MASK)); /* dpr0 */
Juston Li78376532015-07-14 21:14:30 -0700260 write_dpr(accel, DE_DESTINATION,
Mike Rapoportaeaab182016-02-15 19:53:58 +0200261 ((dx << DE_DESTINATION_X_SHIFT) & DE_DESTINATION_X_MASK) |
262 (dy & DE_DESTINATION_Y_MASK)); /* dpr04 */
Juston Li78376532015-07-14 21:14:30 -0700263 write_dpr(accel, DE_DIMENSION,
Mike Rapoport0fab34b2016-02-15 19:53:59 +0200264 ((width << DE_DIMENSION_X_SHIFT) & DE_DIMENSION_X_MASK) |
265 (height & DE_DIMENSION_Y_ET_MASK)); /* dpr08 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530266
Mike Rapoporte2e22582016-02-15 19:54:00 +0200267 de_ctrl = (rop2 & DE_CONTROL_ROP_MASK) | DE_CONTROL_ROP_SELECT |
268 ((nDirection == RIGHT_TO_LEFT) ? DE_CONTROL_DIRECTION : 0) |
269 DE_CONTROL_COMMAND_BITBLT | DE_CONTROL_STATUS;
Juston Li78376532015-07-14 21:14:30 -0700270 write_dpr(accel, DE_CONTROL, de_ctrl); /* dpr0c */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530271
Juston Li78376532015-07-14 21:14:30 -0700272 }
273
274 return 0;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530275}
276
Greg Donaldeb0f4272015-06-18 15:06:56 -0500277static unsigned int deGetTransparency(struct lynx_accel *accel)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530278{
Juston Li78376532015-07-14 21:14:30 -0700279 unsigned int de_ctrl;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530280
Juston Li78376532015-07-14 21:14:30 -0700281 de_ctrl = read_dpr(accel, DE_CONTROL);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530282
Mike Rapoporte2e22582016-02-15 19:54:00 +0200283 de_ctrl &= (DE_CONTROL_TRANSPARENCY_MATCH |
284 DE_CONTROL_TRANSPARENCY_SELECT | DE_CONTROL_TRANSPARENCY);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530285
Juston Li78376532015-07-14 21:14:30 -0700286 return de_ctrl;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530287}
288
Greg Kroah-Hartman7c6f3fd2015-03-10 22:03:01 +0100289int hw_imageblit(struct lynx_accel *accel,
290 const char *pSrcbuf, /* pointer to start of source buffer in system memory */
291 u32 srcDelta, /* Pitch value (in bytes) of the source buffer, +ive means top down and -ive mean button up */
292 u32 startBit, /* Mono data can start at any bit in a byte, this value should be 0 to 7 */
293 u32 dBase, /* Address of destination: offset in frame buffer */
294 u32 dPitch, /* Pitch value of destination surface in BYTE */
295 u32 bytePerPixel, /* Color depth of destination surface */
296 u32 dx,
297 u32 dy, /* Starting coordinate of destination surface */
298 u32 width,
Matej Vasekfbb8c962016-01-25 16:02:33 +0100299 u32 height, /* width and height of rectangle in pixel value */
Greg Kroah-Hartman7c6f3fd2015-03-10 22:03:01 +0100300 u32 fColor, /* Foreground color (corresponding to a 1 in the monochrome data */
301 u32 bColor, /* Background color (corresponding to a 0 in the monochrome data */
302 u32 rop2) /* ROP value */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530303{
Juston Li78376532015-07-14 21:14:30 -0700304 unsigned int ulBytesPerScan;
305 unsigned int ul4BytesPerScan;
306 unsigned int ulBytesRemain;
307 unsigned int de_ctrl = 0;
308 unsigned char ajRemain[4];
309 int i, j;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530310
Juston Li78376532015-07-14 21:14:30 -0700311 startBit &= 7; /* Just make sure the start bit is within legal range */
312 ulBytesPerScan = (width + startBit + 7) / 8;
313 ul4BytesPerScan = ulBytesPerScan & ~3;
314 ulBytesRemain = ulBytesPerScan & 3;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530315
Juston Li7b05cbe2015-07-14 21:14:47 -0700316 if (accel->de_wait() != 0)
Juston Li78376532015-07-14 21:14:30 -0700317 return -1;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530318
Juston Li78376532015-07-14 21:14:30 -0700319 /* 2D Source Base.
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -0700320 * Use 0 for HOST Blt.
Juston Li78376532015-07-14 21:14:30 -0700321 */
322 write_dpr(accel, DE_WINDOW_SOURCE_BASE, 0);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530323
Juston Li78376532015-07-14 21:14:30 -0700324 /* 2D Destination Base.
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -0700325 * It is an address offset (128 bit aligned)
326 * from the beginning of frame buffer.
Juston Li78376532015-07-14 21:14:30 -0700327 */
328 write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dBase);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530329 /* Program pitch (distance between the 1st points of two adjacent lines).
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -0700330 * Note that input pitch is BYTE value, but the 2D Pitch register uses
331 * pixel values. Need Byte to pixel conversion.
332 */
Mike Rapoport71240802016-02-15 19:54:01 +0200333 write_dpr(accel, DE_PITCH,
334 ((dPitch / bytePerPixel << DE_PITCH_DESTINATION_SHIFT) &
335 DE_PITCH_DESTINATION_MASK) |
336 (dPitch / bytePerPixel & DE_PITCH_SOURCE_MASK)); /* dpr10 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530337
Juston Li78376532015-07-14 21:14:30 -0700338 /* Screen Window width in Pixels.
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -0700339 * 2D engine uses this value to calculate the linear address
340 * in frame buffer for a given point.
Juston Li78376532015-07-14 21:14:30 -0700341 */
342 write_dpr(accel, DE_WINDOW_WIDTH,
Mike Rapoport8bac9c82016-02-15 19:54:03 +0200343 ((dPitch / bytePerPixel << DE_WINDOW_WIDTH_DST_SHIFT) &
344 DE_WINDOW_WIDTH_DST_MASK) |
345 (dPitch / bytePerPixel & DE_WINDOW_WIDTH_SRC_MASK));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530346
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -0700347 /* Note: For 2D Source in Host Write, only X_K1_MONO field is needed,
348 * and Y_K2 field is not used.
349 * For mono bitmap, use startBit for X_K1.
350 */
Juston Li78376532015-07-14 21:14:30 -0700351 write_dpr(accel, DE_SOURCE,
Mike Rapoportcf6d8f02016-02-15 19:53:57 +0200352 (startBit << DE_SOURCE_X_K1_SHIFT) &
353 DE_SOURCE_X_K1_MONO_MASK); /* dpr00 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530354
Juston Li78376532015-07-14 21:14:30 -0700355 write_dpr(accel, DE_DESTINATION,
Mike Rapoportaeaab182016-02-15 19:53:58 +0200356 ((dx << DE_DESTINATION_X_SHIFT) & DE_DESTINATION_X_MASK) |
357 (dy & DE_DESTINATION_Y_MASK)); /* dpr04 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530358
Juston Li78376532015-07-14 21:14:30 -0700359 write_dpr(accel, DE_DIMENSION,
Mike Rapoport0fab34b2016-02-15 19:53:59 +0200360 ((width << DE_DIMENSION_X_SHIFT) & DE_DIMENSION_X_MASK) |
361 (height & DE_DIMENSION_Y_ET_MASK)); /* dpr08 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530362
Juston Li78376532015-07-14 21:14:30 -0700363 write_dpr(accel, DE_FOREGROUND, fColor);
364 write_dpr(accel, DE_BACKGROUND, bColor);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530365
Mike Rapoporte2e22582016-02-15 19:54:00 +0200366 de_ctrl = (rop2 & DE_CONTROL_ROP_MASK) |
367 DE_CONTROL_ROP_SELECT | DE_CONTROL_COMMAND_HOST_WRITE |
368 DE_CONTROL_HOST | DE_CONTROL_STATUS;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530369
Isaac Assegaib5d63972015-06-02 03:14:27 -0700370 write_dpr(accel, DE_CONTROL, de_ctrl | deGetTransparency(accel));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530371
Juston Li78376532015-07-14 21:14:30 -0700372 /* Write MONO data (line by line) to 2D Engine data port */
Juston Li259fef32015-07-14 21:14:45 -0700373 for (i = 0; i < height; i++) {
Juston Li78376532015-07-14 21:14:30 -0700374 /* For each line, send the data in chunks of 4 bytes */
Juston Li7b05cbe2015-07-14 21:14:47 -0700375 for (j = 0; j < (ul4BytesPerScan/4); j++)
Juston Li78376532015-07-14 21:14:30 -0700376 write_dpPort(accel, *(unsigned int *)(pSrcbuf + (j * 4)));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530377
Juston Li259fef32015-07-14 21:14:45 -0700378 if (ulBytesRemain) {
Juston Li78376532015-07-14 21:14:30 -0700379 memcpy(ajRemain, pSrcbuf+ul4BytesPerScan, ulBytesRemain);
380 write_dpPort(accel, *(unsigned int *)ajRemain);
381 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530382
Juston Li78376532015-07-14 21:14:30 -0700383 pSrcbuf += srcDelta;
384 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530385
Juston Li78376532015-07-14 21:14:30 -0700386 return 0;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530387}
388