diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2007-10-16 04:29:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 12:43:18 -0400 |
commit | 2a36f9c497a907dd706e1eb2a7c00ced6105d65b (patch) | |
tree | eafb7712883a624b70eca75dfb7cad3a14b9968b | |
parent | e84d436b3cc06fbd411096d734e0ae09da59b26f (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>
-rw-r--r-- | drivers/video/pm2fb.c | 125 | ||||
-rw-r--r-- | include/video/permedia2.h | 7 |
2 files changed, 120 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] = { | |||
1257 | static int pm2vfb_cursor(struct fb_info *info, struct fb_cursor *cursor) | 1257 | static 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) | |||
1369 | static int pm2fb_cursor(struct fb_info *info, struct fb_cursor *cursor) | 1359 | static 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 ------------ */ |
diff --git a/include/video/permedia2.h b/include/video/permedia2.h index c6575b834fef..9ce9adbfda2b 100644 --- a/include/video/permedia2.h +++ b/include/video/permedia2.h | |||
@@ -58,7 +58,14 @@ | |||
58 | #define PM2R_RD_PALETTE_DATA 0x4008 | 58 | #define PM2R_RD_PALETTE_DATA 0x4008 |
59 | #define PM2R_RD_PIXEL_MASK 0x4010 | 59 | #define PM2R_RD_PIXEL_MASK 0x4010 |
60 | #define PM2R_RD_PALETTE_READ_ADDRESS 0x4018 | 60 | #define PM2R_RD_PALETTE_READ_ADDRESS 0x4018 |
61 | #define PM2R_RD_CURSOR_COLOR_ADDRESS 0x4020 | ||
62 | #define PM2R_RD_CURSOR_COLOR_DATA 0x4028 | ||
61 | #define PM2R_RD_INDEXED_DATA 0x4050 | 63 | #define PM2R_RD_INDEXED_DATA 0x4050 |
64 | #define PM2R_RD_CURSOR_DATA 0x4058 | ||
65 | #define PM2R_RD_CURSOR_X_LSB 0x4060 | ||
66 | #define PM2R_RD_CURSOR_X_MSB 0x4068 | ||
67 | #define PM2R_RD_CURSOR_Y_LSB 0x4070 | ||
68 | #define PM2R_RD_CURSOR_Y_MSB 0x4078 | ||
62 | 69 | ||
63 | #define PM2R_START_X_DOM 0x8000 | 70 | #define PM2R_START_X_DOM 0x8000 |
64 | #define PM2R_D_X_DOM 0x8008 | 71 | #define PM2R_D_X_DOM 0x8008 |