si_8348_drv.c 125 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648
  1. /*
  2. SiI8348 Linux Driver
  3. Copyright (C) 2013 Silicon Image, Inc.
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License as
  6. published by the Free Software Foundation version 2.
  7. This program is distributed AS-IS WITHOUT ANY WARRANTY of any
  8. kind, whether express or implied; INCLUDING without the implied warranty
  9. of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE or NON-INFRINGEMENT. See
  10. the GNU General Public License for more details at http://www.gnu.org/licenses/gpl-2.0.html.
  11. */
  12. /*
  13. @file si_8348_drv.c
  14. */
  15. //#include <linux/module.h>
  16. #include <linux/kernel.h>
  17. #include <linux/semaphore.h>
  18. #include <linux/cdev.h>
  19. #include <linux/gpio.h>
  20. #include <linux/device.h>
  21. #include <linux/delay.h>
  22. #include <linux/hrtimer.h>
  23. #include "sii_hal.h"
  24. #include "si_fw_macros.h"
  25. #include "si_app_devcap.h"
  26. #include "si_mhl_defs.h"
  27. #include "si_infoframe.h"
  28. #include "si_edid.h"
  29. #include "si_mhl2_edid_3d_api.h"
  30. #include "si_8348_internal_api.h"
  31. #include "si_mhl_tx_hw_drv_api.h"
  32. #ifdef MEDIA_DATA_TUNNEL_SUPPORT
  33. #include "si_mdt_inputdev.h"
  34. #endif
  35. #include "si_8348_drv.h"
  36. #include "mhl_linux_tx.h"
  37. #include "platform.h"
  38. #include "si_tpi_regs.h"
  39. #include "si_8348_regs.h"
  40. #include "si_timing_defs.h"
  41. #ifdef CONFIG_MTK_MT6306_SUPPORT
  42. #include<mach/dcl_sim_gpio.h>
  43. #endif
  44. #include <mach/irqs.h>
  45. #ifdef CONFIG_MTK_LEGACY
  46. /*#include "mach/eint.h"*/
  47. /*#include <cust_eint.h>*/
  48. #include <mt-plat/mt_gpio.h>
  49. /* #include <cust_gpio_usage.h> */
  50. #endif
  51. /*#include <mach/mt_gpio.h>*/
  52. #include "hdmi_drv.h"
  53. #include "mhl_supp.h"
  54. #include "smartbook.h"
  55. //#define PRINT_ALL_INTR
  56. //#define HDCP_ENABLE // TODO: FD, TBI, to disble this later
  57. extern int debug_msgs;
  58. extern struct mhl_dev_context *si_dev_context;
  59. extern enum HDMI_CABLE_TYPE MHL_Connect_type;
  60. extern bool HDCP_Supported_Info;
  61. /* external functions */
  62. int si_mhl_tx_chip_initialize(struct drv_hw_context *hw_context);
  63. /* Local functions */
  64. static int int_4_isr(struct drv_hw_context *hw_context, uint8_t int_4_status);
  65. #ifdef HDCP_ENABLE
  66. static int int_hdcp2_isr(struct drv_hw_context *hw_context, uint8_t tpi_int_status);
  67. #endif // HDCP_ENABLE
  68. /*static int to_be_deleted(struct drv_hw_context *hw_context, uint8_t int_status);*/
  69. static int int_3_isr(struct drv_hw_context *hw_context, uint8_t int_3_status);
  70. #ifdef HDCP_ENABLE
  71. static int hdcp_isr(struct drv_hw_context *hw_context, uint8_t tpi_int_status);
  72. #endif // HDCP_ENABLE
  73. static int int_1_isr(struct drv_hw_context *hw_context, uint8_t int_1_status);
  74. static int g2wb_isr(struct drv_hw_context *hw_context, uint8_t intr_stat);
  75. static int mhl_cbus_isr(struct drv_hw_context *hw_context, uint8_t cbus_int);
  76. static int mhl_cbus_err_isr(struct drv_hw_context *hw_context, uint8_t cbus_err_int);
  77. static void board_reset(struct drv_hw_context *hw_context, uint16_t hwResetPeriod, uint16_t hwResetDelay);
  78. static int get_device_rev(struct drv_hw_context *hw_context);
  79. static void enable_intr(struct drv_hw_context *hw_context, uint8_t intr_num, uint8_t intr_mask);
  80. static void switch_to_d3(struct drv_hw_context *hw_context,bool do_interrupt_clear);
  81. static void disconnect_mhl(struct drv_hw_context *hw_context,bool do_interrupt_clear);
  82. #ifdef HDCP_ENABLE
  83. static void start_hdcp(struct drv_hw_context *hw_context);
  84. #endif // HDCP_ENABLE
  85. static void stop_video(struct drv_hw_context *hw_context);
  86. static void unmute_video(struct drv_hw_context *hw_context);
  87. static int set_hdmi_params(struct mhl_dev_context *dev_context);
  88. static int start_video(struct drv_hw_context *hw_context, void *edid_parser_context);
  89. /*static int get_cbus_connection_status(struct drv_hw_context *hw_context);*/
  90. // Video Mode Constants
  91. //====================================================
  92. #define VMD_ASPECT_RATIO_4x3 0x01
  93. #define VMD_ASPECT_RATIO_16x9 0x02
  94. //====================================================
  95. typedef struct
  96. {
  97. uint8_t inputColorSpace;
  98. uint8_t outputColorSpace;
  99. uint8_t inputVideoCode;
  100. uint8_t inputcolorimetryAspectRatio;
  101. uint8_t outputcolorimetryAspectRatio;
  102. uint8_t input_AR;
  103. uint8_t output_AR;
  104. } video_data_t;
  105. video_data_t video_data;
  106. //====================================================
  107. // Audio mode define
  108. static int Audio_mode_fs=AUDIO_44K_2CH;
  109. uint8_t current_audio_info_frame[14] = {0x84, 0x01, 0x0A, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  110. void siHdmiTx_VideoSel (int vmode);
  111. void siHdmiTx_AudioSel (int AduioMode);
  112. /* Local data */
  113. #ifdef HDCP_ENABLE
  114. #define HDCP_RPTR_CTS_DELAY_MS 2875
  115. #define HDCP_ERROR_THRESHOLD 5
  116. static int hdcp_bksv_err_count = 0;
  117. static int hdcp_reneg_err_count = 0;
  118. static int hdcp_link_err_count = 0;
  119. static int hdcp_suspend_err_count = 0;
  120. #endif // HDCP_ENABLE
  121. #define DDC_ABORT_THRESHOLD 10
  122. static int ddc_abort_count = 0;
  123. #define MSC_ABORT_THRESHOLD 10 // TODO: FD, TBI, not actually used now
  124. static int msc_abort_count = 0;
  125. struct intr_tbl {
  126. uint8_t mask;
  127. uint8_t mask_page;
  128. uint8_t mask_offset;
  129. uint8_t stat_page;
  130. uint8_t stat_offset;
  131. int (*isr)(struct drv_hw_context *, uint8_t int_5_status);
  132. char name[5];
  133. };
  134. #define REG_TIMING_INTR_MASK 0x66, 0x00 // TODO: FD, TBD
  135. #define REG_TIMING_INTR 0x66, 0x01 // TODO: FD, TBD
  136. struct intr_tbl g_intr_tbl[] = {
  137. {0, REG_INTR4_MASK, REG_INTR4, int_4_isr, "DISC"}
  138. ,{0, REG_CBUS_MDT_INT_0_MASK, REG_CBUS_MDT_INT_0, g2wb_isr, "G2WB"}
  139. ,{0, REG_CBUS_INT_0_MASK, REG_CBUS_INT_0, mhl_cbus_isr, "MSC "}
  140. ,{0, REG_CBUS_INT_1_MASK, REG_CBUS_INT_1, mhl_cbus_err_isr, "MERR"}
  141. //,{0, REG_TIMING_INTR_MASK, REG_TIMING_INTR, to_be_deleted, "INFR"} // TODO: FD, TBD
  142. #ifdef HDCP_ENABLE
  143. ,{0, REG_TPI_INTR_ST0_ENABLE, REG_TPI_INTR_ST0, hdcp_isr, "HDCP"}
  144. #endif // HDCP_ENABLE
  145. ,{0, REG_INTR3_MASK, REG_INTR3, int_3_isr, "EDID"}
  146. #ifdef HDCP_ENABLE
  147. ,{0, REG_TPI_INTR_ST1_ENABLE, REG_TPI_INTR_ST1, int_hdcp2_isr, "HDCP2"}
  148. #endif // HDCP_ENABLE
  149. ,{0, REG_INTR1_MASK, REG_INTR1, int_1_isr, "INTR1"}
  150. };
  151. typedef enum
  152. {
  153. INTR_DISC = 0
  154. ,INTR_G2WB = 1
  155. ,INTR_MSC = 2
  156. ,INTR_MERR = 3
  157. ///,INTR_INFR = 4 // TODO: FD, TBD
  158. #ifdef HDCP_ENABLE
  159. ,INTR_HDCP = 4
  160. ,INTR_EDID = 5
  161. // ,INTR_CKDT = 7
  162. ,INTR_HDCP2 = 6
  163. ,INTR_INTR1 = 7
  164. ,MAX_INTR = 8
  165. #else
  166. ,INTR_EDID = 4
  167. ,INTR_INTR1 = 5
  168. ,MAX_INTR = 6
  169. #endif // HDCP_ENABLE
  170. }intr_nums_t;
  171. #define SILICON_IMAGE_ADOPTER_ID 322
  172. //#define TX_HW_RESET_PERIOD 10 /* 10 ms. */
  173. //#define TX_HW_RESET_DELAY 100
  174. #define TX_HW_RESET_PERIOD 5 /* system: 0.5s is enough */ // TODO: FD, TBI, to reduce this delay smaller
  175. #define TX_HW_RESET_DELAY 5 /* system: 0.5s is enough */ // TODO: FD, TBI, to reduce this delay smaller
  176. #define TX_EDID_POLL_MAX 256
  177. static uint8_t colorSpaceTranslateInfoFrameToHw[] = {
  178. BIT_TPI_INPUT_FORMAT_RGB,
  179. BIT_TPI_INPUT_FORMAT_YCbCr422,
  180. BIT_TPI_INPUT_FORMAT_YCbCr444,
  181. BIT_TPI_INPUT_FORMAT_INTERNAL_RGB /* reserved for future */
  182. };
  183. #ifdef ENABLE_GEN2 //(
  184. static void enable_gen2_write_burst(struct drv_hw_context *hw_context)
  185. {
  186. /* enable Gen2 Write Burst interrupt, MSC and EDID interrupts. */
  187. if(hw_context->ready_for_mdt) {
  188. mhl_tx_write_reg(hw_context, REG_CBUS_MDT_RCV_TIMEOUT, 100); /* 2 second timeout */
  189. mhl_tx_write_reg(hw_context, REG_CBUS_MDT_RCV_CONTROL, BIT_CBUS_MDT_RCV_CONTROL_RCV_EN_ENABLE);
  190. enable_intr(hw_context, INTR_G2WB, BIT_MDT_RXFIFO_DATA_RDY);
  191. hw_context->gen2_write_burst = true;
  192. }
  193. }
  194. static void disable_gen2_write_burst(struct drv_hw_context *hw_context)
  195. {
  196. /* disable Gen2 Write Burst engine to perform it using legacy WRITE_BURST */
  197. mhl_tx_write_reg(hw_context, REG_CBUS_MDT_RCV_CONTROL, BIT_CBUS_MDT_RCV_CONTROL_RCV_EN_DISABLE);
  198. enable_intr(hw_context, INTR_G2WB, 0);
  199. hw_context->gen2_write_burst = false;
  200. }
  201. #endif //)
  202. static void si_mhl_tx_drv_reset_ddc_fifo(struct drv_hw_context *hw_context)
  203. {
  204. uint8_t ddc_status;
  205. ddc_status = mhl_tx_read_reg(hw_context, REG_DDC_STATUS);
  206. mhl_tx_modify_reg(hw_context, REG_TPI_SEL,
  207. BIT_TPI_SEL_SW_TPI_EN_MASK,
  208. BIT_TPI_SEL_SW_TPI_EN_NON_HW_TPI);
  209. if (BIT_DDC_STATUS_DDC_NO_ACK & ddc_status) {
  210. MHL_TX_DBG_ERR(hw_context, "Clearing DDC ack status\n");
  211. mhl_tx_write_reg(hw_context, REG_DDC_STATUS,
  212. ddc_status & ~BIT_DDC_STATUS_DDC_NO_ACK);
  213. }
  214. mhl_tx_modify_reg(hw_context, REG_DDC_CMD,
  215. BIT_DDC_CMD_COMMAND_MASK,
  216. BIT_DDC_CMD_COMMAND_CLEAR_FIFO);
  217. mhl_tx_modify_reg(hw_context, REG_TPI_SEL,
  218. BIT_TPI_SEL_SW_TPI_EN_MASK,
  219. BIT_TPI_SEL_SW_TPI_EN_HW_TPI);
  220. }
  221. // Read specific batch of data in specific EDID block
  222. static void si_mhl_tx_drv_issue_edid_block_batch_read(struct drv_hw_context *hw_context, uint8_t block_number, uint8_t batch_number)
  223. {
  224. uint8_t ddc_status;
  225. uint8_t offset = 0;
  226. MHL_TX_DBG_INFO(hw_context, "called.\n");
  227. ddc_status = mhl_tx_read_reg(hw_context, REG_DDC_STATUS);
  228. // Enter NON-HW TPI mode
  229. mhl_tx_modify_reg(hw_context, REG_TPI_SEL,
  230. BIT_TPI_SEL_SW_TPI_EN_MASK,
  231. BIT_TPI_SEL_SW_TPI_EN_NON_HW_TPI);
  232. if (BIT_DDC_STATUS_DDC_NO_ACK & ddc_status) {
  233. MHL_TX_DBG_ERR(hw_context, "Clearing DDC ack status\n");
  234. mhl_tx_write_reg(hw_context, REG_DDC_STATUS,
  235. ddc_status & ~BIT_DDC_STATUS_DDC_NO_ACK);
  236. }
  237. // Clear DDC FIFO
  238. mhl_tx_modify_reg(hw_context, REG_DDC_CMD,
  239. BIT_DDC_CMD_COMMAND_MASK,
  240. BIT_DDC_CMD_COMMAND_CLEAR_FIFO);
  241. // Set Segment
  242. mhl_tx_write_reg(hw_context, REG_DDC_SEGM, block_number / 2);
  243. // Set EDID slave address
  244. mhl_tx_write_reg(hw_context, REG_DDC_ADDR, 0xA0);
  245. // Set EDID offset address
  246. offset = (0 == (block_number % 2)) ? 0x00 : 0x80;
  247. offset += batch_number * 16;
  248. mhl_tx_write_reg(hw_context, REG_DDC_OFFSET, offset);
  249. // Set count of data to read, 16 bytes per batch
  250. mhl_tx_write_reg(hw_context, REG_DDC_DIN_CNT1, 0x10);
  251. mhl_tx_write_reg(hw_context, REG_DDC_DIN_CNT2, 0x00);
  252. // Trigger Enhanced DDC read
  253. mhl_tx_write_reg(hw_context, REG_DDC_CMD, BIT_DDC_CMD_COMMAND_ENHANCED_READ_NO_ACK);
  254. // Cannot enter HW TPI mode during EDID read
  255. }
  256. bool si_mhl_tx_drv_issue_edid_read_request(struct drv_hw_context *hw_context, uint8_t block_number, uint8_t batch_number)
  257. {
  258. uint8_t reg_val;
  259. reg_val = mhl_tx_read_reg(hw_context, REG_CBUS_STATUS);
  260. if ( BIT_CBUS_HPD & reg_val ) {
  261. MHL_TX_EDID_READ(hw_context,
  262. "\n\tRequesting EDID block:%d\n" \
  263. "\tRequesting EDID block batch:%d\n" \
  264. "\tcurrentEdidRequestBlock:%d\n" \
  265. "\tcurrentEdidRequestBlockBatch:%d\n" \
  266. "\tedidFifoBlockNumber:%d\n",
  267. block_number,
  268. batch_number,
  269. hw_context->current_edid_request_block,
  270. hw_context->current_edid_request_block_batch,
  271. hw_context->edid_fifo_block_number);
  272. si_mhl_tx_drv_reset_ddc_fifo(hw_context);
  273. si_mhl_tx_drv_issue_edid_block_batch_read(hw_context, block_number, batch_number);
  274. return true;
  275. } else {
  276. MHL_TX_DBG_INFO(hw_context,
  277. "\n\tNo HPD for EDID block request:%d\n" \
  278. "\tcurrentEdidRequestBlock:%d\n" \
  279. "\tRequesting EDID block batch:%d\n" \
  280. "\tcurrentEdidRequestBlockBatch:%d\n" \
  281. "\tedidFifoBlockNumber:%d\n",
  282. block_number,
  283. batch_number,
  284. hw_context->current_edid_request_block,
  285. hw_context->current_edid_request_block_batch,
  286. hw_context->edid_fifo_block_number);
  287. return false;
  288. }
  289. }
  290. /*
  291. * si_mhl_tx_drv_send_cbus_command
  292. *
  293. * Write the specified Sideband Channel command to the CBUS.
  294. * such as READ_DEVCAP, SET_INT, WRITE_STAT, etc.
  295. * Command can be a MSC_MSG command (RCP/RAP/RCPK/RCPE/RAPK), or another command
  296. * Parameters:
  297. * req - Pointer to a cbus_req_t structure containing the
  298. * command to write
  299. * Returns: true - successful write
  300. * false - write failed
  301. */
  302. bool si_mhl_tx_drv_send_cbus_command(struct drv_hw_context *hw_context,
  303. struct cbus_req *req)
  304. {
  305. bool success = true;
  306. uint8_t block_write_buffer [3]; // used for efficient block writes
  307. #ifdef ENABLE_GEN2 //(
  308. /* Disable h/w automation of WRITE_BURST until this command completes */
  309. disable_gen2_write_burst(hw_context);
  310. #endif //)
  311. switch (req->command ) {
  312. case MHL_SET_INT:
  313. MHL_TX_DBG_INFO(hw_context, "SET_INT reg: 0x%02x data: 0x%02x\n",
  314. req->reg, req->reg_data);
  315. mhl_tx_write_reg(hw_context, REG_CBUS_MSC_CMD_OR_OFFSET, req->reg);
  316. mhl_tx_write_reg(hw_context, REG_CBUS_MSC_1ST_TRANSMIT_DATA, req->reg_data);
  317. mhl_tx_write_reg(hw_context, REG_CBUS_MSC_COMMAND_START,
  318. BIT_CBUS_MSC_WRITE_STAT_OR_SET_INT);
  319. break;
  320. case MHL_WRITE_STAT:
  321. MHL_TX_DBG_INFO(hw_context,
  322. "WRITE_STAT (0x%02x, 0x%02x)\n",
  323. req->reg,
  324. req->reg_data);
  325. mhl_tx_write_reg(hw_context, REG_CBUS_MSC_CMD_OR_OFFSET, req->reg);
  326. mhl_tx_write_reg(hw_context, REG_CBUS_MSC_1ST_TRANSMIT_DATA, req->reg_data);
  327. mhl_tx_write_reg(hw_context, REG_CBUS_MSC_COMMAND_START,
  328. BIT_CBUS_MSC_WRITE_STAT_OR_SET_INT);
  329. break;
  330. case MHL_READ_DEVCAP:
  331. MHL_TX_DBG_INFO(hw_context,
  332. "READ_DEVCAP (0x%02x, 0x%02x)\n",
  333. req->reg,
  334. req->reg_data);
  335. /* don't call si_mhl_tx_drv_reset_ddc_fifo here */ // TODO: FD, TBC
  336. // TODO: FD, TBC
  337. mhl_tx_write_reg(hw_context, REG_CBUS_MSC_CMD_OR_OFFSET, req->reg);
  338. mhl_tx_write_reg(hw_context, REG_CBUS_MSC_1ST_TRANSMIT_DATA, req->reg_data);
  339. mhl_tx_write_reg(hw_context, REG_CBUS_MSC_COMMAND_START,
  340. BIT_CBUS_MSC_READ_DEVCAP);
  341. break;
  342. case MHL_READ_EDID_BLOCK:
  343. hw_context->current_edid_request_block = 0;
  344. hw_context->current_edid_request_block_batch = 0;
  345. hw_context->edid_fifo_block_number = 0;
  346. MHL_TX_DBG_INFO(hw_context, "before si_mhl_tx_drv_issue_edid_read_request: to read block 0\n");
  347. success = si_mhl_tx_drv_issue_edid_read_request(hw_context,
  348. hw_context->current_edid_request_block,
  349. hw_context->current_edid_request_block_batch);
  350. break;
  351. case MHL_GET_STATE: /* 0x62 - */
  352. case MHL_GET_VENDOR_ID: /* 0x63 - for vendor id */
  353. case MHL_SET_HPD: /* 0x64 - Set Hot Plug Detect */
  354. case MHL_CLR_HPD: /* 0x65 - Clear Hot Plug Detect */
  355. case MHL_GET_SC1_ERRORCODE: /* 0x69 - Get channel 1 command error code */
  356. case MHL_GET_DDC_ERRORCODE: /* 0x6A - Get DDC channel command error code */
  357. case MHL_GET_MSC_ERRORCODE: /* 0x6B - Get MSC command error code */
  358. case MHL_GET_SC3_ERRORCODE: /* 0x6D - Get channel 3 command error code */
  359. MHL_TX_DBG_INFO(hw_context, "Sending MSC command %02x, %02x, %02x\n",
  360. req->command, req->reg, req->reg_data);
  361. mhl_tx_write_reg(hw_context,REG_CBUS_MSC_CMD_OR_OFFSET, req->command);
  362. mhl_tx_write_reg(hw_context,REG_CBUS_MSC_1ST_TRANSMIT_DATA, req->reg_data);
  363. mhl_tx_write_reg(hw_context,REG_CBUS_MSC_COMMAND_START,
  364. BIT_CBUS_MSC_PEER_CMD);
  365. break;
  366. case MHL_MSC_MSG:
  367. MHL_TX_DBG_INFO(hw_context,
  368. "MHL_MSC_MSG sub cmd: 0x%02x data: 0x%02x\n",
  369. req->msg_data[0], req->msg_data[1]);
  370. block_write_buffer[0] = req->command;
  371. block_write_buffer[1] = req->msg_data[0];
  372. block_write_buffer[2] = req->msg_data[1];
  373. /*
  374. mhl_tx_write_reg(hw_context,REG_CBUS_MSC_CMD_OR_OFFSET, req->command);
  375. mhl_tx_write_reg(hw_context,REG_CBUS_MSC_1ST_TRANSMIT_DATA, req->msg_data[0]);
  376. mhl_tx_write_reg(hw_context,REG_CBUS_MSC_2ND_TRANSMIT_DATA, req->msg_data[1]);
  377. */
  378. mhl_tx_write_reg_block(hw_context,REG_CBUS_MSC_CMD_OR_OFFSET, 3, block_write_buffer);
  379. mhl_tx_write_reg(hw_context,REG_CBUS_MSC_COMMAND_START,
  380. BIT_CBUS_MSC_MSG);
  381. break;
  382. case MHL_WRITE_BURST:
  383. MHL_TX_DBG_INFO(hw_context, "MHL_WRITE_BURST offset: 0x%02x "\
  384. "length: 0x%02x\n",
  385. req->offset, req->length);
  386. mhl_tx_write_reg(hw_context, REG_CBUS_MSC_CMD_OR_OFFSET,
  387. req->offset + REG_CBUS_MHL_SCRPAD_BASE);
  388. mhl_tx_write_reg(hw_context, REG_CBUS_MSC_WRITE_BURST_DATA_LEN,
  389. req->length -1);
  390. /* Now copy all bytes from array to local scratchpad */
  391. mhl_tx_write_reg_block(hw_context, REG_CBUS_WB_XMIT_DATA_0,
  392. req->length, req->msg_data);
  393. mhl_tx_write_reg(hw_context,REG_CBUS_MSC_COMMAND_START,
  394. BIT_CBUS_MSC_WRITE_BURST);
  395. break;
  396. default:
  397. MHL_TX_DBG_ERR(hw_context, "Unsupported command 0x%02x detected!\n",
  398. req->command);
  399. success = false;
  400. break;
  401. }
  402. return (success);
  403. }
  404. uint16_t si_mhl_tx_drv_get_incoming_horizontal_total(struct drv_hw_context *hw_context)
  405. {
  406. uint16_t ret_val;
  407. ret_val = (((uint16_t)mhl_tx_read_reg(hw_context, REG_HRESH)) <<8) |
  408. (uint16_t)mhl_tx_read_reg(hw_context, REG_HRESL);
  409. return ret_val;
  410. }
  411. uint16_t si_mhl_tx_drv_get_incoming_vertical_total(struct drv_hw_context *hw_context)
  412. {
  413. uint16_t ret_val;
  414. ret_val = (((uint16_t)mhl_tx_read_reg(hw_context, REG_VRESH)) <<8) |
  415. (uint16_t)mhl_tx_read_reg(hw_context, REG_VRESL);
  416. return ret_val;
  417. }
  418. int si_mhl_tx_drv_get_edid_fifo_next_block(struct drv_hw_context *hw_context, uint8_t *edid_buf)
  419. {
  420. int ret_val;
  421. uint8_t offset;
  422. MHL_TX_DBG_INFO(hw_context, "called.\n");
  423. offset = EDID_BLOCK_SIZE * hw_context->edid_fifo_block_number;
  424. MHL_TX_DBG_INFO(hw_context, "%x %x\n",(unsigned long)hw_context,(unsigned long)edid_buf);
  425. hw_context->edid_fifo_block_number++;
  426. memcpy(edid_buf, hw_context->current_edid_block_data + offset , EDID_BLOCK_SIZE);
  427. /*
  428. // Need to use 'pr_debug' to keep the formatting
  429. if ( DBG_MSG_LEVEL_EDID_READ > debug_msgs )
  430. {
  431. // do nothing
  432. }
  433. else*/
  434. {
  435. MHL_TX_EDID_READ(hw_context, "current edid data: %d.\n", hw_context->edid_fifo_block_number - 1);
  436. #if 0
  437. for ( i = 0; i < 8; i ++)
  438. {
  439. pr_debug("ROW %d:\t\t", i);
  440. for (j=0; j<16; j++)
  441. {
  442. pr_debug("%02X:%02X\t", j, edid_buf[i * 16 + j]); // buffer data
  443. //pr_debug("%02X:%02X\t", j, hw_context->current_edid_block_data[offset + i * 16 + j]); // block data
  444. }
  445. pr_debug("\n");
  446. }
  447. pr_debug("\n");
  448. DUMP_EDID_BLOCK(0,edid_buf, EDID_BLOCK_SIZE);
  449. #endif
  450. }
  451. ret_val = mhl_tx_read_reg(hw_context,REG_CBUS_STATUS);
  452. if (ret_val < 0)
  453. {
  454. MHL_TX_DBG_ERR(hw_context, "%d", ret_val);
  455. return ne_NO_HPD;
  456. }
  457. else if (BIT_CBUS_HPD & ret_val)
  458. {
  459. MHL_TX_DBG_INFO(hw_context, "Done reading EDID from FIFO using Manual DDC read, ret_val:0x%02x\n",ret_val);
  460. return 0;
  461. }
  462. else
  463. {
  464. MHL_TX_DBG_INFO(hw_context, "No HPD ret_val:0x%02x\n",ret_val);
  465. return ne_NO_HPD;
  466. }
  467. }
  468. int si_mhl_tx_drv_get_scratch_pad(struct drv_hw_context *hw_context,
  469. uint8_t start_reg, uint8_t *data,
  470. uint8_t length)
  471. {
  472. if ((start_reg + length) > (int)MHL_SCRATCHPAD_SIZE)
  473. return -1;
  474. memcpy(data, &hw_context->write_burst_data[start_reg], length);
  475. return 0;
  476. }
  477. bool packed_pixel_available(struct mhl_dev_context *dev_context)
  478. {
  479. if ((MHL_DEV_VID_LINK_SUPP_PPIXEL & DEVCAP_VAL_VID_LINK_MODE) &&
  480. (dev_context->dev_cap_cache.mdc.vid_link_mode &
  481. MHL_DEV_VID_LINK_SUPP_PPIXEL)) {
  482. return true;
  483. }
  484. return false;
  485. }
  486. #define SIZE_AVI_INFOFRAME 14
  487. static uint8_t calculate_avi_info_frame_checksum(hw_avi_payload_t *payload)
  488. {
  489. uint8_t checksum;
  490. checksum = 0x82 + 0x02 + 0x0D; /* these are set by the hardware */
  491. return calculate_generic_checksum(payload->ifData, checksum, SIZE_AVI_INFOFRAME);
  492. }
  493. #if 0
  494. #define SIZE_AUDIO_IF 14
  495. static uint8_t calculate_audio_if_checksum(uint8_t *audio_if)
  496. {
  497. uint8_t checksum = 0;
  498. return calculate_generic_checksum(audio_if, checksum, SIZE_AUDIO_IF);
  499. }
  500. #define SIZE_AVIF 9
  501. static uint8_t calculate_avif_checksum(uint8_t *avif)
  502. {
  503. uint8_t checksum = 0;
  504. return calculate_generic_checksum(avif, checksum, SIZE_AVIF);
  505. }
  506. #define SIZE_VSIF 8
  507. static uint8_t calculate_vsif_checksum(uint8_t *vsif)
  508. {
  509. uint8_t checksum = 0;
  510. return calculate_generic_checksum(vsif, checksum, SIZE_VSIF);
  511. }
  512. static int is_valid_avi_info_frame(struct mhl_dev_context *dev_context, avi_info_frame_t *avif)
  513. {
  514. uint8_t checksum;
  515. checksum = calculate_generic_checksum((uint8_t *)avif, 0, sizeof(*avif));
  516. if (0 != checksum) {
  517. MHL_TX_DBG_ERR(dev_context, "AVI info frame checksum is: 0x%02x should be 0\n", checksum);
  518. return 0;
  519. } else if (0x82 != avif->header.type_code) {
  520. MHL_TX_DBG_ERR(dev_context, "Invalid AVI type code: 0x%02x\n", avif->header.type_code);
  521. return 0;
  522. } else if (0x02 != avif->header.version_number) {
  523. MHL_TX_DBG_ERR(dev_context, "Invalid AVI version: 0x%02x\n", avif->header.version_number);
  524. return 0;
  525. } else if (0x0D != avif->header.length) {
  526. return 0;
  527. } else {
  528. return 1;
  529. }
  530. }
  531. static int is_valid_vsif(struct mhl_dev_context *dev_context, vendor_specific_info_frame_t *vsif)
  532. {
  533. uint8_t checksum;
  534. /*
  535. Calculate the checksum assuming that the payload includes the checksum
  536. */
  537. checksum = calculate_generic_checksum((uint8_t *)vsif, 0,
  538. sizeof(vsif->header) + vsif->header.length );
  539. if (0 != checksum) {
  540. MHL_TX_DBG_WARN(dev_context, "VSIF info frame checksum is: 0x%02x should be 0\n", checksum);
  541. /*
  542. Try again, assuming that the header includes the checksum.
  543. */
  544. checksum = calculate_generic_checksum((uint8_t *)vsif, 0,
  545. sizeof(vsif->header) + vsif->header.length
  546. + sizeof(vsif->payLoad.checksum));
  547. if (0 != checksum){
  548. MHL_TX_DBG_ERR(dev_context, "VSIF info frame checksum "
  549. "(adjusted for checksum itself) is: 0x%02x "
  550. "should be 0\n", checksum);
  551. return 0;
  552. }
  553. }
  554. if (0x81 != vsif->header.type_code) {
  555. MHL_TX_DBG_ERR(dev_context, "Invalid VSIF type code: 0x%02x\n",
  556. vsif->header.type_code);
  557. return 0;
  558. } else if (0x01 != vsif->header.version_number) {
  559. MHL_TX_DBG_ERR(dev_context, "Invalid VSIF version: 0x%02x\n",
  560. vsif->header.version_number);
  561. return 0;
  562. } else {
  563. return 1;
  564. }
  565. }
  566. #endif
  567. /*
  568. static void print_vic_modes(struct drv_hw_context *hw_context,uint8_t vic)
  569. {
  570. int i;
  571. struct vic_name {
  572. uint8_t vic;
  573. char name[10];
  574. } vic_name_table[] = {
  575. {2, "480P"}
  576. ,{4, "720P60"}
  577. ,{5, "1080i60"}
  578. ,{6, "480i"}
  579. ,{16,"1080P60"}
  580. ,{17,"576P50"}
  581. ,{19,"720P50"}
  582. ,{20,"1080i50"}
  583. ,{21,"576i50"}
  584. ,{31,"1080P50"}
  585. ,{32,"1080P24"}
  586. ,{33,"1080P25"}
  587. ,{34,"1080P30"}
  588. ,{0,""}
  589. };
  590. #define NUM_VIC_NAMES (sizeof(vic_name_table)/sizeof(vic_name_table[0]) )
  591. for(i = 0; i < (NUM_VIC_NAMES - 1); i++) {
  592. if(vic == vic_name_table[i].vic) {
  593. break;
  594. }
  595. }
  596. MHL_TX_DBG_ERR(hw_context, "VIC = %d (%s)\n", vic, vic_name_table[i].name);
  597. }
  598. */
  599. // TODO: FD, TBU, zone control should be reconfigured after tapeout if auto-zone is not deployed
  600. static void set_mhl_zone_settings(struct mhl_dev_context *dev_context , uint32_t pixel_clock_frequency)
  601. {
  602. /*
  603. struct drv_hw_context *hw_context = (struct drv_hw_context *)&dev_context->drv_context;
  604. MHL_TX_DBG_INFO(hw_context,"pixel clock:%d %04x rev %02x\n",
  605. pixel_clock_frequency,
  606. hw_context->chip_device_id,
  607. hw_context->chip_rev_id);
  608. */
  609. #if 0 // TODO: FD, TBC, double-check for SK, check whether there is a need to manual control and what's the threhold
  610. /*
  611. * Modes below 30MHz need a different zone control
  612. */
  613. if (hw_context->chip_rev_id > 0) {
  614. if (pixel_clock_frequency < 30000000)
  615. mhl_tx_write_reg(hw_context, REG_TXMZ_CTRL2, 0x01);
  616. else
  617. mhl_tx_write_reg(hw_context, REG_TXMZ_CTRL2, 0x00);
  618. }
  619. #endif
  620. /*
  621. * MSC WRITE_STATUS is required to prepare sink for new mode
  622. */
  623. si_mhl_tx_set_pp_link(dev_context, dev_context->link_mode);
  624. }
  625. /*
  626. * This function must not be called for DVI mode.
  627. */
  628. static int set_hdmi_params(struct mhl_dev_context *dev_context)
  629. {
  630. uint16_t h_total;
  631. uint16_t v_total;
  632. uint32_t pixel_clock_frequency;
  633. uint32_t threeDPixelClockRatio;
  634. uint8_t packedPixelNeeded=0;
  635. AviColorSpace_e input_clr_spc =acsRGB;
  636. uint8_t output_clr_spc =acsRGB;
  637. avi_info_frame_data_byte_4_t input_video_code;
  638. struct drv_hw_context *hw_context = (struct drv_hw_context *)&dev_context->drv_context;
  639. enum {
  640. use_avi_vic
  641. ,use_hardware_totals
  642. }timing_info_basis=use_avi_vic;
  643. MHL_TX_DBG_ERR(hw_context,"packed_pixel_available :%d \n",packed_pixel_available(dev_context));
  644. // check if DPI signal is normal
  645. h_total = si_mhl_tx_drv_get_incoming_horizontal_total((struct drv_hw_context *)dev_context);
  646. v_total = si_mhl_tx_drv_get_incoming_vertical_total((struct drv_hw_context *)dev_context);
  647. MHL_TX_DBG_INFO(hw_context, "h_total :%u,v_total:%u\n", h_total,v_total );
  648. //
  649. /* Extract VIC from incoming AVIF */
  650. input_video_code.VIC = video_data.inputVideoCode;
  651. //input_video_code = hw_context->current_avi_info_frame.payLoad.hwPayLoad.namedIfData.ifData_u.bitFields.VIC;
  652. /*
  653. * From VSIF bytes, figure out if we need to perform
  654. * frame packing or not. This helps decide if packed pixel
  655. * (16-bit) is required or not in conjunction with the VIC.
  656. */
  657. threeDPixelClockRatio = 1;
  658. si_mhl_tx_drv_get_incoming_horizontal_total(hw_context);
  659. #ifdef CONFIG_MTK_HDMI_3D_SUPPORT
  660. if (hw_context->valid_vsif && hw_context->valid_3d)
  661. {
  662. MHL_TX_DBG_WARN(, "valid HDMI VSIF\n");
  663. print_vic_modes(hw_context, (uint8_t) input_video_code.VIC);
  664. if (0 == input_video_code.VIC) {
  665. MHL_TX_DBG_ERR(,"AVI VIC is zero!!!\n");
  666. return false;
  667. }
  668. if ( 1 == hw_context->valid_3d_fs )
  669. {
  670. MHL_TX_DBG_INFO(dev_context, "3D Pixel Clock Ratio: Frame Packing\n");
  671. threeDPixelClockRatio = 2;
  672. }
  673. }
  674. #endif
  675. #if 0
  676. else
  677. { /* no VSIF */
  678. if (0 == input_video_code.VIC) {
  679. /*
  680. This routine will not be called until we positively know (from the downstream EDID)
  681. that the sink is HDMI.
  682. We do not support DVI only sources. The upstream source is expected to choose between
  683. HDMI and DVI based upon the EDID that we present upstream.
  684. The other information in the infoframe, even if it is non-zero, is not helpful for
  685. determining the pixel clock frequency.
  686. So we try as best we can to infer the pixel clock from the HTOTAL and VTOTAL registers.
  687. */
  688. timing_info_basis = use_hardware_totals;
  689. MHL_TX_DBG_WARN(,"no VSIF and AVI VIC is zero!!! trying HTOTAL/VTOTAL\n");
  690. }else{
  691. print_vic_modes(hw_context, (uint8_t) input_video_code.VIC);
  692. }
  693. }
  694. #endif
  695. /* make a copy of avif */
  696. // hw_context->outgoingAviPayLoad = hw_context->current_avi_info_frame.payLoad.hwPayLoad; // TODO: FD, TBC, should be ok?
  697. //memcpy( &(hw_context->outgoingAviPayLoad), &(hw_context->current_avi_info_frame.payLoad.hwPayLoad), sizeof(hw_avi_payload_t) );
  698. /* compute pixel frequency */
  699. switch(timing_info_basis){
  700. case use_avi_vic:
  701. pixel_clock_frequency = si_edid_find_pixel_clock_from_AVI_VIC(
  702. dev_context->edid_parser_context,
  703. input_video_code.VIC);
  704. break;
  705. case use_hardware_totals:
  706. pixel_clock_frequency = si_mhl_tx_find_timings_from_totals(
  707. dev_context->edid_parser_context);
  708. if (0 == pixel_clock_frequency){
  709. MHL_TX_DBG_ERR(,"VIC was zero and totals not supported\n");
  710. //return false;
  711. }
  712. break;
  713. }
  714. /* extract input color space */
  715. input_clr_spc = video_data.outputColorSpace;
  716. //input_clr_spc = hw_context->current_avi_info_frame.payLoad.hwPayLoad.namedIfData.
  717. // ifData_u.bitFields.pb1.colorSpace;
  718. MHL_TX_DBG_INFO(dev_context, "input_clr_spc = %02X input_video_code.VIC:%02X\n",
  719. input_clr_spc, input_video_code.VIC);
  720. /*
  721. * decide about packed pixel mode
  722. */
  723. pixel_clock_frequency *= threeDPixelClockRatio;
  724. MHL_TX_DBG_INFO(hw_context, "pixel clock:%u\n", pixel_clock_frequency);
  725. if (qualify_pixel_clock_for_mhl(dev_context->edid_parser_context,
  726. pixel_clock_frequency, 24)) {
  727. MHL_TX_DBG_INFO(hw_context, "OK for 24 bit pixels\n");
  728. } else {
  729. /* not enough bandwidth for uncompressed video */
  730. //if (si_edid_sink_supports_YCbCr422(dev_context->edid_parser_context))
  731. {
  732. MHL_TX_DBG_INFO(hw_context, "Sink supports YCbCr422\n");
  733. if (qualify_pixel_clock_for_mhl(
  734. dev_context->edid_parser_context, pixel_clock_frequency, 16)) {
  735. /* enough for packed pixel */
  736. packedPixelNeeded = 1;
  737. } else {
  738. MHL_TX_DBG_ERR(hw_context,"unsupported video mode."
  739. "pixel clock too high %s\n"
  740. ,si_peer_supports_packed_pixel(dev_context)
  741. ? "" :"(peer does not support packed pixel)."
  742. );
  743. return false;
  744. }
  745. }
  746. /*else {
  747. MHL_TX_DBG_ERR(hw_context,"unsupported video mode."
  748. "Sink doesn't support 4:2:2.\n");
  749. return false;
  750. }
  751. */
  752. }
  753. /*
  754. * Determine output color space if it needs to be 4:2:2 or same as input
  755. */
  756. output_clr_spc = input_clr_spc;
  757. if (packedPixelNeeded){
  758. if (packed_pixel_available(dev_context)) {
  759. MHL_TX_DBG_INFO(hw_context, "setting packed pixel mode\n");
  760. dev_context->link_mode = MHL_STATUS_PATH_ENABLED | MHL_STATUS_CLK_MODE_PACKED_PIXEL;
  761. /* enforcing 4:2:2 if packed pixel. */
  762. output_clr_spc = BIT_EDID_FIELD_FORMAT_YCbCr422;
  763. mhl_tx_write_reg(hw_context
  764. , REG_VID_MODE
  765. , REG_VID_MODE_DEFVAL | BIT_VID_MODE_m1080p_ENABLE);
  766. mhl_tx_modify_reg(hw_context, REG_MHLTX_CTL4,
  767. BIT_MHLTX_CTL4_MHL_CLK_RATIO_MASK,
  768. BIT_MHLTX_CTL4_MHL_CLK_RATIO_2X);
  769. mhl_tx_modify_reg(hw_context, REG_MHLTX_CTL6,
  770. BIT_MHLTX_CTL6_CLK_MASK,
  771. BIT_MHLTX_CTL6_CLK_PP);
  772. } else {
  773. MHL_TX_DBG_ERR(hw_context,
  774. "unsupported video mode. Packed Pixel not available on sink."
  775. "Sink's link mode = 0x%02x\n",
  776. dev_context->dev_cap_cache.mdc.vid_link_mode);
  777. return false;
  778. }
  779. } else {
  780. MHL_TX_DBG_INFO(hw_context, "normal Mode ,Packed Pixel mode disabled \n");
  781. dev_context->link_mode = MHL_STATUS_PATH_ENABLED | MHL_STATUS_CLK_MODE_NORMAL;
  782. mhl_tx_write_reg(hw_context
  783. , REG_VID_MODE
  784. , REG_VID_MODE_DEFVAL | BIT_VID_MODE_m1080p_DISABLE);
  785. mhl_tx_modify_reg(hw_context, REG_MHLTX_CTL4,
  786. BIT_MHLTX_CTL4_MHL_CLK_RATIO_MASK,
  787. BIT_MHLTX_CTL4_MHL_CLK_RATIO_3X);
  788. mhl_tx_modify_reg(hw_context, REG_MHLTX_CTL6,
  789. BIT_MHLTX_CTL6_CLK_MASK,
  790. BIT_MHLTX_CTL6_CLK_NPP);
  791. }
  792. /* Set input color space */
  793. mhl_tx_write_reg(hw_context , REG_TPI_INPUT , colorSpaceTranslateInfoFrameToHw[input_clr_spc]);
  794. /* Set output color space */
  795. mhl_tx_write_reg(hw_context , REG_TPI_OUTPUT , colorSpaceTranslateInfoFrameToHw[output_clr_spc]);
  796. set_mhl_zone_settings(dev_context,pixel_clock_frequency);
  797. /*
  798. * Prepare outgoing AVIF for later programming the registers
  799. *
  800. * the checksum itself is included in the calculation.
  801. */
  802. {
  803. //hw_context->outgoingAviPayLoad.namedIfData.ifData_u.infoFrameData[0] = 0x00;
  804. hw_context->outgoingAviPayLoad.namedIfData.ifData_u.infoFrameData[0] = output_clr_spc << 5|0x02;
  805. hw_context->outgoingAviPayLoad.namedIfData.ifData_u.infoFrameData[1] = video_data.outputcolorimetryAspectRatio;
  806. /*if(VIDEO_CAPABILITY_D_BLOCK_found)
  807. {
  808. hw_context->outgoingAviPayLoad.namedIfData.ifData_u.infoFrameData[2] = 0x04;
  809. TX_DEBUG_PRINT(("VIDEO_CAPABILITY_D_BLOCK_found = true, limited range\n"));
  810. }
  811. else*/
  812. {
  813. hw_context->outgoingAviPayLoad.namedIfData.ifData_u.infoFrameData[2] = 0x04;
  814. TX_DEBUG_PRINT(("VIDEO_CAPABILITY_D_BLOCK_found= false. defult range\n"));
  815. }
  816. hw_context->outgoingAviPayLoad.namedIfData.ifData_u.infoFrameData[3] = video_data.inputVideoCode;
  817. TX_DEBUG_PRINT(("video_data.inputVideoCode:0x%02x\n",(int)video_data.inputVideoCode));
  818. hw_context->outgoingAviPayLoad.namedIfData.ifData_u.infoFrameData[4] = 0x00;
  819. hw_context->outgoingAviPayLoad.namedIfData.ifData_u.infoFrameData[5] = 0x00;
  820. hw_context->outgoingAviPayLoad.namedIfData.ifData_u.infoFrameData[6] = 0x00;
  821. hw_context->outgoingAviPayLoad.namedIfData.ifData_u.infoFrameData[7] = 0x00;
  822. hw_context->outgoingAviPayLoad.namedIfData.ifData_u.infoFrameData[8] = 0x00;
  823. hw_context->outgoingAviPayLoad.namedIfData.ifData_u.infoFrameData[9] = 0x00;
  824. hw_context->outgoingAviPayLoad.namedIfData.ifData_u.infoFrameData[10] = 0x00;
  825. hw_context->outgoingAviPayLoad.namedIfData.ifData_u.infoFrameData[11] = 0x00;
  826. hw_context->outgoingAviPayLoad.namedIfData.ifData_u.infoFrameData[12] = 0x00;
  827. }
  828. hw_context->outgoingAviPayLoad.namedIfData.checksum = 0;
  829. hw_context->outgoingAviPayLoad.namedIfData.ifData_u.bitFields.pb1.colorSpace
  830. = output_clr_spc;
  831. hw_context->outgoingAviPayLoad.namedIfData.checksum =
  832. calculate_avi_info_frame_checksum(&hw_context->outgoingAviPayLoad);
  833. TX_DEBUG_PRINT(("hw_context->outgoingAviPayLoad.namedIfData.checksum:0x%02x\n",(int)hw_context->outgoingAviPayLoad.namedIfData.checksum));
  834. DumpIncomingInfoFrame(&(hw_context->outgoingAviPayLoad),sizeof(hw_context->outgoingAviPayLoad));
  835. return true;
  836. }
  837. #define dump_edid_fifo(hw_context, block_number) /* do nothing */
  838. int si_mhl_tx_drv_set_upstream_edid(struct drv_hw_context *hw_context, uint8_t *edid, uint16_t length)
  839. {
  840. uint8_t reg_val;
  841. reg_val = mhl_tx_read_reg(hw_context, REG_CBUS_STATUS);
  842. if (!(BIT_CBUS_HPD & reg_val)){
  843. return -1;
  844. }
  845. #ifdef NEVER //(
  846. if(si_edid_sink_is_hdmi(hw_context->intr_info->edid_parser_context)) {
  847. mhl_tx_write_reg(hw_context, TPI_SYSTEM_CONTROL_DATA_REG
  848. , TMDS_OUTPUT_CONTROL_POWER_DOWN
  849. | AV_MUTE_MUTED
  850. | TMDS_OUTPUT_MODE_HDMI
  851. );
  852. } else {
  853. mhl_tx_write_reg(hw_context, TPI_SYSTEM_CONTROL_DATA_REG
  854. , TMDS_OUTPUT_CONTROL_POWER_DOWN
  855. | AV_MUTE_MUTED
  856. | TMDS_OUTPUT_MODE_DVI
  857. );
  858. }
  859. #endif //)
  860. // TODO: FD, TBI, any need to initialize anything for 9293 side or 9293 side related stuff here?
  861. // TODO: FD, TBU, to enable 'TIMING_CHANGE'
  862. // TODO: FD, TBI, to wait until stream from 9293 is stable, then enable 9293 'interrupt'
  863. /* Disable EDID interrupt */
  864. enable_intr(hw_context, INTR_EDID, 0); // TODO: FD, TBI, any chance this will forbid EDID_CHG???
  865. /* Enable h/w automation of WRITE_BURST */
  866. hw_context->ready_for_mdt = true;
  867. #ifdef ENABLE_GEN2 //(
  868. enable_gen2_write_burst(hw_context);
  869. #endif //)
  870. /*
  871. Before exposing the EDID to upstream device, setup to drop all packets.
  872. This ensures we do not get Packet Overflow interrupt.
  873. Dropping all packets means we still get the AVIF interrupts which is crucial.
  874. Packet filters must be disabled until after TMDS is enabled.
  875. */
  876. // TODO: FD, TBI, any need to take similar steps to avoid changes from 9293?
  877. // TODO: FD, TBI, enable 9293 'interrupt' i.e. any need here to enable handling for TIMING_CHANGE 'interrupt' from 9293???
  878. // TODO: FD, TBI, used to drive_hpd_high here, any chance to be useful in application-level???
  879. /* HPD was held low all this time. Now we send an HPD high */
  880. return 0;
  881. }
  882. static void tmds_configure(struct drv_hw_context *hw_context)
  883. {
  884. MHL_TX_DBG_INFO(hw_context, "called\n");
  885. mhl_tx_write_reg(hw_context, REG_SRST, 0x9F);
  886. mhl_tx_write_reg(hw_context, REG_SRST, BIT_MHL_FIFO_AUTO_RST);
  887. mhl_tx_write_reg(hw_context, REG_DPD, 0x1F); // TODO: FD, TBC, confirm with system in progress, seems to be wrong
  888. // mhl_tx_write_reg(hw_context, REG_SYS_CTRL1, 0x37); // TODO: FD, TBC, wait for feedback: why 0x35 as falling rising edge latch
  889. mhl_tx_write_reg(hw_context, REG_TMDS_CCTRL, BIT_TMDS_CCTRL_TMDS_OE | BIT_TMDS_CCTRL_SEL_BGR);
  890. mhl_tx_write_reg(hw_context, REG_USB_CHARGE_PUMP_MHL, BIT_USE_CHARGE_PUMP_MHL_DEFAULT);
  891. mhl_tx_write_reg(hw_context, REG_USB_CHARGE_PUMP, BIT_USE_CHARGE_PUMP_DEFAULT);
  892. mhl_tx_write_reg(hw_context, REG_DISC_CTRL3, BIT_DC3_DEFAULT);
  893. mhl_tx_write_reg(hw_context, REG_MHLTX_CTL1, BIT_MHLTX_CTL1_DISC_OVRIDE_ON);
  894. mhl_tx_write_reg(hw_context, REG_MHLTX_CTL2, REG_MHLTX_CTL2_DEFVAL);
  895. mhl_tx_write_reg(hw_context, REG_MHLTX_CTL3, REG_MHLTX_CTL3_DEFVAL);
  896. mhl_tx_write_reg(hw_context, REG_MHLTX_CTL4, REG_MHLTX_CTL4_DEFVAL);
  897. mhl_tx_write_reg(hw_context, REG_MHLTX_CTL6, REG_MHLTX_CTL6_DEFVAL);
  898. mhl_tx_write_reg(hw_context, REG_MHLTX_CTL7, REG_MHLTX_CTL7_DEFVAL);
  899. mhl_tx_write_reg(hw_context, REG_MHLTX_CTL8, REG_MHLTX_CTL8_DEFVAL);
  900. }
  901. static void power_up(struct drv_hw_context *hw_context)
  902. {
  903. MHL_TX_DBG_INFO(hw_context, "called\n");
  904. // Power up TMDS TX core, enable VSYNC/HSYNC and 24-bit input data bus, select falling edge latched
  905. //mhl_tx_write_reg(hw_context, REG_SYS_CTRL1, 0x35);
  906. //for DDR mode(Pclk Dual edge mode)
  907. mhl_tx_write_reg(hw_context, REG_SYS_CTRL1, 0x31);//mhl_tx_write_reg(hw_context, REG_SYS_CTRL1, 0x33);
  908. /* Toggle power strobe on chip */
  909. mhl_tx_modify_reg(hw_context, REG_DISC_CTRL1, BIT_DISC_CTRL1_STROBE_OFF, 0); // TODO: FD, MUST, TBC
  910. }
  911. #define MHL_LOGICAL_DEVICE_MAP (MHL_DEV_LD_AUDIO | MHL_DEV_LD_VIDEO | \
  912. MHL_DEV_LD_MEDIA | MHL_DEV_LD_GUI)
  913. #define DEVCAP_REG(x) REG_CBUS_DEVICE_CAP_0 | DEVCAP_OFFSET_##x
  914. uint8_t dev_cap_values[] = {
  915. DEVCAP_VAL_DEV_STATE
  916. , DEVCAP_VAL_MHL_VERSION
  917. , DEVCAP_VAL_DEV_CAT
  918. , DEVCAP_VAL_ADOPTER_ID_H
  919. , DEVCAP_VAL_ADOPTER_ID_L
  920. , DEVCAP_VAL_VID_LINK_MODE
  921. , DEVCAP_VAL_AUD_LINK_MODE
  922. , DEVCAP_VAL_VIDEO_TYPE
  923. , DEVCAP_VAL_LOG_DEV_MAP
  924. , DEVCAP_VAL_BANDWIDTH
  925. , DEVCAP_VAL_FEATURE_FLAG
  926. , 0
  927. , 0
  928. , DEVCAP_VAL_SCRATCHPAD_SIZE
  929. , DEVCAP_VAL_INT_STAT_SIZE
  930. , DEVCAP_VAL_RESERVED
  931. };
  932. static int init_regs(struct drv_hw_context *hw_context)
  933. {
  934. int ret_val = 0;
  935. MHL_TX_DBG_INFO(hw_context, "called\n");
  936. /* default values for flags */
  937. // TODO: FD, TBC, double-check & update HDCP/timing_changes_isr related code and then set default to 'false'
  938. hw_context->video_ready = true;
  939. // hw_context->video_ready = false;
  940. // TODO: FD, TBC
  941. hw_context->video_path = 0;
  942. // hw_context->video_path = 1;
  943. hw_context->ready_for_mdt = false;
  944. hw_context->audio_poll_enabled = false;
  945. // TODO: FD, MUST, TBC, any need to clear AVIF/VSIF/AIF/etc. here? Need to clear related status/etc.?
  946. /*
  947. * wake pulses necessary in all modes
  948. * No OTG, Discovery pulse proceed, Wake pulse not bypassed
  949. */
  950. /*
  951. mhl_tx_write_reg(hw_context, REG_DISC_CTRL9
  952. , BIT_DC9_WAKE_DRVFLT
  953. | BIT_DC9_CBUS_LOW_TO_DISCONNECT // TODO: FD, MORE CHECK
  954. | BIT_DC9_DISC_PULSE_PROCEED
  955. );
  956. */
  957. {
  958. /* Enable TPI */
  959. ret_val = mhl_tx_read_reg(hw_context, REG_TPI_SEL);
  960. ret_val &= ~BIT_TPI_SEL_SW_TPI_EN_MASK;
  961. ret_val |= BIT_TPI_SEL_SW_TPI_EN_HW_TPI;
  962. mhl_tx_write_reg(hw_context, REG_TPI_SEL, ret_val);
  963. #ifdef HDCP_ENABLE
  964. mhl_tx_write_reg(hw_context, TPI_HDCP_CONTROL_DATA_REG, 0);
  965. #endif // HDCP_ENABLE
  966. mhl_tx_write_reg(hw_context, REG_TPI_HW_OPT3, 0x76); // TODO: FD, TBD, seems the default value is OK, may remove this later
  967. /* TX Source termination ON */
  968. mhl_tx_write_reg(hw_context, REG_MHLTX_CTL1, BIT_MHLTX_CTL1_TX_TERM_MODE_100DIFF | BIT_MHLTX_CTL1_DISC_OVRIDE_ON);
  969. /* Ignore VBUS, wait for usbint_clr */
  970. mhl_tx_write_reg(hw_context, REG_DISC_CTRL8,0x03);
  971. // mhl_tx_write_reg(hw_context, REG_DISC_CTRL8,0x01); // TODO: FD, TBC, check whether this line or the above line is better
  972. // mhl_tx_write_reg(hw_context, REG_DISC_CTRL2, 0xA5); // TODO: FD, MORE CHECK
  973. /* Enable CBUS discovery */
  974. // mhl_tx_write_reg(hw_context, REG_DISC_CTRL1, VAL_DISC_CTRL1_DEFAULT | BIT_DISC_CTRL1_STROBE_OFF | BIT_DISC_CTRL1_MHL_DISCOVERY_ENABLE);
  975. // mhl_tx_write_reg(hw_context, REG_DISC_CTRL1, VAL_DISC_CTRL1_DEFAULT | BIT_DISC_CTRL1_MHL_DISCOVERY_ENABLE); // TODO: FD, MORE CHECK
  976. #ifdef HDCP_ENABLE
  977. /* set time base for one second to be 60Hz/4*5 + 4*/
  978. mhl_tx_write_reg(hw_context , REG_TPI_HDCP_TIMER_1_SEC , 79); // TODO: FD, TBI, Design think default value '0' is ok
  979. #endif // HDCP_ENABLE
  980. }
  981. /* setup local DEVCAP and few more CBUS registers. */
  982. {
  983. /*
  984. * Fill-in DEVCAP device ID values with those read
  985. * from the transmitter.
  986. */
  987. dev_cap_values[DEVCAP_OFFSET_DEVICE_ID_L] =
  988. (uint8_t)hw_context->chip_device_id;
  989. dev_cap_values[DEVCAP_OFFSET_DEVICE_ID_H] =
  990. (uint8_t)(hw_context->chip_device_id >> 8);
  991. /* Setup local DEVCAP registers */
  992. mhl_tx_write_reg_block(hw_context, DEVCAP_REG(DEV_STATE),
  993. ARRAY_SIZE(dev_cap_values), dev_cap_values);
  994. /*
  995. * Make sure MDT registers are initialized and the MDT
  996. * transmit/receive are both disabled.
  997. */
  998. mhl_tx_write_reg(hw_context, REG_CBUS_MDT_XMIT_TIMEOUT, 100);
  999. /* Clear transmit FIFOs and make sure MDT transmit is disabled */
  1000. mhl_tx_write_reg(hw_context, REG_CBUS_MDT_XMIT_CONTROL, 0x03);
  1001. /* Disable MDT transmit preemptive handshake option */
  1002. mhl_tx_write_reg(hw_context, REG_CBUS_MDT_XFIFO_STAT, 0x00);
  1003. mhl_tx_write_reg(hw_context, REG_CBUS_MDT_RCV_TIMEOUT, 100);
  1004. mhl_tx_write_reg(hw_context, REG_CBUS_LINK_CHECK_HIGH_LIMIT, REG_CBUS_LINK_CHECK_HIGH_LIMIT_DEFVAL);
  1005. mhl_tx_write_reg(hw_context, REG_CBUS_LINK_XMIT_BIT_TIME, REG_CBUS_LINK_XMIT_BIT_TIME_DEFVAL);
  1006. }
  1007. #ifdef ENABLE_GEN2 //(
  1008. /*
  1009. Disable h/w automation of WRITE_BURST.
  1010. 3D packets are handled using legacy WRITE_BURST method.
  1011. */
  1012. disable_gen2_write_burst(hw_context);
  1013. #endif //)
  1014. hw_context->ready_for_mdt = false;
  1015. // TODO: FD, MUST, should set to power_down status at startup and use RSEN to trigger mode change from D3 to D2
  1016. // i.e. should start in "power down" mode with bit0 set to '0'
  1017. mhl_tx_write_reg(hw_context, REG_DPD, 0x17); // Bit0/1/2/4 : 1'b0 Power Down : 1'b1 Normal Operarion
  1018. // TODO: FD, TBU
  1019. mhl_tx_write_reg(hw_context, TX_PAGE_TPI, 0x0B, 0x00); // video mode converter // TODO: FD, TBI, same as default value, not needed
  1020. // mhl_tx_write_reg(hw_context, TX_PAGE_TPI, 0x19, 0x00); // trigger under HW-TPI // TODO: FD, TBD
  1021. // mhl_tx_write_reg(hw_context, TX_PAGE_TPI, 0x1A, 0x00); // tmds output enable // TODO: FD, TBD, no need to enable tmds at startup
  1022. mhl_tx_write_reg(hw_context, TX_PAGE_TPI, 0x1F, 0x80); // SD output enable // TODO: FD, TBC, double check with system why this value?
  1023. // TODO: FD, TBC, double check the following registers with system why these values?
  1024. mhl_tx_write_reg(hw_context, TX_PAGE_TPI, 0x20, 0x80); // 256*Fs // changed to new value 0x80 from 0x10 per latest macro
  1025. mhl_tx_write_reg(hw_context, TX_PAGE_TPI, 0x21, 0x00); //
  1026. mhl_tx_write_reg(hw_context, TX_PAGE_TPI, 0x22, 0x00); //
  1027. mhl_tx_write_reg(hw_context, TX_PAGE_TPI, 0x23, 0x00); //
  1028. mhl_tx_write_reg(hw_context, TX_PAGE_TPI, 0x25, 0x0B); //
  1029. mhl_tx_write_reg(hw_context, TPI_DEVICE_POWER_STATE_CTRL_REG, TX_POWER_STATE_D0); // TODO: FD, MUST, D3/D2/D0 mode switch
  1030. //mhl_tx_write_reg(hw_context, TX_PAGE_TPI, 0x1A, 0x01); // enable HDMI output
  1031. mhl_tx_write_reg(hw_context, TX_PAGE_TPI, 0x1A, 0x00); // disable HDMI output
  1032. #ifdef HDCP_ENABLE
  1033. mhl_tx_write_reg(hw_context, TX_PAGE_TPI, 0x2A, 0x01); // enable HDCP
  1034. #endif // HDCP_ENABLE
  1035. return ret_val;
  1036. }
  1037. void si_mhl_tx_drv_set_hw_tpi_mode(struct drv_hw_context *hw_context, bool hw_tpi_mode)
  1038. {
  1039. if ( hw_tpi_mode )
  1040. {
  1041. // Enter HW TPI mode
  1042. mhl_tx_modify_reg(hw_context, REG_TPI_SEL,
  1043. BIT_TPI_SEL_SW_TPI_EN_MASK,
  1044. BIT_TPI_SEL_SW_TPI_EN_HW_TPI);
  1045. }
  1046. else
  1047. {
  1048. // Enter Non-HW TPI mode
  1049. mhl_tx_modify_reg(hw_context, REG_TPI_SEL,
  1050. BIT_TPI_SEL_SW_TPI_EN_MASK,
  1051. BIT_TPI_SEL_SW_TPI_EN_NON_HW_TPI);
  1052. }
  1053. }
  1054. void si_mhl_tx_drv_disable_video_path(struct drv_hw_context *hw_context)
  1055. {
  1056. /* If video was already being output */
  1057. if(hw_context->video_ready && (0 == (AV_MUTE_MUTED &
  1058. mhl_tx_read_reg(hw_context, TPI_SYSTEM_CONTROL_DATA_REG)))) {
  1059. /* stop hdcp and video and remember */
  1060. stop_video(hw_context);
  1061. hw_context->video_path = 0;
  1062. }
  1063. }
  1064. void si_mhl_tx_drv_enable_video_path(struct drv_hw_context *hw_context)
  1065. {
  1066. MHL_TX_DBG_INFO(dev_context, "called\n");
  1067. /* if a path_en = 0 had stopped the video, restart it unless done already. */
  1068. // if(hw_context->video_ready && (0 == hw_context->video_path)) { // TODO: FD, MUST, double check this for SK
  1069. {
  1070. /* remember ds has enabled our path */
  1071. hw_context->video_path = 1;
  1072. //reg = mhl_tx_read_reg(hw_context, TPI_SYSTEM_CONTROL_DATA_REG);
  1073. //if(mask == (mask & reg)) {
  1074. ///start_video(hw_context,hw_context->intr_info->edid_parser_context);
  1075. //}
  1076. }
  1077. }
  1078. void si_mhl_tx_drv_content_off(struct drv_hw_context *hw_context)
  1079. {
  1080. MHL_TX_DBG_INFO(dev_context, "RAP CONTENT_OFF video %sready\n",hw_context->video_ready?"":"NOT ");
  1081. /* If video was already being output */
  1082. if(hw_context->video_ready && (0 == (AV_MUTE_MUTED &
  1083. mhl_tx_read_reg(hw_context, TPI_SYSTEM_CONTROL_DATA_REG)))) {
  1084. MHL_TX_DBG_INFO(dev_context, "RAP CONTENT_OFF\n");
  1085. /* stop hdcp and video and remember */
  1086. stop_video(hw_context);
  1087. }
  1088. }
  1089. void si_mhl_tx_drv_content_on(struct drv_hw_context *hw_context)
  1090. {
  1091. uint8_t mask = (TMDS_OUTPUT_CONTROL_MASK | AV_MUTE_MASK);
  1092. uint8_t reg;
  1093. /* if a path_en = 0 had stopped the video, restart it unless done already. */
  1094. if(hw_context->video_ready) {
  1095. reg = mhl_tx_read_reg(hw_context, TPI_SYSTEM_CONTROL_DATA_REG);
  1096. if(mask == (mask & reg)) {
  1097. start_video(hw_context,hw_context->intr_info->edid_parser_context);
  1098. }
  1099. }
  1100. }
  1101. void dump_audio_register(struct drv_hw_context *hw_context, int audio)
  1102. {
  1103. int value = 0;
  1104. int offset = 0;
  1105. // if(audio == AUDIO_44K_2CH || audio == AUDIO_44K_8CH)
  1106. {
  1107. value = mhl_tx_read_reg(hw_context, REG_TPI_CONFIG3);
  1108. MHL_TX_DBG_ERR(hw_context, "REG_TPI_CONFIG3: 0x%x\n", value);
  1109. value = mhl_tx_read_reg(hw_context, TX_PAGE_TPI, 0x0020);
  1110. MHL_TX_DBG_ERR(hw_context, "TX_PAGE_TPI:0x0020: 0x%x\n", value);
  1111. value = mhl_tx_read_reg(hw_context, TX_PAGE_TPI, 0x001F);
  1112. MHL_TX_DBG_ERR(hw_context, "TX_PAGE_TPI:0x001F : 0x%x\n", value);
  1113. value = mhl_tx_read_reg(hw_context, REG_TPI_CONFIG1);
  1114. MHL_TX_DBG_ERR(hw_context, "REG_TPI_CONFIG1 : 0x%x\n", value);
  1115. value = mhl_tx_read_reg(hw_context, REG_TPI_CONFIG2);
  1116. MHL_TX_DBG_ERR(hw_context, "REG_TPI_CONFIG2 : 0x%x\n", value);
  1117. value = mhl_tx_read_reg(hw_context, TX_PAGE_L1, 0x24);
  1118. MHL_TX_DBG_ERR(hw_context, "TX_PAGE_L1:0x24 : 0x%x\n", value);
  1119. value = mhl_tx_read_reg(hw_context, REG_TPI_CONFIG4);
  1120. MHL_TX_DBG_ERR(hw_context, "REG_TPI_CONFIG4 : 0x%x\n", value);
  1121. value = mhl_tx_read_reg(hw_context, TX_PAGE_TPI, 0x0028);
  1122. MHL_TX_DBG_ERR(hw_context, "TX_PAGE_TPI:0x0028 : 0x%x\n", value);
  1123. pr_debug("/********************************Start*********************************/\n");
  1124. pr_debug("Dump TX_PAGE_TPI 0x001F -> 0x0027 Registers\n");
  1125. offset = 0x001F;
  1126. for(offset=0x001F; offset<=0x0028; offset++)
  1127. {
  1128. value = mhl_tx_read_reg(hw_context, TX_PAGE_TPI, offset);
  1129. MHL_TX_DBG_ERR(hw_context, "TX_PAGE_TPI:0x%x : 0x%x\n", offset, value);
  1130. }
  1131. pr_debug("/********************************End***********************************/\n");
  1132. pr_debug("/********************************Start*********************************/\n");
  1133. pr_debug("Dump TX_PAGE_L1 0x0000 -> 0x0034 Registers\n");
  1134. offset = 0x0000;
  1135. for(offset=0x0000; offset<=0x0034; offset++)
  1136. {
  1137. value = mhl_tx_read_reg(hw_context, TX_PAGE_L1, offset);
  1138. MHL_TX_DBG_ERR(hw_context, "TX_PAGE_L1:0x%x : 0x%x\n", offset, value);
  1139. }
  1140. pr_debug("/********************************End***********************************/\n");
  1141. }
  1142. }
  1143. extern uint8_t CA;//Channel/Speaker Allocation.
  1144. extern uint8_t Samplebit;
  1145. extern uint8_t MAX_channel;
  1146. extern uint8_t Cap_MAX_channel;
  1147. extern uint8_t Cap_Samplebit;
  1148. extern uint16_t Cap_SampleRate;
  1149. void set_platform_bitwidth(int bitWidth)
  1150. {
  1151. Samplebit = bitWidth;
  1152. return ;
  1153. }
  1154. void check_TV_capability(struct drv_hw_context *hw_context, int audio, int bitWidth)
  1155. {
  1156. MHL_TX_DBG_INFO(hw_context, "MAX_channel: %d, Cap_Samplebit: %d, Cap_SampleRate: %d\n", MAX_channel, Cap_Samplebit, Cap_SampleRate);
  1157. if(bitWidth == 24)
  1158. {
  1159. if(Cap_Samplebit != HDMI_BITWIDTH_24)
  1160. {
  1161. MHL_TX_DBG_INFO(hw_context, "Samplebit is not supported\n");
  1162. return ;
  1163. }
  1164. }
  1165. if(audio == AUDIO_32K_8CH || audio == AUDIO_44K_8CH || audio == AUDIO_48K_8CH || audio == AUDIO_96K_8CH || audio == AUDIO_192K_8CH)
  1166. {
  1167. if(Cap_MAX_channel != HDMI_CHANNEL_8)
  1168. {
  1169. MHL_TX_DBG_INFO(hw_context, "MAX_channel is not supported\n");
  1170. return ;
  1171. }
  1172. }
  1173. if(audio == AUDIO_192K_2CH || audio == AUDIO_192K_8CH)
  1174. {
  1175. if(Cap_SampleRate < HDMI_SAMPLERATE_192)
  1176. {
  1177. MHL_TX_DBG_INFO(hw_context, "Cap_SampleRate is not supported\n");
  1178. return ;
  1179. }
  1180. }
  1181. return ;
  1182. }
  1183. static void configure_audio(struct drv_hw_context *hw_context, int audio)
  1184. {
  1185. int BIT_TPI_CONFIG4_AUDIO_WIDTH = BIT_TPI_CONFIG4_AUDIO_WIDTH_16_BIT;
  1186. int BIT_TPI_CONFIG3_AUDIO_TDM_BIT_CH= BIT_TPI_CONFIG3_AUDIO_TDM_32B_CH;
  1187. MHL_TX_DBG_INFO(hw_context, "Audio Update to default: Audio_mode_fs=0x%x,CA=0x%x, Samplebit=%d\n",audio, CA, Samplebit);
  1188. current_audio_info_frame[5]=audio<<2;
  1189. check_TV_capability(hw_context, audio, Samplebit);
  1190. if(Samplebit==16){
  1191. BIT_TPI_CONFIG4_AUDIO_WIDTH = BIT_TPI_CONFIG4_AUDIO_WIDTH_16_BIT;
  1192. BIT_TPI_CONFIG3_AUDIO_TDM_BIT_CH= BIT_TPI_CONFIG3_AUDIO_TDM_16B_CH;
  1193. }
  1194. else if(Samplebit==20){
  1195. BIT_TPI_CONFIG4_AUDIO_WIDTH = BIT_TPI_CONFIG4_AUDIO_WIDTH_20_BIT;
  1196. BIT_TPI_CONFIG3_AUDIO_TDM_BIT_CH= BIT_TPI_CONFIG3_AUDIO_TDM_32B_CH;
  1197. }
  1198. else if(Samplebit==24){
  1199. BIT_TPI_CONFIG4_AUDIO_WIDTH = BIT_TPI_CONFIG4_AUDIO_WIDTH_24_BIT;
  1200. BIT_TPI_CONFIG3_AUDIO_TDM_BIT_CH= BIT_TPI_CONFIG3_AUDIO_TDM_32B_CH;
  1201. }
  1202. if ( AUDIO_32K_2CH == audio )
  1203. {
  1204. MHL_TX_DBG_INFO(hw_context, "Audio Update: 32K / 2CH\n");
  1205. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG3,
  1206. BIT_TPI_CONFIG_3_AUDIO_INTERFACE_I2S
  1207. | BIT_TPI_CONFIG3_AUDIO_PACKET_HEADER_LAYOUT_2CH
  1208. | BIT_TPI_CONFIG3_MUTE_MUTED); // Mute the audio
  1209. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG1, 0x03); // Fs=32KHz
  1210. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG4, 0x09|BIT_TPI_CONFIG4_AUDIO_WIDTH); // XX-bit (refer to stream header), 32KHz, 2CH
  1211. }
  1212. else if ( AUDIO_32K_8CH == audio )
  1213. {
  1214. MHL_TX_DBG_INFO(hw_context, "Audio Update: 32K / 8CH / TDM\n");
  1215. current_audio_info_frame[4] = 0x07; //CC2:CC0=3b111(8ch AVI), CT3:CT0=4b0000(Refer to Stream Header)
  1216. current_audio_info_frame[7] = CA; //current_audio_info_frame[7] = 0x13;
  1217. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_0 | BIT_TPI_AUDIO_SD_SEL_0); // SD0 output enable
  1218. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_1 | BIT_TPI_AUDIO_SD_SEL_1); // SD1 output enable
  1219. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_2 | BIT_TPI_AUDIO_SD_SEL_2); // SD2 output enable
  1220. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_3 | BIT_TPI_AUDIO_SD_SEL_3); // SD3 output enable
  1221. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG3,
  1222. BIT_TPI_CONFIG_3_AUDIO_INTERFACE_HD_AUDIO
  1223. | BIT_TPI_CONFIG3_AUDIO_PACKET_HEADER_LAYOUT_8CH_MAX
  1224. | BIT_TPI_CONFIG3_AUDIO_TDM_MSB_1CLK_DEALY
  1225. | BIT_TPI_CONFIG3_AUDIO_TDM_BIT_CH
  1226. | BIT_TPI_CONFIG3_MUTE_MUTED); // Mute the audio
  1227. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG1, BIT_TPI_CONFIG1_AUDIO_FREQUENCY_32K); // Fs=32KHz
  1228. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG4,
  1229. BIT_TPI_CONFIG4_AUDIO_WIDTH
  1230. | BIT_TPI_CONFIG4_AUDIO_FREQUENCY_32K
  1231. | BIT_TPI_CONFIG4_AUDIO_CHANNEL_8CH); // // XX-bit (refer to stream header), 32KHz, 8CH
  1232. mhl_tx_write_reg(hw_context, TX_PAGE_L1 , 0x0024, 0x02);//16-bit Set the I2S Input Size for I2S extraction
  1233. }
  1234. else if ( AUDIO_44K_2CH == audio )
  1235. {
  1236. MHL_TX_DBG_INFO(hw_context, "Audio Update: 44K / 2CH\n");
  1237. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG3,
  1238. BIT_TPI_CONFIG_3_AUDIO_INTERFACE_I2S
  1239. | BIT_TPI_CONFIG3_AUDIO_PACKET_HEADER_LAYOUT_2CH
  1240. | BIT_TPI_CONFIG3_MUTE_MUTED); // Mute the audio
  1241. mhl_tx_write_reg(hw_context, TX_PAGE_TPI,0x0020, 0x90); // Fs=44KHz
  1242. mhl_tx_write_reg(hw_context, TX_PAGE_TPI,0x001F, 0x91); // Fs=44KHz
  1243. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG1, 0x00); // Fs=44KHz
  1244. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG2, 0x02);
  1245. mhl_tx_write_reg(hw_context, TX_PAGE_L1,0x24, 0x02);
  1246. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG4, 0x11|BIT_TPI_CONFIG4_AUDIO_WIDTH); // XX-bit (refer to stream header), 44KHz, 2CH
  1247. mhl_tx_write_reg(hw_context, TX_PAGE_TPI,0x0028, 0x80); // XX-bit (refer to stream header), 44KHz, 2CH
  1248. }
  1249. else if ( AUDIO_44K_8CH == audio )
  1250. {
  1251. MHL_TX_DBG_INFO(hw_context, "Audio Update: 44.1K / 8CH / TDM \n");
  1252. current_audio_info_frame[4] = 0x07; //CC2:CC0=3b111(8ch AVI), CT3:CT0=4b0000(Refer to Stream Header)
  1253. current_audio_info_frame[7] = CA; //current_audio_info_frame[7] = 0x13;
  1254. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_0 | BIT_TPI_AUDIO_SD_SEL_0); // 0x92:0x1F=0x80 ; // SD0 output enable
  1255. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_1 | BIT_TPI_AUDIO_SD_SEL_1); // 0x92:0x1F=0x91 ; // SD1 output enable
  1256. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_2 | BIT_TPI_AUDIO_SD_SEL_2); // 0x92:0x1F=0xA2 ; // SD2 output enable
  1257. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_3 | BIT_TPI_AUDIO_SD_SEL_3); // 0x92:0x1F=0xC3 ; // SD3 output enable
  1258. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG3,
  1259. BIT_TPI_CONFIG_3_AUDIO_INTERFACE_HD_AUDIO
  1260. | BIT_TPI_CONFIG3_AUDIO_PACKET_HEADER_LAYOUT_8CH_MAX
  1261. | BIT_TPI_CONFIG3_AUDIO_TDM_MSB_1CLK_DEALY
  1262. | BIT_TPI_CONFIG3_AUDIO_TDM_BIT_CH
  1263. | BIT_TPI_CONFIG3_MUTE_MUTED); // 0x92:0x26=0xE0 ; // Mute the audio
  1264. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG1, BIT_TPI_CONFIG1_AUDIO_FREQUENCY_44K); // 0x92:0x24=0x00 ; // Fs=44.1KHz
  1265. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG4,
  1266. BIT_TPI_CONFIG4_AUDIO_WIDTH
  1267. | BIT_TPI_CONFIG4_AUDIO_FREQUENCY_44K
  1268. | BIT_TPI_CONFIG4_AUDIO_CHANNEL_8CH); // 0x92:0x27=0x17 // XX-bit (refer to stream header), 44KHz, 8CH
  1269. mhl_tx_write_reg(hw_context, TX_PAGE_L1 , 0x0024, 0x02);//16-bit Set the I2S Input Size for I2S extraction
  1270. }
  1271. else if ( AUDIO_48K_2CH == audio )
  1272. {
  1273. MHL_TX_DBG_INFO(hw_context, "Audio Update: 48K / 2CH\n");
  1274. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_0 | BIT_TPI_AUDIO_SD_SEL_0); // SD0 output enable
  1275. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_DISABLE | BIT_TPI_AUDIO_FIFO_MAP_1 | BIT_TPI_AUDIO_SD_SEL_1); // SD1 output disable
  1276. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_DISABLE | BIT_TPI_AUDIO_FIFO_MAP_2 | BIT_TPI_AUDIO_SD_SEL_2); // SD2 output disable
  1277. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_DISABLE | BIT_TPI_AUDIO_FIFO_MAP_3 | BIT_TPI_AUDIO_SD_SEL_3); // SD3 output disable
  1278. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG3,
  1279. BIT_TPI_CONFIG_3_AUDIO_INTERFACE_I2S
  1280. | BIT_TPI_CONFIG3_AUDIO_PACKET_HEADER_LAYOUT_2CH
  1281. | BIT_TPI_CONFIG3_MUTE_MUTED); // Mute the audio
  1282. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG1, BIT_TPI_CONFIG1_AUDIO_FREQUENCY_48K); // Fs=48KHz
  1283. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG4,
  1284. BIT_TPI_CONFIG4_AUDIO_WIDTH
  1285. | BIT_TPI_CONFIG4_AUDIO_FREQUENCY_48K
  1286. | BIT_TPI_CONFIG4_AUDIO_CHANNEL_2CH); // 24-bit, 48KHz, 2CH
  1287. }
  1288. else if ( AUDIO_48K_8CH == audio )
  1289. {
  1290. MHL_TX_DBG_INFO(hw_context, "Audio Update: 48K / 8CH / TDM\n");
  1291. current_audio_info_frame[4] = 0x07; //CC2:CC0=3b111(8ch AVI), CT3:CT0=4b0000(Refer to Stream Header)
  1292. current_audio_info_frame[7] = CA; //current_audio_info_frame[7] = 0x13;
  1293. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_0 | BIT_TPI_AUDIO_SD_SEL_0); // SD0 output enable
  1294. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_1 | BIT_TPI_AUDIO_SD_SEL_1); // SD1 output enable
  1295. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_2 | BIT_TPI_AUDIO_SD_SEL_2); // SD2 output enable
  1296. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_3 | BIT_TPI_AUDIO_SD_SEL_3); // SD3 output enable
  1297. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG3,
  1298. BIT_TPI_CONFIG_3_AUDIO_INTERFACE_HD_AUDIO
  1299. | BIT_TPI_CONFIG3_AUDIO_PACKET_HEADER_LAYOUT_8CH_MAX
  1300. | BIT_TPI_CONFIG3_AUDIO_TDM_MSB_1CLK_DEALY
  1301. | BIT_TPI_CONFIG3_AUDIO_TDM_BIT_CH
  1302. | BIT_TPI_CONFIG3_MUTE_MUTED); // Mute the audio
  1303. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG1, BIT_TPI_CONFIG1_AUDIO_FREQUENCY_48K); // Fs=48KHz
  1304. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG4,
  1305. BIT_TPI_CONFIG4_AUDIO_WIDTH
  1306. | BIT_TPI_CONFIG4_AUDIO_FREQUENCY_48K
  1307. | BIT_TPI_CONFIG4_AUDIO_CHANNEL_8CH); // 24-bit, 48KHz, 8CH
  1308. mhl_tx_write_reg(hw_context, TX_PAGE_L1 , 0x0024, 0x02);//16-bit Set the I2S Input Size for I2S extraction
  1309. }
  1310. else if ( AUDIO_96K_2CH == audio )
  1311. {
  1312. MHL_TX_DBG_INFO(hw_context, "Audio Update: 48K / 2CH\n");
  1313. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_0 | BIT_TPI_AUDIO_SD_SEL_0); // SD0 output enable
  1314. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_DISABLE | BIT_TPI_AUDIO_FIFO_MAP_1 | BIT_TPI_AUDIO_SD_SEL_1); // SD1 output disable
  1315. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_DISABLE | BIT_TPI_AUDIO_FIFO_MAP_2 | BIT_TPI_AUDIO_SD_SEL_2); // SD2 output disable
  1316. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_DISABLE | BIT_TPI_AUDIO_FIFO_MAP_3 | BIT_TPI_AUDIO_SD_SEL_3); // SD3 output disable
  1317. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG3,
  1318. BIT_TPI_CONFIG_3_AUDIO_INTERFACE_I2S
  1319. | BIT_TPI_CONFIG3_AUDIO_PACKET_HEADER_LAYOUT_2CH
  1320. | BIT_TPI_CONFIG3_MUTE_MUTED); // Mute the audio
  1321. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG1, BIT_TPI_CONFIG1_AUDIO_FREQUENCY_96K); // Fs=48KHz
  1322. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG4,
  1323. BIT_TPI_CONFIG4_AUDIO_WIDTH
  1324. | BIT_TPI_CONFIG4_AUDIO_FREQUENCY_96K
  1325. | BIT_TPI_CONFIG4_AUDIO_CHANNEL_2CH); // 24-bit, 48KHz, 2CH
  1326. }
  1327. else if ( AUDIO_96K_8CH == audio )
  1328. {
  1329. MHL_TX_DBG_INFO(hw_context, "Audio Update: 48K / 8CH / TDM\n");
  1330. current_audio_info_frame[4] = 0x07; //CC2:CC0=3b111(8ch AVI), CT3:CT0=4b0000(Refer to Stream Header)
  1331. current_audio_info_frame[7] = CA; //current_audio_info_frame[7] = 0x13;
  1332. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_0 | BIT_TPI_AUDIO_SD_SEL_0); // SD0 output enable
  1333. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_1 | BIT_TPI_AUDIO_SD_SEL_1); // SD1 output enable
  1334. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_2 | BIT_TPI_AUDIO_SD_SEL_2); // SD2 output enable
  1335. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_3 | BIT_TPI_AUDIO_SD_SEL_3); // SD3 output enable
  1336. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG3,
  1337. BIT_TPI_CONFIG_3_AUDIO_INTERFACE_HD_AUDIO
  1338. | BIT_TPI_CONFIG3_AUDIO_PACKET_HEADER_LAYOUT_8CH_MAX
  1339. | BIT_TPI_CONFIG3_AUDIO_TDM_MSB_1CLK_DEALY
  1340. | BIT_TPI_CONFIG3_AUDIO_TDM_BIT_CH
  1341. | BIT_TPI_CONFIG3_MUTE_MUTED); // Mute the audio
  1342. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG1, BIT_TPI_CONFIG1_AUDIO_FREQUENCY_96K); // Fs=48KHz
  1343. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG4,
  1344. BIT_TPI_CONFIG4_AUDIO_WIDTH
  1345. | BIT_TPI_CONFIG4_AUDIO_FREQUENCY_96K
  1346. | BIT_TPI_CONFIG4_AUDIO_CHANNEL_8CH); // 24-bit, 48KHz, 8CH
  1347. mhl_tx_write_reg(hw_context, TX_PAGE_L1 , 0x0024, 0x02);//16-bit Set the I2S Input Size for I2S extraction
  1348. }
  1349. else if ( AUDIO_192K_2CH == audio )
  1350. {
  1351. MHL_TX_DBG_INFO(hw_context, "Audio Update: 192K / 2CH\n");
  1352. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_0 | BIT_TPI_AUDIO_SD_SEL_0); // SD0 output enable
  1353. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_DISABLE | BIT_TPI_AUDIO_FIFO_MAP_1 | BIT_TPI_AUDIO_SD_SEL_1); // SD1 output disable
  1354. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_DISABLE | BIT_TPI_AUDIO_FIFO_MAP_2 | BIT_TPI_AUDIO_SD_SEL_2); // SD2 output disable
  1355. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_DISABLE | BIT_TPI_AUDIO_FIFO_MAP_3 | BIT_TPI_AUDIO_SD_SEL_3); // SD3 output disable
  1356. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG3,
  1357. BIT_TPI_CONFIG_3_AUDIO_INTERFACE_I2S
  1358. | BIT_TPI_CONFIG3_AUDIO_PACKET_HEADER_LAYOUT_2CH
  1359. | BIT_TPI_CONFIG3_MUTE_MUTED); // Mute the audio
  1360. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG1, BIT_TPI_CONFIG1_AUDIO_FREQUENCY_192K); // Fs=192KHz
  1361. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG4,
  1362. BIT_TPI_CONFIG4_AUDIO_WIDTH
  1363. | BIT_TPI_CONFIG4_AUDIO_FREQUENCY_192K
  1364. | BIT_TPI_CONFIG4_AUDIO_CHANNEL_2CH); // 24-bit, 192KHz, 2CH
  1365. }
  1366. else if ( AUDIO_192K_8CH == audio )
  1367. {
  1368. MHL_TX_DBG_INFO(hw_context, "Audio Update: 192K / 8CH / TDM\n");
  1369. current_audio_info_frame[4] = 0x07; //CC2:CC0=3b111(8ch AVI), CT3:CT0=4b0000(Refer to Stream Header)
  1370. current_audio_info_frame[7] = CA; //current_audio_info_frame[7] = 0x13;
  1371. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_0 | BIT_TPI_AUDIO_SD_SEL_0); // SD0 output enable
  1372. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_1 | BIT_TPI_AUDIO_SD_SEL_1); // SD1 output enable
  1373. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_2 | BIT_TPI_AUDIO_SD_SEL_2); // SD2 output enable
  1374. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_3 | BIT_TPI_AUDIO_SD_SEL_3); // SD3 output enable
  1375. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG3,
  1376. BIT_TPI_CONFIG_3_AUDIO_INTERFACE_HD_AUDIO
  1377. | BIT_TPI_CONFIG3_AUDIO_PACKET_HEADER_LAYOUT_8CH_MAX
  1378. | BIT_TPI_CONFIG3_AUDIO_TDM_MSB_1CLK_DEALY
  1379. | BIT_TPI_CONFIG3_AUDIO_TDM_BIT_CH
  1380. | BIT_TPI_CONFIG3_MUTE_MUTED); // Mute the audio
  1381. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG1, BIT_TPI_CONFIG1_AUDIO_FREQUENCY_192K); // Fs=192KHz
  1382. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG4,
  1383. BIT_TPI_CONFIG4_AUDIO_WIDTH
  1384. | BIT_TPI_CONFIG4_AUDIO_FREQUENCY_192K
  1385. | BIT_TPI_CONFIG4_AUDIO_CHANNEL_8CH); // 24-bit, 192KHz, 8CH
  1386. mhl_tx_write_reg(hw_context, TX_PAGE_L1 , 0x0024, 0x02);//16-bit Set the I2S Input Size for I2S extraction
  1387. }
  1388. else // default: 48K / 2CH
  1389. {
  1390. MHL_TX_DBG_INFO(hw_context, "Audio Update to default: 48K / 2CH\n");
  1391. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_ENABLE | BIT_TPI_AUDIO_FIFO_MAP_0 | BIT_TPI_AUDIO_SD_SEL_0); // SD0 output enable
  1392. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_DISABLE | BIT_TPI_AUDIO_FIFO_MAP_1 | BIT_TPI_AUDIO_SD_SEL_1); // SD1 output disable
  1393. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_DISABLE | BIT_TPI_AUDIO_FIFO_MAP_2 | BIT_TPI_AUDIO_SD_SEL_2); // SD2 output disable
  1394. mhl_tx_write_reg(hw_context, REG_TPI_AUDIO_MAPPING_CONFIG, BIT_TPI_AUDIO_SD_DISABLE | BIT_TPI_AUDIO_FIFO_MAP_3 | BIT_TPI_AUDIO_SD_SEL_3); // SD3 output disable
  1395. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG3,
  1396. BIT_TPI_CONFIG_3_AUDIO_INTERFACE_I2S
  1397. | BIT_TPI_CONFIG3_AUDIO_PACKET_HEADER_LAYOUT_2CH
  1398. | BIT_TPI_CONFIG3_MUTE_MUTED); // Mute the audio
  1399. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG1, BIT_TPI_CONFIG1_AUDIO_FREQUENCY_48K); // Fs=48KHz
  1400. mhl_tx_write_reg(hw_context, REG_TPI_CONFIG4,
  1401. BIT_TPI_CONFIG4_AUDIO_WIDTH
  1402. | BIT_TPI_CONFIG4_AUDIO_FREQUENCY_48K
  1403. | BIT_TPI_CONFIG4_AUDIO_CHANNEL_2CH); // 24-bit, 48KHz, 2CH
  1404. }
  1405. current_audio_info_frame[3]= 0;
  1406. current_audio_info_frame[3]=calculate_generic_checksum(current_audio_info_frame, 0, 14);
  1407. }
  1408. void configure_and_send_audio_info(struct mhl_dev_context *dev_context, int audio_format)
  1409. {
  1410. struct drv_hw_context *hw_context = (struct drv_hw_context *)&dev_context->drv_context;
  1411. MHL_TX_DBG_INFO(hw_context, "Send Audio IF out again....\n");
  1412. configure_audio(hw_context, audio_format);
  1413. DumpIncomingInfoFrame(&(current_audio_info_frame), 14);
  1414. //unmute the audio
  1415. mhl_tx_modify_reg(hw_context, REG_TPI_CONFIG3, BIT_TPI_CONFIG3_MUTE_MASK, BIT_TPI_CONFIG3_MUTE_NORMAL);
  1416. mhl_tx_write_reg(hw_context, REG_TPI_INFO_FSEL, 0xC2); //send audio if repeatly
  1417. mhl_tx_write_reg_block(hw_context, REG_TPI_INFO_BYTE00, AUDIO_IF_SIZE, current_audio_info_frame);
  1418. return ;
  1419. }
  1420. #ifdef EXAMPLE_ONLY // These functions are not called from anywhere.
  1421. static void mute_video(struct drv_hw_context *hw_context)
  1422. {
  1423. MHL_TX_DBG_INFO(hw_context, "AV muted\n");
  1424. mhl_tx_modify_reg(hw_context, TPI_SYSTEM_CONTROL_DATA_REG, AV_MUTE_MASK, AV_MUTE_MUTED);
  1425. }
  1426. #endif // EXAMPLE_ONLY
  1427. static void unmute_video(struct drv_hw_context *hw_context)
  1428. {
  1429. MHL_TX_DBG_INFO(hw_context, "AV unmuted.\n");
  1430. /*
  1431. * Start sending out InfoFrame & Enable HDMI output
  1432. */
  1433. //if(si_edid_sink_is_hdmi(hw_context->intr_info->edid_parser_context))
  1434. {
  1435. MHL_TX_DBG_INFO(hw_context, "It's an HDMI sink.\n");
  1436. // This MUST be done before VSIF / Audio IF sending
  1437. mhl_tx_write_reg(hw_context, TPI_SYSTEM_CONTROL_DATA_REG, TMDS_OUTPUT_MODE_HDMI);
  1438. /*
  1439. * Send AVIF out
  1440. */
  1441. //if ( 1 == hw_context->valid_avif )
  1442. {
  1443. MHL_TX_DBG_INFO(hw_context, "Send AVIF out...\n");
  1444. DumpIncomingInfoFrame(&(hw_context->outgoingAviPayLoad),sizeof(hw_context->outgoingAviPayLoad));
  1445. mhl_tx_write_reg_block(hw_context, TX_PAGE_TPI , 0x000C,
  1446. sizeof(hw_context->outgoingAviPayLoad.ifData),
  1447. (uint8_t*)&hw_context->outgoingAviPayLoad.namedIfData);
  1448. mhl_tx_write_reg(hw_context, REG_TPI_AVI_BYTE13, 0x00);
  1449. }
  1450. // This MUST be done before VSIF / Audio IF sending
  1451. //mhl_tx_write_reg(hw_context, TPI_SYSTEM_CONTROL_DATA_REG, TMDS_OUTPUT_MODE_HDMI);
  1452. /*
  1453. * Send VSIF out
  1454. */
  1455. #ifndef CONFIG_MTK_HDMI_3D_SUPPORT
  1456. if ( 1 == hw_context->valid_vsif && 1 == hw_context->valid_3d )
  1457. #endif
  1458. {
  1459. MHL_TX_DBG_INFO(hw_context, "Send VSIF out...\n");
  1460. mhl_tx_write_reg(hw_context, REG_TPI_INFO_FSEL, BIT_TPI_INFO_EN | BIT_TPI_INFO_RPT | BIT_TPI_INFO_SEL_3D_VSIF); // Send 3D VSIF repeatly
  1461. DumpIncomingInfoFrame(&(hw_context->current_vs_info_frame),sizeof(hw_context->current_vs_info_frame));
  1462. mhl_tx_write_reg_block(hw_context, REG_TPI_INFO_BYTE00, 8, (u8 *)(&(hw_context->current_vs_info_frame)) ); // only 8 bytes are valid for MHL VSIF
  1463. mhl_tx_write_reg(hw_context, REG_TPI_INFO_BYTE30, 0x00);// Trigger the infoframe sending
  1464. }
  1465. /*
  1466. * Send Audio IF out
  1467. */
  1468. //if ( 1 == hw_context->valid_audio_if )
  1469. {
  1470. MHL_TX_DBG_INFO(hw_context, "Send Audio IF out...\n");
  1471. configure_audio(hw_context, Audio_mode_fs);
  1472. DumpIncomingInfoFrame(&(current_audio_info_frame),14);
  1473. // Unmute the audio
  1474. mhl_tx_modify_reg(hw_context, REG_TPI_CONFIG3, BIT_TPI_CONFIG3_MUTE_MASK, BIT_TPI_CONFIG3_MUTE_NORMAL);
  1475. mhl_tx_write_reg(hw_context, REG_TPI_INFO_FSEL, 0xC2); // Send Audio IF repeatly
  1476. mhl_tx_write_reg_block(hw_context, REG_TPI_INFO_BYTE00, AUDIO_IF_SIZE, current_audio_info_frame);
  1477. }
  1478. // SWWA for Bug 29055, begin
  1479. mhl_tx_modify_reg(hw_context, REG_SRST, BIT_AUDIO_FIFO_RST_MASK, BIT_AUDIO_FIFO_RST_SET);
  1480. mhl_tx_modify_reg(hw_context, REG_SRST, BIT_AUDIO_FIFO_RST_MASK, BIT_AUDIO_FIFO_RST_CLR);
  1481. // SWWA for Bug 29055, end
  1482. }
  1483. #if 0
  1484. /*
  1485. * Enable DVI output without InfoFrame sending
  1486. */
  1487. else
  1488. {
  1489. MHL_TX_DBG_INFO(hw_context, "It's a DVI sink.\n");
  1490. mhl_tx_write_reg(hw_context, TPI_SYSTEM_CONTROL_DATA_REG, TMDS_OUTPUT_MODE_DVI);
  1491. }
  1492. #endif
  1493. /* Now we can entertain PATH_EN */
  1494. hw_context->video_ready = 1;
  1495. }
  1496. /*
  1497. Sequence of operations in this function is important.
  1498. 1. Turn off HDCP interrupt
  1499. 2. Turn of TMDS output
  1500. 3. Turn off HDCP engine/encryption
  1501. 4. Clear any leftover HDCP interrupt
  1502. */
  1503. static void stop_video(struct drv_hw_context *hw_context)
  1504. {
  1505. MHL_TX_DBG_INFO(hw_context, "stop video.\n");
  1506. #ifdef HDCP_ENABLE
  1507. /* Turn off HDCP interrupt */
  1508. enable_intr(hw_context, INTR_HDCP, (0x00));
  1509. enable_intr(hw_context, INTR_HDCP2, (0x00));
  1510. #endif // HDCP_ENABLE
  1511. /* We must maintain the output bit (bit 0) to allow just one bit change
  1512. * later when BKSV read is triggered. */
  1513. if(si_edid_sink_is_hdmi(hw_context->intr_info->edid_parser_context)) {
  1514. mhl_tx_write_reg(hw_context, TPI_SYSTEM_CONTROL_DATA_REG
  1515. , TMDS_OUTPUT_CONTROL_POWER_DOWN
  1516. | AV_MUTE_MUTED
  1517. | TMDS_OUTPUT_MODE_HDMI
  1518. );
  1519. } else {
  1520. mhl_tx_write_reg(hw_context, TPI_SYSTEM_CONTROL_DATA_REG
  1521. , TMDS_OUTPUT_CONTROL_POWER_DOWN
  1522. | AV_MUTE_MUTED
  1523. | TMDS_OUTPUT_MODE_DVI
  1524. );
  1525. }
  1526. // TODO: FD, MUST, seems to be a proper place to stop infoframe sending?
  1527. #ifdef HDCP_ENABLE
  1528. /* stop hdcp engine */
  1529. mhl_tx_write_reg(hw_context, TPI_HDCP_CONTROL_DATA_REG, 0);
  1530. /* clear any leftover hdcp interrupt */
  1531. mhl_tx_write_reg(hw_context, g_intr_tbl[INTR_HDCP].stat_page, g_intr_tbl[INTR_HDCP].stat_offset, 0xff);
  1532. mhl_tx_write_reg(hw_context, g_intr_tbl[INTR_HDCP2].stat_page, g_intr_tbl[INTR_HDCP2].stat_offset, 0xff);
  1533. #endif // HDCP_ENABLE
  1534. }
  1535. #ifdef HDCP_ENABLE
  1536. static void start_hdcp(struct drv_hw_context *hw_context)
  1537. {
  1538. MHL_TX_DBG_INFO(hw_context, "start_hdcp");
  1539. /* First stop hdcp and video */
  1540. stop_video(hw_context);
  1541. #if 0 //(
  1542. /* Came here too often, pause a bit. */
  1543. if( (hdcp_bksv_err_count > HDCP_ERROR_THRESHOLD) ||
  1544. (hdcp_link_err_count > HDCP_ERROR_THRESHOLD) ||
  1545. (hdcp_reneg_err_count > HDCP_ERROR_THRESHOLD) ||
  1546. (hdcp_suspend_err_count > HDCP_ERROR_THRESHOLD))
  1547. {
  1548. MHL_TX_DBG_ERR(hw_context, "Too many HDCP Errors: bksv_err= %d, reneg_err= %d, link_err= %d, suspend_err= %d\n",
  1549. hdcp_bksv_err_count, hdcp_reneg_err_count, hdcp_link_err_count, hdcp_suspend_err_count);
  1550. hdcp_bksv_err_count = hdcp_reneg_err_count = hdcp_link_err_count = hdcp_suspend_err_count = 0;
  1551. //msleep(10 * 1000);
  1552. /*
  1553. * Check CKDT and SCDT.
  1554. * It is possible that lack of clock instability is why hdcp is not
  1555. * succeeding after repeated retries
  1556. *
  1557. * Do not continue this anymore. Returning without restarting HDCP
  1558. * ensures this thread is completely killed.
  1559. */
  1560. return;
  1561. }
  1562. #endif //)
  1563. /* Ensure we get HDCP interrupts now onwards. Clear interrupt first. */
  1564. mhl_tx_write_reg(hw_context, g_intr_tbl[INTR_HDCP].stat_page, g_intr_tbl[INTR_HDCP].stat_offset, 0xff);
  1565. mhl_tx_write_reg(hw_context, g_intr_tbl[INTR_HDCP2].stat_page, g_intr_tbl[INTR_HDCP2].stat_offset, 0xff);
  1566. if(get_cbus_connection_status(hw_context)) {
  1567. /* Enable HDCP interrupt */
  1568. enable_intr(hw_context, INTR_HDCP,
  1569. ( BIT_TPI_INTR_ST0_HDCP_AUTH_STATUS_CHANGE_EVENT
  1570. | BIT_TPI_INTR_ST0_HDCP_SECURITY_CHANGE_EVENT
  1571. ));
  1572. /* Enable HDCP interrupt */
  1573. enable_intr(hw_context, INTR_HDCP2,
  1574. ( BIT_TPI_INTR_ST1_BKSV_DONE
  1575. | BIT_TPI_INTR_ST1_BKSV_ERR
  1576. ));
  1577. msleep(250);
  1578. /*
  1579. * Chip requires only bit 4 to change for BKSV read
  1580. * No other bit should change.
  1581. */
  1582. mhl_tx_modify_reg(hw_context, TPI_SYSTEM_CONTROL_DATA_REG,
  1583. TMDS_OUTPUT_CONTROL_MASK,
  1584. TMDS_OUTPUT_CONTROL_ACTIVE);
  1585. }
  1586. }
  1587. #endif // HDCP_ENABLE
  1588. /*
  1589. * start_video
  1590. *
  1591. *
  1592. */
  1593. static int start_video(struct drv_hw_context *hw_context, void *edid_parser_context)
  1594. {
  1595. struct mhl_dev_context *dev_context;
  1596. MHL_TX_DBG_INFO(hw_context,"called.\n");
  1597. dev_context = get_mhl_device_context(hw_context);
  1598. /*
  1599. * stop hdcp and video
  1600. * this kills any hdcp thread going on already
  1601. */
  1602. stop_video(hw_context);
  1603. /*
  1604. * if path has been disabled by PATH_EN = 0 return with error;
  1605. * When enabled, this function will be called again.
  1606. * if downstream connection has been lost (CLR_HPD), return with error.
  1607. */
  1608. /*
  1609. if((0 == hw_context->video_path)
  1610. || (0 == get_cbus_connection_status(hw_context))
  1611. || (false == dev_context->misc_flags.flags.rap_content_on)
  1612. ) {
  1613. return false;
  1614. }*/
  1615. /*
  1616. * For DVI, output video w/o infoframe; No video settings are changed.
  1617. */
  1618. //if(si_edid_sink_is_hdmi(hw_context->intr_info->edid_parser_context)) {
  1619. /*
  1620. * setup registers for packed pixel, 3D, colors and AVIF
  1621. * using incoming info frames.
  1622. */
  1623. if(false == set_hdmi_params(dev_context)) {
  1624. /* Do not disrupt an ongoing video for bad incoming infoframes */
  1625. return false;
  1626. }
  1627. /*}
  1628. else {
  1629. uint32_t pixel_clock_frequency;
  1630. pixel_clock_frequency = si_mhl_tx_find_timings_from_totals(dev_context->edid_parser_context);
  1631. set_mhl_zone_settings(dev_context,pixel_clock_frequency);
  1632. }*/
  1633. #ifdef HDCP_ENABLE
  1634. MHL_TX_DBG_INFO(hw_context,"Start HDCP Authentication\n");
  1635. start_hdcp(hw_context);
  1636. #else
  1637. unmute_video(hw_context);
  1638. #endif // HDCP_ENABLE
  1639. return true;
  1640. }
  1641. bool si_mhl_tx_set_path_en_I(struct mhl_dev_context *dev_context)
  1642. {
  1643. MHL_TX_DBG_INFO(dev_context, "called si_mhl_tx_set_path_en_I\n");
  1644. return start_video((struct drv_hw_context *) (&dev_context->drv_context), NULL);
  1645. }
  1646. #ifdef HDCP_ENABLE
  1647. static int hdcp_isr(struct drv_hw_context *hw_context, uint8_t tpi_int_status)
  1648. {
  1649. uint8_t query_data;
  1650. MHL_TX_DBG_INFO(hw_context, "hdcp interrupt handling...\n");
  1651. query_data = mhl_tx_read_reg(hw_context, TPI_HDCP_QUERY_DATA_REG);
  1652. MHL_TX_DBG_INFO(hw_context, "R3D= %02x R29= %02x\n", tpi_int_status, query_data);
  1653. if (BIT_TPI_INTR_ST0_HDCP_SECURITY_CHANGE_EVENT & tpi_int_status) {
  1654. int link_status;
  1655. link_status = query_data & LINK_STATUS_MASK;
  1656. switch (link_status) {
  1657. case LINK_STATUS_NORMAL:
  1658. unmute_video(hw_context);
  1659. break;
  1660. case LINK_STATUS_LINK_LOST:
  1661. hdcp_link_err_count++;
  1662. start_hdcp(hw_context);
  1663. break;
  1664. case LINK_STATUS_RENEGOTIATION_REQ:
  1665. MHL_TX_DBG_INFO(hw_context
  1666. , "tpi BSTATUS2: 0x%x\n"
  1667. , mhl_tx_read_reg(hw_context,REG_TPI_BSTATUS2)
  1668. );
  1669. hdcp_reneg_err_count++;
  1670. /* Disabling TMDS output here will disturb the clock */
  1671. mhl_tx_modify_reg(hw_context
  1672. , TPI_SYSTEM_CONTROL_DATA_REG
  1673. , AV_MUTE_MASK
  1674. , AV_MUTE_MUTED);
  1675. /* send TPI hardware to HDCP_Prep state */
  1676. mhl_tx_write_reg(hw_context, TPI_HDCP_CONTROL_DATA_REG, 0);
  1677. break;
  1678. case LINK_STATUS_LINK_SUSPENDED: // TODO: FD, TBC, this bit is rsvd in Drake register map
  1679. MHL_TX_DBG_INFO(hw_context , "######### ATTENTION!!! ######### a rsvd bit in Drake is used.\n");
  1680. hdcp_suspend_err_count++;
  1681. start_hdcp(hw_context);
  1682. break;
  1683. }
  1684. }
  1685. /* Check if HDCP state has changed: */
  1686. else if (BIT_TPI_INTR_ST0_HDCP_AUTH_STATUS_CHANGE_EVENT & tpi_int_status) {
  1687. uint8_t new_link_prot_level;
  1688. new_link_prot_level = (uint8_t)
  1689. (query_data & (EXTENDED_LINK_PROTECTION_MASK |
  1690. LOCAL_LINK_PROTECTION_MASK));
  1691. switch (new_link_prot_level) {
  1692. case (EXTENDED_LINK_PROTECTION_NONE | LOCAL_LINK_PROTECTION_NONE):
  1693. hdcp_link_err_count++;
  1694. start_hdcp(hw_context);
  1695. break;
  1696. case EXTENDED_LINK_PROTECTION_SECURE:
  1697. case LOCAL_LINK_PROTECTION_SECURE:
  1698. case (EXTENDED_LINK_PROTECTION_SECURE | LOCAL_LINK_PROTECTION_SECURE):
  1699. unmute_video(hw_context);
  1700. break;
  1701. }
  1702. }
  1703. return 0;
  1704. }
  1705. #endif // HDCP_ENABLE
  1706. // TODO: FD, TBD, begin
  1707. /*
  1708. static int to_be_deleted(struct drv_hw_context *hw_context, uint8_t int_status)
  1709. {
  1710. hw_context = hw_context;
  1711. int_status = int_status;
  1712. return 0;
  1713. }
  1714. */
  1715. // End
  1716. extern void hdmi_state_callback(enum HDMI_STATE state);
  1717. extern unsigned int sii_mhl_connected;
  1718. static unsigned int int3Number = 0;
  1719. static int int_3_isr(struct drv_hw_context *hw_context, uint8_t int_3_status)
  1720. {
  1721. #if 1
  1722. uint8_t i;
  1723. #endif
  1724. uint8_t block_offset;
  1725. MHL_TX_DBG_INFO(hw_context, "interrupt handling...\n");
  1726. mhl_tx_write_reg(hw_context, REG_INTR3, int_3_status);
  1727. if (!int_3_status)
  1728. {
  1729. return -1; // -1 means no need to further clear interrupts after calling this function
  1730. }
  1731. if (BIT_INTR3_DDC_CMD_DONE & int_3_status) {
  1732. int ddcStatus;
  1733. ddcStatus = mhl_tx_read_reg(hw_context,REG_DDC_STATUS);
  1734. MHL_TX_EDID_READ(hw_context, "mhl_tx_read_reg(hw_context,REG_DDC_STATUS)=)x%x\n",ddcStatus);
  1735. if (BIT_DDC_STATUS_DDC_NO_ACK & ddcStatus) {
  1736. /* Restart EDID read from block 0 */
  1737. MHL_TX_EDID_READ(hw_context, "before si_mhl_tx_drv_issue_edid_read_request: to read block 0\n");
  1738. if (!si_mhl_tx_drv_issue_edid_read_request(hw_context,
  1739. hw_context->current_edid_request_block=0,
  1740. hw_context->current_edid_request_block_batch=0)) {
  1741. hw_context->intr_info->flags |= DRV_INTR_FLAG_MSC_DONE;
  1742. hw_context->intr_info->msc_done_data =1;
  1743. }
  1744. }
  1745. else {
  1746. // TODO: FD, TBI, improve this snippet after double-check
  1747. /*if (0 == (BIT_INTR3_DDC_FIFO_FULL & int_3_status)) {
  1748. // If there is no FIFO_FULL interrupt after the above clear, just ignore this DDC_DONE interrupt & clear the FIFO
  1749. MHL_TX_EDID_READ(hw_context, "BIT_INTR3_DDC_FIFO_FULL & int_3_status!!n");
  1750. si_mhl_tx_drv_reset_ddc_fifo(hw_context);
  1751. mhl_tx_write_reg(hw_context, g_intr_tbl[INTR_EDID].stat_page, g_intr_tbl[INTR_EDID].stat_offset, 0x0F);
  1752. return -1;
  1753. }*/
  1754. MHL_TX_EDID_READ(hw_context, "This batch of EDID read is complete:\n");
  1755. MHL_TX_EDID_READ(hw_context,
  1756. "\tcurrentEdidRequestBlock:%d\t " \
  1757. "\tcurrentEdidRequestBlockBatch:%d \t" \
  1758. "\tedidFifoBlockNumber:%d \n",
  1759. hw_context->current_edid_request_block,
  1760. hw_context->current_edid_request_block_batch,
  1761. hw_context->edid_fifo_block_number);
  1762. // Save current batch of EDID block data
  1763. MHL_TX_EDID_READ(hw_context, "This batch:%d of EDID read:\n",hw_context->current_edid_request_block_batch);
  1764. block_offset = 128 * hw_context->current_edid_request_block + 16 * hw_context->current_edid_request_block_batch;
  1765. //mhl_tx_read_reg_block(hw_context, REG_DDC_DATA, 16, hw_context->current_edid_block_data + block_offset);
  1766. for (i = 0; i < 16; i++)
  1767. {
  1768. * (hw_context->current_edid_block_data + block_offset+ i) = mhl_tx_read_reg(hw_context, REG_DDC_DATA);
  1769. }
  1770. /*
  1771. for (i = 0; i < 16; i++)
  1772. {
  1773. pr_debug("%02X:%02X ", i, hw_context->current_edid_block_data[block_offset+i] );
  1774. if (15 == i )
  1775. {
  1776. pr_debug("\n");
  1777. }
  1778. }
  1779. */
  1780. // The FIFO_FULL interrupt should be able to be cleared now
  1781. mhl_tx_write_reg(hw_context, g_intr_tbl[INTR_EDID].stat_page, g_intr_tbl[INTR_EDID].stat_offset, BIT_INTR3_DDC_FIFO_FULL);
  1782. MHL_TX_EDID_READ(hw_context, " %d \n", hw_context->current_edid_request_block_batch );
  1783. i=0;
  1784. //MHL_TX_EDID_READ(hw_context, " mhl_tx_read_reg(hw_context,REG_DDC_STATUS)=0x%x,(mhl_tx_read_reg(hw_context,REG_DDC_STATUS)&0x0B)=0x% 000000000000\n", mhl_tx_read_reg(hw_context,REG_DDC_STATUS),(mhl_tx_read_reg(hw_context,REG_DDC_STATUS)&0x0B));
  1785. while((i++<30)&&(mhl_tx_read_reg(hw_context,REG_DDC_STATUS)&0x0B)){
  1786. MHL_TX_EDID_READ(hw_context, " mhl_tx_read_reg(hw_context,REG_DDC_STATUS)=0x%x 111111111\n", mhl_tx_read_reg(hw_context,REG_DDC_STATUS));
  1787. si_mhl_tx_drv_reset_ddc_fifo(hw_context);
  1788. mdelay(5);
  1789. MHL_TX_EDID_READ(hw_context, " mhl_tx_read_reg(hw_context,REG_DDC_STATUS)=0x%x,i=%d 22222222\n", mhl_tx_read_reg(hw_context,REG_DDC_STATUS),i);
  1790. }
  1791. // Totally there are 8 batches for each EDID block read
  1792. if ( 7 > hw_context->current_edid_request_block_batch ) // Issue next batch of EDID block read
  1793. {
  1794. si_mhl_tx_drv_reset_ddc_fifo(hw_context);
  1795. si_mhl_tx_drv_issue_edid_block_batch_read(hw_context,
  1796. hw_context->current_edid_request_block,
  1797. ++hw_context->current_edid_request_block_batch);
  1798. }
  1799. else if ( 7 == hw_context->current_edid_request_block_batch ) // It's the complate of last batch of this block
  1800. {
  1801. int num_extensions;
  1802. MHL_TX_EDID_READ(hw_context, "EDID block read complete\n");
  1803. num_extensions =si_mhl_tx_get_num_cea_861_extensions(
  1804. hw_context->intr_info->edid_parser_context,
  1805. hw_context->current_edid_request_block);
  1806. if (num_extensions < 0) {
  1807. MHL_TX_DBG_ERR(hw_context,"edid problem:%d\n",num_extensions);
  1808. hw_context->current_edid_request_block = 0;
  1809. hw_context->current_edid_request_block_batch = 0;
  1810. hw_context->edid_fifo_block_number = 0;
  1811. si_mhl_tx_drv_reset_ddc_fifo(hw_context);
  1812. if (ne_NO_HPD == num_extensions) {
  1813. // no HPD, so start over
  1814. hw_context->intr_info->flags |= DRV_INTR_FLAG_MSC_DONE;
  1815. hw_context->intr_info->msc_done_data =1;
  1816. } else {
  1817. /* Restart EDID read from block 0 */
  1818. MHL_TX_EDID_READ(hw_context, "before si_mhl_tx_drv_issue_edid_read_request: to read block 0\n");
  1819. if (!si_mhl_tx_drv_issue_edid_read_request(hw_context,
  1820. hw_context->current_edid_request_block=0,
  1821. hw_context->current_edid_request_block_batch=0)) {
  1822. // Notify the component layer with error
  1823. hw_context->intr_info->flags |= DRV_INTR_FLAG_MSC_DONE;
  1824. hw_context->intr_info->msc_done_data =1;
  1825. }
  1826. }
  1827. } else if (hw_context->current_edid_request_block < num_extensions) {
  1828. /* EDID read next block */
  1829. MHL_TX_EDID_READ(hw_context, "before si_mhl_tx_drv_issue_edid_read_request: to read block 0+\n");
  1830. if (!si_mhl_tx_drv_issue_edid_read_request(hw_context,
  1831. ++hw_context->current_edid_request_block,
  1832. hw_context->current_edid_request_block_batch=0)) {
  1833. /* Notify the MHL module with error */
  1834. hw_context->intr_info->flags |= DRV_INTR_FLAG_MSC_DONE;
  1835. hw_context->intr_info->msc_done_data =1;
  1836. }
  1837. } else {
  1838. mhl_tx_write_reg(hw_context, g_intr_tbl[INTR_EDID].stat_page, g_intr_tbl[INTR_EDID].stat_offset, 0x0F);
  1839. enable_intr(hw_context, INTR_EDID, 0);
  1840. MHL_TX_EDID_READ(hw_context, "All 0+ block(s) is/are read.\n");
  1841. MHL_TX_DBG_INFO(hw_context, "All EDID have been read.\n");
  1842. /* Inform MHL module of EDID read MSC command completion */
  1843. hw_context->intr_info->flags |= DRV_INTR_FLAG_MSC_DONE;
  1844. hw_context->intr_info->msc_done_data =0;
  1845. hw_context->ready_for_mdt = true;
  1846. {
  1847. struct mhl_dev_context *dev_context;
  1848. struct cbus_req *req;
  1849. dev_context = get_mhl_device_context(hw_context);
  1850. req = dev_context->current_cbus_req;
  1851. si_mhl_tx_handle_atomic_hw_edid_read_complete(dev_context->edid_parser_context, req);
  1852. dev_context->edid_parse_done = true; // TODO: FD, TBC, check carefully
  1853. dev_context->misc_flags.flags.edid_loop_active = 0;
  1854. mhl_event_notify(dev_context, MHL_TX_EVENT_EDID_DONE, 0, NULL);
  1855. int3Number = 0;
  1856. mhl_tx_stop_timer(dev_context, dev_context->cbus_dpi_timer);
  1857. }
  1858. }
  1859. } // end of "else if ( 7 == hw_current_edid_request_block_batch )"
  1860. }
  1861. }
  1862. return int_3_status;
  1863. }
  1864. /*
  1865. static int get_cbus_connection_status(struct drv_hw_context *hw_context)
  1866. {
  1867. return (BIT_CBUS_HPD & mhl_tx_read_reg(hw_context, REG_CBUS_STATUS));
  1868. }
  1869. */
  1870. static int mhl_cbus_err_isr(struct drv_hw_context *hw_context,
  1871. uint8_t cbus_err_int)
  1872. {
  1873. int ret_val = 0;
  1874. uint8_t ddc_abort_reason = 0;
  1875. uint8_t msc_abort_reason = 0;
  1876. MHL_TX_DBG_INFO(hw_context, "interrupt handling...\n");
  1877. /*
  1878. * Three possible errors could be asserted.
  1879. * 94[2] = DDC_ABORT
  1880. * 94[3] = ABORT while receiving a command - MSC_RCV_ERROR
  1881. * The ABORT reasons are in 9A
  1882. * 94[6] = ABORT while sending a command - MSC_SEND_ERROR
  1883. * The ABORT reasons are in 9C
  1884. */
  1885. if(cbus_err_int & BIT_CBUS_DDC_ABRT) {
  1886. /*
  1887. * For DDC ABORTs, options are
  1888. * 1. reset DDC block. This will hamper a broken HDCP or EDID.
  1889. * 2. if error persists, reset the chip. In any case video is not
  1890. * working. So it should not cause blinks.
  1891. * In either case, call an API to let SoC know what happened.
  1892. *
  1893. * Only option 1 has been implemented here.
  1894. */
  1895. ddc_abort_reason = mhl_tx_read_reg(hw_context, REG_CBUS_DDC_ABORT_INT);
  1896. MHL_TX_DBG_ERR(hw_context, "CBUS DDC ABORT. Reason = %02X\n", ddc_abort_reason);
  1897. if(DDC_ABORT_THRESHOLD < ++ddc_abort_count) {
  1898. si_mhl_tx_drv_reset_ddc_fifo(hw_context);
  1899. ddc_abort_count = 0;
  1900. MHL_TX_DBG_ERR(hw_context, "DDC fifo has been reset.%s\n"
  1901. ,((BIT_CBUS_DDC_PEER_ABORT & ddc_abort_reason)
  1902. &&
  1903. (ddc_abort_count >= DDC_ABORT_THRESHOLD)
  1904. ) ? " Please reset sink device!!!"
  1905. : ""
  1906. );
  1907. }
  1908. }
  1909. if(cbus_err_int & BIT_CBUS_MSC_ABORT_RCVD) {
  1910. /*
  1911. * For MSC Receive time ABORTs
  1912. * - Defer submission of new commands by 2 seconds per MHL specs
  1913. * - This is not even worth reporting to SoC. Action is in the hands of peer.
  1914. */
  1915. hw_context->intr_info->flags |= DRV_INTR_FLAG_CBUS_ABORT;
  1916. msc_abort_reason = mhl_tx_read_reg(hw_context, REG_MSC_RCV_ERROR);
  1917. ++msc_abort_count; // TODO: FD, TBI, not actually used now
  1918. MHL_TX_DBG_ERR(hw_context, "#%d: ABORT during MSC RCV. Reason = %02X\n",
  1919. msc_abort_count, msc_abort_reason);
  1920. // TODO: FD, TBI, why not clear the error interrupt here as in 'BIT_CBUS_CMD_ABORT' handling???
  1921. }
  1922. if(cbus_err_int & BIT_CBUS_CMD_ABORT) {
  1923. /*
  1924. * 1. Defer submission of new commands by 2 seconds per MHL specs
  1925. * 2. For API operations such as RCP/UCP etc., report the situation to
  1926. * SoC and let the decision be there. Internal retries have been already
  1927. * done.
  1928. */
  1929. hw_context->intr_info->flags |= DRV_INTR_FLAG_CBUS_ABORT;
  1930. msc_abort_reason = mhl_tx_read_reg(hw_context, REG_CBUS_MSC_MT_ABORT_INT);
  1931. MHL_TX_DBG_ERR(hw_context, "CBUS ABORT during MSC SEND. Reason = %02X\n",
  1932. msc_abort_reason);
  1933. mhl_tx_write_reg(hw_context,REG_CBUS_MSC_MT_ABORT_INT,msc_abort_reason);
  1934. }
  1935. /*
  1936. * Print the reason for information
  1937. */
  1938. if (msc_abort_reason) {
  1939. if (BIT_CBUS_MSC_MT_ABORT_INT_MAX_FAIL & msc_abort_reason) {
  1940. MHL_TX_DBG_ERR(hw_context, "Retry threshold exceeded\n");
  1941. }
  1942. if (BIT_CBUS_MSC_MT_ABORT_INT_PROTO_ERR & msc_abort_reason) {
  1943. MHL_TX_DBG_ERR(hw_context, "Protocol Error\n");
  1944. }
  1945. if (BIT_CBUS_MSC_MT_ABORT_INT_TIMEOUT & msc_abort_reason) {
  1946. MHL_TX_DBG_ERR(hw_context, "Translation layer timeout\n");
  1947. }
  1948. if (BIT_CBUS_MSC_MT_ABORT_INT_UNDEF_CMD & msc_abort_reason) {
  1949. MHL_TX_DBG_ERR(hw_context, "Undefined opcode\n");
  1950. }
  1951. if (BIT_CBUS_MSC_MT_ABORT_INT_MSC_MT_PEER_ABORT & msc_abort_reason) {
  1952. MHL_TX_DBG_ERR(hw_context, "MSC Peer sent an ABORT\n");
  1953. }
  1954. }
  1955. return(ret_val);
  1956. }
  1957. /*
  1958. * mhl_cbus_isr
  1959. *
  1960. * Only when MHL connection has been established. This is where we have the
  1961. * first looks on the CBUS incoming commands or returned data bytes for the
  1962. * previous outgoing command.
  1963. *
  1964. * It simply stores the event and allows application to pick up the event
  1965. * and respond at leisure.
  1966. *
  1967. * return values:
  1968. * 0 - MHL interrupts (all of them) have been cleared
  1969. * - calling routine should exit
  1970. * 1 - MHL interrupts (at least one of them) may not have been cleared
  1971. * - calling routine should proceed with interrupt processing.
  1972. */
  1973. extern void reset_av_info(void);
  1974. static int mhl_cbus_isr(struct drv_hw_context *hw_context, uint8_t cbus_int)
  1975. {
  1976. struct mhl_dev_context *dev_context;
  1977. MHL_TX_DBG_INFO(hw_context, "interrupt handling..., cbus_int=0x%02x\n",cbus_int);
  1978. if (cbus_int & BIT_CBUS_MSC_MR_WRITE_BURST){
  1979. mhl_tx_write_reg(hw_context, REG_CBUS_INT_0,cbus_int & BIT_CBUS_MSC_MR_WRITE_BURST);
  1980. mhl_tx_read_reg_block(hw_context, REG_CBUS_MHL_SCRPAD_0,
  1981. ARRAY_SIZE(hw_context->write_burst_data),
  1982. hw_context->write_burst_data);
  1983. dev_context = get_mhl_device_context(hw_context);
  1984. mhl_event_notify(dev_context, MHL_TX_EVENT_SMB_DATA, 0, (void *)(hw_context->write_burst_data+8));
  1985. }
  1986. if (cbus_int & ~BIT_CBUS_HPD_RCVD){
  1987. // TODO: FD, TBC
  1988. /* bugzilla 27396
  1989. Logic to detect missed HPD interrupt.
  1990. Do not clear BIT_CBUS_HPD_RCVD yet.
  1991. */
  1992. mhl_tx_write_reg(hw_context, REG_CBUS_INT_0,cbus_int & ~BIT_CBUS_HPD_RCVD);
  1993. }
  1994. if (BIT_CBUS_HPD_RCVD & cbus_int) {
  1995. uint8_t cbus_status;
  1996. uint8_t status;
  1997. /* Check if a SET_HPD came from the downstream device. */
  1998. cbus_status = mhl_tx_read_reg(hw_context, REG_CBUS_STATUS);
  1999. status = cbus_status & BIT_CBUS_HPD;
  2000. if(BIT_CBUS_HPD & (hw_context->cbus_status ^ cbus_status)) {
  2001. // TODO: FD, TBC, need to be checked together with above 'todo'
  2002. /* bugzilla 27396
  2003. No HPD interrupt has been missed yet.
  2004. Clear BIT_CBUS_HPD_RCVD.
  2005. */
  2006. mhl_tx_write_reg(hw_context, REG_CBUS_INT_0, BIT_CBUS_HPD_RCVD);
  2007. MHL_TX_DBG_INFO(hw_context, "HPD change\n");
  2008. }
  2009. else{
  2010. MHL_TX_DBG_ERR(hw_context, "missed HPD change\n");
  2011. /* leave the BIT_CBUS_HPD_RCVD interrupt uncleared, so that
  2012. * we get another interrupt
  2013. */
  2014. /* whatever we missed, it's the inverse of what we got */
  2015. status ^= BIT_CBUS_HPD;
  2016. cbus_status ^= BIT_CBUS_HPD;
  2017. }
  2018. MHL_TX_DBG_INFO(hw_context, "DS HPD changed to %02X\n", status);
  2019. hw_context->intr_info->flags |= DRV_INTR_FLAG_HPD_CHANGE;
  2020. hw_context->intr_info->hpd_status = status;
  2021. if ( 0 == status) {
  2022. struct mhl_dev_context *dev_context;
  2023. dev_context = get_mhl_device_context(hw_context);
  2024. MHL_TX_DBG_ERR(hw_context, "got CLR_HPD\n\n");
  2025. // TODO: FD, TBI, any need to fine-tune some power control here?
  2026. hw_context->current_edid_request_block = 0;
  2027. #ifdef ENABLE_GEN2 //(
  2028. /*
  2029. At DS HPD low:
  2030. Disable h/w automation of WRITE_BURST.
  2031. 3D packets are handled using legacy WRITE_BURST method.
  2032. */
  2033. disable_gen2_write_burst(hw_context);
  2034. #endif //)
  2035. hw_context->ready_for_mdt = false;
  2036. /* default values for video */
  2037. hw_context->video_ready = true; // TODO: FD, TBC
  2038. // hw_context->video_ready = false;
  2039. //hw_context->video_path = 1; // TODO: FD, TBC
  2040. /*
  2041. * This cannot wait for the upper layer to notice DRV_INTR_FLAG_HPD_CHANGE.
  2042. * stop_video relies on the result.
  2043. */
  2044. si_edid_reset(dev_context->edid_parser_context);
  2045. }
  2046. else {
  2047. MHL_TX_DBG_INFO(hw_context, "\n\nGot SET_HPD\n\n");
  2048. hw_context->video_ready = true; // TODO: FD, TBC
  2049. // hw_context->video_path = 0; // TODO: FD, TBC
  2050. }
  2051. /* if DS sent CLR_HPD or SET_HPD, ensure video is not there */
  2052. stop_video(hw_context);
  2053. hw_context->cbus_status = cbus_status;
  2054. }
  2055. if (BIT_CBUS_MSC_MT_DONE & cbus_int) {
  2056. MHL_TX_DBG_INFO(hw_context, "MSC_REQ_DONE\n");
  2057. hw_context->intr_info->flags |= DRV_INTR_FLAG_MSC_DONE;
  2058. hw_context->intr_info->msc_done_data =
  2059. mhl_tx_read_reg(hw_context, REG_CBUS_PRI_RD_DATA_1ST);
  2060. #ifdef ENABLE_GEN2 //(
  2061. /* Enable h/w automation of WRITE_BURST */
  2062. enable_gen2_write_burst(hw_context);
  2063. #endif //)
  2064. }
  2065. if (BIT_CBUS_MSC_MT_DONE_NACK & cbus_int){
  2066. MHL_TX_DBG_ERR(hw_context,"MSC_MT_DONE_NACK\n");
  2067. hw_context->intr_info->flags |= DRV_INTR_FLAG_MSC_NAK;
  2068. }
  2069. if (BIT_CBUS_MSC_MR_WRITE_STAT & cbus_int) {
  2070. /* read status bytes */
  2071. mhl_tx_read_reg_block(hw_context, REG_CBUS_WRITE_STAT_0,
  2072. ARRAY_SIZE(hw_context->intr_info->write_stat),
  2073. hw_context->intr_info->write_stat);
  2074. if(MHL_STATUS_DCAP_RDY & hw_context->intr_info->write_stat[0]) {
  2075. MHL_TX_DBG_INFO(hw_context, "\n\ngot DCAP_RDY\n\n");
  2076. /* Enable EDID interrupt */
  2077. // TODO: FD, TBC, EDID DDC handling interrupt
  2078. //enable_intr(hw_context, INTR_EDID, BIT_INTR3_DDC_CMD_DONE
  2079. // | BIT_INTR3_DDC_FIFO_FULL);
  2080. }
  2081. /*
  2082. * Save received write_stat info for later
  2083. * post interrupt processing
  2084. */
  2085. hw_context->intr_info->flags |= DRV_INTR_FLAG_WRITE_STAT;
  2086. }
  2087. if ((BIT_CBUS_MSC_MR_MSC_MSG & cbus_int)) {
  2088. /*
  2089. * Save received MSC message info for later
  2090. * post interrupt processing
  2091. */
  2092. hw_context->intr_info->flags |= DRV_INTR_FLAG_MSC_RECVD;
  2093. mhl_tx_read_reg_block(hw_context,
  2094. REG_CBUS_MSC_MR_MSC_MSG_RCVD_1ST_DATA,
  2095. ARRAY_SIZE(hw_context->intr_info->msc_msg),
  2096. hw_context->intr_info->msc_msg);
  2097. MHL_TX_DBG_INFO(hw_context, "MSC MSG: %02X %02X\n",
  2098. hw_context->intr_info->msc_msg[0],
  2099. hw_context->intr_info->msc_msg[1]);
  2100. }
  2101. /*
  2102. * don't do anything for a scratch pad write received interrupt.
  2103. * instead wait for the DSCR_CHG interrupt
  2104. */
  2105. if(BIT_CBUS_MSC_MR_SET_INT & cbus_int) {
  2106. MHL_TX_DBG_INFO(hw_context, "MHL INTR Received\n");
  2107. /*
  2108. * Save received SET INT message info for later
  2109. * post interrupt processing
  2110. */
  2111. hw_context->intr_info->flags |= DRV_INTR_FLAG_SET_INT;
  2112. mhl_tx_read_reg_block(hw_context,
  2113. REG_CBUS_SET_INT_0,
  2114. ARRAY_SIZE(hw_context->intr_info->int_msg),
  2115. hw_context->intr_info->int_msg);
  2116. mhl_tx_write_reg_block(hw_context,
  2117. REG_CBUS_SET_INT_0,
  2118. ARRAY_SIZE(hw_context->intr_info->int_msg),
  2119. hw_context->intr_info->int_msg);
  2120. if (MHL_INT_EDID_CHG & hw_context->intr_info->int_msg[1]) {
  2121. int reg_val;
  2122. MHL_TX_DBG_INFO(hw_context, "\n\ngot EDID_CHG\n\n");
  2123. /* clear this bit so that BIT_TPI_INFO_EN will get cleared by the h/w */
  2124. mhl_tx_modify_reg(hw_context,REG_TPI_INFO_FSEL
  2125. ,BIT_TPI_INFO_RPT
  2126. ,0
  2127. );
  2128. /* MHL module will re-read EDID */
  2129. // No need to re-read here, it will be handled in later processing: si_mhl_tx_got_mhl_intr
  2130. stop_video(hw_context);
  2131. /* prevent HDCP interrupts from coming in */
  2132. reg_val = mhl_tx_read_reg(hw_context, REG_TPI_SEL);
  2133. MHL_TX_DBG_INFO(hw_context, "REG_TPI_SEL:%02x\n", reg_val);
  2134. reg_val &= ~BIT_TPI_SEL_SW_TPI_EN_MASK;
  2135. reg_val |= BIT_TPI_SEL_SW_TPI_EN_NON_HW_TPI;
  2136. mhl_tx_write_reg(hw_context, REG_TPI_SEL, reg_val);
  2137. /* SetTPIMode */
  2138. MHL_TX_DBG_INFO(hw_context, "REG_TPI_SEL:%02x\n", reg_val);
  2139. reg_val &= ~BIT_TPI_SEL_SW_TPI_EN_MASK;
  2140. reg_val |= BIT_TPI_SEL_SW_TPI_EN_HW_TPI;
  2141. mhl_tx_write_reg(hw_context, REG_TPI_SEL, reg_val);
  2142. #ifdef HDCP_ENABLE
  2143. /*
  2144. * Clear HDCP interrupt - due to TPI enable, we may get one.
  2145. * TODO: Document this in the PR.
  2146. */
  2147. mhl_tx_write_reg(hw_context, g_intr_tbl[INTR_HDCP].stat_page, g_intr_tbl[INTR_HDCP].stat_offset, 0xff);
  2148. mhl_tx_write_reg(hw_context, g_intr_tbl[INTR_HDCP2].stat_page, g_intr_tbl[INTR_HDCP2].stat_offset, 0xff);
  2149. #endif // HDCP_ENABLE
  2150. } else if (MHL_INT_DSCR_CHG & hw_context->intr_info->int_msg[0]) {
  2151. MHL_TX_DBG_INFO(hw_context, "got DSCR_CHG\n");
  2152. if(hw_context->gen2_write_burst) {
  2153. MHL_TX_DBG_INFO(hw_context,
  2154. "Ignored DSCR_CHG since MDT is enabled\n");
  2155. } else {
  2156. struct mhl_dev_context *dev_context;
  2157. dev_context = get_mhl_device_context(hw_context);
  2158. mhl_tx_read_reg_block(hw_context, REG_CBUS_MHL_SCRPAD_0,
  2159. ARRAY_SIZE(hw_context->write_burst_data),
  2160. hw_context->write_burst_data);
  2161. si_mhl_tx_process_write_burst_data(dev_context);
  2162. }
  2163. } else if (MHL_INT_DCAP_CHG & hw_context->intr_info->int_msg[0]) {
  2164. MHL_TX_DBG_INFO(hw_context, "\n\ngot DCAP_CHG\n\n");
  2165. }
  2166. }
  2167. return -1;
  2168. }
  2169. #ifdef HDCP_ENABLE
  2170. static int int_hdcp2_isr(struct drv_hw_context *hw_context, uint8_t tpi_int_status)
  2171. {
  2172. uint8_t query_data;
  2173. MHL_TX_DBG_INFO(hw_context, "hdcp2 interrupt handling...\n");
  2174. query_data = mhl_tx_read_reg(hw_context, TPI_HDCP_QUERY_DATA_REG);
  2175. MHL_TX_DBG_INFO(hw_context, "R3E= %02x R29= %02x\n", tpi_int_status, query_data);
  2176. if (BIT_TPI_INTR_ST1_BKSV_DONE & tpi_int_status) {
  2177. MHL_TX_DBG_INFO(hw_context, "BIT_TPI_INTR_ST1_BKSV_DONE handling...\n");
  2178. if (PROTECTION_TYPE_MASK & query_data) {
  2179. // TODO: FD, TBC, check this HDCP CTS SWWA for hardware limitation
  2180. int temp;
  2181. /*
  2182. TODO: Document this as SWWA 27396.
  2183. Wait for bottom five bits of debug 6 register to change before
  2184. reading query_data (0x29) register.
  2185. */
  2186. do{
  2187. temp = mhl_tx_read_reg(hw_context,REG_TPI_HW_DBG6) & 0x1F;
  2188. } while (temp == 2);
  2189. if (temp < 2)
  2190. return 0; /* TPI hdcp state machine has restarted, just wait for another BKSV_DONE */
  2191. query_data = mhl_tx_read_reg(hw_context, TPI_HDCP_QUERY_DATA_REG);
  2192. /*
  2193. If the downstream device is a repeater, enforce a 5 second delay
  2194. to pass HDCP CTS 1B-03.
  2195. TODO: Describe this in the PR.
  2196. */
  2197. if (HDCP_REPEATER_YES== (HDCP_REPEATER_MASK & query_data)){
  2198. msleep(HDCP_RPTR_CTS_DELAY_MS);
  2199. }
  2200. // Start authentication here
  2201. // TODO: FD, TBC
  2202. mhl_tx_write_reg(hw_context, TPI_HDCP_CONTROL_DATA_REG,
  2203. BIT_TPI_HDCP_CONTROL_DATA_COPP_PROTLEVEL_MAX);
  2204. #if 0
  2205. mhl_tx_write_reg(hw_context, TPI_HDCP_CONTROL_DATA_REG,
  2206. BIT_TPI_HDCP_CONTROL_DATA_COPP_PROTLEVEL_MAX
  2207. | BIT_TPI_HDCP_CONTROL_DATA_DOUBLE_RI_CHECK_ENABLE);
  2208. #endif
  2209. }
  2210. }
  2211. else if ( BIT_TPI_INTR_ST1_BKSV_ERR & tpi_int_status) {
  2212. MHL_TX_DBG_INFO(hw_context, "BIT_TPI_INTR_ST1_BKSV_ERR handling...\n");
  2213. hdcp_bksv_err_count++;
  2214. start_hdcp(hw_context);
  2215. }
  2216. return 0;
  2217. }
  2218. #endif // HDCP_ENABLE
  2219. static int int_1_isr(struct drv_hw_context *hw_context, uint8_t int_1_status)
  2220. {
  2221. int ret_val = 0;
  2222. MHL_TX_DBG_INFO(hw_context, "interrupt handling...\n");
  2223. if (int_1_status)
  2224. {
  2225. if (BIT_INTR1_RSEN_CHG & int_1_status) {
  2226. uint8_t rsen = 0;
  2227. MHL_TX_DBG_INFO(hw_context, "Got RSEN CHG...\n");
  2228. rsen = mhl_tx_read_reg(hw_context, REG_SYS_STAT);
  2229. if (rsen & BIT_STAT_RSEN)
  2230. {
  2231. MHL_TX_DBG_INFO(hw_context, "Got RSEN_CHG: RSEN_ON\n");
  2232. }
  2233. else
  2234. {
  2235. MHL_TX_DBG_INFO(hw_context, "Got RSEN_CHG: RSEN_OFF,mhl_tx_read_reg(hw_context, REG_INTR4)=0x%x\n",mhl_tx_read_reg(hw_context, REG_INTR4));
  2236. }
  2237. }
  2238. }
  2239. return ret_val;
  2240. }
  2241. /*
  2242. get_device_id
  2243. returns chip Id
  2244. */
  2245. int get_device_id(struct drv_hw_context *hw_context)
  2246. {
  2247. int ret_val = 0;
  2248. uint16_t number = 0;
  2249. ret_val = mhl_tx_read_reg(hw_context, REG_DEV_IDH);
  2250. if (ret_val < 0)
  2251. {
  2252. MHL_TX_DBG_ERR(hw_context, "I2C error 0x%x\n", ret_val);
  2253. }
  2254. else
  2255. {
  2256. number = ret_val << 8;
  2257. ret_val = mhl_tx_read_reg(hw_context, REG_DEV_IDL);
  2258. if (ret_val < 0)
  2259. {
  2260. MHL_TX_DBG_ERR(hw_context, "I2C error 0x%x\n", ret_val);
  2261. }
  2262. else
  2263. {
  2264. ret_val |= number;
  2265. MHL_TX_DBG_ERR(hw_context, "Device ID is: %04X\n", ret_val);
  2266. }
  2267. }
  2268. if ( 0x8348 == ret_val )
  2269. {
  2270. return DEVICE_ID_8348;
  2271. }
  2272. else if ( 0x8346 == ret_val )
  2273. {
  2274. return DEVICE_ID_8346;
  2275. }
  2276. else
  2277. {
  2278. return 0;
  2279. }
  2280. }
  2281. /*
  2282. get_device_rev
  2283. returns chip revision
  2284. */
  2285. static int get_device_rev(struct drv_hw_context *hw_context)
  2286. {
  2287. int ret_val;
  2288. #if MHL_PRODUCT_NUM==8348 //(
  2289. ret_val = mhl_tx_read_reg(hw_context, REG_DEV_REV);
  2290. #else //)(
  2291. ///Please execute Makefile with MHL_PRODUCT_NUM={8348}
  2292. af
  2293. MHL_TX_DBG_ERR(hw_context, "error MHL_PRODUCT_NUM not defeind \n");
  2294. #endif //)
  2295. if (ret_val < 0) {
  2296. MHL_TX_DBG_ERR(hw_context, "I2C error\n");
  2297. ret_val = -1;
  2298. }
  2299. return ret_val;
  2300. }
  2301. /*****************************************************************************/
  2302. /**
  2303. * @brief Handler for MHL transmitter reset requests.
  2304. *
  2305. * This function is called by the MHL layer to request that the MHL transmitter
  2306. * chip be reset. Since the MHL layer is platform agnostic and therefore doesn't
  2307. * know how to control the transmitter's reset pin each platform application is
  2308. * required to implement this function to perform the requested reset operation.
  2309. *
  2310. * @param[in] hwResetPeriod Time in ms. that the reset pin is to be asserted.
  2311. * @param[in] hwResetDelay Time in ms. to wait after reset pin is released.
  2312. *
  2313. *****************************************************************************/
  2314. #ifndef CONFIG_MTK_LEGACY
  2315. extern void reset_mhl_board(int hwResetPeriod, int hwResetDelay);
  2316. #endif
  2317. static void board_reset(struct drv_hw_context *hw_context,
  2318. uint16_t hwResetPeriod,
  2319. uint16_t hwResetDelay)
  2320. {
  2321. #ifdef CONFIG_MTK_LEGACY
  2322. #if defined(GPIO_MHL_RST_B_PIN)
  2323. pr_debug("%s,%d+\n", __func__, __LINE__);
  2324. mt_set_gpio_mode(GPIO_MHL_RST_B_PIN, GPIO_MODE_00);
  2325. mt_set_gpio_dir(GPIO_MHL_RST_B_PIN, GPIO_DIR_OUT);
  2326. mt_set_gpio_out(GPIO_MHL_RST_B_PIN, GPIO_OUT_ONE);
  2327. mdelay(hwResetPeriod);
  2328. mt_set_gpio_out(GPIO_MHL_RST_B_PIN, GPIO_OUT_ZERO);
  2329. mdelay(hwResetPeriod);
  2330. mt_set_gpio_out(GPIO_MHL_RST_B_PIN, GPIO_OUT_ONE);
  2331. mdelay(hwResetDelay);
  2332. #elif defined(CONFIG_MTK_MT6306_SUPPORT)
  2333. pr_debug(":MT6306 %s,%d\n", __func__, __LINE__);
  2334. mt6306_set_gpio_dir(GPIO4, GPIO_DIR_OUT);
  2335. mt6306_set_gpio_out(GPIO4, GPIO_OUT_ONE);
  2336. mdelay(hwResetPeriod);
  2337. mt6306_set_gpio_out(GPIO4, GPIO_OUT_ZERO);
  2338. mdelay(hwResetPeriod);
  2339. mt6306_set_gpio_out(GPIO4, GPIO_OUT_ONE);
  2340. mdelay(hwResetDelay);
  2341. #else
  2342. pr_debug("%s,%d Error: GPIO_MHL_RST_B_PIN is not defined\n", __func__, __LINE__);
  2343. #endif
  2344. #else
  2345. reset_mhl_board(hwResetPeriod, hwResetDelay);
  2346. #endif
  2347. }
  2348. /*
  2349. * clear_and_disable_on_disconnect
  2350. */
  2351. static void clear_and_disable_on_disconnect(struct drv_hw_context *hw_context)
  2352. {
  2353. uint8_t intr_num;
  2354. MHL_TX_DBG_INFO(hw_context, "called.\n");
  2355. //mhl_tx_write_reg(hw_context, REG_INTR4, 0x10);
  2356. /* clear and mask all interrupts */
  2357. for(intr_num = 0; intr_num < MAX_INTR; intr_num++)
  2358. {
  2359. // TODO: FD, TBC & TBU, wait for system's report on RGND INTR behaviors to continue
  2360. if(INTR_DISC == intr_num) {
  2361. /* Clear all interrupts */
  2362. mhl_tx_write_reg(hw_context, g_intr_tbl[intr_num].stat_page, g_intr_tbl[intr_num].stat_offset, 0xBF);
  2363. /* Disable all interrupts, but keep only RGND interrupt enabled */
  2364. enable_intr(hw_context, INTR_DISC, BIT_INTR4_RGND_DETECTION);
  2365. }
  2366. // TODO: FD, TBC or TBD???, remove the check for 'INTR_INTR1'
  2367. else if(INTR_INTR1 == intr_num) {
  2368. /* Clear all interrupts */
  2369. mhl_tx_write_reg(hw_context, g_intr_tbl[intr_num].stat_page, g_intr_tbl[intr_num].stat_offset, 0xFF);
  2370. /* Disable all interrupts, but keep only RGND_CHG interrupt enabled */
  2371. enable_intr(hw_context, INTR_INTR1, 0x00);//enable_intr(hw_context, INTR_INTR1, BIT_INTR1_RSEN_CHG);
  2372. } else {
  2373. /* Clear and disable all interrupts */
  2374. mhl_tx_write_reg(hw_context, g_intr_tbl[intr_num].stat_page, g_intr_tbl[intr_num].stat_offset, 0xFF);
  2375. enable_intr(hw_context, intr_num, 0x00);
  2376. }
  2377. }
  2378. }
  2379. /*
  2380. * This function performs s/w as well as h/w state transitions.
  2381. */
  2382. void switch_to_d3(struct drv_hw_context *hw_context,bool do_interrupt_clear)
  2383. {
  2384. // TODO: FD, TBC, any need to change local timing status to INITIAL??? => per latest tests, it works just find during hot-plugs, may not need to do this
  2385. MHL_TX_DBG_INFO(hw_context, "switch_to_d3 called, do_interrupt_clear=%d\n",do_interrupt_clear);
  2386. mhl_tx_vbus_control(VBUS_OFF);
  2387. // mhl_tx_write_reg(hw_context, REG_DISC_CTRL1, VAL_DISC_CTRL1_DEFAULT);
  2388. /* Meet an MHL CTS timing - Tsrc:cbus_float */
  2389. mdelay(1);
  2390. // mhl_tx_write_reg(hw_context, REG_DISC_CTRL1, VAL_DISC_CTRL1_DEFAULT | BIT_DISC_CTRL1_MHL_DISCOVERY_ENABLE); // TODO: FD, MORE CHECK
  2391. if (do_interrupt_clear){
  2392. clear_and_disable_on_disconnect(hw_context);
  2393. }
  2394. mhl_tx_modify_reg(hw_context, REG_DISC_CTRL4,
  2395. BIT_DC6_USB_OVERRIDE_VALUE,
  2396. BIT_DC6_USB_OVERRIDE_VALUE);
  2397. mhl_tx_modify_reg(hw_context, REG_DISC_CTRL6,
  2398. BIT_DC6_USB_D_OVERRIDE_ON,
  2399. BIT_DC6_USB_D_OVERRIDE_ON);
  2400. /*
  2401. * Change state to D3 by clearing bit 0 power control reg
  2402. */
  2403. mhl_tx_modify_reg(hw_context, REG_DPD,
  2404. BIT_MASTER_POWER_CTRL,
  2405. 0x00);
  2406. ///MHL_TX_DBG_INFO(hw_context, "after switch D3,mhl_tx_read_reg(hw_context, REG_INTR4)=0x%x \n",mhl_tx_read_reg(hw_context, REG_INTR4));
  2407. }
  2408. /* for otg currency leakage */
  2409. void ForceSwitchToD3( struct mhl_dev_context *dev_context)
  2410. {
  2411. MHL_TX_DBG_INFO((struct drv_hw_context *)(&dev_context->drv_context), "ForceSwitchToD3..............\n");
  2412. #ifdef MEDIA_DATA_TUNNEL_SUPPORT
  2413. mdt_destroy(dev_context);
  2414. #endif
  2415. /*
  2416. * Change state to D3 by clearing bit 0 power control reg
  2417. */
  2418. //mhl_tx_modify_reg((struct drv_hw_context *)(&dev_context->drv_context), REG_DPD,
  2419. // BIT_MASTER_POWER_CTRL, 0x00);
  2420. mhl_tx_modify_reg((struct drv_hw_context *)(&dev_context->drv_context), REG_DISC_CTRL1, BIT_DISC_CTRL1_STROBE_OFF, 0);
  2421. mhl_tx_modify_reg((struct drv_hw_context *)(&dev_context->drv_context), REG_DPD, BIT_MASTER_POWER_CTRL, 0);
  2422. MHL_TX_DBG_INFO((struct drv_hw_context *)(&dev_context->drv_context), "!!!!!!!!!!!. ForceSwitchToD3 to D3 0x%x\n", mhl_tx_read_reg((struct drv_hw_context *)(&dev_context->drv_context), REG_INTR4));
  2423. return;
  2424. }
  2425. void ForceNotSwitchToD3(void)
  2426. {
  2427. board_reset(NULL,TX_HW_RESET_PERIOD,TX_HW_RESET_DELAY);
  2428. }
  2429. /*
  2430. * disconnect_mhl
  2431. * This function performs s/w as well as h/w state transitions.
  2432. */
  2433. static void disconnect_mhl(struct drv_hw_context *hw_context,bool do_interrupt_clear)
  2434. {
  2435. MHL_TX_DBG_INFO(hw_context, "called.\n");
  2436. /*
  2437. * Change TMDS termination to high impedance on disconnection
  2438. */
  2439. mhl_tx_write_reg(hw_context, REG_MHLTX_CTL1, BIT_MHLTX_CTL1_TX_TERM_MODE_OFF | BIT_MHLTX_CTL1_DISC_OVRIDE_ON);
  2440. mhl_tx_write_reg(hw_context, REG_DISC_CTRL2, REG_DISC_CTRL2_DEFVAL);
  2441. mhl_tx_write_reg(hw_context, REG_DISC_CTRL4, REG_DISC_CTRL4_DEFVAL);
  2442. mhl_tx_write_reg(hw_context, REG_DISC_CTRL5, REG_DISC_CTRL5_DEFVAL);
  2443. /* Enable MHL discovery so we are waken up by h/w on impedance measurement */
  2444. // mhl_tx_write_reg(hw_context, REG_DISC_CTRL1, VAL_DISC_CTRL1_DEFAULT | BIT_DISC_CTRL1_STROBE_OFF | BIT_DISC_CTRL1_MHL_DISCOVERY_ENABLE);
  2445. // mhl_tx_write_reg(hw_context, REG_DISC_CTRL1, VAL_DISC_CTRL1_DEFAULT | BIT_DISC_CTRL1_MHL_DISCOVERY_ENABLE); // TODO: FD, MORE CHECK
  2446. //if (do_interrupt_clear){
  2447. clear_and_disable_on_disconnect(hw_context);
  2448. //}
  2449. /* 11/23: clear this flag to fix DS hot plug issue */
  2450. hw_context->cbus_status = 0;
  2451. }
  2452. /*
  2453. * MHL device discovery interrupt handler
  2454. * 1. When impedance is measured as 1k, RGND interrupt is asserted.
  2455. * 2. Chip sends out wake pulses and discovery pulses.
  2456. * Then asserts MHL_EST if CBUS stays high to meet MHL timings.
  2457. * 3. If discovery fails, NON_MHL_EST is asserted.
  2458. * 4. If MHL cable is removed, CBUS_DIS is asserted.
  2459. * (Need to check this bit all the time)
  2460. */
  2461. static int int_4_isr(struct drv_hw_context *hw_context, uint8_t int_4_status)
  2462. {
  2463. int ret_val = 0; /* Safe to clear interrupt from master handler */
  2464. MHL_TX_DBG_INFO(hw_context, "interrupt handling...\n");
  2465. //we li
  2466. if(BIT_INTR4_CBUS_LKOUT & int_4_status){
  2467. mhl_tx_write_reg(hw_context, REG_INTR4, 0x30);
  2468. int_4_status = int_4_status & 0xCF;
  2469. MHL_TX_DBG_INFO(hw_context, "BIT_INTR4_CBUS_LKOUT...\n");
  2470. si_mhl_tx_chip_initialize(hw_context);
  2471. }
  2472. if ((BIT_INTR4_CBUS_DISCONNECT & int_4_status) ||
  2473. (BIT_INTR4_NON_MHL_EST & int_4_status)) {
  2474. struct mhl_dev_context *dev_context;
  2475. dev_context = get_mhl_device_context(hw_context);
  2476. MHL_TX_DBG_ERR(hw_context, "got CBUS_DIS. MHL disconnection or USB\n");
  2477. //set_pin(hw_context,LED_MHL, GPIO_LED_OFF);
  2478. //set_pin(hw_context,LED_USB, GPIO_LED_ON);
  2479. /* Setup termination etc. */
  2480. hw_context->intr_info->flags |= DRV_INTR_FLAG_DISCONNECT;
  2481. #if 0
  2482. if (BIT_INTR4_CBUS_DISCONNECT & int_4_status){
  2483. disconnect_mhl(hw_context,true);
  2484. switch_to_d3(hw_context,false);
  2485. }else{ /* must be BIT_INTR4_NON_MHL_EST */
  2486. disconnect_mhl(hw_context,false);
  2487. switch_to_d3(hw_context,true);
  2488. }
  2489. #else
  2490. mhl_tx_stop_timer(dev_context, dev_context->cbus_dpi_timer);
  2491. mhl_tx_stop_timer(dev_context, dev_context->cbus_abort_timer);
  2492. disconnect_mhl(hw_context,true);
  2493. switch_to_d3(hw_context,false);
  2494. #endif
  2495. // TODO: FD, TBI, configure LED_VBUS properly, here?
  2496. ret_val = 0xFF; /* interrupt has been cleared already in disconnect_mhl */
  2497. MHL_TX_DBG_INFO(hw_context, "CBUS disconnection or USB handling done.\n");
  2498. }
  2499. else if (int_4_status & BIT_INTR4_RGND_DETECTION) {
  2500. mhl_tx_modify_reg(hw_context, REG_DISC_STAT2,
  2501. 0x80, 0x80);
  2502. if(0x02 == (mhl_tx_read_reg(hw_context, REG_DISC_STAT2) & 0x03)) {
  2503. MHL_TX_DBG_INFO(hw_context, "Cable impedance = 1k (MHL Device)\n");
  2504. /* Call platform function to turn the VBUS on for unpowered dongle */
  2505. mhl_tx_vbus_control(VBUS_ON);
  2506. msleep(100);
  2507. mhl_tx_write_reg(hw_context, REG_DISC_CTRL1, 0x27);
  2508. /*************************************************************/
  2509. //mhl_tx_write_reg(hw_context, REG_INT_CTRL, BIT_INT_CTRL_POLARITY_LEVEL_LOW | BIT_INT_CTRL_OPEN_DRAIN); // configure INT: open drain & polarity level as '1'
  2510. tmds_configure(hw_context);
  2511. /* Power up to read device ID */
  2512. power_up(hw_context);
  2513. mhl_tx_write_reg(hw_context, REG_INTR4_MASK, 0x00); // clear INT4 mask
  2514. //mhl_tx_write_reg(hw_context, REG_DISC_CTRL1, VAL_DISC_CTRL1_DEFAULT | BIT_DISC_CTRL1_MHL_DISCOVERY_ENABLE); // TODO: FD, MORE CHECK
  2515. mhl_tx_write_reg(hw_context, REG_MHLTX_CTL1, BIT_MHLTX_CTL1_TX_TERM_MODE_OFF | BIT_MHLTX_CTL1_DISC_OVRIDE_ON);
  2516. mhl_tx_write_reg(hw_context, REG_DISC_CTRL2, REG_DISC_CTRL2_DEFVAL);
  2517. mhl_tx_write_reg(hw_context, REG_DISC_CTRL4, REG_DISC_CTRL4_DEFVAL);
  2518. mhl_tx_write_reg(hw_context, REG_DISC_CTRL5, REG_DISC_CTRL5_DEFVAL);
  2519. /* Power up the chip cores to access registers */
  2520. // power_up(hw_context); // TODO: FD, MUST, this is required for D0/D2/D3 support: to wake up from D2 to D3
  2521. /* Ensure Wake up pulse is sent */
  2522. mhl_tx_write_reg(hw_context, REG_DISC_CTRL9
  2523. , BIT_DC9_WAKE_DRVFLT
  2524. | BIT_DC9_DISC_PULSE_PROCEED
  2525. );
  2526. }
  2527. /* enable remaining discovery interrupts */
  2528. enable_intr(hw_context, INTR_DISC,
  2529. BIT_INTR4_MHL_EST
  2530. | BIT_INTR4_NON_MHL_EST
  2531. | BIT_INTR4_CBUS_LKOUT
  2532. | BIT_INTR4_CBUS_DISCONNECT
  2533. | BIT_INTR4_RGND_DETECTION
  2534. | BIT_INTR4_VBUS_CHG // this is required // TODO: FD, TBI, check PR_Notes for details on this, however, seems no other project support this
  2535. );
  2536. /* Enable MSC interrupt to handle initial exchanges */
  2537. /*enable_intr(hw_context, INTR_MERR,
  2538. ( BIT_CBUS_DDC_ABRT
  2539. | BIT_CBUS_MSC_ABORT_RCVD
  2540. | BIT_CBUS_CMD_ABORT
  2541. ));
  2542. enable_intr(hw_context, INTR_MSC,
  2543. ( BIT_CBUS_MSC_MT_DONE
  2544. | BIT_CBUS_HPD_RCVD
  2545. | BIT_CBUS_MSC_MR_WRITE_STAT
  2546. | BIT_CBUS_MSC_MR_MSC_MSG
  2547. | BIT_CBUS_MSC_MR_WRITE_BURST
  2548. | BIT_CBUS_MSC_MR_SET_INT
  2549. | BIT_CBUS_MSC_MT_DONE_NACK
  2550. | BIT_CBUS_CNX_CHG
  2551. ));
  2552. enable_intr(hw_context, INTR_INTR1, BIT_INTR1_RSEN_CHG);*/
  2553. }
  2554. else if(int_4_status & BIT_INTR4_MHL_EST) {
  2555. struct mhl_dev_context *dev_context;
  2556. dev_context = get_mhl_device_context(hw_context);
  2557. /*
  2558. * ENABLE_DISCOVERY ensures it sends wake up and discovery pulse
  2559. * and as result sink/dongle would respond CBUS high.
  2560. */
  2561. MHL_TX_DBG_ERR(hw_context, "got MHL_EST. MHL connection\n");
  2562. /* turn on MHL LED */
  2563. //set_pin(hw_context,LED_MHL,GPIO_LED_ON);
  2564. //set_pin(hw_context,LED_USB, GPIO_LED_OFF);
  2565. // TODO: FD, TBI, configure LED_VBUS properly, here?
  2566. /* Setup registers and enable interrupts for DCAP_RDY, SET_HPD etc. */
  2567. init_regs(hw_context);
  2568. /*
  2569. * Setting this flag triggers sending DCAP_RDY.
  2570. */
  2571. hw_context->intr_info->flags |= DRV_INTR_FLAG_CONNECT;
  2572. /* Enable MSC interrupt to handle initial exchanges */
  2573. enable_intr(hw_context, INTR_MERR,
  2574. ( BIT_CBUS_DDC_ABRT
  2575. | BIT_CBUS_MSC_ABORT_RCVD
  2576. | BIT_CBUS_CMD_ABORT
  2577. ));
  2578. enable_intr(hw_context, INTR_MSC,
  2579. ( BIT_CBUS_MSC_MT_DONE
  2580. | BIT_CBUS_HPD_RCVD
  2581. | BIT_CBUS_MSC_MR_WRITE_STAT
  2582. | BIT_CBUS_MSC_MR_MSC_MSG
  2583. | BIT_CBUS_MSC_MR_WRITE_BURST
  2584. | BIT_CBUS_MSC_MR_SET_INT
  2585. | BIT_CBUS_MSC_MT_DONE_NACK
  2586. | BIT_CBUS_CNX_CHG
  2587. ));
  2588. //process_dpi(dev_context);
  2589. //enable_intr(hw_context, INTR_INTR1, BIT_INTR1_RSEN_CHG);
  2590. }
  2591. return ret_val;
  2592. }
  2593. void SiiMhlTxDrvGetScratchPad(struct drv_hw_context *hw_context,uint8_t startReg,uint8_t *pData,uint8_t length)
  2594. {
  2595. int i;
  2596. for (i = 0; i < length;++i,++startReg)
  2597. {
  2598. //*pData++ = mhl_tx_read_reg(hw_context, (TX_PAGE_CBUS | 0x00C0) + startReg);
  2599. }
  2600. }
  2601. static int g2wb_isr(struct drv_hw_context *hw_context, uint8_t intr_stat)
  2602. {
  2603. uint8_t ret_val = 0,i;
  2604. uint8_t mdt_buffer[20];
  2605. MHL_TX_DBG_INFO(hw_context, "interrupt handling...\n");
  2606. /* Read error register if there was any problem */
  2607. ret_val = mhl_tx_read_reg(hw_context, REG_CBUS_MDT_INT_1);
  2608. if(ret_val) {
  2609. mhl_tx_write_reg(hw_context, REG_CBUS_MDT_INT_1, ret_val);
  2610. MHL_TX_DBG_INFO(hw_context, "\n\ngot MDT Error = %02X\n", ret_val);
  2611. } else {
  2612. uint8_t length;
  2613. /* Read all bytes */
  2614. /*mhl_tx_read_reg_block(hw_context,
  2615. REG_CBUS_MDT_RCV_READ_PORT,
  2616. 16,
  2617. mdt_buffer);*/
  2618. for (i = 0; i < 16; i++)
  2619. {
  2620. mdt_buffer[i] = mhl_tx_read_reg(hw_context, REG_CBUS_MDT_RCV_READ_PORT);
  2621. }
  2622. /* first byte contains the length of data */
  2623. length = mdt_buffer[0];
  2624. /*
  2625. * There isn't any way to know how much of the scratch pad
  2626. * was written so we have to read it all. The app. will have
  2627. * to parse the data to know how much of it is valid.
  2628. */
  2629. /* mhl_tx_read_reg_block(hw_context, REG_CBUS_MDT_RCV_READ_PORT,
  2630. ARRAY_SIZE(hw_context->write_burst_data),
  2631. hw_context->write_burst_data);
  2632. */
  2633. memcpy(hw_context->write_burst_data, &mdt_buffer[1], 16);
  2634. /* Signal upper layer of this arrival */
  2635. hw_context->intr_info->flags |= DRV_INTR_FLAG_WRITE_BURST;
  2636. /*
  2637. * Clear current level in the FIFO.
  2638. * Moves pointer to the next keep RSM enabled
  2639. */
  2640. mhl_tx_write_reg(hw_context,
  2641. REG_CBUS_MDT_RCV_CONTROL,
  2642. BIT_CBUS_MDT_RCV_CONTROL_RFIFO_CLR_CUR_CLEAR
  2643. | BIT_CBUS_MDT_RCV_CONTROL_RCV_EN_ENABLE
  2644. );
  2645. }
  2646. return 0;
  2647. }
  2648. static void enable_intr(struct drv_hw_context *hw_context, uint8_t intr_num, uint8_t intr_mask)
  2649. {
  2650. g_intr_tbl[intr_num].mask = intr_mask;
  2651. mhl_tx_write_reg(hw_context, g_intr_tbl[intr_num].mask_page, g_intr_tbl[intr_num].mask_offset, intr_mask);
  2652. }
  2653. void enable_intr3(struct drv_hw_context *hw_context)
  2654. {
  2655. enable_intr(hw_context, INTR_EDID, BIT_INTR3_DDC_CMD_DONE);
  2656. //| BIT_INTR3_DDC_FIFO_FULL);
  2657. }
  2658. void si_mhl_tx_drv_device_isr(struct drv_hw_context *hw_context, struct interrupt_info *intr_info)
  2659. {
  2660. uint8_t intr_num;
  2661. hw_context->intr_info = intr_info;
  2662. //MHL_TX_DBG_INFO(hw_context, "got INTR\n");
  2663. /* Skip checking interrupts if GPIO pin is not asserted anymore */
  2664. for(intr_num = 0; (intr_num < MAX_INTR) ; intr_num++) {
  2665. if(g_intr_tbl[intr_num].mask)
  2666. {
  2667. int reg_value;
  2668. uint8_t intr_stat;
  2669. reg_value = mhl_tx_read_reg(hw_context,
  2670. g_intr_tbl[intr_num].stat_page,
  2671. g_intr_tbl[intr_num].stat_offset);
  2672. //MHL_TX_DBG_INFO(hw_context, "got INTR11111111111111\n");
  2673. if(reg_value < 0) {
  2674. return;
  2675. }
  2676. intr_stat = (uint8_t)reg_value;
  2677. if(intr_stat) {
  2678. /* Clear interrupt since specific ISR did not. */
  2679. mhl_tx_write_reg(hw_context,
  2680. g_intr_tbl[intr_num].stat_page,
  2681. g_intr_tbl[intr_num].stat_offset,
  2682. intr_stat);
  2683. //}
  2684. }
  2685. //MHL_TX_DBG_INFO(hw_context, "got INTR,intr_stat1111111=0x%x,intr_num=%d\n",intr_stat,intr_num);
  2686. /* Process only specific interrupts we have enabled. Ignore others*/
  2687. //intr_stat = intr_stat & g_intr_tbl[intr_num].mask;
  2688. //MHL_TX_DBG_INFO(hw_context, "got INTR,intr_stat2222222222222=0x%x\n",intr_stat);
  2689. //if(intr_stat)
  2690. {
  2691. int already_cleared;
  2692. #ifdef PRINT_ALL_INTR
  2693. MHL_TX_DBG_ERR(hw_context, "INTR-%s = %02X\n", g_intr_tbl[intr_num].name, intr_stat);
  2694. #else // PRINT_ALL_INTR
  2695. MHL_TX_DBG_INFO(hw_context, "INTR-%s = %02X\n", g_intr_tbl[intr_num].name, intr_stat);
  2696. #endif // PRINT_ALL_INTR
  2697. already_cleared = g_intr_tbl[intr_num].isr(hw_context, intr_stat);
  2698. //if (already_cleared >=0){
  2699. /*
  2700. * only clear the interrupts that were not cleared by the specific ISR.
  2701. */
  2702. //intr_stat &= ~already_cleared;
  2703. }
  2704. } // end of "if(g_intr_tbl[intr_num].mask)"
  2705. #ifdef PRINT_ALL_INTR
  2706. /* These lines print all interrupt status irrespective of mask */
  2707. else {
  2708. uint8_t intr_stat;
  2709. /* Only for debugging - Print other masked interrupts - do not clear */
  2710. intr_stat = mhl_tx_read_reg(hw_context,
  2711. g_intr_tbl[intr_num].stat_page,
  2712. g_intr_tbl[intr_num].stat_offset);
  2713. MHL_TX_DBG_ERR(hw_context, "INTN-%s = %02X\n", g_intr_tbl[intr_num].name, intr_stat);
  2714. }
  2715. #endif // PRINT_ALL_INTR
  2716. }
  2717. }
  2718. /*
  2719. * si_mhl_tx_chip_initialize
  2720. *
  2721. * Chip specific initialization.
  2722. * This function resets and initializes the transmitter and puts chip into sleep.
  2723. * MHL Detection interrupt setups up the chip for video.
  2724. */
  2725. int si_mhl_tx_chip_initialize(struct drv_hw_context *hw_context)
  2726. {
  2727. int ret_val;
  2728. int status = -1;
  2729. siHdmiTx_VideoSel(HDMI_1080P60);
  2730. siHdmiTx_AudioSel(AUDIO_44K_2CH);
  2731. board_reset(hw_context,TX_HW_RESET_PERIOD,TX_HW_RESET_DELAY);
  2732. /*
  2733. if(true ==need_reset_usb_switch)
  2734. {
  2735. mhl_tx_modify_reg(hw_context, REG_DISC_CTRL7, 0xC0,0x40);
  2736. mdelay(5);
  2737. board_reset(hw_context,TX_HW_RESET_PERIOD,TX_HW_RESET_DELAY);
  2738. mhl_tx_modify_reg(hw_context, REG_DISC_CTRL7, 0xC0,0x20);
  2739. }
  2740. */
  2741. mhl_tx_write_reg(hw_context, REG_INT_CTRL, BIT_INT_CTRL_POLARITY_LEVEL_LOW | BIT_INT_CTRL_OPEN_DRAIN); // configure INT: open drain & polarity level as '1'
  2742. tmds_configure(hw_context);
  2743. /* Power up to read device ID */
  2744. power_up(hw_context);
  2745. mhl_tx_write_reg(hw_context, REG_INTR4_MASK, 0x00); // clear INT4 mask
  2746. mhl_tx_write_reg(hw_context, REG_DISC_CTRL1, VAL_DISC_CTRL1_DEFAULT | BIT_DISC_CTRL1_MHL_DISCOVERY_ENABLE); // TODO: FD, MORE CHECK
  2747. ret_val = get_device_rev(hw_context);
  2748. hw_context->chip_rev_id = (uint8_t)ret_val;
  2749. ret_val = get_device_id(hw_context);
  2750. hw_context->chip_device_id = (uint16_t)ret_val;
  2751. chip_device_id = ret_val;
  2752. if (ret_val > 0)
  2753. {
  2754. MHL_TX_DBG_ERR(hw_context, "Found SiI%04X rev: %01X.%01X\n",
  2755. hw_context->chip_device_id,
  2756. hw_context->chip_rev_id >> 4,
  2757. (hw_context->chip_rev_id & 0x0f));
  2758. /* Move to disconnected state. Let RGND/MHL connection event start the driver */
  2759. disconnect_mhl(hw_context, true);
  2760. //mhl_tx_modify_reg(hw_context, REG_DISC_STAT2, 0x80,0x00);
  2761. switch_to_d3(hw_context, false);
  2762. status = 0;
  2763. // TODO: FD, TBI, any better place to initialze the following?
  2764. //hw_context->valid_audio_if = 0;
  2765. hw_context->valid_vsif = 0;
  2766. //hw_context->valid_avif = 0;
  2767. hw_context->valid_3d = 0;
  2768. #ifdef CONFIG_MTK_HDMI_3D_SUPPORT
  2769. hw_context->valid_3d_fs = 0;
  2770. #endif
  2771. //hw_context->current_audio_configure = 0;
  2772. //memset( hw_context->current_audio_info_frame, 0, AUDIO_IF_SIZE );
  2773. memset(&hw_context->current_vs_info_frame, 0, sizeof(hw_context->current_vs_info_frame));
  2774. //memset(&hw_context->current_avi_info_frame, 0, sizeof(hw_context->current_avi_info_frame));
  2775. }
  2776. else
  2777. {
  2778. MHL_TX_DBG_ERR(hw_context, "SiI8348 is not found!\n");
  2779. MHL_TX_DBG_ERR(hw_context, "Found %04X rev: %01X.%01X\n",
  2780. hw_context->chip_device_id,
  2781. hw_context->chip_rev_id >> 4,
  2782. (hw_context->chip_rev_id & 0x0f));
  2783. }
  2784. return status;
  2785. }
  2786. void si_mhl_tx_drv_shutdown(struct drv_hw_context *hw_context)
  2787. {
  2788. if( is_reset_on_exit_requested() )
  2789. {
  2790. board_reset(hw_context,TX_HW_RESET_PERIOD,TX_HW_RESET_DELAY);
  2791. //gpio_expander_reset();
  2792. MHL_TX_DBG_ERR(hw_context, "MHL hardware was reset\n");
  2793. }
  2794. }
  2795. //------------------------------------------------------------------------------
  2796. // Function Name: siHdmiTx_VideoSel()
  2797. // Function Description: Select output video mode
  2798. //
  2799. // Accepts: Video mode
  2800. // Returns: none
  2801. // Globals: none
  2802. //------------------------------------------------------------------------------
  2803. void siHdmiTx_VideoSel (int vmode)
  2804. {
  2805. int AspectRatio = 0;
  2806. video_data.inputColorSpace = acsRGB;
  2807. video_data.outputColorSpace = acsRGB;
  2808. video_data.inputVideoCode = vmode;
  2809. TX_DEBUG_PRINT(("video_data.inputVideoCode:0x%02x\n",(int)video_data.inputVideoCode));
  2810. //siHdmiTx.ColorDepth = VMD_COLOR_DEPTH_8BIT;
  2811. //siHdmiTx.SyncMode = EXTERNAL_HSVSDE;
  2812. switch (vmode)
  2813. {
  2814. case HDMI_480I60_4X3:
  2815. case HDMI_576I50_4X3:
  2816. AspectRatio = VMD_ASPECT_RATIO_4x3;
  2817. break;
  2818. case HDMI_480I60_16X9:
  2819. case HDMI_576I50_16X9:
  2820. AspectRatio = VMD_ASPECT_RATIO_16x9;
  2821. break;
  2822. case HDMI_480P60_4X3:
  2823. case HDMI_576P50_4X3:
  2824. case HDMI_640X480P:
  2825. AspectRatio = VMD_ASPECT_RATIO_4x3;
  2826. break;
  2827. case HDMI_480P60_16X9:
  2828. case HDMI_576P50_16X9:
  2829. AspectRatio = VMD_ASPECT_RATIO_16x9;
  2830. break;
  2831. case HDMI_720P60:
  2832. case HDMI_720P50:
  2833. case HDMI_1080I60:
  2834. case HDMI_1080I50:
  2835. case HDMI_1080P24:
  2836. case HDMI_1080P25:
  2837. case HDMI_1080P30:
  2838. case HDMI_1080P50:
  2839. case HDMI_1080P60:
  2840. AspectRatio = VMD_ASPECT_RATIO_16x9;
  2841. break;
  2842. default:
  2843. break;
  2844. }
  2845. if (AspectRatio == VMD_ASPECT_RATIO_4x3)
  2846. video_data.inputcolorimetryAspectRatio = 0x18;
  2847. else video_data.inputcolorimetryAspectRatio = 0x28;
  2848. video_data.input_AR = AspectRatio;
  2849. }
  2850. void siHdmiTx_AudioSel (int AduioMode)
  2851. {
  2852. Audio_mode_fs = AduioMode;
  2853. /*
  2854. siHdmiTx.AudioChannels = ACHANNEL_2CH;
  2855. siHdmiTx.AudioFs = Afs;
  2856. siHdmiTx.AudioWordLength = ALENGTH_24BITS;
  2857. siHdmiTx.AudioI2SFormat = (MCLK256FS << 4) |SCK_SAMPLE_RISING_EDGE |0x00; //last num 0x00-->0x02
  2858. */
  2859. }
  2860. #ifdef CONFIG_MTK_HDMI_3D_SUPPORT
  2861. #define SIZE_VSIF 8
  2862. static uint8_t calculate_vsif_checksum(uint8_t *vsif)
  2863. {
  2864. uint8_t checksum = 0;
  2865. return calculate_generic_checksum(vsif, checksum, SIZE_VSIF);
  2866. }
  2867. static int is_valid_vsif(struct mhl_dev_context *dev_context, vendor_specific_info_frame_t *vsif)
  2868. {
  2869. uint8_t checksum;
  2870. /*
  2871. Calculate the checksum assuming that the payload includes the checksum
  2872. */
  2873. checksum = calculate_generic_checksum((uint8_t *)vsif, 0,
  2874. sizeof(vsif->header) + vsif->header.length );
  2875. if (0 != checksum) {
  2876. MHL_TX_DBG_WARN(dev_context, "VSIF info frame checksum is: 0x%02x should be 0\n", checksum);
  2877. /*
  2878. Try again, assuming that the header includes the checksum.
  2879. */
  2880. checksum = calculate_generic_checksum((uint8_t *)vsif, 0,
  2881. sizeof(vsif->header) + vsif->header.length
  2882. + sizeof(vsif->payLoad.checksum));
  2883. if (0 != checksum){
  2884. MHL_TX_DBG_ERR(dev_context, "VSIF info frame checksum "
  2885. "(adjusted for checksum itself) is: 0x%02x "
  2886. "should be 0\n", checksum);
  2887. return 0;
  2888. }
  2889. }
  2890. if (0x81 != vsif->header.type_code) {
  2891. MHL_TX_DBG_ERR(dev_context, "Invalid VSIF type code: 0x%02x\n",
  2892. vsif->header.type_code);
  2893. return 0;
  2894. } else if (0x01 != vsif->header.version_number) {
  2895. MHL_TX_DBG_ERR(dev_context, "Invalid VSIF version: 0x%02x\n",
  2896. vsif->header.version_number);
  2897. return 0;
  2898. } else {
  2899. return 1;
  2900. }
  2901. }
  2902. /*
  2903. process_info_frame_change
  2904. called by the MHL Tx driver when a
  2905. new AVI info frame is received from upstream
  2906. OR
  2907. called by customer's SOC video driver when a mode change is desired.
  2908. */
  2909. void process_info_frame_change(struct drv_hw_context *hw_context
  2910. , vendor_specific_info_frame_t *vsif
  2911. , avi_info_frame_t *avif)
  2912. {
  2913. bool mode_change = false;
  2914. struct mhl_dev_context *dev_context;
  2915. dev_context = container_of((void *)hw_context, struct mhl_dev_context, drv_context);
  2916. if (NULL != vsif) {
  2917. if(is_valid_vsif(dev_context, vsif)) {
  2918. MHL_TX_DBG_INFO(hw_context, "refresh VISF!!!!!!!\n");
  2919. memcpy( (void *)&(hw_context->current_vs_info_frame), (void *)vsif, sizeof(vendor_specific_info_frame_t));
  2920. hw_context->valid_vsif = 1;
  2921. mode_change = true;
  2922. }
  2923. else
  2924. {
  2925. MHL_TX_DBG_INFO(hw_context, "It's NOT a valid VSIF!\n");
  2926. hw_context->valid_vsif = 0;
  2927. }
  2928. }
  2929. /*if (NULL != avif) {
  2930. if(is_valid_avi_info_frame(dev_context, avif)) {
  2931. memcpy( (void *)&(hw_context->current_avi_info_frame), (void *)avif, sizeof(avi_info_frame_t));
  2932. hw_context->valid_avif = 1;
  2933. mode_change = true;
  2934. }
  2935. else
  2936. {
  2937. MHL_TX_DBG_INFO(hw_context, "It's NOT a valid AVIF!\n");
  2938. hw_context->valid_avif = 0;
  2939. }
  2940. }
  2941. // No need to check Audio IF
  2942. // Save the changes only, no need to proceed if EDID is not yet parsed
  2943. if ( false == dev_context->edid_parse_done )
  2944. {
  2945. return;
  2946. }
  2947. if (mode_change) {
  2948. start_video(hw_context,dev_context->edid_parser_context);
  2949. }*/
  2950. }
  2951. static void fill_vsif(struct drv_hw_context *hw_context, uint8_t *p_vsif, int video_3d)
  2952. {
  2953. // uint8_t video_3d_structure = 0; // per HDMI
  2954. uint8_t mhl_3d_fmt_type = 0;
  2955. uint8_t mhl_vid_fmt = 0;
  2956. MHL_TX_DBG_INFO(hw_context, "Fill VSIF, video_3d:%02X ...\n", video_3d);
  2957. if ( VIDEO_3D_NONE == video_3d )
  2958. {
  2959. MHL_TX_DBG_INFO(hw_context, "Input Video 3D Update: NO 3D\n");
  2960. mhl_vid_fmt = 0x00;
  2961. hw_context->valid_3d = 0;
  2962. hw_context->valid_3d_fs = 0;
  2963. }
  2964. else if ( VIDEO_3D_FS == video_3d )
  2965. {
  2966. MHL_TX_DBG_INFO(hw_context, "Input Video 3D Update: 3D - Frame Sequential\n");
  2967. // video_3d_structure = 0x00; // per HDMI
  2968. mhl_vid_fmt = 0x01;
  2969. mhl_3d_fmt_type = 0x00;
  2970. hw_context->valid_3d = 1;
  2971. hw_context->valid_3d_fs = 1;
  2972. }
  2973. else if ( VIDEO_3D_TB == video_3d )
  2974. {
  2975. MHL_TX_DBG_INFO(hw_context, "Input Video 3D Update: 3D - Top Bottom\n");
  2976. // video_3d_structure = 0x06; // per HDMI
  2977. mhl_vid_fmt = 0x01;
  2978. mhl_3d_fmt_type = 0x01;
  2979. hw_context->valid_3d = 1;
  2980. hw_context->valid_3d_fs = 0;
  2981. }
  2982. else if ( VIDEO_3D_SS == video_3d )
  2983. {
  2984. MHL_TX_DBG_INFO(hw_context, "Input Video 3D Update: 3D - Side by side\n");
  2985. // video_3d_structure = 0x08; // per HDMI
  2986. mhl_vid_fmt = 0x01;
  2987. mhl_3d_fmt_type = 0x02;
  2988. hw_context->valid_3d = 1;
  2989. hw_context->valid_3d_fs = 0;
  2990. }
  2991. // Fill VSIF
  2992. p_vsif[0] = 0x81; // VSIF header
  2993. p_vsif[1] = 0x01; // Version
  2994. p_vsif[2] = 0x04; // Length
  2995. p_vsif[3] = 0x00; // Initial checksum
  2996. // Per MHL, begin
  2997. // Should use this for MHL
  2998. p_vsif[4] = 0x1D; // 0x7CA61D in Little Endian
  2999. p_vsif[5] = 0xA6;
  3000. p_vsif[6] = 0x7C;
  3001. p_vsif[7] = mhl_3d_fmt_type << 2 | mhl_vid_fmt;
  3002. // Per MHL, end
  3003. p_vsif[3] = calculate_vsif_checksum(p_vsif); // Checksum
  3004. // In case there is a need to use HDMI VSIF
  3005. // Per HDMI, begin
  3006. /*
  3007. p_vsif[2] = 0x07; // Length
  3008. // For compatibility with 'bad' MHL sinks, which accept HDMI IEEE OUI instead of MHL IEEE OUI
  3009. p_vsif[4] = 0x03; // 0x000C03 in Little Endian
  3010. p_vsif[5] = 0x0C;
  3011. p_vsif[6] = 0x00;
  3012. p_vsif[7] = 0x40; // 0x010-00000 -- 3D format indication present
  3013. p_vsif[8] = video_3d_structure << 4; // 3D structure & 3D_Meta_present=0
  3014. p_vsif[9] = 0x00;
  3015. p_vsif[10] = 0x00;
  3016. */
  3017. // Per HDMI, end
  3018. }
  3019. //void si_mhl_tx_drv_video_3d_update(struct drv_hw_context *hw_context, int video, int video_3d)
  3020. void si_mhl_tx_drv_video_3d(struct mhl_dev_context *dev_context, int video_3d)
  3021. {
  3022. vendor_specific_info_frame_t vsif;
  3023. MHL_TX_DBG_INFO((struct drv_hw_context *) (&dev_context->drv_context), "Input Timing Update: video 3D configuration changed %d\n", video_3d);
  3024. memset( &vsif, 0, sizeof(vendor_specific_info_frame_t) );
  3025. fill_vsif( (struct drv_hw_context *) (&dev_context->drv_context), (uint8_t *)(&vsif), video_3d ); // Fill VISF
  3026. // Process VSIF only
  3027. process_info_frame_change((struct drv_hw_context *) (&dev_context->drv_context),&vsif,NULL);
  3028. //fill_video_lcd( hw_context, video, video_3d );
  3029. //set_pin(hw_context, VID_CTRL_ACK, 1); // tell to allow further VID_CTRL_INT
  3030. }
  3031. #if 0
  3032. struct timer_list restart_timer;
  3033. struct drv_hw_context *temp_hw_context = NULL;
  3034. void __restart_timer_isr(unsigned long n)
  3035. {
  3036. unmute_video(temp_hw_context);
  3037. del_timer(&restart_timer);
  3038. }
  3039. #endif
  3040. extern enum HDMI_CABLE_TYPE MHL_Connect_type;
  3041. extern enum HDMI_STATE hdmi_drv_get_state(void);
  3042. void si_mhl_tx_drv_video_3d_update(struct mhl_dev_context *dev_context, int video_3d)
  3043. {
  3044. vendor_specific_info_frame_t vsif;
  3045. struct drv_hw_context *hw_context = (struct drv_hw_context *)&dev_context->drv_context;
  3046. MHL_TX_DBG_INFO((struct drv_hw_context *) (&dev_context->drv_context), "Input Timing Update to: video 3D configuration changed-%d, cable type: %d\n", video_3d, MHL_Connect_type);
  3047. if(MHL_Connect_type != MHL_3D_GLASSES)
  3048. stop_video(hw_context);
  3049. memset( &vsif, 0, sizeof(vendor_specific_info_frame_t) );
  3050. fill_vsif( (struct drv_hw_context *) (&dev_context->drv_context), (uint8_t *)(&vsif), video_3d ); // Fill VISF
  3051. // Process VSIF only
  3052. process_info_frame_change((struct drv_hw_context *) (&dev_context->drv_context),&vsif,NULL);
  3053. /*
  3054. * Send VSIF out
  3055. */
  3056. ///if ( 1 == hw_context->valid_vsif && 1 == hw_context->valid_3d )
  3057. {
  3058. MHL_TX_DBG_INFO((struct drv_hw_context *) (&dev_context->drv_context), "Send VSIF out...\n");
  3059. mhl_tx_write_reg((struct drv_hw_context *) (&dev_context->drv_context), REG_TPI_INFO_FSEL, BIT_TPI_INFO_EN | BIT_TPI_INFO_RPT | BIT_TPI_INFO_SEL_3D_VSIF); // Send 3D VSIF repeatly
  3060. ///DumpIncomingInfoFrame(&((struct drv_hw_context *) (&dev_context->drv_context)->current_vs_info_frame),sizeof((struct drv_hw_context *) (&dev_context->drv_context)->current_vs_info_frame));
  3061. ///mhl_tx_write_reg_block((struct drv_hw_context *) (&dev_context->drv_context), REG_TPI_INFO_BYTE00, 8, (u8 *)(&((struct drv_hw_context *) (&dev_context->drv_context)->current_vs_info_frame)) ); // only 8 bytes are valid for MHL VSIF
  3062. DumpIncomingInfoFrame(&(hw_context->current_vs_info_frame),sizeof(hw_context->current_vs_info_frame));
  3063. mhl_tx_write_reg_block((struct drv_hw_context *) (&dev_context->drv_context), REG_TPI_INFO_BYTE00, 8, (u8 *)(&(hw_context->current_vs_info_frame)) ); // only 8 bytes are valid for MHL VSIF
  3064. mhl_tx_write_reg((struct drv_hw_context *) (&dev_context->drv_context), REG_TPI_INFO_BYTE30, 0x00);// Trigger the infoframe sending
  3065. }
  3066. #if 0
  3067. restart_timer.expires = jiffies + msecs_to_jiffies(500);
  3068. restart_timer.function = __restart_timer_isr;
  3069. init_timer(&restart_timer);
  3070. add_timer(&restart_timer);
  3071. #else
  3072. if(MHL_Connect_type != MHL_3D_GLASSES)
  3073. {
  3074. msleep(120);
  3075. if(hdmi_drv_get_state()==HDMI_STATE_ACTIVE)
  3076. unmute_video(hw_context);
  3077. }
  3078. MHL_TX_DBG_INFO((struct drv_hw_context *) (&dev_context->drv_context), "Input Timing Update to: video 3D configuration changed done\n");
  3079. #endif
  3080. }
  3081. #endif