ark1668e_lcdc_funcs.c 81 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725
  1. /*
  2. * Arkmicro ark1668 lcd driver
  3. *
  4. * Licensed under GPLv2 or later.
  5. */
  6. #include <linux/kernel.h>
  7. #include <linux/fb.h>
  8. #include <linux/poll.h>
  9. #include "ark1668e_lcdc.h"
  10. #define CVBS_PAL 0
  11. #define CVBS_NTSC 1
  12. static struct ark1668e_lcdfb_info *lcdfb_info = NULL;
  13. static void *lcdc_base = NULL;
  14. static int lcdc_width = 0;
  15. static int lcdc_height = 0;
  16. static struct ark_disp_vp lcdc_vp = {0};
  17. #define lcdc_readl_sys(sinfo, reg) __raw_readl((sinfo)->sysreg+(reg))
  18. #define lcdc_writel_sys(sinfo, reg, val) __raw_writel((val), (sinfo)->sysreg+(reg))
  19. static int ark1668e_lcdc_layer_enable(int layer, int enable)
  20. {
  21. unsigned int reg;
  22. unsigned int val;
  23. int offset = 0;
  24. reg = ARK1668E_LCDC_CONTROL;
  25. val = readl(lcdc_base + reg);
  26. switch (layer) {
  27. case ARK1668E_LCDC_LAYER_VIDEO1:
  28. offset = 5;
  29. break;
  30. case ARK1668E_LCDC_LAYER_VIDEO2:
  31. offset = 6;
  32. break;
  33. case ARK1668E_LCDC_LAYER_OSD1:
  34. offset = 7;
  35. break;
  36. case ARK1668E_LCDC_LAYER_OSD2:
  37. offset = 8;
  38. break;
  39. case ARK1668E_LCDC_LAYER_OSD3:
  40. offset = 9;
  41. break;
  42. default:
  43. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  44. return -1;
  45. }
  46. if(enable)
  47. val |= (1<<offset);
  48. else
  49. val &= ~(1<<offset);
  50. writel(val, lcdc_base + reg);
  51. return 0;
  52. }
  53. //no use func
  54. #if 0
  55. static int ark1668e_lcdc_set_backcolor(int y, int cb, int cr)
  56. {
  57. unsigned int val = ((y&0xFF) << 16) |((cb&0xFF) << 8) | (cr&0xFF);
  58. writel(val, lcdc_base + ARK1668E_LCDC_BACK_COLOR);
  59. return 0;
  60. }
  61. static int ark1668e_lcdc_set_backcolor_tvout(int y, int cb, int cr)
  62. {
  63. unsigned int val = ((y&0xFF) << 16) |((cb&0xFF) << 8) | (cr&0xFF);
  64. writel(val, lcdc_base + ARK1668E_LCDC_BACK_COLOR_TV);
  65. return 0;
  66. }
  67. static int ark1668e_lcdc_set_priority(int video1_prio, int video2_prio, int osd1_prio, int osd2_prio, int osd3_prio)
  68. {
  69. unsigned int reg;
  70. unsigned int val;
  71. if((video1_prio + video2_prio + osd1_prio + osd2_prio + osd3_prio) != 10) {
  72. printk(KERN_ERR "%s, Invalid priority value, video1_prio:%d, video2_prio:%d, osd1_prio:%d, osd2_prio:%d, osd3_prio:%d\n",
  73. __FUNCTION__, video1_prio, video2_prio, osd1_prio, osd2_prio, osd3_prio);
  74. return -1;
  75. }
  76. reg = ARK1668E_LCDC_BLD_MODE_LCD_REG0;
  77. val = readl(lcdc_base + reg);
  78. val &= ~((0x7<<0) | (0x7<8) | (0x7<<16) | (0x7<24));
  79. val |= ((video1_prio<<0) | (osd1_prio<8) | (osd2_prio<<16) | (osd3_prio<24));
  80. writel(val, lcdc_base + reg);
  81. reg = ARK1668E_LCDC_BLD_MODE_LCD_REG1;
  82. val = readl(lcdc_base + reg);
  83. val &= ~(0x7<<0);
  84. val |= (video2_prio<<0);
  85. writel(val, lcdc_base + reg);
  86. return 0;
  87. }
  88. static int ark1668e_lcdc_set_priority_tvout(int video1_prio, int video2_prio, int osd1_prio, int osd2_prio, int osd3_prio)
  89. {
  90. unsigned int reg;
  91. unsigned int val;
  92. if((video1_prio + video2_prio + osd1_prio + osd2_prio + osd3_prio) != 10) {
  93. printk(KERN_ERR "%s, Invalid priority value, video1_prio:%d, video2_prio:%d, osd1_prio:%d, osd2_prio:%d, osd3_prio:%d\n",
  94. __FUNCTION__, video1_prio, video2_prio, osd1_prio, osd2_prio, osd3_prio);
  95. return -1;
  96. }
  97. reg = ARK1668E_LCDC_BLD_MODE_TV_REG0;
  98. val = readl(lcdc_base + reg);
  99. val &= ~((0x7<<0) | (0x7<8) | (0x7<<16) | (0x7<24));
  100. val |= ((video1_prio<<0) | (osd1_prio<8) | (osd2_prio<<16) | (osd3_prio<24));
  101. writel(val, lcdc_base + reg);
  102. reg = ARK1668E_LCDC_BLD_MODE_TV_REG1;
  103. val = readl(lcdc_base + reg);
  104. val &= ~(0x7<<0);
  105. val |= (video2_prio<<0);
  106. writel(val, lcdc_base + reg);
  107. return 0;
  108. }
  109. static int ark1668e_lcdc_set_alpha_blend_mode(int layer, int mode)
  110. {
  111. unsigned int reg;
  112. unsigned int val;
  113. int offset = 0;
  114. if((mode < 0) || (mode > 0xE0)) {
  115. printk(KERN_ERR "%s, Invalid mode:%d\n", __FUNCTION__, mode);
  116. return -1;
  117. }
  118. switch (layer) {
  119. case ARK1668E_LCDC_LAYER_VIDEO1:
  120. reg = ARK1668E_LCDC_BLD_MODE_LCD_REG0;
  121. offset = 4;
  122. break;
  123. case ARK1668E_LCDC_LAYER_VIDEO2:
  124. reg = ARK1668E_LCDC_BLD_MODE_LCD_REG1;
  125. offset = 4;
  126. break;
  127. case ARK1668E_LCDC_LAYER_OSD1:
  128. reg = ARK1668E_LCDC_BLD_MODE_LCD_REG0;
  129. offset = 12;
  130. break;
  131. case ARK1668E_LCDC_LAYER_OSD2:
  132. reg = ARK1668E_LCDC_BLD_MODE_LCD_REG0;
  133. offset = 20;
  134. break;
  135. case ARK1668E_LCDC_LAYER_OSD3:
  136. reg = ARK1668E_LCDC_BLD_MODE_LCD_REG0;
  137. offset = 28;
  138. break;
  139. default:
  140. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  141. return -1;
  142. }
  143. val = readl(lcdc_base + reg);
  144. val &= ~(0xF<<offset);
  145. val |= (mode<<offset);
  146. writel(val, lcdc_base + reg);
  147. return 0;
  148. }
  149. static int ark1668e_lcdc_set_alpha_blend_mode_tvout(int layer, int mode)
  150. {
  151. unsigned int reg;
  152. unsigned int val;
  153. int offset = 0;
  154. if((mode < 0) || (mode > 0xE0)) {
  155. printk(KERN_ERR "%s, Invalid mode:%d\n", __FUNCTION__, mode);
  156. return -1;
  157. }
  158. switch (layer) {
  159. case ARK1668E_LCDC_LAYER_VIDEO1:
  160. reg = ARK1668E_LCDC_BLD_MODE_TV_REG0;
  161. offset = 4;
  162. break;
  163. case ARK1668E_LCDC_LAYER_VIDEO2:
  164. reg = ARK1668E_LCDC_BLD_MODE_TV_REG1;
  165. offset = 4;
  166. break;
  167. case ARK1668E_LCDC_LAYER_OSD1:
  168. reg = ARK1668E_LCDC_BLD_MODE_TV_REG0;
  169. offset = 12;
  170. break;
  171. case ARK1668E_LCDC_LAYER_OSD2:
  172. reg = ARK1668E_LCDC_BLD_MODE_TV_REG0;
  173. offset = 20;
  174. break;
  175. case ARK1668E_LCDC_LAYER_OSD3:
  176. reg = ARK1668E_LCDC_BLD_MODE_TV_REG0;
  177. offset = 28;
  178. break;
  179. default:
  180. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  181. return -1;
  182. }
  183. val = readl(lcdc_base + reg);
  184. val &= ~(0xF<<offset);
  185. val |= (mode<<offset);
  186. writel(val, lcdc_base + reg);
  187. return 0;
  188. }
  189. static int ark1668e_lcdc_set_video_osd_alpha(int layer, int alpha)
  190. {
  191. unsigned int reg;
  192. unsigned int val;
  193. switch (layer) {
  194. case ARK1668E_LCDC_LAYER_VIDEO1:
  195. reg = ARK1668E_LCDC_VIDEO1_ALPHA1_ALPHA0_BLENDING_COEFF;
  196. break;
  197. case ARK1668E_LCDC_LAYER_VIDEO2:
  198. reg = ARK1668E_LCDC_VIDEO2_ALPHA1_ALPHA0_BLENDING_COEFF;
  199. break;
  200. case ARK1668E_LCDC_LAYER_OSD1:
  201. reg = ARK1668E_LCDC_OSD1_CTL;
  202. break;
  203. case ARK1668E_LCDC_LAYER_OSD2:
  204. reg = ARK1668E_LCDC_OSD2_CTL;
  205. break;
  206. case ARK1668E_LCDC_LAYER_OSD3:
  207. reg = ARK1668E_LCDC_OSD3_CTL;
  208. break;
  209. default:
  210. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  211. return -1;
  212. }
  213. val = readl(lcdc_base + reg);
  214. val &= ~0xFF;
  215. val |= alpha;
  216. writel(val, lcdc_base + reg);
  217. return 0;
  218. }
  219. static int ark1668e_lcdc_set_video_osd_blend_win_cut(int layer, int left, int right, int up, int down)
  220. {
  221. unsigned int reg_cut_lr, reg_cut_ud;
  222. unsigned int val;
  223. switch (layer) {
  224. case ARK1668E_LCDC_LAYER_VIDEO1:
  225. reg_cut_lr = ARK1668E_LCDC_BLD_CUT_LEFT_RIGHT_VIDEO1;
  226. reg_cut_ud = ARK1668E_LCDC_BLD_CUT_UP_DOWN_VIDEO1;
  227. break;
  228. case ARK1668E_LCDC_LAYER_VIDEO2:
  229. reg_cut_lr = ARK1668E_LCDC_BLD_CUT_LEFT_RIGHT_VIDEO2;
  230. reg_cut_ud = ARK1668E_LCDC_BLD_CUT_UP_DOWN_VIDEO2;
  231. break;
  232. case ARK1668E_LCDC_LAYER_OSD1:
  233. reg_cut_lr = ARK1668E_LCDC_BLD_CUT_LEFT_RIGHT_OSD1;
  234. reg_cut_ud = ARK1668E_LCDC_BLD_CUT_UP_DOWN_OSD1;
  235. break;
  236. case ARK1668E_LCDC_LAYER_OSD2:
  237. reg_cut_lr = ARK1668E_LCDC_BLD_CUT_LEFT_RIGHT_OSD2;
  238. reg_cut_ud = ARK1668E_LCDC_BLD_CUT_UP_DOWN_OSD2;
  239. break;
  240. case ARK1668E_LCDC_LAYER_OSD3:
  241. reg_cut_lr = ARK1668E_LCDC_BLD_CUT_LEFT_RIGHT_OSD3;
  242. reg_cut_ud = ARK1668E_LCDC_BLD_CUT_UP_DOWN_OSD3;
  243. break;
  244. default:
  245. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  246. return -1;
  247. }
  248. val = ((right&0xFFF)<<12) | (left&0xFFF);
  249. writel(val, lcdc_base + reg_cut_lr);
  250. val = ((down&0xFFF)<<12) | (up&0xFFF);
  251. writel(val, lcdc_base + reg_cut_ud);
  252. return 0;
  253. }
  254. static int ark1668e_lcdc_set_video_osd_colorkey_mask_value(int layer, int y, int cb, int cr, int enable)
  255. {
  256. unsigned int reg;
  257. unsigned int val;
  258. switch (layer) {
  259. case ARK1668E_LCDC_LAYER_VIDEO1:
  260. reg = ARK1668E_LCDC_COLOR_KEY_MASK_VALUE_VIDEO1;
  261. break;
  262. case ARK1668E_LCDC_LAYER_VIDEO2:
  263. reg = ARK1668E_LCDC_COLOR_KEY_MASK_VALUE_VIDEO2;
  264. break;
  265. case ARK1668E_LCDC_LAYER_OSD1:
  266. reg = ARK1668E_LCDC_COLOR_KEY_MASK_VALUE_OSD1;
  267. break;
  268. case ARK1668E_LCDC_LAYER_OSD2:
  269. reg = ARK1668E_LCDC_COLOR_KEY_MASK_VALUE_OSD2;
  270. break;
  271. case ARK1668E_LCDC_LAYER_OSD3:
  272. reg = ARK1668E_LCDC_COLOR_KEY_MASK_VALUE_OSD3;
  273. break;
  274. default:
  275. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  276. return -1;
  277. }
  278. val = ((!!enable)<<24) | ((y&0xFF)<<16) | ((cb&0xFF)<<8) | (cr&0xFF);
  279. writel(val, lcdc_base + reg);
  280. return 0;
  281. }
  282. static int ark1668e_lcdc_set_video_osd_colorkey_mask_thld(int layer, int y, int cb, int cr)
  283. {
  284. unsigned int reg;
  285. unsigned int val;
  286. switch (layer) {
  287. case ARK1668E_LCDC_LAYER_VIDEO1:
  288. reg = ARK1668E_LCDC_COLOR_KEY_MASK_THLD_VIDEO1;
  289. break;
  290. case ARK1668E_LCDC_LAYER_VIDEO2:
  291. reg = ARK1668E_LCDC_COLOR_KEY_MASK_THLD_VIDEO2;
  292. break;
  293. case ARK1668E_LCDC_LAYER_OSD1:
  294. reg = ARK1668E_LCDC_COLOR_KEY_MASK_THLD_OSD1;
  295. break;
  296. case ARK1668E_LCDC_LAYER_OSD2:
  297. reg = ARK1668E_LCDC_COLOR_KEY_MASK_THLD_OSD2;
  298. break;
  299. case ARK1668E_LCDC_LAYER_OSD3:
  300. reg = ARK1668E_LCDC_COLOR_KEY_MASK_THLD_OSD3;
  301. break;
  302. default:
  303. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  304. return -1;
  305. }
  306. val = ((y&0xFF)<<16) | ((cb&0xFF)<<8) | (cr&0xFF);
  307. writel(val, lcdc_base + reg);
  308. return 0;
  309. }
  310. static int ark1668e_lcdc_set_video_addr_group1(int layer, unsigned int yaddr,unsigned int cbaddr, unsigned int craddr)
  311. {
  312. unsigned int reg_addr1, reg_addr2, reg_addr3;
  313. switch (layer) {
  314. case ARK1668E_LCDC_LAYER_VIDEO1:
  315. reg_addr1 = ARK1668E_LCDC_VIDEO1_ADDR1_GROUP1;
  316. reg_addr2 = ARK1668E_LCDC_VIDEO1_ADDR2_GROUP1;
  317. reg_addr3 = ARK1668E_LCDC_VIDEO1_ADDR3_GROUP1;
  318. break;
  319. case ARK1668E_LCDC_LAYER_VIDEO2:
  320. reg_addr1 = ARK1668E_LCDC_VIDEO2_ADDR1_GROUP1;
  321. reg_addr2 = ARK1668E_LCDC_VIDEO2_ADDR2_GROUP1;
  322. reg_addr3 = ARK1668E_LCDC_VIDEO2_ADDR3_GROUP1;
  323. break;
  324. default:
  325. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  326. return -1;
  327. }
  328. writel(yaddr, lcdc_base + reg_addr1);
  329. if(cbaddr)
  330. writel(cbaddr, lcdc_base + reg_addr2);
  331. if(craddr)
  332. writel(craddr, lcdc_base + reg_addr3);
  333. return 0;
  334. }
  335. static int ark1668e_lcdc_set_video_ycbcr_format(int layer, ARK1668E_LCDC_YCBCR_FORMAT format)
  336. {
  337. unsigned int reg;
  338. unsigned int val;
  339. int offset = 0;
  340. if((format < 0) || (format >= ARK1668E_LCDC_YCBCR_FORMAT_END)) {
  341. printk(KERN_ERR "%s, Invalid YCBCR fromat:%d\n", __FUNCTION__, format);
  342. return -1;
  343. }
  344. switch (layer) {
  345. case ARK1668E_LCDC_LAYER_VIDEO1:
  346. reg = ARK1668E_LCDC_VIDEO1_CTL;
  347. offset = 21;
  348. break;
  349. case ARK1668E_LCDC_LAYER_VIDEO2:
  350. reg = ARK1668E_LCDC_VIDEO2_CTL;
  351. offset = 21;
  352. break;
  353. default:
  354. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  355. return -1;
  356. }
  357. val = readl(lcdc_base + reg);
  358. val &= ~(0x1 << offset);
  359. val |= ((format&0x1) << offset);
  360. writel(val, lcdc_base + reg);
  361. return 0;
  362. }
  363. static int ark1668e_lcdc_set_osd_addr_group1(int layer, int addr)
  364. {
  365. unsigned int reg;
  366. switch (layer) {
  367. case ARK1668E_LCDC_LAYER_OSD1:
  368. reg = ARK1668E_LCDC_OSD1_ADDR_GROUP1;
  369. break;
  370. case ARK1668E_LCDC_LAYER_OSD2:
  371. reg = ARK1668E_LCDC_OSD2_ADDR_GROUP1;
  372. break;
  373. case ARK1668E_LCDC_LAYER_OSD3:
  374. reg = ARK1668E_LCDC_OSD3_ADDR_GROUP1;
  375. break;
  376. default:
  377. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  378. return -1;
  379. }
  380. writel(addr, lcdc_base + reg);
  381. return 0;
  382. }
  383. static void ark1668e_lcdc_global_enable(int enable)
  384. {
  385. writel((enable?1:0), lcdc_base + ARK1668E_LCDC_EANBLE);
  386. }
  387. #endif
  388. static int ark1668e_lcdc_alpha_blend_per_pix_mode_enable(int layer, int enable)
  389. {
  390. unsigned int pos;
  391. unsigned int val;
  392. if ((layer < 0) || (layer > ARK1668E_LCDC_LAYER_MAX))
  393. return -1;
  394. val = readl(lcdc_base + ARK1668E_LCDC_BLD_MODE_LCD_REG1);
  395. switch (layer)
  396. {
  397. case ARK1668E_LCDC_LAYER_VIDEO1:
  398. pos = 10;
  399. break;
  400. case ARK1668E_LCDC_LAYER_VIDEO2:
  401. pos = 8;
  402. break;
  403. case ARK1668E_LCDC_LAYER_OSD1:
  404. pos = 12;
  405. break;
  406. case ARK1668E_LCDC_LAYER_OSD2:
  407. pos = 14;
  408. break;
  409. case ARK1668E_LCDC_LAYER_OSD3:
  410. pos = 16;
  411. break;
  412. default:
  413. return -1;
  414. }
  415. if (enable)
  416. val |= 1<<pos;
  417. else
  418. val &= ~(1 << pos);
  419. writel(val, lcdc_base + ARK1668E_LCDC_BLD_MODE_LCD_REG1);
  420. return 0;
  421. }
  422. static int ark1668e_lcdc_alpha_blend_with_backcolor_enable(int layer, int enable)
  423. {
  424. unsigned int reg;
  425. unsigned int val;
  426. int offset = 0;
  427. switch (layer) {
  428. case ARK1668E_LCDC_LAYER_VIDEO1:
  429. reg = ARK1668E_LCDC_BLD_MODE_LCD_REG1;
  430. offset = 11;
  431. break;
  432. case ARK1668E_LCDC_LAYER_VIDEO2:
  433. reg = ARK1668E_LCDC_BLD_MODE_LCD_REG1;
  434. offset = 9;
  435. break;
  436. case ARK1668E_LCDC_LAYER_OSD1:
  437. reg = ARK1668E_LCDC_BLD_MODE_LCD_REG1;
  438. offset = 13;
  439. break;
  440. case ARK1668E_LCDC_LAYER_OSD2:
  441. reg = ARK1668E_LCDC_BLD_MODE_LCD_REG1;
  442. offset = 15;
  443. break;
  444. case ARK1668E_LCDC_LAYER_OSD3:
  445. reg = ARK1668E_LCDC_BLD_MODE_LCD_REG1;
  446. offset = 17;
  447. break;
  448. default:
  449. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  450. return -1;
  451. }
  452. val = readl(lcdc_base + reg);
  453. if(enable)
  454. val |= (0x1<<offset);
  455. else
  456. val &= ~(0x1<<offset);
  457. writel(val, lcdc_base + reg);
  458. return 0;
  459. }
  460. /**************************************************************************************************
  461. * Video and Osd common interface.
  462. *
  463. **************************************************************************************************/
  464. static int ark1668e_lcdc_set_video_osd_format(int layer, ARK1668E_LCDC_FORMAT format, int yuv_order, int rgb_order)
  465. {
  466. int rgb_ycbcr_bypass;
  467. int yuv_ycbcr_bypass;
  468. int y_uv_order;
  469. int colour_matrix_reg0;
  470. int colour_matrix_reg1;
  471. int colour_matrix_reg2;
  472. int colour_matrix_reg3;
  473. int colour_matrix_reg4;
  474. int colour_matrix_reg5;
  475. unsigned int reg;
  476. unsigned int val;
  477. if((format < 0) || ((format >= ARK1668E_LCDC_FORMAT_MAX) && (format != ARK1668E_LCDC_FORMAT_Y_UV422)&&
  478. (format != ARK1668E_LCDC_FORMAT_Y_UV420))) {
  479. printk(KERN_ERR "%s, Invalid fromat:%d\n", __FUNCTION__, format);
  480. return -1;
  481. }
  482. #if 0
  483. if(format <= ARK1668E_LCDC_FORMAT_OSD_BMP24BIT_VIDEO_YUV420) {
  484. if((layer >= ARK1668E_LCDC_LAYER_VIDEO1) && (layer <= ARK1668E_LCDC_LAYER_VIDEO2)) {
  485. rgb_ycbcr_bypass = 1;
  486. } else {
  487. rgb_ycbcr_bypass = 0;
  488. }
  489. } else if(format <= ARK1668E_LCDC_FORMAT_YUV) {
  490. rgb_ycbcr_bypass = 1;
  491. } else {
  492. rgb_ycbcr_bypass = 0;
  493. }
  494. #else
  495. rgb_ycbcr_bypass = 1;
  496. yuv_ycbcr_bypass = 1;
  497. #endif
  498. switch (layer) {
  499. case ARK1668E_LCDC_LAYER_VIDEO1:
  500. reg = ARK1668E_LCDC_VIDEO1_CTL;
  501. colour_matrix_reg0 = ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG0;
  502. colour_matrix_reg1 = ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG1;
  503. colour_matrix_reg2 = ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG2;
  504. colour_matrix_reg3 = ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG3;
  505. colour_matrix_reg4 = ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG4;
  506. colour_matrix_reg5 = ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG5;
  507. break;
  508. case ARK1668E_LCDC_LAYER_VIDEO2:
  509. reg = ARK1668E_LCDC_VIDEO2_CTL;
  510. colour_matrix_reg0 = ARK1668E_LCDC_VIDEO2_COLOUR_MATRIX_REG0;
  511. colour_matrix_reg1 = ARK1668E_LCDC_VIDEO2_COLOUR_MATRIX_REG1;
  512. colour_matrix_reg2 = ARK1668E_LCDC_VIDEO2_COLOUR_MATRIX_REG2;
  513. colour_matrix_reg3 = ARK1668E_LCDC_VIDEO2_COLOUR_MATRIX_REG3;
  514. colour_matrix_reg4 = ARK1668E_LCDC_VIDEO2_COLOUR_MATRIX_REG4;
  515. colour_matrix_reg5 = ARK1668E_LCDC_VIDEO2_COLOUR_MATRIX_REG5;
  516. break;
  517. case ARK1668E_LCDC_LAYER_OSD1:
  518. reg = ARK1668E_LCDC_OSD1_CTL;
  519. colour_matrix_reg0 = ARK1668E_LCDC_OSD1_COLOUR_MATRIX_REG0;
  520. colour_matrix_reg1 = ARK1668E_LCDC_OSD1_COLOUR_MATRIX_REG1;
  521. colour_matrix_reg2 = ARK1668E_LCDC_OSD1_COLOUR_MATRIX_REG2;
  522. colour_matrix_reg3 = ARK1668E_LCDC_OSD1_COLOUR_MATRIX_REG3;
  523. colour_matrix_reg4 = ARK1668E_LCDC_OSD1_COLOUR_MATRIX_REG4;
  524. colour_matrix_reg5 = ARK1668E_LCDC_OSD1_COLOUR_MATRIX_REG5;
  525. break;
  526. case ARK1668E_LCDC_LAYER_OSD2:
  527. reg = ARK1668E_LCDC_OSD2_CTL;
  528. colour_matrix_reg0 = ARK1668E_LCDC_OSD2_COLOUR_MATRIX_REG0;
  529. colour_matrix_reg1 = ARK1668E_LCDC_OSD2_COLOUR_MATRIX_REG1;
  530. colour_matrix_reg2 = ARK1668E_LCDC_OSD2_COLOUR_MATRIX_REG2;
  531. colour_matrix_reg3 = ARK1668E_LCDC_OSD2_COLOUR_MATRIX_REG3;
  532. colour_matrix_reg4 = ARK1668E_LCDC_OSD2_COLOUR_MATRIX_REG4;
  533. colour_matrix_reg5 = ARK1668E_LCDC_OSD2_COLOUR_MATRIX_REG5;
  534. break;
  535. case ARK1668E_LCDC_LAYER_OSD3:
  536. reg = ARK1668E_LCDC_OSD3_CTL;
  537. colour_matrix_reg0 = ARK1668E_LCDC_OSD3_COLOUR_MATRIX_REG0;
  538. colour_matrix_reg1 = ARK1668E_LCDC_OSD3_COLOUR_MATRIX_REG1;
  539. colour_matrix_reg2 = ARK1668E_LCDC_OSD3_COLOUR_MATRIX_REG2;
  540. colour_matrix_reg3 = ARK1668E_LCDC_OSD3_COLOUR_MATRIX_REG3;
  541. colour_matrix_reg4 = ARK1668E_LCDC_OSD3_COLOUR_MATRIX_REG4;
  542. colour_matrix_reg5 = ARK1668E_LCDC_OSD3_COLOUR_MATRIX_REG5;
  543. break;
  544. default:
  545. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  546. return -1;
  547. }
  548. if((format >= ARK1668E_LCDC_FORMAT_RGBI555) && (format < ARK1668E_LCDC_FORMAT_MAX)) {
  549. writel(0, lcdc_base + colour_matrix_reg0);
  550. writel(0, lcdc_base + colour_matrix_reg1);
  551. writel(0, lcdc_base + colour_matrix_reg2);
  552. writel(0, lcdc_base + colour_matrix_reg3);
  553. writel(0, lcdc_base + colour_matrix_reg4);
  554. writel(0, lcdc_base + colour_matrix_reg5);
  555. } else {
  556. writel(0x01000100, lcdc_base + colour_matrix_reg0);
  557. writel(0x100167, lcdc_base + colour_matrix_reg1);
  558. writel(0xf4afa8, lcdc_base + colour_matrix_reg2);
  559. writel(0x12d100, lcdc_base + colour_matrix_reg3);
  560. writel(0xf4d000, lcdc_base + colour_matrix_reg4);
  561. writel(0xf69086, lcdc_base + colour_matrix_reg5);
  562. }
  563. val = readl(lcdc_base + reg);
  564. if((layer >= ARK1668E_LCDC_LAYER_VIDEO1) && (layer <= ARK1668E_LCDC_LAYER_VIDEO2)) {
  565. int scal_bypass_sel = 1; //1:bypass; 0:if scale based on input/ouput size.
  566. int scal_bypass_mode = 1; //1:disable scale; 0:enable, ignore scal_bypass_sel.
  567. if(format == ARK1668E_LCDC_FORMAT_Y_UV420) {
  568. y_uv_order = 1; //0:y_u_v order, 1:y_uv order.
  569. format = ARK1668E_LCDC_FORMAT_OSD_BMP24BIT_VIDEO_YUV420;
  570. } else if(format == ARK1668E_LCDC_FORMAT_Y_UV422) {
  571. y_uv_order = 1;
  572. format = ARK1668E_LCDC_FORMAT_OSD_PALETTE_VIDEO_YUV422;
  573. } else {
  574. y_uv_order = 0;
  575. }
  576. val &= ~((1<<21) | (3<<17) | (1<<9) | (1<<8) | (7<<14) | (1<<5) | (1<<4) | (0xF<<0));
  577. val |= ((y_uv_order<<21) | (yuv_order<<17) | (rgb_order<<14) | (scal_bypass_sel<<9) | (scal_bypass_mode<<8) | (yuv_ycbcr_bypass<<5) | (rgb_ycbcr_bypass<<4) | (format<<0));
  578. } else {
  579. val &= ~((3<<21) | (7<<18) | (1<<17) | (1<<16) | (0xF<<12));
  580. val |= ((yuv_order<<21) | (rgb_order<<18) | (yuv_ycbcr_bypass<<17) | (rgb_ycbcr_bypass<<16) | (format<<12));
  581. }
  582. writel(val, lcdc_base + reg);
  583. //printk(KERN_ALERT "%s, layer:%d, reg:0x%x, val:0x%x, format:0x%x\n", __FUNCTION__, layer, reg, val, format);
  584. return 0;
  585. }
  586. static int ark1668e_lcdc_get_video_osd_format(int layer)
  587. {
  588. unsigned int reg;
  589. unsigned int val;
  590. int format;
  591. switch (layer) {
  592. case ARK1668E_LCDC_LAYER_VIDEO1:
  593. reg = ARK1668E_LCDC_VIDEO1_CTL;
  594. break;
  595. case ARK1668E_LCDC_LAYER_VIDEO2:
  596. reg = ARK1668E_LCDC_VIDEO2_CTL;
  597. break;
  598. case ARK1668E_LCDC_LAYER_OSD1:
  599. reg = ARK1668E_LCDC_OSD1_CTL;
  600. break;
  601. case ARK1668E_LCDC_LAYER_OSD2:
  602. reg = ARK1668E_LCDC_OSD2_CTL;
  603. break;
  604. case ARK1668E_LCDC_LAYER_OSD3:
  605. reg = ARK1668E_LCDC_OSD3_CTL;
  606. break;
  607. default:
  608. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  609. return -1;
  610. }
  611. val = readl(lcdc_base + reg);
  612. if((layer >= ARK1668E_LCDC_LAYER_VIDEO1) && (layer <= ARK1668E_LCDC_LAYER_VIDEO2)) {
  613. int y_uv_order = (val>>21) & 0x1;;
  614. format = val & 0xF;
  615. if(y_uv_order) {
  616. if(format == ARK1668E_LCDC_FORMAT_OSD_BMP24BIT_VIDEO_YUV420)
  617. format = ARK1668E_LCDC_FORMAT_Y_UV420;
  618. else if(format == ARK1668E_LCDC_FORMAT_OSD_PALETTE_VIDEO_YUV422)
  619. format = ARK1668E_LCDC_FORMAT_Y_UV422;
  620. }
  621. } else {
  622. format = (val>>12)&0xF;
  623. }
  624. return format;
  625. }
  626. static int ark1668e_lcdc_set_video_osd_source_size(int layer, int width, int height)
  627. {
  628. unsigned int val;
  629. int reg;
  630. switch (layer) {
  631. case ARK1668E_LCDC_LAYER_VIDEO1:
  632. reg = ARK1668E_LCDC_VIDEO1_SOURCE_SIZE;
  633. break;
  634. case ARK1668E_LCDC_LAYER_VIDEO2:
  635. reg = ARK1668E_LCDC_VIDEO2_SOURCE_SIZE;
  636. break;
  637. case ARK1668E_LCDC_LAYER_OSD1:
  638. reg = ARK1668E_LCDC_OSD1_SOURCE_SIZE;
  639. break;
  640. case ARK1668E_LCDC_LAYER_OSD2:
  641. reg = ARK1668E_LCDC_OSD2_SOURCE_SIZE;
  642. break;
  643. case ARK1668E_LCDC_LAYER_OSD3:
  644. reg = ARK1668E_LCDC_OSD3_SOURCE_SIZE;
  645. break;
  646. default:
  647. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  648. return -1;
  649. }
  650. val = ((height&0xFFF) << 12) | (width&0xFFF);
  651. writel(val, lcdc_base + reg);
  652. return 0;
  653. }
  654. static int ark1668e_lcdc_set_video_osd_size(int layer, int width, int height)
  655. {
  656. unsigned int val;
  657. int reg;
  658. switch (layer) {
  659. case ARK1668E_LCDC_LAYER_VIDEO1:
  660. reg = ARK1668E_LCDC_VIDEO1_SIZE;
  661. break;
  662. case ARK1668E_LCDC_LAYER_VIDEO2:
  663. reg = ARK1668E_LCDC_VIDEO2_SIZE;
  664. break;
  665. case ARK1668E_LCDC_LAYER_OSD1:
  666. reg = ARK1668E_LCDC_OSD1_SIZE;
  667. break;
  668. case ARK1668E_LCDC_LAYER_OSD2:
  669. reg = ARK1668E_LCDC_OSD2_SIZE;
  670. break;
  671. case ARK1668E_LCDC_LAYER_OSD3:
  672. reg = ARK1668E_LCDC_OSD3_SIZE;
  673. break;
  674. default:
  675. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  676. return -1;
  677. }
  678. val = ((height&0xFFF) << 12) | (width&0xFFF);
  679. writel(val, lcdc_base + reg);
  680. return 0;
  681. }
  682. static int ark1668e_lcdc_set_video_osd_win_point(int layer, int x, int y)
  683. {
  684. unsigned int val;
  685. int reg;
  686. switch (layer) {
  687. case ARK1668E_LCDC_LAYER_VIDEO1:
  688. reg = ARK1668E_LCDC_VIDEO1_WIN_POINT;
  689. break;
  690. case ARK1668E_LCDC_LAYER_VIDEO2:
  691. reg = ARK1668E_LCDC_VIDEO2_WIN_POINT;
  692. break;
  693. case ARK1668E_LCDC_LAYER_OSD1:
  694. reg = ARK1668E_LCDC_OSD1_WIN_POINT;
  695. break;
  696. case ARK1668E_LCDC_LAYER_OSD2:
  697. reg = ARK1668E_LCDC_OSD2_WIN_POINT;
  698. break;
  699. case ARK1668E_LCDC_LAYER_OSD3:
  700. reg = ARK1668E_LCDC_OSD3_WIN_POINT;
  701. break;
  702. default:
  703. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  704. return -1;
  705. }
  706. val = ((y&0xFFF) << 12) | (x&0xFFF);
  707. writel(val, lcdc_base + reg);
  708. return 0;
  709. }
  710. static int ark1668e_lcdc_set_video_osd_layer_point(int layer, int x, int y)
  711. {
  712. unsigned int val;
  713. int reg;
  714. int sign_x = 0;
  715. int sign_y = 0;
  716. if (x < 0) {
  717. sign_x = 1;
  718. x = -x;
  719. }
  720. if (y < 0) {
  721. sign_y = 1;
  722. y = -y;
  723. }
  724. switch (layer) {
  725. case ARK1668E_LCDC_LAYER_VIDEO1:
  726. reg = ARK1668E_LCDC_VIDEO1_POSITION;
  727. break;
  728. case ARK1668E_LCDC_LAYER_VIDEO2:
  729. reg = ARK1668E_LCDC_VIDEO2_POSITION;
  730. break;
  731. case ARK1668E_LCDC_LAYER_OSD1:
  732. reg = ARK1668E_LCDC_OSD1_POSITION;
  733. break;
  734. case ARK1668E_LCDC_LAYER_OSD2:
  735. reg = ARK1668E_LCDC_OSD2_POSITION;
  736. break;
  737. case ARK1668E_LCDC_LAYER_OSD3:
  738. reg = ARK1668E_LCDC_OSD3_POSITION;
  739. break;
  740. default:
  741. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  742. return -1;
  743. }
  744. val = (sign_y << 25) | ((y&0xFFF) << 13) | (sign_x << 12) | (x&0xFFF);
  745. writel(val, lcdc_base + reg);
  746. return 0;
  747. }
  748. static int ark1668e_lcdc_set_video_osd_color_matrix(int layer, int reg0_val, int reg1_val, int reg2_val, int reg3_val, int reg4_val, int reg5_val)
  749. {
  750. unsigned int reg0, reg1, reg2, reg3, reg4, reg5;
  751. switch (layer) {
  752. case ARK1668E_LCDC_LAYER_VIDEO1:
  753. reg0 = ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG0;
  754. reg1 = ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG1;
  755. reg2 = ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG2;
  756. reg3 = ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG3;
  757. reg4 = ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG4;
  758. reg5 = ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG5;
  759. break;
  760. case ARK1668E_LCDC_LAYER_VIDEO2:
  761. reg0 = ARK1668E_LCDC_VIDEO2_COLOUR_MATRIX_REG0;
  762. reg1 = ARK1668E_LCDC_VIDEO2_COLOUR_MATRIX_REG1;
  763. reg2 = ARK1668E_LCDC_VIDEO2_COLOUR_MATRIX_REG2;
  764. reg3 = ARK1668E_LCDC_VIDEO2_COLOUR_MATRIX_REG3;
  765. reg4 = ARK1668E_LCDC_VIDEO2_COLOUR_MATRIX_REG4;
  766. reg5 = ARK1668E_LCDC_VIDEO2_COLOUR_MATRIX_REG5;
  767. break;
  768. case ARK1668E_LCDC_LAYER_OSD1:
  769. reg0 = ARK1668E_LCDC_OSD1_COLOUR_MATRIX_REG0;
  770. reg1 = ARK1668E_LCDC_OSD1_COLOUR_MATRIX_REG1;
  771. reg2 = ARK1668E_LCDC_OSD1_COLOUR_MATRIX_REG2;
  772. reg3 = ARK1668E_LCDC_OSD1_COLOUR_MATRIX_REG3;
  773. reg4 = ARK1668E_LCDC_OSD1_COLOUR_MATRIX_REG4;
  774. reg5 = ARK1668E_LCDC_OSD1_COLOUR_MATRIX_REG5;
  775. break;
  776. case ARK1668E_LCDC_LAYER_OSD2:
  777. reg0 = ARK1668E_LCDC_OSD2_COLOUR_MATRIX_REG0;
  778. reg1 = ARK1668E_LCDC_OSD2_COLOUR_MATRIX_REG1;
  779. reg2 = ARK1668E_LCDC_OSD2_COLOUR_MATRIX_REG2;
  780. reg3 = ARK1668E_LCDC_OSD2_COLOUR_MATRIX_REG3;
  781. reg4 = ARK1668E_LCDC_OSD2_COLOUR_MATRIX_REG4;
  782. reg5 = ARK1668E_LCDC_OSD2_COLOUR_MATRIX_REG5;
  783. break;
  784. case ARK1668E_LCDC_LAYER_OSD3:
  785. reg0 = ARK1668E_LCDC_OSD3_COLOUR_MATRIX_REG0;
  786. reg1 = ARK1668E_LCDC_OSD3_COLOUR_MATRIX_REG1;
  787. reg2 = ARK1668E_LCDC_OSD3_COLOUR_MATRIX_REG2;
  788. reg3 = ARK1668E_LCDC_OSD3_COLOUR_MATRIX_REG3;
  789. reg4 = ARK1668E_LCDC_OSD3_COLOUR_MATRIX_REG4;
  790. reg5 = ARK1668E_LCDC_OSD3_COLOUR_MATRIX_REG5;
  791. break;
  792. default:
  793. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  794. return -1;
  795. }
  796. writel(reg0_val, lcdc_base + reg0);
  797. writel(reg1_val, lcdc_base + reg1);
  798. writel(reg2_val, lcdc_base + reg2);
  799. writel(reg3_val, lcdc_base + reg3);
  800. writel(reg4_val, lcdc_base + reg4);
  801. writel(reg5_val, lcdc_base + reg5);
  802. return 0;
  803. }
  804. /**************************************************************************************************
  805. * Video interface.
  806. *
  807. **************************************************************************************************/
  808. static int ark1668e_lcdc_set_video_win_size(int layer, int width, int height)
  809. {
  810. unsigned int val;
  811. int reg;
  812. switch (layer) {
  813. case ARK1668E_LCDC_LAYER_VIDEO1:
  814. reg = ARK1668E_LCDC_VIDEO1_WIN_SIZE;
  815. break;
  816. case ARK1668E_LCDC_LAYER_VIDEO2:
  817. reg = ARK1668E_LCDC_VIDEO2_WIN_SIZE;
  818. break;
  819. default:
  820. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  821. return -1;
  822. }
  823. val = ((height & 0xFFF) << 12) | (width & 0xFFF);
  824. writel(val, lcdc_base + reg);
  825. return 0;
  826. }
  827. int ark1668e_lcdc_set_video_addr(int layer, unsigned int yaddr,unsigned int cbaddr, unsigned int craddr)
  828. {
  829. unsigned int reg_addr1, reg_addr2, reg_addr3;
  830. switch (layer) {
  831. case ARK1668E_LCDC_LAYER_VIDEO1:
  832. reg_addr1 = ARK1668E_LCDC_VIDEO1_ADDR1;
  833. reg_addr2 = ARK1668E_LCDC_VIDEO1_ADDR2;
  834. reg_addr3 = ARK1668E_LCDC_VIDEO1_ADDR3;
  835. break;
  836. case ARK1668E_LCDC_LAYER_VIDEO2:
  837. reg_addr1 = ARK1668E_LCDC_VIDEO2_ADDR1;
  838. reg_addr2 = ARK1668E_LCDC_VIDEO2_ADDR2;
  839. reg_addr3 = ARK1668E_LCDC_VIDEO2_ADDR3;
  840. break;
  841. default:
  842. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  843. return -1;
  844. }
  845. writel(yaddr, lcdc_base + reg_addr1);
  846. if(cbaddr)
  847. writel(cbaddr, lcdc_base + reg_addr2);
  848. if(craddr)
  849. writel(craddr, lcdc_base + reg_addr3);
  850. return 0;
  851. }
  852. static int ark1668e_lcdc_get_video_addr(int layer, unsigned int *yaddr,unsigned int *cbaddr, unsigned int *craddr)
  853. {
  854. unsigned int reg_addr1, reg_addr2, reg_addr3;
  855. switch (layer) {
  856. case ARK1668E_LCDC_LAYER_VIDEO1:
  857. reg_addr1 = ARK1668E_LCDC_VIDEO1_ADDR1;
  858. reg_addr2 = ARK1668E_LCDC_VIDEO1_ADDR2;
  859. reg_addr3 = ARK1668E_LCDC_VIDEO1_ADDR3;
  860. break;
  861. case ARK1668E_LCDC_LAYER_VIDEO2:
  862. reg_addr1 = ARK1668E_LCDC_VIDEO2_ADDR1;
  863. reg_addr2 = ARK1668E_LCDC_VIDEO2_ADDR2;
  864. reg_addr3 = ARK1668E_LCDC_VIDEO2_ADDR3;
  865. break;
  866. default:
  867. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  868. return -1;
  869. }
  870. *yaddr = readl(lcdc_base + reg_addr1);
  871. *cbaddr = readl(lcdc_base + reg_addr2);
  872. *craddr = readl(lcdc_base + reg_addr3);
  873. return 0;
  874. }
  875. static int ark1668e_lcdc_set_video1_scal(
  876. int layer,
  877. unsigned int win_width, unsigned int win_height,
  878. unsigned int left_blank, unsigned int right_blank,
  879. unsigned int top_blank, unsigned int bottom_blank,
  880. unsigned int dst_width, unsigned int dst_height,
  881. int interlace_out_en // 1=interlace, 0=progressive
  882. )
  883. {
  884. unsigned int vblank = top_blank + bottom_blank;
  885. unsigned int hblank = left_blank + right_blank;
  886. unsigned int reg_ctl, reg_ctl0, reg_ctl1, reg_cut;
  887. unsigned int val;
  888. unsigned int format;
  889. if (layer != ARK1668E_LCDC_LAYER_VIDEO1) {
  890. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  891. return -EINVAL;
  892. }
  893. if (dst_width == 0 || dst_height == 0) {
  894. printk(KERN_ERR "%s, Invalid dst_width:%d, dst_height:%d\n", __FUNCTION__, dst_width, dst_height);
  895. return -EINVAL;;
  896. }
  897. val = readl(lcdc_base + ARK1668E_LCDC_VIDEO1_CTL);
  898. format = (val & 0xF);
  899. if(format == ARK1668E_LCDC_FORMAT_OSD_BMP24BIT_VIDEO_YUV420) {
  900. int src_width = (readl(lcdc_base + ARK1668E_LCDC_VIDEO1_SOURCE_SIZE) & 0xFFF);
  901. if(src_width&7) {
  902. printk(KERN_ERR "Video layer scaler didn't support the width which is not the multiple of 8 when the format is YUV420.\n");
  903. return -EINVAL;
  904. }
  905. }
  906. if(((val >> 8) & 0x3) != 1) {
  907. val &= ~(1<<9); //scale bypass select(1:not bypass).
  908. val |= (1<<8); //1: enable scale when scale is not bypass and disable scale when scale bypass; 0: enable scale no matter if scale is bypass.
  909. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_CTL);
  910. }
  911. reg_ctl = ARK1668E_LCDC_VIDEO1_SCALE_CTL;
  912. reg_ctl0 = ARK1668E_LCDC_VIDEO1_SCAL_CTL0;
  913. reg_ctl1 = ARK1668E_LCDC_VIDEO1_SCAL_CTL1;
  914. reg_cut = ARK1668E_LCDC_VIDEO1_RIGHT_BOTTOM_CUT_NUM;
  915. val = 0<<11| // 0=addr update per field
  916. 0<<9 | // 10-9: 00=
  917. 0<<8 | // 0=not line chroma
  918. 1<<7 | // 1=YUV
  919. 0<<6 | // 0=disable horizontal filter (use for down scale)
  920. 1<<5 | // 1=auto set coef of h-filter when down scale
  921. 0<<4 | // 0=normal scale de-interlace mode
  922. 0<<3 | // 0=current field is field=0
  923. 0<<2 | // 0=field=0 is odd, field=1 is even
  924. 0<<1 | // 0=de-interlace disable
  925. 0<<0; // 0=use 2 line buffers
  926. if ((dst_width + hblank) < win_width)
  927. val |= 1<<6;
  928. writel(val, lcdc_base + reg_ctl);
  929. val = (right_blank<<8) | bottom_blank;
  930. writel(val, lcdc_base + reg_cut);
  931. val = (left_blank<<18) |(win_width * 1024 / (dst_width + hblank));
  932. writel(val, lcdc_base + reg_ctl0);
  933. val = (top_blank<<18) | (win_height * 1024 / (dst_height + vblank));
  934. writel(val, lcdc_base + reg_ctl1);
  935. if (interlace_out_en) {
  936. val = readl(lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  937. val &= ~(1<<8);
  938. writel(val, lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  939. /* when v scaler cof is 0x400,v scaler bypass, now we should change the cof to
  940. force v scaler, otherwise there was sawtooth on picture */
  941. val = readl(lcdc_base + reg_ctl1);
  942. if ((val & 0x3FFFF) == 0x400) {
  943. val -= 1;
  944. writel(val, lcdc_base + reg_ctl1);
  945. }
  946. val = readl(lcdc_base + reg_ctl);
  947. val &= ~(7<<9);
  948. val |= (1<<11) | (1<<9);
  949. writel(val, lcdc_base + reg_ctl);
  950. }
  951. return 0;
  952. }
  953. /**************************************************************************************************
  954. * Osd interface.
  955. *
  956. **************************************************************************************************/
  957. int ark1668e_lcdc_set_osd_addr(int layer, int addr)
  958. {
  959. unsigned int reg;
  960. switch (layer) {
  961. case ARK1668E_LCDC_LAYER_OSD1:
  962. reg = ARK1668E_LCDC_OSD1_ADDR;
  963. break;
  964. case ARK1668E_LCDC_LAYER_OSD2:
  965. reg = ARK1668E_LCDC_OSD2_ADDR;
  966. break;
  967. case ARK1668E_LCDC_LAYER_OSD3:
  968. reg = ARK1668E_LCDC_OSD3_ADDR;
  969. break;
  970. default:
  971. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  972. return -1;
  973. }
  974. writel(addr, lcdc_base + reg);
  975. return 0;
  976. }
  977. static int ark1668e_lcdc_get_osd_addr(int layer)
  978. {
  979. unsigned int reg;
  980. switch (layer) {
  981. case ARK1668E_LCDC_LAYER_OSD1:
  982. reg = ARK1668E_LCDC_OSD1_ADDR;
  983. break;
  984. case ARK1668E_LCDC_LAYER_OSD2:
  985. reg = ARK1668E_LCDC_OSD2_ADDR;
  986. break;
  987. case ARK1668E_LCDC_LAYER_OSD3:
  988. reg = ARK1668E_LCDC_OSD3_ADDR;
  989. break;
  990. default:
  991. printk(KERN_ERR "%s, Invalid layer:%d\n", __FUNCTION__, layer);
  992. return -1;
  993. }
  994. return readl(lcdc_base + reg);
  995. }
  996. /**************************************************************************************************
  997. * Ioctl interface.
  998. *
  999. **************************************************************************************************/
  1000. static void ark1668e_lcdc_display_update_atomic(struct ark1668e_lcdfb_info* sinfo)
  1001. {
  1002. unsigned int format, yuv_order, rgb_order, i, layer;
  1003. struct ark_disp_atomic *p = NULL;
  1004. if(!sinfo->atomic_flag)
  1005. return;
  1006. for(i = 0; i < ARK1668E_LCDC_LAYER_MAX; i++) {
  1007. if(!(sinfo->atomic_flag & (1 << i)))
  1008. continue;
  1009. p = &sinfo->patomic[i];
  1010. if(!p->atomic_stat || (p->layer < 0) || (p->layer) > ARK1668E_LCDC_LAYER_MAX){
  1011. sinfo->atomic_flag &= ~(1 << i);
  1012. memset(&sinfo->patomic[i], 0 ,sizeof(struct ark_disp_atomic));
  1013. continue;
  1014. }
  1015. //printk(KERN_ALERT "%s: atomic_stat=0x%0x, layer=%d.\n ",__func__, p->atomic_stat, p->layer);
  1016. layer = p->layer;
  1017. if(p->layer >= ARK1668E_LCDC_LAYER_OSD1 && p->layer <= ARK1668E_LCDC_LAYER_OSD3){
  1018. if(p->atomic_stat & ATOMIC_SET_LAYER_POS) {
  1019. ark1668e_lcdc_set_video_osd_layer_point(layer, p->pos_x, p->pos_y);
  1020. }
  1021. if(p->atomic_stat & ATOMIC_SET_LAYER_SIZE) {
  1022. ark1668e_lcdc_set_video_osd_size(layer, p->width, p->height);
  1023. ark1668e_lcdc_set_video_osd_source_size(layer, p->width, p->height);
  1024. }
  1025. if(p->atomic_stat & ATOMIC_SET_LAYER_FMT) {
  1026. format = (p->format >> 0) & 0xFF;
  1027. yuv_order = (p->format >> 16) & 0xF;
  1028. rgb_order = (p->format >> 24) & 0xF;
  1029. ark1668e_lcdc_set_video_osd_format(layer, format, yuv_order, rgb_order);
  1030. if(format == ARK1668E_LCDC_FORMAT_RGBA888){
  1031. ark1668e_lcdc_alpha_blend_with_backcolor_enable(layer, 1);
  1032. ark1668e_lcdc_alpha_blend_per_pix_mode_enable(layer, 1);
  1033. }
  1034. //printk(KERN_ALERT "%s: format=%d, yuv_order=%d, rgb_order=%d.\n ",__func__, format, yuv_order,rgb_order);
  1035. }
  1036. if(p->atomic_stat & ATOMIC_SET_LAYER_ADDR)
  1037. ark1668e_lcdc_set_osd_addr(layer, p->addr.yaddr);
  1038. }else{
  1039. if(p->atomic_stat & ATOMIC_SET_LAYER_POS) {
  1040. ark1668e_lcdc_set_video_osd_layer_point(layer, p->pos_x, p->pos_y);
  1041. }
  1042. if(p->atomic_stat & ATOMIC_SET_LAYER_SIZE) {
  1043. ark1668e_lcdc_set_video_osd_source_size(layer, p->width, p->height);
  1044. ark1668e_lcdc_set_video_win_size(layer, p->width, p->height);
  1045. ark1668e_lcdc_set_video_osd_win_point(layer, 0, 0);
  1046. ark1668e_lcdc_set_video_osd_size(layer, p->width, p->height);
  1047. //if(!(p->atomic_stat & ATOMIC_SET_LAYER_SCALER)) {
  1048. // if(layer == ARK1668E_LCDC_LAYER_VIDEO1) {
  1049. // ark1668e_lcdc_set_video1_scal(layer, p->width, p->height,
  1050. // 0, 0, 0, 0, p->width, p->height, 0);
  1051. // }
  1052. //}
  1053. }
  1054. if(p->atomic_stat & ATOMIC_SET_LAYER_FMT){
  1055. format = (p->format >> 0) & 0xFF;
  1056. yuv_order = (p->format >> 16) & 0xF;
  1057. rgb_order = (p->format >> 24) & 0xF;
  1058. ark1668e_lcdc_set_video_osd_format(layer, format, yuv_order, rgb_order);
  1059. }
  1060. if(p->atomic_stat & ATOMIC_SET_LAYER_ADDR)
  1061. ark1668e_lcdc_set_video_addr(layer, p->addr.yaddr, p->addr.cbaddr, p->addr.craddr);
  1062. if(p->atomic_stat & ATOMIC_SET_LAYER_SCALER) {
  1063. if(layer == ARK1668E_LCDC_LAYER_VIDEO1) {
  1064. ark1668e_lcdc_set_video1_scal(layer, p->scaler.src_w, p->scaler.src_h,
  1065. p->scaler.cut_left, p->scaler.cut_right, p->scaler.cut_top, p->scaler.cut_bottom,
  1066. p->scaler.out_w, p->scaler.out_h, 0);
  1067. }
  1068. }
  1069. }
  1070. sinfo->atomic_flag &= ~(1 << i);
  1071. memset(&sinfo->patomic[i], 0 ,sizeof(struct ark_disp_atomic));
  1072. }
  1073. }
  1074. int ark1668e_lcdc_wait_for_vsync(void)
  1075. {
  1076. struct ark1668e_lcdfb_info *sinfo = lcdfb_info;
  1077. int ret;
  1078. if(!sinfo)
  1079. return -EINVAL;
  1080. sinfo->vsync_flag = 0;
  1081. ret = wait_event_interruptible_timeout(sinfo->vsync_waitq,
  1082. sinfo->vsync_flag != 0,
  1083. msecs_to_jiffies(100)); // 100ms at most
  1084. if (ret < 0)
  1085. return ret;
  1086. if (ret == 0)
  1087. return -ETIMEDOUT;
  1088. if(sinfo->atomic_flag)
  1089. ark1668e_lcdc_display_update_atomic(sinfo);
  1090. return 0;
  1091. }
  1092. EXPORT_SYMBOL(ark1668e_lcdc_wait_for_vsync);
  1093. int ark_vin_get_screen_info(int* width,int* height)
  1094. {
  1095. if(lcdc_base == NULL){
  1096. return -1;
  1097. }
  1098. *width = lcdc_width;
  1099. *height = lcdc_height;
  1100. return 0;
  1101. }
  1102. EXPORT_SYMBOL(ark_vin_get_screen_info);
  1103. int ark_vin_display_init(int layer,int src_width, int src_height,int out_posx, int out_posy)
  1104. {
  1105. if(lcdc_base == NULL)
  1106. return -1;
  1107. ark1668e_lcdc_set_video_osd_source_size(layer, src_width, src_height);
  1108. ark1668e_lcdc_set_video_win_size(layer, src_width, src_height);
  1109. ark1668e_lcdc_set_video_osd_layer_point(layer, out_posx, out_posy);
  1110. ark1668e_lcdc_set_video_osd_win_point(layer, 0, 0);
  1111. ark1668e_lcdc_set_video_osd_size(layer, src_width, src_height);
  1112. ark1668e_lcdc_set_video_osd_format(layer,ARK1668E_LCDC_FORMAT_Y_UV420,ARK_LCDC_ORDER_VYUY,0);
  1113. return 0;
  1114. }
  1115. EXPORT_SYMBOL(ark_vin_display_init);
  1116. int ark_vin_display_addr(unsigned int yaddr, unsigned int uaddr, unsigned int vaddr)
  1117. {
  1118. if(lcdc_base == NULL || yaddr == 0){
  1119. return -1;
  1120. }
  1121. //ark1668e_lcdc_set_video_addr(ARK1668E_LCDC_LAYER_VIDEO2, addr, 0, 0);
  1122. lcdfb_info->render_addr[ARK1668E_LCDC_LAYER_VIDEO2].yaddr = yaddr;
  1123. lcdfb_info->render_addr[ARK1668E_LCDC_LAYER_VIDEO2].cbaddr = uaddr;
  1124. lcdfb_info->render_addr[ARK1668E_LCDC_LAYER_VIDEO2].craddr = vaddr;
  1125. return 0;
  1126. }
  1127. EXPORT_SYMBOL(ark_vin_display_addr);
  1128. int ark_vin_get_display_addr(void)
  1129. {
  1130. int yaddr,uaddr,vaddr;
  1131. if(lcdc_base == NULL){
  1132. return -1;
  1133. }
  1134. ark1668e_lcdc_get_video_addr(ARK1668E_LCDC_LAYER_VIDEO2, &yaddr,&uaddr,&vaddr);
  1135. return yaddr;
  1136. }
  1137. EXPORT_SYMBOL(ark_vin_get_display_addr);
  1138. int ark_bootanimation_display_init(int width, int height, unsigned int Yaddr,unsigned int Uaddr,unsigned int Vaddr,unsigned int format)
  1139. {
  1140. // ark1668_lcdc_set_osd_size(OSD_LAYER2, width, height);
  1141. // ark1668_lcdc_set_osd_pos(OSD_LAYER2, (lcdc_width - width) / 2, (lcdc_height - height) / 2);
  1142. // ark1668_lcdc_set_osd_format(OSD_LAYER2, ARK1668_LCDC_FORMAT_VYUY, ARK_LCDC_ORDER_UYVY, 0);
  1143. // ark1668_lcdc_set_osd_addr(OSD_LAYER2, addr);
  1144. // ark1668_lcdc_set_osd_en(OSD_LAYER2, 1);
  1145. if(lcdc_base == NULL)
  1146. return -1;
  1147. ark1668e_lcdc_set_video_osd_source_size(ARK1668E_LCDC_LAYER_VIDEO1, width, height);
  1148. ark1668e_lcdc_set_video_win_size(ARK1668E_LCDC_LAYER_VIDEO1, width, height);
  1149. ark1668e_lcdc_set_video_osd_layer_point(ARK1668E_LCDC_LAYER_VIDEO1, 0, 0);
  1150. ark1668e_lcdc_set_video_osd_win_point(ARK1668E_LCDC_LAYER_VIDEO1, 0, 0);
  1151. ark1668e_lcdc_set_video_osd_size(ARK1668E_LCDC_LAYER_VIDEO1, width, height);
  1152. ark1668e_lcdc_set_video_osd_format(ARK1668E_LCDC_LAYER_VIDEO1,/*ARK1668E_LCDC_FORMAT_Y_UV420*/format,ARK_LCDC_ORDER_VYUY,0);
  1153. ark1668e_lcdc_set_video_addr(ARK1668E_LCDC_LAYER_VIDEO1, Yaddr, Uaddr,Vaddr);
  1154. ark1668e_lcdc_layer_enable(ARK1668E_LCDC_LAYER_VIDEO1, 1);
  1155. return 0;
  1156. }
  1157. EXPORT_SYMBOL(ark_bootanimation_display_init);
  1158. int ark_bootanimation_display_uninit(void)
  1159. {
  1160. ark1668e_lcdc_layer_enable(ARK1668E_LCDC_LAYER_VIDEO1, 0);
  1161. return 0;
  1162. }
  1163. EXPORT_SYMBOL(ark_bootanimation_display_uninit);
  1164. int ark_bootanimation_set_display_addr(unsigned int Yaddr,unsigned int Uaddr,unsigned int Vaddr,unsigned int format)
  1165. {
  1166. ark1668e_lcdc_set_video_addr(ARK1668E_LCDC_LAYER_VIDEO1, Yaddr, Uaddr, Vaddr);
  1167. // ark1668e_lcdc_wait_for_vsync();
  1168. return 0;
  1169. }
  1170. EXPORT_SYMBOL(ark_bootanimation_set_display_addr);
  1171. static int ark1668e_lcdc_convert_layer(int layer)
  1172. {
  1173. switch(layer) {
  1174. case 0: //fb0 for UI.
  1175. layer = ARK1668E_LCDC_LAYER_OSD2;
  1176. break;
  1177. case 1: //fb1 for video/carback/phonelink
  1178. layer = ARK1668E_LCDC_LAYER_VIDEO2;
  1179. break;
  1180. case 2: //overlay for UI(carback track/radar)
  1181. layer = ARK1668E_LCDC_LAYER_OSD1;
  1182. break;
  1183. case 3: //tvout
  1184. layer = ARK1668E_LCDC_LAYER_VIDEO1;
  1185. break;
  1186. case 4: //aux for(itu601/itu656). Here is reserved.
  1187. layer = ARK1668E_LCDC_LAYER_OSD3;
  1188. break;
  1189. default:
  1190. layer = -1;
  1191. break;
  1192. }
  1193. return layer;
  1194. }
  1195. int ark_disp_set_layer_en(int layer_id, int enable)
  1196. {
  1197. if(lcdc_base == NULL){
  1198. return -1;
  1199. }
  1200. if(layer_id > 4 || layer_id < 0){
  1201. return -1;
  1202. }
  1203. ark1668e_lcdc_layer_enable(layer_id, enable);
  1204. return 0;
  1205. }
  1206. EXPORT_SYMBOL(ark_disp_set_layer_en);
  1207. /*******************************************************************************/
  1208. int ark_track_display_init(int width,int height)
  1209. {
  1210. if(lcdc_base == NULL)
  1211. return -1;
  1212. ark1668e_lcdc_set_video_osd_source_size(ARK1668E_LCDC_LAYER_OSD1, width, height);
  1213. ark1668e_lcdc_set_video_osd_layer_point(ARK1668E_LCDC_LAYER_OSD1, 0, 0);
  1214. ark1668e_lcdc_set_video_osd_win_point(ARK1668E_LCDC_LAYER_OSD1, 0, 0);
  1215. ark1668e_lcdc_set_video_osd_size(ARK1668E_LCDC_LAYER_OSD1, width, height);
  1216. ark1668e_lcdc_set_video_osd_format(ARK1668E_LCDC_LAYER_OSD1,ARK1668E_LCDC_FORMAT_RGBA888,ARK_LCDC_ORDER_YUYV,0);
  1217. return 0;
  1218. }
  1219. EXPORT_SYMBOL(ark_track_display_init);
  1220. int ark_track_set_display_addr(unsigned int addr)
  1221. {
  1222. //ark1668e_lcdc_set_osd_addr(ARK1668E_LCDC_LAYER_OSD1, addr);
  1223. //ark1668e_lcdc_wait_for_vsync();
  1224. lcdfb_info->render_addr[ARK1668E_LCDC_LAYER_OSD1].yaddr = addr;
  1225. return 0;
  1226. }
  1227. EXPORT_SYMBOL(ark_track_set_display_addr);
  1228. int ark_track_alpha_blend(void)
  1229. {
  1230. unsigned int val;
  1231. val = readl(lcdc_base + ARK1668E_LCDC_BLD_MODE_LCD_REG0);
  1232. val &= ~(0xF << 12);
  1233. writel(val, lcdc_base + ARK1668E_LCDC_BLD_MODE_LCD_REG0);
  1234. val = readl(lcdc_base + ARK1668E_LCDC_BLD_MODE_LCD_REG1);
  1235. val |= (3 << 14);
  1236. writel(val, lcdc_base + ARK1668E_LCDC_BLD_MODE_LCD_REG1);
  1237. return 0;
  1238. }
  1239. EXPORT_SYMBOL(ark_track_alpha_blend);
  1240. int ark_track_get_screen_info(int* width,int* height)
  1241. {
  1242. if(lcdc_base == NULL){
  1243. return -1;
  1244. }
  1245. *width = lcdc_width;
  1246. *height = lcdc_height;
  1247. return 0;
  1248. }
  1249. EXPORT_SYMBOL(ark_track_get_screen_info);
  1250. static void ark1668e_tvenc_video1_image_scaler(video_scaler_para *para)
  1251. {
  1252. unsigned int rgb_ycbcr_bypass=0;
  1253. unsigned int y_uv_order=0;
  1254. unsigned int format = para->Format;
  1255. unsigned int vblank,hblank,val;
  1256. if ((para->XOffset+para->WinWidth)>para->SrcWidth || (para->YOffset+para->WinHeight)>para->SrcHeight
  1257. || para->DstHeight ==0 || para->DstWidth == 0) {
  1258. printk("video layer scaler parameter error!\n");
  1259. return ;
  1260. }
  1261. if(para->Format == ARK1668E_LCDC_FORMAT_Y_UV420 || para->Format == ARK1668E_LCDC_FORMAT_Y_UV420) {
  1262. if(para->SrcWidth&7) {
  1263. printk("Video layer scaler didn't support the width which is not the multiple of 8 when the format is SEQ420.\n");
  1264. return ;
  1265. }
  1266. }
  1267. vblank = para->UpBlank + para->DownBlank;
  1268. hblank = para->LeftBlank + para->RightBlank;
  1269. if (format >= ARK1668E_LCDC_FORMAT_Y_UV422) {
  1270. y_uv_order = 1;
  1271. format &= 1;
  1272. rgb_ycbcr_bypass = 1;
  1273. } else
  1274. rgb_ycbcr_bypass = 0;
  1275. val = readl(lcdc_base + ARK1668E_LCDC_VIDEO1_CTL);
  1276. val = (1<<22) | (y_uv_order<<21) | (1<<8) | (1<<5) | (1<<4) | (format<<0);
  1277. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_CTL);
  1278. if (format == ARK1668E_LCDC_FORMAT_OSD_BMP24BIT_VIDEO_YUV420) {
  1279. val = readl(lcdc_base + ARK1668E_LCDC_VIDEO1_CTL);
  1280. val |= (1<<11);
  1281. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_CTL);
  1282. }
  1283. val = (para->YOffset<<12) | (para->XOffset);
  1284. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_WIN_POINT);
  1285. val = (para->WinHeight<<12) | (para->WinWidth<<0);
  1286. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_WIN_SIZE);
  1287. val = 0;
  1288. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_POSITION);
  1289. val = (para->DstHeight<<12) | (para->DstWidth<<0);
  1290. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_SIZE);
  1291. val = (para->SrcHeight<< 12) | (para->SrcWidth);
  1292. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_SOURCE_SIZE);
  1293. #if 0
  1294. val = (unsigned int )para->SrcBuf;
  1295. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_ADDR1);
  1296. val = (unsigned int )para->SrcBuf + para->SrcWidth*para->SrcHeight;
  1297. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_ADDR2);
  1298. if (para->Format == ARK1668E_LCDC_FORMAT_OSD_BMP24BIT_VIDEO_YUV420) {
  1299. val = ((unsigned int )para->SrcBuf + para->SrcWidth*para->SrcHeight) + para->SrcWidth*para->SrcHeight/4;
  1300. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_ADDR3);
  1301. }
  1302. else if (para->Format == ARK1668E_LCDC_FORMAT_OSD_PALETTE_VIDEO_YUV422) {
  1303. val = ((unsigned int )para->SrcBuf + para->SrcWidth*para->SrcHeight) + para->SrcWidth*para->SrcHeight/2;
  1304. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_ADDR3);
  1305. }
  1306. #endif
  1307. val = readl(lcdc_base + ARK1668E_LCDC_VIDEO1_SCALE_CTL);
  1308. val = (1<<7) | (1<<5);
  1309. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_SCALE_CTL);
  1310. if ((para->DstWidth+hblank) < para->WinWidth) { // enable filter when horizontal down scaler
  1311. val = readl(lcdc_base + ARK1668E_LCDC_VIDEO1_SCALE_CTL);
  1312. val |= (1<<6);
  1313. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_SCALE_CTL);
  1314. }
  1315. val = (para->LeftBlank<<18) | (para->WinWidth*1024/(para->DstWidth+hblank));
  1316. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_SCAL_CTL0);
  1317. val = (para->UpBlank<<18) | (para->WinHeight*1024/(para->DstHeight+vblank));
  1318. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_SCAL_CTL1);
  1319. if (para->Interlace4TV) {
  1320. val = readl(lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1321. val &= ~(1<<8);
  1322. writel(val, lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1323. //when v scaler cof is 0x400,v scaler bypass, now we should change the cof to
  1324. //force v scaler, otherwise there was sawtooth on picture
  1325. if((readl(lcdc_base + ARK1668E_LCDC_VIDEO1_SCAL_CTL1) &0x3FFFF) == 0x400) {
  1326. val = readl(lcdc_base + ARK1668E_LCDC_VIDEO1_SCAL_CTL1);
  1327. val = val - 1;
  1328. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_SCAL_CTL1);
  1329. }
  1330. val = readl(lcdc_base + ARK1668E_LCDC_VIDEO1_SCALE_CTL);
  1331. val &= ~(7<<9);
  1332. val |= (1<<9) | (1<<11);
  1333. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_SCALE_CTL);
  1334. }
  1335. if ((para->Format>= 4)&&(para->Format <= 12)) {
  1336. val = 0;
  1337. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG0);
  1338. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG1);
  1339. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG2);
  1340. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG3);
  1341. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG4);
  1342. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG5);
  1343. } else {
  1344. val = 0x01000100;
  1345. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG0);
  1346. val = 0x100167;
  1347. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG1);
  1348. val = 0xf4afa8;
  1349. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG2);
  1350. val = 0x12d100;
  1351. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG3);
  1352. val = 0xf4d000;
  1353. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG4);
  1354. val = 0xf69086;
  1355. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_COLOUR_MATRIX_REG5);
  1356. }
  1357. }
  1358. static void ark1668e_tvenc_cfg_lcdclk(int enable)
  1359. {
  1360. unsigned int val;
  1361. if(enable){
  1362. val = lcdc_readl_sys(lcdfb_info, 0xcc);
  1363. val |= (1 << 14); //video out
  1364. lcdc_writel_sys(lcdfb_info, 0xcc, val);
  1365. }else{
  1366. val = lcdc_readl_sys(lcdfb_info, 0xcc);
  1367. val &= ~(1<<14); //video out
  1368. lcdc_writel_sys(lcdfb_info, 0xcc, val);
  1369. }
  1370. }
  1371. static int ark1668e_tvenc_cfg_tvpll(int mode)
  1372. {
  1373. switch (mode)
  1374. {
  1375. case ARKE_TVENC_OUT_CVBS_NTSC:
  1376. case ARKE_TVENC_OUT_CVBS_PAL:
  1377. lcdc_writel_sys(lcdfb_info, 0x24, 0x08A09004); //432M
  1378. break;
  1379. case ARKE_TVENC_AHDOUT_720P_25FPS:
  1380. lcdc_writel_sys(lcdfb_info, 0x24, 0x08E12904); //297M
  1381. break;
  1382. default:
  1383. return -1;
  1384. }
  1385. return 0;
  1386. }
  1387. static void ark1668e_enable_tvenc(int enable)
  1388. {
  1389. unsigned int val;
  1390. if (enable) {
  1391. val = readl(lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1392. val |=(1 << 2); //video out
  1393. writel(val, lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1394. ark1668e_lcdc_layer_enable(ARK1668E_LCDC_LAYER_VIDEO1, 0);
  1395. } else {
  1396. val = readl(lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1397. val &= ~(1 << 2); //video out
  1398. writel(val, lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1399. }
  1400. }
  1401. static void ark1668e_set_tvenc_backcolor(unsigned char y, unsigned char cb, unsigned char cr)
  1402. {
  1403. unsigned int val;
  1404. val = (y << 16) |(cb << 8) |cr;
  1405. writel(val, lcdc_base + ARK1668E_LCDC_BACK_COLOR_TV);
  1406. }
  1407. static void ark1668e_config_tvenc_cvbs_clk(void)
  1408. {
  1409. unsigned int val;
  1410. val = lcdc_readl_sys(lcdfb_info, 0xd0);
  1411. val &= ~(0xff << 20);
  1412. val |= (0x7 << 24) |(1 << 21) | ( 0 << 14) | (0 << 12);
  1413. lcdc_writel_sys(lcdfb_info, 0xd0, val);
  1414. ark1668e_tvenc_cfg_lcdclk(1);
  1415. }
  1416. static void ark1668e_config_tvenc_ahd_clk(void)
  1417. {
  1418. unsigned int val;
  1419. val = lcdc_readl_sys(lcdfb_info, 0xd0);
  1420. val &= ~(0xff << 20);
  1421. val |= (1 << 24) |(1 << 21) | ( 0 << 14) | (0 << 12) | 3;
  1422. val &= ~(1 << 15);
  1423. lcdc_writel_sys(lcdfb_info, 0xd0, val);
  1424. ark1668e_tvenc_cfg_lcdclk(1);
  1425. }
  1426. static void ark1668e_enable_dac(void)
  1427. {
  1428. unsigned int val;
  1429. val = lcdc_readl_sys(lcdfb_info, 0x120);
  1430. val &= ~(0x1f << 16);
  1431. val |= (1 << 17) | ( 1 << 20);
  1432. lcdc_writel_sys(lcdfb_info, 0x120, val);
  1433. }
  1434. static void ark1668e_cvbs_ntsc_init(void)
  1435. {
  1436. //TV encoder setting
  1437. unsigned int chroma_freq_ntsc = 0x21f07c1f; //ntsc
  1438. unsigned int chroma_phase = 0x2a;
  1439. unsigned int clrbar_sel = 0;
  1440. unsigned int clrbar_mode = 0;
  1441. unsigned int bypass_yclamp = 0;
  1442. unsigned int yc_delay = 4;
  1443. unsigned int cvbs_enable = 1;
  1444. unsigned int chroma_bw_1 = 0; // bw_1,bw_0 : 00: narrow band; 01: wide band; 10: extra wide; 11: ultra wide.
  1445. unsigned int chroma_bw_0 = 1;
  1446. unsigned int comp_yuv = 0;
  1447. unsigned int compchgain = 0;
  1448. unsigned int hsync_width = 0x3f; //0x7e*2
  1449. unsigned int burst_width = 0x44; //pal 0x3e ntsc 0x44
  1450. unsigned int back_porch = 0x3b; //pal 0x45 ntsc 0x3b
  1451. unsigned int cb_burst_amp = 0x20;
  1452. unsigned int cr_burst_amp = 0x00; //pal 0x20 ntsc 0x00
  1453. unsigned int slave_mode = 0x1;
  1454. unsigned int black_level = 0xf2;
  1455. unsigned int blank_level = 0xf0;
  1456. unsigned int n1 = 0x17;
  1457. unsigned int n3 = 0x21;
  1458. unsigned int n8 = 0x1b;
  1459. unsigned int n9 = 0x1b;
  1460. unsigned int n10 = 0x24;
  1461. unsigned int num_lines = 525; // pal: 625; ntsc: 525.
  1462. unsigned int n0 = 0x3e;
  1463. unsigned int n13 = 0x0f;
  1464. unsigned int n14 = 0x0f;
  1465. unsigned int n15 = 0x60;
  1466. unsigned int n5 = 0x05;
  1467. unsigned int white_level = 0x320;
  1468. unsigned int cb_gain = 0x89;
  1469. unsigned int n20 = 0x04;
  1470. unsigned int cr_gain = 0x89;
  1471. unsigned int n16 = 0x1;
  1472. unsigned int n7 = 0x2;
  1473. unsigned int tint = 0;
  1474. unsigned int n17 = 0x0a;
  1475. unsigned int n19 = 0x05;
  1476. unsigned int n18 = 0x00;
  1477. unsigned int breeze_way = 0x16;
  1478. unsigned int n21 = 0x3ff;
  1479. unsigned int front_porch = 0x10; //pal 0x0c ntsc 0x10 ??
  1480. unsigned int n11 = 0x7ce;
  1481. unsigned int n12 = 0x000;
  1482. unsigned int activeline = 1440;
  1483. unsigned int firstvideoline = 0xe;
  1484. unsigned int uv_order = 0;
  1485. unsigned int pal_mode = 0; //pal 0x1 ntsc 0x0
  1486. unsigned int invert_top = 0;
  1487. unsigned int sys625_50 = 0;
  1488. unsigned int cphase_rst = 3;
  1489. unsigned int vsync5 = 1;
  1490. unsigned int sync_level = 0x48;
  1491. unsigned int n22 = 0;
  1492. unsigned int agc_pulse_level = 0xa3;
  1493. unsigned int bp_pulse_level = 0xc8;
  1494. unsigned int n4 = 0x15;
  1495. unsigned int n6 = 0x05;
  1496. unsigned int n2 = 0x15;
  1497. unsigned int vbi_blank_level = 0x128;
  1498. unsigned int soft_rst = 0;
  1499. //unsigned int row63 = 0;
  1500. unsigned int row64 = 0x07;
  1501. unsigned int wss_clock = 0x2f7;
  1502. unsigned int wss_dataf1 = 0;
  1503. unsigned int wss_dataf0 = 0;
  1504. unsigned int wss_linef1 = 0;
  1505. unsigned int wss_linef0 = 0;
  1506. unsigned int wss_level = 0x3ff;
  1507. unsigned int venc_en = 1;
  1508. unsigned int uv_first = 0;
  1509. unsigned int uv_flter_en = 1;
  1510. unsigned int notch_en = 0;
  1511. unsigned int notch_wide = 0;
  1512. unsigned int notch_freq = 0;
  1513. unsigned int row78 = 0;
  1514. unsigned int row79 = 0;
  1515. unsigned int row80 = 0;
  1516. unsigned int val;
  1517. val = chroma_freq_ntsc;
  1518. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG0); //森揭隅砱 N秶 P秶
  1519. val = chroma_bw_1<<27 | comp_yuv<<26|compchgain<<24|yc_delay<<17|cvbs_enable<<16|clrbar_sel<<10|clrbar_mode<<9|
  1520. bypass_yclamp<<8 | chroma_phase;
  1521. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG1);
  1522. val = cb_burst_amp<<24 | back_porch<<16 | burst_width<<8 | hsync_width;
  1523. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG2);
  1524. val = black_level<< 16 | slave_mode<<8 | cr_burst_amp ;
  1525. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG3);
  1526. val = n3<<24 | n1<<16 | blank_level ;
  1527. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG4);
  1528. val = n10<<24 | n9<<16 | n8 ;
  1529. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG5);
  1530. val = num_lines ;
  1531. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG6);
  1532. val = n15<<24 | n14<<16| n13<<8 | n0 ;
  1533. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG7);
  1534. val = cb_gain<<24 | white_level<<8 | n5 ;
  1535. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG8);
  1536. val = n7<<24 | n16 <<16 | cr_gain<<8 | n20 ;
  1537. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG9);
  1538. val = n18<<24 | n19 <<16 | n17<<8 | tint ;
  1539. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG10);
  1540. val = front_porch<<24 | n21<<8 | breeze_way ;
  1541. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG11);
  1542. val = n12 <<16 | n11 ;
  1543. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG12);
  1544. val = activeline ;
  1545. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG13);
  1546. val = n22<<24 | sync_level <<16 | uv_order<<15|pal_mode<<14|chroma_bw_0<<13|invert_top<<12|sys625_50<<11|
  1547. cphase_rst<<9|vsync5<<8 | firstvideoline ;
  1548. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG14);
  1549. val = n6<<24 | n4 <<16 | bp_pulse_level<<8 | agc_pulse_level ;
  1550. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG15);
  1551. val = soft_rst<<24| vbi_blank_level<<8 | n2 ;
  1552. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG16);
  1553. val = row64 <<16 | wss_clock ;
  1554. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG17);
  1555. val = wss_dataf1 ;
  1556. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG18);
  1557. val = wss_dataf0 ;
  1558. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG19);
  1559. val = wss_level <<16 | wss_linef0<<8 | wss_linef1 ;
  1560. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG20);
  1561. val = row80<<24 | row79<<16 | row78<<8 | venc_en<<7 | uv_first <<6 | uv_flter_en<<5 |notch_en<<4 | notch_wide<<3 | notch_freq ;
  1562. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG21);
  1563. }
  1564. static void ark1668e_cvbs_pal_init(void)
  1565. {
  1566. //TV encoder setting
  1567. unsigned int chroma_freq_palbg = 0x2a098acb; //pal
  1568. unsigned int chroma_phase = 0x2a;
  1569. unsigned int clrbar_sel = 0;
  1570. unsigned int clrbar_mode = 0;
  1571. unsigned int bypass_yclamp = 0;
  1572. unsigned int yc_delay = 4;
  1573. unsigned int cvbs_enable = 1;
  1574. unsigned int chroma_bw_1 = 0; // bw_1,bw_0 : 00: narrow band; 01: wide band; 10: extra wide; 11: ultra wide.
  1575. unsigned int chroma_bw_0 = 1;
  1576. unsigned int comp_yuv = 0;
  1577. unsigned int compchgain = 0;
  1578. unsigned int hsync_width = 0x3f; //0x7e*2
  1579. unsigned int burst_width = 0x3e; //pal 0x3e ntsc 0x44
  1580. unsigned int back_porch = 0x45; //pal 0x45 ntsc 0x3b
  1581. unsigned int cb_burst_amp = 0x20;
  1582. unsigned int cr_burst_amp = 0x20; //pal 0x20 ntsc 0x00
  1583. unsigned int slave_mode = 0x1;
  1584. unsigned int black_level = 0xf2;
  1585. unsigned int blank_level = 0xf0;
  1586. unsigned int n1 = 0x17;
  1587. unsigned int n3 = 0x21;
  1588. unsigned int n8 = 0x1b;
  1589. unsigned int n9 = 0x1b;
  1590. unsigned int n10 = 0x24;
  1591. unsigned int num_lines = 625; // pal: 625; ntsc: 525.
  1592. unsigned int n0 = 0x3e;
  1593. unsigned int n13 = 0x0f;
  1594. unsigned int n14 = 0x0f;
  1595. unsigned int n15 = 0x60;
  1596. unsigned int n5 = 0x05;
  1597. unsigned int white_level = 0x320;
  1598. unsigned int cb_gain = 0x89;
  1599. unsigned int n20 = 0x04;
  1600. unsigned int cr_gain = 0x89;
  1601. unsigned int n16 = 0x1;
  1602. unsigned int n7 = 0x2;
  1603. unsigned int tint = 0;
  1604. unsigned int n17 = 0x0a;
  1605. unsigned int n19 = 0x05;
  1606. unsigned int n18 = 0x00;
  1607. unsigned int breeze_way = 0x16;
  1608. unsigned int n21 = 0x3ff;
  1609. unsigned int front_porch = 0x0c; //pal 0x0c ntsc 0x10
  1610. unsigned int n11 = 0x7ce;
  1611. unsigned int n12 = 0x000;
  1612. unsigned int activeline = 1440;
  1613. unsigned int firstvideoline = 0x0e;
  1614. unsigned int uv_order = 0;
  1615. unsigned int pal_mode = 1; //pal 0x1 ntsc 0x0
  1616. unsigned int invert_top = 0;
  1617. unsigned int sys625_50 = 0;
  1618. unsigned int cphase_rst = 3;
  1619. unsigned int vsync5 = 1;
  1620. unsigned int sync_level = 0x48;
  1621. unsigned int n22 = 0;
  1622. unsigned int agc_pulse_level = 0xa3;
  1623. unsigned int bp_pulse_level = 0xc8;
  1624. unsigned int n4 = 0x15;
  1625. unsigned int n6 = 0x05;
  1626. unsigned int n2 = 0x15;
  1627. unsigned int vbi_blank_level = 0x128;
  1628. unsigned int soft_rst = 0;
  1629. //unsigned int row63 = 0;
  1630. unsigned int row64 = 0x07;
  1631. unsigned int wss_clock = 0x2f7;
  1632. unsigned int wss_dataf1 = 0;
  1633. unsigned int wss_dataf0 = 0;
  1634. unsigned int wss_linef1 = 0;
  1635. unsigned int wss_linef0 = 0;
  1636. unsigned int wss_level = 0x3ff;
  1637. unsigned int venc_en = 1;
  1638. unsigned int uv_first = 0;
  1639. unsigned int uv_flter_en = 1;
  1640. unsigned int notch_en = 0;
  1641. unsigned int notch_wide = 0;
  1642. unsigned int notch_freq = 0;
  1643. unsigned int row78 = 0;
  1644. unsigned int row79 = 0;
  1645. unsigned int row80 = 0;
  1646. unsigned int val;
  1647. val = chroma_freq_palbg;
  1648. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG0); //森揭隅砱 N秶 P秶
  1649. val = chroma_bw_1<<27 | comp_yuv<<26|compchgain<<24|yc_delay<<17|cvbs_enable<<16|clrbar_sel<<10|clrbar_mode<<9|
  1650. bypass_yclamp<<8 | chroma_phase;
  1651. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG1);
  1652. val = cb_burst_amp<<24 | back_porch<<16 | burst_width<<8 | hsync_width;
  1653. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG2);
  1654. val = black_level<< 16 | slave_mode<<8 | cr_burst_amp ;
  1655. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG3);
  1656. val = n3<<24 | n1<<16 | blank_level ;
  1657. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG4);
  1658. val = n10<<24 | n9<<16 | n8 ;
  1659. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG5);
  1660. val = num_lines ;
  1661. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG6);
  1662. val = n15<<24 | n14<<16| n13<<8 | n0 ;
  1663. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG7);
  1664. val = cb_gain<<24 | white_level<<8 | n5 ;
  1665. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG8);
  1666. val = n7<<24 | n16 <<16 | cr_gain<<8 | n20 ;
  1667. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG9);
  1668. val = n18<<24 | n19 <<16 | n17<<8 | tint ;
  1669. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG10);
  1670. val = front_porch<<24 | n21<<8 | breeze_way ;
  1671. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG11);
  1672. val = n12 <<16 | n11 ;
  1673. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG12);
  1674. val = activeline ;
  1675. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG13);
  1676. val = n22<<24 | sync_level <<16 | uv_order<<15|pal_mode<<14|chroma_bw_0<<13|invert_top<<12|sys625_50<<11|
  1677. cphase_rst<<9|vsync5<<8 | firstvideoline ;
  1678. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG14);
  1679. val = n6<<24 | n4 <<16 | bp_pulse_level<<8 | agc_pulse_level ;
  1680. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG15);
  1681. val = soft_rst<<24| vbi_blank_level<<8 | n2 ;
  1682. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG16);
  1683. val = row64 <<16 | wss_clock ;
  1684. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG17);
  1685. val = wss_dataf1 ;
  1686. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG18);
  1687. val = wss_dataf0 ;
  1688. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG19);
  1689. val = wss_level <<16 | wss_linef0<<8 | wss_linef1 ;
  1690. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG20);
  1691. val = row80<<24 | row79<<16 | row78<<8 | venc_en<<7 | uv_first <<6 | uv_flter_en<<5 |notch_en<<4 | notch_wide<<3 | notch_freq ;
  1692. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG21);
  1693. }
  1694. static void ark1668e_ahd_720p25_init(void)
  1695. {
  1696. unsigned int Control_0 = 0xa4;
  1697. unsigned int Control_1 = 0xc0;
  1698. unsigned int Control_2 = 0x40;
  1699. unsigned int Control_3 = 0x00;
  1700. unsigned int Hphase_value_man = 0x192;
  1701. unsigned int Vphase_value_man = 0x2eb; //0x0;
  1702. unsigned int Fsc_seed_man = 0x27890423;
  1703. unsigned int Hblank_start_man = 0x656;
  1704. unsigned int Hblank_end_man = 0x116;
  1705. unsigned int Hsync1_start_man = 0x00;
  1706. unsigned int Hsync1_end_man = 0x7c;
  1707. unsigned int Hsync2_start_man = 0x00;
  1708. unsigned int Hsync2_end_man = 0x7c;
  1709. unsigned int HBroad1_start_man = 0x0;
  1710. unsigned int HBroad1_end_man = 0x268;
  1711. unsigned int HBroad2_start_man = 0x3de;
  1712. unsigned int HBroad2_end_man = 0x646;
  1713. unsigned int burstgate_start_man = 0x9f;
  1714. unsigned int burstgate_end_man = 0x10b;
  1715. unsigned int Halfline_start_man = 0x000;
  1716. unsigned int Equalising1_end_man = 0x3e;
  1717. unsigned int Halfline2_start_man = 0x3de;
  1718. unsigned int Halfline2_end_man = 0x41c;
  1719. unsigned int Equalising2_end_man = 0x00;
  1720. unsigned int Vsync1_start_man = 0x00;
  1721. unsigned int Vsync1_end_man = 0x02;
  1722. unsigned int Vsync2_start_man = 0x00;
  1723. unsigned int Vsync2_end_man = 0x02;
  1724. unsigned int Vblank1_start_man = 0x2eb;
  1725. unsigned int Vblank1_end_man = 0x1b;
  1726. unsigned int Vblank2_start_man = 0x2eb;
  1727. unsigned int Vblank2_end_man = 0x1b;
  1728. unsigned int Luma_scaling_value = 0x4e;
  1729. unsigned int Sync_scaling_value = 0x40;
  1730. unsigned int Black_level_value = 0x00;
  1731. unsigned int Preemphasis_gain = 0x00;
  1732. unsigned int Tx_Data_word = 0x000;
  1733. unsigned int VSync1_half_start = 0x2eb;
  1734. unsigned int VSync1_half_end = 0x4;
  1735. unsigned int VSync2_half_start = 0x2eb;
  1736. unsigned int VSync2_half_end = 0x4;
  1737. unsigned int vsyn_hor_start = 0x3de;
  1738. unsigned int vsyn_hor_end = 0x0;
  1739. unsigned int Y_in_offset = 16;
  1740. unsigned int Default_UV_scaling_value = 0x3b1; //0x2b1;
  1741. unsigned int Default_CB_scaling_value = 0x15c;
  1742. unsigned int Default_CR_scaling_value = 0x2b0;
  1743. unsigned int Default_Burst_amplitude_value = 0x59;
  1744. unsigned int val;
  1745. val = (Control_0 << 0)|(Control_1 << 8)|(Control_2 <<16)|(Control_3 <<24);
  1746. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG0);
  1747. val = Hphase_value_man|(Vphase_value_man<<16);
  1748. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG1);
  1749. val = Hblank_start_man|(Hblank_end_man<<16);
  1750. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG2);
  1751. val = Hsync1_start_man|(Hsync1_end_man<<16);
  1752. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG3);
  1753. val = Hsync2_start_man|(Hsync2_end_man<<16);
  1754. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG4);
  1755. val = HBroad1_start_man|(HBroad1_end_man<<16);
  1756. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG5);
  1757. val = HBroad2_start_man|(HBroad2_end_man<<16);
  1758. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG6);
  1759. val = burstgate_start_man|(burstgate_end_man<<16);
  1760. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG7);
  1761. val = Halfline_start_man;
  1762. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG8);
  1763. val = Equalising1_end_man|(Equalising2_end_man<<16);
  1764. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG9);
  1765. val = Vsync1_start_man|(Vsync1_end_man<<16);
  1766. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG10);
  1767. val = Vsync2_start_man|(Vsync2_end_man<<16);
  1768. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG11);
  1769. val = Vblank1_start_man|(Vblank1_end_man<<16);
  1770. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG12);
  1771. val = Vblank2_start_man|(Vblank2_end_man<<16);
  1772. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG13);
  1773. val = Fsc_seed_man ;
  1774. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG14);
  1775. val = Luma_scaling_value|(Sync_scaling_value<<8)|(Black_level_value <<16)|(Preemphasis_gain<<24);
  1776. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG15);
  1777. val = VSync1_half_start|(VSync1_half_end<<16);
  1778. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG16);
  1779. val = VSync2_half_start|(VSync2_half_end<<16);
  1780. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG17);
  1781. val = Default_UV_scaling_value | (Default_CB_scaling_value << 16);
  1782. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG18);
  1783. val = Default_CR_scaling_value;
  1784. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG19);
  1785. val = Default_Burst_amplitude_value;
  1786. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG20);
  1787. val = vsyn_hor_start | (vsyn_hor_end << 12);
  1788. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG21);
  1789. val = Y_in_offset;
  1790. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG22);
  1791. val = Halfline2_start_man | (Halfline2_end_man << 12);
  1792. writel(val, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG23);
  1793. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG24);
  1794. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG25);
  1795. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG26);
  1796. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG27);
  1797. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG28);
  1798. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG29);
  1799. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG30);
  1800. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG31);
  1801. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG32);
  1802. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG33);
  1803. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG34);
  1804. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG35);
  1805. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG36);
  1806. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG37);
  1807. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG38);
  1808. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG39);
  1809. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG40);
  1810. writel(0, lcdc_base + ARK1668E_LCDC_TV_AHD_PARAM_REG41);
  1811. val = Tx_Data_word;
  1812. writel(val, lcdc_base + ARK1668E_LCDC_TV_PARAM_REG16);
  1813. }
  1814. cvbs_format_struct cvbs_info[2] =
  1815. {
  1816. //{720, 576, 144, 24, 0}, //PAL
  1817. {720, 576, 142, 24, 0}, //PAL
  1818. // {720, 480, 138, 22, 1} //NTSC
  1819. {720, 480, 136, 22, 1} //NTSC
  1820. };
  1821. ahd_format_struct AHD_info[2] =
  1822. {
  1823. {1279, 719,27,670,0,6,22,0,1}, //720p @25 pixle1980
  1824. //{1279, 719,199,299,199,6,22,0,1}, //720p @25 pixle1980
  1825. {0},
  1826. };
  1827. static void ark1668e_config_tvenc_cvbs_timing(unsigned int mode)
  1828. {
  1829. unsigned int tvmode = mode;
  1830. unsigned int val;
  1831. tvenc_info_struct cvbs_timing;
  1832. cvbs_timing.tHSW = (cvbs_info[tvmode].hsw-1);
  1833. cvbs_timing.tHBP = 0x0;
  1834. cvbs_timing.tHFP = 0x0;
  1835. cvbs_timing.tCPL = (cvbs_info[tvmode].width - 1);
  1836. cvbs_timing.tVSW = (cvbs_info[tvmode].vsw - 1);
  1837. cvbs_timing.tVFP = 0x0;
  1838. cvbs_timing.tVBP = 0x0;
  1839. cvbs_timing.tLPS = (cvbs_info[tvmode].height/2- 1);
  1840. cvbs_timing.tIVS = 0x0;
  1841. cvbs_timing.tIHS = 0x0;
  1842. cvbs_timing.tIOE = 0x0;
  1843. val = (cvbs_timing.tHSW<<20) | (cvbs_timing.tHBP<<10) | (cvbs_timing.tHFP<<0);
  1844. writel(val, lcdc_base + ARK1668E_LCDC_TIMING0_TV);
  1845. val = (cvbs_timing.tVFP<<19) | (cvbs_timing.tVSW<<13) | (cvbs_timing.tCPL<<0);
  1846. writel(val, lcdc_base + ARK1668E_LCDC_TIMING1_TV);
  1847. val = (cvbs_timing.tIOE<<23) | (cvbs_timing.tIHS<<22) | (cvbs_timing.tIVS<<21) | (cvbs_timing.tLPS<<10) | (cvbs_timing.tVBP<<0);
  1848. writel(val, lcdc_base + ARK1668E_LCDC_TIMING2_TV);
  1849. val = readl(lcdc_base + ARK1668E_LCDC_TIMING_FRAME_START_CNT_TV);
  1850. val = cvbs_timing.tVSW/2;
  1851. writel(val, lcdc_base + ARK1668E_LCDC_TIMING_FRAME_START_CNT_TV);
  1852. //rLCD_TV_HV_DELAY = 39;
  1853. }
  1854. static void ark1668e_config_tvenc_ahd_timing(void)
  1855. {
  1856. tvenc_info_struct ahdtiming;
  1857. unsigned int val;
  1858. ahdtiming.tHSW = AHD_info[0].hsw;
  1859. ahdtiming.tHBP = AHD_info[0].hbp;
  1860. ahdtiming.tHFP = AHD_info[0].hfp;
  1861. ahdtiming.tCPL = AHD_info[0].width;
  1862. ahdtiming.tVSW = AHD_info[0].vsw;
  1863. ahdtiming.tVFP = AHD_info[0].vfp;
  1864. ahdtiming.tVBP = AHD_info[0].vbp;
  1865. ahdtiming.tLPS = AHD_info[0].height;
  1866. ahdtiming.tIVS = 0x0;
  1867. ahdtiming.tIHS = 0x0;
  1868. ahdtiming.tIOE = 0x0;
  1869. val = (ahdtiming.tHSW<<20)|(ahdtiming.tHBP<<10)|(ahdtiming.tHFP<<0);
  1870. writel(val, lcdc_base + ARK1668E_LCDC_TIMING0_TV);
  1871. val = (ahdtiming.tVFP<<19)|(ahdtiming.tVSW<<13)|(ahdtiming.tCPL<<0);
  1872. writel(val, lcdc_base + ARK1668E_LCDC_TIMING1_TV);
  1873. val = (ahdtiming.tIOE<<23)|(ahdtiming.tIHS<<22)|(ahdtiming.tIVS<<21)|(ahdtiming.tLPS<<10)|(ahdtiming.tVBP<<0);
  1874. writel(val, lcdc_base + ARK1668E_LCDC_TIMING2_TV);
  1875. val = readl(lcdc_base + ARK1668E_LCDC_TIMING_FRAME_START_CNT_TV);
  1876. val = ahdtiming.tVSW/2;
  1877. writel(val, lcdc_base + ARK1668E_LCDC_TIMING_FRAME_START_CNT_TV);
  1878. }
  1879. static void ark1668e_config_ahd_mode(void)
  1880. {
  1881. unsigned int val;
  1882. val = (0<<10)|(0<<9)|(0<<8)|(0<<7) |(AHD_info[0].mode<<1)|(1<<0);
  1883. writel(val, lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1884. val = readl(lcdc_base + ARK1668E_LCDC_VIDEO1_CTL);
  1885. val |= 1<<7;
  1886. writel(val, lcdc_base + ARK1668E_LCDC_VIDEO1_CTL);
  1887. }
  1888. static void ark1668e_disp_init_tvenc_cvbs(unsigned int mode)
  1889. {
  1890. unsigned int val;
  1891. if (mode == CVBS_NTSC) {
  1892. printk(KERN_ALERT "ark1668e_disp_init_tvenc_cvbs mode is ntsc\n");
  1893. val = readl(lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1894. val |= (1<<1);
  1895. writel(val, lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1896. ark1668e_config_tvenc_cvbs_timing(mode);
  1897. ark1668e_enable_dac();
  1898. ark1668e_cvbs_ntsc_init();
  1899. ark1668e_config_tvenc_cvbs_clk();
  1900. } else {
  1901. printk(KERN_ALERT "ark1668e_disp_init_tvenc_cvbs mode is pal\n");
  1902. val = readl(lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1903. val &= ~(1<<1);
  1904. writel(val, lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1905. ark1668e_config_tvenc_cvbs_timing(mode);
  1906. ark1668e_enable_dac();
  1907. ark1668e_cvbs_pal_init();
  1908. ark1668e_config_tvenc_cvbs_clk();
  1909. }
  1910. val = readl(lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1911. val |= (1<<8) | (1<<0);
  1912. val &= ~((1<<10)|(1<<9)|(1<<7));
  1913. writel(val, lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1914. }
  1915. static void ark1668e_disp_init_tvenc_ahd(unsigned int mode)
  1916. {
  1917. unsigned int val;
  1918. if (mode == ARKE_TVENC_AHDOUT_720P_25FPS) {
  1919. printk(KERN_ALERT "ark1668e_disp_init_tvenc_cvbs mode is ahd 720p 25fps\n");
  1920. ark1668e_config_tvenc_ahd_timing();
  1921. ark1668e_enable_dac();
  1922. ark1668e_config_ahd_mode();
  1923. ark1668e_config_tvenc_ahd_clk();
  1924. ark1668e_ahd_720p25_init();
  1925. }
  1926. val = readl(lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1927. val |= 1<<16;//ピ遙善AHD
  1928. writel(val, lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1929. }
  1930. static int ark1668e_disp_set_tvenc_out_mode(int out_mode)
  1931. {
  1932. ark1668e_tvenc_cfg_tvpll(out_mode);
  1933. switch (out_mode)
  1934. {
  1935. case ARKE_TVENC_OUT_CVBS_NTSC:
  1936. case ARKE_TVENC_OUT_CVBS_PAL:
  1937. ark1668e_disp_init_tvenc_cvbs(out_mode - ARKE_TVENC_OUT_CVBS_PAL);
  1938. break;
  1939. case ARKE_TVENC_AHDOUT_720P_25FPS:
  1940. ark1668e_disp_init_tvenc_ahd(out_mode);
  1941. break;
  1942. default:
  1943. return -1;
  1944. }
  1945. return 0;
  1946. }
  1947. static int ark1668e_disp_set_tvenc_cfg(struct ark_disp_tvenc_cfg_arg *arg)
  1948. {
  1949. if(lcdfb_info->pdata.interface_type > ARK1668E_LCDC_INTERFACE_MIPI){
  1950. printk(KERN_ALERT "+++The screen type no need to set tvenc cfg+++\n");
  1951. return 0;
  1952. }
  1953. if (ark1668e_disp_set_tvenc_out_mode(arg->out_mode)) {
  1954. printk(KERN_ALERT "%s %d: set out mode error\n",
  1955. __FUNCTION__, __LINE__);
  1956. return -1;
  1957. }
  1958. ark1668e_set_tvenc_backcolor(arg->backcolor_y,arg->backcolor_cb,arg->backcolor_cr);
  1959. return 0;
  1960. }
  1961. static int ark1668e_disp_set_gui_tvout(struct ark_disp_tvenc_cfg_arg *arg)
  1962. {
  1963. unsigned int val;
  1964. video_scaler_para para={0};
  1965. if (lcdc_base == NULL) {
  1966. printk(KERN_ALERT "lcdc_base is null\n");
  1967. return -1;
  1968. }
  1969. if (arg->enable) {
  1970. printk(KERN_ALERT "ark1668e_disp_set_gui_tvout enable\n");
  1971. lcdfb_info->gui_tvout = 1;
  1972. ark1668e_disp_set_tvenc_cfg(arg);
  1973. val = readl(lcdc_base + ARK1668E_LCDC_CONTROL);
  1974. val |= (1<<14);
  1975. writel(val, lcdc_base + ARK1668E_LCDC_CONTROL);
  1976. val = readl(lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1977. val &=~(0x3f<<10);
  1978. val |=(0x3f<<10);
  1979. writel(val, lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  1980. para.Format = ARK1668E_LCDC_FORMAT_RGBA888;;
  1981. para.SrcBuf = readl(lcdc_base + ARK1668E_LCDC_OSD2_ADDR);
  1982. para.SrcWidth = lcdfb_info->info->var.xres;
  1983. para.SrcHeight = lcdfb_info->info->var.yres;
  1984. para.WinWidth = lcdfb_info->info->var.xres;
  1985. para.WinHeight = lcdfb_info->info->var.yres;
  1986. para.Interlace4TV = 0;
  1987. if (arg->out_mode== ARKE_TVENC_OUT_CVBS_NTSC) {
  1988. para.DstWidth = 720;
  1989. para.DstHeight =480;
  1990. } else if (arg->out_mode == ARKE_TVENC_OUT_CVBS_PAL) {
  1991. para.DstWidth = 720;
  1992. para.DstHeight =576;
  1993. } else if (arg->out_mode == ARKE_TVENC_AHDOUT_720P_25FPS) {
  1994. para.DstWidth = 1280;
  1995. para.DstHeight =720;
  1996. } else {
  1997. para.DstWidth = 720;
  1998. para.DstHeight =480;
  1999. }
  2000. ark1668e_enable_tvenc(0);
  2001. writel(para.SrcBuf, lcdc_base + ARK1668E_LCDC_VIDEO1_ADDR1);
  2002. ark1668e_tvenc_video1_image_scaler(&para);
  2003. ark1668e_enable_tvenc(1);
  2004. } else {
  2005. printk(KERN_ALERT "ark1668e_disp_set_gui_tvout disable\n");
  2006. lcdfb_info->gui_tvout = 0;
  2007. ark1668e_enable_tvenc(0);
  2008. //ark1668e_tvenc_cfg_lcdclk(0);
  2009. }
  2010. return 0;
  2011. }
  2012. static int ark1668e_disp_set_video_tvout(struct ark_disp_tvenc_cfg_arg *arg)
  2013. {
  2014. video_scaler_para para={0};
  2015. if(lcdc_base == NULL){
  2016. printk(KERN_ALERT "lcdc_base is null\n");
  2017. return -1;
  2018. }
  2019. if (arg->enable) {
  2020. printk(KERN_ALERT "ark1668e_disp_set_video_tvout enable\n");
  2021. lcdfb_info->video_tvout = 1;
  2022. #if 0
  2023. ark1668e_disp_set_tvenc_cfg(arg);
  2024. val = readl(lcdc_base + ARK1668E_LCDC_CONTROL);
  2025. val |= (1<<14);
  2026. writel(val, lcdc_base + ARK1668E_LCDC_CONTROL);
  2027. val = readl(lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  2028. val &=~(0x7f<<10);
  2029. val |=(0x3f<<10);
  2030. writel(val, lcdc_base + ARK1668E_LCDC_TV_CONTROL);
  2031. #endif
  2032. para.Format = ARK1668E_LCDC_FORMAT_Y_UV420;
  2033. //para.SrcBuf = readl(lcdc_base + ARK1668E_LCDC_VIDEO2_ADDR1);
  2034. para.SrcWidth = arg->src_width;
  2035. para.SrcHeight = arg->src_height;
  2036. para.WinWidth = arg->src_width;
  2037. para.WinHeight = arg->src_height;
  2038. para.Interlace4TV = 0;
  2039. if (arg->out_mode== ARKE_TVENC_OUT_CVBS_NTSC) {
  2040. para.DstWidth = 720;
  2041. para.DstHeight =480;
  2042. } else if (arg->out_mode == ARKE_TVENC_OUT_CVBS_PAL) {
  2043. para.DstWidth = 720;
  2044. para.DstHeight =576;
  2045. } else if (arg->out_mode == ARKE_TVENC_AHDOUT_720P_25FPS) {
  2046. para.DstWidth = 1280;
  2047. para.DstHeight =720;
  2048. } else {
  2049. para.DstWidth = 720;
  2050. para.DstHeight =480;
  2051. }
  2052. ark1668e_enable_tvenc(0);
  2053. ark1668e_tvenc_video1_image_scaler(&para);
  2054. //ark1668e_enable_tvenc(1);
  2055. } else {
  2056. printk(KERN_ALERT "ark1668e_disp_set_video_tvout disable\n");
  2057. lcdfb_info->video_tvout = 0;
  2058. ark1668e_enable_tvenc(0);
  2059. //ark1668e_tvenc_cfg_lcdclk(0);
  2060. }
  2061. return 0;
  2062. }
  2063. /*******************************************************************************/
  2064. int ark1668e_lcdfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
  2065. {
  2066. struct ark1668e_lcdfb_info *sinfo;
  2067. int layer;
  2068. int error = 0;
  2069. if(!info || !info->par) {
  2070. printk(KERN_ERR "ERR: %s, Invalid info:%p or info->par:%p\n", __FUNCTION__, info, info->par);
  2071. error = -EINVAL;
  2072. goto end;
  2073. }
  2074. if(!lcdc_base) {
  2075. printk(KERN_ERR "ERR: %s, Invalid lcdc_base(NULL)\n", __FUNCTION__);
  2076. error = -EINVAL;
  2077. goto end;
  2078. }
  2079. sinfo = info->par;
  2080. //layer = info->node;
  2081. layer = ark1668e_lcdc_convert_layer(info->node);
  2082. if(layer < 0) {
  2083. printk(KERN_ERR "ERR: %s, Invalid layer:%d\n", __FUNCTION__, layer);
  2084. error = -EINVAL;
  2085. goto end;
  2086. }
  2087. /* printk("ark1668e_lcdfb_ioctl layer=%d, cmd=0x%x.\n", layer, cmd); */
  2088. switch (cmd) {
  2089. case FBIO_WAITFORVSYNC:
  2090. case ARKFB_WAITFORVSYNC:
  2091. error = ark1668e_lcdc_wait_for_vsync();
  2092. break;
  2093. case ARKFB_SHOW_WINDOW:
  2094. error = ark1668e_lcdc_layer_enable(layer, 1);
  2095. break;
  2096. case ARKFB_HIDE_WINDOW:
  2097. error = ark1668e_lcdc_layer_enable(layer, 0);
  2098. break;
  2099. case ARKFB_SET_WINDOW_POS: {
  2100. unsigned int x, y, data;
  2101. if(copy_from_user(&data, (void *)arg, sizeof(unsigned int))) {
  2102. printk("ERR: %s, copy from user para error\n", __func__);
  2103. error = -EFAULT;
  2104. goto end;
  2105. }
  2106. x = data & 0xFFFF;
  2107. y = (data >> 16) & 0xFFFF;
  2108. error = ark1668e_lcdc_set_video_osd_layer_point(layer, x, y);
  2109. break;
  2110. }
  2111. case ARKFB_SET_WINDOW_SIZE: {
  2112. unsigned int width, height, data;
  2113. if(copy_from_user(&data, (void *)arg, sizeof(unsigned int))){
  2114. printk("ERR: %s, copy from user para error\n", __func__);
  2115. error = -EFAULT;
  2116. goto end;
  2117. }
  2118. width = data & 0xFFFF;
  2119. height = (data >> 16) & 0xFFFF;
  2120. if((layer >= ARK1668E_LCDC_LAYER_OSD1) && (layer <= ARK1668E_LCDC_LAYER_OSD3)) {
  2121. error += ark1668e_lcdc_set_video_osd_size(layer, width, height);
  2122. error += ark1668e_lcdc_set_video_osd_source_size(layer, width, height);
  2123. } else if ((layer >= ARK1668E_LCDC_LAYER_VIDEO1) && (layer <= ARK1668E_LCDC_LAYER_VIDEO2)) {
  2124. error += ark1668e_lcdc_set_video_osd_source_size(layer, width, height);
  2125. error += ark1668e_lcdc_set_video_osd_win_point(layer, 0, 0);
  2126. error += ark1668e_lcdc_set_video_win_size(layer, width, height);
  2127. error += ark1668e_lcdc_set_video_osd_size(layer, width, height);
  2128. //scale
  2129. //if(layer == ARK1668E_LCDC_LAYER_VIDEO1) {
  2130. // error += ark1668e_lcdc_set_video1_scal(ARK1668E_LCDC_LAYER_VIDEO1, width, height,
  2131. // 0, 0, 0, 0, width, height, 0);
  2132. //}
  2133. }
  2134. break;
  2135. }
  2136. case ARKFB_SET_WINDOW_FORMAT: {
  2137. unsigned int data, format, yuv_order, rgb_order;
  2138. if(copy_from_user(&data, (void *)arg, sizeof(unsigned int))) {
  2139. printk("ERR: %s, copy from user para error\n", __func__);
  2140. error = -EFAULT;
  2141. goto end;
  2142. }
  2143. format = (data >> 0) & 0xFF;
  2144. yuv_order = (data >> 16) & 0xF;
  2145. rgb_order = (data >> 24) & 0xF;
  2146. error = ark1668e_lcdc_set_video_osd_format(layer, format, yuv_order, rgb_order);
  2147. //if((layer >= ARK1668E_LCDC_LAYER_OSD1) && (layer <= ARK1668E_LCDC_LAYER_OSD3)) {
  2148. //error += ark1668e_lcdc_alpha_blend_with_backcolor_enable(layer, 1);
  2149. //error += ark1668e_lcdc_alpha_blend_per_pix_mode_enable(layer, 1);
  2150. //}
  2151. if(format == ARK1668E_LCDC_FORMAT_RGBA888){
  2152. error += ark1668e_lcdc_alpha_blend_with_backcolor_enable(layer, 1);
  2153. error += ark1668e_lcdc_alpha_blend_per_pix_mode_enable(layer, 1);
  2154. }
  2155. printk(KERN_DEBUG "layer=%d: format=%d, yuv_order:%d, rgb_order:%d\n",
  2156. layer, format, yuv_order, rgb_order);
  2157. break;
  2158. }
  2159. case ARKFB_SET_WINDOW_ADDR: {
  2160. struct ark_disp_addr addr;
  2161. if(copy_from_user(&addr, (void *)arg, sizeof(struct ark_disp_addr))){
  2162. printk("ERR: %s, copy from user para error\n", __func__);
  2163. error = -EFAULT;
  2164. goto end;
  2165. }
  2166. memcpy(&sinfo->render_addr[layer], &addr, sizeof(struct ark_disp_addr));
  2167. //printk(KERN_ALERT "layer=%d: yaddr=0x%0x, cbaddr=0x%0x, craddr=0x%0x.\n ",layer, addr.yaddr, addr.cbaddr, addr.craddr);
  2168. if(lcdfb_info->video_tvout && layer == ARK1668E_LCDC_LAYER_VIDEO2){
  2169. writel(addr.yaddr, lcdc_base + ARK1668E_LCDC_VIDEO1_ADDR1);
  2170. writel(addr.cbaddr, lcdc_base + ARK1668E_LCDC_VIDEO1_ADDR2);
  2171. ark1668e_enable_tvenc(1);
  2172. }
  2173. break;
  2174. }
  2175. case ARKFB_SET_WINDOW_SCALER: {
  2176. struct ark_disp_scaler scaler;
  2177. if(layer != ARK1668E_LCDC_LAYER_VIDEO1){
  2178. error = -EINVAL;
  2179. printk("ERR: %s, Only video1 layer support scaler\n", __func__);
  2180. goto end;
  2181. }
  2182. if(copy_from_user(&scaler, (void *)arg, sizeof(struct ark_disp_scaler))){
  2183. printk("ERR: %s, copy from user para error\n", __func__);
  2184. error = -EFAULT;
  2185. goto end;
  2186. }
  2187. error += ark1668e_lcdc_set_video_osd_size(layer, scaler.out_w, scaler.out_h);
  2188. error += ark1668e_lcdc_set_video1_scal(layer, scaler.src_w, scaler.src_h,
  2189. scaler.cut_left, scaler.cut_right, scaler.cut_top, scaler.cut_bottom,
  2190. scaler.out_w, scaler.out_h, 0);
  2191. //printk(KERN_DEBUG "layer=%d: scaler src_w=%d, src_h=%d, out_w=%d, out_h=%d.\n ",
  2192. // layer, scaler.src_w, scaler.src_h, scaler.out_w, scaler.out_h);
  2193. break;
  2194. }
  2195. case ARKFB_SET_WINDOW_ATOMIC: {
  2196. struct ark_disp_atomic atomic;
  2197. if(copy_from_user(&atomic, (void *)arg, sizeof(struct ark_disp_atomic))){
  2198. printk("ERR: %s, copy from user para error\n", __func__);
  2199. error = -EFAULT;
  2200. goto end;
  2201. }
  2202. atomic.layer = ark1668e_lcdc_convert_layer(atomic.layer);
  2203. if(!atomic.atomic_stat || atomic.layer != layer){
  2204. printk("ERR: %s, atomic_stat:%d or layer:%d error\n", __func__, atomic.atomic_stat, atomic.layer);
  2205. error = -EFAULT;
  2206. goto end;
  2207. }
  2208. printk(KERN_DEBUG "%s===>layer=%d, atomic_stat=0x%0x.\n ",__func__, layer, atomic.atomic_stat);
  2209. sinfo->atomic_flag |= (1 << layer);
  2210. memcpy(&sinfo->patomic[layer], &atomic, sizeof(struct ark_disp_atomic));
  2211. error += ark1668e_lcdc_wait_for_vsync();
  2212. break;
  2213. }
  2214. case ARKFB_GET_WINDOW_ADDR: {
  2215. struct ark_disp_addr addr;
  2216. memset(&addr, 0, sizeof(struct ark_disp_addr));
  2217. if((layer >= ARK1668E_LCDC_LAYER_OSD1) && (layer <= ARK1668E_LCDC_LAYER_OSD3)) {
  2218. addr.yaddr = ark1668e_lcdc_get_osd_addr(layer);
  2219. if(addr.yaddr < 0) {
  2220. addr.yaddr = 0;
  2221. goto end;
  2222. }
  2223. } else {
  2224. error += ark1668e_lcdc_get_video_addr(layer, &addr.yaddr, &addr.cbaddr, &addr.craddr);
  2225. if(error < 0) {
  2226. printk("%s: ark1668e_lcdc_get_video_addr failed\n", __func__);
  2227. error = -EFAULT;
  2228. goto end;
  2229. }
  2230. }
  2231. if(copy_to_user((void *)arg, &addr, sizeof(struct ark_disp_addr))){
  2232. printk("%s: copy to user para error\n", __func__);
  2233. error = -EFAULT;
  2234. goto end;
  2235. }
  2236. break;
  2237. }
  2238. case ARKFB_GET_SCREEN_INFO: {
  2239. struct ark_screen screen;
  2240. memset(&screen, 0, sizeof(struct ark_screen));
  2241. screen.width = screen.disp_width = lcdc_width;
  2242. screen.height = screen.disp_height = lcdc_height;
  2243. if(copy_to_user((void *)arg, &screen, sizeof(struct ark_screen))){
  2244. printk("%s: copy to user para error\n", __func__);
  2245. error = -EFAULT;
  2246. goto end;
  2247. }
  2248. break;
  2249. }
  2250. case ARKFB_SET_SCREEN_INFO: {
  2251. struct ark_screen screen;
  2252. if(copy_from_user(&screen, (void *)arg, sizeof(struct ark_screen))){
  2253. printk("%s: copy to user para error\n", __func__);
  2254. error = -EFAULT;
  2255. goto end;
  2256. }
  2257. ///////////////// Reserved///////////////////
  2258. break;
  2259. }
  2260. case ARKFB_GET_PLATFORM_INFO: {
  2261. struct ark_platform_info platform;
  2262. memset(&platform, 0, sizeof(struct ark_platform_info));
  2263. platform.type = ARK_PLATFORM_ARK1668ED;
  2264. if(copy_to_user((void *)arg, &platform, sizeof(struct ark_platform_info))){
  2265. printk("%s: copy to user para error\n", __func__);
  2266. error = -EFAULT;
  2267. goto end;
  2268. }
  2269. break;
  2270. }
  2271. case ARKFB_GET_WINDOW_FORMAT: {
  2272. int format = ark1668e_lcdc_get_video_osd_format(layer);
  2273. if(format < 0) {
  2274. printk("%s: get format failed\n", __func__);
  2275. error = -EFAULT;
  2276. goto end;
  2277. }
  2278. if(copy_to_user((void *)arg, &format, sizeof(int))){
  2279. printk("%s: copy to user para error\n", __func__);
  2280. error = -EFAULT;
  2281. goto end;
  2282. }
  2283. break;
  2284. }
  2285. case ARKFB_SET_VP_INFO: {
  2286. struct ark_disp_vp vp;
  2287. memset(&vp, 0, sizeof(struct ark_disp_vp));
  2288. if(copy_from_user(&vp, (void *)arg, sizeof(struct ark_disp_vp))) {
  2289. printk("%s: copy to user para error\n", __func__);
  2290. error = -EFAULT;
  2291. goto end;
  2292. }
  2293. error += ark1668e_lcdc_set_video_osd_color_matrix(layer,
  2294. vp.reg[0], vp.reg[1], vp.reg[2], vp.reg[3], vp.reg[4], vp.reg[5]);
  2295. if(error == 0) {
  2296. memcpy(&lcdc_vp, &vp, sizeof(struct ark_disp_vp));
  2297. }
  2298. break;
  2299. }
  2300. case ARKFB_GET_VP_INFO: {
  2301. if(copy_to_user((void *)arg, &lcdc_vp, sizeof(struct ark_disp_vp))) {
  2302. printk("%s: copy to user para error\n", __func__);
  2303. error = -EFAULT;
  2304. goto end;
  2305. }
  2306. break;
  2307. }
  2308. case ARKFB_SET_REG_VALUE: {
  2309. struct ark_disp_reg reg;
  2310. if(copy_from_user(&reg, (void *)arg, sizeof(struct ark_disp_reg))){
  2311. printk("%s: copy from user para error\n", __func__);
  2312. error = -EFAULT;
  2313. goto end;
  2314. }
  2315. if((reg.addr & 0xffff0000) == 0xe0500000){
  2316. writel(reg.value, sinfo->mmio + (reg.addr&0xffff));
  2317. printk("arkfb write reg:0x%0x=0x%0x.\n ", reg.addr, reg.value);
  2318. }else{
  2319. error = -EINVAL;
  2320. goto end;
  2321. }
  2322. break;
  2323. }
  2324. case ARKFB_GET_REG_VALUE: {
  2325. struct ark_disp_reg reg;
  2326. if(copy_from_user(&reg, (void *)arg, sizeof(struct ark_disp_reg))){
  2327. printk("%s: copy from user para error\n", __func__);
  2328. error = -EFAULT;
  2329. goto end;
  2330. }
  2331. if((reg.addr & 0xffff0000) == 0xe0500000){
  2332. reg.value = readl(sinfo->mmio + (reg.addr&0xffff));
  2333. printk("arkfb read reg:0x%0x=0x%0x.\n ", reg.addr, reg.value);
  2334. }else{
  2335. error = -EINVAL;
  2336. goto end;
  2337. }
  2338. if(copy_to_user((void *)arg, &reg, sizeof(struct ark_disp_reg))){
  2339. printk("%s: copy to user para error\n", __func__);
  2340. error = -EFAULT;
  2341. goto end;
  2342. }
  2343. break;
  2344. }
  2345. case ARKFB_SET_GUI_TVOUT: {
  2346. struct ark_disp_tvenc_cfg_arg cfg;
  2347. if(copy_from_user(&cfg, (void *)arg, sizeof(struct ark_disp_tvenc_cfg_arg))){
  2348. printk("ERR: %s, copy from user para error\n", __func__);
  2349. error = -EFAULT;
  2350. goto end;
  2351. }
  2352. ark1668e_disp_set_gui_tvout(&cfg);
  2353. break;
  2354. }
  2355. case ARKFB_SET_VIDEO_TVOUT: {
  2356. struct ark_disp_tvenc_cfg_arg cfg;
  2357. if(copy_from_user(&cfg, (void *)arg, sizeof(struct ark_disp_tvenc_cfg_arg))){
  2358. printk("ERR: %s, copy from user para error\n", __func__);
  2359. error = -EFAULT;
  2360. goto end;
  2361. }
  2362. ark1668e_disp_set_video_tvout(&cfg);
  2363. break;
  2364. }
  2365. default:
  2366. break;
  2367. }
  2368. end:
  2369. return error;
  2370. }
  2371. EXPORT_SYMBOL(ark1668e_lcdfb_ioctl);
  2372. int ark1668e_lcdc_funcs_init(struct ark1668e_lcdfb_info *sinfo)
  2373. {
  2374. struct fb_info *info = NULL;
  2375. struct fb_var_screeninfo *var = NULL;
  2376. if(!sinfo) {
  2377. printk(KERN_ERR "ERR: %s, Invalid sinfo(NULL)\n", __func__);
  2378. return -EINVAL;
  2379. }
  2380. info = sinfo->info;
  2381. var = &info->var;
  2382. lcdfb_info = sinfo;
  2383. lcdc_base = sinfo->mmio;
  2384. lcdc_width = var->xres;
  2385. lcdc_height = var->yres;
  2386. return 0;
  2387. }
  2388. EXPORT_SYMBOL(ark1668e_lcdc_funcs_init);