vpbe_osd.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596
  1. /*
  2. * Copyright (C) 2007-2010 Texas Instruments Inc
  3. * Copyright (C) 2007 MontaVista Software, Inc.
  4. *
  5. * Andy Lowe (alowe@mvista.com), MontaVista Software
  6. * - Initial version
  7. * Murali Karicheri (mkaricheri@gmail.com), Texas Instruments Ltd.
  8. * - ported to sub device interface
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation version 2.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. */
  20. #include <linux/module.h>
  21. #include <linux/mod_devicetable.h>
  22. #include <linux/kernel.h>
  23. #include <linux/interrupt.h>
  24. #include <linux/platform_device.h>
  25. #include <linux/clk.h>
  26. #include <linux/slab.h>
  27. #ifdef CONFIG_ARCH_DAVINCI
  28. #include <mach/cputype.h>
  29. #include <mach/hardware.h>
  30. #endif
  31. #include <media/davinci/vpss.h>
  32. #include <media/v4l2-device.h>
  33. #include <media/davinci/vpbe_types.h>
  34. #include <media/davinci/vpbe_osd.h>
  35. #include <linux/io.h>
  36. #include "vpbe_osd_regs.h"
  37. #define MODULE_NAME "davinci-vpbe-osd"
  38. static const struct platform_device_id vpbe_osd_devtype[] = {
  39. {
  40. .name = DM644X_VPBE_OSD_SUBDEV_NAME,
  41. .driver_data = VPBE_VERSION_1,
  42. }, {
  43. .name = DM365_VPBE_OSD_SUBDEV_NAME,
  44. .driver_data = VPBE_VERSION_2,
  45. }, {
  46. .name = DM355_VPBE_OSD_SUBDEV_NAME,
  47. .driver_data = VPBE_VERSION_3,
  48. },
  49. {
  50. /* sentinel */
  51. }
  52. };
  53. MODULE_DEVICE_TABLE(platform, vpbe_osd_devtype);
  54. /* register access routines */
  55. static inline u32 osd_read(struct osd_state *sd, u32 offset)
  56. {
  57. struct osd_state *osd = sd;
  58. return readl(osd->osd_base + offset);
  59. }
  60. static inline u32 osd_write(struct osd_state *sd, u32 val, u32 offset)
  61. {
  62. struct osd_state *osd = sd;
  63. writel(val, osd->osd_base + offset);
  64. return val;
  65. }
  66. static inline u32 osd_set(struct osd_state *sd, u32 mask, u32 offset)
  67. {
  68. struct osd_state *osd = sd;
  69. void __iomem *addr = osd->osd_base + offset;
  70. u32 val = readl(addr) | mask;
  71. writel(val, addr);
  72. return val;
  73. }
  74. static inline u32 osd_clear(struct osd_state *sd, u32 mask, u32 offset)
  75. {
  76. struct osd_state *osd = sd;
  77. void __iomem *addr = osd->osd_base + offset;
  78. u32 val = readl(addr) & ~mask;
  79. writel(val, addr);
  80. return val;
  81. }
  82. static inline u32 osd_modify(struct osd_state *sd, u32 mask, u32 val,
  83. u32 offset)
  84. {
  85. struct osd_state *osd = sd;
  86. void __iomem *addr = osd->osd_base + offset;
  87. u32 new_val = (readl(addr) & ~mask) | (val & mask);
  88. writel(new_val, addr);
  89. return new_val;
  90. }
  91. /* define some macros for layer and pixfmt classification */
  92. #define is_osd_win(layer) (((layer) == WIN_OSD0) || ((layer) == WIN_OSD1))
  93. #define is_vid_win(layer) (((layer) == WIN_VID0) || ((layer) == WIN_VID1))
  94. #define is_rgb_pixfmt(pixfmt) \
  95. (((pixfmt) == PIXFMT_RGB565) || ((pixfmt) == PIXFMT_RGB888))
  96. #define is_yc_pixfmt(pixfmt) \
  97. (((pixfmt) == PIXFMT_YCBCRI) || ((pixfmt) == PIXFMT_YCRCBI) || \
  98. ((pixfmt) == PIXFMT_NV12))
  99. #define MAX_WIN_SIZE OSD_VIDWIN0XP_V0X
  100. #define MAX_LINE_LENGTH (OSD_VIDWIN0OFST_V0LO << 5)
  101. /**
  102. * _osd_dm6446_vid0_pingpong() - field inversion fix for DM6446
  103. * @sd: ptr to struct osd_state
  104. * @field_inversion: inversion flag
  105. * @fb_base_phys: frame buffer address
  106. * @lconfig: ptr to layer config
  107. *
  108. * This routine implements a workaround for the field signal inversion silicon
  109. * erratum described in Advisory 1.3.8 for the DM6446. The fb_base_phys and
  110. * lconfig parameters apply to the vid0 window. This routine should be called
  111. * whenever the vid0 layer configuration or start address is modified, or when
  112. * the OSD field inversion setting is modified.
  113. * Returns: 1 if the ping-pong buffers need to be toggled in the vsync isr, or
  114. * 0 otherwise
  115. */
  116. static int _osd_dm6446_vid0_pingpong(struct osd_state *sd,
  117. int field_inversion,
  118. unsigned long fb_base_phys,
  119. const struct osd_layer_config *lconfig)
  120. {
  121. struct osd_platform_data *pdata;
  122. pdata = (struct osd_platform_data *)sd->dev->platform_data;
  123. if (pdata != NULL && pdata->field_inv_wa_enable) {
  124. if (!field_inversion || !lconfig->interlaced) {
  125. osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR);
  126. osd_write(sd, fb_base_phys & ~0x1F, OSD_PPVWIN0ADR);
  127. osd_modify(sd, OSD_MISCCTL_PPSW | OSD_MISCCTL_PPRV, 0,
  128. OSD_MISCCTL);
  129. return 0;
  130. } else {
  131. unsigned miscctl = OSD_MISCCTL_PPRV;
  132. osd_write(sd,
  133. (fb_base_phys & ~0x1F) - lconfig->line_length,
  134. OSD_VIDWIN0ADR);
  135. osd_write(sd,
  136. (fb_base_phys & ~0x1F) + lconfig->line_length,
  137. OSD_PPVWIN0ADR);
  138. osd_modify(sd,
  139. OSD_MISCCTL_PPSW | OSD_MISCCTL_PPRV, miscctl,
  140. OSD_MISCCTL);
  141. return 1;
  142. }
  143. }
  144. return 0;
  145. }
  146. static void _osd_set_field_inversion(struct osd_state *sd, int enable)
  147. {
  148. unsigned fsinv = 0;
  149. if (enable)
  150. fsinv = OSD_MODE_FSINV;
  151. osd_modify(sd, OSD_MODE_FSINV, fsinv, OSD_MODE);
  152. }
  153. static void _osd_set_blink_attribute(struct osd_state *sd, int enable,
  154. enum osd_blink_interval blink)
  155. {
  156. u32 osdatrmd = 0;
  157. if (enable) {
  158. osdatrmd |= OSD_OSDATRMD_BLNK;
  159. osdatrmd |= blink << OSD_OSDATRMD_BLNKINT_SHIFT;
  160. }
  161. /* caller must ensure that OSD1 is configured in attribute mode */
  162. osd_modify(sd, OSD_OSDATRMD_BLNKINT | OSD_OSDATRMD_BLNK, osdatrmd,
  163. OSD_OSDATRMD);
  164. }
  165. static void _osd_set_rom_clut(struct osd_state *sd,
  166. enum osd_rom_clut rom_clut)
  167. {
  168. if (rom_clut == ROM_CLUT0)
  169. osd_clear(sd, OSD_MISCCTL_RSEL, OSD_MISCCTL);
  170. else
  171. osd_set(sd, OSD_MISCCTL_RSEL, OSD_MISCCTL);
  172. }
  173. static void _osd_set_palette_map(struct osd_state *sd,
  174. enum osd_win_layer osdwin,
  175. unsigned char pixel_value,
  176. unsigned char clut_index,
  177. enum osd_pix_format pixfmt)
  178. {
  179. static const int map_2bpp[] = { 0, 5, 10, 15 };
  180. static const int map_1bpp[] = { 0, 15 };
  181. int bmp_offset;
  182. int bmp_shift;
  183. int bmp_mask;
  184. int bmp_reg;
  185. switch (pixfmt) {
  186. case PIXFMT_1BPP:
  187. bmp_reg = map_1bpp[pixel_value & 0x1];
  188. break;
  189. case PIXFMT_2BPP:
  190. bmp_reg = map_2bpp[pixel_value & 0x3];
  191. break;
  192. case PIXFMT_4BPP:
  193. bmp_reg = pixel_value & 0xf;
  194. break;
  195. default:
  196. return;
  197. }
  198. switch (osdwin) {
  199. case OSDWIN_OSD0:
  200. bmp_offset = OSD_W0BMP01 + (bmp_reg >> 1) * sizeof(u32);
  201. break;
  202. case OSDWIN_OSD1:
  203. bmp_offset = OSD_W1BMP01 + (bmp_reg >> 1) * sizeof(u32);
  204. break;
  205. default:
  206. return;
  207. }
  208. if (bmp_reg & 1) {
  209. bmp_shift = 8;
  210. bmp_mask = 0xff << 8;
  211. } else {
  212. bmp_shift = 0;
  213. bmp_mask = 0xff;
  214. }
  215. osd_modify(sd, bmp_mask, clut_index << bmp_shift, bmp_offset);
  216. }
  217. static void _osd_set_rec601_attenuation(struct osd_state *sd,
  218. enum osd_win_layer osdwin, int enable)
  219. {
  220. switch (osdwin) {
  221. case OSDWIN_OSD0:
  222. osd_modify(sd, OSD_OSDWIN0MD_ATN0E,
  223. enable ? OSD_OSDWIN0MD_ATN0E : 0,
  224. OSD_OSDWIN0MD);
  225. if (sd->vpbe_type == VPBE_VERSION_1)
  226. osd_modify(sd, OSD_OSDWIN0MD_ATN0E,
  227. enable ? OSD_OSDWIN0MD_ATN0E : 0,
  228. OSD_OSDWIN0MD);
  229. else if ((sd->vpbe_type == VPBE_VERSION_3) ||
  230. (sd->vpbe_type == VPBE_VERSION_2))
  231. osd_modify(sd, OSD_EXTMODE_ATNOSD0EN,
  232. enable ? OSD_EXTMODE_ATNOSD0EN : 0,
  233. OSD_EXTMODE);
  234. break;
  235. case OSDWIN_OSD1:
  236. osd_modify(sd, OSD_OSDWIN1MD_ATN1E,
  237. enable ? OSD_OSDWIN1MD_ATN1E : 0,
  238. OSD_OSDWIN1MD);
  239. if (sd->vpbe_type == VPBE_VERSION_1)
  240. osd_modify(sd, OSD_OSDWIN1MD_ATN1E,
  241. enable ? OSD_OSDWIN1MD_ATN1E : 0,
  242. OSD_OSDWIN1MD);
  243. else if ((sd->vpbe_type == VPBE_VERSION_3) ||
  244. (sd->vpbe_type == VPBE_VERSION_2))
  245. osd_modify(sd, OSD_EXTMODE_ATNOSD1EN,
  246. enable ? OSD_EXTMODE_ATNOSD1EN : 0,
  247. OSD_EXTMODE);
  248. break;
  249. }
  250. }
  251. static void _osd_set_blending_factor(struct osd_state *sd,
  252. enum osd_win_layer osdwin,
  253. enum osd_blending_factor blend)
  254. {
  255. switch (osdwin) {
  256. case OSDWIN_OSD0:
  257. osd_modify(sd, OSD_OSDWIN0MD_BLND0,
  258. blend << OSD_OSDWIN0MD_BLND0_SHIFT, OSD_OSDWIN0MD);
  259. break;
  260. case OSDWIN_OSD1:
  261. osd_modify(sd, OSD_OSDWIN1MD_BLND1,
  262. blend << OSD_OSDWIN1MD_BLND1_SHIFT, OSD_OSDWIN1MD);
  263. break;
  264. }
  265. }
  266. static void _osd_enable_rgb888_pixblend(struct osd_state *sd,
  267. enum osd_win_layer osdwin)
  268. {
  269. osd_modify(sd, OSD_MISCCTL_BLDSEL, 0, OSD_MISCCTL);
  270. switch (osdwin) {
  271. case OSDWIN_OSD0:
  272. osd_modify(sd, OSD_EXTMODE_OSD0BLDCHR,
  273. OSD_EXTMODE_OSD0BLDCHR, OSD_EXTMODE);
  274. break;
  275. case OSDWIN_OSD1:
  276. osd_modify(sd, OSD_EXTMODE_OSD1BLDCHR,
  277. OSD_EXTMODE_OSD1BLDCHR, OSD_EXTMODE);
  278. break;
  279. }
  280. }
  281. static void _osd_enable_color_key(struct osd_state *sd,
  282. enum osd_win_layer osdwin,
  283. unsigned colorkey,
  284. enum osd_pix_format pixfmt)
  285. {
  286. switch (pixfmt) {
  287. case PIXFMT_1BPP:
  288. case PIXFMT_2BPP:
  289. case PIXFMT_4BPP:
  290. case PIXFMT_8BPP:
  291. if (sd->vpbe_type == VPBE_VERSION_3) {
  292. switch (osdwin) {
  293. case OSDWIN_OSD0:
  294. osd_modify(sd, OSD_TRANSPBMPIDX_BMP0,
  295. colorkey <<
  296. OSD_TRANSPBMPIDX_BMP0_SHIFT,
  297. OSD_TRANSPBMPIDX);
  298. break;
  299. case OSDWIN_OSD1:
  300. osd_modify(sd, OSD_TRANSPBMPIDX_BMP1,
  301. colorkey <<
  302. OSD_TRANSPBMPIDX_BMP1_SHIFT,
  303. OSD_TRANSPBMPIDX);
  304. break;
  305. }
  306. }
  307. break;
  308. case PIXFMT_RGB565:
  309. if (sd->vpbe_type == VPBE_VERSION_1)
  310. osd_write(sd, colorkey & OSD_TRANSPVAL_RGBTRANS,
  311. OSD_TRANSPVAL);
  312. else if (sd->vpbe_type == VPBE_VERSION_3)
  313. osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL,
  314. OSD_TRANSPVALL);
  315. break;
  316. case PIXFMT_YCBCRI:
  317. case PIXFMT_YCRCBI:
  318. if (sd->vpbe_type == VPBE_VERSION_3)
  319. osd_modify(sd, OSD_TRANSPVALU_Y, colorkey,
  320. OSD_TRANSPVALU);
  321. break;
  322. case PIXFMT_RGB888:
  323. if (sd->vpbe_type == VPBE_VERSION_3) {
  324. osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL,
  325. OSD_TRANSPVALL);
  326. osd_modify(sd, OSD_TRANSPVALU_RGBU, colorkey >> 16,
  327. OSD_TRANSPVALU);
  328. }
  329. break;
  330. default:
  331. break;
  332. }
  333. switch (osdwin) {
  334. case OSDWIN_OSD0:
  335. osd_set(sd, OSD_OSDWIN0MD_TE0, OSD_OSDWIN0MD);
  336. break;
  337. case OSDWIN_OSD1:
  338. osd_set(sd, OSD_OSDWIN1MD_TE1, OSD_OSDWIN1MD);
  339. break;
  340. }
  341. }
  342. static void _osd_disable_color_key(struct osd_state *sd,
  343. enum osd_win_layer osdwin)
  344. {
  345. switch (osdwin) {
  346. case OSDWIN_OSD0:
  347. osd_clear(sd, OSD_OSDWIN0MD_TE0, OSD_OSDWIN0MD);
  348. break;
  349. case OSDWIN_OSD1:
  350. osd_clear(sd, OSD_OSDWIN1MD_TE1, OSD_OSDWIN1MD);
  351. break;
  352. }
  353. }
  354. static void _osd_set_osd_clut(struct osd_state *sd,
  355. enum osd_win_layer osdwin,
  356. enum osd_clut clut)
  357. {
  358. u32 winmd = 0;
  359. switch (osdwin) {
  360. case OSDWIN_OSD0:
  361. if (clut == RAM_CLUT)
  362. winmd |= OSD_OSDWIN0MD_CLUTS0;
  363. osd_modify(sd, OSD_OSDWIN0MD_CLUTS0, winmd, OSD_OSDWIN0MD);
  364. break;
  365. case OSDWIN_OSD1:
  366. if (clut == RAM_CLUT)
  367. winmd |= OSD_OSDWIN1MD_CLUTS1;
  368. osd_modify(sd, OSD_OSDWIN1MD_CLUTS1, winmd, OSD_OSDWIN1MD);
  369. break;
  370. }
  371. }
  372. static void _osd_set_zoom(struct osd_state *sd, enum osd_layer layer,
  373. enum osd_zoom_factor h_zoom,
  374. enum osd_zoom_factor v_zoom)
  375. {
  376. u32 winmd = 0;
  377. switch (layer) {
  378. case WIN_OSD0:
  379. winmd |= (h_zoom << OSD_OSDWIN0MD_OHZ0_SHIFT);
  380. winmd |= (v_zoom << OSD_OSDWIN0MD_OVZ0_SHIFT);
  381. osd_modify(sd, OSD_OSDWIN0MD_OHZ0 | OSD_OSDWIN0MD_OVZ0, winmd,
  382. OSD_OSDWIN0MD);
  383. break;
  384. case WIN_VID0:
  385. winmd |= (h_zoom << OSD_VIDWINMD_VHZ0_SHIFT);
  386. winmd |= (v_zoom << OSD_VIDWINMD_VVZ0_SHIFT);
  387. osd_modify(sd, OSD_VIDWINMD_VHZ0 | OSD_VIDWINMD_VVZ0, winmd,
  388. OSD_VIDWINMD);
  389. break;
  390. case WIN_OSD1:
  391. winmd |= (h_zoom << OSD_OSDWIN1MD_OHZ1_SHIFT);
  392. winmd |= (v_zoom << OSD_OSDWIN1MD_OVZ1_SHIFT);
  393. osd_modify(sd, OSD_OSDWIN1MD_OHZ1 | OSD_OSDWIN1MD_OVZ1, winmd,
  394. OSD_OSDWIN1MD);
  395. break;
  396. case WIN_VID1:
  397. winmd |= (h_zoom << OSD_VIDWINMD_VHZ1_SHIFT);
  398. winmd |= (v_zoom << OSD_VIDWINMD_VVZ1_SHIFT);
  399. osd_modify(sd, OSD_VIDWINMD_VHZ1 | OSD_VIDWINMD_VVZ1, winmd,
  400. OSD_VIDWINMD);
  401. break;
  402. }
  403. }
  404. static void _osd_disable_layer(struct osd_state *sd, enum osd_layer layer)
  405. {
  406. switch (layer) {
  407. case WIN_OSD0:
  408. osd_clear(sd, OSD_OSDWIN0MD_OACT0, OSD_OSDWIN0MD);
  409. break;
  410. case WIN_VID0:
  411. osd_clear(sd, OSD_VIDWINMD_ACT0, OSD_VIDWINMD);
  412. break;
  413. case WIN_OSD1:
  414. /* disable attribute mode as well as disabling the window */
  415. osd_clear(sd, OSD_OSDWIN1MD_OASW | OSD_OSDWIN1MD_OACT1,
  416. OSD_OSDWIN1MD);
  417. break;
  418. case WIN_VID1:
  419. osd_clear(sd, OSD_VIDWINMD_ACT1, OSD_VIDWINMD);
  420. break;
  421. }
  422. }
  423. static void osd_disable_layer(struct osd_state *sd, enum osd_layer layer)
  424. {
  425. struct osd_state *osd = sd;
  426. struct osd_window_state *win = &osd->win[layer];
  427. unsigned long flags;
  428. spin_lock_irqsave(&osd->lock, flags);
  429. if (!win->is_enabled) {
  430. spin_unlock_irqrestore(&osd->lock, flags);
  431. return;
  432. }
  433. win->is_enabled = 0;
  434. _osd_disable_layer(sd, layer);
  435. spin_unlock_irqrestore(&osd->lock, flags);
  436. }
  437. static void _osd_enable_attribute_mode(struct osd_state *sd)
  438. {
  439. /* enable attribute mode for OSD1 */
  440. osd_set(sd, OSD_OSDWIN1MD_OASW, OSD_OSDWIN1MD);
  441. }
  442. static void _osd_enable_layer(struct osd_state *sd, enum osd_layer layer)
  443. {
  444. switch (layer) {
  445. case WIN_OSD0:
  446. osd_set(sd, OSD_OSDWIN0MD_OACT0, OSD_OSDWIN0MD);
  447. break;
  448. case WIN_VID0:
  449. osd_set(sd, OSD_VIDWINMD_ACT0, OSD_VIDWINMD);
  450. break;
  451. case WIN_OSD1:
  452. /* enable OSD1 and disable attribute mode */
  453. osd_modify(sd, OSD_OSDWIN1MD_OASW | OSD_OSDWIN1MD_OACT1,
  454. OSD_OSDWIN1MD_OACT1, OSD_OSDWIN1MD);
  455. break;
  456. case WIN_VID1:
  457. osd_set(sd, OSD_VIDWINMD_ACT1, OSD_VIDWINMD);
  458. break;
  459. }
  460. }
  461. static int osd_enable_layer(struct osd_state *sd, enum osd_layer layer,
  462. int otherwin)
  463. {
  464. struct osd_state *osd = sd;
  465. struct osd_window_state *win = &osd->win[layer];
  466. struct osd_layer_config *cfg = &win->lconfig;
  467. unsigned long flags;
  468. spin_lock_irqsave(&osd->lock, flags);
  469. /*
  470. * use otherwin flag to know this is the other vid window
  471. * in YUV420 mode, if is, skip this check
  472. */
  473. if (!otherwin && (!win->is_allocated ||
  474. !win->fb_base_phys ||
  475. !cfg->line_length ||
  476. !cfg->xsize ||
  477. !cfg->ysize)) {
  478. spin_unlock_irqrestore(&osd->lock, flags);
  479. return -1;
  480. }
  481. if (win->is_enabled) {
  482. spin_unlock_irqrestore(&osd->lock, flags);
  483. return 0;
  484. }
  485. win->is_enabled = 1;
  486. if (cfg->pixfmt != PIXFMT_OSD_ATTR)
  487. _osd_enable_layer(sd, layer);
  488. else {
  489. _osd_enable_attribute_mode(sd);
  490. _osd_set_blink_attribute(sd, osd->is_blinking, osd->blink);
  491. }
  492. spin_unlock_irqrestore(&osd->lock, flags);
  493. return 0;
  494. }
  495. #define OSD_SRC_ADDR_HIGH4 0x7800000
  496. #define OSD_SRC_ADDR_HIGH7 0x7F0000
  497. #define OSD_SRCADD_OFSET_SFT 23
  498. #define OSD_SRCADD_ADD_SFT 16
  499. #define OSD_WINADL_MASK 0xFFFF
  500. #define OSD_WINOFST_MASK 0x1000
  501. #define VPBE_REG_BASE 0x80000000
  502. static void _osd_start_layer(struct osd_state *sd, enum osd_layer layer,
  503. unsigned long fb_base_phys,
  504. unsigned long cbcr_ofst)
  505. {
  506. if (sd->vpbe_type == VPBE_VERSION_1) {
  507. switch (layer) {
  508. case WIN_OSD0:
  509. osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN0ADR);
  510. break;
  511. case WIN_VID0:
  512. osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR);
  513. break;
  514. case WIN_OSD1:
  515. osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN1ADR);
  516. break;
  517. case WIN_VID1:
  518. osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN1ADR);
  519. break;
  520. }
  521. } else if (sd->vpbe_type == VPBE_VERSION_3) {
  522. unsigned long fb_offset_32 =
  523. (fb_base_phys - VPBE_REG_BASE) >> 5;
  524. switch (layer) {
  525. case WIN_OSD0:
  526. osd_modify(sd, OSD_OSDWINADH_O0AH,
  527. fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
  528. OSD_OSDWINADH_O0AH_SHIFT),
  529. OSD_OSDWINADH);
  530. osd_write(sd, fb_offset_32 & OSD_OSDWIN0ADL_O0AL,
  531. OSD_OSDWIN0ADL);
  532. break;
  533. case WIN_VID0:
  534. osd_modify(sd, OSD_VIDWINADH_V0AH,
  535. fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
  536. OSD_VIDWINADH_V0AH_SHIFT),
  537. OSD_VIDWINADH);
  538. osd_write(sd, fb_offset_32 & OSD_VIDWIN0ADL_V0AL,
  539. OSD_VIDWIN0ADL);
  540. break;
  541. case WIN_OSD1:
  542. osd_modify(sd, OSD_OSDWINADH_O1AH,
  543. fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
  544. OSD_OSDWINADH_O1AH_SHIFT),
  545. OSD_OSDWINADH);
  546. osd_write(sd, fb_offset_32 & OSD_OSDWIN1ADL_O1AL,
  547. OSD_OSDWIN1ADL);
  548. break;
  549. case WIN_VID1:
  550. osd_modify(sd, OSD_VIDWINADH_V1AH,
  551. fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
  552. OSD_VIDWINADH_V1AH_SHIFT),
  553. OSD_VIDWINADH);
  554. osd_write(sd, fb_offset_32 & OSD_VIDWIN1ADL_V1AL,
  555. OSD_VIDWIN1ADL);
  556. break;
  557. }
  558. } else if (sd->vpbe_type == VPBE_VERSION_2) {
  559. struct osd_window_state *win = &sd->win[layer];
  560. unsigned long fb_offset_32, cbcr_offset_32;
  561. fb_offset_32 = fb_base_phys - VPBE_REG_BASE;
  562. if (cbcr_ofst)
  563. cbcr_offset_32 = cbcr_ofst;
  564. else
  565. cbcr_offset_32 = win->lconfig.line_length *
  566. win->lconfig.ysize;
  567. cbcr_offset_32 += fb_offset_32;
  568. fb_offset_32 = fb_offset_32 >> 5;
  569. cbcr_offset_32 = cbcr_offset_32 >> 5;
  570. /*
  571. * DM365: start address is 27-bit long address b26 - b23 are
  572. * in offset register b12 - b9, and * bit 26 has to be '1'
  573. */
  574. if (win->lconfig.pixfmt == PIXFMT_NV12) {
  575. switch (layer) {
  576. case WIN_VID0:
  577. case WIN_VID1:
  578. /* Y is in VID0 */
  579. osd_modify(sd, OSD_VIDWIN0OFST_V0AH,
  580. ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
  581. (OSD_SRCADD_OFSET_SFT -
  582. OSD_WINOFST_AH_SHIFT)) |
  583. OSD_WINOFST_MASK, OSD_VIDWIN0OFST);
  584. osd_modify(sd, OSD_VIDWINADH_V0AH,
  585. (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
  586. (OSD_SRCADD_ADD_SFT -
  587. OSD_VIDWINADH_V0AH_SHIFT),
  588. OSD_VIDWINADH);
  589. osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
  590. OSD_VIDWIN0ADL);
  591. /* CbCr is in VID1 */
  592. osd_modify(sd, OSD_VIDWIN1OFST_V1AH,
  593. ((cbcr_offset_32 &
  594. OSD_SRC_ADDR_HIGH4) >>
  595. (OSD_SRCADD_OFSET_SFT -
  596. OSD_WINOFST_AH_SHIFT)) |
  597. OSD_WINOFST_MASK, OSD_VIDWIN1OFST);
  598. osd_modify(sd, OSD_VIDWINADH_V1AH,
  599. (cbcr_offset_32 &
  600. OSD_SRC_ADDR_HIGH7) >>
  601. (OSD_SRCADD_ADD_SFT -
  602. OSD_VIDWINADH_V1AH_SHIFT),
  603. OSD_VIDWINADH);
  604. osd_write(sd, cbcr_offset_32 & OSD_WINADL_MASK,
  605. OSD_VIDWIN1ADL);
  606. break;
  607. default:
  608. break;
  609. }
  610. }
  611. switch (layer) {
  612. case WIN_OSD0:
  613. osd_modify(sd, OSD_OSDWIN0OFST_O0AH,
  614. ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
  615. (OSD_SRCADD_OFSET_SFT -
  616. OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK,
  617. OSD_OSDWIN0OFST);
  618. osd_modify(sd, OSD_OSDWINADH_O0AH,
  619. (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
  620. (OSD_SRCADD_ADD_SFT -
  621. OSD_OSDWINADH_O0AH_SHIFT), OSD_OSDWINADH);
  622. osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
  623. OSD_OSDWIN0ADL);
  624. break;
  625. case WIN_VID0:
  626. if (win->lconfig.pixfmt != PIXFMT_NV12) {
  627. osd_modify(sd, OSD_VIDWIN0OFST_V0AH,
  628. ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
  629. (OSD_SRCADD_OFSET_SFT -
  630. OSD_WINOFST_AH_SHIFT)) |
  631. OSD_WINOFST_MASK, OSD_VIDWIN0OFST);
  632. osd_modify(sd, OSD_VIDWINADH_V0AH,
  633. (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
  634. (OSD_SRCADD_ADD_SFT -
  635. OSD_VIDWINADH_V0AH_SHIFT),
  636. OSD_VIDWINADH);
  637. osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
  638. OSD_VIDWIN0ADL);
  639. }
  640. break;
  641. case WIN_OSD1:
  642. osd_modify(sd, OSD_OSDWIN1OFST_O1AH,
  643. ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
  644. (OSD_SRCADD_OFSET_SFT -
  645. OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK,
  646. OSD_OSDWIN1OFST);
  647. osd_modify(sd, OSD_OSDWINADH_O1AH,
  648. (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
  649. (OSD_SRCADD_ADD_SFT -
  650. OSD_OSDWINADH_O1AH_SHIFT),
  651. OSD_OSDWINADH);
  652. osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
  653. OSD_OSDWIN1ADL);
  654. break;
  655. case WIN_VID1:
  656. if (win->lconfig.pixfmt != PIXFMT_NV12) {
  657. osd_modify(sd, OSD_VIDWIN1OFST_V1AH,
  658. ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
  659. (OSD_SRCADD_OFSET_SFT -
  660. OSD_WINOFST_AH_SHIFT)) |
  661. OSD_WINOFST_MASK, OSD_VIDWIN1OFST);
  662. osd_modify(sd, OSD_VIDWINADH_V1AH,
  663. (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
  664. (OSD_SRCADD_ADD_SFT -
  665. OSD_VIDWINADH_V1AH_SHIFT),
  666. OSD_VIDWINADH);
  667. osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
  668. OSD_VIDWIN1ADL);
  669. }
  670. break;
  671. }
  672. }
  673. }
  674. static void osd_start_layer(struct osd_state *sd, enum osd_layer layer,
  675. unsigned long fb_base_phys,
  676. unsigned long cbcr_ofst)
  677. {
  678. struct osd_state *osd = sd;
  679. struct osd_window_state *win = &osd->win[layer];
  680. struct osd_layer_config *cfg = &win->lconfig;
  681. unsigned long flags;
  682. spin_lock_irqsave(&osd->lock, flags);
  683. win->fb_base_phys = fb_base_phys & ~0x1F;
  684. _osd_start_layer(sd, layer, fb_base_phys, cbcr_ofst);
  685. if (layer == WIN_VID0) {
  686. osd->pingpong =
  687. _osd_dm6446_vid0_pingpong(sd, osd->field_inversion,
  688. win->fb_base_phys,
  689. cfg);
  690. }
  691. spin_unlock_irqrestore(&osd->lock, flags);
  692. }
  693. static void osd_get_layer_config(struct osd_state *sd, enum osd_layer layer,
  694. struct osd_layer_config *lconfig)
  695. {
  696. struct osd_state *osd = sd;
  697. struct osd_window_state *win = &osd->win[layer];
  698. unsigned long flags;
  699. spin_lock_irqsave(&osd->lock, flags);
  700. *lconfig = win->lconfig;
  701. spin_unlock_irqrestore(&osd->lock, flags);
  702. }
  703. /**
  704. * try_layer_config() - Try a specific configuration for the layer
  705. * @sd: ptr to struct osd_state
  706. * @layer: layer to configure
  707. * @lconfig: layer configuration to try
  708. *
  709. * If the requested lconfig is completely rejected and the value of lconfig on
  710. * exit is the current lconfig, then try_layer_config() returns 1. Otherwise,
  711. * try_layer_config() returns 0. A return value of 0 does not necessarily mean
  712. * that the value of lconfig on exit is identical to the value of lconfig on
  713. * entry, but merely that it represents a change from the current lconfig.
  714. */
  715. static int try_layer_config(struct osd_state *sd, enum osd_layer layer,
  716. struct osd_layer_config *lconfig)
  717. {
  718. struct osd_state *osd = sd;
  719. struct osd_window_state *win = &osd->win[layer];
  720. int bad_config = 0;
  721. /* verify that the pixel format is compatible with the layer */
  722. switch (lconfig->pixfmt) {
  723. case PIXFMT_1BPP:
  724. case PIXFMT_2BPP:
  725. case PIXFMT_4BPP:
  726. case PIXFMT_8BPP:
  727. case PIXFMT_RGB565:
  728. if (osd->vpbe_type == VPBE_VERSION_1)
  729. bad_config = !is_vid_win(layer);
  730. break;
  731. case PIXFMT_YCBCRI:
  732. case PIXFMT_YCRCBI:
  733. bad_config = !is_vid_win(layer);
  734. break;
  735. case PIXFMT_RGB888:
  736. if (osd->vpbe_type == VPBE_VERSION_1)
  737. bad_config = !is_vid_win(layer);
  738. else if ((osd->vpbe_type == VPBE_VERSION_3) ||
  739. (osd->vpbe_type == VPBE_VERSION_2))
  740. bad_config = !is_osd_win(layer);
  741. break;
  742. case PIXFMT_NV12:
  743. if (osd->vpbe_type != VPBE_VERSION_2)
  744. bad_config = 1;
  745. else
  746. bad_config = is_osd_win(layer);
  747. break;
  748. case PIXFMT_OSD_ATTR:
  749. bad_config = (layer != WIN_OSD1);
  750. break;
  751. default:
  752. bad_config = 1;
  753. break;
  754. }
  755. if (bad_config) {
  756. /*
  757. * The requested pixel format is incompatible with the layer,
  758. * so keep the current layer configuration.
  759. */
  760. *lconfig = win->lconfig;
  761. return bad_config;
  762. }
  763. /* DM6446: */
  764. /* only one OSD window at a time can use RGB pixel formats */
  765. if ((osd->vpbe_type == VPBE_VERSION_1) &&
  766. is_osd_win(layer) && is_rgb_pixfmt(lconfig->pixfmt)) {
  767. enum osd_pix_format pixfmt;
  768. if (layer == WIN_OSD0)
  769. pixfmt = osd->win[WIN_OSD1].lconfig.pixfmt;
  770. else
  771. pixfmt = osd->win[WIN_OSD0].lconfig.pixfmt;
  772. if (is_rgb_pixfmt(pixfmt)) {
  773. /*
  774. * The other OSD window is already configured for an
  775. * RGB, so keep the current layer configuration.
  776. */
  777. *lconfig = win->lconfig;
  778. return 1;
  779. }
  780. }
  781. /* DM6446: only one video window at a time can use RGB888 */
  782. if ((osd->vpbe_type == VPBE_VERSION_1) && is_vid_win(layer) &&
  783. lconfig->pixfmt == PIXFMT_RGB888) {
  784. enum osd_pix_format pixfmt;
  785. if (layer == WIN_VID0)
  786. pixfmt = osd->win[WIN_VID1].lconfig.pixfmt;
  787. else
  788. pixfmt = osd->win[WIN_VID0].lconfig.pixfmt;
  789. if (pixfmt == PIXFMT_RGB888) {
  790. /*
  791. * The other video window is already configured for
  792. * RGB888, so keep the current layer configuration.
  793. */
  794. *lconfig = win->lconfig;
  795. return 1;
  796. }
  797. }
  798. /* window dimensions must be non-zero */
  799. if (!lconfig->line_length || !lconfig->xsize || !lconfig->ysize) {
  800. *lconfig = win->lconfig;
  801. return 1;
  802. }
  803. /* round line_length up to a multiple of 32 */
  804. lconfig->line_length = ((lconfig->line_length + 31) / 32) * 32;
  805. lconfig->line_length =
  806. min(lconfig->line_length, (unsigned)MAX_LINE_LENGTH);
  807. lconfig->xsize = min(lconfig->xsize, (unsigned)MAX_WIN_SIZE);
  808. lconfig->ysize = min(lconfig->ysize, (unsigned)MAX_WIN_SIZE);
  809. lconfig->xpos = min(lconfig->xpos, (unsigned)MAX_WIN_SIZE);
  810. lconfig->ypos = min(lconfig->ypos, (unsigned)MAX_WIN_SIZE);
  811. lconfig->interlaced = (lconfig->interlaced != 0);
  812. if (lconfig->interlaced) {
  813. /* ysize and ypos must be even for interlaced displays */
  814. lconfig->ysize &= ~1;
  815. lconfig->ypos &= ~1;
  816. }
  817. return 0;
  818. }
  819. static void _osd_disable_vid_rgb888(struct osd_state *sd)
  820. {
  821. /*
  822. * The DM6446 supports RGB888 pixel format in a single video window.
  823. * This routine disables RGB888 pixel format for both video windows.
  824. * The caller must ensure that neither video window is currently
  825. * configured for RGB888 pixel format.
  826. */
  827. if (sd->vpbe_type == VPBE_VERSION_1)
  828. osd_clear(sd, OSD_MISCCTL_RGBEN, OSD_MISCCTL);
  829. }
  830. static void _osd_enable_vid_rgb888(struct osd_state *sd,
  831. enum osd_layer layer)
  832. {
  833. /*
  834. * The DM6446 supports RGB888 pixel format in a single video window.
  835. * This routine enables RGB888 pixel format for the specified video
  836. * window. The caller must ensure that the other video window is not
  837. * currently configured for RGB888 pixel format, as this routine will
  838. * disable RGB888 pixel format for the other window.
  839. */
  840. if (sd->vpbe_type == VPBE_VERSION_1) {
  841. if (layer == WIN_VID0)
  842. osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
  843. OSD_MISCCTL_RGBEN, OSD_MISCCTL);
  844. else if (layer == WIN_VID1)
  845. osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
  846. OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
  847. OSD_MISCCTL);
  848. }
  849. }
  850. static void _osd_set_cbcr_order(struct osd_state *sd,
  851. enum osd_pix_format pixfmt)
  852. {
  853. /*
  854. * The caller must ensure that all windows using YC pixfmt use the same
  855. * Cb/Cr order.
  856. */
  857. if (pixfmt == PIXFMT_YCBCRI)
  858. osd_clear(sd, OSD_MODE_CS, OSD_MODE);
  859. else if (pixfmt == PIXFMT_YCRCBI)
  860. osd_set(sd, OSD_MODE_CS, OSD_MODE);
  861. }
  862. static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer,
  863. const struct osd_layer_config *lconfig)
  864. {
  865. u32 winmd = 0, winmd_mask = 0, bmw = 0;
  866. _osd_set_cbcr_order(sd, lconfig->pixfmt);
  867. switch (layer) {
  868. case WIN_OSD0:
  869. if (sd->vpbe_type == VPBE_VERSION_1) {
  870. winmd_mask |= OSD_OSDWIN0MD_RGB0E;
  871. if (lconfig->pixfmt == PIXFMT_RGB565)
  872. winmd |= OSD_OSDWIN0MD_RGB0E;
  873. } else if ((sd->vpbe_type == VPBE_VERSION_3) ||
  874. (sd->vpbe_type == VPBE_VERSION_2)) {
  875. winmd_mask |= OSD_OSDWIN0MD_BMP0MD;
  876. switch (lconfig->pixfmt) {
  877. case PIXFMT_RGB565:
  878. winmd |= (1 <<
  879. OSD_OSDWIN0MD_BMP0MD_SHIFT);
  880. break;
  881. case PIXFMT_RGB888:
  882. winmd |= (2 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
  883. _osd_enable_rgb888_pixblend(sd, OSDWIN_OSD0);
  884. break;
  885. case PIXFMT_YCBCRI:
  886. case PIXFMT_YCRCBI:
  887. winmd |= (3 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
  888. break;
  889. default:
  890. break;
  891. }
  892. }
  893. winmd_mask |= OSD_OSDWIN0MD_BMW0 | OSD_OSDWIN0MD_OFF0;
  894. switch (lconfig->pixfmt) {
  895. case PIXFMT_1BPP:
  896. bmw = 0;
  897. break;
  898. case PIXFMT_2BPP:
  899. bmw = 1;
  900. break;
  901. case PIXFMT_4BPP:
  902. bmw = 2;
  903. break;
  904. case PIXFMT_8BPP:
  905. bmw = 3;
  906. break;
  907. default:
  908. break;
  909. }
  910. winmd |= (bmw << OSD_OSDWIN0MD_BMW0_SHIFT);
  911. if (lconfig->interlaced)
  912. winmd |= OSD_OSDWIN0MD_OFF0;
  913. osd_modify(sd, winmd_mask, winmd, OSD_OSDWIN0MD);
  914. osd_write(sd, lconfig->line_length >> 5, OSD_OSDWIN0OFST);
  915. osd_write(sd, lconfig->xpos, OSD_OSDWIN0XP);
  916. osd_write(sd, lconfig->xsize, OSD_OSDWIN0XL);
  917. if (lconfig->interlaced) {
  918. osd_write(sd, lconfig->ypos >> 1, OSD_OSDWIN0YP);
  919. osd_write(sd, lconfig->ysize >> 1, OSD_OSDWIN0YL);
  920. } else {
  921. osd_write(sd, lconfig->ypos, OSD_OSDWIN0YP);
  922. osd_write(sd, lconfig->ysize, OSD_OSDWIN0YL);
  923. }
  924. break;
  925. case WIN_VID0:
  926. winmd_mask |= OSD_VIDWINMD_VFF0;
  927. if (lconfig->interlaced)
  928. winmd |= OSD_VIDWINMD_VFF0;
  929. osd_modify(sd, winmd_mask, winmd, OSD_VIDWINMD);
  930. osd_write(sd, lconfig->line_length >> 5, OSD_VIDWIN0OFST);
  931. osd_write(sd, lconfig->xpos, OSD_VIDWIN0XP);
  932. osd_write(sd, lconfig->xsize, OSD_VIDWIN0XL);
  933. /*
  934. * For YUV420P format the register contents are
  935. * duplicated in both VID registers
  936. */
  937. if ((sd->vpbe_type == VPBE_VERSION_2) &&
  938. (lconfig->pixfmt == PIXFMT_NV12)) {
  939. /* other window also */
  940. if (lconfig->interlaced) {
  941. winmd_mask |= OSD_VIDWINMD_VFF1;
  942. winmd |= OSD_VIDWINMD_VFF1;
  943. osd_modify(sd, winmd_mask, winmd,
  944. OSD_VIDWINMD);
  945. }
  946. osd_modify(sd, OSD_MISCCTL_S420D,
  947. OSD_MISCCTL_S420D, OSD_MISCCTL);
  948. osd_write(sd, lconfig->line_length >> 5,
  949. OSD_VIDWIN1OFST);
  950. osd_write(sd, lconfig->xpos, OSD_VIDWIN1XP);
  951. osd_write(sd, lconfig->xsize, OSD_VIDWIN1XL);
  952. /*
  953. * if NV21 pixfmt and line length not 32B
  954. * aligned (e.g. NTSC), Need to set window
  955. * X pixel size to be 32B aligned as well
  956. */
  957. if (lconfig->xsize % 32) {
  958. osd_write(sd,
  959. ((lconfig->xsize + 31) & ~31),
  960. OSD_VIDWIN1XL);
  961. osd_write(sd,
  962. ((lconfig->xsize + 31) & ~31),
  963. OSD_VIDWIN0XL);
  964. }
  965. } else if ((sd->vpbe_type == VPBE_VERSION_2) &&
  966. (lconfig->pixfmt != PIXFMT_NV12)) {
  967. osd_modify(sd, OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D,
  968. OSD_MISCCTL);
  969. }
  970. if (lconfig->interlaced) {
  971. osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN0YP);
  972. osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN0YL);
  973. if ((sd->vpbe_type == VPBE_VERSION_2) &&
  974. lconfig->pixfmt == PIXFMT_NV12) {
  975. osd_write(sd, lconfig->ypos >> 1,
  976. OSD_VIDWIN1YP);
  977. osd_write(sd, lconfig->ysize >> 1,
  978. OSD_VIDWIN1YL);
  979. }
  980. } else {
  981. osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP);
  982. osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL);
  983. if ((sd->vpbe_type == VPBE_VERSION_2) &&
  984. lconfig->pixfmt == PIXFMT_NV12) {
  985. osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP);
  986. osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL);
  987. }
  988. }
  989. break;
  990. case WIN_OSD1:
  991. /*
  992. * The caller must ensure that OSD1 is disabled prior to
  993. * switching from a normal mode to attribute mode or from
  994. * attribute mode to a normal mode.
  995. */
  996. if (lconfig->pixfmt == PIXFMT_OSD_ATTR) {
  997. if (sd->vpbe_type == VPBE_VERSION_1) {
  998. winmd_mask |= OSD_OSDWIN1MD_ATN1E |
  999. OSD_OSDWIN1MD_RGB1E | OSD_OSDWIN1MD_CLUTS1 |
  1000. OSD_OSDWIN1MD_BLND1 | OSD_OSDWIN1MD_TE1;
  1001. } else {
  1002. winmd_mask |= OSD_OSDWIN1MD_BMP1MD |
  1003. OSD_OSDWIN1MD_CLUTS1 | OSD_OSDWIN1MD_BLND1 |
  1004. OSD_OSDWIN1MD_TE1;
  1005. }
  1006. } else {
  1007. if (sd->vpbe_type == VPBE_VERSION_1) {
  1008. winmd_mask |= OSD_OSDWIN1MD_RGB1E;
  1009. if (lconfig->pixfmt == PIXFMT_RGB565)
  1010. winmd |= OSD_OSDWIN1MD_RGB1E;
  1011. } else if ((sd->vpbe_type == VPBE_VERSION_3)
  1012. || (sd->vpbe_type == VPBE_VERSION_2)) {
  1013. winmd_mask |= OSD_OSDWIN1MD_BMP1MD;
  1014. switch (lconfig->pixfmt) {
  1015. case PIXFMT_RGB565:
  1016. winmd |=
  1017. (1 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
  1018. break;
  1019. case PIXFMT_RGB888:
  1020. winmd |=
  1021. (2 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
  1022. _osd_enable_rgb888_pixblend(sd,
  1023. OSDWIN_OSD1);
  1024. break;
  1025. case PIXFMT_YCBCRI:
  1026. case PIXFMT_YCRCBI:
  1027. winmd |=
  1028. (3 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
  1029. break;
  1030. default:
  1031. break;
  1032. }
  1033. }
  1034. winmd_mask |= OSD_OSDWIN1MD_BMW1;
  1035. switch (lconfig->pixfmt) {
  1036. case PIXFMT_1BPP:
  1037. bmw = 0;
  1038. break;
  1039. case PIXFMT_2BPP:
  1040. bmw = 1;
  1041. break;
  1042. case PIXFMT_4BPP:
  1043. bmw = 2;
  1044. break;
  1045. case PIXFMT_8BPP:
  1046. bmw = 3;
  1047. break;
  1048. default:
  1049. break;
  1050. }
  1051. winmd |= (bmw << OSD_OSDWIN1MD_BMW1_SHIFT);
  1052. }
  1053. winmd_mask |= OSD_OSDWIN1MD_OFF1;
  1054. if (lconfig->interlaced)
  1055. winmd |= OSD_OSDWIN1MD_OFF1;
  1056. osd_modify(sd, winmd_mask, winmd, OSD_OSDWIN1MD);
  1057. osd_write(sd, lconfig->line_length >> 5, OSD_OSDWIN1OFST);
  1058. osd_write(sd, lconfig->xpos, OSD_OSDWIN1XP);
  1059. osd_write(sd, lconfig->xsize, OSD_OSDWIN1XL);
  1060. if (lconfig->interlaced) {
  1061. osd_write(sd, lconfig->ypos >> 1, OSD_OSDWIN1YP);
  1062. osd_write(sd, lconfig->ysize >> 1, OSD_OSDWIN1YL);
  1063. } else {
  1064. osd_write(sd, lconfig->ypos, OSD_OSDWIN1YP);
  1065. osd_write(sd, lconfig->ysize, OSD_OSDWIN1YL);
  1066. }
  1067. break;
  1068. case WIN_VID1:
  1069. winmd_mask |= OSD_VIDWINMD_VFF1;
  1070. if (lconfig->interlaced)
  1071. winmd |= OSD_VIDWINMD_VFF1;
  1072. osd_modify(sd, winmd_mask, winmd, OSD_VIDWINMD);
  1073. osd_write(sd, lconfig->line_length >> 5, OSD_VIDWIN1OFST);
  1074. osd_write(sd, lconfig->xpos, OSD_VIDWIN1XP);
  1075. osd_write(sd, lconfig->xsize, OSD_VIDWIN1XL);
  1076. /*
  1077. * For YUV420P format the register contents are
  1078. * duplicated in both VID registers
  1079. */
  1080. if (sd->vpbe_type == VPBE_VERSION_2) {
  1081. if (lconfig->pixfmt == PIXFMT_NV12) {
  1082. /* other window also */
  1083. if (lconfig->interlaced) {
  1084. winmd_mask |= OSD_VIDWINMD_VFF0;
  1085. winmd |= OSD_VIDWINMD_VFF0;
  1086. osd_modify(sd, winmd_mask, winmd,
  1087. OSD_VIDWINMD);
  1088. }
  1089. osd_modify(sd, OSD_MISCCTL_S420D,
  1090. OSD_MISCCTL_S420D, OSD_MISCCTL);
  1091. osd_write(sd, lconfig->line_length >> 5,
  1092. OSD_VIDWIN0OFST);
  1093. osd_write(sd, lconfig->xpos, OSD_VIDWIN0XP);
  1094. osd_write(sd, lconfig->xsize, OSD_VIDWIN0XL);
  1095. } else {
  1096. osd_modify(sd, OSD_MISCCTL_S420D,
  1097. ~OSD_MISCCTL_S420D, OSD_MISCCTL);
  1098. }
  1099. }
  1100. if (lconfig->interlaced) {
  1101. osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN1YP);
  1102. osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN1YL);
  1103. if ((sd->vpbe_type == VPBE_VERSION_2) &&
  1104. lconfig->pixfmt == PIXFMT_NV12) {
  1105. osd_write(sd, lconfig->ypos >> 1,
  1106. OSD_VIDWIN0YP);
  1107. osd_write(sd, lconfig->ysize >> 1,
  1108. OSD_VIDWIN0YL);
  1109. }
  1110. } else {
  1111. osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP);
  1112. osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL);
  1113. if ((sd->vpbe_type == VPBE_VERSION_2) &&
  1114. lconfig->pixfmt == PIXFMT_NV12) {
  1115. osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP);
  1116. osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL);
  1117. }
  1118. }
  1119. break;
  1120. }
  1121. }
  1122. static int osd_set_layer_config(struct osd_state *sd, enum osd_layer layer,
  1123. struct osd_layer_config *lconfig)
  1124. {
  1125. struct osd_state *osd = sd;
  1126. struct osd_window_state *win = &osd->win[layer];
  1127. struct osd_layer_config *cfg = &win->lconfig;
  1128. unsigned long flags;
  1129. int reject_config;
  1130. spin_lock_irqsave(&osd->lock, flags);
  1131. reject_config = try_layer_config(sd, layer, lconfig);
  1132. if (reject_config) {
  1133. spin_unlock_irqrestore(&osd->lock, flags);
  1134. return reject_config;
  1135. }
  1136. /* update the current Cb/Cr order */
  1137. if (is_yc_pixfmt(lconfig->pixfmt))
  1138. osd->yc_pixfmt = lconfig->pixfmt;
  1139. /*
  1140. * If we are switching OSD1 from normal mode to attribute mode or from
  1141. * attribute mode to normal mode, then we must disable the window.
  1142. */
  1143. if (layer == WIN_OSD1) {
  1144. if (((lconfig->pixfmt == PIXFMT_OSD_ATTR) &&
  1145. (cfg->pixfmt != PIXFMT_OSD_ATTR)) ||
  1146. ((lconfig->pixfmt != PIXFMT_OSD_ATTR) &&
  1147. (cfg->pixfmt == PIXFMT_OSD_ATTR))) {
  1148. win->is_enabled = 0;
  1149. _osd_disable_layer(sd, layer);
  1150. }
  1151. }
  1152. _osd_set_layer_config(sd, layer, lconfig);
  1153. if (layer == WIN_OSD1) {
  1154. struct osd_osdwin_state *osdwin_state =
  1155. &osd->osdwin[OSDWIN_OSD1];
  1156. if ((lconfig->pixfmt != PIXFMT_OSD_ATTR) &&
  1157. (cfg->pixfmt == PIXFMT_OSD_ATTR)) {
  1158. /*
  1159. * We just switched OSD1 from attribute mode to normal
  1160. * mode, so we must initialize the CLUT select, the
  1161. * blend factor, transparency colorkey enable, and
  1162. * attenuation enable (DM6446 only) bits in the
  1163. * OSDWIN1MD register.
  1164. */
  1165. _osd_set_osd_clut(sd, OSDWIN_OSD1,
  1166. osdwin_state->clut);
  1167. _osd_set_blending_factor(sd, OSDWIN_OSD1,
  1168. osdwin_state->blend);
  1169. if (osdwin_state->colorkey_blending) {
  1170. _osd_enable_color_key(sd, OSDWIN_OSD1,
  1171. osdwin_state->
  1172. colorkey,
  1173. lconfig->pixfmt);
  1174. } else
  1175. _osd_disable_color_key(sd, OSDWIN_OSD1);
  1176. _osd_set_rec601_attenuation(sd, OSDWIN_OSD1,
  1177. osdwin_state->
  1178. rec601_attenuation);
  1179. } else if ((lconfig->pixfmt == PIXFMT_OSD_ATTR) &&
  1180. (cfg->pixfmt != PIXFMT_OSD_ATTR)) {
  1181. /*
  1182. * We just switched OSD1 from normal mode to attribute
  1183. * mode, so we must initialize the blink enable and
  1184. * blink interval bits in the OSDATRMD register.
  1185. */
  1186. _osd_set_blink_attribute(sd, osd->is_blinking,
  1187. osd->blink);
  1188. }
  1189. }
  1190. /*
  1191. * If we just switched to a 1-, 2-, or 4-bits-per-pixel bitmap format
  1192. * then configure a default palette map.
  1193. */
  1194. if ((lconfig->pixfmt != cfg->pixfmt) &&
  1195. ((lconfig->pixfmt == PIXFMT_1BPP) ||
  1196. (lconfig->pixfmt == PIXFMT_2BPP) ||
  1197. (lconfig->pixfmt == PIXFMT_4BPP))) {
  1198. enum osd_win_layer osdwin =
  1199. ((layer == WIN_OSD0) ? OSDWIN_OSD0 : OSDWIN_OSD1);
  1200. struct osd_osdwin_state *osdwin_state =
  1201. &osd->osdwin[osdwin];
  1202. unsigned char clut_index;
  1203. unsigned char clut_entries = 0;
  1204. switch (lconfig->pixfmt) {
  1205. case PIXFMT_1BPP:
  1206. clut_entries = 2;
  1207. break;
  1208. case PIXFMT_2BPP:
  1209. clut_entries = 4;
  1210. break;
  1211. case PIXFMT_4BPP:
  1212. clut_entries = 16;
  1213. break;
  1214. default:
  1215. break;
  1216. }
  1217. /*
  1218. * The default palette map maps the pixel value to the clut
  1219. * index, i.e. pixel value 0 maps to clut entry 0, pixel value
  1220. * 1 maps to clut entry 1, etc.
  1221. */
  1222. for (clut_index = 0; clut_index < 16; clut_index++) {
  1223. osdwin_state->palette_map[clut_index] = clut_index;
  1224. if (clut_index < clut_entries) {
  1225. _osd_set_palette_map(sd, osdwin, clut_index,
  1226. clut_index,
  1227. lconfig->pixfmt);
  1228. }
  1229. }
  1230. }
  1231. *cfg = *lconfig;
  1232. /* DM6446: configure the RGB888 enable and window selection */
  1233. if (osd->win[WIN_VID0].lconfig.pixfmt == PIXFMT_RGB888)
  1234. _osd_enable_vid_rgb888(sd, WIN_VID0);
  1235. else if (osd->win[WIN_VID1].lconfig.pixfmt == PIXFMT_RGB888)
  1236. _osd_enable_vid_rgb888(sd, WIN_VID1);
  1237. else
  1238. _osd_disable_vid_rgb888(sd);
  1239. if (layer == WIN_VID0) {
  1240. osd->pingpong =
  1241. _osd_dm6446_vid0_pingpong(sd, osd->field_inversion,
  1242. win->fb_base_phys,
  1243. cfg);
  1244. }
  1245. spin_unlock_irqrestore(&osd->lock, flags);
  1246. return 0;
  1247. }
  1248. static void osd_init_layer(struct osd_state *sd, enum osd_layer layer)
  1249. {
  1250. struct osd_state *osd = sd;
  1251. struct osd_window_state *win = &osd->win[layer];
  1252. enum osd_win_layer osdwin;
  1253. struct osd_osdwin_state *osdwin_state;
  1254. struct osd_layer_config *cfg = &win->lconfig;
  1255. unsigned long flags;
  1256. spin_lock_irqsave(&osd->lock, flags);
  1257. win->is_enabled = 0;
  1258. _osd_disable_layer(sd, layer);
  1259. win->h_zoom = ZOOM_X1;
  1260. win->v_zoom = ZOOM_X1;
  1261. _osd_set_zoom(sd, layer, win->h_zoom, win->v_zoom);
  1262. win->fb_base_phys = 0;
  1263. _osd_start_layer(sd, layer, win->fb_base_phys, 0);
  1264. cfg->line_length = 0;
  1265. cfg->xsize = 0;
  1266. cfg->ysize = 0;
  1267. cfg->xpos = 0;
  1268. cfg->ypos = 0;
  1269. cfg->interlaced = 0;
  1270. switch (layer) {
  1271. case WIN_OSD0:
  1272. case WIN_OSD1:
  1273. osdwin = (layer == WIN_OSD0) ? OSDWIN_OSD0 : OSDWIN_OSD1;
  1274. osdwin_state = &osd->osdwin[osdwin];
  1275. /*
  1276. * Other code relies on the fact that OSD windows default to a
  1277. * bitmap pixel format when they are deallocated, so don't
  1278. * change this default pixel format.
  1279. */
  1280. cfg->pixfmt = PIXFMT_8BPP;
  1281. _osd_set_layer_config(sd, layer, cfg);
  1282. osdwin_state->clut = RAM_CLUT;
  1283. _osd_set_osd_clut(sd, osdwin, osdwin_state->clut);
  1284. osdwin_state->colorkey_blending = 0;
  1285. _osd_disable_color_key(sd, osdwin);
  1286. osdwin_state->blend = OSD_8_VID_0;
  1287. _osd_set_blending_factor(sd, osdwin, osdwin_state->blend);
  1288. osdwin_state->rec601_attenuation = 0;
  1289. _osd_set_rec601_attenuation(sd, osdwin,
  1290. osdwin_state->
  1291. rec601_attenuation);
  1292. if (osdwin == OSDWIN_OSD1) {
  1293. osd->is_blinking = 0;
  1294. osd->blink = BLINK_X1;
  1295. }
  1296. break;
  1297. case WIN_VID0:
  1298. case WIN_VID1:
  1299. cfg->pixfmt = osd->yc_pixfmt;
  1300. _osd_set_layer_config(sd, layer, cfg);
  1301. break;
  1302. }
  1303. spin_unlock_irqrestore(&osd->lock, flags);
  1304. }
  1305. static void osd_release_layer(struct osd_state *sd, enum osd_layer layer)
  1306. {
  1307. struct osd_state *osd = sd;
  1308. struct osd_window_state *win = &osd->win[layer];
  1309. unsigned long flags;
  1310. spin_lock_irqsave(&osd->lock, flags);
  1311. if (!win->is_allocated) {
  1312. spin_unlock_irqrestore(&osd->lock, flags);
  1313. return;
  1314. }
  1315. spin_unlock_irqrestore(&osd->lock, flags);
  1316. osd_init_layer(sd, layer);
  1317. spin_lock_irqsave(&osd->lock, flags);
  1318. win->is_allocated = 0;
  1319. spin_unlock_irqrestore(&osd->lock, flags);
  1320. }
  1321. static int osd_request_layer(struct osd_state *sd, enum osd_layer layer)
  1322. {
  1323. struct osd_state *osd = sd;
  1324. struct osd_window_state *win = &osd->win[layer];
  1325. unsigned long flags;
  1326. spin_lock_irqsave(&osd->lock, flags);
  1327. if (win->is_allocated) {
  1328. spin_unlock_irqrestore(&osd->lock, flags);
  1329. return -1;
  1330. }
  1331. win->is_allocated = 1;
  1332. spin_unlock_irqrestore(&osd->lock, flags);
  1333. return 0;
  1334. }
  1335. static void _osd_init(struct osd_state *sd)
  1336. {
  1337. osd_write(sd, 0, OSD_MODE);
  1338. osd_write(sd, 0, OSD_VIDWINMD);
  1339. osd_write(sd, 0, OSD_OSDWIN0MD);
  1340. osd_write(sd, 0, OSD_OSDWIN1MD);
  1341. osd_write(sd, 0, OSD_RECTCUR);
  1342. osd_write(sd, 0, OSD_MISCCTL);
  1343. if (sd->vpbe_type == VPBE_VERSION_3) {
  1344. osd_write(sd, 0, OSD_VBNDRY);
  1345. osd_write(sd, 0, OSD_EXTMODE);
  1346. osd_write(sd, OSD_MISCCTL_DMANG, OSD_MISCCTL);
  1347. }
  1348. }
  1349. static void osd_set_left_margin(struct osd_state *sd, u32 val)
  1350. {
  1351. osd_write(sd, val, OSD_BASEPX);
  1352. }
  1353. static void osd_set_top_margin(struct osd_state *sd, u32 val)
  1354. {
  1355. osd_write(sd, val, OSD_BASEPY);
  1356. }
  1357. static int osd_initialize(struct osd_state *osd)
  1358. {
  1359. if (osd == NULL)
  1360. return -ENODEV;
  1361. _osd_init(osd);
  1362. /* set default Cb/Cr order */
  1363. osd->yc_pixfmt = PIXFMT_YCBCRI;
  1364. if (osd->vpbe_type == VPBE_VERSION_3) {
  1365. /*
  1366. * ROM CLUT1 on the DM355 is similar (identical?) to ROM CLUT0
  1367. * on the DM6446, so make ROM_CLUT1 the default on the DM355.
  1368. */
  1369. osd->rom_clut = ROM_CLUT1;
  1370. }
  1371. _osd_set_field_inversion(osd, osd->field_inversion);
  1372. _osd_set_rom_clut(osd, osd->rom_clut);
  1373. osd_init_layer(osd, WIN_OSD0);
  1374. osd_init_layer(osd, WIN_VID0);
  1375. osd_init_layer(osd, WIN_OSD1);
  1376. osd_init_layer(osd, WIN_VID1);
  1377. return 0;
  1378. }
  1379. static const struct vpbe_osd_ops osd_ops = {
  1380. .initialize = osd_initialize,
  1381. .request_layer = osd_request_layer,
  1382. .release_layer = osd_release_layer,
  1383. .enable_layer = osd_enable_layer,
  1384. .disable_layer = osd_disable_layer,
  1385. .set_layer_config = osd_set_layer_config,
  1386. .get_layer_config = osd_get_layer_config,
  1387. .start_layer = osd_start_layer,
  1388. .set_left_margin = osd_set_left_margin,
  1389. .set_top_margin = osd_set_top_margin,
  1390. };
  1391. static int osd_probe(struct platform_device *pdev)
  1392. {
  1393. const struct platform_device_id *pdev_id;
  1394. struct osd_state *osd;
  1395. struct resource *res;
  1396. pdev_id = platform_get_device_id(pdev);
  1397. if (!pdev_id)
  1398. return -EINVAL;
  1399. osd = devm_kzalloc(&pdev->dev, sizeof(struct osd_state), GFP_KERNEL);
  1400. if (osd == NULL)
  1401. return -ENOMEM;
  1402. osd->dev = &pdev->dev;
  1403. osd->vpbe_type = pdev_id->driver_data;
  1404. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  1405. osd->osd_base = devm_ioremap_resource(&pdev->dev, res);
  1406. if (IS_ERR(osd->osd_base))
  1407. return PTR_ERR(osd->osd_base);
  1408. osd->osd_base_phys = res->start;
  1409. osd->osd_size = resource_size(res);
  1410. spin_lock_init(&osd->lock);
  1411. osd->ops = osd_ops;
  1412. platform_set_drvdata(pdev, osd);
  1413. dev_notice(osd->dev, "OSD sub device probe success\n");
  1414. return 0;
  1415. }
  1416. static int osd_remove(struct platform_device *pdev)
  1417. {
  1418. return 0;
  1419. }
  1420. static struct platform_driver osd_driver = {
  1421. .probe = osd_probe,
  1422. .remove = osd_remove,
  1423. .driver = {
  1424. .name = MODULE_NAME,
  1425. },
  1426. .id_table = vpbe_osd_devtype
  1427. };
  1428. module_platform_driver(osd_driver);
  1429. MODULE_LICENSE("GPL");
  1430. MODULE_DESCRIPTION("DaVinci OSD Manager Driver");
  1431. MODULE_AUTHOR("Texas Instruments");