console_rotate.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2015 Google, Inc
  4. * (C) Copyright 2015
  5. * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
  6. */
  7. #include <common.h>
  8. #include <dm.h>
  9. #include <video.h>
  10. #include <video_console.h>
  11. #include <video_font.h> /* Get font data, width and height */
  12. static int console_set_row_1(struct udevice *dev, uint row, int clr)
  13. {
  14. struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
  15. int pbytes = VNBYTES(vid_priv->bpix);
  16. void *line;
  17. int i, j;
  18. line = vid_priv->fb + vid_priv->line_length -
  19. (row + 1) * VIDEO_FONT_HEIGHT * pbytes;
  20. for (j = 0; j < vid_priv->ysize; j++) {
  21. switch (vid_priv->bpix) {
  22. #ifdef CONFIG_VIDEO_BPP8
  23. case VIDEO_BPP8: {
  24. uint8_t *dst = line;
  25. for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
  26. *dst++ = clr;
  27. break;
  28. }
  29. #endif
  30. #ifdef CONFIG_VIDEO_BPP16
  31. case VIDEO_BPP16: {
  32. uint16_t *dst = line;
  33. for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
  34. *dst++ = clr;
  35. break;
  36. }
  37. #endif
  38. #ifdef CONFIG_VIDEO_BPP32
  39. case VIDEO_BPP32: {
  40. uint32_t *dst = line;
  41. for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
  42. *dst++ = clr;
  43. break;
  44. }
  45. #endif
  46. default:
  47. return -ENOSYS;
  48. }
  49. line += vid_priv->line_length;
  50. }
  51. return 0;
  52. }
  53. static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
  54. uint count)
  55. {
  56. struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
  57. void *dst;
  58. void *src;
  59. int pbytes = VNBYTES(vid_priv->bpix);
  60. int j;
  61. dst = vid_priv->fb + vid_priv->line_length -
  62. (rowdst + count) * VIDEO_FONT_HEIGHT * pbytes;
  63. src = vid_priv->fb + vid_priv->line_length -
  64. (rowsrc + count) * VIDEO_FONT_HEIGHT * pbytes;
  65. for (j = 0; j < vid_priv->ysize; j++) {
  66. memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
  67. src += vid_priv->line_length;
  68. dst += vid_priv->line_length;
  69. }
  70. return 0;
  71. }
  72. static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
  73. {
  74. struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
  75. struct udevice *vid = dev->parent;
  76. struct video_priv *vid_priv = dev_get_uclass_priv(vid);
  77. int pbytes = VNBYTES(vid_priv->bpix);
  78. int i, col;
  79. int mask = 0x80;
  80. void *line;
  81. uchar *pfont = video_fontdata + ch * VIDEO_FONT_HEIGHT;
  82. line = vid_priv->fb + (VID_TO_PIXEL(x_frac) + 1) *
  83. vid_priv->line_length - (y + 1) * pbytes;
  84. if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
  85. return -EAGAIN;
  86. for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
  87. switch (vid_priv->bpix) {
  88. #ifdef CONFIG_VIDEO_BPP8
  89. case VIDEO_BPP8: {
  90. uint8_t *dst = line;
  91. for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
  92. *dst-- = (pfont[i] & mask) ? vid_priv->colour_fg
  93. : vid_priv->colour_bg;
  94. }
  95. break;
  96. }
  97. #endif
  98. #ifdef CONFIG_VIDEO_BPP16
  99. case VIDEO_BPP16: {
  100. uint16_t *dst = line;
  101. for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
  102. *dst-- = (pfont[i] & mask) ? vid_priv->colour_fg
  103. : vid_priv->colour_bg;
  104. }
  105. break;
  106. }
  107. #endif
  108. #ifdef CONFIG_VIDEO_BPP32
  109. case VIDEO_BPP32: {
  110. uint32_t *dst = line;
  111. for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
  112. *dst-- = (pfont[i] & mask) ? vid_priv->colour_fg
  113. : vid_priv->colour_bg;
  114. }
  115. break;
  116. }
  117. #endif
  118. default:
  119. return -ENOSYS;
  120. }
  121. line += vid_priv->line_length;
  122. mask >>= 1;
  123. }
  124. return VID_TO_POS(VIDEO_FONT_WIDTH);
  125. }
  126. static int console_set_row_2(struct udevice *dev, uint row, int clr)
  127. {
  128. struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
  129. void *line;
  130. int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
  131. int i;
  132. line = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
  133. (row + 1) * VIDEO_FONT_HEIGHT * vid_priv->line_length;
  134. switch (vid_priv->bpix) {
  135. #ifdef CONFIG_VIDEO_BPP8
  136. case VIDEO_BPP8: {
  137. uint8_t *dst = line;
  138. for (i = 0; i < pixels; i++)
  139. *dst++ = clr;
  140. break;
  141. }
  142. #endif
  143. #ifdef CONFIG_VIDEO_BPP16
  144. case VIDEO_BPP16: {
  145. uint16_t *dst = line;
  146. for (i = 0; i < pixels; i++)
  147. *dst++ = clr;
  148. break;
  149. }
  150. #endif
  151. #ifdef CONFIG_VIDEO_BPP32
  152. case VIDEO_BPP32: {
  153. uint32_t *dst = line;
  154. for (i = 0; i < pixels; i++)
  155. *dst++ = clr;
  156. break;
  157. }
  158. #endif
  159. default:
  160. return -ENOSYS;
  161. }
  162. return 0;
  163. }
  164. static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc,
  165. uint count)
  166. {
  167. struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
  168. void *dst;
  169. void *src;
  170. void *end;
  171. end = vid_priv->fb + vid_priv->ysize * vid_priv->line_length;
  172. dst = end - (rowdst + count) * VIDEO_FONT_HEIGHT *
  173. vid_priv->line_length;
  174. src = end - (rowsrc + count) * VIDEO_FONT_HEIGHT *
  175. vid_priv->line_length;
  176. memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
  177. return 0;
  178. }
  179. static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
  180. {
  181. struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
  182. struct udevice *vid = dev->parent;
  183. struct video_priv *vid_priv = dev_get_uclass_priv(vid);
  184. int i, row;
  185. void *line;
  186. if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
  187. return -EAGAIN;
  188. line = vid_priv->fb + (vid_priv->ysize - y - 1) *
  189. vid_priv->line_length +
  190. (vid_priv->xsize - VID_TO_PIXEL(x_frac) -
  191. VIDEO_FONT_WIDTH - 1) * VNBYTES(vid_priv->bpix);
  192. for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
  193. uchar bits = video_fontdata[ch * VIDEO_FONT_HEIGHT + row];
  194. switch (vid_priv->bpix) {
  195. #ifdef CONFIG_VIDEO_BPP8
  196. case VIDEO_BPP8: {
  197. uint8_t *dst = line;
  198. for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
  199. *dst-- = (bits & 0x80) ? vid_priv->colour_fg
  200. : vid_priv->colour_bg;
  201. bits <<= 1;
  202. }
  203. break;
  204. }
  205. #endif
  206. #ifdef CONFIG_VIDEO_BPP16
  207. case VIDEO_BPP16: {
  208. uint16_t *dst = line;
  209. for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
  210. *dst-- = (bits & 0x80) ? vid_priv->colour_fg
  211. : vid_priv->colour_bg;
  212. bits <<= 1;
  213. }
  214. break;
  215. }
  216. #endif
  217. #ifdef CONFIG_VIDEO_BPP32
  218. case VIDEO_BPP32: {
  219. uint32_t *dst = line;
  220. for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
  221. *dst-- = (bits & 0x80) ? vid_priv->colour_fg
  222. : vid_priv->colour_bg;
  223. bits <<= 1;
  224. }
  225. break;
  226. }
  227. #endif
  228. default:
  229. return -ENOSYS;
  230. }
  231. line -= vid_priv->line_length;
  232. }
  233. return VID_TO_POS(VIDEO_FONT_WIDTH);
  234. }
  235. static int console_set_row_3(struct udevice *dev, uint row, int clr)
  236. {
  237. struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
  238. int pbytes = VNBYTES(vid_priv->bpix);
  239. void *line;
  240. int i, j;
  241. line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * pbytes;
  242. for (j = 0; j < vid_priv->ysize; j++) {
  243. switch (vid_priv->bpix) {
  244. #ifdef CONFIG_VIDEO_BPP8
  245. case VIDEO_BPP8: {
  246. uint8_t *dst = line;
  247. for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
  248. *dst++ = clr;
  249. break;
  250. }
  251. #endif
  252. #ifdef CONFIG_VIDEO_BPP16
  253. case VIDEO_BPP16: {
  254. uint16_t *dst = line;
  255. for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
  256. *dst++ = clr;
  257. break;
  258. }
  259. #endif
  260. #ifdef CONFIG_VIDEO_BPP32
  261. case VIDEO_BPP32: {
  262. uint32_t *dst = line;
  263. for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
  264. *dst++ = clr;
  265. break;
  266. }
  267. #endif
  268. default:
  269. return -ENOSYS;
  270. }
  271. line += vid_priv->line_length;
  272. }
  273. return 0;
  274. }
  275. static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc,
  276. uint count)
  277. {
  278. struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
  279. void *dst;
  280. void *src;
  281. int pbytes = VNBYTES(vid_priv->bpix);
  282. int j;
  283. dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * pbytes;
  284. src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * pbytes;
  285. for (j = 0; j < vid_priv->ysize; j++) {
  286. memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
  287. src += vid_priv->line_length;
  288. dst += vid_priv->line_length;
  289. }
  290. return 0;
  291. }
  292. static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
  293. {
  294. struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
  295. struct udevice *vid = dev->parent;
  296. struct video_priv *vid_priv = dev_get_uclass_priv(vid);
  297. int pbytes = VNBYTES(vid_priv->bpix);
  298. int i, col;
  299. int mask = 0x80;
  300. void *line = vid_priv->fb +
  301. (vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1) *
  302. vid_priv->line_length + y * pbytes;
  303. uchar *pfont = video_fontdata + ch * VIDEO_FONT_HEIGHT;
  304. if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
  305. return -EAGAIN;
  306. for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
  307. switch (vid_priv->bpix) {
  308. #ifdef CONFIG_VIDEO_BPP8
  309. case VIDEO_BPP8: {
  310. uint8_t *dst = line;
  311. for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
  312. *dst++ = (pfont[i] & mask) ? vid_priv->colour_fg
  313. : vid_priv->colour_bg;
  314. }
  315. break;
  316. }
  317. #endif
  318. #ifdef CONFIG_VIDEO_BPP16
  319. case VIDEO_BPP16: {
  320. uint16_t *dst = line;
  321. for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
  322. *dst++ = (pfont[i] & mask) ? vid_priv->colour_fg
  323. : vid_priv->colour_bg;
  324. }
  325. break;
  326. }
  327. #endif
  328. #ifdef CONFIG_VIDEO_BPP32
  329. case VIDEO_BPP32: {
  330. uint32_t *dst = line;
  331. for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
  332. *dst++ = (pfont[i] & mask) ? vid_priv->colour_fg
  333. : vid_priv->colour_bg;
  334. }
  335. break;
  336. }
  337. #endif
  338. default:
  339. return -ENOSYS;
  340. }
  341. line -= vid_priv->line_length;
  342. mask >>= 1;
  343. }
  344. return VID_TO_POS(VIDEO_FONT_WIDTH);
  345. }
  346. static int console_probe_2(struct udevice *dev)
  347. {
  348. struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
  349. struct udevice *vid_dev = dev->parent;
  350. struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
  351. vc_priv->x_charsize = VIDEO_FONT_WIDTH;
  352. vc_priv->y_charsize = VIDEO_FONT_HEIGHT;
  353. vc_priv->cols = vid_priv->xsize / VIDEO_FONT_WIDTH;
  354. vc_priv->rows = vid_priv->ysize / VIDEO_FONT_HEIGHT;
  355. return 0;
  356. }
  357. static int console_probe_1_3(struct udevice *dev)
  358. {
  359. struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
  360. struct udevice *vid_dev = dev->parent;
  361. struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
  362. vc_priv->x_charsize = VIDEO_FONT_WIDTH;
  363. vc_priv->y_charsize = VIDEO_FONT_HEIGHT;
  364. vc_priv->cols = vid_priv->ysize / VIDEO_FONT_WIDTH;
  365. vc_priv->rows = vid_priv->xsize / VIDEO_FONT_HEIGHT;
  366. vc_priv->xsize_frac = VID_TO_POS(vid_priv->ysize);
  367. return 0;
  368. }
  369. struct vidconsole_ops console_ops_1 = {
  370. .putc_xy = console_putc_xy_1,
  371. .move_rows = console_move_rows_1,
  372. .set_row = console_set_row_1,
  373. };
  374. struct vidconsole_ops console_ops_2 = {
  375. .putc_xy = console_putc_xy_2,
  376. .move_rows = console_move_rows_2,
  377. .set_row = console_set_row_2,
  378. };
  379. struct vidconsole_ops console_ops_3 = {
  380. .putc_xy = console_putc_xy_3,
  381. .move_rows = console_move_rows_3,
  382. .set_row = console_set_row_3,
  383. };
  384. U_BOOT_DRIVER(vidconsole_1) = {
  385. .name = "vidconsole1",
  386. .id = UCLASS_VIDEO_CONSOLE,
  387. .ops = &console_ops_1,
  388. .probe = console_probe_1_3,
  389. };
  390. U_BOOT_DRIVER(vidconsole_2) = {
  391. .name = "vidconsole2",
  392. .id = UCLASS_VIDEO_CONSOLE,
  393. .ops = &console_ops_2,
  394. .probe = console_probe_2,
  395. };
  396. U_BOOT_DRIVER(vidconsole_3) = {
  397. .name = "vidconsole3",
  398. .id = UCLASS_VIDEO_CONSOLE,
  399. .ops = &console_ops_3,
  400. .probe = console_probe_1_3,
  401. };