s3c_lts222qv.c 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/errno.h>
  4. #include <linux/string.h>
  5. #include <linux/mm.h>
  6. #include <linux/tty.h>
  7. #include <linux/slab.h>
  8. #include <linux/delay.h>
  9. #include <linux/fb.h>
  10. #include <linux/init.h>
  11. #include <linux/dma-mapping.h>
  12. #include <linux/string.h>
  13. #include <linux/ioctl.h>
  14. #include <linux/clk.h>
  15. #include <asm/io.h>
  16. #include <asm/uaccess.h>
  17. #include <asm/mach/map.h>
  18. #include <asm/arch/regs-lcd.h>
  19. #include <asm/arch/regs-gpio.h>
  20. #include <asm/arch/regs-gpioj.h>
  21. #include <asm/arch/regs-spi.h>
  22. #if defined(CONFIG_CPU_S3C2443)
  23. #include <asm/arch/regs-s3c2443-clock.h>
  24. #elif defined(CONFIG_CPU_S3C2450)
  25. #include <asm/arch/regs-s3c2450-clock.h>
  26. #elif defined(CONFIG_CPU_S3C6400)
  27. #include <asm/arch/regs-s3c6400-clock.h>
  28. #elif defined(CONFIG_CPU_S3C6410)
  29. #include <asm/arch/regs-s3c6410-clock.h>
  30. #endif
  31. #include "s3cfb.h"
  32. #define ON 1
  33. #define OFF 0
  34. #define DEFAULT_BACKLIGHT_LEVEL 2
  35. #define H_FP 7 /* front porch */
  36. #define H_SW 4 /* Hsync width */
  37. #define H_BP 2 /* Back porch */
  38. #define V_FP 11 /* front porch */
  39. #define V_SW 4 /* Vsync width */
  40. #define V_BP 10 /* Back porch */
  41. extern struct s3c_fb_info info[S3C_FB_NUM];
  42. s3c_win_info_t window_info;
  43. //------------------ Virtual Screen -----------------------
  44. #if defined(CONFIG_FB_VIRTUAL_SCREEN)
  45. vs_info_t vs_info;
  46. #define START_VIRTUAL_LCD 11
  47. #define STOP_VIRTUAL_LCD 10
  48. #define SET_VIRTUAL_LCD 12
  49. #define VS_MOVE_LEFT 15
  50. #define VS_MOVE_RIGHT 16
  51. #define VS_MOVE_UP 17
  52. #define VS_MOVE_DOWN 18
  53. #define MAX_DISPLAY_OFFSET 200
  54. #define DEF_DISPLAY_OFFSET 100
  55. int virtual_display_offset = DEF_DISPLAY_OFFSET;
  56. #endif
  57. //------------------ OSD (On Screen Display) -----------------------
  58. #define START_OSD 1
  59. #define STOP_OSD 0
  60. // QCIF OSD image
  61. #if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450)
  62. #define H_RESOLUTION_OSD 240 /* horizon pixel x resolition */
  63. #define V_RESOLUTION_OSD 320 /* line cnt y resolution */
  64. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  65. #define H_RESOLUTION_OSD 240 /* horizon pixel x resolition */
  66. #define V_RESOLUTION_OSD 320 /* line cnt y resolution */
  67. #endif
  68. #define ALPHA_UP 3
  69. #define ALPHA_DOWN 4
  70. #define MOVE_LEFT 5
  71. #define MOVE_RIGHT 6
  72. #define MOVE_UP 7
  73. #define MOVE_DOWN 8
  74. #define MAX_ALPHA_LEVEL 0x0f
  75. int osd_alpha_level = MAX_ALPHA_LEVEL;
  76. int osd_left_top_x = 0;
  77. int osd_left_top_y = 0;
  78. int osd_right_bottom_x = H_RESOLUTION_OSD-1;
  79. int osd_left_bottom_y = V_RESOLUTION_OSD -1;
  80. //------------------------------------------------------------------------
  81. #define H_RESOLUTION 240 /* horizon pixel x resolition */
  82. #define V_RESOLUTION 320 /* line cnt y resolution */
  83. #define H_RESOLUTION_VIRTUAL 240 /* horizon pixel x resolition */
  84. #define V_RESOLUTION_VIRTUAL 320 /* line cnt y resolution */
  85. #if defined(CONFIG_CPU_S3C2443)||defined(CONFIG_CPU_S3C2450)
  86. #define VFRAME_FREQ 75 /* frame rate freq */
  87. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  88. #define VFRAME_FREQ 60 /* frame rate freq */
  89. #endif
  90. #define PIXEL_CLOCK VFRAME_FREQ * LCD_PIXEL_CLOCK /* vclk = frame * pixel_count */
  91. #define PIXEL_BPP8 8
  92. #define PIXEL_BPP16 16 /* RGB 5-6-5 format for SMDK EVAL BOARD */
  93. #define PIXEL_BPP24 24 /* RGB 8-8-8 format for SMDK EVAL BOARD */
  94. #define LCD_PIXEL_CLOCK (VFRAME_FREQ *(H_FP+H_SW+H_BP+H_RESOLUTION) * (V_FP+V_SW+V_BP+V_RESOLUTION))
  95. #define MAX_DISPLAY_BRIGHTNESS 9
  96. #define DEF_DISPLAY_BRIGHTNESS 4
  97. int display_brightness = DEF_DISPLAY_BRIGHTNESS;
  98. void set_brightness(int);
  99. struct s3c_fb_mach_info mach_info = {
  100. #if defined(CONFIG_CPU_S3C2443)||defined(CONFIG_CPU_S3C2450)
  101. .vidcon0= S3C_VIDCON0_VIDOUT_RGB_IF | S3C_VIDCON0_PNRMODE_RGB_P | S3C_VIDCON0_CLKDIR_DIVIDED | S3C_VIDCON0_VCLKEN_ENABLE |S3C_VIDCON0_CLKSEL_F_HCLK,
  102. .vidcon1= S3C_VIDCON1_IHSYNC_INVERT | S3C_VIDCON1_IVSYNC_INVERT,
  103. .vidtcon0= S3C_VIDTCON0_VBPD(V_BP-1) | S3C_VIDTCON0_VFPD(V_FP-1) | S3C_VIDTCON0_VSPW(V_SW-1),
  104. .vidtcon1= S3C_VIDTCON1_HBPD(H_BP-1) | S3C_VIDTCON1_HFPD(H_FP-1 ) | S3C_VIDTCON1_HSPW(H_SW-1),
  105. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  106. .vidcon0 = S3C_VIDCON0_INTERLACE_F_PROGRESSIVE | S3C_VIDCON0_VIDOUT_RGB_IF | S3C_VIDCON0_L1_DATA16_SUB_16_MODE
  107. | S3C_VIDCON0_L0_DATA16_MAIN_16_MODE | S3C_VIDCON0_PNRMODE_RGB_P
  108. | S3C_VIDCON0_CLKVALUP_ALWAYS | S3C_VIDCON0_CLKDIR_DIVIDED | S3C_VIDCON0_CLKSEL_F_HCLK |
  109. S3C_VIDCON0_ENVID_DISABLE | S3C_VIDCON0_ENVID_F_DISABLE,
  110. .vidcon1 = S3C_VIDCON1_IHSYNC_INVERT | S3C_VIDCON1_IVSYNC_INVERT |S3C_VIDCON1_IVDEN_INVERT,
  111. .vidtcon0 = S3C_VIDTCON0_VBPDE(0) | S3C_VIDTCON0_VBPD(V_BP-1) | S3C_VIDTCON0_VFPD(V_FP-1) | S3C_VIDTCON0_VSPW(V_SW-1),
  112. .vidtcon1 = S3C_VIDTCON1_VFPDE(0) | S3C_VIDTCON1_HBPD(H_BP-1) | S3C_VIDTCON1_HFPD(H_FP-1) | S3C_VIDTCON1_HSPW(H_SW-1),
  113. #endif
  114. .vidtcon2= S3C_VIDTCON2_LINEVAL(V_RESOLUTION-1) | S3C_VIDTCON2_HOZVAL(H_RESOLUTION-1),
  115. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  116. .dithmode = ( S3C_DITHMODE_RDITHPOS_5BIT |S3C_DITHMODE_GDITHPOS_6BIT | S3C_DITHMODE_BDITHPOS_5BIT ) & S3C_DITHMODE_DITHERING_DISABLE,
  117. #endif
  118. #if defined (CONFIG_FB_BPP_8)
  119. .wincon0= S3C_WINCONx_BYTSWP_ENABLE |S3C_WINCONx_BURSTLEN_4WORD | S3C_WINCONx_BPPMODE_F_8BPP_PAL, // 4word burst, 8bpp-palletized,
  120. .wincon1= S3C_WINCONx_HAWSWP_ENABLE | S3C_WINCONx_BURSTLEN_4WORD | S3C_WINCONx_BPPMODE_F_16BPP_565 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1, // 4word burst, 16bpp for OSD
  121. //.wincon1= S3C_WINCONx_HAWSWP_ENABLE | S3C_WINCONx_BURSTLEN_4WORD | S3C_WINCONx_BPPMODE_F_16BPP_A555 | S3C_WINCONx_BLD_PIX_PIXEL| S3C_WINCONx_ALPHA_SEL_1, // 4word burst, 16bpp for OSD
  122. #elif defined (CONFIG_FB_BPP_16)
  123. #if defined(CONFIG_CPU_S3C2443)||defined(CONFIG_CPU_S3C2450)
  124. .wincon0= S3C_WINCONx_HAWSWP_ENABLE | S3C_WINCONx_BURSTLEN_4WORD | S3C_WINCONx_BPPMODE_F_16BPP_565, // 4word burst, 16bpp,
  125. .wincon1= S3C_WINCONx_HAWSWP_ENABLE | S3C_WINCONx_BURSTLEN_4WORD | S3C_WINCONx_BPPMODE_F_16BPP_565 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1, // 4word burst, 16bpp for OSD
  126. //.wincon1= S3C_WINCONx_HAWSWP_ENABLE | S3C_WINCONx_BURSTLEN_4WORD | S3C_WINCONx_BPPMODE_F_16BPP_A555 | S3C_WINCONx_BLD_PIX_PIXEL| S3C_WINCONx_ALPHA_SEL_1, // 4word burst, 16bpp for OSD
  127. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  128. // .wincon0 = S3C_WINCONx_ENLOCAL_DMA | S3C_WINCONx_BUFSEL_0 | S3C_WINCONx_BUFAUTOEN_DISABLE | S3C_WINCONx_BITSWP_DISABLE |
  129. .wincon0 = S3C_WINCONx_ENLOCAL_DMA | S3C_WINCONx_BUFSEL_1 | S3C_WINCONx_BUFAUTOEN_DISABLE | S3C_WINCONx_BITSWP_DISABLE |
  130. S3C_WINCONx_BYTSWP_DISABLE | S3C_WINCONx_HAWSWP_ENABLE|
  131. S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BPPMODE_F_16BPP_565 |
  132. #if defined(CONFIG_FB_DOUBLE_BUFFERING)
  133. // S3C_WINCONx_BUFAUTOEN_ENABLE |
  134. #endif
  135. S3C_WINCONx_ENWIN_F_DISABLE, // 4word burst, 16bpp,
  136. .wincon1 = S3C_WINCONx_ENLOCAL_DMA | S3C_WINCONx_BUFSEL_0 | S3C_WINCONx_BUFAUTOEN_DISABLE | S3C_WINCONx_BITSWP_DISABLE |
  137. S3C_WINCONx_BYTSWP_DISABLE | S3C_WINCONx_HAWSWP_ENABLE|
  138. S3C_WINCONx_BURSTLEN_16WORD |S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_BPPMODE_F_16BPP_565 |
  139. #if defined(CONFIG_FB_DOUBLE_BUFFERING)
  140. // S3C_WINCONx_BUFAUTOEN_ENABLE |
  141. #endif
  142. S3C_WINCONx_ALPHA_SEL_1 | S3C_WINCONx_ENWIN_F_DISABLE, // 4word burst, 16bpp,
  143. .wincon2 = S3C_WINCONx_ENLOCAL_DMA | S3C_WINCONx_BITSWP_DISABLE |
  144. S3C_WINCONx_BYTSWP_DISABLE | S3C_WINCONx_HAWSWP_ENABLE|
  145. S3C_WINCONx_BURSTLEN_4WORD | S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_BPPMODE_F_16BPP_565 |
  146. S3C_WINCONx_ALPHA_SEL_1 | S3C_WINCONx_ENWIN_F_DISABLE,
  147. .wincon3 = S3C_WINCONx_BITSWP_DISABLE | S3C_WINCONx_BYTSWP_DISABLE | S3C_WINCONx_HAWSWP_ENABLE|
  148. S3C_WINCONx_BURSTLEN_4WORD | S3C_WINCONx_BURSTLEN_16WORD |
  149. S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_BPPMODE_F_16BPP_565 | S3C_WINCONx_ALPHA_SEL_1 | S3C_WINCONx_ENWIN_F_DISABLE,
  150. .wincon4 = S3C_WINCONx_BITSWP_DISABLE | S3C_WINCONx_BYTSWP_DISABLE | S3C_WINCONx_HAWSWP_ENABLE|
  151. S3C_WINCONx_BURSTLEN_4WORD | S3C_WINCONx_BURSTLEN_16WORD |
  152. S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_BPPMODE_F_16BPP_565 | S3C_WINCONx_ALPHA_SEL_1 | S3C_WINCONx_ENWIN_F_DISABLE,
  153. #endif
  154. #elif defined (CONFIG_FB_BPP_24)
  155. .wincon0= S3C_WINCONx_HAWSWP_DISABLE | S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BPPMODE_F_24BPP_888, // 4word burst, 24bpp,
  156. .wincon1= S3C_WINCONx_HAWSWP_DISABLE | S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BPPMODE_F_24BPP_888 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1, // 4word burst, 24bpp for OSD
  157. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  158. .wincon2 = S3C_WINCONx_HAWSWP_DISABLE | S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BPPMODE_F_24BPP_888 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1,
  159. .wincon3 = S3C_WINCONx_HAWSWP_DISABLE | S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BPPMODE_F_24BPP_888 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1,
  160. .wincon4 = S3C_WINCONx_HAWSWP_DISABLE | S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BPPMODE_F_24BPP_888 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1,
  161. #endif
  162. #endif
  163. #if defined(CONFIG_CPU_S3C2443)||defined(CONFIG_CPU_S3C2450)
  164. .vidosd0a= S3C_VIDOSDxA_OSD_LTX_F(0) | S3C_VIDOSDxA_OSD_LTY_F(0),
  165. .vidosd0b= S3C_VIDOSDxB_OSD_RBX_F(H_RESOLUTION-1) | S3C_VIDOSDxB_OSD_RBY_F(V_RESOLUTION-1),
  166. .vidosd1a= S3C_VIDOSDxA_OSD_LTX_F(0) | S3C_VIDOSDxA_OSD_LTY_F(0),
  167. .vidosd1b= S3C_VIDOSDxB_OSD_RBX_F(H_RESOLUTION_OSD-1) | S3C_VIDOSDxB_OSD_RBY_F(V_RESOLUTION_OSD-1),
  168. .vidosd1c= S3C_VIDOSDxC_ALPHA1_B(MAX_ALPHA_LEVEL) | S3C_VIDOSDxC_ALPHA1_G(MAX_ALPHA_LEVEL) |S3C_VIDOSDxC_ALPHA1_R(MAX_ALPHA_LEVEL),
  169. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  170. .vidosd0a = S3C_VIDOSDxA_OSD_LTX_F(0) | S3C_VIDOSDxA_OSD_LTY_F(0),
  171. .vidosd0b = S3C_VIDOSDxB_OSD_RBX_F(H_RESOLUTION-1) | S3C_VIDOSDxB_OSD_RBY_F(V_RESOLUTION-1),
  172. .vidosd0c = S3C_VIDOSDxD_OSDSIZE(H_RESOLUTION*V_RESOLUTION),
  173. .vidosd1a = S3C_VIDOSDxA_OSD_LTX_F(0) | S3C_VIDOSDxA_OSD_LTY_F(0),
  174. .vidosd1b = S3C_VIDOSDxB_OSD_RBX_F(H_RESOLUTION_OSD-1) | S3C_VIDOSDxB_OSD_RBY_F(V_RESOLUTION_OSD-1),
  175. .vidosd1c= S3C_VIDOSDxC_ALPHA1_B(MAX_ALPHA_LEVEL) | S3C_VIDOSDxC_ALPHA1_G(MAX_ALPHA_LEVEL) |S3C_VIDOSDxC_ALPHA1_R(MAX_ALPHA_LEVEL),
  176. .vidosd1d = S3C_VIDOSDxD_OSDSIZE(H_RESOLUTION*V_RESOLUTION),
  177. .vidosd2a = S3C_VIDOSDxA_OSD_LTX_F(0) | S3C_VIDOSDxA_OSD_LTY_F(0),
  178. .vidosd2b = S3C_VIDOSDxB_OSD_RBX_F(H_RESOLUTION_OSD-1) | S3C_VIDOSDxB_OSD_RBY_F(V_RESOLUTION_OSD-1),
  179. .vidosd2c = S3C_VIDOSDxC_ALPHA1_B(MAX_ALPHA_LEVEL) | S3C_VIDOSDxC_ALPHA1_G(MAX_ALPHA_LEVEL) |S3C_VIDOSDxC_ALPHA1_R(MAX_ALPHA_LEVEL),
  180. .vidosd2d = S3C_VIDOSDxD_OSDSIZE(H_RESOLUTION*V_RESOLUTION),
  181. .vidosd3a = S3C_VIDOSDxA_OSD_LTX_F(0) | S3C_VIDOSDxA_OSD_LTY_F(0),
  182. .vidosd3b = S3C_VIDOSDxB_OSD_RBX_F(H_RESOLUTION_OSD-1) | S3C_VIDOSDxB_OSD_RBY_F(V_RESOLUTION_OSD-1),
  183. .vidosd3c = S3C_VIDOSDxC_ALPHA1_B(MAX_ALPHA_LEVEL) | S3C_VIDOSDxC_ALPHA1_G(MAX_ALPHA_LEVEL) |S3C_VIDOSDxC_ALPHA1_R(MAX_ALPHA_LEVEL),
  184. .vidosd4a = S3C_VIDOSDxA_OSD_LTX_F(0) | S3C_VIDOSDxA_OSD_LTY_F(0),
  185. .vidosd4b = S3C_VIDOSDxB_OSD_RBX_F(H_RESOLUTION_OSD-1) | S3C_VIDOSDxB_OSD_RBY_F(V_RESOLUTION_OSD-1),
  186. .vidosd4c = S3C_VIDOSDxC_ALPHA1_B(MAX_ALPHA_LEVEL) | S3C_VIDOSDxC_ALPHA1_G(MAX_ALPHA_LEVEL) |S3C_VIDOSDxC_ALPHA1_R(MAX_ALPHA_LEVEL),
  187. #endif
  188. #if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450)
  189. .vidintcon= S3C_VIDINTCON0_FRAMESEL0_VSYNC | S3C_VIDINTCON0_FRAMESEL1_NONE | S3C_VIDINTCON0_INTFRMEN_ENABLE | S3C_VIDINTCON0_INTEN_ENABLE,
  190. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  191. // .vidintcon0 = S3C_VIDINTCON0_FRAMESEL0_BACK | S3C_VIDINTCON0_FRAMESEL1_NONE | S3C_VIDINTCON0_INTFRMEN_DISABLE | S3C_VIDINTCON0_FIFOSEL_WIN0 | S3C_VIDINTCON0_FIFOLEVEL_25 | S3C_VIDINTCON0_INTFIFOEN_DISABLE | S3C_VIDINTCON0_INTEN_DISABLE,
  192. .vidintcon0 = S3C_VIDINTCON0_FRAMESEL0_VSYNC | S3C_VIDINTCON0_FRAMESEL1_NONE | S3C_VIDINTCON0_INTFRMEN_DISABLE | S3C_VIDINTCON0_FIFOSEL_WIN0 | S3C_VIDINTCON0_FIFOLEVEL_25 | S3C_VIDINTCON0_INTFIFOEN_DISABLE | S3C_VIDINTCON0_INTEN_ENABLE,
  193. .vidintcon1 = 0,
  194. #endif
  195. .width= H_RESOLUTION,
  196. .height= V_RESOLUTION,
  197. .xres= H_RESOLUTION,
  198. .yres= V_RESOLUTION,
  199. .xoffset= 0,
  200. .yoffset= 0,
  201. #if defined(CONFIG_FB_VIRTUAL_SCREEN)
  202. .xres_virtual = H_RESOLUTION_VIRTUAL,
  203. .yres_virtual = V_RESOLUTION_VIRTUAL,
  204. #else
  205. .xres_virtual = H_RESOLUTION,
  206. .yres_virtual = V_RESOLUTION,
  207. #endif
  208. .osd_width= H_RESOLUTION_OSD,
  209. .osd_height= V_RESOLUTION_OSD,
  210. .osd_xres= H_RESOLUTION_OSD,
  211. .osd_yres= V_RESOLUTION_OSD,
  212. .osd_xres_virtual= H_RESOLUTION_OSD,
  213. .osd_yres_virtual= V_RESOLUTION_OSD,
  214. #if defined (CONFIG_FB_BPP_8)
  215. .bpp= PIXEL_BPP8,
  216. .bytes_per_pixel= 1,
  217. #if defined(CONFIG_CPU_S3C2443)||defined(CONFIG_CPU_S3C2450)
  218. .wpalcon= W0PAL_24BIT,
  219. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  220. .wpalcon= W0PAL_16BIT,
  221. #endif
  222. #elif defined (CONFIG_FB_BPP_16)
  223. .bpp= PIXEL_BPP16,
  224. .bytes_per_pixel= 2,
  225. #elif defined (CONFIG_FB_BPP_24)
  226. .bpp= PIXEL_BPP24,
  227. .bytes_per_pixel= 4,
  228. #endif
  229. .pixclock= PIXEL_CLOCK,
  230. .hsync_len= H_SW,
  231. .vsync_len= V_SW,
  232. .left_margin= H_FP,
  233. .upper_margin= V_FP,
  234. .right_margin= H_BP,
  235. .lower_margin= V_BP,
  236. .sync= 0,
  237. .cmap_static= 1,
  238. };
  239. #if defined(CONFIG_S3C6400_PWM)
  240. void set_brightness(int val)
  241. {
  242. int channel = 1; // must use channel-1
  243. int usec = 0; // don't care value
  244. unsigned long tcnt=1000;
  245. unsigned long tcmp=0;
  246. if(val < 0) val=0;
  247. if(val > MAX_DISPLAY_BRIGHTNESS) val=MAX_DISPLAY_BRIGHTNESS;
  248. display_brightness = val;
  249. switch (val) {
  250. case 0:
  251. tcmp= 0;
  252. break;
  253. case 1:
  254. tcmp= 50;
  255. break;
  256. case 2:
  257. tcmp= 100;
  258. break;
  259. case 3:
  260. tcmp= 150;
  261. break;
  262. case 4:
  263. tcmp= 200;
  264. break;
  265. case 5:
  266. tcmp= 250;
  267. break;
  268. case 6:
  269. tcmp= 300;
  270. break;
  271. case 7:
  272. tcmp= 350;
  273. break;
  274. case 8:
  275. tcmp= 400;
  276. break;
  277. case 9:
  278. tcmp= 450;
  279. break;
  280. } // end of switch (level)
  281. s3c6400_timer_setup (channel, usec, tcnt, tcmp);
  282. }
  283. #endif
  284. #if defined(CONFIG_S3C2443_PWM)
  285. /*
  286. * Function for PWM Control of S3C2443
  287. */
  288. void set_brightness(int val)
  289. {
  290. int channel = 3; // must use channel-3
  291. int usec = 0; // don't care value
  292. unsigned long tcnt=1000;
  293. unsigned long tcmp=0;
  294. if(val < 0) val=0;
  295. if(val > MAX_DISPLAY_BRIGHTNESS) val=MAX_DISPLAY_BRIGHTNESS;
  296. display_brightness = val;
  297. switch (val) {
  298. case 0:
  299. tcmp= 0;
  300. break;
  301. case 1:
  302. tcmp= 50;
  303. break;
  304. case 2:
  305. tcmp= 100;
  306. break;
  307. case 3:
  308. tcmp= 150;
  309. break;
  310. case 4:
  311. tcmp= 200;
  312. break;
  313. case 5:
  314. tcmp= 250;
  315. break;
  316. case 6:
  317. tcmp= 300;
  318. break;
  319. case 7:
  320. tcmp= 350;
  321. break;
  322. case 8:
  323. tcmp= 400;
  324. break;
  325. case 9:
  326. tcmp= 450;
  327. break;
  328. }
  329. s3c2443_timer_setup (channel, usec, tcnt, tcmp);
  330. }
  331. #endif
  332. #if defined(CONFIG_S3C2450_PWM)
  333. /*
  334. * Function for PWM Control of S3C2450
  335. */
  336. void set_brightness(int val)
  337. {
  338. int channel = 1; // must use channel-3
  339. int usec = 0; // don't care value
  340. unsigned long tcnt=1000;
  341. unsigned long tcmp=0;
  342. if(val < 0) val=0;
  343. if(val > MAX_DISPLAY_BRIGHTNESS) val=MAX_DISPLAY_BRIGHTNESS;
  344. display_brightness = val;
  345. switch (val) {
  346. case 0:
  347. tcmp= 0;
  348. break;
  349. case 1:
  350. tcmp= 50;
  351. break;
  352. case 2:
  353. tcmp= 100;
  354. break;
  355. case 3:
  356. tcmp= 150;
  357. break;
  358. case 4:
  359. tcmp= 200;
  360. break;
  361. case 5:
  362. tcmp= 250;
  363. break;
  364. case 6:
  365. tcmp= 300;
  366. break;
  367. case 7:
  368. tcmp= 350;
  369. break;
  370. case 8:
  371. tcmp= 400;
  372. break;
  373. case 9:
  374. tcmp= 450;
  375. break;
  376. }
  377. s3c2450_timer_setup (channel, usec, tcnt, tcmp);
  378. }
  379. #endif
  380. #if defined(CONFIG_FB_VIRTUAL_SCREEN)
  381. void set_virtual_display_offset(int val)
  382. {
  383. if(val < 1)
  384. val = 1;
  385. if(val > MAX_DISPLAY_OFFSET)
  386. val = MAX_DISPLAY_OFFSET;
  387. virtual_display_offset = val;
  388. }
  389. int set_vs_info(vs_info_t vs_info_from_app )
  390. {
  391. /* check invalid value */
  392. if(vs_info_from_app.width != H_RESOLUTION || vs_info_from_app.height != V_RESOLUTION ){
  393. return 1;
  394. }
  395. if(!(vs_info_from_app.bpp==8 ||vs_info_from_app.bpp==16 ||vs_info_from_app.bpp==24 || vs_info_from_app.bpp==32) ){
  396. return 1;
  397. }
  398. if(vs_info_from_app.offset<0){
  399. return 1;
  400. }
  401. if(vs_info_from_app.v_width != H_RESOLUTION_VIRTUAL || vs_info_from_app.v_height != V_RESOLUTION_VIRTUAL){
  402. return 1;
  403. }
  404. /* save virtual screen information */
  405. vs_info = vs_info_from_app;
  406. set_virtual_display_offset(vs_info.offset);
  407. return 0;
  408. }
  409. int set_virtual_display_register(int vs_cmd)
  410. {
  411. int PageWidth, Offset;
  412. int ShiftValue;
  413. PageWidth = mach_info.xres * mach_info.bytes_per_pixel;
  414. Offset = (mach_info.xres_virtual - mach_info.xres) * mach_info.bytes_per_pixel;
  415. switch(vs_cmd){
  416. case SET_VIRTUAL_LCD:
  417. /* size of buffer */
  418. #if defined(CONFIG_CPU_S3C2443)||defined(CONFIG_CPU_S3C2450)
  419. mach_info.vidw00add2b0 = S3C_VIDWxxADD2_OFFSIZE_F(Offset) | (S3C_VIDWxxADD2_PAGEWIDTH_F(PageWidth));
  420. mach_info.vidw00add2b1 = S3C_VIDWxxADD2_OFFSIZE_F(Offset) | (S3C_VIDWxxADD2_PAGEWIDTH_F(PageWidth));
  421. __raw_writel(mach_info.vidw00add2b0, S3C_VIDW00ADD2B0);
  422. __raw_writel(mach_info.vidw00add2b1, S3C_VIDW00ADD2B1);
  423. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  424. mach_info.vidw00add2 = S3C_VIDWxxADD2_OFFSIZE_F(Offset) | (S3C_VIDWxxADD2_PAGEWIDTH_F(PageWidth));
  425. __raw_writel(mach_info.vidw00add2, S3C_VIDW00ADD2);
  426. #endif
  427. break;
  428. case VS_MOVE_LEFT:
  429. if(mach_info.xoffset < virtual_display_offset){
  430. ShiftValue = mach_info.xoffset;
  431. }
  432. else ShiftValue = virtual_display_offset;
  433. mach_info.xoffset -= ShiftValue;
  434. /* For buffer start address */
  435. mach_info.vidw00add0b0 = mach_info.vidw00add0b0 - ShiftValue*mach_info.bytes_per_pixel;
  436. mach_info.vidw00add0b1 = mach_info.vidw00add0b1 - ShiftValue*mach_info.bytes_per_pixel;
  437. break;
  438. case VS_MOVE_RIGHT:
  439. if((vs_info.v_width - (mach_info.xoffset + vs_info.width) )< (virtual_display_offset)){
  440. ShiftValue = vs_info.v_width - (mach_info.xoffset + vs_info.width);
  441. }
  442. else ShiftValue = virtual_display_offset;
  443. mach_info.xoffset += ShiftValue;
  444. /* For buffer start address */
  445. mach_info.vidw00add0b0 = mach_info.vidw00add0b0 + ShiftValue*mach_info.bytes_per_pixel;
  446. mach_info.vidw00add0b1 = mach_info.vidw00add0b1 + ShiftValue*mach_info.bytes_per_pixel;
  447. break;
  448. case VS_MOVE_UP:
  449. if(mach_info.yoffset < virtual_display_offset){
  450. ShiftValue = mach_info.yoffset;
  451. }
  452. else ShiftValue = virtual_display_offset;
  453. mach_info.yoffset -= ShiftValue;
  454. /* For buffer start address */
  455. mach_info.vidw00add0b0 = mach_info.vidw00add0b0 - ShiftValue*mach_info.xres_virtual*mach_info.bytes_per_pixel;
  456. mach_info.vidw00add0b1 = mach_info.vidw00add0b1 - ShiftValue*mach_info.xres_virtual*mach_info.bytes_per_pixel;
  457. break;
  458. case VS_MOVE_DOWN:
  459. if((vs_info.v_height - (mach_info.yoffset + vs_info.height) )< (virtual_display_offset)){
  460. ShiftValue = vs_info.v_height - (mach_info.yoffset + vs_info.height);
  461. }
  462. else ShiftValue = virtual_display_offset;
  463. mach_info.yoffset += ShiftValue;
  464. /* For buffer start address */
  465. mach_info.vidw00add0b0 = mach_info.vidw00add0b0 + ShiftValue*mach_info.xres_virtual*mach_info.bytes_per_pixel;
  466. mach_info.vidw00add0b1 = mach_info.vidw00add0b1 + ShiftValue*mach_info.xres_virtual*mach_info.bytes_per_pixel;
  467. break;
  468. default:
  469. return -EINVAL;
  470. }
  471. /* End address */
  472. mach_info.vidw00add1b0 = S3C_VIDWxxADD1_VBASEL_F(mach_info.vidw00add0b0 + (PageWidth + Offset) * (mach_info.yres));
  473. mach_info.vidw00add1b1 = S3C_VIDWxxADD1_VBASEL_F(mach_info.vidw00add0b1 + (PageWidth + Offset) * (mach_info.yres));
  474. __raw_writel(mach_info.vidw00add0b0, S3C_VIDW00ADD0B0);
  475. __raw_writel(mach_info.vidw00add0b1, S3C_VIDW00ADD0B1);
  476. __raw_writel(mach_info.vidw00add1b0, S3C_VIDW00ADD1B0);
  477. __raw_writel(mach_info.vidw00add1b1, S3C_VIDW00ADD1B1);
  478. return 0;
  479. }
  480. #endif
  481. /*
  482. * As LCD-Brightness is best related to Display and hence FrameBuffer,
  483. * so we put the brightness control in /dev/fb.
  484. */
  485. #define GET_DISPLAY_BRIGHTNESS _IOR('F', 1, u_int) /* get brightness */
  486. #define SET_DISPLAY_BRIGHTNESS _IOW('F', 2, u_int) /* set brightness */
  487. #if defined(CONFIG_FB_VIRTUAL_SCREEN)
  488. #define SET_VS_START _IO('F', 103)
  489. #define SET_VS_STOP _IO('F', 104)
  490. #define SET_VS_INFO _IOW('F', 105, vs_info_t)
  491. #define SET_VS_MOVE _IOW('F', 106, u_int)
  492. #endif
  493. #define SET_OSD_START _IO('F', 201)
  494. #define SET_OSD_STOP _IO('F', 202)
  495. #define SET_OSD_ALPHA_UP _IO('F', 203)
  496. #define SET_OSD_ALPHA_DOWN _IO('F', 204)
  497. #define SET_OSD_MOVE_LEFT _IO('F', 205)
  498. #define SET_OSD_MOVE_RIGHT _IO('F', 206)
  499. #define SET_OSD_MOVE_UP _IO('F', 207)
  500. #define SET_OSD_MOVE_DOWN _IO('F', 208)
  501. #define SET_OSD_INFO _IOW('F', 209, s3c_win_info_t)
  502. #define SET_OSD_BRIGHT _IOW('F', 210, int)
  503. #if defined(CONFIG_FB_DOUBLE_BUFFERING)
  504. #define GET_FB_NUM _IOWR('F', 301, u_int)
  505. #endif
  506. #if defined(CONFIG_G3D)
  507. #define S3C_FBIO_CHANGE_FB _IOW('F', 81,int)
  508. #endif
  509. int s3c_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
  510. {
  511. struct s3c_fb_info *fbi = container_of(info, struct s3c_fb_info, fb);
  512. struct fb_var_screeninfo *var= &fbi->fb.var;
  513. int brightness;
  514. #if defined(CONFIG_FB_DOUBLE_BUFFERING)
  515. u_int f_num_val;
  516. #endif
  517. #if defined(CONFIG_FB_VIRTUAL_SCREEN)
  518. vs_info_t vs_info_from_app;
  519. #endif
  520. s3c_win_info_t win_info_from_app;
  521. // int bright_level_from_app;
  522. #if defined(CONFIG_G3D)
  523. int value;
  524. int sizeof_fb;
  525. unsigned int start1;
  526. unsigned int end1;
  527. unsigned int start2;
  528. unsigned int end2;
  529. unsigned int start3;
  530. unsigned int end3;
  531. unsigned int TargetFBStartReg;
  532. unsigned int TargetFBEndReg;
  533. unsigned int TargetFBSel;
  534. int currentDrawing;
  535. #endif
  536. switch(cmd){
  537. #if defined(CONFIG_FB_VIRTUAL_SCREEN)
  538. case SET_VS_START:
  539. mach_info.wincon0 &= ~(S3C_WINCONx_ENWIN_F_ENABLE);
  540. __raw_writel(mach_info.wincon0|S3C_WINCONx_ENWIN_F_ENABLE|S3C_WINCONx_BUFAUTOEN_ENABLE, S3C_WINCON0); /* Double buffer auto enable bit */
  541. fbi->fb.var.xoffset = mach_info.xoffset;
  542. fbi->fb.var.yoffset = mach_info.yoffset;
  543. break;
  544. case SET_VS_STOP:
  545. break;
  546. case SET_VS_INFO:
  547. if(copy_from_user
  548. (&vs_info_from_app, (vs_info_t *) arg,
  549. sizeof(vs_info_t)))
  550. return -EFAULT;
  551. if(set_vs_info(vs_info_from_app)){
  552. // invalid value is input. so return Error
  553. return -EINVAL;
  554. }
  555. set_virtual_display_register(SET_VIRTUAL_LCD);
  556. fbi->fb.var.xoffset = mach_info.xoffset;
  557. fbi->fb.var.yoffset = mach_info.yoffset;
  558. break;
  559. case SET_VS_MOVE:
  560. set_virtual_display_register(arg);
  561. fbi->fb.var.xoffset = mach_info.xoffset;
  562. fbi->fb.var.yoffset = mach_info.yoffset;
  563. break;
  564. #endif
  565. case SET_OSD_INFO :
  566. if(copy_from_user
  567. (&win_info_from_app, (s3c_win_info_t *) arg,
  568. sizeof(s3c_win_info_t)))
  569. return -EFAULT;
  570. s3c_fb_init_win(fbi, win_info_from_app.Bpp,
  571. win_info_from_app.LeftTop_x, win_info_from_app.LeftTop_y, win_info_from_app.Width, win_info_from_app.Height, OFF);
  572. break;
  573. case SET_OSD_START :
  574. #if 0
  575. if(fbi->win_id==1){
  576. win_info_from_app.LeftTop_x=0;
  577. win_info_from_app.LeftTop_y=0;
  578. }
  579. else if(fbi->win_id==2){
  580. win_info_from_app.LeftTop_x=160;
  581. win_info_from_app.LeftTop_y=0;
  582. }
  583. else if(fbi->win_id==3){
  584. win_info_from_app.LeftTop_x=0;
  585. win_info_from_app.LeftTop_y=120;
  586. }
  587. else if(fbi->win_id==4){
  588. win_info_from_app.LeftTop_x=160;
  589. win_info_from_app.LeftTop_y=120;
  590. }
  591. win_info_from_app.Bpp=16;
  592. win_info_from_app.Width=160;
  593. win_info_from_app.Height=120;
  594. s3c_fb_init_win(fbi, win_info_from_app.Bpp,
  595. win_info_from_app.LeftTop_x, win_info_from_app.LeftTop_y, win_info_from_app.Width, win_info_from_app.Height, OFF);
  596. #endif
  597. #if 0
  598. win_info_from_app.LeftTop_x=0;
  599. win_info_from_app.LeftTop_y=0;
  600. win_info_from_app.Bpp=16;
  601. win_info_from_app.Width=100;
  602. win_info_from_app.Height=30;
  603. s3c_fb_init_win(fbi, win_info_from_app.Bpp,
  604. win_info_from_app.LeftTop_x, win_info_from_app.LeftTop_y, win_info_from_app.Width, win_info_from_app.Height, OFF);
  605. #endif
  606. s3c_fb_win_onoff(fbi, ON); // on
  607. break;
  608. case SET_OSD_STOP:
  609. s3c_fb_win_onoff(fbi, OFF); // off
  610. break;
  611. case SET_OSD_ALPHA_UP:
  612. if(osd_alpha_level < MAX_ALPHA_LEVEL) osd_alpha_level ++;
  613. s3c_fb_set_alpha_level(fbi);
  614. break;
  615. case SET_OSD_ALPHA_DOWN:
  616. if(osd_alpha_level > 0) osd_alpha_level --;
  617. s3c_fb_set_alpha_level(fbi);
  618. break;
  619. case SET_OSD_MOVE_LEFT:
  620. if(var->xoffset>0) var->xoffset--;
  621. s3c_fb_set_position_win(fbi, var->xoffset, var->yoffset, var->xres, var->yres);
  622. break;
  623. case SET_OSD_MOVE_RIGHT:
  624. if(var->xoffset < (H_RESOLUTION - var->xres)) var->xoffset ++;
  625. s3c_fb_set_position_win(fbi, var->xoffset, var->yoffset, var->xres, var->yres);
  626. break;
  627. case SET_OSD_MOVE_UP:
  628. if(var->yoffset>0) var->yoffset--;
  629. s3c_fb_set_position_win(fbi, var->xoffset, var->yoffset, var->xres, var->yres);
  630. break;
  631. case SET_OSD_MOVE_DOWN:
  632. if(var->yoffset < (V_RESOLUTION - var->yres)) var->yoffset ++;
  633. s3c_fb_set_position_win(fbi, var->xoffset, var->yoffset, var->xres, var->yres);
  634. break;
  635. #if defined(CONFIG_FB_DOUBLE_BUFFERING)
  636. case GET_FB_NUM:
  637. copy_from_user((void *)&f_num_val, (const void *)arg, sizeof(u_int));
  638. copy_to_user((void *)arg, (const void *) &f_num_val, sizeof(u_int));
  639. break;
  640. #endif
  641. #if defined(CONFIG_G3D)
  642. case S3C_FBIO_CHANGE_FB:
  643. if (copy_from_user(&value, (__user void *)arg, sizeof(int)))
  644. return(-EFAULT);
  645. currentDrawing = __raw_readl(S3C_WINCON0);
  646. currentDrawing = currentDrawing & (1<<20);
  647. sizeof_fb = var->xres_virtual * var->yres_virtual * (var->bits_per_pixel/8);
  648. start1 = (unsigned int)fbi->map_dma_f1;
  649. end1 = (start1+(unsigned int)sizeof_fb)&0x00ffffff;
  650. start2 = (unsigned int)fbi->map_dma_f1+sizeof_fb;
  651. end2 = (start2+(unsigned int)sizeof_fb)&0x00ffffff;
  652. start3 = (unsigned int)fbi->map_dma_f1+sizeof_fb+sizeof_fb;
  653. end3 = (start3+(unsigned int)sizeof_fb)&0x00ffffff;
  654. if(currentDrawing!=0)
  655. {
  656. TargetFBStartReg=S3C_VIDW00ADD0B0;
  657. TargetFBEndReg=S3C_VIDW00ADD1B0;
  658. TargetFBSel =__raw_readl(S3C_WINCON0);
  659. TargetFBSel = TargetFBSel & ~(1<<20);
  660. }
  661. else
  662. {
  663. TargetFBStartReg=S3C_VIDW00ADD0B1;
  664. TargetFBEndReg=S3C_VIDW00ADD1B1;
  665. TargetFBSel =__raw_readl(S3C_WINCON0);
  666. TargetFBSel = TargetFBSel | (1<<20);
  667. }
  668. if(value==0)
  669. {
  670. // printk("s3c_fb set fb0 Saddr=0x%x Eaddr=0x%x\n",start1,end1);
  671. __raw_writel(start1,TargetFBStartReg);
  672. __raw_writel(end1,TargetFBEndReg);
  673. __raw_writel(TargetFBSel,S3C_WINCON0);
  674. }
  675. else if(value==1)
  676. {
  677. // printk("s3c_fb set fb1 Saddr=0x%x Eaddr=0x%x\n",start2,end2);
  678. __raw_writel(start2,TargetFBStartReg);
  679. __raw_writel(end2,TargetFBEndReg);
  680. __raw_writel(TargetFBSel,S3C_WINCON0);
  681. }
  682. else
  683. {
  684. // printk("s3c_fb set fb2 Saddr=0x%x Eaddr=0x%x\n",start3,end3);
  685. __raw_writel(start3,TargetFBStartReg);
  686. __raw_writel(end3,TargetFBEndReg);
  687. __raw_writel(TargetFBSel,S3C_WINCON0);
  688. }
  689. break;
  690. #endif
  691. case SET_DISPLAY_BRIGHTNESS:
  692. if(copy_from_user(&brightness, (int *) arg, sizeof(int)))
  693. return -EFAULT;
  694. #if defined(CONFIG_S3C6400_PWM)
  695. set_brightness(brightness);
  696. #endif
  697. #if defined(CONFIG_S3C2443_PWM)
  698. set_brightness(brightness);
  699. #endif
  700. #if defined(CONFIG_S3C2450_PWM)
  701. set_brightness(brightness);
  702. #endif
  703. case GET_DISPLAY_BRIGHTNESS:
  704. if(copy_to_user((void *)arg, (const void *) &display_brightness, sizeof(int)))
  705. return -EFAULT;
  706. break;
  707. default:
  708. return -EINVAL;
  709. }
  710. return 0;
  711. }
  712. /*
  713. * s3c_fb_map_video_memory():
  714. * Allocates the DRAM memory for the frame buffer. This buffer is
  715. * remapped into a non-cached, non-buffered, memory region to
  716. * allow palette and pixel writes to occur without flushing the
  717. * cache. Once this area is remapped, all virtual memory
  718. * access to the video memory should occur at the new region.
  719. */
  720. int __init s3c_fb_map_video_memory(struct s3c_fb_info *fbi)
  721. {
  722. dprintk("map_video_memory(fbi=%p)\n", fbi);
  723. fbi->map_size_f1 = PAGE_ALIGN(fbi->fb.fix.smem_len + PAGE_SIZE);
  724. fbi->map_cpu_f1 = dma_alloc_writecombine(fbi->dev, fbi->map_size_f1,
  725. &fbi->map_dma_f1, GFP_KERNEL);
  726. fbi->map_size_f1 = fbi->fb.fix.smem_len;
  727. if (fbi->map_cpu_f1) {
  728. /* prevent initial garbage on screen */
  729. printk("Window[%d]- FB1 : map_video_memory: clear %p:%08x\n",
  730. fbi->win_id, fbi->map_cpu_f1, fbi->map_size_f1);
  731. memset(fbi->map_cpu_f1, 0xf0, fbi->map_size_f1);
  732. fbi->screen_dma_f1 = fbi->map_dma_f1;
  733. fbi->fb.screen_base = fbi->map_cpu_f1;
  734. fbi->fb.fix.smem_start = fbi->screen_dma_f1;
  735. printk(" FB1 : map_video_memory: dma=%08x cpu=%p size=%08x\n",
  736. fbi->map_dma_f1, fbi->map_cpu_f1, fbi->fb.fix.smem_len);
  737. }
  738. if( !fbi->map_cpu_f1)
  739. return -ENOMEM;
  740. #if !defined(CONFIG_FB_VIRTUAL_SCREEN) && defined(CONFIG_FB_DOUBLE_BUFFERING)
  741. #if defined(CONFIG_CPU_S3C2443)||defined(CONFIG_CPU_S3C2450)
  742. if(fbi->win_id<1){ // WIN0 support double-buffer
  743. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  744. if(fbi->win_id<2){ // WIN0, WIN1 support double-buffer
  745. #endif
  746. fbi->map_size_f2 = PAGE_ALIGN(fbi->fb.fix.smem_len + PAGE_SIZE);
  747. fbi->map_cpu_f2 = dma_alloc_writecombine(fbi->dev, fbi->map_size_f2,
  748. &fbi->map_dma_f2, GFP_KERNEL);
  749. fbi->map_size_f2 = fbi->fb.fix.smem_len;
  750. if (fbi->map_cpu_f2) {
  751. /* prevent initial garbage on screen */
  752. printk("Window[%d] - FB2 : map_video_memory: clear %p:%08x\n",
  753. fbi->win_id, fbi->map_cpu_f2, fbi->map_size_f2);
  754. memset(fbi->map_cpu_f2, 0xf0, fbi->map_size_f2);
  755. fbi->screen_dma_f2 = fbi->map_dma_f2;
  756. printk(" FB2 : map_video_memory: dma=%08x cpu=%p size=%08x\n",
  757. fbi->map_dma_f2, fbi->map_cpu_f2, fbi->fb.fix.smem_len);
  758. }
  759. if( !fbi->map_cpu_f2)
  760. return -ENOMEM;
  761. }
  762. #endif
  763. return 0;
  764. }
  765. void s3c_fb_unmap_video_memory(struct s3c_fb_info *fbi)
  766. {
  767. dma_free_writecombine(fbi->dev, fbi->map_size_f1, fbi->map_cpu_f1, fbi->map_dma_f1);
  768. #if !defined(CONFIG_FB_VIRTUAL_SCREEN) && defined(CONFIG_FB_DOUBLE_BUFFERING)
  769. dma_free_writecombine(fbi->dev, fbi->map_size_f2, fbi->map_cpu_f2, fbi->map_dma_f2);
  770. #endif
  771. }
  772. /*
  773. * s3c_fb_init_registers - Initialise all LCD-related registers
  774. */
  775. int s3c_fb_init_registers(struct s3c_fb_info *fbi)
  776. {
  777. u_long flags = 0;
  778. u_long PageWidth = 0, Offset = 0;
  779. int win_num = fbi->win_id;
  780. struct clk *lcd_clock;
  781. struct fb_var_screeninfo *var= &fbi->fb.var;
  782. unsigned long VideoPhysicalTemp_f1 = fbi->screen_dma_f1;
  783. unsigned long VideoPhysicalTemp_f2 = fbi->screen_dma_f2;
  784. /* Initialise LCD with values from hare */
  785. local_irq_save(flags);
  786. if(win_num==0){
  787. mach_info.vidcon0 = mach_info.vidcon0 & ~(S3C_VIDCON0_ENVID_ENABLE | S3C_VIDCON0_ENVID_F_ENABLE);
  788. __raw_writel(mach_info.vidcon0, S3C_VIDCON0);
  789. lcd_clock = clk_get(NULL, "lcd");
  790. mach_info.vidcon0 |= S3C_VIDCON0_CLKVAL_F((int)((clk_get_rate(lcd_clock) / LCD_PIXEL_CLOCK) - 1));
  791. }
  792. /* For buffer start address */
  793. __raw_writel(VideoPhysicalTemp_f1, S3C_VIDW00ADD0B0+(0x08*win_num));
  794. #if defined(CONFIG_CPU_S3C2443)||defined(CONFIG_CPU_S3C2450)
  795. if(win_num==0) __raw_writel(VideoPhysicalTemp_f2, S3C_VIDW00ADD0B1);
  796. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  797. if(win_num<2) __raw_writel(VideoPhysicalTemp_f2, S3C_VIDW00ADD0B1+(0x08*win_num));
  798. #endif
  799. #if defined(CONFIG_FB_VIRTUAL_SCREEN)
  800. if(win_num==0){
  801. mach_info.vidw00add0b0=VideoPhysicalTemp_f1;
  802. mach_info.vidw00add0b1=VideoPhysicalTemp_f2;
  803. }
  804. #endif
  805. PageWidth = var->xres * mach_info.bytes_per_pixel;
  806. Offset = (var->xres_virtual - var->xres) * mach_info.bytes_per_pixel;
  807. #if defined(CONFIG_FB_VIRTUAL_SCREEN)
  808. if(win_num==0) Offset=0;
  809. #endif
  810. /* End address */
  811. __raw_writel(S3C_VIDWxxADD1_VBASEL_F((unsigned long) VideoPhysicalTemp_f1 + (PageWidth + Offset) * (var->yres)),
  812. S3C_VIDW00ADD1B0+(0x08*win_num));
  813. #if defined(CONFIG_CPU_S3C2443)||defined(CONFIG_CPU_S3C2450)
  814. if(win_num==0)
  815. __raw_writel(S3C_VIDWxxADD1_VBASEL_F((unsigned long) VideoPhysicalTemp_f2 + (PageWidth + Offset) * (var->yres)),
  816. S3C_VIDW00ADD1B1);
  817. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  818. if(win_num<2)
  819. __raw_writel(S3C_VIDWxxADD1_VBASEL_F((unsigned long) VideoPhysicalTemp_f2 + (PageWidth + Offset) * (var->yres)),
  820. S3C_VIDW00ADD1B1+(0x08*win_num));
  821. #endif
  822. #if defined(CONFIG_FB_VIRTUAL_SCREEN)
  823. if(win_num==0){
  824. mach_info.vidw00add1b0=S3C_VIDWxxADD1_VBASEL_F((unsigned long) VideoPhysicalTemp_f1 + (PageWidth + Offset) * (var->yres));
  825. mach_info.vidw00add1b1=S3C_VIDWxxADD1_VBASEL_F((unsigned long) VideoPhysicalTemp_f2 + (PageWidth + Offset) * (var->yres));
  826. }
  827. #endif
  828. /* size of buffer */
  829. #if defined(CONFIG_CPU_S3C2443)||defined(CONFIG_CPU_S3C2450)
  830. __raw_writel(S3C_VIDWxxADD2_OFFSIZE_F(Offset) | (S3C_VIDWxxADD2_PAGEWIDTH_F(PageWidth)), S3C_VIDW00ADD2B0+(0x08*win_num));
  831. if(win_num==0) __raw_writel(S3C_VIDWxxADD2_OFFSIZE_F(Offset) | (S3C_VIDWxxADD2_PAGEWIDTH_F(PageWidth)), S3C_VIDW00ADD2B1);
  832. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  833. __raw_writel(S3C_VIDWxxADD2_OFFSIZE_F(Offset) | (S3C_VIDWxxADD2_PAGEWIDTH_F(PageWidth)), S3C_VIDW00ADD2+(0x04*win_num));
  834. #endif
  835. switch(win_num){
  836. case 0:
  837. __raw_writel(mach_info.wincon0, S3C_WINCON0);
  838. __raw_writel(mach_info.vidcon0, S3C_VIDCON0);
  839. __raw_writel(mach_info.vidcon1, S3C_VIDCON1);
  840. __raw_writel(mach_info.vidtcon0, S3C_VIDTCON0);
  841. __raw_writel(mach_info.vidtcon1, S3C_VIDTCON1);
  842. __raw_writel(mach_info.vidtcon2, S3C_VIDTCON2);
  843. #if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450)
  844. __raw_writel(mach_info.vidintcon, S3C_VIDINTCON);
  845. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  846. __raw_writel(mach_info.dithmode, S3C_DITHMODE);
  847. __raw_writel(mach_info.vidintcon0, S3C_VIDINTCON0);
  848. __raw_writel(mach_info.vidintcon1, S3C_VIDINTCON1);
  849. #endif
  850. __raw_writel(mach_info.vidosd0a, S3C_VIDOSD0A);
  851. __raw_writel(mach_info.vidosd0b, S3C_VIDOSD0B);
  852. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  853. __raw_writel(mach_info.vidosd0c, S3C_VIDOSD0C);
  854. #endif
  855. __raw_writel(mach_info.wpalcon, S3C_WPALCON);
  856. s3c_fb_win_onoff(fbi, ON);
  857. break;
  858. case 1:
  859. __raw_writel(mach_info.wincon1, S3C_WINCON1);
  860. __raw_writel(mach_info.vidosd1a, S3C_VIDOSD1A);
  861. __raw_writel(mach_info.vidosd1b, S3C_VIDOSD1B);
  862. __raw_writel(mach_info.vidosd1c, S3C_VIDOSD1C);
  863. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  864. __raw_writel(mach_info.vidosd1d, S3C_VIDOSD1D);
  865. #endif
  866. __raw_writel(mach_info.wpalcon, S3C_WPALCON);
  867. s3c_fb_win_onoff(fbi, OFF);
  868. break;
  869. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  870. case 2:
  871. __raw_writel(mach_info.wincon2, S3C_WINCON2);
  872. __raw_writel(mach_info.vidosd2a, S3C_VIDOSD2A);
  873. __raw_writel(mach_info.vidosd2b, S3C_VIDOSD2B);
  874. __raw_writel(mach_info.vidosd2c, S3C_VIDOSD2C);
  875. __raw_writel(mach_info.vidosd2d, S3C_VIDOSD2D);
  876. __raw_writel(mach_info.wpalcon, S3C_WPALCON);
  877. s3c_fb_win_onoff(fbi, OFF);
  878. break;
  879. case 3:
  880. __raw_writel(mach_info.wincon3, S3C_WINCON3);
  881. __raw_writel(mach_info.vidosd3a, S3C_VIDOSD3A);
  882. __raw_writel(mach_info.vidosd3b, S3C_VIDOSD3B);
  883. __raw_writel(mach_info.vidosd3c, S3C_VIDOSD3C);
  884. __raw_writel(mach_info.wpalcon, S3C_WPALCON);
  885. s3c_fb_win_onoff(fbi, OFF);
  886. break;
  887. case 4:
  888. __raw_writel(mach_info.wincon4, S3C_WINCON4);
  889. __raw_writel(mach_info.vidosd4a, S3C_VIDOSD4A);
  890. __raw_writel(mach_info.vidosd4b, S3C_VIDOSD4B);
  891. __raw_writel(mach_info.vidosd4c, S3C_VIDOSD4C);
  892. __raw_writel(mach_info.wpalcon, S3C_WPALCON);
  893. s3c_fb_win_onoff(fbi, OFF);
  894. break;
  895. #endif
  896. }
  897. local_irq_restore(flags);
  898. return 0;
  899. }
  900. /* s3c_fb_set_lcdaddr
  901. *
  902. * initialise lcd controller address pointers
  903. */
  904. void s3c_fb_set_lcdaddr(struct s3c_fb_info *fbi)
  905. {
  906. #if 0
  907. struct fb_var_screeninfo *var = &fbi->fb.var;
  908. unsigned long VideoPhysicalTemp_f1 = fbi->screen_dma_f1;
  909. unsigned long VideoPhysicalTemp_f2 = fbi->screen_dma_f2;
  910. /* For buffer start address */
  911. mach_info.vidw00add0b0 = VideoPhysicalTemp_f1;
  912. mach_info.vidw00add0b1 = VideoPhysicalTemp_f2;
  913. __raw_writel(mach_info.vidw00add0b0, S3C_VIDW00ADD0B0);
  914. __raw_writel(mach_info.vidw00add0b1, S3C_VIDW00ADD0B1);
  915. #endif
  916. }
  917. void s3c_fb_set_fb_change(int req_fb) {
  918. info[req_fb].fb_change_ready = 0;
  919. #if (defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450)) && defined(CONFIG_FB_DOUBLE_BUFFERING)
  920. // Software-based trigger
  921. __raw_writel((1<<0), S3C_CPUTRIGCON2);
  922. #elif (defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)) && defined(CONFIG_FB_DOUBLE_BUFFERING)
  923. // Software-based trigger
  924. __raw_writel((3<<0), S3C_TRIGCON);
  925. #endif // #if defined(CONFIG_CPU_S3C2443)
  926. }
  927. /* s3c_fb_activate_var
  928. *
  929. * activate (set) the controller from the given framebuffer
  930. * information
  931. */
  932. void s3c_fb_activate_var(struct s3c_fb_info *fbi,
  933. struct fb_var_screeninfo *var)
  934. {
  935. dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel);
  936. switch (var->bits_per_pixel) {
  937. case 8:
  938. mach_info.wincon0= S3C_WINCONx_BYTSWP_ENABLE | S3C_WINCONx_BURSTLEN_4WORD | S3C_WINCONx_BPPMODE_F_8BPP_PAL; // 4word burst, 8bpp-palletized,
  939. mach_info.wincon1= S3C_WINCONx_HAWSWP_ENABLE | S3C_WINCONx_BURSTLEN_4WORD | S3C_WINCONx_BPPMODE_F_16BPP_565 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1; // 4word burst, 16bpp for OSD
  940. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  941. mach_info.wincon2= S3C_WINCONx_HAWSWP_ENABLE | S3C_WINCONx_BURSTLEN_4WORD | S3C_WINCONx_BPPMODE_F_16BPP_565 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1; // 4word burst, 16bpp for OSD
  942. mach_info.wincon3= S3C_WINCONx_HAWSWP_ENABLE | S3C_WINCONx_BURSTLEN_4WORD | S3C_WINCONx_BPPMODE_F_16BPP_565 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1; // 4word burst, 16bpp for OSD
  943. mach_info.wincon4= S3C_WINCONx_HAWSWP_ENABLE | S3C_WINCONx_BURSTLEN_4WORD | S3C_WINCONx_BPPMODE_F_16BPP_565 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1; // 4word burst, 16bpp for OSD
  944. #endif
  945. mach_info.bpp= PIXEL_BPP8;
  946. mach_info.bytes_per_pixel= 1;
  947. #if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450)
  948. mach_info.wpalcon= S3C_WPALCON_W0PAL_24BIT;
  949. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  950. mach_info.wpalcon= S3C_WPALCON_W0PAL_16BIT;
  951. #endif
  952. break;
  953. case 16:
  954. mach_info.wincon0= S3C_WINCONx_HAWSWP_ENABLE | S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BPPMODE_F_16BPP_565; // 4word burst, 16bpp,
  955. mach_info.wincon1= S3C_WINCONx_HAWSWP_ENABLE | S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BPPMODE_F_16BPP_565 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1; //
  956. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  957. mach_info.wincon2= S3C_WINCONx_HAWSWP_ENABLE | S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BPPMODE_F_16BPP_565 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1; //
  958. mach_info.wincon3= S3C_WINCONx_HAWSWP_ENABLE | S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BPPMODE_F_16BPP_565 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1; //
  959. mach_info.wincon4= S3C_WINCONx_HAWSWP_ENABLE | S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BPPMODE_F_16BPP_565 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1; //
  960. #endif
  961. mach_info.bpp= PIXEL_BPP16;
  962. mach_info.bytes_per_pixel= 2;
  963. break;
  964. case 24:
  965. mach_info.wincon0= S3C_WINCONx_HAWSWP_DISABLE | S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BPPMODE_F_24BPP_888; // 4word burst, 24bpp,,
  966. mach_info.wincon1= S3C_WINCONx_HAWSWP_DISABLE | S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BPPMODE_F_24BPP_888 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1; // 4word burst, 24bpp for OSD
  967. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  968. mach_info.wincon2= S3C_WINCONx_HAWSWP_DISABLE | S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BPPMODE_F_24BPP_888 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1; // 4word burst, 24bpp for OSD
  969. mach_info.wincon3= S3C_WINCONx_HAWSWP_DISABLE | S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BPPMODE_F_24BPP_888 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1; // 4word burst, 24bpp for OSD
  970. mach_info.wincon4= S3C_WINCONx_HAWSWP_DISABLE | S3C_WINCONx_BURSTLEN_16WORD | S3C_WINCONx_BPPMODE_F_24BPP_888 | S3C_WINCONx_BLD_PIX_PLANE | S3C_WINCONx_ALPHA_SEL_1; // 4word burst, 24bpp for OSD
  971. #endif
  972. mach_info.bpp= PIXEL_BPP24;
  973. mach_info.bytes_per_pixel= 4;
  974. break;
  975. case 32:
  976. mach_info.bytes_per_pixel= 4;
  977. break;
  978. }
  979. /* write new registers */
  980. __raw_writel(mach_info.wincon0, S3C_WINCON0);
  981. __raw_writel(mach_info.wincon1, S3C_WINCON1);
  982. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  983. __raw_writel(mach_info.wincon2, S3C_WINCON2);
  984. __raw_writel(mach_info.wincon3, S3C_WINCON3);
  985. __raw_writel(mach_info.wincon4, S3C_WINCON4);
  986. #endif
  987. __raw_writel(mach_info.wpalcon, S3C_WPALCON);
  988. /* set lcd address pointers */
  989. #if 0
  990. s3c_fb_set_lcdaddr(fbi);
  991. #endif
  992. __raw_writel(mach_info.wincon0|S3C_WINCONx_ENWIN_F_ENABLE|S3C_WINCONx_BUFAUTOEN_ENABLE, S3C_WINCON0); /* Double buffer auto enable bit */
  993. __raw_writel(mach_info.vidcon0|S3C_VIDCON0_ENVID_ENABLE|S3C_VIDCON0_ENVID_F_ENABLE, S3C_VIDCON0);
  994. }
  995. int s3c_fb_init_win (struct s3c_fb_info *fbi, int Bpp, int LeftTop_x, int LeftTop_y, int Width, int Height, int OnOff)
  996. {
  997. s3c_fb_win_onoff(fbi, OFF); // off
  998. s3c_fb_set_bpp(fbi, Bpp);
  999. s3c_fb_set_position_win(fbi, LeftTop_x, LeftTop_y, Width, Height);
  1000. s3c_fb_set_size_win(fbi, Width, Height);
  1001. s3c_fb_set_memory_size_win(fbi);
  1002. // s3c_fb_set_alpha_mode(fbi, int Alpha_mode, int Alpha_level)
  1003. s3c_fb_win_onoff(fbi, OnOff); // off
  1004. return 0;
  1005. }
  1006. int s3c_fb_win_onoff(struct s3c_fb_info *fbi, int On)
  1007. {
  1008. int win_num = fbi->win_id;
  1009. if(On)
  1010. __raw_writel(__raw_readl(S3C_WINCON0+(0x04*win_num))|S3C_WINCONx_ENWIN_F_ENABLE,
  1011. S3C_WINCON0+(0x04*win_num)); // ON
  1012. else
  1013. __raw_writel(__raw_readl(S3C_WINCON0+(0x04*win_num))&~(S3C_WINCONx_ENWIN_F_ENABLE),
  1014. S3C_WINCON0+(0x04*win_num)); // OFF
  1015. return 0;
  1016. }
  1017. int s3c_fb_set_alpha_level(struct s3c_fb_info *fbi)
  1018. {
  1019. unsigned long alpha_val;
  1020. int win_num = fbi->win_id;
  1021. if(win_num==0){
  1022. printk("WIN0 do not support alpha blending.\n");
  1023. return -1;
  1024. }
  1025. alpha_val = S3C_VIDOSDxC_ALPHA1_B(osd_alpha_level) | S3C_VIDOSDxC_ALPHA1_G(osd_alpha_level) |S3C_VIDOSDxC_ALPHA1_R(osd_alpha_level);
  1026. #if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450)
  1027. __raw_writel(alpha_val, S3C_VIDOSD1C);
  1028. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  1029. __raw_writel(alpha_val, S3C_VIDOSD0C+(0x10*win_num));
  1030. #endif
  1031. return 0;
  1032. }
  1033. int s3c_fb_set_alpha_mode(struct s3c_fb_info *fbi, int Alpha_mode, int Alpha_level)
  1034. {
  1035. unsigned long alpha_val;
  1036. int win_num = fbi->win_id;
  1037. if(win_num==0){
  1038. printk("WIN0 do not support alpha blending.\n");
  1039. return -1;
  1040. }
  1041. switch(Alpha_mode){
  1042. case 0: // Plane Blending
  1043. __raw_writel(__raw_readl(S3C_WINCON0+(0x04*win_num))|S3C_WINCONx_BLD_PIX_PLANE,
  1044. S3C_WINCON0+(0x04*win_num));
  1045. break;
  1046. case 1: // Pixel Blending
  1047. __raw_writel(__raw_readl(S3C_WINCON0+(0x04*win_num))|S3C_WINCONx_BLD_PIX_PIXEL,
  1048. S3C_WINCON0+(0x04*win_num));
  1049. break;
  1050. }
  1051. osd_alpha_level = Alpha_level;
  1052. alpha_val = S3C_VIDOSDxC_ALPHA1_B(osd_alpha_level) | S3C_VIDOSDxC_ALPHA1_G(osd_alpha_level) |S3C_VIDOSDxC_ALPHA1_R(osd_alpha_level);
  1053. #if defined(CONFIG_CPU_S3C2443)||defined(CONFIG_CPU_S3C2450)
  1054. __raw_writel(alpha_val, S3C_VIDOSD1C);
  1055. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  1056. __raw_writel(alpha_val, S3C_VIDOSD0C+(0x10*win_num));
  1057. #endif
  1058. return 0;
  1059. }
  1060. #if 0
  1061. int s3c_fb_alpha_onoff(struct s3c_fb_info *fbi)
  1062. {
  1063. }
  1064. int s3c_fb_set_color_key(struct s3c_fb_info *fbi)
  1065. {
  1066. }
  1067. int s3c_fb_color_key_onoff(struct s3c_fb_info *fbi, int On)
  1068. {
  1069. int win_num = fbi->win_id;
  1070. if(On)
  1071. __raw_writel(__raw_readl(S3C_WINCON0+(0x04*win_num))|S3C_WINCONx_ENWIN_F_ENABLE,
  1072. S3C_WINCON0+(0x04*win_num)); // ON
  1073. else
  1074. __raw_writel(__raw_readl(S3C_WINCON0+(0x04*win_num))&~(S3C_WINCONx_ENWIN_F_ENABLE),
  1075. S3C_WINCON0+(0x04*win_num)); // OFF
  1076. }
  1077. int s3c_fb_set_color_key_level(struct s3c_fb_info *fbi)
  1078. {
  1079. unsigned long alpha_val;
  1080. int win_num = fbi->win_id;
  1081. if(win_num==0){
  1082. printk("WIN0 do not support color-key.\n");
  1083. return -1;
  1084. }
  1085. alpha_val = S3C_VIDOSDxC_ALPHA1_B(osd_alpha_level) | S3C_VIDOSDxC_ALPHA1_G(osd_alpha_level) |S3C_VIDOSDxC_ALPHA1_R(osd_alpha_level);
  1086. __raw_writel(alpha_val, S3C_VIDOSD0C+(0x10*win_num));
  1087. return 0;
  1088. }
  1089. #endif
  1090. int s3c_fb_set_position_win(struct s3c_fb_info *fbi, int LeftTop_x, int LeftTop_y, int Width, int Height)
  1091. {
  1092. struct fb_var_screeninfo *var= &fbi->fb.var;
  1093. int win_num = fbi->win_id;
  1094. if(win_num==0){
  1095. printk("WIN0 do not support window position control.\n");
  1096. return -1;
  1097. }
  1098. #if defined(CONFIG_CPU_S3C2443)||defined(CONFIG_CPU_S3C2450)
  1099. __raw_writel(S3C_VIDOSDxA_OSD_LTX_F(LeftTop_x) | S3C_VIDOSDxA_OSD_LTY_F(LeftTop_y),
  1100. S3C_VIDOSD0A+(0x0c*win_num));
  1101. __raw_writel(S3C_VIDOSDxB_OSD_RBX_F(Width-1 + LeftTop_x) | S3C_VIDOSDxB_OSD_RBY_F(Height-1 + LeftTop_y),
  1102. S3C_VIDOSD0B+(0x0c*win_num));
  1103. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  1104. __raw_writel(S3C_VIDOSDxA_OSD_LTX_F(LeftTop_x) | S3C_VIDOSDxA_OSD_LTY_F(LeftTop_y),
  1105. S3C_VIDOSD0A+(0x10*win_num));
  1106. __raw_writel(S3C_VIDOSDxB_OSD_RBX_F(Width-1 + LeftTop_x) | S3C_VIDOSDxB_OSD_RBY_F(Height-1 + LeftTop_y),
  1107. S3C_VIDOSD0B+(0x10*win_num));
  1108. #endif
  1109. var->xoffset=LeftTop_x;
  1110. var->yoffset=LeftTop_y;
  1111. return 0;
  1112. }
  1113. int s3c_fb_set_size_win(struct s3c_fb_info *fbi, int Width, int Height)
  1114. {
  1115. struct fb_var_screeninfo *var= &fbi->fb.var;
  1116. int win_num = fbi->win_id;
  1117. if(win_num==0){
  1118. printk("WIN0 do not support window size control.\n");
  1119. return -1;
  1120. }
  1121. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  1122. if(win_num==1)
  1123. __raw_writel(S3C_VIDOSD0C_OSDSIZE(Width*Height),S3C_VIDOSD1D);
  1124. else if(win_num==2)
  1125. __raw_writel(S3C_VIDOSD0C_OSDSIZE(Width*Height),S3C_VIDOSD2D);
  1126. #endif
  1127. var->xres = Width;
  1128. var->yres = Height;
  1129. var->xres_virtual = Width;
  1130. var->yres_virtual= Height;
  1131. return 0;
  1132. }
  1133. int s3c_fb_set_bpp(struct s3c_fb_info *fbi, int Bpp)
  1134. {
  1135. struct fb_var_screeninfo *var= &fbi->fb.var;
  1136. int win_num = fbi->win_id;
  1137. switch(Bpp){
  1138. case 1:
  1139. // What should I do???
  1140. break;
  1141. case 2:
  1142. // What should I do???
  1143. break;
  1144. case 4:
  1145. // What should I do???
  1146. break;
  1147. case 8:
  1148. // What should I do???
  1149. break;
  1150. case 16:
  1151. __raw_writel(__raw_readl(S3C_WINCON0+(0x04*win_num))|S3C_WINCONx_BPPMODE_F_16BPP_565,
  1152. S3C_WINCON0+(0x04*win_num));
  1153. var->bits_per_pixel=16;
  1154. break;
  1155. case 24:
  1156. __raw_writel(__raw_readl(S3C_WINCON0+(0x04*win_num))|S3C_WINCONx_BPPMODE_F_24BPP_888,
  1157. S3C_WINCON0+(0x04*win_num));
  1158. var->bits_per_pixel=24;
  1159. break;
  1160. case 32:
  1161. var->bits_per_pixel=32;
  1162. break;
  1163. }
  1164. return 0;
  1165. }
  1166. int s3c_fb_set_memory_size_win(struct s3c_fb_info *fbi)
  1167. {
  1168. struct fb_var_screeninfo *var= &fbi->fb.var;
  1169. int win_num = fbi->win_id;
  1170. unsigned long Offset = 0;
  1171. unsigned long PageWidth = 0;
  1172. unsigned long FrameBufferSize = 0;
  1173. PageWidth = var->xres * mach_info.bytes_per_pixel;
  1174. Offset = (var->xres_virtual - var->xres) * mach_info.bytes_per_pixel;
  1175. #if defined(CONFIG_FB_VIRTUAL_SCREEN)
  1176. if(win_num==0) Offset=0;
  1177. #endif
  1178. __raw_writel(S3C_VIDWxxADD1_VBASEL_F((unsigned long)__raw_readl(S3C_VIDW00ADD0B0+(0x08*win_num)) + (PageWidth + Offset) * (var->yres)),
  1179. S3C_VIDW00ADD1B0+(0x08*win_num));
  1180. if(win_num==1)
  1181. __raw_writel(S3C_VIDWxxADD1_VBASEL_F((unsigned long)__raw_readl(S3C_VIDW00ADD0B1+(0x08*win_num)) + (PageWidth + Offset) * (var->yres)),
  1182. S3C_VIDW00ADD1B1+(0x08*win_num));
  1183. /* size of frame buffer */
  1184. FrameBufferSize = S3C_VIDWxxADD2_OFFSIZE_F(Offset) | (S3C_VIDWxxADD2_PAGEWIDTH_F(PageWidth));
  1185. #if defined(CONFIG_CPU_S3C2443)||defined(CONFIG_CPU_S3C2450)
  1186. __raw_writel(FrameBufferSize, S3C_VIDW00ADD2B0+(0x08*win_num));
  1187. if(win_num==0)
  1188. __raw_writel(FrameBufferSize, S3C_VIDW00ADD2B1);
  1189. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  1190. __raw_writel(FrameBufferSize, S3C_VIDW00ADD2+(0x04*win_num));
  1191. #endif
  1192. return 0;
  1193. }
  1194. int s3c_fb_set_out_path(struct s3c_fb_info *fbi, int Path)
  1195. {
  1196. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  1197. switch(Path){
  1198. case 0: // RGB I/F
  1199. __raw_writel(__raw_readl(S3C_VIDCON0) | S3C_VIDCON0_VIDOUT_RGB_IF | S3C_VIDCON0_PNRMODE_RGB_P, S3C_VIDCON0);
  1200. break;
  1201. case 1: // TV Encoder T/F
  1202. __raw_writel(__raw_readl(S3C_VIDCON0) | S3C_VIDCON0_VIDOUT_TV, S3C_VIDCON0);
  1203. break;
  1204. case 2: // Indirect I80 I/F-0
  1205. __raw_writel(__raw_readl(S3C_VIDCON0) | S3C_VIDCON0_VIDOUT_I80IF0, S3C_VIDCON0);
  1206. break;
  1207. case 3: // Indirect I80 I/F-1
  1208. __raw_writel(__raw_readl(S3C_VIDCON0) | S3C_VIDCON0_VIDOUT_I80IF1, S3C_VIDCON0);
  1209. break;
  1210. case 4: // TV Encoder & RGB I/F
  1211. __raw_writel(__raw_readl(S3C_VIDCON0) | S3C_VIDCON0_VIDOUT_TVNRGBIF, S3C_VIDCON0);
  1212. break;
  1213. case 6: // TV Encoder & Indirect I80 I/F-0
  1214. __raw_writel(__raw_readl(S3C_VIDCON0) | S3C_VIDCON0_VIDOUT_TVNI80IF0, S3C_VIDCON0);
  1215. break;
  1216. case 7: // TV Encoder & Indirect I80 I/F-1
  1217. __raw_writel(__raw_readl(S3C_VIDCON0) | S3C_VIDCON0_VIDOUT_TVNI80IF1, S3C_VIDCON0);
  1218. break;
  1219. default: // RGB I/F
  1220. __raw_writel(__raw_readl(S3C_VIDCON0) | S3C_VIDCON0_VIDOUT_RGB_IF | S3C_VIDCON0_PNRMODE_RGB_P, S3C_VIDCON0);
  1221. break;
  1222. }
  1223. #endif
  1224. return 0;
  1225. }
  1226. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  1227. #define LCD_TV 1
  1228. // LCD display controller configuration functions
  1229. void s3c_fb_set_output_path(int out)
  1230. {
  1231. u32 tmp;
  1232. //printk("s3c_fb_set_output_path() called.\n");
  1233. tmp = __raw_readl(S3C_VIDCON0);
  1234. // if output mode is LCD mode, Scan mode always should be progressive mode
  1235. if(out == LCD_TV) {
  1236. tmp &=~(1<<29);
  1237. }
  1238. tmp &=~(0x7<<26);
  1239. tmp |= (out<<26);
  1240. __raw_writel(tmp, S3C_VIDCON0);
  1241. }
  1242. void s3c_fb_set_clkval(u32 clkval)
  1243. {
  1244. u32 tmp;
  1245. //printk("s3c_fb_set_clkval() called.\n");
  1246. tmp = __raw_readl(S3C_VIDCON0);
  1247. tmp &=~(0x1<<4);
  1248. tmp &=~(0xff<<6);
  1249. __raw_writel(tmp | (clkval<<6) | (1<<4), S3C_VIDCON0);
  1250. }
  1251. void s3c_fb_enable_rgbport(u32 on_off)
  1252. {
  1253. //printk("s3c_fb_enable_rgbport() called.\n");
  1254. if(on_off) //enable
  1255. __raw_writel(0x380, S3C_VIDCON2);
  1256. else //disable
  1257. __raw_writel(0x0, S3C_VIDCON2);
  1258. }
  1259. EXPORT_SYMBOL(s3c_fb_set_output_path);
  1260. EXPORT_SYMBOL(s3c_fb_set_clkval);
  1261. EXPORT_SYMBOL(s3c_fb_enable_rgbport);
  1262. #endif
  1263. void SetLcdPort(void)
  1264. {
  1265. unsigned long gpdat;
  1266. unsigned long gpcon;
  1267. unsigned long hclkcon; //, sclkcon;
  1268. #if defined(CONFIG_CPU_S3C2443)||defined(CONFIG_CPU_S3C2450)
  1269. //Enable clock to LCD
  1270. hclkcon = __raw_readl(S3C2443_HCLKCON);
  1271. hclkcon |= S3C2443_HCLKCON_LCDC;
  1272. __raw_writel(hclkcon, S3C2443_HCLKCON);
  1273. // To select TFT LCD type
  1274. gpdat = __raw_readl(S3C2410_MISCCR);
  1275. gpdat |= (1<<28);
  1276. __raw_writel(gpdat, S3C2410_MISCCR);
  1277. __raw_writel(0xaaaaaaaa, S3C2410_GPCCON); // CTRL, VD[7:0]
  1278. __raw_writel(0xaaaaaaaa, S3C2410_GPDCON); // VD[23:8]
  1279. /* LCD Backlight Enable control */
  1280. gpcon = __raw_readl(S3C2410_GPBCON);
  1281. gpcon = (gpcon & ~(3<<6)) | (1<<6); // Backlight(GPB3) Enable control
  1282. __raw_writel(gpcon, S3C2410_GPBCON);
  1283. /* LCD Backlight ON */
  1284. gpdat = __raw_readl(S3C2410_GPBDAT);
  1285. gpdat |= (1<<3);
  1286. __raw_writel(gpdat, S3C2410_GPBDAT);
  1287. // LCD _nRESET control
  1288. gpcon = __raw_readl(S3C2410_GPBCON);
  1289. gpcon = (gpcon & ~(3<<2)) |(1<<2);
  1290. __raw_writel(gpcon, S3C2410_GPBCON);
  1291. gpdat = __raw_readl(S3C2410_GPBDAT);
  1292. gpdat |= (1<<1);
  1293. __raw_writel(gpdat, S3C2410_GPBDAT);
  1294. // LCD module reset
  1295. gpdat = __raw_readl(S3C2410_GPBDAT);
  1296. gpdat |= (1<<2);
  1297. __raw_writel(gpdat, S3C2410_GPBDAT);
  1298. gpdat = __raw_readl(S3C2410_GPBDAT);
  1299. gpdat &= ~(1<<2); // goes to LOW
  1300. __raw_writel(gpdat, S3C2410_GPBDAT);
  1301. mdelay(10);
  1302. gpdat = __raw_readl(S3C2410_GPBDAT);
  1303. gpdat |= (1<<2); // goes to HIGH
  1304. __raw_writel(gpdat, S3C2410_GPBDAT);
  1305. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  1306. //Must be '0' for Normal-path instead of By-pass
  1307. // (*(volatile unsigned *)0x7410800c)=0;
  1308. __raw_writel(0x0, S3C_HOSTIFB_MIFPCON); // VD[15:0]
  1309. //Enable clock to LCD
  1310. hclkcon = __raw_readl(S3C_HCLK_GATE);
  1311. hclkcon |= S3C_CLKCON_HCLK_LCD;
  1312. __raw_writel(hclkcon, S3C_HCLK_GATE);
  1313. // To select TFT LCD type (RGB I/F)
  1314. gpdat = __raw_readl(S3C_SPCON);
  1315. gpdat &= ~0x3;
  1316. gpdat |= (1<<0);
  1317. __raw_writel(gpdat, S3C_SPCON);
  1318. __raw_writel(0xaaaaaaaa, S3C_GPICON); // VD[15:0]
  1319. __raw_writel(0xaaaaaaaa, S3C_GPJCON); // VD[23:16], Ctrl
  1320. #if 1
  1321. /* Dummy code : remove to LCD pwm control (ryu)*/
  1322. /* LCD Backlight Enable control */
  1323. gpcon = __raw_readl(S3C_GPFCON);
  1324. gpcon = (gpcon & ~(3<<30)) | (1<<30); // Backlight(GPF15) Enable control
  1325. __raw_writel(gpcon, S3C_GPFCON);
  1326. /* LCD Backlight ON */
  1327. gpdat = __raw_readl(S3C_GPFDAT);
  1328. gpdat |= (1<<15);
  1329. __raw_writel(gpdat, S3C_GPFDAT);
  1330. #endif
  1331. // LCD _nRESET control
  1332. gpcon = __raw_readl(S3C_GPNCON);
  1333. gpcon = (gpcon & ~(3<<10)) |(1<<10);
  1334. __raw_writel(gpcon, S3C_GPNCON);
  1335. gpdat = __raw_readl(S3C_GPNDAT);
  1336. gpdat |= (1<<5);
  1337. __raw_writel(gpdat, S3C_GPNDAT);
  1338. mdelay(100);
  1339. gpdat = __raw_readl(S3C_GPNDAT);
  1340. gpdat |= (0<<5);
  1341. __raw_writel(gpdat, S3C_GPNDAT);
  1342. mdelay(10);
  1343. gpdat = __raw_readl(S3C_GPNDAT);
  1344. gpdat |= (1<<5);
  1345. __raw_writel(gpdat, S3C_GPNDAT);
  1346. mdelay(10);
  1347. s3c_gpio_cfgpin(S3C_GPC1, S3C_GPC1_OUTP);
  1348. s3c_gpio_cfgpin(S3C_GPC2, S3C_GPC2_OUTP);
  1349. s3c_gpio_cfgpin(S3C_GPC3, S3C_GPC3_OUTP);
  1350. s3c_gpio_pullup(S3C_GPC1, 0);
  1351. s3c_gpio_pullup(S3C_GPC2, 0);
  1352. s3c_gpio_pullup(S3C_GPC3, 0);
  1353. #endif
  1354. }
  1355. #if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450)
  1356. #define LCD_DEN (1<<14)
  1357. #define LCD_DSERI (1<<11)
  1358. #define LCD_DCLK (1<<10)
  1359. #define LCD_DEN_BIT 14
  1360. #define LCD_DSERI_BIT 11
  1361. #define LCD_DCLK_BIT 10
  1362. #define LCD_nRESET 1
  1363. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  1364. #define LCD_DEN (1<<3)
  1365. #define LCD_DSERI (1<<2)
  1366. #define LCD_DCLK (1<<1)
  1367. #define LCD_DEN_BIT 3
  1368. #define LCD_DSERI_BIT 2
  1369. #define LCD_DCLK_BIT 1
  1370. #define LCD_nRESET 5
  1371. #endif
  1372. #define LCD_RESET (0)
  1373. #define LCD_RESET_Lo (0)
  1374. #define LCD_RESET_Hi (1)
  1375. #if defined(CONFIG_CPU_S3C2443)||defined(CONFIG_CPU_S3C2450)
  1376. #define LCD_DEN_Lo { gpdat = __raw_readl(S3C2443_GPLDAT); \
  1377. gpdat &= ~LCD_DEN; \
  1378. __raw_writel(gpdat, S3C2443_GPLDAT); \
  1379. }
  1380. #define LCD_DEN_Hi { gpdat = __raw_readl(S3C2443_GPLDAT); \
  1381. gpdat |= LCD_DEN; \
  1382. __raw_writel(gpdat, S3C2443_GPLDAT); \
  1383. }
  1384. #define LCD_DCLK_Lo { gpdat = __raw_readl(S3C2443_GPLDAT); \
  1385. gpdat &= ~LCD_DCLK; \
  1386. __raw_writel(gpdat, S3C2443_GPLDAT); \
  1387. }
  1388. #define LCD_DCLK_Hi { gpdat = __raw_readl(S3C2443_GPLDAT); \
  1389. gpdat |= LCD_DCLK; \
  1390. __raw_writel(gpdat, S3C2443_GPLDAT); \
  1391. }
  1392. #define LCD_DSERI_Lo { gpdat = __raw_readl(S3C2443_GPLDAT); \
  1393. gpdat &= ~LCD_DSERI; \
  1394. __raw_writel(gpdat, S3C2443_GPLDAT); \
  1395. }
  1396. #define LCD_DSERI_Hi { gpdat = __raw_readl(S3C2443_GPLDAT); \
  1397. gpdat |= LCD_DSERI; \
  1398. __raw_writel(gpdat, S3C2443_GPLDAT); \
  1399. }
  1400. #define SET_LCD_DATA { gpdat= __raw_readl(S3C2443_GPLCON); \
  1401. gpdat &= ~(((3<<(LCD_DEN_BIT*2))) | ((3<<(LCD_DCLK_BIT*2))) | ((3<<(LCD_DSERI_BIT*2)))); \
  1402. gpdat |= (((1<<(LCD_DEN_BIT*2))) | ((1<<(LCD_DCLK_BIT*2))) | ((1<<(LCD_DSERI_BIT*2)))); \
  1403. __raw_writel(gpdat, S3C2443_GPLCON); \
  1404. gpfpu = __raw_readl(S3C2443_GPLUDP); \
  1405. gpfpu |= ~(((3<<(LCD_DEN_BIT*2))) | ((3<<(LCD_DCLK_BIT*2))) | ((3<<(LCD_DSERI_BIT*2)))); \
  1406. gpfpu |= (((2<<(LCD_DEN_BIT*2))) | ((2<<(LCD_DCLK_BIT*2))) | ((2<<(LCD_DSERI_BIT*2)))); \
  1407. __raw_writel(gpfpu, S3C2443_GPLUDP); \
  1408. }
  1409. #elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
  1410. #define LCD_DEN_Lo { gpdat = __raw_readl(S3C_GPCDAT); \
  1411. gpdat &= ~LCD_DEN; \
  1412. __raw_writel(gpdat, S3C_GPCDAT); \
  1413. }
  1414. #define LCD_DEN_Hi { gpdat = __raw_readl(S3C_GPCDAT); \
  1415. gpdat |= LCD_DEN; \
  1416. __raw_writel(gpdat, S3C_GPCDAT); \
  1417. }
  1418. #define LCD_DCLK_Lo { gpdat = __raw_readl(S3C_GPCDAT); \
  1419. gpdat &= ~LCD_DCLK; \
  1420. __raw_writel(gpdat, S3C_GPCDAT); \
  1421. }
  1422. #define LCD_DCLK_Hi { gpdat = __raw_readl(S3C_GPCDAT); \
  1423. gpdat |= LCD_DCLK; \
  1424. __raw_writel(gpdat, S3C_GPCDAT); \
  1425. }
  1426. #define LCD_DSERI_Lo { gpdat = __raw_readl(S3C_GPCDAT); \
  1427. gpdat &= ~LCD_DSERI; \
  1428. __raw_writel(gpdat, S3C_GPCDAT); \
  1429. }
  1430. #define LCD_DSERI_Hi { gpdat = __raw_readl(S3C_GPCDAT); \
  1431. gpdat |= LCD_DSERI; \
  1432. __raw_writel(gpdat, S3C_GPCDAT); \
  1433. }
  1434. #define SET_LCD_DATA { gpdat= __raw_readl(S3C_GPCCON); \
  1435. gpdat &= ~(((0xF<<(LCD_DEN_BIT*4))) | ((0xF<<(LCD_DCLK_BIT*4))) | ((0xF<<(LCD_DSERI_BIT*4)))); \
  1436. gpdat |= (((1<<(LCD_DEN_BIT*4))) | ((1<<(LCD_DCLK_BIT*4))) | ((1<<(LCD_DSERI_BIT*4)))); \
  1437. __raw_writel(gpdat, S3C_GPCCON); \
  1438. gpfpu = __raw_readl(S3C_GPCPU); \
  1439. gpfpu &= ~(((3<<(LCD_DEN_BIT*2))) | ((3<<(LCD_DCLK_BIT*2))) | ((3<<(LCD_DSERI_BIT*2)))); \
  1440. __raw_writel(gpfpu, S3C_GPCPU); \
  1441. }
  1442. #endif
  1443. void LCD_SpiSendByte(u16 uData)
  1444. {
  1445. int j;
  1446. u8 delay=50;
  1447. unsigned long gpdat;
  1448. LCD_DEN_Hi; // CS(EN) -> High
  1449. LCD_DCLK_Hi; // SCL(DCLK) -> High
  1450. LCD_DSERI_Hi; // MOSI(DSERI) -> High
  1451. udelay(delay);
  1452. LCD_DEN_Lo;
  1453. udelay(delay);
  1454. for (j = 7; j >= 0; j--)
  1455. {
  1456. LCD_DCLK_Lo;
  1457. if ((uData >> j) & 0x0001)
  1458. {
  1459. LCD_DSERI_Hi;
  1460. }
  1461. else
  1462. {
  1463. LCD_DSERI_Lo;
  1464. }
  1465. udelay(delay);
  1466. LCD_DCLK_Hi;
  1467. udelay(delay);
  1468. }
  1469. LCD_DEN_Hi;
  1470. udelay(delay);
  1471. }
  1472. void WriteCmd(u16 uAddr, u16 uData)
  1473. {
  1474. u32 uMode = 0x8;
  1475. writel(uMode|0x01, S3C_SIFCCON0);
  1476. writel(uMode|0x03, S3C_SIFCCON0);
  1477. LCD_SpiSendByte(uAddr);
  1478. writel(uMode|0x01, S3C_SIFCCON0);
  1479. writel(uMode|0x00, S3C_SIFCCON0);
  1480. udelay(100);
  1481. writel(uMode|0x01, S3C_SIFCCON0);
  1482. writel(uMode|0x03, S3C_SIFCCON0);
  1483. LCD_SpiSendByte(uData);
  1484. writel(uMode|0x01, S3C_SIFCCON0);
  1485. writel(uMode|0x00, S3C_SIFCCON0);
  1486. }
  1487. void InitStartPosOnLcd(void)
  1488. {
  1489. // start addr setting
  1490. // WriteCmd(0x44, 0x00); // y addr 2
  1491. // WriteCmd(0x42, 0x00); // x addr
  1492. // WriteCmd(0x43, 0x00); // y addr 1
  1493. }
  1494. void Init_LDI(void)
  1495. {
  1496. u64 endtime;
  1497. printk(KERN_INFO "LCD TYPE :: S3C_LTS222QV LCD will be initialized\n");
  1498. SetLcdPort();
  1499. ///////////////////////////////////////////////////////////////////
  1500. // Power Setting Function 1
  1501. //////////////////////////////////////////////////////////////////
  1502. WriteCmd(0x22,0x01); // PARTIAL 2 DISPLAY AREA RASTER-ROW NUMBER REGISTER 1
  1503. WriteCmd(0x03,0x01); // RESET REGISTER
  1504. ///////////////////////////////////////////////////////////////////
  1505. // Initializing Function 1
  1506. ///////////////////////////////////////////////////////////////////
  1507. WriteCmd(0x00,0xa0); udelay(5); // CONTROL REGISTER 1, delay about 300ns
  1508. WriteCmd(0x01,0x10); udelay(5); // CONTROL REGISTER 2, delay about 300ns
  1509. WriteCmd(0x02,0x00); udelay(5); // RGB INTERFACE REGISTER
  1510. WriteCmd(0x05,0x00); udelay(5); // DATA ACCESS CONTROL REGISTER
  1511. WriteCmd(0x0D,0x00); endtime = get_jiffies_64() + 4; while(jiffies < endtime); // delay about 40ms
  1512. ///////////////////////////////////////////////////////////////////
  1513. // Initializing Function 2
  1514. ///////////////////////////////////////////////////////////////////
  1515. WriteCmd(0x0E,0x00); udelay(5); // delay about 300ns
  1516. WriteCmd(0x0F,0x00); udelay(5); // delay about 300ns
  1517. WriteCmd(0x10,0x00); udelay(5); // delay about 300ns
  1518. WriteCmd(0x11,0x00); udelay(5); // delay about 300ns
  1519. WriteCmd(0x12,0x00); udelay(5); // delay about 300ns
  1520. WriteCmd(0x13,0x00); udelay(5); // DISPLAY SIZE CONTROL REGISTER
  1521. WriteCmd(0x14,0x00); udelay(5); // PARTIAL-OFF AREA COLOR REGISTER 1
  1522. WriteCmd(0x15,0x00); udelay(5); // PARTIAL-OFF AREA COLOR REGISTER 2
  1523. WriteCmd(0x16,0x00); udelay(5); // PARTIAL 1 DISPLAY AREA STARTING REGISTER 1
  1524. WriteCmd(0x17,0x00); udelay(5); // PARTIAL 1 DISPLAY AREA STARTING REGISTER 2
  1525. WriteCmd(0x34,0x01); udelay(5); // POWER SUPPLY SYSTEM CONTROL REGISTER 14
  1526. WriteCmd(0x35,0x00); endtime = get_jiffies_64() + 4; while(jiffies < endtime); // POWER SUPPLY SYSTEM CONTROL REGISTER 7
  1527. ////////////////////////////////////////////////////////////////////
  1528. // Initializing Function 3
  1529. ////////////////////////////////////////////////////////////////////
  1530. WriteCmd(0x8D,0x01); udelay(5); // delay about 300ns
  1531. WriteCmd(0x8B,0x28); udelay(5); // delay about 300ns
  1532. WriteCmd(0x4B,0x00); udelay(5); // delay about 300ns
  1533. WriteCmd(0x4C,0x00); udelay(5); // delay about 300ns
  1534. WriteCmd(0x4D,0x00); udelay(5); // delay about 300ns
  1535. WriteCmd(0x4E,0x00); udelay(5); // delay about 300ns
  1536. WriteCmd(0x4F,0x00); udelay(5); // delay about 300ns
  1537. WriteCmd(0x50,0x00); endtime = get_jiffies_64() + 5; while(jiffies < endtime); // ID CODE REGISTER 2, Check it out, delay about 50 ms
  1538. WriteCmd(0x86,0x00); udelay(5); // delay about 300ns
  1539. WriteCmd(0x87,0x26); udelay(5); // delay about 300ns
  1540. WriteCmd(0x88,0x02); udelay(5); // delay about 300ns
  1541. WriteCmd(0x89,0x05); udelay(5); // delay about 300ns
  1542. WriteCmd(0x33,0x01); udelay(5); // POWER SUPPLY SYSTEM CONTROL REGISTER 13
  1543. WriteCmd(0x37,0x06); endtime = get_jiffies_64() + 5; while(jiffies < endtime); // POWER SUPPLY SYSTEM CONTROL REGISTER 12, Check it out
  1544. WriteCmd(0x76,0x00); endtime = get_jiffies_64() + 4; while(jiffies < endtime); // SCROLL AREA START REGISTER 2, delay about 30ms
  1545. /////////////////////////////////////////////////////////////////////
  1546. // Initializing Function 4
  1547. /////////////////////////////////////////////////////////////////////
  1548. WriteCmd(0x42,0x00); udelay(5); // delay about 300ns
  1549. WriteCmd(0x43,0x00); udelay(5); // delay about 300ns
  1550. WriteCmd(0x44,0x00); udelay(5); // delay about 300ns
  1551. WriteCmd(0x45,0x00); udelay(5); // CALIBRATION REGISTER
  1552. WriteCmd(0x46,0xef); udelay(5);
  1553. WriteCmd(0x47,0x00); udelay(5);
  1554. WriteCmd(0x48,0x00); udelay(5);
  1555. WriteCmd(0x49,0x01); endtime = get_jiffies_64() + 5; while(jiffies < endtime); // ID CODE REGISTER 1 check it out
  1556. WriteCmd(0x4A,0x3f); udelay(5); // delay about 300ns
  1557. WriteCmd(0x3C,0x00); udelay(5); // delay about 300ns
  1558. WriteCmd(0x3D,0x00); udelay(5); // delay about 300ns
  1559. WriteCmd(0x3E,0x01); udelay(5); // delay about 300ns
  1560. WriteCmd(0x3F,0x3f); udelay(5); // delay about 300ns
  1561. WriteCmd(0x40,0x01); udelay(5); // delay about 300ns, horizontal back porch, 050105 Boaz.Kim
  1562. // WriteCmd(0x40,0x02); udelay(1); // horizontal back porch //050105 Boaz.Kim
  1563. WriteCmd(0x41,0x0a); udelay(5); // vertical back porch
  1564. // WriteCmd(0x41,0x08); udelay(1); // vertical back porch
  1565. #if 0 /// 6.15
  1566. WriteCmd(0x8f, 0x05); udelay(400); // Gamma adjustment (upper amplitude-positive) (default: 0x05)
  1567. #else
  1568. WriteCmd(0x8F,0x3f); endtime = get_jiffies_64() + 4; while(jiffies < endtime); // this value is more comfortable to look
  1569. #endif
  1570. /////////////////////////////////////////////////////////////////////
  1571. // Initializing Function 5
  1572. /////////////////////////////////////////////////////////////////////
  1573. #if 0 /// 6.15 0->1
  1574. // Gamma adjustment regs
  1575. WriteCmd(0x90,0x05); udelay(5); // delay about 300ns
  1576. WriteCmd(0x91,0x44); udelay(5); // delay about 300ns
  1577. WriteCmd(0x92,0x44); udelay(5); // delay about 300ns
  1578. WriteCmd(0x93,0x44); udelay(5); // delay about 300ns
  1579. WriteCmd(0x94,0x33); udelay(5); // delay about 300ns
  1580. WriteCmd(0x95,0x05); udelay(5); // delay about 300ns
  1581. WriteCmd(0x96,0x05); udelay(5); // delay about 300ns
  1582. WriteCmd(0x97,0x44); udelay(5); // delay about 300ns
  1583. WriteCmd(0x98,0x44); udelay(5); // delay about 300ns
  1584. WriteCmd(0x99,0x44); udelay(5); // delay about 300ns
  1585. WriteCmd(0x9A,0x33); udelay(5); // delay about 300ns
  1586. WriteCmd(0x9B,0x33); udelay(5); // delay about 300ns
  1587. WriteCmd(0x9C,0x33); udelay(5); // delay about 300ns
  1588. #else // this value is more comfortable to look
  1589. WriteCmd(0x90,0x3f); udelay(5); // delay about 300ns
  1590. WriteCmd(0x91,0x33); udelay(5); // delay about 300ns
  1591. WriteCmd(0x92,0x77); udelay(5); // delay about 300ns
  1592. WriteCmd(0x93,0x77); udelay(5); // delay about 300ns
  1593. WriteCmd(0x94,0x17); udelay(5); // delay about 300ns
  1594. WriteCmd(0x95,0x3f); udelay(5); // delay about 300ns
  1595. WriteCmd(0x96,0x00); udelay(5); // delay about 300ns
  1596. WriteCmd(0x97,0x33); udelay(5); // delay about 300ns
  1597. WriteCmd(0x98,0x77); udelay(5); // delay about 300ns
  1598. WriteCmd(0x99,0x77); udelay(5); // delay about 300ns
  1599. WriteCmd(0x9A,0x17); udelay(5); // delay about 300ns
  1600. WriteCmd(0x9B,0x07); udelay(5); // delay about 300ns
  1601. WriteCmd(0x9C,0x07); udelay(5); // delay about 300ns
  1602. #endif
  1603. WriteCmd(0x9D,0x80); endtime = get_jiffies_64() + 4; while(jiffies < endtime); // 16 or 18bit RGB (BWS2="H": 16bit, BWS2="L": 18bit[default config in DualLcd b'd])
  1604. /////////////////////////////////////////////////////////////////////
  1605. // Power Setting 2
  1606. /////////////////////////////////////////////////////////////////////
  1607. WriteCmd(0x1D,0x08); endtime = get_jiffies_64() + 4; while(jiffies < endtime);// delay about 50 us
  1608. WriteCmd(0x23,0x00); endtime = get_jiffies_64() + 5; while(jiffies < endtime); // PARTIAL 2 DISPLAY AREA RASTER-ROW NUMBER REGISTER 2
  1609. WriteCmd(0x24,0x94); endtime = get_jiffies_64() + 5; while(jiffies < endtime); // POWER SUPPLY SYSTEM CONTROL REGISTER 1
  1610. WriteCmd(0x25,0x6f); endtime = get_jiffies_64() + 4; while(jiffies < endtime); // POWER SUPPLY SYSTEM CONTROL REGISTER 2
  1611. /////////////////////////////////////////////////////////////////////
  1612. // Power Setting 3
  1613. /////////////////////////////////////////////////////////////////////
  1614. WriteCmd(0x28,0x1e); //
  1615. WriteCmd(0x1A,0x00); //
  1616. WriteCmd(0x21,0x10); // PARTIAL 1 DISPLAY AREA RASTER-ROW NUMBER REGISTER 2
  1617. WriteCmd(0x18,0x25); // PARTIAL 2 DISPLAY AREA STARTING REGISTER 1
  1618. // delay about 40ms
  1619. endtime = get_jiffies_64() + 4; while(jiffies < endtime);
  1620. WriteCmd(0x19,0x48); // PARTIAL 2 DISPLAY AREA STARTING REGISTER 2
  1621. WriteCmd(0x18,0xe5); // PARTIAL 2 DISPLAY AREA STARTING REGISTER 1
  1622. // delay about 10ms
  1623. endtime = get_jiffies_64() + 4; while(jiffies < endtime);
  1624. WriteCmd(0x18,0xF7); // PARTIAL 2 DISPLAY AREA STARTING REGISTER 1
  1625. // delay about 40ms
  1626. endtime = get_jiffies_64() + 4; while(jiffies < endtime);
  1627. #if 0 /// 6.15 best look
  1628. WriteCmd(0x1B,0x07); // VS regulator ON at 4.5V
  1629. // delay about 40ms
  1630. endtime = get_jiffies_64() + 4; while(jiffies < endtime);
  1631. WriteCmd(0x1F,0x5a);
  1632. WriteCmd(0x20,0x54);
  1633. WriteCmd(0x1E,0xc1);
  1634. #elif 0 /// 6.15
  1635. WriteCmd(0x1B,0x01); // 0x01 - VS regulator ON at 3.5V // 0x03 - ON at 4.0V
  1636. // delay about 40ms
  1637. udelay(400);
  1638. WriteCmd(0x1F,0x5e); // Specify the VCOM1 amplitude between 0x33 and 0xb4.
  1639. WriteCmd(0x20,0x5f); // Specify the VCOM1 center voltage between 0x07 and 0xbd.
  1640. WriteCmd(0x1E,0xc1); // VCOM1: Normal operation, use the boosting circuit, use the extra CP1(twin CP1)
  1641. #else
  1642. WriteCmd(0x1B,0x07); // org
  1643. // delay about 80ms
  1644. endtime = get_jiffies_64() + 4; while(jiffies < endtime);
  1645. WriteCmd(0x1F,0x68); // Specify the VCOM1 amplitude between 0x33 and 0xb4.
  1646. WriteCmd(0x20,0x45); // Specify the VCOM1 center voltage between 0x07 and 0xbd.
  1647. WriteCmd(0x1E,0xc1); // VCOM1: Normal operation, use the boosting circuit, use the extra CP1(twin CP1)
  1648. #endif
  1649. // delay about 10ms
  1650. endtime = get_jiffies_64() + 4; while(jiffies < endtime);
  1651. WriteCmd(0x21,0x00); // PARTIAL 1 DISPLAY AREA RASTER-ROW NUMBER REGISTER 2
  1652. WriteCmd(0x3B,0x01); //
  1653. // delay about 20ms
  1654. endtime = get_jiffies_64() + 4; while(jiffies < endtime);
  1655. WriteCmd(0x00,0x20); // CONTROL REGISTER 1
  1656. WriteCmd(0x02,0x01); // RGB INTERFACE REGISTER
  1657. // delay about 10ms
  1658. endtime = get_jiffies_64() + 4; while(jiffies < endtime);
  1659. InitStartPosOnLcd();
  1660. }