aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/pm2fb.c
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2007-10-16 04:29:16 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:43:18 -0400
commit2a36f9c497a907dd706e1eb2a7c00ced6105d65b (patch)
treeeafb7712883a624b70eca75dfb7cad3a14b9968b /drivers/video/pm2fb.c
parente84d436b3cc06fbd411096d734e0ae09da59b26f (diff)
pm2fb: hardware cursor support for the Permedia2
This patch adds hardware cursor support for the Permedia 2 chip. Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Antonino Daplas <adaplas@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/pm2fb.c')
-rw-r--r--drivers/video/pm2fb.c125
1 files changed, 113 insertions, 12 deletions
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index 53dd639e9753..20476f4c43ae 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -1257,18 +1257,8 @@ static const u8 cursor_bits_lookup[16] = {
1257static int pm2vfb_cursor(struct fb_info *info, struct fb_cursor *cursor) 1257static int pm2vfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1258{ 1258{
1259 struct pm2fb_par *par = info->par; 1259 struct pm2fb_par *par = info->par;
1260 u8 mode; 1260 u8 mode = PM2F_CURSORMODE_TYPE_X;
1261
1262 if (!hwcursor)
1263 return -EINVAL; /* just to force soft_cursor() call */
1264
1265 /* Too large of a cursor or wrong bpp :-( */
1266 if (cursor->image.width > 64 ||
1267 cursor->image.height > 64 ||
1268 cursor->image.depth > 1)
1269 return -EINVAL;
1270 1261
1271 mode = PM2F_CURSORMODE_TYPE_X;
1272 if (cursor->enable) 1262 if (cursor->enable)
1273 mode |= PM2F_CURSORMODE_CURSOR_ENABLE; 1263 mode |= PM2F_CURSORMODE_CURSOR_ENABLE;
1274 1264
@@ -1369,11 +1359,122 @@ static int pm2vfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1369static int pm2fb_cursor(struct fb_info *info, struct fb_cursor *cursor) 1359static int pm2fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1370{ 1360{
1371 struct pm2fb_par *par = info->par; 1361 struct pm2fb_par *par = info->par;
1362 u8 mode;
1363
1364 if (!hwcursor)
1365 return -EINVAL; /* just to force soft_cursor() call */
1366
1367 /* Too large of a cursor or wrong bpp :-( */
1368 if (cursor->image.width > 64 ||
1369 cursor->image.height > 64 ||
1370 cursor->image.depth > 1)
1371 return -EINVAL;
1372 1372
1373 if (par->type == PM2_TYPE_PERMEDIA2V) 1373 if (par->type == PM2_TYPE_PERMEDIA2V)
1374 return pm2vfb_cursor(info, cursor); 1374 return pm2vfb_cursor(info, cursor);
1375 1375
1376 return -ENXIO; 1376 mode = 0;
1377 if (cursor->enable)
1378 mode = 0x43;
1379
1380 pm2_RDAC_WR(par, PM2I_RD_CURSOR_CONTROL, mode);
1381
1382 /*
1383 * If the cursor is not be changed this means either we want the
1384 * current cursor state (if enable is set) or we want to query what
1385 * we can do with the cursor (if enable is not set)
1386 */
1387 if (!cursor->set)
1388 return 0;
1389
1390 if (cursor->set & FB_CUR_SETPOS) {
1391 int x, y;
1392
1393 x = cursor->image.dx + 63;
1394 y = cursor->image.dy + 63;
1395 WAIT_FIFO(par, 4);
1396 pm2_WR(par, PM2R_RD_CURSOR_X_LSB, x & 0xff);
1397 pm2_WR(par, PM2R_RD_CURSOR_X_MSB, (x >> 8) & 0x7);
1398 pm2_WR(par, PM2R_RD_CURSOR_Y_LSB, y & 0xff);
1399 pm2_WR(par, PM2R_RD_CURSOR_Y_MSB, (y >> 8) & 0x7);
1400 }
1401
1402 if (cursor->set & FB_CUR_SETCMAP) {
1403 u32 fg_idx = cursor->image.fg_color;
1404 u32 bg_idx = cursor->image.bg_color;
1405
1406 WAIT_FIFO(par, 7);
1407 pm2_WR(par, PM2R_RD_CURSOR_COLOR_ADDRESS, 1);
1408 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1409 info->cmap.red[bg_idx] >> 8);
1410 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1411 info->cmap.green[bg_idx] >> 8);
1412 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1413 info->cmap.blue[bg_idx] >> 8);
1414
1415 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1416 info->cmap.red[fg_idx] >> 8);
1417 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1418 info->cmap.green[fg_idx] >> 8);
1419 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1420 info->cmap.blue[fg_idx] >> 8);
1421 }
1422
1423 if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
1424 u8 *bitmap = (u8 *)cursor->image.data;
1425 u8 *mask = (u8 *)cursor->mask;
1426 int i;
1427
1428 WAIT_FIFO(par, 1);
1429 pm2_WR(par, PM2R_RD_PALETTE_WRITE_ADDRESS, 0);
1430
1431 for (i = 0; i < cursor->image.height; i++) {
1432 int j = (cursor->image.width + 7) >> 3;
1433 int k = 8 - j;
1434
1435 WAIT_FIFO(par, 8);
1436 for (; j > 0; j--) {
1437 u8 data = *bitmap ^ *mask;
1438
1439 if (cursor->rop == ROP_COPY)
1440 data = *mask & *bitmap;
1441 /* bitmap data */
1442 pm2_WR(par, PM2R_RD_CURSOR_DATA, data);
1443 bitmap++;
1444 mask++;
1445 }
1446 for (; k > 0; k--)
1447 pm2_WR(par, PM2R_RD_CURSOR_DATA, 0);
1448 }
1449 for (; i < 64; i++) {
1450 int j = 8;
1451 WAIT_FIFO(par, 8);
1452 while (j-- > 0)
1453 pm2_WR(par, PM2R_RD_CURSOR_DATA, 0);
1454 }
1455
1456 mask = (u8 *)cursor->mask;
1457 for (i = 0; i < cursor->image.height; i++) {
1458 int j = (cursor->image.width + 7) >> 3;
1459 int k = 8 - j;
1460
1461 WAIT_FIFO(par, 8);
1462 for (; j > 0; j--) {
1463 /* mask */
1464 pm2_WR(par, PM2R_RD_CURSOR_DATA, *mask);
1465 mask++;
1466 }
1467 for (; k > 0; k--)
1468 pm2_WR(par, PM2R_RD_CURSOR_DATA, 0);
1469 }
1470 for (; i < 64; i++) {
1471 int j = 8;
1472 WAIT_FIFO(par, 8);
1473 while (j-- > 0)
1474 pm2_WR(par, PM2R_RD_CURSOR_DATA, 0);
1475 }
1476 }
1477 return 0;
1377} 1478}
1378 1479
1379/* ------------ Hardware Independent Functions ------------ */ 1480/* ------------ Hardware Independent Functions ------------ */