vpbe_osd.c 42 KB

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