Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Krzysztof Helt and committed by
Linus Torvalds
2a36f9c4 e84d436b

+120 -12
+113 -12
drivers/video/pm2fb.c
··· 1257 1257 static int pm2vfb_cursor(struct fb_info *info, struct fb_cursor *cursor) 1258 1258 { 1259 1259 struct pm2fb_par *par = info->par; 1260 - u8 mode; 1260 + u8 mode = PM2F_CURSORMODE_TYPE_X; 1261 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 - 1271 - mode = PM2F_CURSORMODE_TYPE_X; 1272 1262 if (cursor->enable) 1273 1263 mode |= PM2F_CURSORMODE_CURSOR_ENABLE; 1274 1264 ··· 1359 1369 static int pm2fb_cursor(struct fb_info *info, struct fb_cursor *cursor) 1360 1370 { 1361 1371 struct pm2fb_par *par = info->par; 1372 + u8 mode; 1373 + 1374 + if (!hwcursor) 1375 + return -EINVAL; /* just to force soft_cursor() call */ 1376 + 1377 + /* Too large of a cursor or wrong bpp :-( */ 1378 + if (cursor->image.width > 64 || 1379 + cursor->image.height > 64 || 1380 + cursor->image.depth > 1) 1381 + return -EINVAL; 1362 1382 1363 1383 if (par->type == PM2_TYPE_PERMEDIA2V) 1364 1384 return pm2vfb_cursor(info, cursor); 1365 1385 1366 - return -ENXIO; 1386 + mode = 0; 1387 + if (cursor->enable) 1388 + mode = 0x43; 1389 + 1390 + pm2_RDAC_WR(par, PM2I_RD_CURSOR_CONTROL, mode); 1391 + 1392 + /* 1393 + * If the cursor is not be changed this means either we want the 1394 + * current cursor state (if enable is set) or we want to query what 1395 + * we can do with the cursor (if enable is not set) 1396 + */ 1397 + if (!cursor->set) 1398 + return 0; 1399 + 1400 + if (cursor->set & FB_CUR_SETPOS) { 1401 + int x, y; 1402 + 1403 + x = cursor->image.dx + 63; 1404 + y = cursor->image.dy + 63; 1405 + WAIT_FIFO(par, 4); 1406 + pm2_WR(par, PM2R_RD_CURSOR_X_LSB, x & 0xff); 1407 + pm2_WR(par, PM2R_RD_CURSOR_X_MSB, (x >> 8) & 0x7); 1408 + pm2_WR(par, PM2R_RD_CURSOR_Y_LSB, y & 0xff); 1409 + pm2_WR(par, PM2R_RD_CURSOR_Y_MSB, (y >> 8) & 0x7); 1410 + } 1411 + 1412 + if (cursor->set & FB_CUR_SETCMAP) { 1413 + u32 fg_idx = cursor->image.fg_color; 1414 + u32 bg_idx = cursor->image.bg_color; 1415 + 1416 + WAIT_FIFO(par, 7); 1417 + pm2_WR(par, PM2R_RD_CURSOR_COLOR_ADDRESS, 1); 1418 + pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA, 1419 + info->cmap.red[bg_idx] >> 8); 1420 + pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA, 1421 + info->cmap.green[bg_idx] >> 8); 1422 + pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA, 1423 + info->cmap.blue[bg_idx] >> 8); 1424 + 1425 + pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA, 1426 + info->cmap.red[fg_idx] >> 8); 1427 + pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA, 1428 + info->cmap.green[fg_idx] >> 8); 1429 + pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA, 1430 + info->cmap.blue[fg_idx] >> 8); 1431 + } 1432 + 1433 + if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) { 1434 + u8 *bitmap = (u8 *)cursor->image.data; 1435 + u8 *mask = (u8 *)cursor->mask; 1436 + int i; 1437 + 1438 + WAIT_FIFO(par, 1); 1439 + pm2_WR(par, PM2R_RD_PALETTE_WRITE_ADDRESS, 0); 1440 + 1441 + for (i = 0; i < cursor->image.height; i++) { 1442 + int j = (cursor->image.width + 7) >> 3; 1443 + int k = 8 - j; 1444 + 1445 + WAIT_FIFO(par, 8); 1446 + for (; j > 0; j--) { 1447 + u8 data = *bitmap ^ *mask; 1448 + 1449 + if (cursor->rop == ROP_COPY) 1450 + data = *mask & *bitmap; 1451 + /* bitmap data */ 1452 + pm2_WR(par, PM2R_RD_CURSOR_DATA, data); 1453 + bitmap++; 1454 + mask++; 1455 + } 1456 + for (; k > 0; k--) 1457 + pm2_WR(par, PM2R_RD_CURSOR_DATA, 0); 1458 + } 1459 + for (; i < 64; i++) { 1460 + int j = 8; 1461 + WAIT_FIFO(par, 8); 1462 + while (j-- > 0) 1463 + pm2_WR(par, PM2R_RD_CURSOR_DATA, 0); 1464 + } 1465 + 1466 + mask = (u8 *)cursor->mask; 1467 + for (i = 0; i < cursor->image.height; i++) { 1468 + int j = (cursor->image.width + 7) >> 3; 1469 + int k = 8 - j; 1470 + 1471 + WAIT_FIFO(par, 8); 1472 + for (; j > 0; j--) { 1473 + /* mask */ 1474 + pm2_WR(par, PM2R_RD_CURSOR_DATA, *mask); 1475 + mask++; 1476 + } 1477 + for (; k > 0; k--) 1478 + pm2_WR(par, PM2R_RD_CURSOR_DATA, 0); 1479 + } 1480 + for (; i < 64; i++) { 1481 + int j = 8; 1482 + WAIT_FIFO(par, 8); 1483 + while (j-- > 0) 1484 + pm2_WR(par, PM2R_RD_CURSOR_DATA, 0); 1485 + } 1486 + } 1487 + return 0; 1367 1488 } 1368 1489 1369 1490 /* ------------ Hardware Independent Functions ------------ */
+7
include/video/permedia2.h
··· 58 58 #define PM2R_RD_PALETTE_DATA 0x4008 59 59 #define PM2R_RD_PIXEL_MASK 0x4010 60 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 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 70 #define PM2R_START_X_DOM 0x8000 64 71 #define PM2R_D_X_DOM 0x8008