hdmi_tx_hw.c 142 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331
  1. /*
  2. * Amlogic M3
  3. * frame buffer driver-----------HDMI_TX
  4. * Copyright (C) 2010 Amlogic, Inc.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the named License,
  9. * or any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. */
  17. #define HDMI_DEBUG() printk("HDMI DEBUG: %s [%d]\n", __FUNCTION__, __LINE__)
  18. #ifndef AVOS
  19. #include <linux/version.h>
  20. #include <linux/module.h>
  21. #include <linux/types.h>
  22. #include <linux/kernel.h>
  23. #include <linux/delay.h>
  24. #include <linux/interrupt.h>
  25. #include <linux/fs.h>
  26. #include <linux/init.h>
  27. #include <linux/device.h>
  28. #include <linux/mm.h>
  29. #include <linux/major.h>
  30. #include <linux/platform_device.h>
  31. #include <linux/mutex.h>
  32. #include <linux/cdev.h>
  33. //#include <linux/amports/canvas.h>
  34. #include <asm/uaccess.h>
  35. #include <asm/delay.h>
  36. #include <mach/am_regs.h>
  37. #include <mach/clock.h>
  38. #include <mach/power_gate.h>
  39. #include <linux/clk.h>
  40. #else
  41. #include "ioapi.h"
  42. #include <chipsupport/chipsupport.h>
  43. #include <os/extend/interrupt.h>
  44. #include <Drivers/include/peripheral_reg.h>
  45. #include <Drivers/include/isa_reg.h>
  46. #include <Drivers/include/mpeg_reg.h>
  47. #include <Drivers/include/venc_reg.h>
  48. #include <interrupt.h>
  49. #include "displaydev.h"
  50. #include "policy.h"
  51. #define printk(...)
  52. #define INT_HDMI_TX 25
  53. #endif
  54. #include "../hdmi_info_global.h"
  55. #include "../hdmi_tx_module.h"
  56. #include "hdmi_tx_reg.h"
  57. #include "tvenc_conf.h"
  58. //#define XTAL_24MHZ
  59. #ifdef Wr
  60. #undef Wr
  61. #endif
  62. #ifdef Rd
  63. #undef Rd
  64. #endif
  65. #define Wr(reg,val) WRITE_MPEG_REG(reg,val)
  66. #define Rd(reg) READ_MPEG_REG(reg)
  67. #define Wr_reg_bits(reg, val, start, len) \
  68. Wr(reg, (Rd(reg) & ~(((1L<<(len))-1)<<(start)))|((unsigned int)(val) << (start)))
  69. static void hdmi_audio_init(unsigned char spdif_flag);
  70. static void hdmitx_dump_tvenc_reg(int cur_VIC, int printk_flag);
  71. static void hdmi_suspend(void);
  72. static void hdmi_wakeup(void);
  73. #define CEC0_LOG_ADDR 0x4
  74. //#define HPD_DELAY_CHECK
  75. //#define CEC_SUPPORT
  76. //#define MORE_LOW_P
  77. #define LOG_EDID
  78. #ifdef CEC_SUPPORT
  79. static void cec_test_function(void);
  80. static irqreturn_t cec_handler(int irq, void *dev_instance);
  81. #endif
  82. #ifdef CONFIG_AML_HDMI_TX_HDCP
  83. static unsigned force_wrong=0;
  84. static int hdcpkey_status = -1;
  85. #endif
  86. extern int task_tx_key_setting(unsigned force_wrong);
  87. #define HDMI_M1A 'a'
  88. #define HDMI_M1B 'b'
  89. #define HDMI_M1C 'c'
  90. static unsigned char hdmi_chip_type = 0;
  91. unsigned char hdmi_pll_mode = 0; /* 1, use external clk as hdmi pll source */
  92. static unsigned char aud_para = 0x49;
  93. #define HSYNC_POLARITY 1 // HSYNC polarity: active high
  94. #define VSYNC_POLARITY 1 // VSYNC polarity: active high
  95. #define TX_INPUT_COLOR_DEPTH 0 // Pixel bit width: 0=24-bit; 1=30-bit; 2=36-bit; 3=48-bit.
  96. #define TX_INPUT_COLOR_FORMAT 1 // Pixel format: 0=RGB444; 1=YCbCr444; 2=Rsrv; 3=YCbCr422.
  97. #define TX_INPUT_COLOR_RANGE 0 // Pixel range: 0=16-235/240; 1=16-240; 2=1-254; 3=0-255.
  98. #define TX_OUTPUT_COLOR_RANGE 0 // Pixel range: 0=16-235/240; 1=16-240; 2=1-254; 3=0-255.
  99. #if 1
  100. //spdif
  101. #define TX_I2S_SPDIF 0 // 0=SPDIF; 1=I2S.
  102. #define TX_I2S_8_CHANNEL 0 // 0=I2S 2-channel; 1=I2S 4 x 2-channel.
  103. #else
  104. //i2s 8 channel
  105. #define TX_I2S_SPDIF 1 // 0=SPDIF; 1=I2S.
  106. #define TX_I2S_8_CHANNEL 1 // 0=I2S 2-channel; 1=I2S 4 x 2-channel.
  107. #endif
  108. #ifdef HPD_DELAY_CHECK
  109. static struct timer_list hpd_timer;
  110. #endif
  111. //static struct tasklet_struct EDID_tasklet;
  112. static unsigned delay_flag = 0;
  113. //#ifdef AML_A3
  114. //static unsigned serial_reg_val=0x24;
  115. //static unsigned char i2s_to_spdif_flag=1; //i2s clock in avos is div by 4 from amclk by audio driver, so use spdif
  116. //#else
  117. static unsigned serial_reg_val=0x1; //0x22;
  118. static unsigned char i2s_to_spdif_flag=0;
  119. //#endif
  120. static unsigned color_depth_f=0;
  121. static unsigned color_space_f=0;
  122. static unsigned char new_reset_sequence_flag=1;
  123. static unsigned char power_mode=1;
  124. static unsigned char power_off_vdac_flag=0;
  125. /* 0, do not use fixed tvenc val for all mode; 1, use fixed tvenc val mode for 480i; 2, use fixed tvenc val mode for all modes */
  126. static unsigned char use_tvenc_conf_flag=1;
  127. static unsigned char hpd_debug_mode=0;
  128. static unsigned char cur_vout_index = 1; //CONFIG_AM_TV_OUTPUT2
  129. #define HPD_DEBUG_IGNORE_UNPLUG 1
  130. static unsigned long modulo(unsigned long a, unsigned long b)
  131. {
  132. if (a >= b) {
  133. return(a-b);
  134. } else {
  135. return(a);
  136. }
  137. }
  138. static signed int to_signed(unsigned int a)
  139. {
  140. if (a <= 7) {
  141. return(a);
  142. } else {
  143. return(a-16);
  144. }
  145. }
  146. static void delay_us (int us)
  147. {
  148. #ifndef AVOS
  149. //udelay(us);
  150. if(delay_flag&0x1)
  151. mdelay((us+999)/1000);
  152. else
  153. udelay(us);
  154. #else
  155. //#define ISA_TIMERE IREG_TIMER_E_COUNT
  156. Wr(IREG_TIMER_E_COUNT,0);
  157. while(Rd(IREG_TIMER_E_COUNT)<us){}
  158. #endif
  159. } /* delay_us */
  160. #ifndef AVOS
  161. static irqreturn_t intr_handler(int irq, void *dev_instance)
  162. #else
  163. static void intr_handler(void *arg)
  164. #endif
  165. {
  166. unsigned int data32;
  167. #ifndef AVOS
  168. hdmitx_dev_t* hdmitx_device = (hdmitx_dev_t*)dev_instance;
  169. #else
  170. hdmitx_dev_t* hdmitx_device = (hdmitx_dev_t*)arg;
  171. #endif
  172. WRITE_MPEG_REG(HHI_GCLK_MPEG2, READ_MPEG_REG(HHI_GCLK_MPEG2) | (1<<4)); //Enable HDMI PCLK
  173. data32 = hdmi_rd_reg(OTHER_BASE_ADDR + HDMI_OTHER_INTR_STAT);
  174. hdmi_print(1,"HDMI irq %x\n",data32);
  175. if (data32 & (1 << 0)) { //HPD rising
  176. hdmi_wr_only_reg(OTHER_BASE_ADDR + HDMI_OTHER_INTR_STAT_CLR, 1 << 0); //clear HPD rising interrupt in hdmi module
  177. // If HPD asserts, then start DDC transaction
  178. #ifdef HPD_DELAY_CHECK
  179. del_timer(&hpd_timer);
  180. hpd_timer.expires = jiffies + HZ/2;
  181. add_timer(&hpd_timer);
  182. #else
  183. if (hdmi_rd_reg(TX_HDCP_ST_EDID_STATUS) & (1<<1)) {
  184. // Start DDC transaction
  185. #ifdef AML_A3
  186. hdmi_wr_reg(TX_HDCP_EDID_CONFIG, hdmi_rd_reg(TX_HDCP_EDID_CONFIG) | (1<<6)); // Assert sys_trigger_config
  187. #else
  188. hdmi_wr_reg(TX_HDCP_EDID_CONFIG, hdmi_rd_reg(TX_HDCP_EDID_CONFIG) | (1<<6)); // Assert sys_trigger_config
  189. //\\ Temporary mark.
  190. // hdmi_wr_reg(TX_HDCP_EDID_CONFIG, hdmi_rd_reg(TX_HDCP_EDID_CONFIG) & ~(1<<1)); // Release sys_trigger_config_semi_manu
  191. #endif
  192. hdmitx_device->cur_edid_block=0;
  193. hdmitx_device->cur_phy_block_ptr=0;
  194. hdmitx_device->hpd_event = 1;
  195. // Error if HPD deasserts
  196. } else {
  197. hdmi_print(1,"HDMI Error: HDMI HPD deasserts!\n");
  198. }
  199. #endif
  200. } else if (data32 & (1 << 1)) { //HPD falling
  201. if(hpd_debug_mode&HPD_DEBUG_IGNORE_UNPLUG){
  202. hdmi_wr_only_reg(OTHER_BASE_ADDR + HDMI_OTHER_INTR_STAT_CLR, 1 << 1); //clear HPD falling interrupt in hdmi module
  203. }
  204. else{
  205. hdmi_wr_only_reg(OTHER_BASE_ADDR + HDMI_OTHER_INTR_STAT_CLR, 1 << 1); //clear HPD falling interrupt in hdmi module
  206. #ifdef HPD_DELAY_CHECK
  207. del_timer(&hpd_timer);
  208. hpd_timer.expires = jiffies + HZ/2;
  209. add_timer(&hpd_timer);
  210. #else
  211. hdmi_wr_reg(TX_HDCP_EDID_CONFIG, hdmi_rd_reg(TX_HDCP_EDID_CONFIG) & ~(1<<6)); // Release sys_trigger_config
  212. hdmi_wr_reg(TX_HDCP_EDID_CONFIG, hdmi_rd_reg(TX_HDCP_EDID_CONFIG) | (1<<1)); // Assert sys_trigger_config_semi_manu
  213. hdmitx_device->hpd_event = 2;
  214. #endif
  215. }
  216. } else if (data32 & (1 << 2)) { //TX EDID interrupt
  217. if((hdmitx_device->cur_edid_block+2)<=EDID_MAX_BLOCK){
  218. int ii, jj;
  219. for(jj=0;jj<2;jj++){
  220. #ifdef LOG_EDID
  221. int edid_log_pos=0;
  222. edid_log_pos+=snprintf((char*)hdmitx_device->tmp_buf+edid_log_pos, HDMI_TMP_BUF_SIZE-edid_log_pos, "EDID Interrupt cur block %d:",hdmitx_device->cur_edid_block);
  223. #endif
  224. for(ii=0;ii<128;ii++){
  225. hdmitx_device->EDID_buf[hdmitx_device->cur_edid_block*128+ii]
  226. =hdmi_rd_reg(0x600+hdmitx_device->cur_phy_block_ptr*128+ii);
  227. #ifdef LOG_EDID
  228. if((ii&0xf)==0)
  229. edid_log_pos+=snprintf((char*)hdmitx_device->tmp_buf+edid_log_pos, HDMI_TMP_BUF_SIZE-edid_log_pos, "\n");
  230. edid_log_pos+=snprintf((char*)hdmitx_device->tmp_buf+edid_log_pos, HDMI_TMP_BUF_SIZE-edid_log_pos, "%02x ",hdmitx_device->EDID_buf[hdmitx_device->cur_edid_block*128+ii]);
  231. #endif
  232. }
  233. #ifdef LOG_EDID
  234. hdmitx_device->tmp_buf[edid_log_pos]=0;
  235. hdmi_print_buf((char*)hdmitx_device->tmp_buf, strlen((char*)hdmitx_device->tmp_buf));
  236. hdmi_print(0,"\n");
  237. #endif
  238. hdmitx_device->cur_edid_block++;
  239. hdmitx_device->cur_phy_block_ptr++;
  240. hdmitx_device->cur_phy_block_ptr=hdmitx_device->cur_phy_block_ptr&0x3;
  241. }
  242. }
  243. //#ifndef AML_A3
  244. // /*walkaround: manually clear EDID interrupt*/
  245. // hdmi_wr_reg(TX_HDCP_EDID_CONFIG, hdmi_rd_reg(TX_HDCP_EDID_CONFIG) | (1<<1));
  246. // hdmi_wr_reg(TX_HDCP_EDID_CONFIG, hdmi_rd_reg(TX_HDCP_EDID_CONFIG) & ~(1<<1));
  247. // /**/
  248. //#endif
  249. //tasklet_schedule(&EDID_tasklet);
  250. hdmi_wr_only_reg(OTHER_BASE_ADDR + HDMI_OTHER_INTR_STAT_CLR, 1 << 2); //clear EDID rising interrupt in hdmi module
  251. } else {
  252. hdmi_print(1,"HDMI Error: Unkown HDMI Interrupt source Process_Irq\n");
  253. hdmi_wr_only_reg(OTHER_BASE_ADDR + HDMI_OTHER_INTR_STAT_CLR, data32); //clear unkown interrupt in hdmi module
  254. }
  255. //#ifdef AML_A3
  256. hdmi_rd_reg(OTHER_BASE_ADDR + HDMI_OTHER_INTR_STAT_CLR); // A read to allow the interrupt cleared in hdmi_module before next action
  257. //#endif
  258. #ifndef AVOS
  259. Wr(A9_0_IRQ_IN1_INTR_STAT_CLR, 1 << 25); //clear hdmi_tx interrupt
  260. return IRQ_HANDLED;
  261. #else
  262. Wr(SYS_CPU_0_IRQ_IN1_INTR_STAT_CLR,(1 << INT_HDMI_TX));
  263. return ;
  264. #endif
  265. }
  266. static void hdmi_tvenc1080i_set(Hdmi_tx_video_para_t* param)
  267. {
  268. unsigned long VFIFO2VD_TO_HDMI_LATENCY = 2; // Annie 01Sep2011: Change value from 3 to 2, due to video encoder path delay change.
  269. unsigned long TOTAL_PIXELS, PIXEL_REPEAT_HDMI, PIXEL_REPEAT_VENC, ACTIVE_PIXELS;
  270. unsigned FRONT_PORCH, HSYNC_PIXELS, ACTIVE_LINES, INTERLACE_MODE, TOTAL_LINES, SOF_LINES, VSYNC_LINES;
  271. unsigned LINES_F0, LINES_F1,BACK_PORCH, EOF_LINES, TOTAL_FRAMES;
  272. unsigned long total_pixels_venc ;
  273. unsigned long active_pixels_venc;
  274. unsigned long front_porch_venc ;
  275. unsigned long hsync_pixels_venc ;
  276. unsigned long de_h_begin, de_h_end;
  277. unsigned long de_v_begin_even, de_v_end_even, de_v_begin_odd, de_v_end_odd;
  278. unsigned long hs_begin, hs_end;
  279. unsigned long vs_adjust;
  280. unsigned long vs_bline_evn, vs_eline_evn, vs_bline_odd, vs_eline_odd;
  281. unsigned long vso_begin_evn, vso_begin_odd;
  282. if(param->VIC==HDMI_1080i60){
  283. INTERLACE_MODE = 1;
  284. PIXEL_REPEAT_VENC = 1;
  285. PIXEL_REPEAT_HDMI = 0;
  286. ACTIVE_PIXELS = (1920*(1+PIXEL_REPEAT_HDMI)); // Number of active pixels per line.
  287. ACTIVE_LINES = (1080/(1+INTERLACE_MODE)); // Number of active lines per field.
  288. LINES_F0 = 562;
  289. LINES_F1 = 563;
  290. FRONT_PORCH = 88;
  291. HSYNC_PIXELS = 44;
  292. BACK_PORCH = 148;
  293. EOF_LINES = 2;
  294. VSYNC_LINES = 5;
  295. SOF_LINES = 15;
  296. TOTAL_FRAMES = 4;
  297. }
  298. else if(param->VIC==HDMI_1080i50){
  299. INTERLACE_MODE = 1;
  300. PIXEL_REPEAT_VENC = 1;
  301. PIXEL_REPEAT_HDMI = 0;
  302. ACTIVE_PIXELS = (1920*(1+PIXEL_REPEAT_HDMI)); // Number of active pixels per line.
  303. ACTIVE_LINES = (1080/(1+INTERLACE_MODE)); // Number of active lines per field.
  304. LINES_F0 = 562;
  305. LINES_F1 = 563;
  306. FRONT_PORCH = 528;
  307. HSYNC_PIXELS = 44;
  308. BACK_PORCH = 148;
  309. EOF_LINES = 2;
  310. VSYNC_LINES = 5;
  311. SOF_LINES = 15;
  312. TOTAL_FRAMES = 4;
  313. }
  314. TOTAL_PIXELS =(FRONT_PORCH+HSYNC_PIXELS+BACK_PORCH+ACTIVE_PIXELS); // Number of total pixels per line.
  315. TOTAL_LINES =(LINES_F0+(LINES_F1*INTERLACE_MODE)); // Number of total lines per frame.
  316. total_pixels_venc = (TOTAL_PIXELS / (1+PIXEL_REPEAT_HDMI)) * (1+PIXEL_REPEAT_VENC); // 2200 / 1 * 2 = 4400
  317. active_pixels_venc= (ACTIVE_PIXELS / (1+PIXEL_REPEAT_HDMI)) * (1+PIXEL_REPEAT_VENC); // 1920 / 1 * 2 = 3840
  318. front_porch_venc = (FRONT_PORCH / (1+PIXEL_REPEAT_HDMI)) * (1+PIXEL_REPEAT_VENC); // 88 / 1 * 2 = 176
  319. hsync_pixels_venc = (HSYNC_PIXELS / (1+PIXEL_REPEAT_HDMI)) * (1+PIXEL_REPEAT_VENC); // 44 / 1 * 2 = 88
  320. hdmi_print(0, "[ENCP_VIDEO_MODE:%x]=%x\n",ENCP_VIDEO_MODE, Rd(ENCP_VIDEO_MODE));
  321. Wr(ENCP_VIDEO_MODE,Rd(ENCP_VIDEO_MODE)|(1<<14)); // cfg_de_v = 1
  322. // Program DE timing
  323. hdmi_print(0, "[ENCP_VIDEO_HAVON_BEGIN:%x]=%x\n",ENCP_VIDEO_HAVON_BEGIN, Rd(ENCP_VIDEO_HAVON_BEGIN));
  324. de_h_begin = modulo(Rd(ENCP_VIDEO_HAVON_BEGIN) + VFIFO2VD_TO_HDMI_LATENCY, total_pixels_venc); // (383 + 3) % 4400 = 386
  325. de_h_end = modulo(de_h_begin + active_pixels_venc, total_pixels_venc); // (386 + 3840) % 4400 = 4226
  326. Wr(ENCP_DE_H_BEGIN, de_h_begin); // 386
  327. Wr(ENCP_DE_H_END, de_h_end); // 4226
  328. // Program DE timing for even field
  329. hdmi_print(0, "[ENCP_VIDEO_VAVON_BLINE:%x]=%x\n",ENCP_VIDEO_VAVON_BLINE, Rd(ENCP_VIDEO_VAVON_BLINE));
  330. de_v_begin_even = Rd(ENCP_VIDEO_VAVON_BLINE); // 20
  331. de_v_end_even = de_v_begin_even + ACTIVE_LINES; // 20 + 540 = 560
  332. Wr(ENCP_DE_V_BEGIN_EVEN,de_v_begin_even); // 20
  333. Wr(ENCP_DE_V_END_EVEN, de_v_end_even); // 560
  334. // Program DE timing for odd field if needed
  335. if (INTERLACE_MODE) {
  336. // Calculate de_v_begin_odd according to enc480p_timing.v:
  337. //wire[10:0] cfg_ofld_vavon_bline = {{7{ofld_vavon_ofst1 [3]}},ofld_vavon_ofst1 [3:0]} + cfg_video_vavon_bline + ofld_line;
  338. hdmi_print(0, "[ENCP_VIDEO_OFLD_VOAV_OFST:%x]=%x\n",ENCP_VIDEO_OFLD_VOAV_OFST, Rd(ENCP_VIDEO_OFLD_VOAV_OFST));
  339. de_v_begin_odd = to_signed((Rd(ENCP_VIDEO_OFLD_VOAV_OFST) & 0xf0)>>4) + de_v_begin_even + (TOTAL_LINES-1)/2; // 1 + 20 + (1125-1)/2 = 583
  340. de_v_end_odd = de_v_begin_odd + ACTIVE_LINES; // 583 + 540 = 1123
  341. Wr(ENCP_DE_V_BEGIN_ODD, de_v_begin_odd);// 583
  342. Wr(ENCP_DE_V_END_ODD, de_v_end_odd); // 1123
  343. }
  344. // Program Hsync timing
  345. if (de_h_end + front_porch_venc >= total_pixels_venc) {
  346. hs_begin = de_h_end + front_porch_venc - total_pixels_venc; // 4226 + 176 - 4400 = 2
  347. vs_adjust = 1;
  348. } else {
  349. hs_begin = de_h_end + front_porch_venc;
  350. vs_adjust = 0;
  351. }
  352. hs_end = modulo(hs_begin + hsync_pixels_venc, total_pixels_venc); // (2 + 88) % 4400 = 90
  353. Wr(ENCP_DVI_HSO_BEGIN, hs_begin); // 2
  354. Wr(ENCP_DVI_HSO_END, hs_end); // 90
  355. // Program Vsync timing for even field
  356. if (de_v_begin_even >= SOF_LINES + VSYNC_LINES + (1-vs_adjust)) {
  357. vs_bline_evn = de_v_begin_even - SOF_LINES - VSYNC_LINES - (1-vs_adjust); // 20 - 15 - 5 - 0 = 0
  358. } else {
  359. vs_bline_evn = TOTAL_LINES + de_v_begin_even - SOF_LINES - VSYNC_LINES - (1-vs_adjust);
  360. }
  361. vs_eline_evn = modulo(vs_bline_evn + VSYNC_LINES, TOTAL_LINES); // (0 + 5) % 1125 = 5
  362. Wr(ENCP_DVI_VSO_BLINE_EVN, vs_bline_evn); // 0
  363. Wr(ENCP_DVI_VSO_ELINE_EVN, vs_eline_evn); // 5
  364. vso_begin_evn = hs_begin; // 2
  365. Wr(ENCP_DVI_VSO_BEGIN_EVN, vso_begin_evn); // 2
  366. Wr(ENCP_DVI_VSO_END_EVN, vso_begin_evn); // 2
  367. // Program Vsync timing for odd field if needed
  368. if (INTERLACE_MODE) {
  369. vs_bline_odd = de_v_begin_odd-1 - SOF_LINES - VSYNC_LINES; // 583-1 - 15 - 5 = 562
  370. vs_eline_odd = de_v_begin_odd-1 - SOF_LINES; // 583-1 - 15 = 567
  371. vso_begin_odd = modulo(hs_begin + (total_pixels_venc>>1), total_pixels_venc); // (2 + 4400/2) % 4400 = 2202
  372. Wr(ENCP_DVI_VSO_BLINE_ODD, vs_bline_odd); // 562
  373. Wr(ENCP_DVI_VSO_ELINE_ODD, vs_eline_odd); // 567
  374. Wr(ENCP_DVI_VSO_BEGIN_ODD, vso_begin_odd); // 2202
  375. Wr(ENCP_DVI_VSO_END_ODD, vso_begin_odd); // 2202
  376. }
  377. // Annie 01Sep2011: Register VENC_DVI_SETTING and VENC_DVI_SETTING_MORE are no long valid, use VPU_HDMI_SETTING instead.
  378. Wr(VPU_HDMI_SETTING, (0 << 0) | // [ 0] src_sel_enci
  379. (0 << 1) | // [ 1] src_sel_encp
  380. (HSYNC_POLARITY << 2) | // [ 2] inv_hsync. 1=Invert Hsync polarity.
  381. (VSYNC_POLARITY << 3) | // [ 3] inv_vsync. 1=Invert Vsync polarity.
  382. (0 << 4) | // [ 4] inv_dvi_clk. 1=Invert clock to external DVI, (clock invertion exists at internal HDMI).
  383. (((TX_INPUT_COLOR_FORMAT==0)?1:0) << 5) | // [ 7: 5] data_comp_map. Input data is CrYCb(BRG), map the output data to desired format:
  384. // 0=output CrYCb(BRG);
  385. // 1=output YCbCr(RGB);
  386. // 2=output YCrCb(RBG);
  387. // 3=output CbCrY(GBR);
  388. // 4=output CbYCr(GRB);
  389. // 5=output CrCbY(BGR);
  390. // 6,7=Rsrv.
  391. #ifdef DOUBLE_CLK_720P_1080I
  392. (0 << 8) | // [11: 8] wr_rate. 0=A write every clk1; 1=A write every 2 clk1; ...; 15=A write every 16 clk1.
  393. #else
  394. (1 << 8) | // [11: 8] wr_rate. 0=A write every clk1; 1=A write every 2 clk1; ...; 15=A write every 16 clk1.
  395. #endif
  396. (0 <<12) // [15:12] rd_rate. 0=A read every clk2; 1=A read every 2 clk2; ...; 15=A read every 16 clk2.
  397. );
  398. Wr_reg_bits(VPU_HDMI_SETTING, 1, 1, 1); // [ 1] src_sel_encp: Enable ENCP output to HDMI
  399. }
  400. static void hdmi_tvenc480i_set(Hdmi_tx_video_para_t* param)
  401. {
  402. unsigned long VFIFO2VD_TO_HDMI_LATENCY = 1; // Annie 01Sep2011: Change value from 2 to 1, due to video encoder path delay change.
  403. unsigned long TOTAL_PIXELS, PIXEL_REPEAT_HDMI, PIXEL_REPEAT_VENC, ACTIVE_PIXELS;
  404. unsigned FRONT_PORCH, HSYNC_PIXELS, ACTIVE_LINES, INTERLACE_MODE, TOTAL_LINES, SOF_LINES, VSYNC_LINES;
  405. unsigned LINES_F0, LINES_F1,BACK_PORCH, EOF_LINES, TOTAL_FRAMES;
  406. unsigned long total_pixels_venc ;
  407. unsigned long active_pixels_venc;
  408. unsigned long front_porch_venc ;
  409. unsigned long hsync_pixels_venc ;
  410. unsigned long de_h_begin, de_h_end;
  411. unsigned long de_v_begin_even, de_v_end_even, de_v_begin_odd, de_v_end_odd;
  412. unsigned long hs_begin, hs_end;
  413. unsigned long vs_adjust;
  414. unsigned long vs_bline_evn, vs_eline_evn, vs_bline_odd, vs_eline_odd;
  415. unsigned long vso_begin_evn, vso_begin_odd;
  416. if((param->VIC==HDMI_480i60)||(param->VIC==HDMI_480i60_16x9)){
  417. INTERLACE_MODE = 1;
  418. PIXEL_REPEAT_VENC = 1;
  419. PIXEL_REPEAT_HDMI = 1;
  420. ACTIVE_PIXELS = (720*(1+PIXEL_REPEAT_HDMI)); // Number of active pixels per line.
  421. ACTIVE_LINES = (480/(1+INTERLACE_MODE)); // Number of active lines per field.
  422. LINES_F0 = 262;
  423. LINES_F1 = 263;
  424. FRONT_PORCH = 38;
  425. HSYNC_PIXELS = 124;
  426. BACK_PORCH = 114;
  427. EOF_LINES = 4;
  428. VSYNC_LINES = 3;
  429. SOF_LINES = 15;
  430. TOTAL_FRAMES = 4;
  431. }
  432. else if((param->VIC==HDMI_576i50)||(param->VIC==HDMI_576i50_16x9)){
  433. INTERLACE_MODE = 1;
  434. PIXEL_REPEAT_VENC = 1;
  435. PIXEL_REPEAT_HDMI = 1;
  436. ACTIVE_PIXELS = (720*(1+PIXEL_REPEAT_HDMI)); // Number of active pixels per line.
  437. ACTIVE_LINES = (576/(1+INTERLACE_MODE)); // Number of active lines per field.
  438. LINES_F0 = 312;
  439. LINES_F1 = 313;
  440. FRONT_PORCH = 24;
  441. HSYNC_PIXELS = 126;
  442. BACK_PORCH = 138;
  443. EOF_LINES = 2;
  444. VSYNC_LINES = 3;
  445. SOF_LINES = 19;
  446. TOTAL_FRAMES = 4;
  447. }
  448. TOTAL_PIXELS =(FRONT_PORCH+HSYNC_PIXELS+BACK_PORCH+ACTIVE_PIXELS); // Number of total pixels per line.
  449. TOTAL_LINES =(LINES_F0+(LINES_F1*INTERLACE_MODE)); // Number of total lines per frame.
  450. total_pixels_venc = (TOTAL_PIXELS / (1+PIXEL_REPEAT_HDMI)) * (1+PIXEL_REPEAT_VENC); // 1716 / 2 * 2 = 1716
  451. active_pixels_venc= (ACTIVE_PIXELS / (1+PIXEL_REPEAT_HDMI)) * (1+PIXEL_REPEAT_VENC); // 1440 / 2 * 2 = 1440
  452. front_porch_venc = (FRONT_PORCH / (1+PIXEL_REPEAT_HDMI)) * (1+PIXEL_REPEAT_VENC); // 38 / 2 * 2 = 38
  453. hsync_pixels_venc = (HSYNC_PIXELS / (1+PIXEL_REPEAT_HDMI)) * (1+PIXEL_REPEAT_VENC); // 124 / 2 * 2 = 124
  454. // Annie 01Sep2011: Comment out the following 2 lines. Because ENCP is not used for 480i and 576i.
  455. //hdmi_print(0, "[ENCP_VIDEO_MODE:%x]=%x\n",ENCP_VIDEO_MODE, Rd(ENCP_VIDEO_MODE));
  456. //Wr(ENCP_VIDEO_MODE,Rd(ENCP_VIDEO_MODE)|(1<<14)); // cfg_de_v = 1
  457. // Program DE timing
  458. // Annie 01Sep2011: for 480/576i, replace VFIFO2VD_PIXEL_START with ENCI_VFIFO2VD_PIXEL_START.
  459. hdmi_print(0, "[ENCI_VFIFO2VD_PIXEL_START:%x]=%x\n",ENCI_VFIFO2VD_PIXEL_START, Rd(ENCI_VFIFO2VD_PIXEL_START));
  460. de_h_begin = modulo(Rd(ENCI_VFIFO2VD_PIXEL_START) + VFIFO2VD_TO_HDMI_LATENCY, total_pixels_venc); // (233 + 2) % 1716 = 235
  461. de_h_end = modulo(de_h_begin + active_pixels_venc, total_pixels_venc); // (235 + 1440) % 1716 = 1675
  462. Wr(ENCI_DE_H_BEGIN, de_h_begin); // 235
  463. Wr(ENCI_DE_H_END, de_h_end); // 1675
  464. // Annie 01Sep2011: for 480/576i, replace VFIFO2VD_LINE_TOP/BOT_START with ENCI_VFIFO2VD_LINE_TOP/BOT_START.
  465. hdmi_print(0, "[ENCI_VFIFO2VD_LINE_TOP_START:%x]=%x\n",ENCI_VFIFO2VD_LINE_TOP_START, Rd(ENCI_VFIFO2VD_LINE_TOP_START));
  466. hdmi_print(0, "[ENCI_VFIFO2VD_LINE_BOT_START:%x]=%x\n",ENCI_VFIFO2VD_LINE_BOT_START, Rd(ENCI_VFIFO2VD_LINE_BOT_START));
  467. de_v_begin_even = Rd(ENCI_VFIFO2VD_LINE_TOP_START); // 17
  468. de_v_end_even = de_v_begin_even + ACTIVE_LINES; // 17 + 240 = 257
  469. de_v_begin_odd = Rd(ENCI_VFIFO2VD_LINE_BOT_START); // 18
  470. de_v_end_odd = de_v_begin_odd + ACTIVE_LINES; // 18 + 480/2 = 258
  471. Wr(ENCI_DE_V_BEGIN_EVEN,de_v_begin_even); // 17
  472. Wr(ENCI_DE_V_END_EVEN, de_v_end_even); // 257
  473. Wr(ENCI_DE_V_BEGIN_ODD, de_v_begin_odd); // 18
  474. Wr(ENCI_DE_V_END_ODD, de_v_end_odd); // 258
  475. // Program Hsync timing
  476. if (de_h_end + front_porch_venc >= total_pixels_venc) {
  477. hs_begin = de_h_end + front_porch_venc - total_pixels_venc;
  478. vs_adjust = 1;
  479. } else {
  480. hs_begin = de_h_end + front_porch_venc; // 1675 + 38 = 1713
  481. vs_adjust = 0;
  482. }
  483. hs_end = modulo(hs_begin + hsync_pixels_venc, total_pixels_venc); // (1713 + 124) % 1716 = 121
  484. Wr(ENCI_DVI_HSO_BEGIN, hs_begin); // 1713
  485. Wr(ENCI_DVI_HSO_END, hs_end); // 121
  486. // Program Vsync timing for even field
  487. if (de_v_end_odd-1 + EOF_LINES + vs_adjust >= LINES_F1) {
  488. vs_bline_evn = de_v_end_odd-1 + EOF_LINES + vs_adjust - LINES_F1;
  489. vs_eline_evn = vs_bline_evn + VSYNC_LINES;
  490. Wr(ENCI_DVI_VSO_BLINE_EVN, vs_bline_evn);
  491. //vso_bline_evn_reg_wr_cnt ++;
  492. Wr(ENCI_DVI_VSO_ELINE_EVN, vs_eline_evn);
  493. //vso_eline_evn_reg_wr_cnt ++;
  494. Wr(ENCI_DVI_VSO_BEGIN_EVN, hs_begin);
  495. Wr(ENCI_DVI_VSO_END_EVN, hs_begin);
  496. } else {
  497. vs_bline_odd = de_v_end_odd-1 + EOF_LINES + vs_adjust; // 258-1 + 4 + 0 = 261
  498. Wr(ENCI_DVI_VSO_BLINE_ODD, vs_bline_odd); // 261
  499. //vso_bline_odd_reg_wr_cnt ++;
  500. Wr(ENCI_DVI_VSO_BEGIN_ODD, hs_begin); // 1713
  501. if (vs_bline_odd + VSYNC_LINES >= LINES_F1) {
  502. vs_eline_evn = vs_bline_odd + VSYNC_LINES - LINES_F1; // 261 + 3 - 263 = 1
  503. Wr(ENCI_DVI_VSO_ELINE_EVN, vs_eline_evn); // 1
  504. //vso_eline_evn_reg_wr_cnt ++;
  505. Wr(ENCI_DVI_VSO_END_EVN, hs_begin); // 1713
  506. } else {
  507. vs_eline_odd = vs_bline_odd + VSYNC_LINES;
  508. Wr(ENCI_DVI_VSO_ELINE_ODD, vs_eline_odd);
  509. //vso_eline_odd_reg_wr_cnt ++;
  510. Wr(ENCI_DVI_VSO_END_ODD, hs_begin);
  511. }
  512. }
  513. // Program Vsync timing for odd field
  514. if (de_v_end_even-1 + EOF_LINES + 1 >= LINES_F0) {
  515. vs_bline_odd = de_v_end_even-1 + EOF_LINES + 1 - LINES_F0;
  516. vs_eline_odd = vs_bline_odd + VSYNC_LINES;
  517. Wr(ENCI_DVI_VSO_BLINE_ODD, vs_bline_odd);
  518. //vso_bline_odd_reg_wr_cnt ++;
  519. Wr(ENCI_DVI_VSO_ELINE_ODD, vs_eline_odd);
  520. //vso_eline_odd_reg_wr_cnt ++;
  521. vso_begin_odd = modulo(hs_begin + (total_pixels_venc>>1), total_pixels_venc);
  522. Wr(ENCI_DVI_VSO_BEGIN_ODD, vso_begin_odd);
  523. Wr(ENCI_DVI_VSO_END_ODD, vso_begin_odd);
  524. } else {
  525. vs_bline_evn = de_v_end_even-1 + EOF_LINES + 1; // 257-1 + 4 + 1 = 261
  526. Wr(ENCI_DVI_VSO_BLINE_EVN, vs_bline_evn); // 261
  527. //vso_bline_evn_reg_wr_cnt ++;
  528. vso_begin_evn = modulo(hs_begin + (total_pixels_venc>>1), total_pixels_venc); // (1713 + 1716/2) % 1716 = 855
  529. Wr(ENCI_DVI_VSO_BEGIN_EVN, vso_begin_evn); // 855
  530. if (vs_bline_evn + VSYNC_LINES >= LINES_F0) {
  531. vs_eline_odd = vs_bline_evn + VSYNC_LINES - LINES_F0; // 261 + 3 - 262 = 2
  532. Wr(ENCI_DVI_VSO_ELINE_ODD, vs_eline_odd); // 2
  533. //vso_eline_odd_reg_wr_cnt ++;
  534. Wr(ENCI_DVI_VSO_END_ODD, vso_begin_evn); // 855
  535. } else {
  536. vs_eline_evn = vs_bline_evn + VSYNC_LINES;
  537. Wr(ENCI_DVI_VSO_ELINE_EVN, vs_eline_evn);
  538. //vso_eline_evn_reg_wr_cnt ++;
  539. Wr(ENCI_DVI_VSO_END_EVN, vso_begin_evn);
  540. }
  541. }
  542. // Check if there are duplicate or missing timing settings
  543. //if ((vso_bline_evn_reg_wr_cnt != 1) || (vso_bline_odd_reg_wr_cnt != 1) ||
  544. // (vso_eline_evn_reg_wr_cnt != 1) || (vso_eline_odd_reg_wr_cnt != 1)) {
  545. //stimulus_print("[TEST.C] Error: Multiple or missing timing settings on reg ENCI_DVI_VSO_B(E)LINE_EVN(ODD)!\n");
  546. //stimulus_finish_fail(1);
  547. //}
  548. // Annie 01Sep2011: Register VENC_DVI_SETTING and VENC_DVI_SETTING_MORE are no long valid, use VPU_HDMI_SETTING instead.
  549. Wr(VPU_HDMI_SETTING, (0 << 0) | // [ 0] src_sel_enci
  550. (0 << 1) | // [ 1] src_sel_encp
  551. (HSYNC_POLARITY << 2) | // [ 2] inv_hsync. 1=Invert Hsync polarity.
  552. (VSYNC_POLARITY << 3) | // [ 3] inv_vsync. 1=Invert Vsync polarity.
  553. (0 << 4) | // [ 4] inv_dvi_clk. 1=Invert clock to external DVI, (clock invertion exists at internal HDMI).
  554. (((TX_INPUT_COLOR_FORMAT==0)?1:0) << 5) | // [ 7: 5] data_comp_map. Input data is CrYCb(BRG), map the output data to desired format:
  555. // 0=output CrYCb(BRG);
  556. // 1=output YCbCr(RGB);
  557. // 2=output YCrCb(RBG);
  558. // 3=output CbCrY(GBR);
  559. // 4=output CbYCr(GRB);
  560. // 5=output CrCbY(BGR);
  561. // 6,7=Rsrv.
  562. (1 << 8) | // [11: 8] wr_rate. 0=A write every clk1; 1=A write every 2 clk1; ...; 15=A write every 16 clk1.
  563. (1 <<12) // [15:12] rd_rate. 0=A read every clk2; 1=A read every 2 clk2; ...; 15=A read every 16 clk2.
  564. );
  565. Wr_reg_bits(VPU_HDMI_SETTING, 1, 0, 1); // [ 0] src_sel_enci: Enable ENCI output to HDMI
  566. }
  567. #ifndef AVOS
  568. static
  569. #endif
  570. void hdmi_tvenc_set(Hdmi_tx_video_para_t *param)
  571. {
  572. unsigned long VFIFO2VD_TO_HDMI_LATENCY = 2; // Annie 01Sep2011: Change value from 3 to 2, due to video encoder path delay change.
  573. unsigned long TOTAL_PIXELS, PIXEL_REPEAT_HDMI, PIXEL_REPEAT_VENC, ACTIVE_PIXELS;
  574. unsigned FRONT_PORCH, HSYNC_PIXELS, ACTIVE_LINES, INTERLACE_MODE, TOTAL_LINES, SOF_LINES, VSYNC_LINES;
  575. unsigned LINES_F0, LINES_F1,BACK_PORCH, EOF_LINES, TOTAL_FRAMES;
  576. unsigned long total_pixels_venc ;
  577. unsigned long active_pixels_venc;
  578. unsigned long front_porch_venc ;
  579. unsigned long hsync_pixels_venc ;
  580. unsigned long de_h_begin, de_h_end;
  581. unsigned long de_v_begin_even, de_v_end_even, de_v_begin_odd, de_v_end_odd;
  582. unsigned long hs_begin, hs_end;
  583. unsigned long vs_adjust;
  584. unsigned long vs_bline_evn, vs_eline_evn, vs_bline_odd, vs_eline_odd;
  585. unsigned long vso_begin_evn, vso_begin_odd;
  586. if((param->VIC==HDMI_480p60)||(param->VIC==HDMI_480p60_16x9)){
  587. INTERLACE_MODE = 0;
  588. PIXEL_REPEAT_VENC = 1;
  589. PIXEL_REPEAT_HDMI = 0;
  590. ACTIVE_PIXELS = (720*(1+PIXEL_REPEAT_HDMI)); // Number of active pixels per line.
  591. ACTIVE_LINES = (480/(1+INTERLACE_MODE)); // Number of active lines per field.
  592. LINES_F0 = 525;
  593. LINES_F1 = 525;
  594. FRONT_PORCH = 16;
  595. HSYNC_PIXELS = 62;
  596. BACK_PORCH = 60;
  597. EOF_LINES = 9;
  598. VSYNC_LINES = 6;
  599. SOF_LINES = 30;
  600. TOTAL_FRAMES = 4;
  601. }
  602. else if((param->VIC==HDMI_576p50)||(param->VIC==HDMI_576p50_16x9)){
  603. INTERLACE_MODE = 0;
  604. PIXEL_REPEAT_VENC = 1;
  605. PIXEL_REPEAT_HDMI = 0;
  606. ACTIVE_PIXELS = (720*(1+PIXEL_REPEAT_HDMI)); // Number of active pixels per line.
  607. ACTIVE_LINES = (576/(1+INTERLACE_MODE)); // Number of active lines per field.
  608. LINES_F0 = 625;
  609. LINES_F1 = 625;
  610. FRONT_PORCH = 12;
  611. HSYNC_PIXELS = 64;
  612. BACK_PORCH = 68;
  613. EOF_LINES = 5;
  614. VSYNC_LINES = 5;
  615. SOF_LINES = 39;
  616. TOTAL_FRAMES = 4;
  617. }
  618. else if(param->VIC==HDMI_720p60){
  619. INTERLACE_MODE = 0;
  620. PIXEL_REPEAT_VENC = 1;
  621. PIXEL_REPEAT_HDMI = 0;
  622. ACTIVE_PIXELS = (1280*(1+PIXEL_REPEAT_HDMI)); // Number of active pixels per line.
  623. ACTIVE_LINES = (720/(1+INTERLACE_MODE)); // Number of active lines per field.
  624. LINES_F0 = 750;
  625. LINES_F1 = 750;
  626. FRONT_PORCH = 110;
  627. HSYNC_PIXELS = 40;
  628. BACK_PORCH = 220;
  629. EOF_LINES = 5;
  630. VSYNC_LINES = 5;
  631. SOF_LINES = 20;
  632. TOTAL_FRAMES = 4;
  633. }
  634. else if(param->VIC==HDMI_720p50){
  635. INTERLACE_MODE = 0;
  636. PIXEL_REPEAT_VENC = 1;
  637. PIXEL_REPEAT_HDMI = 0;
  638. ACTIVE_PIXELS = (1280*(1+PIXEL_REPEAT_HDMI)); // Number of active pixels per line.
  639. ACTIVE_LINES = (720/(1+INTERLACE_MODE)); // Number of active lines per field.
  640. LINES_F0 = 750;
  641. LINES_F1 = 750;
  642. FRONT_PORCH = 440;
  643. HSYNC_PIXELS = 40;
  644. BACK_PORCH = 220;
  645. EOF_LINES = 5;
  646. VSYNC_LINES = 5;
  647. SOF_LINES = 20;
  648. TOTAL_FRAMES = 4;
  649. }
  650. else if(param->VIC==HDMI_1080p50){
  651. INTERLACE_MODE =0;
  652. PIXEL_REPEAT_VENC =0;
  653. PIXEL_REPEAT_HDMI =0;
  654. ACTIVE_PIXELS =(1920*(1+PIXEL_REPEAT_HDMI)); // Number of active pixels per line.
  655. ACTIVE_LINES =(1080/(1+INTERLACE_MODE)); // Number of active lines per field.
  656. LINES_F0 =1125;
  657. LINES_F1 =1125;
  658. FRONT_PORCH =528;
  659. HSYNC_PIXELS =44;
  660. BACK_PORCH =148;
  661. EOF_LINES =4;
  662. VSYNC_LINES =5;
  663. SOF_LINES =36;
  664. TOTAL_FRAMES =4;
  665. }
  666. else{ //HDMI_1080p60, HDMI_1080p30
  667. INTERLACE_MODE =0;
  668. PIXEL_REPEAT_VENC =0;
  669. PIXEL_REPEAT_HDMI =0;
  670. ACTIVE_PIXELS =(1920*(1+PIXEL_REPEAT_HDMI)); // Number of active pixels per line.
  671. ACTIVE_LINES =(1080/(1+INTERLACE_MODE)); // Number of active lines per field.
  672. LINES_F0 =1125;
  673. LINES_F1 =1125;
  674. FRONT_PORCH =88;
  675. HSYNC_PIXELS =44;
  676. BACK_PORCH =148;
  677. EOF_LINES =4;
  678. VSYNC_LINES =5;
  679. SOF_LINES =36;
  680. TOTAL_FRAMES =4;
  681. }
  682. TOTAL_PIXELS = (FRONT_PORCH+HSYNC_PIXELS+BACK_PORCH+ACTIVE_PIXELS); // Number of total pixels per line.
  683. TOTAL_LINES = (LINES_F0+(LINES_F1*INTERLACE_MODE)); // Number of total lines per frame.
  684. total_pixels_venc = (TOTAL_PIXELS / (1+PIXEL_REPEAT_HDMI)) * (1+PIXEL_REPEAT_VENC); // 858 / 1 * 2 = 1716
  685. active_pixels_venc= (ACTIVE_PIXELS / (1+PIXEL_REPEAT_HDMI)) * (1+PIXEL_REPEAT_VENC); // 720 / 1 * 2 = 1440
  686. front_porch_venc = (FRONT_PORCH / (1+PIXEL_REPEAT_HDMI)) * (1+PIXEL_REPEAT_VENC); // 16 / 1 * 2 = 32
  687. hsync_pixels_venc = (HSYNC_PIXELS / (1+PIXEL_REPEAT_HDMI)) * (1+PIXEL_REPEAT_VENC); // 62 / 1 * 2 = 124
  688. hdmi_print(0, "[ENCP_VIDEO_MODE:%x]=%x\n",ENCP_VIDEO_MODE, Rd(ENCP_VIDEO_MODE));
  689. Wr(ENCP_VIDEO_MODE,Rd(ENCP_VIDEO_MODE)|(1<<14)); // cfg_de_v = 1
  690. // Program DE timing
  691. hdmi_print(0, "[ENCP_VIDEO_HAVON_BEGIN:%x]=%x\n",ENCP_VIDEO_HAVON_BEGIN, Rd(ENCP_VIDEO_HAVON_BEGIN));
  692. de_h_begin = modulo(Rd(ENCP_VIDEO_HAVON_BEGIN) + VFIFO2VD_TO_HDMI_LATENCY, total_pixels_venc); // (217 + 3) % 1716 = 220
  693. de_h_end = modulo(de_h_begin + active_pixels_venc, total_pixels_venc); // (220 + 1440) % 1716 = 1660
  694. Wr(ENCP_DE_H_BEGIN, de_h_begin); // 220
  695. Wr(ENCP_DE_H_END, de_h_end); // 1660
  696. // Program DE timing for even field
  697. hdmi_print(0, "[ENCP_VIDEO_VAVON_BLINE:%x]=%x\n",ENCP_VIDEO_VAVON_BLINE, Rd(ENCP_VIDEO_VAVON_BLINE));
  698. de_v_begin_even = Rd(ENCP_VIDEO_VAVON_BLINE); // 42
  699. de_v_end_even = de_v_begin_even + ACTIVE_LINES; // 42 + 480 = 522
  700. Wr(ENCP_DE_V_BEGIN_EVEN,de_v_begin_even); // 42
  701. Wr(ENCP_DE_V_END_EVEN, de_v_end_even); // 522
  702. // Program DE timing for odd field if needed
  703. if (INTERLACE_MODE) {
  704. // Calculate de_v_begin_odd according to enc480p_timing.v:
  705. //wire[10:0] cfg_ofld_vavon_bline = {{7{ofld_vavon_ofst1 [3]}},ofld_vavon_ofst1 [3:0]} + cfg_video_vavon_bline + ofld_line;
  706. hdmi_print(0, "[ENCP_VIDEO_OFLD_VOAV_OFST:%x]=%x\n",ENCP_VIDEO_OFLD_VOAV_OFST, Rd(ENCP_VIDEO_OFLD_VOAV_OFST));
  707. de_v_begin_odd = to_signed((Rd(ENCP_VIDEO_OFLD_VOAV_OFST) & 0xf0)>>4) + de_v_begin_even + (TOTAL_LINES-1)/2;
  708. de_v_end_odd = de_v_begin_odd + ACTIVE_LINES;
  709. Wr(ENCP_DE_V_BEGIN_ODD, de_v_begin_odd);
  710. Wr(ENCP_DE_V_END_ODD, de_v_end_odd);
  711. }
  712. // Program Hsync timing
  713. if (de_h_end + front_porch_venc >= total_pixels_venc) {
  714. hs_begin = de_h_end + front_porch_venc - total_pixels_venc;
  715. vs_adjust = 1;
  716. } else {
  717. hs_begin = de_h_end + front_porch_venc; // 1660 + 32 = 1692
  718. vs_adjust = 0;
  719. }
  720. hs_end = modulo(hs_begin + hsync_pixels_venc, total_pixels_venc); // (1692 + 124) % 1716 = 100
  721. Wr(ENCP_DVI_HSO_BEGIN, hs_begin); // 1692
  722. Wr(ENCP_DVI_HSO_END, hs_end); // 100
  723. // Program Vsync timing for even field
  724. if (de_v_begin_even >= SOF_LINES + VSYNC_LINES + (1-vs_adjust)) {
  725. vs_bline_evn = de_v_begin_even - SOF_LINES - VSYNC_LINES - (1-vs_adjust); // 42 - 30 - 6 - 1 = 5
  726. } else {
  727. vs_bline_evn = TOTAL_LINES + de_v_begin_even - SOF_LINES - VSYNC_LINES - (1-vs_adjust);
  728. }
  729. vs_eline_evn = modulo(vs_bline_evn + VSYNC_LINES, TOTAL_LINES); // (5 + 6) % 525 = 11
  730. Wr(ENCP_DVI_VSO_BLINE_EVN, vs_bline_evn); // 5
  731. Wr(ENCP_DVI_VSO_ELINE_EVN, vs_eline_evn); // 11
  732. vso_begin_evn = hs_begin; // 1692
  733. Wr(ENCP_DVI_VSO_BEGIN_EVN, vso_begin_evn); // 1692
  734. Wr(ENCP_DVI_VSO_END_EVN, vso_begin_evn); // 1692
  735. // Program Vsync timing for odd field if needed
  736. if (INTERLACE_MODE) {
  737. vs_bline_odd = de_v_begin_odd-1 - SOF_LINES - VSYNC_LINES;
  738. vs_eline_odd = de_v_begin_odd-1 - SOF_LINES;
  739. vso_begin_odd = modulo(hs_begin + (total_pixels_venc>>1), total_pixels_venc);
  740. Wr(ENCP_DVI_VSO_BLINE_ODD, vs_bline_odd);
  741. Wr(ENCP_DVI_VSO_ELINE_ODD, vs_eline_odd);
  742. Wr(ENCP_DVI_VSO_BEGIN_ODD, vso_begin_odd);
  743. Wr(ENCP_DVI_VSO_END_ODD, vso_begin_odd);
  744. }
  745. // Annie 01Sep2011: Remove the following line as register VENC_DVI_SETTING_MORE is no long valid, use VPU_HDMI_SETTING instead.
  746. //Wr(VENC_DVI_SETTING_MORE, (TX_INPUT_COLOR_FORMAT==0)? 1 : 0); // [0] 0=Map data pins from Venc to Hdmi Tx as CrYCb mode;
  747. switch(param->VIC)
  748. {
  749. case HDMI_480p60:
  750. case HDMI_480p60_16x9:
  751. case HDMI_576p50:
  752. case HDMI_576p50_16x9:
  753. //Note: Hsync & Vsync polarity should be negative.
  754. //Refer to HDMI CTS 1.4A Page 169
  755. // Annie 01Sep2011: Register VENC_DVI_SETTING and VENC_DVI_SETTING_MORE are no long valid, use VPU_HDMI_SETTING instead.
  756. Wr(VPU_HDMI_SETTING, (0 << 0) | // [ 0] src_sel_enci
  757. (0 << 1) | // [ 1] src_sel_encp
  758. (0 << 2) | // [ 2] inv_hsync. 1=Invert Hsync polarity.
  759. (0 << 3) | // [ 3] inv_vsync. 1=Invert Vsync polarity.
  760. (0 << 4) | // [ 4] inv_dvi_clk. 1=Invert clock to external DVI, (clock invertion exists at internal HDMI).
  761. (((TX_INPUT_COLOR_FORMAT==0)?1:0) << 5) | // [ 7: 5] data_comp_map. Input data is CrYCb(BRG), map the output data to desired format:
  762. // 0=output CrYCb(BRG);
  763. // 1=output YCbCr(RGB);
  764. // 2=output YCrCb(RBG);
  765. // 3=output CbCrY(GBR);
  766. // 4=output CbYCr(GRB);
  767. // 5=output CrCbY(BGR);
  768. // 6,7=Rsrv.
  769. (1 << 8) | // [11: 8] wr_rate. 0=A write every clk1; 1=A write every 2 clk1; ...; 15=A write every 16 clk1.
  770. (0 <<12) // [15:12] rd_rate. 0=A read every clk2; 1=A read every 2 clk2; ...; 15=A read every 16 clk2.
  771. );
  772. break;
  773. case HDMI_720p60:
  774. case HDMI_720p50:
  775. // Annie 01Sep2011: Register VENC_DVI_SETTING and VENC_DVI_SETTING_MORE are no long valid, use VPU_HDMI_SETTING instead.
  776. Wr(VPU_HDMI_SETTING, (0 << 0) | // [ 0] src_sel_enci
  777. (0 << 1) | // [ 1] src_sel_encp
  778. (HSYNC_POLARITY << 2) | // [ 2] inv_hsync. 1=Invert Hsync polarity.
  779. (VSYNC_POLARITY << 3) | // [ 3] inv_vsync. 1=Invert Vsync polarity.
  780. (0 << 4) | // [ 4] inv_dvi_clk. 1=Invert clock to external DVI, (clock invertion exists at internal HDMI).
  781. (((TX_INPUT_COLOR_FORMAT==0)?1:0) << 5) | // [ 7: 5] data_comp_map. Input data is CrYCb(BRG), map the output data to desired format:
  782. // 0=output CrYCb(BRG);
  783. // 1=output YCbCr(RGB);
  784. // 2=output YCrCb(RBG);
  785. // 3=output CbCrY(GBR);
  786. // 4=output CbYCr(GRB);
  787. // 5=output CrCbY(BGR);
  788. // 6,7=Rsrv.
  789. #ifdef DOUBLE_CLK_720P_1080I
  790. (0 << 8) | // [11: 8] wr_rate. 0=A write every clk1; 1=A write every 2 clk1; ...; 15=A write every 16 clk1.
  791. #else
  792. (1 << 8) | // [11: 8] wr_rate. 0=A write every clk1; 1=A write every 2 clk1; ...; 15=A write every 16 clk1.
  793. #endif
  794. (0 <<12) // [15:12] rd_rate. 0=A read every clk2; 1=A read every 2 clk2; ...; 15=A read every 16 clk2.
  795. );
  796. break;
  797. default:
  798. // Annie 01Sep2011: Register VENC_DVI_SETTING and VENC_DVI_SETTING_MORE are no long valid, use VPU_HDMI_SETTING instead.
  799. Wr(VPU_HDMI_SETTING, (0 << 0) | // [ 0] src_sel_enci
  800. (0 << 1) | // [ 1] src_sel_encp
  801. (HSYNC_POLARITY << 2) | // [ 2] inv_hsync. 1=Invert Hsync polarity.
  802. (VSYNC_POLARITY << 3) | // [ 3] inv_vsync. 1=Invert Vsync polarity.
  803. (0 << 4) | // [ 4] inv_dvi_clk. 1=Invert clock to external DVI, (clock invertion exists at internal HDMI).
  804. (((TX_INPUT_COLOR_FORMAT==0)?1:0) << 5) | // [ 7: 5] data_comp_map. Input data is CrYCb(BRG), map the output data to desired format:
  805. // 0=output CrYCb(BRG);
  806. // 1=output YCbCr(RGB);
  807. // 2=output YCrCb(RBG);
  808. // 3=output CbCrY(GBR);
  809. // 4=output CbYCr(GRB);
  810. // 5=output CrCbY(BGR);
  811. // 6,7=Rsrv.
  812. (0 << 8) | // [11: 8] wr_rate. 0=A write every clk1; 1=A write every 2 clk1; ...; 15=A write every 16 clk1.
  813. (0 <<12) // [15:12] rd_rate. 0=A read every clk2; 1=A read every 2 clk2; ...; 15=A read every 16 clk2.
  814. );
  815. }
  816. // Annie 01Sep2011: Register VENC_DVI_SETTING and VENC_DVI_SETTING_MORE are no long valid, use VPU_HDMI_SETTING instead.
  817. Wr_reg_bits(VPU_HDMI_SETTING, 1, 1, 1); // [ 1] src_sel_encp: Enable ENCP output to HDMI
  818. }
  819. /*
  820. hdmi on/off
  821. */
  822. static int is_hpd_muxed(void)
  823. {
  824. int ret;
  825. //#ifdef AML_A3
  826. // ret = Rd(PERIPHS_PIN_MUX_0)&(1<<0);
  827. //#else
  828. // ret = Rd(PERIPHS_PIN_MUX_0)&(1<<1);
  829. //#endif
  830. ret = !!(Rd(PERIPHS_PIN_MUX_1)&(1<<22));
  831. return ret;
  832. }
  833. static void mux_hpd(void)
  834. {
  835. //#ifdef AML_A3
  836. // Wr(PERIPHS_PIN_MUX_0, Rd(PERIPHS_PIN_MUX_0)|(1 << 0)); // pm_gpioA_0_hdmi_hpd
  837. //#else
  838. // Wr(PERIPHS_PIN_MUX_0, Rd(PERIPHS_PIN_MUX_0)|(1 << 1)); // pm_hdmi_hpd_5v_en
  839. //#endif
  840. Wr(PERIPHS_PIN_MUX_1, Rd(PERIPHS_PIN_MUX_1)|(1 << 22));
  841. }
  842. static void unmux_hpd(void)
  843. {
  844. //#ifdef AML_A3
  845. // Wr(PERIPHS_PIN_MUX_0, Rd(PERIPHS_PIN_MUX_0)&(~(1<<0))); //use hpd as gpio
  846. //#else
  847. // //Wr(PERIPHS_PIN_MUX_0, Rd(PERIPHS_PIN_MUX_0)&(~(1 << 1))); //use hpd as gpio
  848. // Wr(PERIPHS_PIN_MUX_1, Rd(PERIPHS_PIN_MUX_1)&(~(1 <<22))); //use hpd as gpio
  849. //#endif
  850. // Wr(PREG_PAD_GPIO2_EN_N, Rd(PREG_PAD_GPIO2_EN_N)|(1<<0)); //GPIOA_0 as input
  851. Wr(PERIPHS_PIN_MUX_1, Rd(PERIPHS_PIN_MUX_1)&~(1 << 22));
  852. //GPIOC_10 0x2012[10]
  853. Wr(PREG_PAD_GPIO2_EN_N, Rd(PREG_PAD_GPIO2_EN_N)|(1<<10)); //GPIOC_10 as input
  854. }
  855. static int read_hpd_gpio(void)
  856. {
  857. int level;
  858. // level = Rd(PREG_PAD_GPIO2_I)&0x1; //read GPIOA_0
  859. level = !!(Rd(PREG_PAD_GPIO2_I)&(1<<10)); //read GPIOC_10
  860. return level;
  861. }
  862. #if 0
  863. static unsigned long clk81_rate = 100000000;
  864. static void clk81_set(void)
  865. {
  866. struct clk *clk_tmp;
  867. clk_tmp = clk_get_sys("clk81", NULL);
  868. if (clk_tmp)
  869. {
  870. clk81_rate = clk_get_rate(clk_tmp);
  871. clk_set_rate(clk_tmp, 168000000);
  872. CLEAR_AOBUS_REG_MASK(AO_UART_CONTROL, (1 << 19) | 0xFFF);
  873. WRITE_AOBUS_REG_BITS(AO_UART_CONTROL, ((168000000 / (115200 * 4)) - 1) & 0xfff, 0, 12);
  874. }
  875. msleep(2); //Waiting some time
  876. //printk("%s clk81_rate: %d\n", __FUNCTION__, clk81_rate);
  877. }
  878. static void clk81_resume(void)
  879. {
  880. struct clk *clk_tmp;
  881. clk_tmp = clk_get_sys("clk81", NULL);
  882. if (clk_tmp)
  883. {
  884. clk_set_rate(clk_tmp, clk81_rate);
  885. CLEAR_AOBUS_REG_MASK(AO_UART_CONTROL, (1 << 19) | 0xFFF);
  886. WRITE_AOBUS_REG_BITS(AO_UART_CONTROL, ((clk81_rate / (115200 * 4)) - 1) & 0xfff, 0, 12);
  887. }
  888. msleep(2); //Waiting some time
  889. //printk("%s clk81_rate: %d\n", __FUNCTION__, clk81_rate);
  890. }
  891. #endif
  892. static void digital_clk_off(unsigned char flag)
  893. {
  894. // clk81_resume();
  895. if(flag&1){
  896. //#ifdef AML_A3
  897. /* off hdmi audio clock */
  898. // hdmi_wr_reg(OTHER_BASE_ADDR + HDMI_OTHER_CTRL1, hdmi_rd_reg(OTHER_BASE_ADDR + HDMI_OTHER_CTRL1)&(~(1<<13))); //
  899. // hdmi_wr_reg(TX_AUDIO_FORMAT, hdmi_rd_reg(TX_AUDIO_FORMAT)|(1<<7));
  900. // hdmi_wr_reg(TX_AUDIO_I2S, hdmi_rd_reg(TX_AUDIO_I2S)|(1<<1));
  901. //#endif
  902. }
  903. if(flag&2){
  904. /* off hdmi pixel clock */
  905. // Wr(HHI_GCLK_MPEG2, Rd(HHI_GCLK_MPEG2)&(~(1<<4))); //disable pixel clock, set cbus reg HHI_GCLK_MPEG2 bit [4] = 0
  906. Wr(HHI_GCLK_OTHER, Rd(HHI_GCLK_OTHER)&(~(1<<17))); //disable VCLK1_HDMI GATE, set cbus reg HHI_GCLK_OTHER bit [17] = 0
  907. Wr(VENC_DVI_SETTING, (Rd(VENC_DVI_SETTING)&(~(7<<4)))|(5<<4)); //set cbus reg VENC_DVI_SETTING bit[6:4] = 0x5
  908. Wr(HHI_VID_PLL_CNTL, (Rd(HHI_VID_PLL_CNTL) | (1<<30))); //0x105c[30]PD, 1: PowerDown
  909. Wr(HHI_VID_PLL_CNTL3, (Rd(HHI_VID_PLL_CNTL3) & ~((1<<5)|(1<<3)))); //0x1058[5]VBG_PU [3]IREXT_PU
  910. #if 1
  911. // Second turn off gate.
  912. WRITE_MPEG_REG(HHI_GCLK_MPEG2, READ_MPEG_REG(HHI_GCLK_MPEG2) & (~(1<<4))); //Disable HDMI PCLK
  913. #endif
  914. }
  915. if(flag&4){
  916. /* off hdmi sys clock */
  917. Wr( HHI_HDMI_CLK_CNTL, Rd(HHI_HDMI_CLK_CNTL)&(~(1<<8))); // off hdmi sys clock gate
  918. }
  919. }
  920. static void digital_clk_on(unsigned char flag)
  921. {
  922. int i;
  923. // clk81_set();
  924. if(flag&4){
  925. /* on hdmi sys clock */
  926. //#ifdef AML_A3
  927. #if 1
  928. // -----------------------------------------
  929. // HDMI (90Mhz)
  930. // -----------------------------------------
  931. // .clk_div ( hi_hdmi_clk_cntl[6:0] ),
  932. // .clk_en ( hi_hdmi_clk_cntl[8] ),
  933. // .clk_sel ( hi_hdmi_clk_cntl[11:9]),
  934. Wr_reg_bits(HHI_HDMI_CLK_CNTL, 1, 8, 1);
  935. // Wr( HHI_HDMI_CLK_CNTL, ((2 << 9) | // select "misc" PLL
  936. // (1 << 8) | // Enable gated clock
  937. // (5 << 0)) ); // Divide the "other" PLL output by 6
  938. #else
  939. // -----------------------------------------
  940. // HDMI (90Mhz)
  941. // -----------------------------------------
  942. // .clk_div ( hi_hdmi_clk_cntl[6:0] ),
  943. // .clk_en ( hi_hdmi_clk_cntl[8] ),
  944. // .clk_sel ( hi_hdmi_clk_cntl[11:9]),
  945. Wr( HHI_HDMI_CLK_CNTL, ((1 << 9) | // select "other" PLL
  946. (1 << 8) | // Enable gated clock
  947. (5 << 0)) ); // Divide the "other" PLL output by 6
  948. #endif
  949. }
  950. if(flag&2){
  951. /* on hdmi pixel clock */
  952. #if 1
  953. WRITE_MPEG_REG(HHI_GCLK_MPEG2, READ_MPEG_REG(HHI_GCLK_MPEG2) | (1<<4)); //Enable HDMI PCLK
  954. Wr(HHI_VID_PLL_CNTL3, (Rd(HHI_VID_PLL_CNTL3) | ((1<<5)|(1<<3)))); //0x1058[5]VBG_PU [3]IREXT_PU
  955. i=100;
  956. while(i--); //delay some time and then PowerUp HHI_VID_PLL
  957. Wr(HHI_VID_PLL_CNTL, (Rd(HHI_VID_PLL_CNTL) & ~(1<<30))); //0x105c[30]PD, 0: Power Up
  958. #endif
  959. // Wr(HHI_GCLK_MPEG2, Rd(HHI_GCLK_MPEG2)|(1<<4)); //enable pixel clock, set cbus reg HHI_GCLK_MPEG2 bit [4] = 1
  960. Wr(HHI_GCLK_OTHER, Rd(HHI_GCLK_OTHER)|(1<<17)); //enable VCLK1_HDMI GATE, set cbus reg HHI_GCLK_OTHER bit [17] = 1
  961. }
  962. if(flag&1){
  963. //#ifdef AML_A3
  964. /* on hdmi audio clock */
  965. hdmi_wr_reg(OTHER_BASE_ADDR + HDMI_OTHER_CTRL1, hdmi_rd_reg(OTHER_BASE_ADDR + HDMI_OTHER_CTRL1)|(1<<13));
  966. //#endif
  967. }
  968. }
  969. static void phy_pll_off(void)
  970. {
  971. /* power down hdmi phy */
  972. // hdmi_wr_reg(TX_CORE_CALIB_MODE, 0x8);
  973. // hdmi_wr_reg(TX_SYS1_TERMINATION, hdmi_rd_reg(TX_SYS1_TERMINATION)&(~0xf));
  974. // hdmi_wr_reg(TX_SYS1_AFE_SPARE0, hdmi_rd_reg(TX_SYS1_AFE_SPARE0)&(~0xf));
  975. // hdmi_wr_reg(TX_SYS1_AFE_TEST, hdmi_rd_reg(TX_SYS1_AFE_TEST)&(~0x1f));
  976. /**/
  977. hdmi_suspend();
  978. #if 0
  979. //no HDMI PLL in M3
  980. #ifndef AML_A3
  981. /* no HDMI PLL in A3 */
  982. Wr(HHI_VID_PLL_CNTL, Rd(HHI_VID_PLL_CNTL)|(1<<30)); //disable HDMI PLL
  983. Wr(HHI_VID_PLL_CNTL3, Rd(HHI_VID_PLL_CNTL3)&(~0x38));
  984. #endif
  985. #endif
  986. }
  987. /**/
  988. void hdmi_hw_set_powermode( int power_mode, int vic)
  989. {
  990. hdmi_wakeup();
  991. switch(power_mode){
  992. case 1:
  993. hdmi_wr_reg(0x016, 0x02);
  994. hdmi_wr_reg(0x014, 0x02);
  995. hdmi_wr_reg(TX_CORE_CALIB_MODE, 0xc);
  996. hdmi_wr_reg(TX_CORE_CALIB_VALUE, 0x0);
  997. hdmi_wr_reg(0x010, 0x2);
  998. switch(vic)
  999. {
  1000. case HDMI_480p60:
  1001. case HDMI_480p60_16x9:
  1002. hdmi_wr_reg(TX_SYS1_AFE_TEST, 0x7f); //0x17
  1003. hdmi_wr_reg(TX_CORE_CALIB_VALUE,0x5); //0xf7
  1004. hdmi_wr_reg(TX_SYS1_AFE_RESET, 0x1); //0x16
  1005. hdmi_wr_reg(TX_SYS1_BANDGAP, 0x0); //0x14
  1006. hdmi_wr_reg(TX_SYS1_BIAS, 0x0); //0x15
  1007. break;
  1008. case HDMI_720p60:
  1009. hdmi_wr_reg(TX_SYS1_AFE_TEST, 0x7f); //0x17
  1010. hdmi_wr_reg(TX_CORE_CALIB_VALUE,0x3); //0xf7
  1011. hdmi_wr_reg(TX_SYS1_AFE_RESET, 0x1); //0x16
  1012. hdmi_wr_reg(TX_SYS1_BANDGAP, 0x0); //0x14
  1013. hdmi_wr_reg(TX_SYS1_BIAS, 0x3); //0x15
  1014. break;
  1015. case HDMI_1080p60:
  1016. hdmi_wr_reg(TX_SYS1_AFE_TEST, 0x7f); //0x17
  1017. hdmi_wr_reg(TX_CORE_CALIB_VALUE,0x3); //0xf7
  1018. hdmi_wr_reg(TX_SYS1_AFE_RESET, 0x1); //0x16
  1019. hdmi_wr_reg(TX_SYS1_BANDGAP, 0x1); //0x14 Prem
  1020. hdmi_wr_reg(TX_SYS1_BIAS, 0x3); //0x15 Slew
  1021. break;
  1022. default:
  1023. break;
  1024. }
  1025. #ifdef MORE_LOW_P
  1026. hdmi_wr_reg(0x010, 0x0);
  1027. hdmi_wr_reg(0x01a, 0x3);
  1028. #endif
  1029. break;
  1030. case 2:
  1031. hdmi_wr_reg(0x017, 0x1f);
  1032. hdmi_wr_reg(0x016, 0x01);
  1033. hdmi_wr_reg(0x015, 0x03);
  1034. hdmi_wr_reg(0x0ec, 0x0f);
  1035. if(vic == HDMI_1080p60){
  1036. hdmi_wr_reg(0x014, 0x02); //for 1080p only
  1037. }
  1038. else{
  1039. hdmi_wr_reg(0x014, 0x0);
  1040. }
  1041. break;
  1042. default:
  1043. hdmi_wr_reg(0x016, 0x03); //hdmi_wr_reg(0x016, 0x04); // Bit[3:0] is HDMI-PHY's output swing control register
  1044. hdmi_wr_reg(TX_CORE_CALIB_MODE, 0x8);
  1045. hdmi_wr_reg(TX_CORE_CALIB_VALUE, 0xf);
  1046. #ifdef MORE_LOW_P
  1047. hdmi_wr_reg(0x010, 0x3);
  1048. hdmi_wr_reg(0x01a, 0xfb);
  1049. #endif
  1050. break;
  1051. }
  1052. }
  1053. void hdmi_hw_init(hdmitx_dev_t* hdmitx_device)
  1054. {
  1055. unsigned int tmp_add_data;
  1056. HDMI_DEBUG();
  1057. digital_clk_on(7);
  1058. #ifndef AML_A3
  1059. if((hdmi_chip_type == HDMI_M1A)||(hdmi_pll_mode == 1)){
  1060. Wr(HHI_VID_PLL_CNTL3, 0x50e8);
  1061. }
  1062. else{
  1063. Wr(HHI_VID_PLL_CNTL3, 0x40e8);
  1064. }
  1065. Wr(HHI_VID_PLL_CNTL, 0x03040502);
  1066. Wr(HHI_VID_PLL_CNTL2, 0x00040003);
  1067. #endif
  1068. Wr(HHI_HDMI_AFC_CNTL, Rd(HHI_HDMI_AFC_CNTL) | 0x3);
  1069. // Configure HDMI TX serializer:
  1070. //hdmi_wr_reg(0x011, 0x0f); //Channels Power Up Setting ,"1" for Power-up ,"0" for Power-down,Bit[3:0]=CK,Data2,data1,data1,data0 Channels ;
  1071. //hdmi_wr_reg(0x015, 0x03); //slew rate
  1072. hdmi_wr_reg(0x017, 0x1d); //1d for power-up Band-gap and main-bias ,00 is power down
  1073. if(serial_reg_val<0x20){
  1074. hdmi_wr_reg(0x018, 0x24);
  1075. }
  1076. else{
  1077. hdmi_wr_reg(0x018, serial_reg_val); //Serializer Internal clock setting ,please fix to vaue 24 ,other setting is only for debug
  1078. }
  1079. hdmi_wr_reg(0x01a, 0xfb); //bit[2:0]=011 ,CK channel output TMDS CLOCK ,bit[2:0]=101 ,ck channel output PHYCLCK
  1080. hdmi_hw_set_powermode(power_mode, 0);
  1081. hdmi_wr_reg(0x0F7, 0x0F); // Termination resistor calib value
  1082. //hdmi_wr_reg(0x014, 0x07); // This register is for pre-emphasis control ,we need test different TMDS Clcok speed then write down the suggested value for each one ;
  1083. //hdmi_wr_reg(0x014, 0x01); // This is a sample for Pre-emphasis setting ,recommended for 225MHz's TMDS Setting & ** meters HDMI Cable
  1084. // --------------------------------------------------------
  1085. // Program core_pin_mux to enable HDMI pins
  1086. // --------------------------------------------------------
  1087. //wire pm_hdmi_cec_en = pin_mux_reg0[2];
  1088. //wire pm_hdmi_hpd_5v_en = pin_mux_reg0[1];
  1089. //wire pm_hdmi_i2c_5v_en = pin_mux_reg0[0];
  1090. #ifdef AML_A3
  1091. // --------------------------------------------------------
  1092. // Program core_pin_mux to enable HDMI pins
  1093. // --------------------------------------------------------
  1094. //wire pm_gpioA_3_hdmi_cec = pin_mux_reg0[3];
  1095. //wire pm_gpioA_2_hdmi_scl = pin_mux_reg0[2];
  1096. //wire pm_gpioA_1_hdmi_sda = pin_mux_reg0[1];
  1097. //wire pm_gpioA_0_hdmi_hpd = pin_mux_reg0[0];
  1098. #ifdef CEC_SUPPORT
  1099. Wr(PERIPHS_PIN_MUX_0, Rd(PERIPHS_PIN_MUX_0)|((1 << 3) | // pm_gpioA_3_hdmi_cec
  1100. (1 << 2) | // pm_gpioA_2_hdmi_scl
  1101. (1 << 1) | // pm_gpioA_1_hdmi_sda
  1102. (0 << 0 ))); // pm_gpioA_0_hdmi_hpd , enable this signal after all init done to ensure fist HPD rising ok
  1103. #else
  1104. Wr(PERIPHS_PIN_MUX_0, Rd(PERIPHS_PIN_MUX_0)|((0 << 3) | // pm_gpioA_3_hdmi_cec
  1105. (1 << 2) | // pm_gpioA_2_hdmi_scl
  1106. (1 << 1) | // pm_gpioA_1_hdmi_sda
  1107. (0 << 0 ))); // pm_gpioA_0_hdmi_hpd , enable this signal after all init done to ensure fist HPD rising ok
  1108. #endif
  1109. #else
  1110. #ifdef CEC_SUPPORT
  1111. Wr(PERIPHS_PIN_MUX_1, Rd(PERIPHS_PIN_MUX_1)|((1 << 25) | // pm_hdmi_cec_en
  1112. (0 << 22) | // pm_hdmi_hpd_5v_en , enable this signal after all init done to ensure fist HPD rising ok
  1113. (1 << 23) | // pm_hdmi_i2c_sda_en
  1114. (1 << 24))); // pm_hdmi_i2c_scl_en
  1115. #else
  1116. Wr(PERIPHS_PIN_MUX_1, Rd(PERIPHS_PIN_MUX_1)|((0 << 25) | // pm_hdmi_cec_en
  1117. (0 << 22) | // pm_hdmi_hpd_5v_en , enable this signal after all init done to ensure fist HPD rising ok
  1118. (1 << 23) | // pm_hdmi_i2c_sda_en
  1119. (1 << 24))); // pm_hdmi_i2c_scl_en
  1120. #endif
  1121. #endif
  1122. // Enable these interrupts: [2] tx_edit_int_rise [1] tx_hpd_int_fall [0] tx_hpd_int_rise
  1123. hdmi_wr_reg(OTHER_BASE_ADDR + HDMI_OTHER_INTR_MASKN, 0x7);
  1124. // HPD glitch filter
  1125. hdmi_wr_reg(TX_HDCP_HPD_FILTER_L, 0x00);
  1126. hdmi_wr_reg(TX_HDCP_HPD_FILTER_H, 0xa0);
  1127. //#ifdef AML_A3
  1128. #if 1
  1129. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x90); //bit5,6 is converted
  1130. delay_us(10);
  1131. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x60);
  1132. delay_us(10);
  1133. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_1, 0xff);
  1134. delay_us(10);
  1135. #else
  1136. //new reset sequence, 2010Sep09, rain
  1137. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0xf0);
  1138. delay_us(10);
  1139. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x00);
  1140. delay_us(10);
  1141. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_1, 0xff);
  1142. delay_us(10);
  1143. #endif
  1144. /**/
  1145. // Enable software controlled DDC transaction
  1146. //tmp_add_data[15:8] = 0;
  1147. //tmp_add_data[7] = 1'b0 ; // forced_sys_trigger
  1148. //tmp_add_data[6] = 1'b0 ; // sys_trigger_config
  1149. //tmp_add_data[5] = 1'b0 ; // mem_acc_seq_mode
  1150. //tmp_add_data[4] = 1'b0 ; // mem_acc_seq_start
  1151. //tmp_add_data[3] = 1'b1 ; // forced_mem_copy_done
  1152. //tmp_add_data[2] = 1'b1 ; // mem_copy_done_config
  1153. //tmp_add_data[1] = 1'b1 ; // sys_trigger_config_semi_manu
  1154. //tmp_add_data[0] = 1'b0 ; // Rsrv
  1155. hdmi_wr_reg(TX_HDCP_EDID_CONFIG, 0x0c); //// for hdcp, can not use 0x0e
  1156. hdmi_wr_reg(TX_HDCP_CONFIG0, 1<<3); //set TX rom_encrypt_off=1
  1157. hdmi_wr_reg(TX_HDCP_MEM_CONFIG, 0<<3); //set TX read_decrypt=0
  1158. hdmi_wr_reg(TX_HDCP_ENCRYPT_BYTE, 0); //set TX encrypt_byte=0x00
  1159. #ifdef CONFIG_AML_HDMI_TX_HDCP
  1160. hdcpkey_status = task_tx_key_setting(force_wrong);
  1161. #endif
  1162. //tmp_add_data[15:8] = 0;
  1163. //tmp_add_data[7] = 1'b0; // Force packet timing
  1164. //tmp_add_data[6] = 1'b0; // PACKET ALLOC MODE
  1165. //tmp_add_data[5:0] = 6'd47 ; // PACKET_START_LATENCY
  1166. //tmp_add_data = 47;
  1167. tmp_add_data = 58;
  1168. hdmi_wr_reg(TX_PACKET_CONTROL_1, tmp_add_data); //this register should be set to ensure the first hdcp succeed
  1169. //tmp_add_data[7] = 1'b0; // cp_desired
  1170. //tmp_add_data[6] = 1'b0; // ess_config
  1171. //tmp_add_data[5] = 1'b0; // set_avmute
  1172. //tmp_add_data[4] = 1'b1; // clear_avmute
  1173. //tmp_add_data[3] = 1'b0; // hdcp_1_1
  1174. //tmp_add_data[2] = 1'b0; // Vsync/Hsync forced_polarity_select
  1175. //tmp_add_data[1] = 1'b0; // forced_vsync_polarity
  1176. //tmp_add_data[0] = 1'b0; // forced_hsync_polarity
  1177. //tmp_add_data = 0x10;
  1178. tmp_add_data = 0x0; //rain
  1179. hdmi_wr_reg(TX_HDCP_MODE, tmp_add_data);
  1180. //config_hdmi(1);
  1181. //tmp_add_data[15:8] = 0;
  1182. //tmp_add_data[7:0] = 0xa ; // time_divider[7:0] for DDC I2C bus clock
  1183. //tmp_add_data = 0xa; //800k
  1184. //tmp_add_data = 0x3f; //190k
  1185. tmp_add_data = 0x78; //100k
  1186. hdmi_wr_reg(TX_HDCP_CONFIG3, tmp_add_data);
  1187. //tmp_add_data[15:8] = 0;
  1188. //tmp_add_data[7] = 8'b1 ; //cp_desired
  1189. //tmp_add_data[6] = 8'b1 ; //ess_config
  1190. //tmp_add_data[5] = 8'b0 ; //set_avmute
  1191. //tmp_add_data[4] = 8'b0 ; //clear_avmute
  1192. //tmp_add_data[3] = 8'b1 ; //hdcp_1_1
  1193. //tmp_add_data[2] = 8'b0 ; //forced_polarity
  1194. //tmp_add_data[1] = 8'b0 ; //forced_vsync_polarity
  1195. //tmp_add_data[0] = 8'b0 ; //forced_hsync_polarity
  1196. tmp_add_data = 0x40;
  1197. hdmi_wr_reg(TX_HDCP_MODE, tmp_add_data);
  1198. hdmi_hw_set_powermode(power_mode, 0);
  1199. // --------------------------------------------------------
  1200. // Release TX out of reset
  1201. // --------------------------------------------------------
  1202. //new reset sequence, 2010Sep09, rain
  1203. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_1, 1<<6); // Release resets all other TX digital clock domain, except tmds_clk
  1204. delay_us(10);
  1205. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_1, 0x00); // Final release reset on tmds_clk domain
  1206. delay_us(10);
  1207. //#ifdef AML_A3
  1208. #if 1
  1209. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x68);
  1210. delay_us(10);
  1211. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x60);
  1212. delay_us(10);
  1213. #else
  1214. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x08);
  1215. delay_us(10);
  1216. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x00);
  1217. delay_us(10);
  1218. #endif
  1219. /**/
  1220. }
  1221. static void hdmi_hw_reset(Hdmi_tx_video_para_t *param)
  1222. {
  1223. unsigned int tmp_add_data;
  1224. unsigned long TX_OUTPUT_COLOR_FORMAT;
  1225. HDMI_DEBUG();
  1226. digital_clk_on(7);
  1227. if(param->color==COLOR_SPACE_YUV444){
  1228. TX_OUTPUT_COLOR_FORMAT=1;
  1229. }
  1230. else if(param->color==COLOR_SPACE_YUV422){
  1231. TX_OUTPUT_COLOR_FORMAT=3;
  1232. }
  1233. else{
  1234. TX_OUTPUT_COLOR_FORMAT=0;
  1235. }
  1236. #ifndef AML_A3
  1237. // Configure HDMI PLL
  1238. if((hdmi_chip_type == HDMI_M1A)||(hdmi_pll_mode == 1)){
  1239. Wr(HHI_VID_PLL_CNTL3, 0x50e8);
  1240. }
  1241. else{
  1242. Wr(HHI_VID_PLL_CNTL3, 0x40e8);
  1243. }
  1244. if(new_reset_sequence_flag){
  1245. Wr(HHI_VID_PLL_CNTL2, 0x00040003); //should turn on always for new reset sequence
  1246. }
  1247. else{
  1248. Wr(HHI_VID_PLL_CNTL2, 0x00040003);
  1249. }
  1250. #endif
  1251. if(delay_flag&2)
  1252. delay_us(1000*100);
  1253. //printk("delay 100ms\n");
  1254. Wr(HHI_HDMI_AFC_CNTL, Rd(HHI_HDMI_AFC_CNTL) | 0x3);
  1255. // Configure HDMI TX serializer:
  1256. //hdmi_wr_reg(0x011, 0x0f); //Channels Power Up Setting ,"1" for Power-up ,"0" for Power-down,Bit[3:0]=CK,Data2,data1,data1,data0 Channels ;
  1257. //hdmi_wr_reg(0x015, 0x03); //slew rate
  1258. hdmi_wr_reg(0x017, 0x1d); //1d for power-up Band-gap and main-bias ,00 is power down
  1259. if(new_reset_sequence_flag==0){
  1260. if(serial_reg_val==0){
  1261. if((param->VIC==HDMI_1080p30)||(param->VIC==HDMI_720p60)||(param->VIC==HDMI_1080i60)
  1262. ||(param->VIC==HDMI_1080p24)){
  1263. hdmi_wr_reg(0x018, 0x22);
  1264. }
  1265. else{
  1266. hdmi_wr_reg(0x018, 0x24);
  1267. }
  1268. }
  1269. else if(serial_reg_val==1){
  1270. if((param->VIC==HDMI_480p60)||(param->VIC==HDMI_480p60_16x9)
  1271. ||(param->VIC==HDMI_576p50)||(param->VIC==HDMI_576p50_16x9)
  1272. ||(param->VIC==HDMI_480i60)||(param->VIC==HDMI_480i60_16x9)
  1273. ||(param->VIC==HDMI_576i50)||(param->VIC==HDMI_576i50_16x9)){
  1274. hdmi_wr_reg(0x018, 0x24);
  1275. }
  1276. else{
  1277. hdmi_wr_reg(0x018, 0x22);
  1278. }
  1279. }
  1280. else{
  1281. hdmi_wr_reg(0x018, serial_reg_val);
  1282. }
  1283. if((param->VIC==HDMI_1080p60)&&(param->color_depth==COLOR_30BIT)&&(hdmi_rd_reg(0x018)==0x22)){
  1284. hdmi_wr_reg(0x018,0x12);
  1285. }
  1286. }
  1287. hdmi_wr_reg(0x01a, 0xfb); //bit[2:0]=011 ,CK channel output TMDS CLOCK ,bit[2:0]=101 ,ck channel output PHYCLCK
  1288. hdmi_hw_set_powermode(power_mode, param->VIC);
  1289. hdmi_wr_reg(0x0F7, 0x0F); // Termination resistor calib value
  1290. //hdmi_wr_reg(0x014, 0x07); // This register is for pre-emphasis control ,we need test different TMDS Clcok speed then write down the suggested value for each one ;
  1291. //hdmi_wr_reg(0x014, 0x01); // This is a sample for Pre-emphasis setting ,recommended for 225MHz's TMDS Setting & ** meters HDMI Cable
  1292. // delay 1000uS, then check HPLL_LOCK
  1293. delay_us(1000);
  1294. //while ( (Rd(HHI_VID_PLL_CNTL3) & (1<<31)) != (1<<31) );
  1295. //////////////////////////////reset
  1296. if(new_reset_sequence_flag){
  1297. //#ifdef AML_A3
  1298. #if 1
  1299. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x90);
  1300. delay_us(10);
  1301. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x60);
  1302. delay_us(10);
  1303. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_1, 0xff);
  1304. delay_us(10);
  1305. #else
  1306. //new reset sequence, 2010Sep09, rain
  1307. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0xf0);
  1308. delay_us(10);
  1309. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x00);
  1310. delay_us(10);
  1311. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_1, 0xff);
  1312. delay_us(10);
  1313. #endif
  1314. }
  1315. else{
  1316. #ifndef AML_A3
  1317. // Keep TX (except register I/F) in reset, while programming the registers:
  1318. tmp_add_data = 0;
  1319. tmp_add_data |= 1 << 7; // tx_pixel_rstn
  1320. tmp_add_data |= 1 << 6; // tx_tmds_rstn
  1321. tmp_add_data |= 1 << 5; // tx_audio_master_rstn
  1322. tmp_add_data |= 1 << 4; // tx_audio_sample_rstn
  1323. tmp_add_data |= 1 << 3; // tx_i2s_reset_rstn
  1324. tmp_add_data |= 1 << 2; // tx_dig_reset_n_ch2
  1325. tmp_add_data |= 1 << 1; // tx_dig_reset_n_ch1
  1326. tmp_add_data |= 1 << 0; // tx_dig_reset_n_ch0
  1327. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_1, tmp_add_data);
  1328. tmp_add_data = 0;
  1329. tmp_add_data |= 1 << 7; // HDMI_CH3_RST_IN
  1330. tmp_add_data |= 1 << 6; // HDMI_CH2_RST_IN
  1331. tmp_add_data |= 1 << 5; // HDMI_CH1_RST_IN
  1332. tmp_add_data |= 1 << 4; // HDMI_CH0_RST_IN
  1333. tmp_add_data |= 1 << 3; // HDMI_SR_RST
  1334. tmp_add_data |= 1 << 0; // tx_dig_reset_n_ch3
  1335. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, tmp_add_data);
  1336. #endif
  1337. }
  1338. // Enable software controlled DDC transaction
  1339. //tmp_add_data[15:8] = 0;
  1340. //tmp_add_data[7] = 1'b0 ; // forced_sys_trigger
  1341. //tmp_add_data[6] = 1'b0 ; // sys_trigger_config
  1342. //tmp_add_data[5] = 1'b0 ; // mem_acc_seq_mode
  1343. //tmp_add_data[4] = 1'b0 ; // mem_acc_seq_start
  1344. //tmp_add_data[3] = 1'b1 ; // forced_mem_copy_done
  1345. //tmp_add_data[2] = 1'b1 ; // mem_copy_done_config
  1346. //tmp_add_data[1] = 1'b1 ; // sys_trigger_config_semi_manu
  1347. //tmp_add_data[0] = 1'b0 ; // Rsrv
  1348. tmp_add_data = 0x0c; // for hdcp, can not use 0x0e
  1349. hdmi_wr_reg(TX_HDCP_EDID_CONFIG, tmp_add_data);
  1350. hdmi_wr_reg(TX_HDCP_CONFIG0, 1<<3); //set TX rom_encrypt_off=1
  1351. hdmi_wr_reg(TX_HDCP_MEM_CONFIG, 0<<3); //set TX read_decrypt=0
  1352. hdmi_wr_reg(TX_HDCP_ENCRYPT_BYTE, 0); //set TX encrypt_byte=0x00
  1353. #ifdef CONFIG_AML_HDMI_TX_HDCP
  1354. hdcpkey_status = task_tx_key_setting(force_wrong);
  1355. #endif
  1356. //tmp_add_data[15:8] = 0;
  1357. //tmp_add_data[7] = 1'b0; // Force DTV timing (Auto)
  1358. //tmp_add_data[6] = 1'b0; // Force Video Scan, only if [7]is set
  1359. //tmp_add_data[5] = 1'b0 ; // Force Video field, only if [7]is set
  1360. //tmp_add_data[4:0] = 5'b00 ; // Rsrv
  1361. tmp_add_data = 0;
  1362. hdmi_wr_reg(TX_VIDEO_DTV_TIMING, tmp_add_data);
  1363. tmp_add_data = 0;
  1364. tmp_add_data |= 0 << 7; // [7] forced_default_phase
  1365. tmp_add_data |= 0 << 2; // [6:2] Rsrv
  1366. tmp_add_data |= param->color_depth << 0; // [1:0] Color_depth:0=24-bit pixel; 1=30-bit pixel; 2=36-bit pixel; 3=48-bit pixel
  1367. hdmi_wr_reg(TX_VIDEO_DTV_MODE, tmp_add_data); // 0x00
  1368. //tmp_add_data[15:8] = 0;
  1369. //tmp_add_data[7] = 1'b0; // Force packet timing
  1370. //tmp_add_data[6] = 1'b0; // PACKET ALLOC MODE
  1371. //tmp_add_data[5:0] = 6'd47 ; // PACKET_START_LATENCY
  1372. //tmp_add_data = 47;
  1373. tmp_add_data = 58;
  1374. hdmi_wr_reg(TX_PACKET_CONTROL_1, tmp_add_data);
  1375. // For debug: disable packets of audio_request, acr_request, deep_color_request, and avmute_request
  1376. //hdmi_wr_reg(TX_PACKET_CONTROL_2, hdmi_rd_reg(TX_PACKET_CONTROL_2) | 0x0f);
  1377. //HDMI CT 7-19 GCP PB1 through PB6 not equal to 0 | 720 3 0 37 72 16367911819.90 31822 General Control Packet (GCP)
  1378. //PACKET_CONTROL[~deep_color_request_enable]
  1379. //0: horizontal GC packet transport enabled
  1380. //1: horizontal GC packet masked
  1381. hdmi_wr_reg(TX_PACKET_CONTROL_2, hdmi_rd_reg(TX_PACKET_CONTROL_2) | (0x1<<1));
  1382. //tmp_add_data[15:8] = 0;
  1383. //tmp_add_data[7:6] = 2'b0; // audio_source_select[1:0]
  1384. //tmp_add_data[5] = 1'b0; // external_packet_enable
  1385. //tmp_add_data[4] = 1'b1 ; // internal_packet_enable
  1386. //tmp_add_data[3:2] = 2'b0; // afe_fifo_source_select_lane_1[1:0]
  1387. //tmp_add_data[1:0] = 2'b0 ; // afe_fifo_source_select_lane_0[1:0]
  1388. tmp_add_data = 0x10;
  1389. hdmi_wr_reg(TX_CORE_DATA_CAPTURE_2, tmp_add_data);
  1390. //tmp_add_data[15:8] = 0;
  1391. //tmp_add_data[7] = 1'b0; // monitor_lane_1
  1392. //tmp_add_data[6:4] = 3'd0; // monitor_select_lane_1[2:0]
  1393. //tmp_add_data[3] = 1'b1 ; // monitor_lane_0
  1394. //tmp_add_data[2:0] = 3'd7; // monitor_select_lane_0[2:0]
  1395. tmp_add_data = 0xf;
  1396. hdmi_wr_reg(TX_CORE_DATA_MONITOR_1, tmp_add_data);
  1397. //tmp_add_data[15:8] = 0;
  1398. //tmp_add_data[7:3] = 5'b0; // Rsrv
  1399. //tmp_add_data[2:0] = 3'd2; // monitor_select[2:0]
  1400. tmp_add_data = 0x2;
  1401. hdmi_wr_reg(TX_CORE_DATA_MONITOR_2, tmp_add_data);
  1402. //tmp_add_data[15:8] = 0;
  1403. //tmp_add_data[7] = 1'b1; // forced_hdmi
  1404. //tmp_add_data[6] = 1'b1; // hdmi_config
  1405. //tmp_add_data[5:4] = 2'b0; // Rsrv
  1406. //tmp_add_data[3] = 1'b0; // bit_swap.
  1407. //tmp_add_data[2:0] = 3'd0; // channel_swap[2:0]
  1408. tmp_add_data = 0xc0;
  1409. hdmi_wr_reg(TX_TMDS_MODE, tmp_add_data);
  1410. //tmp_add_data[15:8] = 0;
  1411. //tmp_add_data[7] = 1'b0; // Rsrv
  1412. //tmp_add_data[6] = 1'b0; // TX_CONNECT_SEL: 0=use lower channel data[29:0]; 1=use upper channel data[59:30]
  1413. //tmp_add_data[5:0] = 'h0; // Rsrv
  1414. tmp_add_data = 0x0;
  1415. hdmi_wr_reg(TX_SYS4_CONNECT_SEL_1, tmp_add_data);
  1416. // Normally it makes sense to synch 3 channel output with clock channel's rising edge,
  1417. // as HDMI's serializer is LSB out first, invert tmds_clk pattern from "1111100000" to
  1418. // "0000011111" actually enable data synch with clock rising edge.
  1419. //if((param->VIC==HDMI_1080p30)||(param->VIC==HDMI_720p60)||(param->VIC==HDMI_1080i60)){
  1420. // hdmi_wr_reg(TX_SYS4_CK_INV_VIDEO, 0xf0);
  1421. //}
  1422. //else{
  1423. tmp_add_data = 1 << 4; // Set tmds_clk pattern to be "0000011111" before being sent to AFE clock channel
  1424. hdmi_wr_reg(TX_SYS4_CK_INV_VIDEO, tmp_add_data);
  1425. //}
  1426. //tmp_add_data[15:8] = 0;
  1427. //tmp_add_data[7] = 1'b0; // Rsrv
  1428. //tmp_add_data[6] = 1'b0; // TX_AFE_FIFO channel 2 bypass=0
  1429. //tmp_add_data[5] = 1'b0; // TX_AFE_FIFO channel 1 bypass=0
  1430. //tmp_add_data[4] = 1'b0; // TX_AFE_FIFO channel 0 bypass=0
  1431. //tmp_add_data[3] = 1'b1; // output enable of clk channel (channel 3)
  1432. //tmp_add_data[2] = 1'b1; // TX_AFE_FIFO channel 2 enable
  1433. //tmp_add_data[1] = 1'b1; // TX_AFE_FIFO channel 1 enable
  1434. //tmp_add_data[0] = 1'b1; // TX_AFE_FIFO channel 0 enable
  1435. tmp_add_data = 0x0f;
  1436. hdmi_wr_reg(TX_SYS5_FIFO_CONFIG, tmp_add_data);
  1437. tmp_add_data = 0;
  1438. tmp_add_data |= TX_OUTPUT_COLOR_FORMAT << 6; // [7:6] output_color_format: 0=RGB444; 1=YCbCr444; 2=Rsrv; 3=YCbCr422.
  1439. tmp_add_data |= TX_INPUT_COLOR_FORMAT << 4; // [5:4] input_color_format: 0=RGB444; 1=YCbCr444; 2=Rsrv; 3=YCbCr422.
  1440. tmp_add_data |= param->color_depth << 2; // [3:2] output_color_depth: 0=24-b; 1=30-b; 2=36-b; 3=48-b.
  1441. tmp_add_data |= TX_INPUT_COLOR_DEPTH << 0; // [1:0] input_color_depth: 0=24-b; 1=30-b; 2=36-b; 3=48-b.
  1442. hdmi_wr_reg(TX_VIDEO_DTV_OPTION_L, tmp_add_data); // 0x50
  1443. tmp_add_data = 0;
  1444. tmp_add_data |= 0 << 4; // [7:4] Rsrv
  1445. tmp_add_data |= TX_OUTPUT_COLOR_RANGE << 2; // [3:2] output_color_range: 0=16-235/240; 1=16-240; 2=1-254; 3=0-255.
  1446. tmp_add_data |= TX_INPUT_COLOR_RANGE << 0; // [1:0] input_color_range: 0=16-235/240; 1=16-240; 2=1-254; 3=0-255.
  1447. hdmi_wr_reg(TX_VIDEO_DTV_OPTION_H, tmp_add_data); // 0x00
  1448. if(!hdmi_audio_off_flag){
  1449. #if 1
  1450. hdmi_audio_init(i2s_to_spdif_flag);
  1451. #else
  1452. hdmi_wr_reg(TX_AUDIO_PACK, 0x00); // disable audio sample packets
  1453. #endif
  1454. }
  1455. //tmp_add_data[7] = 1'b0; // cp_desired
  1456. //tmp_add_data[6] = 1'b0; // ess_config
  1457. //tmp_add_data[5] = 1'b0; // set_avmute
  1458. //tmp_add_data[4] = 1'b1; // clear_avmute
  1459. //tmp_add_data[3] = 1'b0; // hdcp_1_1
  1460. //tmp_add_data[2] = 1'b0; // Vsync/Hsync forced_polarity_select
  1461. //tmp_add_data[1] = 1'b0; // forced_vsync_polarity
  1462. //tmp_add_data[0] = 1'b0; // forced_hsync_polarity
  1463. //tmp_add_data = 0x10;
  1464. tmp_add_data = 0x0; //rain
  1465. hdmi_wr_reg(TX_HDCP_MODE, tmp_add_data);
  1466. //config_hdmi(1);
  1467. //tmp_add_data[15:8] = 0;
  1468. //tmp_add_data[7:0] = 0xa ; // time_divider[7:0] for DDC I2C bus clock
  1469. //tmp_add_data = 0xa; //800k
  1470. //tmp_add_data = 0x3f; //190k
  1471. tmp_add_data = 0x78; //100k
  1472. hdmi_wr_reg(TX_HDCP_CONFIG3, tmp_add_data);
  1473. //tmp_add_data[15:8] = 0;
  1474. //tmp_add_data[7] = 8'b1 ; //cp_desired
  1475. //tmp_add_data[6] = 8'b1 ; //ess_config
  1476. //tmp_add_data[5] = 8'b0 ; //set_avmute
  1477. //tmp_add_data[4] = 8'b0 ; //clear_avmute
  1478. //tmp_add_data[3] = 8'b1 ; //hdcp_1_1
  1479. //tmp_add_data[2] = 8'b0 ; //forced_polarity
  1480. //tmp_add_data[1] = 8'b0 ; //forced_vsync_polarity
  1481. //tmp_add_data[0] = 8'b0 ; //forced_hsync_polarity
  1482. tmp_add_data = 0x40;
  1483. hdmi_wr_reg(TX_HDCP_MODE, tmp_add_data);
  1484. if(param->cc == CC_ITU709){
  1485. hdmi_wr_reg(TX_VIDEO_CSC_COEFF_CB0, 0xf2);
  1486. hdmi_wr_reg(TX_VIDEO_CSC_COEFF_CB1, 0x2f);
  1487. hdmi_wr_reg(TX_VIDEO_CSC_COEFF_CR0, 0xd4);
  1488. hdmi_wr_reg(TX_VIDEO_CSC_COEFF_CR1, 0x77);
  1489. }
  1490. else{
  1491. hdmi_wr_reg(TX_VIDEO_CSC_COEFF_CB0, 0x18);
  1492. hdmi_wr_reg(TX_VIDEO_CSC_COEFF_CB1, 0x58);
  1493. hdmi_wr_reg(TX_VIDEO_CSC_COEFF_CR0, 0xd0);
  1494. hdmi_wr_reg(TX_VIDEO_CSC_COEFF_CR1, 0x66);
  1495. }
  1496. hdmi_hw_set_powermode(power_mode, param->VIC);
  1497. // --------------------------------------------------------
  1498. // Release TX out of reset
  1499. // --------------------------------------------------------
  1500. if(new_reset_sequence_flag){
  1501. //new reset sequence, 2010Sep09, rain
  1502. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_1, 1<<6); // Release resets all other TX digital clock domain, except tmds_clk
  1503. delay_us(10);
  1504. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_1, 0x00); // Final release reset on tmds_clk domain
  1505. delay_us(10);
  1506. //#ifdef AML_A3
  1507. #if 1
  1508. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x68);
  1509. delay_us(10);
  1510. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x60);
  1511. delay_us(10);
  1512. #else
  1513. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x08);
  1514. delay_us(10);
  1515. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x00);
  1516. delay_us(10);
  1517. #endif
  1518. /* select serial*/
  1519. if(serial_reg_val==0){
  1520. if((param->VIC==HDMI_1080p30)||(param->VIC==HDMI_720p60)||(param->VIC==HDMI_1080i60)
  1521. ||(param->VIC==HDMI_1080p24)){
  1522. hdmi_wr_reg(0x018, 0x22);
  1523. }
  1524. else{
  1525. hdmi_wr_reg(0x018, 0x24);
  1526. }
  1527. }
  1528. else if(serial_reg_val==1){
  1529. if((param->VIC==HDMI_480p60)||(param->VIC==HDMI_480p60_16x9)
  1530. ||(param->VIC==HDMI_576p50)||(param->VIC==HDMI_576p50_16x9)
  1531. ||(param->VIC==HDMI_480i60)||(param->VIC==HDMI_480i60_16x9)
  1532. ||(param->VIC==HDMI_576i50)||(param->VIC==HDMI_576i50_16x9)){
  1533. hdmi_wr_reg(0x018, 0x24);
  1534. }
  1535. else{
  1536. hdmi_wr_reg(0x018, 0x22);
  1537. }
  1538. }
  1539. else{
  1540. hdmi_wr_reg(0x018, serial_reg_val);
  1541. }
  1542. if((param->VIC==HDMI_1080p60)&&(param->color_depth==COLOR_30BIT)&&(hdmi_rd_reg(0x018)==0x22)){
  1543. hdmi_wr_reg(0x018,0x12);
  1544. }
  1545. }
  1546. else{
  1547. #ifndef AML_A3
  1548. Wr(HHI_VID_PLL_CNTL2, 0x00040000); // turn off phy_clk
  1549. delay_us(10);
  1550. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x01); // Release serializer resets
  1551. delay_us(10);
  1552. Wr(HHI_VID_PLL_CNTL2, 0x00040003); // turn on phy_clk
  1553. delay_us(10);
  1554. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x00); // Release reset on TX digital clock channel
  1555. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_1, 1<<6); // Release resets all other TX digital clock domain, except tmds_clk
  1556. delay_us(10);
  1557. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_1, 0x00); // Final release reset on tmds_clk domain
  1558. tmp_add_data = hdmi_rd_reg(0x018);
  1559. if((tmp_add_data==0x22)||(tmp_add_data==0x12)){
  1560. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x08);
  1561. delay_us(10);
  1562. hdmi_wr_reg(TX_SYS5_TX_SOFT_RESET_2, 0x00);
  1563. }
  1564. #endif
  1565. }
  1566. }
  1567. static void hdmi_audio_init(unsigned char spdif_flag)
  1568. {
  1569. unsigned tmp_add_data;
  1570. #if 1
  1571. /* If TX_AUDIO_FORMAT is set as 0, "Channel Status" will not be sent out correctly */
  1572. /* TX_AUDIO_CONTROL[bit 0] should be 1, otherwise no sound??? */
  1573. unsigned char tx_i2s_spdif;
  1574. unsigned char tx_i2s_8_channel;
  1575. hdmi_print(0,"HDMI DEBUG [%s] [%d]\n", __FUNCTION__, spdif_flag);
  1576. if(spdif_flag){
  1577. tx_i2s_spdif=0;
  1578. tx_i2s_8_channel=0;
  1579. }
  1580. else{
  1581. tx_i2s_spdif=1;
  1582. tx_i2s_8_channel=0;
  1583. }
  1584. tmp_add_data = 0;
  1585. tmp_add_data |= tx_i2s_spdif << 7; // [7] I2S or SPDIF
  1586. tmp_add_data |= tx_i2s_8_channel<< 6; // [6] 8 or 2ch
  1587. tmp_add_data |= 2 << 4; // [5:4] Serial Format: I2S format
  1588. tmp_add_data |= 3 << 2; // [3:2] Bit Width: 24-bit
  1589. tmp_add_data |= 0 << 1; // [1] WS Polarity: 0=WS high is right
  1590. tmp_add_data |= 1 << 0; // [0] For I2S: 0=one-bit audio; 1=I2S;
  1591. // For SPDIF: 0= channel status from input data; 1=from register
  1592. hdmi_wr_reg(TX_AUDIO_FORMAT, tmp_add_data); // 0x2f
  1593. //tmp_add_data = 0;
  1594. //tmp_add_data |= 0x4 << 4; // [7:4] FIFO Depth=512
  1595. //tmp_add_data |= 0x2 << 2; // [3:2] Critical threshold=Depth/16
  1596. //tmp_add_data |= 0x1 << 0; // [1:0] Normal threshold=Depth/8
  1597. //hdmi_wr_reg(TX_AUDIO_FIFO, tmp_add_data); // 0x49
  1598. hdmi_wr_reg(TX_AUDIO_FIFO, aud_para); // 0x49
  1599. hdmi_wr_reg(TX_AUDIO_LIPSYNC, 0); // [7:0] Normalized lip-sync param: 0 means S(lipsync) = S(total)/2
  1600. tmp_add_data = 0;
  1601. tmp_add_data |= 0 << 7; // [7] forced_audio_fifo_clear
  1602. tmp_add_data |= 1 << 6; // [6] auto_audio_fifo_clear
  1603. tmp_add_data |= 0x0 << 4; // [5:4] audio_packet_type: 0=audio sample packet; 1=one bit audio; 2=HBR audio packet; 3=DST audio packet.
  1604. tmp_add_data |= 0 << 3; // [3] Rsrv
  1605. tmp_add_data |= 0 << 2; // [2] Audio sample packet's valid bit: 0=valid bit is 0 for I2S, is input data for SPDIF; 1=valid bit from register
  1606. tmp_add_data |= 0 << 1; // [1] Audio sample packet's user bit: 0=user bit is 0 for I2S, is input data for SPDIF; 1=user bit from register
  1607. tmp_add_data |= 0 << 0; // [0] 0=Audio sample packet's sample_flat bit is 1; 1=sample_flat is 0.
  1608. hdmi_wr_reg(TX_AUDIO_CONTROL, tmp_add_data); // 0x40
  1609. tmp_add_data = 0;
  1610. tmp_add_data |= tx_i2s_8_channel<< 7; // [7] Audio sample packet's header layout bit: 0=layout0; 1=layout1
  1611. tmp_add_data |= 0 << 6; // [6] Set normal_double bit in DST packet header.
  1612. tmp_add_data |= 0 << 0; // [5:0] Rsrv
  1613. hdmi_wr_reg(TX_AUDIO_HEADER, tmp_add_data); // 0x00
  1614. tmp_add_data = tx_i2s_8_channel ? 0xff : 0x03;
  1615. hdmi_wr_reg(TX_AUDIO_SAMPLE, tmp_add_data); // Channel valid for up to 8 channels, 1 bit per channel.
  1616. hdmi_wr_reg(TX_AUDIO_PACK, 0x01); // Enable audio sample packets
  1617. // Set N = 4096 (N is not measured, N must be configured so as to be a reference to clock_meter)
  1618. hdmi_wr_reg(TX_SYS1_ACR_N_0, 0x00); // N[7:0]
  1619. hdmi_wr_reg(TX_SYS1_ACR_N_1, 0x18 /*0x10*/); // N[15:8]
  1620. tmp_add_data = 0;
  1621. tmp_add_data |= 0xa << 4; // [7:4] Meas Tolerance
  1622. tmp_add_data |= 0x0 << 0; // [3:0] N[19:16]
  1623. hdmi_wr_reg(TX_SYS1_ACR_N_2, tmp_add_data); // 0xa0
  1624. hdmi_wr_reg(TX_AUDIO_CONTROL, hdmi_rd_reg(TX_AUDIO_CONTROL)|0x1);
  1625. #else
  1626. /* reference register setting */
  1627. /* this register setting works for spdif_flag==1*/
  1628. if(spdif_flag){
  1629. hdmi_wr_reg(TX_AUDIO_CONTROL, 0x40); // Address 0x5D=0x40 TX_AUDIO_CONTROL
  1630. hdmi_wr_reg(TX_AUDIO_FIFO, 0x1 ); // Address 0x5B=0x1 TX_AUDIO_FIFO
  1631. hdmi_wr_reg(TX_AUDIO_CONTROL, 0x40); // Address 0x5D=0x40 TX_AUDIO_CONTROL
  1632. hdmi_wr_reg(TX_AUDIO_FIFO, 0xD ); // Address 0x5B=0xD TX_AUDIO_FIFO
  1633. hdmi_wr_reg(TX_AUDIO_FIFO, 0x3D); // Address 0x5B=0x3D TX_AUDIO_FIFO
  1634. hdmi_wr_reg(TX_AUDIO_LIPSYNC, 0x1 ); // Address 0x5C=0x1 TX_AUDIO_LIPSYNC
  1635. hdmi_wr_reg(TX_AUDIO_PACK, 0x1 ); // Address 0x62=0x1 TX_AUDIO_PACK
  1636. hdmi_wr_reg(TX_AUDIO_CONTROL, 0x40); // Address 0x5D=0x40 TX_AUDIO_CONTROL
  1637. hdmi_wr_reg(TX_AUDIO_HEADER, 0x0 ); // Address 0x5E=0x0 TX_AUDIO_HEADER
  1638. hdmi_wr_reg(TX_HDCP_MODE, 0x0 ); // Address 0x2F=0x0 TX_HDCP_MODE
  1639. hdmi_wr_reg(TX_HDCP_MODE, 0x0 ); // Address 0x2F=0x0 TX_HDCP_MODE
  1640. hdmi_wr_reg(TX_SYS0_ACR_CTS_2, 0x20); // Address 0x4=0x20 TX_SYS0_ACR_CTS_2
  1641. hdmi_wr_reg(TX_SYS0_ACR_CTS_2, 0x20); // Address 0x4=0x20 TX_SYS0_ACR_CTS_2
  1642. hdmi_wr_reg(TX_SYS0_ACR_CTS_2, 0x20); // Address 0x4=0x20 TX_SYS0_ACR_CTS_2
  1643. hdmi_wr_reg(TX_SYS0_ACR_CTS_2, 0x20); // Address 0x4=0x20 TX_SYS0_ACR_CTS_2
  1644. hdmi_wr_reg(TX_AUDIO_CONTROL, 0x40); // Address 0x5D=0x40 TX_AUDIO_CONTROL
  1645. hdmi_wr_reg(TX_AUDIO_SAMPLE, 0x3 ); // Address 0x5F=0x3 TX_AUDIO_SAMPLE
  1646. hdmi_wr_reg(TX_AUDIO_CONTROL, 0x41); // Address 0x5D=0x41 TX_AUDIO_CONTROL
  1647. //hdmi_wr_reg(0x280, 0x70); // Address 0x280=0x70 TX_PKT_REG_AUDIO_INFO_BASE_ADDR
  1648. //hdmi_wr_reg(0x29E, 0xA ); // Address 0x29E=0xA
  1649. //hdmi_wr_reg(0x29D, 0x1 ); // Address 0x29D=0x1
  1650. //hdmi_wr_reg(0x29C, 0x84); // Address 0x29C=0x84
  1651. //hdmi_wr_reg(0x281, 0x1 ); // Address 0x281=0x1
  1652. //hdmi_wr_reg(0x29F, 0x80); // Address 0x29F=0x80
  1653. hdmi_wr_reg(TX_AUDIO_FORMAT, 0x0 ); // Address 0x58=0x0 TX_AUDIO_FORMAT
  1654. hdmi_wr_reg(TX_AUDIO_I2S, 0x0 ); // Address 0x5A=0x0 TX_AUDIO_I2S
  1655. hdmi_wr_reg(TX_AUDIO_SPDIF, 0x1 ); // Address 0x59=0x1 TX_AUDIO_SPDIF
  1656. hdmi_wr_reg(TX_SYS1_ACR_N_2, 0x0 ); // Address 0x1E=0x0 TX_SYS1_ACR_N_2
  1657. hdmi_wr_reg(TX_SYS1_ACR_N_1, 0x2D); // Address 0x1D=0x2D TX_SYS1_ACR_N_1
  1658. hdmi_wr_reg(TX_SYS1_ACR_N_0, 0x80); // Address 0x1C=0x80 TX_SYS1_ACR_N_0
  1659. }
  1660. else{
  1661. hdmi_wr_reg(TX_AUDIO_CONTROL, 0x40); //Address 0x5D=0x40
  1662. hdmi_wr_reg(TX_AUDIO_FIFO, 0x1 ); //Address 0x5B=0x1
  1663. hdmi_wr_reg(TX_AUDIO_CONTROL, 0x40); //Address 0x5D=0x40
  1664. hdmi_wr_reg(TX_AUDIO_FIFO, 0xD ); //Address 0x5B=0xD
  1665. hdmi_wr_reg(TX_AUDIO_FIFO, 0x3D); //Address 0x5B=0x3D
  1666. hdmi_wr_reg(TX_AUDIO_LIPSYNC, 0x1 ); //Address 0x5C=0x1
  1667. hdmi_wr_reg(TX_AUDIO_PACK, 0x1 ); //Address 0x62=0x1
  1668. hdmi_wr_reg(TX_AUDIO_CONTROL, 0x40); //Address 0x5D=0x40
  1669. hdmi_wr_reg(TX_AUDIO_HEADER, 0x0 ); //Address 0x5E=0x0
  1670. hdmi_wr_reg(TX_SYS0_ACR_CTS_2, 0x20); //Address 0x4=0x20
  1671. hdmi_wr_reg(TX_SYS0_ACR_CTS_2, 0x20); //Address 0x4=0x20
  1672. hdmi_wr_reg(TX_SYS0_ACR_CTS_2, 0x20); //Address 0x4=0x20
  1673. hdmi_wr_reg(TX_SYS0_ACR_CTS_2, 0x20); //Address 0x4=0x20
  1674. hdmi_wr_reg(TX_AUDIO_CONTROL, 0x40); //Address 0x5D=0x40
  1675. hdmi_wr_reg(TX_AUDIO_SAMPLE, 0x15); //Address 0x5F=0x15
  1676. hdmi_wr_reg(TX_AUDIO_CONTROL, 0x41); //Address 0x5D=0x41
  1677. hdmi_wr_reg(TX_AUDIO_FORMAT, 0x0 ); //Address 0x58=0x0
  1678. hdmi_wr_reg(TX_AUDIO_HEADER, 0x0 ); //Address 0x5E=0x0
  1679. hdmi_wr_reg(TX_AUDIO_SAMPLE, 0x3 ); //Address 0x5F=0x3
  1680. hdmi_wr_reg(TX_AUDIO_SPDIF, 0x0 ); //Address 0x59=0x0
  1681. hdmi_wr_reg(TX_AUDIO_FORMAT, 0x80); //Address 0x58=0x80
  1682. hdmi_wr_reg(TX_AUDIO_I2S, 0x1 ); //Address 0x5A=0x1
  1683. hdmi_wr_reg(TX_AUDIO_FORMAT, 0x81); //Address 0x58=0x81
  1684. hdmi_wr_reg(TX_AUDIO_FORMAT, 0xA1); //Address 0x58=0xA1
  1685. hdmi_wr_reg(TX_SYS1_ACR_N_2, 0x0 ); //Address 0x1E=0x0
  1686. hdmi_wr_reg(TX_SYS1_ACR_N_1, 0x2D); //Address 0x1D=0x2D
  1687. hdmi_wr_reg(TX_SYS1_ACR_N_0, 0x80); //Address 0x1C=0x80
  1688. }
  1689. #endif
  1690. }
  1691. #ifdef AVOS
  1692. #define AIU_CLK_CTRL MREG_AIU_clk_ctrl
  1693. #define AIU_958_MISC MREG_AIU_958_misc
  1694. #define AIU_958_FORCE_LEFT MREG_AIU_958_force_left
  1695. #define AIU_958_CTRL MREG_AIU_958_ctrl
  1696. #define AIU_958_BPF MREG_AIU_958_bpf
  1697. #define AIU_I2S_MISC MREG_AIU_i2s_misc
  1698. #define AIU_CLK_CTRL_MORE MREG_AIU_clk_ctrl_more
  1699. #define AIU_958_DCU_FF_CTRL MREG_AIU_958_dcu_ff_ctrl
  1700. #endif
  1701. static void enable_audio_spdif(void)
  1702. {
  1703. printk("Enable audio spdif to HDMI\n");
  1704. Wr( AIU_958_MISC, 0x204a ); // // Program the IEC958 Module in the AIU
  1705. Wr( AIU_958_FORCE_LEFT, 0x0000 );
  1706. Wr( AIU_958_CTRL, 0x0240 );
  1707. /* enable audio*/
  1708. hdmi_wr_reg(TX_AUDIO_I2S, 0x0 ); // Address 0x5A=0x0 TX_AUDIO_I2S
  1709. hdmi_wr_reg(TX_AUDIO_SPDIF, 1); // TX AUDIO SPDIF Enable
  1710. Wr(AIU_CLK_CTRL, Rd(AIU_CLK_CTRL) | 2); // enable iec958 clock which is audio_master_clk
  1711. Wr( AIU_958_BPF, 0x0100 ); // Set the PCM frame size to 256 bytes
  1712. Wr( AIU_958_DCU_FF_CTRL, 0x0001 );
  1713. Wr(AIU_I2S_MISC, Rd(AIU_I2S_MISC)|0x18); //i2s_to_958 directly
  1714. #ifdef AML_A3
  1715. //hdmi 958 clk = amclk/128/2;
  1716. Wr(AIU_CLK_CTRL, (Rd(AIU_CLK_CTRL)&(~(0x3<<4))&(~(1<<12)))|(0x1<<4));
  1717. #endif
  1718. }
  1719. static void enable_audio_i2s(void)
  1720. {
  1721. printk("Enable audio i2s to HDMI\n");
  1722. hdmi_wr_reg(TX_AUDIO_I2S, 0x1 ); // Address 0x5A=0x0 TX_AUDIO_I2S
  1723. hdmi_wr_reg(TX_AUDIO_SPDIF, 0); // TX AUDIO SPDIF Enable
  1724. Wr(AIU_CLK_CTRL, Rd(AIU_CLK_CTRL) | 3); // enable iec958 clock which is audio_master_clk
  1725. Wr(AIU_CLK_CTRL, (Rd(AIU_CLK_CTRL)&(~(0x3 << 4)))|(1<<4));
  1726. #ifdef AML_A3
  1727. //hdmi 958 clk = amclk/128/2;
  1728. Wr(AIU_CLK_CTRL, (Rd(AIU_CLK_CTRL)&(~(0x3<<4))&(~(1<<12)))|(0x1<<4));
  1729. #endif
  1730. }
  1731. /************************************
  1732. * hdmitx hardware level interface
  1733. *************************************/
  1734. static unsigned char hdmitx_m3_getediddata(hdmitx_dev_t* hdmitx_device)
  1735. {
  1736. if(hdmi_rd_reg(TX_HDCP_ST_EDID_STATUS) & (1<<4)){
  1737. if((hdmitx_device->cur_edid_block+2)<=EDID_MAX_BLOCK){
  1738. int ii, jj;
  1739. for(jj=0;jj<2;jj++){
  1740. #ifdef LOG_EDID
  1741. int edid_log_pos=0;
  1742. edid_log_pos+=snprintf((char*)hdmitx_device->tmp_buf+edid_log_pos, HDMI_TMP_BUF_SIZE-edid_log_pos, "EDID Interrupt cur block %d:",hdmitx_device->cur_edid_block);
  1743. #endif
  1744. for(ii=0;ii<128;ii++){
  1745. hdmitx_device->EDID_buf[hdmitx_device->cur_edid_block*128+ii]
  1746. =hdmi_rd_reg(0x600+hdmitx_device->cur_phy_block_ptr*128+ii);
  1747. #ifdef LOG_EDID
  1748. if((ii&0xf)==0)
  1749. edid_log_pos+=snprintf((char*)hdmitx_device->tmp_buf+edid_log_pos, HDMI_TMP_BUF_SIZE-edid_log_pos, "\n");
  1750. edid_log_pos+=snprintf((char*)hdmitx_device->tmp_buf+edid_log_pos, HDMI_TMP_BUF_SIZE-edid_log_pos, "%02x ",hdmitx_device->EDID_buf[hdmitx_device->cur_edid_block*128+ii]);
  1751. #endif
  1752. }
  1753. #ifdef LOG_EDID
  1754. hdmitx_device->tmp_buf[edid_log_pos]=0;
  1755. hdmi_print_buf((char*)hdmitx_device->tmp_buf, strlen((char*)hdmitx_device->tmp_buf));
  1756. hdmi_print(0,"\n");
  1757. #endif
  1758. hdmitx_device->cur_edid_block++;
  1759. hdmitx_device->cur_phy_block_ptr++;
  1760. hdmitx_device->cur_phy_block_ptr=hdmitx_device->cur_phy_block_ptr&0x3;
  1761. }
  1762. }
  1763. return 1;
  1764. }
  1765. else{
  1766. return 0;
  1767. }
  1768. }
  1769. static void check_chip_type(void)
  1770. {
  1771. #ifndef AML_A3
  1772. if(Rd(HHI_MPEG_CLK_CNTL)&(1<<11)){ //audio pll is selected as video clk
  1773. if(hdmi_chip_type != HDMI_M1A){
  1774. hdmi_chip_type = HDMI_M1A;
  1775. hdmi_print(1,"Set HDMI:Chip A\n");
  1776. }
  1777. }
  1778. else{
  1779. if((hdmi_chip_type != HDMI_M1B)&&(hdmi_chip_type != HDMI_M1C)){
  1780. hdmi_chip_type = HDMI_M1C;
  1781. hdmi_print(1,"Set HDMI:Chip C\n");
  1782. }
  1783. }
  1784. #endif
  1785. }
  1786. #if 0
  1787. // Only applicable if external HPD is on and stable.
  1788. // This function generates an HDMI TX internal sys_trigger pulse that will
  1789. // restart EDID and then HDCP transfer on DDC channel.
  1790. static void restart_edid_hdcp (void)
  1791. {
  1792. // Force clear HDMI TX internal sys_trigger
  1793. hdmi_wr_reg(TX_HDCP_EDID_CONFIG, hdmi_rd_reg(TX_HDCP_EDID_CONFIG) & ~(1<<6)); // Release sys_trigger_config
  1794. hdmi_wr_reg(TX_HDCP_EDID_CONFIG, hdmi_rd_reg(TX_HDCP_EDID_CONFIG) | (1<<1)); // Assert sys_trigger_config_semi_manu
  1795. // Wait some time for both TX and RX to reset DDC channel
  1796. delay_us(10);
  1797. // Recover HDMI TX internal sys_trigger
  1798. hdmi_wr_reg(TX_HDCP_EDID_CONFIG, hdmi_rd_reg(TX_HDCP_EDID_CONFIG) | (1<<6)); // Assert sys_trigger_config
  1799. hdmi_wr_reg(TX_HDCP_EDID_CONFIG, hdmi_rd_reg(TX_HDCP_EDID_CONFIG) & ~(1<<1)); // Release sys_trigger_config_semi_manu
  1800. }
  1801. #endif
  1802. //static void hdmitx_set_tvenc_reg(int cur_VIC)
  1803. //{
  1804. // int i,j;
  1805. // for(i=0;hdmi_tvenc_configs[i].vic!=HDMI_Unkown;i++){
  1806. // if(cur_VIC==hdmi_tvenc_configs[i].vic){
  1807. // const reg_t* reg_set=hdmi_tvenc_configs[i].reg_set;
  1808. // for(j=0;reg_set[j].reg;j++){
  1809. // Wr(reg_set[j].reg,reg_set[j].val);
  1810. // }
  1811. // break;
  1812. // }
  1813. // }
  1814. //}
  1815. static void hdmitx_dump_tvenc_reg(int cur_VIC, int printk_flag)
  1816. {
  1817. int i,j;
  1818. for(i=0;hdmi_tvenc_configs[i].vic!=HDMI_Unkown;i++){
  1819. if(cur_VIC==hdmi_tvenc_configs[i].vic){
  1820. reg_t* reg_set=hdmi_tvenc_configs[i].reg_set;
  1821. hdmi_print(printk_flag, "------dump tevenc reg for mode %d----\n", cur_VIC);
  1822. for(j=0;reg_set[j].reg;j++){
  1823. hdmi_print(printk_flag, "[%08x]=%08x\n",reg_set[j].reg,Rd(reg_set[j].reg));
  1824. }
  1825. hdmi_print(printk_flag, "------------------\n");
  1826. break;
  1827. }
  1828. }
  1829. }
  1830. static void hdmitx_config_tvenc_reg(int vic, unsigned reg, unsigned val)
  1831. {
  1832. int i,j;
  1833. for(i=0;hdmi_tvenc_configs[i].vic!=HDMI_Unkown;i++){
  1834. if(vic==hdmi_tvenc_configs[i].vic){
  1835. reg_t* reg_set=hdmi_tvenc_configs[i].reg_set;
  1836. for(j=0;reg_set[j].reg;j++){
  1837. if(reg_set[j].reg==reg){
  1838. reg_set[j].val = val;
  1839. hdmi_print(1, "set [%08x]=%08x\n",reg_set[j].reg, reg_set[j].val);
  1840. break;
  1841. }
  1842. }
  1843. if(reg_set[j].reg == 0){
  1844. hdmi_print(1, "no [%08x] in config\n", reg);
  1845. }
  1846. break;
  1847. }
  1848. }
  1849. }
  1850. static void hdmitx_set_pll(Hdmi_tx_video_para_t *param)
  1851. {
  1852. HDMI_DEBUG();
  1853. printk("param->VIC:%d\n", param->VIC);
  1854. cur_vout_index = get_cur_vout_index();
  1855. // Wr_reg_bits(VPU_HDMI_SETTING, 2, 0, 2); //[ 1: 0] src_sel. 0=Disable output to HDMI; 1=Select VENC_I output to HDMI; 2=Select VENC_P output.
  1856. //reset HHI_VID_DIVIDER_CNTL
  1857. Wr(HHI_VID_DIVIDER_CNTL, Rd(HHI_VID_DIVIDER_CNTL)|(1<<7)); //0x1066[7]:SOFT_RESET_POST
  1858. Wr(HHI_VID_DIVIDER_CNTL, Rd(HHI_VID_DIVIDER_CNTL)|(1<<3)); //0x1066[3]:SOFT_RESET_PRE
  1859. Wr(HHI_VID_DIVIDER_CNTL, Rd(HHI_VID_DIVIDER_CNTL)&(~(1<<1))); //0x1066[1]:RESET_N_POST
  1860. Wr(HHI_VID_DIVIDER_CNTL, Rd(HHI_VID_DIVIDER_CNTL)&(~(1<<0))); //0x1066[0]:RESET_N_PRE
  1861. msleep(2);
  1862. Wr(HHI_VID_DIVIDER_CNTL, Rd(HHI_VID_DIVIDER_CNTL)&(~((1<<7)|(1<<3))));
  1863. Wr(HHI_VID_DIVIDER_CNTL, Rd(HHI_VID_DIVIDER_CNTL)|((1<<1)|(1<<0)));
  1864. Wr(HHI_VID_DIVIDER_CNTL, 0x10843); //0x1066, set vid_pll_clk = HPLL_CLK_OUT_DIG / 5
  1865. if(cur_vout_index !=2 ){
  1866. Wr_reg_bits(HHI_VID_CLK_CNTL, 0, 16, 3); //0x105f 0: vid_pll_clk
  1867. Wr_reg_bits(HHI_VID_CLK_CNTL, 0x1f, 0, 5); //0x105f 1: DIV1_EN
  1868. Wr_reg_bits(HHI_VID_CLK_CNTL, 1, 19, 1); //0x105f 1: CLK_EN0
  1869. }
  1870. switch(param->VIC)
  1871. {
  1872. case HDMI_480p60:
  1873. case HDMI_480p60_16x9:
  1874. case HDMI_576p50:
  1875. case HDMI_576p50_16x9:
  1876. case HDMI_480i60:
  1877. case HDMI_480i60_16x9:
  1878. case HDMI_576i50:
  1879. case HDMI_576i50_16x9:
  1880. //Wr(HHI_VID_PLL_CNTL, (3<<18)|(2<<10)|(90<<0)); //27MHz=24MHz*45/4/10
  1881. Wr(HHI_VID_PLL_CNTL, 0xc042d);//use value 0x42d calculated by "m3_pll_video.pl 1080 24 pll_out hpll"
  1882. if(cur_vout_index !=2 ){
  1883. Wr(HHI_VID_CLK_DIV, 3); //0x1059
  1884. Wr_reg_bits(HHI_HDMI_CLK_CNTL, 1, 16, 4); //cts_hdmi_tx_pixel_clk from clk_div2
  1885. }
  1886. else{
  1887. Wr_reg_bits(HHI_HDMI_CLK_CNTL, 9, 16, 4); //cts_hdmi_tx_pixel_clk from v2_clk_div2
  1888. }
  1889. break;
  1890. case HDMI_1080p30:
  1891. case HDMI_1080p24:
  1892. case HDMI_720p60:
  1893. case HDMI_720p50:
  1894. case HDMI_1080i60:
  1895. case HDMI_1080i50:
  1896. //Wr(HHI_VID_PLL_CNTL, (12<<10)|(371<<0)); //74.2MHz=24MHz*371/12/10
  1897. Wr(HHI_VID_PLL_CNTL, 0x5043e);//use value 0x15043e (0x15043e does not work in some TV, use 0x5043e) calculated by "m3_pll_video.pl 742.5 24 pll_out hpll",
  1898. if(cur_vout_index !=2 ){
  1899. Wr(HHI_VID_CLK_DIV, 0); //0x1059
  1900. Wr_reg_bits(HHI_HDMI_CLK_CNTL, 1, 16, 4); //cts_hdmi_tx_pixel_clk from clk_div2
  1901. }
  1902. else{
  1903. Wr_reg_bits(HHI_HDMI_CLK_CNTL, 9, 16, 4); //cts_hdmi_tx_pixel_clk from v2_clk_div2
  1904. }
  1905. //[19:16] 0:clk_div1 1:clk_div2 2:clk_div4 3: clk_div6 ...
  1906. break;
  1907. case HDMI_1080p60:
  1908. case HDMI_1080p50:
  1909. //Wr(HHI_VID_PLL_CNTL, (6<<10)|(371<<0)); //148.4MHz=24MHz*371/6/10
  1910. Wr(HHI_VID_PLL_CNTL, 0x43e);//use value calculated by "m3_pll_video.pl 1485 24 pll_out hpll"
  1911. if(cur_vout_index !=2 ){
  1912. Wr(HHI_VID_CLK_DIV, 1); //0x1059
  1913. Wr_reg_bits(HHI_HDMI_CLK_CNTL, 0, 16, 4); //0x1073, cts_hdmi_tx_pixel_clk from clk_div1
  1914. }
  1915. else{
  1916. Wr_reg_bits(HHI_HDMI_CLK_CNTL, 8, 16, 4); //cts_hdmi_tx_pixel_clk from v2_clk_div1
  1917. }
  1918. break;
  1919. default:
  1920. break;
  1921. }
  1922. }
  1923. static int hdmitx_m3_set_dispmode(Hdmi_tx_video_para_t *param)
  1924. {
  1925. if(param == NULL){ //disable HDMI
  1926. return 0;
  1927. }
  1928. else if((param->VIC!=HDMI_480p60)&&(param->VIC!=HDMI_480p60_16x9)
  1929. &&(param->VIC!=HDMI_576p50)&&(param->VIC!=HDMI_576p50_16x9)
  1930. &&(param->VIC!=HDMI_480i60)&&(param->VIC!=HDMI_480i60_16x9)
  1931. &&(param->VIC!=HDMI_576i50)&&(param->VIC!=HDMI_576i50_16x9)
  1932. &&(param->VIC!=HDMI_1080p30)
  1933. &&(param->VIC!=HDMI_1080p24)
  1934. &&(param->VIC!=HDMI_1080p60)&&(param->VIC!=HDMI_1080p50)
  1935. &&(param->VIC!=HDMI_720p60)&&(param->VIC!=HDMI_720p50)
  1936. &&(param->VIC!=HDMI_1080i60)&&(param->VIC!=HDMI_1080i50)){
  1937. return -1;
  1938. }
  1939. #ifdef CONFIG_AML_HDMI_TX_HDCP
  1940. hdmi_wr_reg(TX_HDCP_MODE, hdmi_rd_reg(TX_HDCP_MODE)&(~0x80)); //disable authentication
  1941. #endif
  1942. check_chip_type(); /* check chip_type again */
  1943. if((hdmi_chip_type == HDMI_M1B || hdmi_chip_type == HDMI_M1C)&&(color_depth_f != 0)){
  1944. if(color_depth_f==24)
  1945. param->color_depth = COLOR_24BIT;
  1946. else if(color_depth_f==30)
  1947. param->color_depth = COLOR_30BIT;
  1948. else if(color_depth_f==36)
  1949. param->color_depth = COLOR_36BIT;
  1950. else if(color_depth_f==48)
  1951. param->color_depth = COLOR_48BIT;
  1952. }
  1953. hdmi_print(1,"set mode VIC %d (cd%d,cs%d,pm%d,vd%d,%x) \n",param->VIC, color_depth_f, color_space_f,power_mode,power_off_vdac_flag,serial_reg_val);
  1954. if(color_space_f != 0){
  1955. param->color = color_space_f;
  1956. }
  1957. hdmitx_set_pll(param);
  1958. hdmi_hw_reset(param);
  1959. if((param->VIC==HDMI_720p60)||(param->VIC==HDMI_720p50)||
  1960. (param->VIC==HDMI_1080i60)||(param->VIC==HDMI_1080i50)){
  1961. Wr(ENCP_VIDEO_HAVON_BEGIN, Rd(ENCP_VIDEO_HAVON_BEGIN)-1);
  1962. Wr(ENCP_VIDEO_HAVON_END, Rd(ENCP_VIDEO_HAVON_END)-1);
  1963. }
  1964. switch(param->VIC){
  1965. case HDMI_480i60:
  1966. case HDMI_480i60_16x9:
  1967. case HDMI_576i50:
  1968. case HDMI_576i50_16x9:
  1969. hdmi_tvenc480i_set(param);
  1970. break;
  1971. case HDMI_1080i60:
  1972. case HDMI_1080i50:
  1973. hdmi_tvenc1080i_set(param);
  1974. break;
  1975. default:
  1976. hdmi_tvenc_set(param);
  1977. }
  1978. // if(use_tvenc_conf_flag==1){
  1979. // if((param->VIC==HDMI_480i60)||(param->VIC==HDMI_480i60_16x9)){
  1980. // hdmitx_set_tvenc_reg(param->VIC);
  1981. // }
  1982. // else{
  1983. // goto set_tvenc;
  1984. // }
  1985. // }
  1986. // else if(use_tvenc_conf_flag==2){
  1987. // hdmitx_set_tvenc_reg(param->VIC);
  1988. // }
  1989. // else{
  1990. //set_tvenc:
  1991. // if((param->VIC==HDMI_480i60)||(param->VIC==HDMI_480i60_16x9)
  1992. // ||(param->VIC==HDMI_576i50)||(param->VIC==HDMI_576i50_16x9)){
  1993. // hdmi_tvenc480i_set(param);
  1994. // }
  1995. // else if((param->VIC==HDMI_1080i60)||(param->VIC==HDMI_1080i50)){
  1996. // hdmi_tvenc1080i_set(param);
  1997. // }
  1998. // else{
  1999. // hdmi_tvenc_set(param);
  2000. // }
  2001. // }
  2002. #ifdef CONFIG_AML_HDMI_TX_HDCP
  2003. if(hdcpkey_status>=0){
  2004. hdmi_wr_reg(TX_HDCP_MODE, hdmi_rd_reg(TX_HDCP_MODE)|0x80); //enable authentication
  2005. }
  2006. else{
  2007. printk("HDMITX: HDCP Key error, disable authentication\n");
  2008. }
  2009. #endif
  2010. #ifndef AVOS
  2011. if(power_off_vdac_flag){
  2012. //video_dac_disable();
  2013. SET_CBUS_REG_MASK(VENC_VDAC_SETTING, 0x1f);
  2014. }
  2015. #endif
  2016. hdmitx_dump_tvenc_reg(param->VIC, 0);
  2017. hdmi_wr_reg(0x011, 0x0f); //Channels Power Up Setting ,"1" for Power-up ,"0" for Power-down,Bit[3:0]=CK,Data2,data1,data1,data0 Channels ;
  2018. return 0;
  2019. }
  2020. static void hdmitx_m3_set_packet(int type, unsigned char* DB, unsigned char* HB)
  2021. {
  2022. // AVI frame
  2023. int i ;
  2024. unsigned char ucData ;
  2025. unsigned int pkt_reg_base=TX_PKT_REG_AVI_INFO_BASE_ADDR;
  2026. int pkt_data_len=0;
  2027. switch(type)
  2028. {
  2029. case HDMI_PACKET_AVI:
  2030. pkt_reg_base=TX_PKT_REG_AVI_INFO_BASE_ADDR;
  2031. pkt_data_len=13;
  2032. break;
  2033. case HDMI_PACKET_VEND:
  2034. pkt_reg_base=TX_PKT_REG_VEND_INFO_BASE_ADDR;
  2035. pkt_data_len=6;
  2036. break;
  2037. case HDMI_AUDIO_INFO:
  2038. pkt_reg_base=TX_PKT_REG_AUDIO_INFO_BASE_ADDR;
  2039. pkt_data_len=9;
  2040. break;
  2041. default:
  2042. break;
  2043. }
  2044. if(DB){
  2045. for(i=0;i<pkt_data_len;i++){
  2046. hdmi_wr_reg(pkt_reg_base+i+1, DB[i]);
  2047. }
  2048. for(i = 0,ucData = 0; i < pkt_data_len ; i++)
  2049. {
  2050. ucData -= DB[i] ;
  2051. }
  2052. for(i=0; i<3; i++){
  2053. ucData -= HB[i];
  2054. }
  2055. hdmi_wr_reg(pkt_reg_base+0x00, ucData);
  2056. hdmi_wr_reg(pkt_reg_base+0x1C, HB[0]);
  2057. hdmi_wr_reg(pkt_reg_base+0x1D, HB[1]);
  2058. hdmi_wr_reg(pkt_reg_base+0x1E, HB[2]);
  2059. hdmi_wr_reg(pkt_reg_base+0x1F, 0x00ff); // Enable packet generation
  2060. }
  2061. else{
  2062. hdmi_wr_reg(pkt_reg_base+0x1F, 0x0); // disable packet generation
  2063. }
  2064. #if 0
  2065. printk("AVI:%02x\n",ucData);
  2066. for(i=0;i<13;i++)
  2067. printk("%02x ", DB[i]);
  2068. printk("\n");
  2069. for(i=0;i<3;i++)
  2070. printk("%02x ", HB[i]);
  2071. #endif
  2072. }
  2073. static void hdmitx_m3_setaudioinfoframe(unsigned char* AUD_DB, unsigned char* CHAN_STAT_BUF)
  2074. {
  2075. int i ;
  2076. unsigned char AUD_HB[3]={0x84, 0x1, 0xa};
  2077. hdmitx_m3_set_packet(HDMI_AUDIO_INFO, AUD_DB, AUD_HB);
  2078. //channel status
  2079. if(CHAN_STAT_BUF){
  2080. for(i=0;i<24;i++){
  2081. hdmi_wr_reg(TX_IEC60958_SUB1_OFFSET+i, CHAN_STAT_BUF[i]);
  2082. hdmi_wr_reg(TX_IEC60958_SUB2_OFFSET+i, CHAN_STAT_BUF[24+i]);
  2083. }
  2084. }
  2085. }
  2086. //------------------------------------------------------------------------------
  2087. // set_hdmi_audio_source(unsigned int src)
  2088. //
  2089. // Description:
  2090. // Select HDMI audio clock source, and I2S input data source.
  2091. //
  2092. // Parameters:
  2093. // src -- 0=no audio clock to HDMI; 1=pcmout to HDMI; 2=Aiu I2S out to HDMI.
  2094. //------------------------------------------------------------------------------
  2095. static void set_hdmi_audio_source(unsigned int src)
  2096. {
  2097. unsigned long data32;
  2098. unsigned int i;
  2099. switch(src)
  2100. {
  2101. case 0:
  2102. printk("No audio clock to HDMI\n");
  2103. break;
  2104. case 1:
  2105. printk("PCM out to HDMI\n");
  2106. break;
  2107. case 2:
  2108. printk("I2S out to HDMI\n");
  2109. break;
  2110. default:
  2111. printk("Audio Src clock to HDMI Error\n");
  2112. break;
  2113. }
  2114. // Disable HDMI audio clock input and its I2S input
  2115. data32 = 0;
  2116. data32 |= 0 << 4; // [5:4] hdmi_data_sel: 00=disable hdmi i2s input; 01=Select pcm data; 10=Select AIU I2S data; 11=Not allowed.
  2117. data32 |= 0 << 0; // [1:0] hdmi_clk_sel: 00=Disable hdmi audio clock input; 01=Select pcm clock; 10=Select AIU aoclk; 11=Not allowed.
  2118. Wr(AIU_HDMI_CLK_DATA_CTRL, data32);
  2119. // Enable HDMI audio clock from the selected source
  2120. data32 = 0;
  2121. data32 |= 0 << 4; // [5:4] hdmi_data_sel: 00=disable hdmi i2s input; 01=Select pcm data; 10=Select AIU I2S data; 11=Not allowed.
  2122. data32 |= src << 0; // [1:0] hdmi_clk_sel: 00=Disable hdmi audio clock input; 01=Select pcm clock; 10=Select AIU aoclk; 11=Not allowed.
  2123. Wr(AIU_HDMI_CLK_DATA_CTRL, data32);
  2124. // Wait until clock change is settled
  2125. i = 0;
  2126. while ( (((Rd(AIU_HDMI_CLK_DATA_CTRL))>>8)&0x3) != src ) {
  2127. // if (i > 255) {
  2128. // //stimulus_print("[TEST.C] Error: set_hdmi_audio_source timeout!\n");
  2129. // //stimulus_finish_fail(10);
  2130. // }
  2131. i ++;
  2132. if(i>100000)
  2133. break;
  2134. }
  2135. if(i>100000)
  2136. printk("Time out: AIU_HDMI_CLK_DATA_CTRL\n");
  2137. // Enable HDMI I2S input from the selected source
  2138. data32 = 0;
  2139. data32 |= src << 4; // [5:4] hdmi_data_sel: 00=disable hdmi i2s input; 01=Select pcm data; 10=Select AIU I2S data; 11=Not allowed.
  2140. data32 |= src << 0; // [1:0] hdmi_clk_sel: 00=Disable hdmi audio clock input; 01=Select pcm clock; 10=Select AIU aoclk; 11=Not allowed.
  2141. Wr(AIU_HDMI_CLK_DATA_CTRL, data32);
  2142. // Wait until data change is settled
  2143. i = 0;
  2144. while ((((Rd(AIU_HDMI_CLK_DATA_CTRL))>>12)&0x3) != src ) {
  2145. i++;
  2146. if(i>100000)
  2147. break;
  2148. }
  2149. if(i>100000)
  2150. printk("Time out: AIU_HDMI_CLK_DATA_CTRL\n");
  2151. } /* set_hdmi_audio_source */
  2152. static int hdmitx_m3_set_audmode(struct hdmi_tx_dev_s* hdmitx_device, Hdmi_tx_audio_para_t* audio_param)
  2153. {
  2154. unsigned int audio_N_para = 6272;
  2155. unsigned int audio_N_tolerance = 1;
  2156. // unsigned int audio_CTS = 30000;
  2157. hdmi_print(0,"HDMI DEBUG [%s] hdmitx_device->cur_VIC=[%d]\n", __FUNCTION__, hdmitx_device->cur_VIC);
  2158. //Refer to HDMI SPEC V1.4 Page 137
  2159. switch(hdmitx_device->cur_VIC)
  2160. {
  2161. //TMDS Clock:27MHz
  2162. case HDMI_480p60:
  2163. case HDMI_480p60_16x9:
  2164. case HDMI_576p50:
  2165. case HDMI_576p50_16x9:
  2166. case HDMI_480i60:
  2167. case HDMI_480i60_16x9:
  2168. case HDMI_576i50:
  2169. case HDMI_576i50_16x9:
  2170. switch(audio_param->sample_rate)
  2171. {
  2172. case FS_32K:
  2173. case FS_44K1:
  2174. audio_N_para = 6272;
  2175. break;
  2176. case FS_88K2:
  2177. audio_N_para = 12544;
  2178. break;
  2179. case FS_176K4:
  2180. audio_N_para = 25088;
  2181. break;
  2182. case FS_48K:
  2183. audio_N_para = 6144*2; // not default 6144, otherwise HDMI CTS 7-29 ACR fail
  2184. break;
  2185. case FS_96K:
  2186. audio_N_para = 12288;
  2187. break;
  2188. case FS_192K:
  2189. audio_N_para = 24576;
  2190. break;
  2191. default:
  2192. break;
  2193. }
  2194. break;
  2195. //TMDS Clock:74.176MHz
  2196. case HDMI_720p60:
  2197. case HDMI_1080i60:
  2198. case HDMI_1080p30:
  2199. case HDMI_1080p24:
  2200. switch(audio_param->sample_rate)
  2201. {
  2202. case FS_32K:
  2203. audio_N_para = 11648;
  2204. break;
  2205. case FS_44K1:
  2206. audio_N_para = 17836;
  2207. break;
  2208. case FS_88K2:
  2209. audio_N_para = 35672;
  2210. break;
  2211. case FS_176K4:
  2212. audio_N_para = 71344;
  2213. break;
  2214. case FS_48K:
  2215. audio_N_para = 11648;
  2216. break;
  2217. case FS_96K:
  2218. audio_N_para = 23296;
  2219. break;
  2220. case FS_192K:
  2221. audio_N_para = 46592;
  2222. break;
  2223. default:
  2224. break;
  2225. }
  2226. break;
  2227. //TMDS Clock:74.25MHz
  2228. case HDMI_720p50:
  2229. case HDMI_1080i50:
  2230. switch(audio_param->sample_rate)
  2231. {
  2232. case FS_32K:
  2233. audio_N_para = 4096;
  2234. break;
  2235. case FS_44K1:
  2236. audio_N_para = 6272;
  2237. break;
  2238. case FS_88K2:
  2239. audio_N_para = 12544;
  2240. break;
  2241. case FS_176K4:
  2242. audio_N_para = 25088;
  2243. break;
  2244. case FS_48K:
  2245. audio_N_para = 6144;
  2246. break;
  2247. case FS_96K:
  2248. audio_N_para = 12288;
  2249. break;
  2250. case FS_192K:
  2251. audio_N_para = 24576;
  2252. break;
  2253. default:
  2254. break;
  2255. }
  2256. break;
  2257. //TMDS Clock:148.5MHz
  2258. case HDMI_1080p50:
  2259. switch(audio_param->sample_rate)
  2260. {
  2261. case FS_32K:
  2262. audio_N_para = 4096;
  2263. break;
  2264. case FS_44K1:
  2265. audio_N_para = 6272;
  2266. break;
  2267. case FS_88K2:
  2268. audio_N_para = 12544;
  2269. break;
  2270. case FS_176K4:
  2271. audio_N_para = 25088;
  2272. break;
  2273. case FS_48K:
  2274. audio_N_para = 6144;
  2275. break;
  2276. case FS_96K:
  2277. audio_N_para = 12288;
  2278. break;
  2279. case FS_192K:
  2280. audio_N_para = 24576;
  2281. break;
  2282. default:
  2283. break;
  2284. }
  2285. break;
  2286. //TMDS Clock:148.325MHz
  2287. case HDMI_1080p60:
  2288. switch(audio_param->sample_rate)
  2289. {
  2290. case FS_32K:
  2291. audio_N_para = 11648;
  2292. break;
  2293. case FS_44K1:
  2294. audio_N_para = 8918;
  2295. break;
  2296. case FS_88K2:
  2297. audio_N_para = 17836;
  2298. break;
  2299. case FS_176K4:
  2300. audio_N_para = 35672;
  2301. break;
  2302. case FS_48K:
  2303. audio_N_para = 5824;
  2304. break;
  2305. case FS_96K:
  2306. audio_N_para = 11648;
  2307. break;
  2308. case FS_192K:
  2309. audio_N_para = 23296;
  2310. break;
  2311. default:
  2312. break;
  2313. }
  2314. break;
  2315. default:
  2316. break;
  2317. }
  2318. hdmi_wr_reg(TX_SYS1_ACR_N_0, (audio_N_para&0xff)); // N[7:0]
  2319. hdmi_wr_reg(TX_SYS1_ACR_N_1, (audio_N_para>>8)&0xff); // N[15:8]
  2320. hdmi_wr_reg(TX_SYS1_ACR_N_2, (audio_N_tolerance<<4)|((audio_N_para>>16)&0xf)); // N[19:16]
  2321. hdmi_wr_reg(TX_AUDIO_CONTROL, hdmi_rd_reg(TX_AUDIO_CONTROL)|0x1);
  2322. hdmi_wr_reg(TX_SYS0_ACR_CTS_0, 0); //audio_CTS & 0xff);
  2323. hdmi_wr_reg(TX_SYS0_ACR_CTS_1, 0); //(audio_CTS>>8) & 0xff);
  2324. hdmi_wr_reg(TX_SYS0_ACR_CTS_2, 0); //(1<<5)|(1<<4)|((audio_CTS>>16)&0xf));
  2325. set_hdmi_audio_source(i2s_to_spdif_flag ? 1 : 2);
  2326. if(i2s_to_spdif_flag)
  2327. enable_audio_spdif();
  2328. else
  2329. enable_audio_i2s();
  2330. return 0;
  2331. }
  2332. static void hdmitx_m3_setupirq(hdmitx_dev_t* hdmitx_device)
  2333. {
  2334. #ifndef AVOS
  2335. int r;
  2336. r = request_irq(INT_HDMI_TX, &intr_handler,
  2337. IRQF_SHARED, "amhdmitx",
  2338. (void *)hdmitx_device);
  2339. Rd(A9_0_IRQ_IN1_INTR_STAT_CLR);
  2340. Wr(A9_0_IRQ_IN1_INTR_MASK, Rd(A9_0_IRQ_IN1_INTR_MASK)|(1 << 25));
  2341. #ifdef CEC_SUPPORT
  2342. //CEC
  2343. r = request_irq(INT_HDMI_CEC, &cec_handler,
  2344. IRQF_SHARED, "amhdmitx",
  2345. (void *)hdmitx_device);
  2346. Wr(A9_0_IRQ_IN1_INTR_MASK, Rd(A9_0_IRQ_IN1_INTR_MASK)|(1 << 23));
  2347. //cec_test_function();
  2348. #endif
  2349. #else
  2350. AVRequestIrqContext(ISR_TYPE_GENERAL2, (1 << INT_HDMI_TX), intr_handler, NULL, (void *)hdmitx_device);
  2351. Rd(SYS_CPU_0_IRQ_IN1_INTR_STAT_CLR);
  2352. Wr(SYS_CPU_0_IRQ_IN1_INTR_MASK, Rd(SYS_CPU_0_IRQ_IN1_INTR_MASK)|(1 << INT_HDMI_TX));
  2353. #endif
  2354. }
  2355. #if 1
  2356. //Expect 8*10-Bit shift pattern data:
  2357. //
  2358. //0x2e3 = 1011100011
  2359. //0x245 = 1001000101
  2360. //0x1cb = 0111001011
  2361. //0x225 = 1000100101
  2362. //0x2da = 1011011010
  2363. //0x3e0 = 1111100000
  2364. //0x367 = 1101100111
  2365. //0x000 = 0000000000
  2366. static void turn_on_shift_pattern (void)
  2367. {
  2368. unsigned int tmp_add_data;
  2369. hdmi_wr_reg(TX_SYS0_BIST_DATA_0, 0x00);
  2370. hdmi_wr_reg(TX_SYS0_BIST_DATA_1, 0x6c);
  2371. hdmi_wr_reg(TX_SYS0_BIST_DATA_2, 0xfe);
  2372. hdmi_wr_reg(TX_SYS0_BIST_DATA_3, 0x41);
  2373. hdmi_wr_reg(TX_SYS0_BIST_DATA_4, 0x5b);
  2374. hdmi_wr_reg(TX_SYS0_BIST_DATA_5, 0x91);
  2375. hdmi_wr_reg(TX_SYS0_BIST_DATA_6, 0x3a);
  2376. hdmi_wr_reg(TX_SYS0_BIST_DATA_7, 0x9d);
  2377. hdmi_wr_reg(TX_SYS0_BIST_DATA_8, 0x68);
  2378. hdmi_wr_reg(TX_SYS0_BIST_DATA_9, 0xc7);
  2379. //tmp_add_data[7:6] = 2'b0; // audio_source_select[1:0]
  2380. //tmp_add_data[5] = 1'b0; // external_packet_enable
  2381. //tmp_add_data[4] = 1'b1 ; // internal_packet_enable
  2382. //tmp_add_data[3:2] = 2'b0; // afe_fifo_source_select_lane_1[1:0]
  2383. //tmp_add_data[1:0] = 2'd3 ; // afe_fifo_source_select_lane_0[1:0] : 0=data path; 1=injected on lane 0; 2=inject on lane 1; 3=BIST.
  2384. tmp_add_data = 0x13;
  2385. hdmi_wr_reg(TX_CORE_DATA_CAPTURE_2, tmp_add_data);
  2386. hdmi_wr_reg(TX_SYS0_BIST_CONTROL, 0x00); // Reset BIST
  2387. hdmi_wr_reg(TX_SYS0_BIST_CONTROL, 0xc0); // Enable shift pattern BIST
  2388. }
  2389. static void turn_off_shift_pattern (void)
  2390. {
  2391. unsigned int tmp_add_data;
  2392. hdmi_wr_reg(TX_SYS0_BIST_CONTROL, 0x00); // Reset BIST
  2393. //tmp_add_data[7:6] = 2'b0; // audio_source_select[1:0]
  2394. //tmp_add_data[5] = 1'b0; // external_packet_enable
  2395. //tmp_add_data[4] = 1'b1 ; // internal_packet_enable
  2396. //tmp_add_data[3:2] = 2'b0; // afe_fifo_source_select_lane_1[1:0]
  2397. //tmp_add_data[1:0] = 2'd0 ; // afe_fifo_source_select_lane_0[1:0] : 0=data path; 1=injected on lane 0; 2=inject on lane 1; 3=BIST.
  2398. tmp_add_data = 0x10;
  2399. hdmi_wr_reg(TX_CORE_DATA_CAPTURE_2, tmp_add_data);
  2400. }
  2401. static void turn_on_prbs_mode(int prbs_mode)
  2402. {
  2403. unsigned int tmp_add_data;
  2404. tmp_add_data = 0;
  2405. tmp_add_data |= 0 << 6; // [7:6] audio_source_select[1:0]
  2406. tmp_add_data |= 0 << 5; // [5] external_packet_enable
  2407. tmp_add_data |= 0 << 4; // [4] internal_packet_enable
  2408. tmp_add_data |= 0 << 2; // [3:2] afe_fifo_source_select_lane_1[1:0]: 0=DATA_PATH; 1=TMDS_LANE_0; 2=TMDS_LANE_1; 3=BIST_PATTERN
  2409. tmp_add_data |= 3 << 0; // [1:0] afe_fifo_source_select_lane_0[1:0]: 0=DATA_PATH; 1=TMDS_LANE_0; 2=TMDS_LANE_1; 3=BIST_PATTERN
  2410. hdmi_wr_reg(TX_CORE_DATA_CAPTURE_2, tmp_add_data); // 0x03
  2411. tmp_add_data = 0;
  2412. tmp_add_data |= 0 << 7; // [7] monitor_lane_1
  2413. tmp_add_data |= 0 << 4; // [6:4] monitor_select_lane_1[2:0]
  2414. tmp_add_data |= 1 << 3; // [3] monitor_lane_0
  2415. tmp_add_data |= 7 << 0; // [2:0] monitor_select_lane_0[2:0]: 7=TMDS_ENCODE
  2416. hdmi_wr_reg(TX_CORE_DATA_MONITOR_1, tmp_add_data); // 0x0f
  2417. // Program PRBS_MODE
  2418. hdmi_wr_reg(TX_SYS1_PRBS_DATA, prbs_mode); // 0=PRBS 11; 1=PRBS 15; 2=PRBS 7; 3=PRBS 31.
  2419. // Program PRBS BIST
  2420. tmp_add_data = 0;
  2421. tmp_add_data |= 1 << 7; // [7] afe_bist_enable
  2422. tmp_add_data |= 0 << 6; // [6] tmds_shift_pattern_select
  2423. tmp_add_data |= 3 << 4; // [5:4] tmds_prbs_pattern_select[1:0]:
  2424. // 0=output all 0; 1=output 8-bit pattern;
  2425. // 2=output 1-bit differential pattern; 3=output 10-bit pattern
  2426. tmp_add_data |= 0 << 3; // [3] Rsrv
  2427. tmp_add_data |= 0 << 0; // [2:0] tmds_repeat_bist_pattern[2:0]
  2428. hdmi_wr_reg(TX_SYS0_BIST_CONTROL, tmp_add_data); // 0xb0
  2429. printk("PRBS mode %d On\n", prbs_mode);
  2430. }
  2431. #endif
  2432. static void hdmitx_m3_uninit(hdmitx_dev_t* hdmitx_device)
  2433. {
  2434. #ifndef AVOS
  2435. Rd(A9_0_IRQ_IN1_INTR_STAT_CLR);
  2436. Wr(A9_0_IRQ_IN1_INTR_MASK, Rd(A9_0_IRQ_IN1_INTR_MASK)&(~(1 << 25)));
  2437. free_irq(INT_HDMI_TX, (void *)hdmitx_device);
  2438. #ifdef CEC_SUPPORT
  2439. //CEC
  2440. Wr(A9_0_IRQ_IN1_INTR_MASK, Rd(A9_0_IRQ_IN1_INTR_MASK)&(~(1 << 23)));
  2441. free_irq(INT_HDMI_CEC, (void *)hdmitx_device);
  2442. #endif
  2443. #ifdef HPD_DELAY_CHECK
  2444. del_timer(&hpd_timer);
  2445. #endif
  2446. #endif
  2447. hdmi_print(1,"power off hdmi, unmux hpd\n");
  2448. phy_pll_off();
  2449. digital_clk_off(7); //off sys clk
  2450. unmux_hpd();
  2451. }
  2452. static int hdmitx_m3_cntl(hdmitx_dev_t* hdmitx_device, int cmd, unsigned argv)
  2453. {
  2454. if(cmd == HDMITX_HWCMD_POWERMODE_SWITCH){
  2455. power_mode=argv;
  2456. hdmi_hw_set_powermode(power_mode, hdmitx_device->cur_VIC);
  2457. }
  2458. #ifndef AVOS
  2459. else if(cmd == HDMITX_HWCMD_VDAC_OFF){
  2460. power_off_vdac_flag=1;
  2461. //video_dac_disable();
  2462. SET_CBUS_REG_MASK(VENC_VDAC_SETTING, 0x1f);
  2463. }
  2464. #endif
  2465. else if(cmd == HDMITX_HWCMD_MUX_HPD_IF_PIN_HIGH){
  2466. /* turnon digital module if gpio is high */
  2467. if(is_hpd_muxed() == 0){
  2468. if(read_hpd_gpio()){
  2469. hdmi_print(1,"mux hpd\n");
  2470. digital_clk_on(4);
  2471. delay_us(1000*100);
  2472. mux_hpd();
  2473. }
  2474. }
  2475. }
  2476. else if(cmd == HDMITX_HWCMD_MUX_HPD){
  2477. mux_hpd();
  2478. }
  2479. // For test only.
  2480. else if(cmd == HDMITX_HWCMD_TURNOFF_HDMIHW){
  2481. int unmux_hpd_flag = argv;
  2482. // WRITE_MPEG_REG(VENC_DVI_SETTING, READ_MPEG_REG(VENC_DVI_SETTING)&(~(1<<13))); //bit 13 is used by HDMI only
  2483. // digital_clk_on(4); //enable sys clk so that hdmi registers can be accessed when calling phy_pll_off/digit_clk_off
  2484. if(unmux_hpd_flag){
  2485. hdmi_print(1,"power off hdmi, unmux hpd\n");
  2486. phy_pll_off();
  2487. digital_clk_off(7); //off sys clk
  2488. unmux_hpd();
  2489. }
  2490. // else{
  2491. // hdmi_print(1,"power off hdmi\n");
  2492. // digital_clk_on(6);
  2493. // phy_pll_off(); //should call digital_clk_on(), otherwise hdmi_rd/wr_reg will hungup
  2494. // digital_clk_off(3); //do not off sys clk
  2495. // }
  2496. }
  2497. // else if(cmd == HDMITX_HWCMD_TURNOFF_HDMIHW){
  2498. // int unmux_hpd_flag = argv;
  2499. // WRITE_MPEG_REG(VENC_DVI_SETTING, READ_MPEG_REG(VENC_DVI_SETTING)&(~(1<<13))); //bit 13 is used by HDMI only
  2500. // digital_clk_on(4); //enable sys clk so that hdmi registers can be accessed when calling phy_pll_off/digit_clk_off
  2501. // if(unmux_hpd_flag){
  2502. // hdmi_print(1,"power off hdmi, unmux hpd\n");
  2503. // phy_pll_off();
  2504. // digital_clk_off(7); //off sys clk
  2505. // unmux_hpd();
  2506. // }
  2507. // else{
  2508. // hdmi_print(1,"power off hdmi\n");
  2509. // phy_pll_off();
  2510. // digital_clk_off(3); //do not off sys clk
  2511. // }
  2512. // }
  2513. else if(cmd == HDMITX_HWCMD_TURN_ON_PRBS){
  2514. turn_on_prbs_mode(argv);
  2515. }
  2516. else if(cmd == HDMITX_OUTPUT_ENABLE){
  2517. //Channels Power Up Setting ,"1" for Power-up ,"0" for Power-down,Bit[3:0]=CK,Data2,data1,data1,data0 Channels ;
  2518. if(argv){
  2519. hdmi_wr_reg(0x011, hdmi_rd_reg(0x011)|0xf);
  2520. }
  2521. else{
  2522. hdmi_wr_reg(0x011, hdmi_rd_reg(0x011)&(~0xf));
  2523. }
  2524. }
  2525. else if(cmd == HDMITX_GET_AUTHENTICATE_STATE){
  2526. if(((hdmi_rd_reg(TX_HDCP_ST_AUTHENTICATION)&0xf)==0x4)
  2527. &&((hdmi_rd_reg(TX_HDCP_ST_STATUS_3)&0xa0)==0xa0)){
  2528. return 1;
  2529. }
  2530. else{
  2531. return 0;
  2532. }
  2533. }
  2534. }
  2535. #if 0
  2536. #include <mach/gpio.h>
  2537. struct gpio_addr
  2538. {
  2539. unsigned long mode_addr;
  2540. unsigned long out_addr;
  2541. unsigned long in_addr;
  2542. };
  2543. static struct gpio_addr gpio_addrs[]=
  2544. {
  2545. [PREG_EGPIO]={PREG_EGPIO_EN_N,PREG_EGPIO_O,PREG_EGPIO_I},
  2546. [PREG_FGPIO]={PREG_FGPIO_EN_N,PREG_FGPIO_O,PREG_FGPIO_I},
  2547. [PREG_GGPIO]={PREG_GGPIO_EN_N,PREG_GGPIO_O,PREG_GGPIO_I},
  2548. [PREG_HGPIO]={PREG_HGPIO_EN_N,PREG_HGPIO_O,PREG_HGPIO_I},
  2549. };
  2550. static int set_gpio_valaaa(gpio_bank_t bank,int bit,unsigned long val)
  2551. {
  2552. unsigned long addr=gpio_addrs[bank].out_addr;
  2553. WRITE_CBUS_REG_BITS(addr,val?1:0,bit,1);
  2554. return 0;
  2555. }
  2556. static unsigned long get_gpio_valaaa(gpio_bank_t bank,int bit)
  2557. {
  2558. unsigned long addr=gpio_addrs[bank].in_addr;
  2559. return READ_CBUS_REG_BITS(addr,bit,1);
  2560. }
  2561. static int set_gpio_modeaaa(gpio_bank_t bank,int bit,gpio_mode_t mode)
  2562. {
  2563. unsigned long addr=gpio_addrs[bank].mode_addr;
  2564. WRITE_CBUS_REG_BITS(addr,mode,bit,1);
  2565. return 0;
  2566. }
  2567. static gpio_mode_t get_gpio_modeaaa(gpio_bank_t bank,int bit)
  2568. {
  2569. unsigned long addr=gpio_addrs[bank].mode_addr;
  2570. return (READ_CBUS_REG_BITS(addr,bit,1)>0)?(GPIO_INPUT_MODE):(GPIO_OUTPUT_MODE);
  2571. }
  2572. #endif
  2573. static void hdmitx_print_info(hdmitx_dev_t* hdmitx_device, int printk_flag)
  2574. {
  2575. hdmi_print(printk_flag, "------------------\nHdmitx driver version: %s\nSerial %x\nColor Depth %d\n", HDMITX_VER, serial_reg_val, color_depth_f);
  2576. hdmi_print(printk_flag, "chip type %c\n", hdmi_chip_type);
  2577. hdmi_print(printk_flag, "current vout index %d\n", cur_vout_index);
  2578. hdmi_print(printk_flag, "reset sequence %d\n", new_reset_sequence_flag);
  2579. hdmi_print(printk_flag, "power mode %d\n", power_mode);
  2580. hdmi_print(printk_flag, "%spowerdown when unplug\n",hdmitx_device->unplug_powerdown?"":"do not ");
  2581. hdmi_print(printk_flag, "use_tvenc_conf_flag=%d\n",use_tvenc_conf_flag);
  2582. hdmi_print(printk_flag, "vdac %s\n", power_off_vdac_flag?"off":"on");
  2583. hdmi_print(printk_flag, "hdmi audio %s\n", hdmi_audio_off_flag?"off":"on");
  2584. if(!hdmi_audio_off_flag){
  2585. hdmi_print(printk_flag, "audio out type %s\n", i2s_to_spdif_flag?"spdif":"i2s");
  2586. }
  2587. hdmi_print(printk_flag, "delay flag %d\n", delay_flag);
  2588. hdmi_print(printk_flag, "------------------\n");
  2589. }
  2590. static void hdmitx_m3_debug(hdmitx_dev_t* hdmitx_device, const char* buf)
  2591. {
  2592. #ifndef AVOS
  2593. char tmpbuf[128];
  2594. int i=0;
  2595. unsigned int adr;
  2596. unsigned int value=0;
  2597. while((buf[i])&&(buf[i]!=',')&&(buf[i]!=' ')){
  2598. tmpbuf[i]=buf[i];
  2599. i++;
  2600. }
  2601. tmpbuf[i]=0;
  2602. if((strncmp(tmpbuf, "dumpreg", 7)==0) || (strncmp(tmpbuf, "dumptvencreg", 12)==0)){
  2603. hdmitx_dump_tvenc_reg(hdmitx_device->cur_VIC, 1);
  2604. return;
  2605. }
  2606. else if(strncmp(tmpbuf, "dumphdmireg", 11)==0){
  2607. unsigned char reg_val = 0;
  2608. unsigned int reg_adr = 0;
  2609. for (reg_adr = 0; reg_adr < 0x800; reg_adr ++){ //HDMI Regs address range: 0 ~ 0x7ff
  2610. reg_val = hdmi_rd_reg(reg_adr);
  2611. printk("HDMI[0x%x]: 0x%x\n", reg_adr, reg_val);
  2612. }
  2613. return ;
  2614. }
  2615. else if(strncmp(tmpbuf, "dumpcbusreg", 11)==0){
  2616. unsigned j;
  2617. adr=simple_strtoul(tmpbuf+11, NULL, 16); //CBUS Start addr
  2618. value=simple_strtoul(buf+i+1, NULL, 16); //CBUS End addr
  2619. for(j = 0 ; j < value-adr+1 ; j++){
  2620. printk("CBUS[0x%x]: 0x%x\n", adr+j, READ_MPEG_REG(adr+j));
  2621. }
  2622. }
  2623. else if(strncmp(tmpbuf, "pllcalc", 7)==0){
  2624. adr=simple_strtoul(tmpbuf+7, NULL, 10);
  2625. if((adr == 0) && (*(tmpbuf+7) != 'a')){
  2626. printk("CTS_VDAC_CLK1: %uMHz\n", clk_util_clk_msr(CTS_VDAC_CLK1));
  2627. printk("CTS_VDAC_CLK0: %uMHz\n", clk_util_clk_msr(CTS_VDAC_CLK0));
  2628. printk("CTS_A9_CLK: %uMHz\n", clk_util_clk_msr(CTS_A9_CLK));
  2629. printk("CTS_DDR_CLK: %uMHz\n", clk_util_clk_msr(CTS_DDR_CLK));
  2630. printk("LVDS_FIFO_CLK: %uMHz\n", clk_util_clk_msr(LVDS_FIFO_CLK));
  2631. printk("MOD_AUDIN_AMCLK_I: %uMHz\n", clk_util_clk_msr(MOD_AUDIN_AMCLK_I));
  2632. printk("CTS_AMCLK: %uMHz\n", clk_util_clk_msr(CTS_AMCLK));
  2633. printk("CLK81: %uMHz\n", clk_util_clk_msr(CLK81));
  2634. printk("AUD_PLL_CLK: %uMHz\n", clk_util_clk_msr(AUD_PLL_CLK));
  2635. printk("MISC_PLL_CLK: %uMHz\n", clk_util_clk_msr(MISC_PLL_CLK));
  2636. printk("DDR_PLL_CLK: %uMHz\n", clk_util_clk_msr(DDR_PLL_CLK));
  2637. printk("SYS_PLL_CLK: %uMHz\n", clk_util_clk_msr(SYS_PLL_CLK));
  2638. printk("CTS_HDMI_TX_PIXEL_CLK: %uMHz\n", clk_util_clk_msr(CTS_HDMI_TX_PIXEL_CLK));
  2639. printk("HDMI_CH3_TMDSCLK: %uMHz\n", clk_util_clk_msr(HDMI_CH3_TMDSCLK));
  2640. printk("CTS_HDMI_SYS_CLK: %uMHz\n", clk_util_clk_msr(CTS_HDMI_SYS_CLK));
  2641. printk("VID2_PLL_CLK: %uMHz\n", clk_util_clk_msr(VID2_PLL_CLK));
  2642. printk("VID_PLL_CLK: %uMHz\n", clk_util_clk_msr(VID_PLL_CLK));
  2643. printk("CTS_ENCI_CLK: %uMHz\n", clk_util_clk_msr(CTS_ENCI_CLK));
  2644. printk("CTS_ENCT_CLK: %uMHz\n", clk_util_clk_msr(CTS_ENCT_CLK));
  2645. printk("CTS_ENCL_CLK: %uMHz\n", clk_util_clk_msr(CTS_ENCL_CLK));
  2646. printk("CTS_ENCP_CLK: %uMHz\n", clk_util_clk_msr(CTS_ENCP_CLK));
  2647. }
  2648. else{
  2649. if(adr < 46)
  2650. printk("Tree[%d] clk: %uMHz\n", adr, clk_util_clk_msr(adr));
  2651. }
  2652. if(*(tmpbuf+7) == 'a'){
  2653. for(adr = 0; adr < 46; adr ++){
  2654. printk("Tree[%d] clk: %uMHz\n", adr, clk_util_clk_msr(adr));
  2655. }
  2656. }
  2657. return;
  2658. }
  2659. else if(strncmp(tmpbuf, "hdmiaudio", 9)==0){
  2660. value=simple_strtoul(tmpbuf+9, NULL, 16);
  2661. if(value == 1){
  2662. hdmi_audio_off_flag = 1;
  2663. hdmi_audio_init(i2s_to_spdif_flag);
  2664. }
  2665. else if(value == 0){
  2666. hdmi_audio_off_flag = 0;
  2667. hdmi_wr_reg(TX_AUDIO_PACK, 0x00); // disable audio sample packets
  2668. }
  2669. return;
  2670. }
  2671. else if(strncmp(tmpbuf, "cfgreg", 6)==0){
  2672. adr=simple_strtoul(tmpbuf+6, NULL, 16);
  2673. value=simple_strtoul(buf+i+1, NULL, 16);
  2674. hdmitx_config_tvenc_reg(hdmitx_device->cur_VIC, adr, value);
  2675. return;
  2676. }
  2677. else if(strncmp(tmpbuf, "tvenc_flag", 10)==0){
  2678. use_tvenc_conf_flag = tmpbuf[10]-'0';
  2679. printk("set use_tvenc_conf_flag = %d\n", use_tvenc_conf_flag);
  2680. }
  2681. #ifdef CEC_SUPPORT
  2682. else if(tmpbuf[0]=='c'){
  2683. cec_test_function();
  2684. }
  2685. #endif
  2686. else if(strncmp(tmpbuf, "ignore_unplug_on", 16)==0){
  2687. hpd_debug_mode|=HPD_DEBUG_IGNORE_UNPLUG;
  2688. }
  2689. else if(strncmp(tmpbuf, "force_plug_off", 17)==0){
  2690. hpd_debug_mode&=~HPD_DEBUG_IGNORE_UNPLUG;
  2691. }
  2692. else if(strncmp(tmpbuf, "reset", 5)==0){
  2693. if(tmpbuf[5]=='0')
  2694. new_reset_sequence_flag=0;
  2695. else
  2696. new_reset_sequence_flag=1;
  2697. return;
  2698. }
  2699. else if(strncmp(tmpbuf, "delay_flag", 10)==0){
  2700. delay_flag = tmpbuf[10]-'0';
  2701. }
  2702. else if(tmpbuf[0]=='v'){
  2703. hdmitx_print_info(hdmitx_device, 1);
  2704. return;
  2705. }
  2706. else if(tmpbuf[0]=='s'){
  2707. serial_reg_val=simple_strtoul(tmpbuf+1,NULL,16);
  2708. return;
  2709. }
  2710. else if(tmpbuf[0]=='c'){
  2711. if(tmpbuf[1]=='d'){
  2712. color_depth_f=simple_strtoul(tmpbuf+2,NULL,10);
  2713. if((color_depth_f!=24)&&(color_depth_f!=30)&&(color_depth_f!=36)){
  2714. printk("Color depth %d is not supported\n", color_depth_f);
  2715. color_depth_f=0;
  2716. }
  2717. return;
  2718. }
  2719. else if(tmpbuf[1]=='s'){
  2720. color_space_f=simple_strtoul(tmpbuf+2,NULL,10);
  2721. if(color_space_f>2){
  2722. printk("Color space %d is not supported\n", color_space_f);
  2723. color_space_f=0;
  2724. }
  2725. }
  2726. }
  2727. else if(strncmp(tmpbuf,"i2s",2)==0){
  2728. if(strncmp(tmpbuf+3,"off",3)==0)
  2729. i2s_to_spdif_flag=1;
  2730. else
  2731. i2s_to_spdif_flag=0;
  2732. }
  2733. else if(strncmp(tmpbuf, "pattern_on", 10)==0){
  2734. turn_on_shift_pattern();
  2735. printk("Shift Pattern On\n");
  2736. return;
  2737. }
  2738. else if(strncmp(tmpbuf, "pattern_off", 11)==0){
  2739. turn_off_shift_pattern();
  2740. printk("Shift Pattern Off\n");
  2741. return;
  2742. }
  2743. else if(strncmp(tmpbuf, "prbs", 4)==0){
  2744. int prbs_mode =simple_strtoul(tmpbuf+4, NULL, 10);
  2745. turn_on_prbs_mode(prbs_mode);
  2746. return;
  2747. }
  2748. else if(tmpbuf[0]=='w'){
  2749. unsigned read_back = 0;
  2750. adr=simple_strtoul(tmpbuf+2, NULL, 16);
  2751. value=simple_strtoul(buf+i+1, NULL, 16);
  2752. if(buf[1]=='h'){
  2753. hdmi_wr_reg(adr, value);
  2754. read_back = hdmi_rd_reg(adr);
  2755. }
  2756. else if(buf[1]=='c'){
  2757. WRITE_MPEG_REG(adr, value);
  2758. read_back = READ_MPEG_REG(adr);
  2759. }
  2760. else if(buf[1]=='p'){
  2761. WRITE_APB_REG(adr, value);
  2762. read_back = READ_APB_REG(adr);
  2763. }
  2764. printk("write %x to %s reg[%x]\n",value,buf[1]=='p'?"APB":(buf[1]=='h'?"HDMI":"CBUS"), adr);
  2765. //Add read back function in order to judge writting is OK or NG.
  2766. printk("Read Back %s reg[%x]=%x\n",buf[1]=='p'?"APB":(buf[1]=='h'?"HDMI":"CBUS"), adr, read_back);
  2767. }
  2768. else if(tmpbuf[0]=='r'){
  2769. adr=simple_strtoul(tmpbuf+2, NULL, 16);
  2770. if(buf[1]=='h'){
  2771. value = hdmi_rd_reg(adr);
  2772. }
  2773. else if(buf[1]=='c'){
  2774. value = READ_MPEG_REG(adr);
  2775. }
  2776. else if(buf[1]=='p'){
  2777. value = READ_APB_REG(adr);
  2778. }
  2779. printk("%s reg[%x]=%x\n",buf[1]=='p'?"APB":(buf[1]=='h'?"HDMI":"CBUS"), adr, value);
  2780. }
  2781. #endif
  2782. }
  2783. #ifdef HPD_DELAY_CHECK
  2784. static void hpd_post_process(unsigned long arg)
  2785. {
  2786. hdmitx_dev_t* hdmitx_device = (hdmitx_dev_t*)arg;
  2787. hdmi_print(1,"hpd_post_process\n");
  2788. if (hdmi_rd_reg(TX_HDCP_ST_EDID_STATUS) & (1<<1)) {
  2789. // Start DDC transaction
  2790. hdmi_wr_reg(TX_HDCP_EDID_CONFIG, hdmi_rd_reg(TX_HDCP_EDID_CONFIG) | (1<<6)); // Assert sys_trigger_config
  2791. hdmi_wr_reg(TX_HDCP_EDID_CONFIG, hdmi_rd_reg(TX_HDCP_EDID_CONFIG) & ~(1<<1)); // Release sys_trigger_config_semi_manu
  2792. hdmitx_device->cur_edid_block=0;
  2793. hdmitx_device->cur_phy_block_ptr=0;
  2794. hdmitx_device->hpd_event = 1;
  2795. hdmi_print(1,"hpd_event 1\n");
  2796. }
  2797. else{ //HPD falling
  2798. hdmi_wr_only_reg(OTHER_BASE_ADDR + HDMI_OTHER_INTR_STAT_CLR, 1 << 1); //clear HPD falling interrupt in hdmi module
  2799. hdmi_wr_reg(TX_HDCP_EDID_CONFIG, hdmi_rd_reg(TX_HDCP_EDID_CONFIG) & ~(1<<6)); // Release sys_trigger_config
  2800. hdmi_wr_reg(TX_HDCP_EDID_CONFIG, hdmi_rd_reg(TX_HDCP_EDID_CONFIG) | (1<<1)); // Assert sys_trigger_config_semi_manu
  2801. hdmitx_device->hpd_event = 2;
  2802. hdmi_print(1,"hpd_event 2\n");
  2803. }
  2804. del_timer(&hpd_timer);
  2805. }
  2806. #endif
  2807. void HDMITX_M1B_Init(hdmitx_dev_t* hdmitx_device)
  2808. {
  2809. hdmitx_device->HWOp.SetPacket = hdmitx_m3_set_packet;
  2810. hdmitx_device->HWOp.SetAudioInfoFrame = hdmitx_m3_setaudioinfoframe;
  2811. hdmitx_device->HWOp.GetEDIDData = hdmitx_m3_getediddata;
  2812. hdmitx_device->HWOp.SetDispMode = hdmitx_m3_set_dispmode;
  2813. hdmitx_device->HWOp.SetAudMode = hdmitx_m3_set_audmode;
  2814. hdmitx_device->HWOp.SetupIRQ = hdmitx_m3_setupirq;
  2815. hdmitx_device->HWOp.DebugFun = hdmitx_m3_debug;
  2816. hdmitx_device->HWOp.UnInit = hdmitx_m3_uninit;
  2817. hdmitx_device->HWOp.Cntl = hdmitx_m3_cntl;
  2818. #ifdef HPD_DELAY_CHECK
  2819. /*hdp timer*/
  2820. init_timer(&hpd_timer);
  2821. hpd_timer.function = &hpd_post_process;
  2822. hpd_timer.data = (unsigned long)hdmitx_device;
  2823. /**/
  2824. #endif
  2825. if(hdmi_chip_type==0){
  2826. check_chip_type();
  2827. }
  2828. // 1=Map data pins from Venc to Hdmi Tx as RGB mode.
  2829. // --------------------------------------------------------
  2830. // Configure HDMI TX analog, and use HDMI PLL to generate TMDS clock
  2831. // --------------------------------------------------------
  2832. // Enable APB3 fail on error
  2833. WRITE_APB_REG(HDMI_CNTL_PORT, READ_APB_REG(HDMI_CNTL_PORT)|(1<<15)); //APB3 err_en
  2834. /**/
  2835. hdmi_hw_init(hdmitx_device);
  2836. #ifdef CEC_SUPPORT
  2837. /*cec config*/
  2838. hdmi_wr_reg(CEC0_BASE_ADDR+CEC_CLOCK_DIV_L, 0x003F ),
  2839. hdmi_wr_reg(CEC0_BASE_ADDR+CEC_LOGICAL_ADDR0, (0x1 << 4) | CEC0_LOG_ADDR);
  2840. #endif
  2841. }
  2842. #ifndef AVOS
  2843. static int __init hdmi_chip_select(char *s)
  2844. {
  2845. #ifndef AML_A3
  2846. switch(s[0])
  2847. {
  2848. case 'a':
  2849. case 'A':
  2850. hdmi_chip_type = HDMI_M1A;
  2851. break;
  2852. case 'b':
  2853. case 'B':
  2854. i2s_to_spdif_flag=1;
  2855. hdmi_chip_type = HDMI_M1B;
  2856. break;
  2857. default:
  2858. hdmi_chip_type = HDMI_M1C;
  2859. break;
  2860. }
  2861. #endif
  2862. return 0;
  2863. }
  2864. __setup("chip=",hdmi_chip_select);
  2865. void hdmi_set_audio_para(int para)
  2866. {
  2867. aud_para = para;
  2868. }
  2869. #endif
  2870. #ifdef CEC_SUPPORT
  2871. static int cec_echo_flag=1;
  2872. static void cec_test_function(void)
  2873. {
  2874. /* use CEC0_LOG_ADDR as target address */
  2875. int i;
  2876. unsigned char tmp_log_addr = CEC0_LOG_ADDR+1;
  2877. int cec0_msgs[] = {(tmp_log_addr << 4) | CEC0_LOG_ADDR,
  2878. 0xa1, 0xb2, 0xc3, 0xd4
  2879. };
  2880. int cec0_msg_length = 5;
  2881. cec_echo_flag=0;
  2882. printk("CEC test is starting!!!!!!!!\n");
  2883. hdmi_wr_reg(CEC0_BASE_ADDR+CEC_LOGICAL_ADDR0, (0x1 << 4) | tmp_log_addr);
  2884. for (i = 0; i < cec0_msg_length; i++)
  2885. {
  2886. hdmi_wr_reg(CEC0_BASE_ADDR+CEC_TX_MSG_0_HEADER + i, cec0_msgs[i]);
  2887. }
  2888. hdmi_wr_reg(CEC0_BASE_ADDR+CEC_TX_MSG_LENGTH, cec0_msg_length);
  2889. //hdmi_wr_reg(CEC0_BASE_ADDR+CEC_TX_MSG_CMD, TX_REQ_CURRENT);
  2890. hdmi_wr_reg(CEC0_BASE_ADDR+CEC_TX_MSG_CMD, TX_REQ_NEXT);
  2891. }
  2892. // rx_msg_cmd
  2893. #define RX_NO_OP 0 // No transaction
  2894. #define RX_ACK_CURRENT 1 // Read earliest message in buffer
  2895. #define RX_DISABLE 2 // Disable receiving latest message
  2896. #define RX_ACK_NEXT 3 // Clear earliest message from buffer and read next message
  2897. // rx_msg_status
  2898. #define RX_IDLE 0 // No transaction
  2899. #define RX_BUSY 1 // Receiver is busy
  2900. #define RX_DONE 2 // Message has been received successfully
  2901. #define RX_ERROR 3 // Message has been received with error
  2902. static irqreturn_t cec_handler(int irq, void *dev_instance)
  2903. {
  2904. unsigned int data;
  2905. int i;
  2906. //hdmitx_dev_t* hdmitx_device = (hdmitx_dev_t*)dev_instance;
  2907. data = hdmi_rd_reg(CEC0_BASE_ADDR+CEC_RX_MSG_STATUS);
  2908. if(data){
  2909. printk("CEC Irq Rx Status %x\n", data);
  2910. if((data & 0x3) == RX_DONE) {
  2911. data = hdmi_rd_reg(CEC0_BASE_ADDR + CEC_RX_NUM_MSG);
  2912. if (data == 1)
  2913. {
  2914. int rx_msg_length = hdmi_rd_reg(CEC0_BASE_ADDR + CEC_RX_MSG_LENGTH);
  2915. for (i = 0; i < rx_msg_length; i++)
  2916. {
  2917. data = hdmi_rd_reg(CEC0_BASE_ADDR + CEC_RX_MSG_0_HEADER +i);
  2918. printk("cec0 rx message %x = %x\n", i, data);
  2919. if(cec_echo_flag){ //for testing
  2920. if(i==0)
  2921. hdmi_wr_reg(CEC0_BASE_ADDR+CEC_TX_MSG_0_HEADER + i, ((data>>4)&0xf)|((data<<4)&0xf0));
  2922. else
  2923. hdmi_wr_reg(CEC0_BASE_ADDR+CEC_TX_MSG_0_HEADER + i, data);
  2924. }
  2925. }
  2926. hdmi_wr_reg(CEC0_BASE_ADDR + CEC_RX_MSG_CMD, RX_ACK_CURRENT);
  2927. if(cec_echo_flag){ //for testing
  2928. hdmi_wr_reg(CEC0_BASE_ADDR+CEC_TX_MSG_LENGTH, rx_msg_length);
  2929. //hdmi_wr_reg(CEC0_BASE_ADDR+CEC_TX_MSG_CMD, TX_REQ_CURRENT);
  2930. hdmi_wr_reg(CEC0_BASE_ADDR+CEC_TX_MSG_CMD, TX_REQ_NEXT);
  2931. }
  2932. }
  2933. else
  2934. {
  2935. printk("Error: CEC1->CEC0 transmit data fail, rx_num_msg = %x !", data);
  2936. }
  2937. }
  2938. else {
  2939. printk("Error: CEC1->CEC0 transmit data fail, msg_status = %x!", data);
  2940. }
  2941. printk ("cec successful\n");
  2942. }
  2943. data = hdmi_rd_reg(CEC0_BASE_ADDR+CEC_TX_MSG_STATUS);
  2944. if(data){
  2945. printk("CEC Irq Tx Status %x\n", data);
  2946. }
  2947. return IRQ_HANDLED;
  2948. }
  2949. #endif
  2950. // The following two functions should move to
  2951. // static struct platform_driver amhdmitx_driver.suspend & .wakeup
  2952. // For tempelet use only.
  2953. // Later will change it.
  2954. typedef struct
  2955. {
  2956. unsigned long reg;
  2957. unsigned long val_sleep;
  2958. unsigned long val_save;
  2959. }hdmi_phy_t;
  2960. static char hdmi_phy_reg_save_flag = 0;
  2961. #define HDMI_PHY_REG_NUM 9
  2962. static hdmi_phy_t hdmi_phy_reg [HDMI_PHY_REG_NUM] = {
  2963. {0x10, 0x2, 0x0},
  2964. {0x11, 0x0, 0x0},
  2965. {0x12, 0x1, 0x0},
  2966. {0x13, 0xc, 0x0},
  2967. {0x14, 0x1, 0x0},
  2968. {0x15, 0x3, 0x0},
  2969. {0x16, 0x1, 0x0},
  2970. {0x17, 0x0, 0x0},
  2971. //{0x18, 0x24,0x0}, remove this line per shichao's suggestion, rain
  2972. {0x1a, 0x3, 0x0},
  2973. };
  2974. static void hdmi_suspend(void)
  2975. {
  2976. // First backup HDMI PHY register according to Chao Shi.
  2977. int i;
  2978. #if 0
  2979. WRITE_MPEG_REG(HHI_GCLK_MPEG2, READ_MPEG_REG(HHI_GCLK_MPEG2) | (1<<4)); //Enable HDMI PCLK
  2980. WRITE_MPEG_REG(0x1073, READ_MPEG_REG(0x1073) | (1<<8));
  2981. for(i = 0 ; i< 10000; i++)
  2982. {
  2983. //Delay some time
  2984. }
  2985. #endif
  2986. for(i = 0; i < HDMI_PHY_REG_NUM; i++)
  2987. {
  2988. hdmi_phy_reg[i].val_save = hdmi_rd_reg(hdmi_phy_reg[i].reg);
  2989. }
  2990. for(i = 0; i < HDMI_PHY_REG_NUM; i++)
  2991. {
  2992. hdmi_wr_reg(hdmi_phy_reg[i].reg, hdmi_phy_reg[i].val_sleep);
  2993. }
  2994. hdmi_phy_reg_save_flag = 1;
  2995. #if 0
  2996. //move this code to digital_clk_off(), rain
  2997. // Second turn off gate.
  2998. WRITE_MPEG_REG(0x1073, 0x0);
  2999. WRITE_MPEG_REG(HHI_GCLK_MPEG2, READ_MPEG_REG(HHI_GCLK_MPEG2) & (~(1<<4))); //Disable HDMI PCLK
  3000. #endif
  3001. printk("Hdmi phy suspend\n");
  3002. }
  3003. static void hdmi_wakeup(void)
  3004. {
  3005. int i;
  3006. #if 0
  3007. //move this code to digital_clk_on(), rain
  3008. WRITE_MPEG_REG(HHI_GCLK_MPEG2, READ_MPEG_REG(HHI_GCLK_MPEG2) | (1<<4)); //Enable HDMI PCLK
  3009. WRITE_MPEG_REG(0x1073, READ_MPEG_REG(0x1073) | (1<<8));
  3010. for(i = 0 ; i< 10000; i++)
  3011. {
  3012. //Delay some time
  3013. }
  3014. #endif
  3015. if(hdmi_phy_reg_save_flag){
  3016. for(i = 0; i < HDMI_PHY_REG_NUM; i++)
  3017. {
  3018. hdmi_wr_reg(hdmi_phy_reg[i].reg, hdmi_phy_reg[i].val_save);
  3019. }
  3020. printk("Hdmi phy wakeup\n");
  3021. hdmi_phy_reg_save_flag = 0;
  3022. }
  3023. }
  3024. #if 0
  3025. static void hdcp_status_loop_check()
  3026. {
  3027. static unsigned reg190=0;
  3028. static unsigned reg192=0;
  3029. static unsigned reg195=0;
  3030. static unsigned reg19f=0;
  3031. static unsigned reg194=0;
  3032. unsigned char check_flag=0;
  3033. if(hdmi_rd_reg(0x190)!=reg190){
  3034. reg190=hdmi_rd_reg(0x190);
  3035. check_flag|=0x1;
  3036. }
  3037. if(hdmi_rd_reg(0x192)!=reg192){
  3038. reg192=hdmi_rd_reg(0x192);
  3039. check_flag|=0x2;
  3040. }
  3041. if(hdmi_rd_reg(0x195)!=reg195){
  3042. reg195=hdmi_rd_reg(0x195);
  3043. check_flag|=0x4;
  3044. }
  3045. if(hdmi_rd_reg(0x19f)!=reg19f){
  3046. reg19f=hdmi_rd_reg(0x19f);
  3047. check_flag|=0x8;
  3048. }
  3049. if(hdmi_rd_reg(0x194)!=reg194){
  3050. reg194=hdmi_rd_reg(0x194);
  3051. check_flag|=0x10;
  3052. }
  3053. if(check_flag){
  3054. printk("[%c190,%c192,%c195,%c19f,%c194]=%02x,%02x,%02x,%02x,%02x\n",
  3055. (check_flag&0x1)?'*':' ',(check_flag&0x2)?'*':' ',
  3056. (check_flag&0x4)?'*':' ',(check_flag&0x8)?'*':' ',
  3057. (check_flag&0x10)?'*':' ',
  3058. reg190,reg192,reg195,reg19f,reg194);
  3059. }
  3060. }
  3061. #endif