edid.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  1. #include <linux/vmalloc.h>
  2. #include <linux/module.h>
  3. #include <linux/cdev.h>
  4. #include <linux/fs.h>
  5. #include <linux/kernel.h>
  6. #include <linux/delay.h>
  7. #include <linux/interrupt.h>
  8. #include <linux/timer.h>
  9. #include <linux/semaphore.h>
  10. #include <asm/io.h>
  11. #include "edid.h"
  12. #include <drv_devices.h>
  13. #include <drv_spi.h>
  14. #include <Customization.h>
  15. #include <drv_spi_flashalloc_internal.h>
  16. #include <linux/slab.h>
  17. #define SiS365_patch 1
  18. #if 0
  19. #define DisableEdidOutsideUpdate 0
  20. #else
  21. #define DisableEdidOutsideUpdate 1 //2009.08.31 close all EDID update outside mechanism
  22. #endif
  23. EDID_DEV EdidDev,*pEdidDev=NULL;
  24. static INT32 fmode=0;
  25. static UINT8 HDMI_UpdateOK=0, VGA_UpdateOK=0;
  26. extern INT32 spi_write_flash(void *flashaddr, void *dramaddr, ULONG size);
  27. extern void GPIOWriteFun(UINT8 index, UINT8 value);
  28. extern void GPIOOpenDrainWriteFun(UINT8 index, UINT8 value);
  29. //extern INT32 tv_SetEDIDstate(UINT8 bDefault);
  30. void *mtmp=NULL;
  31. #if !DisableEdidOutsideUpdate//2009.08.31 close all EDID update outside mechanism
  32. static void HwI2CWriteEnable(void){
  33. if ((*(volatile UINT8 *)0xbe000002)>=0x38){ //if after 338
  34. (*(volatile UINT32 *)Slave_ModeSel)|=SlaveW_Protect;
  35. // if ((*(volatile UINT8 *)0xbe000005)==0x11){ // 338 A1 chip only
  36. (*(volatile UINT32 *)Slave0_CTRL)|=r_i2c_wr_ena;
  37. // }
  38. }
  39. }
  40. #endif
  41. static void HwI2CWriteDisable(void){
  42. if ((*(volatile UINT8 *)0xbe000002)>=0x38){ //if after 338
  43. (*(volatile UINT32 *)Slave_ModeSel)&=~(SlaveW_Protect);
  44. // if ((*(volatile UINT8 *)0xbe000005)==0x11){ // 338 A1 chip only
  45. (*(volatile UINT32 *)Slave0_CTRL)&=~(r_i2c_wr_ena);
  46. // }
  47. }
  48. }
  49. #if !DisableEdidOutsideUpdate
  50. static void ReadChipDatatoShadow(void){
  51. INT32 j=0;
  52. UINT32 tmp0, tmp1, tmp2;
  53. #if SiS365_patch
  54. for(j=0;j<0xa0;j++){
  55. MmioWriteFun(Slave_MMIO_Raddr,j+0x100); //2010.05.10, SiS365 hw bug1, it can be patched by set 0xbe060040[8] and clear it when read 0xbe060044
  56. MmioWriteFun(Slave_MMIO_Raddr,j);
  57. while(1){ //2010.05.10, Software reserve patch
  58. tmp0=MmioReadFun(Slave_MMIO_Rdata);
  59. tmp1=MmioReadFun(Slave_MMIO_Rdata);
  60. if(tmp0!=tmp1){
  61. printk(KERN_EMERG "%08x != %08x\n", tmp0, tmp1);
  62. }
  63. else{
  64. break;
  65. }
  66. }
  67. MmioWriteFun(HDMIA_SHADOWADDR+j*4,tmp0);
  68. }
  69. MmioWriteFun(Slave_MMIO_Raddr, 0x100); //2010.05.12, SiS365 hw bug2, set 0xbe060040[8] always to prevent hw EDID I2C stop reset index bug
  70. #else
  71. for(j=0;j<0xa0;j++){
  72. MmioWriteFun(Slave_MMIO_Raddr,j+0x100);
  73. MmioWriteFun(HDMIA_SHADOWADDR+j*4,MmioReadFun(Slave_MMIO_Rdata));
  74. }
  75. #endif
  76. }
  77. static void EdidOutsideUpdateInitFunction(void){
  78. /* Firstly, copy data from SRAM to Shadow, HDMIA, HDMIB, VGA */
  79. ReadChipDatatoShadow();
  80. /* Secondly, also copy data to mtmp, for compare usage */
  81. memcpy((void *)mtmp, (void *)HDMIA_SHADOWADDR, 640);
  82. }
  83. #endif
  84. void EDID_FMODE(INT32 Enable){
  85. if((Enable == 1)&&(fmode == 1)){ //fix UMF bug 2009.09.23
  86. printk(KERN_EMERG "UMF double call FMODE ERROR\n");
  87. return;
  88. }
  89. fmode=Enable;
  90. #if 0
  91. if(fmode){
  92. GPIOWriteFun(3, 0);
  93. }
  94. else{
  95. GPIOWriteFun(3, 1);
  96. }
  97. #endif
  98. #if 0
  99. if(fmode){
  100. GPIOOpenDrainWriteFun(16, 0);
  101. }
  102. else{
  103. GPIOOpenDrainWriteFun(16, 1);
  104. }
  105. #endif
  106. #if DisableEdidOutsideUpdate //2009.08.31 close all EDID update outside mechanism
  107. if(fmode){
  108. HDMI_UpdateOK=0;
  109. VGA_UpdateOK=0;
  110. }
  111. else{
  112. }
  113. DBG_MSG1(DBGCFG_EDID, "EDID_FMODE:%d\n",Enable);
  114. #else //old code
  115. if(fmode){
  116. //I2C Slaver Write Enable
  117. EdidOutsideUpdateInitFunction();
  118. HwI2CWriteEnable();
  119. HDMI_UpdateOK=0;
  120. VGA_UpdateOK=0;
  121. schedule_delayed_work(&pEdidDev->EdidWork,HZ);
  122. #if 0
  123. GPIOWriteFun(20, 0);
  124. #endif
  125. }
  126. else{
  127. //I2C Slaver Write Disable
  128. HwI2CWriteDisable();
  129. cancel_delayed_work(&pEdidDev->EdidWork);
  130. #if 0
  131. GPIOWriteFun(20, 1);
  132. #endif
  133. }
  134. DBG_MSG1(DBGCFG_EDID, "EDID_FMODE:%d\n",Enable);
  135. #endif
  136. }
  137. #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,8)
  138. long Slave1IoctlFun(struct file *pFile,UINT32 cmd, ULONG arg){
  139. #else
  140. static INT32 Slave1IoctlFun(struct inode *inode, struct file *pFile,UINT32 cmd, ULONG arg){
  141. #endif
  142. INT32 retval;
  143. //UINT8 Status;
  144. DBG_MSG1(DBGCFG_EDID, "Slave1IoctlFun");
  145. if (_IOC_TYPE(cmd) != SIS_IOC_MAGIC)
  146. {
  147. DBG_MSG1(DBGCFG_EDID, "Invalid command");
  148. return -ENOTTY;
  149. }
  150. retval = 0;
  151. //Status = 0;
  152. switch(cmd)
  153. {
  154. default:
  155. DBG_MSG1(DBGCFG_EDID, "Invalid Command");
  156. retval = -ENOTTY;
  157. break;
  158. }
  159. return retval;
  160. }
  161. static void ReInitHDMIEDID(void){
  162. INT32 i;
  163. UINT32 Data;
  164. spi_read_flash(mtmp,(void *)SPI_EDID_FLASHADDR,0x280); //read from flash
  165. for(i=0;i<0x20;i++)
  166. {
  167. Data = MmioReadFun(mtmp+i*4);
  168. MmioWriteByteFun(Slave_MMIO_Waddr,i);
  169. MmioWriteFun(Slave_MMIO_Wdata,Data);
  170. MmioWriteByteFun(Slave_MMIO_Push,MmioReadByteFun(Slave_MMIO_Push)|1);
  171. }
  172. for(i=0;i<0x40;i++)
  173. {
  174. Data = MmioReadFun(mtmp+0x100+i*4);
  175. MmioWriteByteFun(Slave_MMIO_Waddr,i+0x40);
  176. MmioWriteFun(Slave_MMIO_Wdata,Data);
  177. MmioWriteByteFun(Slave_MMIO_Push,MmioReadByteFun(Slave_MMIO_Push)|1);
  178. }
  179. }
  180. static void ReInitAllEDID(void){
  181. INT32 i;
  182. UINT32 Data;
  183. spi_read_flash(mtmp,(void *)SPI_EDID_FLASHADDR,0x280); //read from flash
  184. for(i=0;i<0x20;i++) //HDMI A upper part
  185. {
  186. Data = MmioReadFun(mtmp+i*4);
  187. MmioWriteByteFun(Slave_MMIO_Waddr,i);
  188. MmioWriteFun(Slave_MMIO_Wdata,Data);
  189. MmioWriteByteFun(Slave_MMIO_Push,MmioReadByteFun(Slave_MMIO_Push)|1);
  190. }
  191. for(i=0;i<0x20;i++) //HDMI B upper part
  192. {
  193. Data = MmioReadFun(mtmp+i*4);
  194. MmioWriteByteFun(Slave_MMIO_Waddr,i+0x40);
  195. MmioWriteFun(Slave_MMIO_Wdata,Data);
  196. MmioWriteByteFun(Slave_MMIO_Push,MmioReadByteFun(Slave_MMIO_Push)|1);
  197. }
  198. for(i=0;i<0x20;i++) //VGA part
  199. {
  200. Data = MmioReadFun(mtmp+i*4+0x200);
  201. MmioWriteByteFun(Slave_MMIO_Waddr,i+0x80);
  202. MmioWriteFun(Slave_MMIO_Wdata,Data);
  203. MmioWriteByteFun(Slave_MMIO_Push,MmioReadByteFun(Slave_MMIO_Push)|1);
  204. }
  205. }
  206. static UINT8 EdidHdmiAUpPartCheckSum(void){
  207. UINT8 CheckSum;
  208. UINT32 i,j;
  209. i=0x0; //HDMIA:up part
  210. for(j=0,CheckSum=0x0;j<127;j++){
  211. CheckSum-=RB(HDMIA_SHADOWADDR+i+j);
  212. //printk(KERN_EMERG "-%x=%x\t",RB(HDMIA_SHADOWADDR+i+j),CheckSum);
  213. }
  214. //printk(KERN_EMERG "HdmiAUpPartCheckSum:%x\n",CheckSum);
  215. return CheckSum;
  216. }
  217. static UINT8 EdidHdmiADownPartCheckSum(void){
  218. UINT8 CheckSum;
  219. UINT32 i,j;
  220. i=0x80; //HDMIA:down part
  221. for(j=0,CheckSum=0x0;j<127;j++){
  222. CheckSum-=RB(HDMIA_SHADOWADDR+i+j);
  223. //printk(KERN_EMERG "-%x=%x\t",RB(HDMIA_SHADOWADDR+i+j),CheckSum);
  224. }
  225. //printk(KERN_EMERG "EdidHdmiADownPartCheckSum:%x\n",CheckSum);
  226. return CheckSum;
  227. }
  228. static UINT8 EdidHdmiBUpPartCheckSum(void){
  229. UINT8 CheckSum;
  230. UINT32 i,j;
  231. i=0x100; //HDMIA:up part
  232. for(j=0,CheckSum=0x0;j<127;j++){
  233. CheckSum-=RB(HDMIA_SHADOWADDR+i+j);
  234. //printk(KERN_EMERG "-%x=%x\t",RB(HDMIA_SHADOWADDR+i+j),CheckSum);
  235. }
  236. //printk(KERN_EMERG "HdmiAUpPartCheckSum:%x\n",CheckSum);
  237. return CheckSum;
  238. }
  239. #if !DisableEdidOutsideUpdate
  240. static UINT8 EdidHdmiBDownPartCheckSum(void){
  241. UINT8 CheckSum;
  242. UINT32 i,j;
  243. i=0x180; //HDMIA:down part
  244. for(j=0,CheckSum=0x0;j<127;j++){
  245. CheckSum-=RB(HDMIA_SHADOWADDR+i+j);
  246. //printk(KERN_EMERG "-%x=%x\t",RB(HDMIA_SHADOWADDR+i+j),CheckSum);
  247. }
  248. //printk(KERN_EMERG "EdidHdmiADownPartCheckSum:%x\n",CheckSum);
  249. return CheckSum;
  250. }
  251. #endif
  252. static UINT8 EdidVGAPartCheckSum(void){
  253. UINT8 CheckSum;
  254. UINT32 i,j;
  255. i=0x200; //VGA: part
  256. for(j=0,CheckSum=0x0;j<127;j++){
  257. CheckSum-=RB(HDMIA_SHADOWADDR+i+j);
  258. //printk(KERN_EMERG "-%x=%x\t",RB(HDMIA_SHADOWADDR+i+j),CheckSum);
  259. }
  260. //printk(KERN_EMERG "EdidVGAPartCheckSum:%x\n",CheckSum);
  261. return CheckSum;
  262. }
  263. UINT8 ComputEDIDCheckSum(void){
  264. UINT8 CheckSum;
  265. //printk(KERN_EMERG "ComputEDIDCheckSum\n");
  266. ReInitHDMIEDID(); //reload shadow from flash
  267. //printk(KERN_EMERG "EdidHdmiAUpPartCheckSum\n");
  268. CheckSum=EdidHdmiAUpPartCheckSum();
  269. if(CheckSum!=RB(HDMIA_SHADOWADDR+127))
  270. return 1;
  271. //printk(KERN_EMERG "EdidHdmiADownPartCheckSum\n");
  272. CheckSum=EdidHdmiADownPartCheckSum();
  273. if(CheckSum!=RB(HDMIA_SHADOWADDR+0x80+127))
  274. return 2;
  275. //printk(KERN_EMERG "EdidVGAPartCheckSum\n");
  276. CheckSum=EdidVGAPartCheckSum();
  277. if(CheckSum!=RB(HDMIA_SHADOWADDR+0x200+127))
  278. return 3;
  279. //printk(KERN_EMERG "ComputEDIDCheckSum Done\n");
  280. return 0; //ok
  281. }
  282. EXPORT_SYMBOL(ComputEDIDCheckSum);
  283. INT32 EDID_WriteHDMI(UINT8 StartAddr, INT32 len, UINT8 *ptr){
  284. INT32 i;
  285. //write data into ShadowA
  286. for( i=0; i < len; i++){
  287. WB(HDMIA_SHADOWADDR+StartAddr+i, ptr[i]);
  288. }
  289. //check Header
  290. if((RB(HDMIA_SHADOWADDR)!=0x00)||(RB(HDMIA_SHADOWADDR+1)!=0xff)){
  291. printk(KERN_EMERG "EDID_WriteHDMI Header Error !\n");
  292. return -1;
  293. }
  294. //check checksum
  295. i = EdidHdmiAUpPartCheckSum(); //recompute HDMI A up part checksum
  296. WB(HDMIA_SHADOWADDR+0x7f, i);
  297. i = EdidHdmiADownPartCheckSum(); //recompute HDMI A down part checksum
  298. WB(HDMIA_SHADOWADDR+0xff, i);
  299. if(spi_write_flash((void*)SPI_EDID_FLASHADDR,(void*)(HDMIA_SHADOWADDR),0x100)==0){ //copy shadowA to flashA
  300. printk(KERN_EMERG "EDID_WriteHDMI Write flash fail !!\n");
  301. return -1;
  302. }
  303. ReInitAllEDID();
  304. //printk(KERN_EMERG "EDID_WriteHDMI OK!\n");
  305. return 0;
  306. }
  307. EXPORT_SYMBOL(EDID_WriteHDMI);
  308. INT32 EDID_WriteVGA(UINT8 StartAddr, INT32 len, UINT8 *ptr){
  309. INT32 i;
  310. //write data into Shadow VGA
  311. for( i=0; i < len; i++){
  312. WB(VGA_SHADOWADDR+StartAddr+i, ptr[i]);
  313. }
  314. //check Header
  315. if((RB(VGA_SHADOWADDR)!=0x00)||(RB(VGA_SHADOWADDR+1)!=0xff)){
  316. printk(KERN_EMERG "EDID_WriteVGA Header Error !\n");
  317. return -1;
  318. }
  319. //check checksum
  320. i= EdidVGAPartCheckSum(); //recompute VGA checksum
  321. WB(VGA_SHADOWADDR+0x7f, i);
  322. if(spi_write_flash((void*)SPI_EDID_FLASHADDR+0x200, (void*)(VGA_SHADOWADDR),0x80)==0){ //copy VGA to flash
  323. printk(KERN_EMERG "EDID_WriteVGA Write flash fail !!\n");
  324. return -1;
  325. }
  326. ReInitAllEDID();
  327. //printk(KERN_EMERG "EDID_WriteVGA OK!\n");
  328. return 0;
  329. }
  330. EXPORT_SYMBOL(EDID_WriteVGA);
  331. void EDID_ReadHDMI(UINT8 StartAddr, INT32 len, UINT8 *ptr){
  332. INT32 i;
  333. for( i=0; i < len; i++){
  334. ptr[i] = RB(SPI_EDID_FLASHADDR+StartAddr+i);
  335. }
  336. }
  337. EXPORT_SYMBOL(EDID_ReadHDMI);
  338. void EDID_ReadVGA(UINT8 StartAddr, INT32 len, UINT8 *ptr){
  339. INT32 i;
  340. for( i=0; i < len; i++){
  341. ptr[i] = RB(SPI_EDID_FLASHADDR+0x200+StartAddr+i);
  342. }
  343. }
  344. EXPORT_SYMBOL(EDID_ReadVGA);
  345. INT32 EDID_URupdate(UINT8 *SN){
  346. UINT8 tmp[2];
  347. UINT32 tmpi,i;
  348. #if !DisableEdidOutsideUpdate
  349. cancel_delayed_work(&pEdidDev->EdidWork); //stop EDID work first
  350. #endif
  351. /*
  352. 911QQ2UY99999
  353. _ 2009@11
  354. __ 11 @10
  355. ______ 5 @0c-0x0f
  356. 32 @0a-0b fix
  357. ______________
  358. 13 byte @from 5f to 6b
  359. */
  360. tmp[0]=(SN[0]-'0')+10; //base on 1990, so 2009 = 19
  361. WB(HDMIB_SHADOWADDR+0x11, tmp[0]); //write year
  362. WB(VGA_SHADOWADDR+0x11, tmp[0]);
  363. DBG_MSG1(DBGCFG_EDID, "Year:%d", tmp[0]);
  364. tmp[0]=(SN[1]-'0')*10+(SN[2]-'0');
  365. WB(HDMIB_SHADOWADDR+0x10, tmp[0]); //write week
  366. WB(VGA_SHADOWADDR+0x10, tmp[0]);
  367. DBG_MSG1(DBGCFG_EDID, "week:%d", tmp[0]);
  368. tmpi=(SN[8]-'0')*10000+(SN[9]-'0')*1000+(SN[10]-'0')*100+(SN[11]-'0')*10+(SN[12]-'0');
  369. tmp[0]=(tmpi&0x000000ff);
  370. WB(HDMIB_SHADOWADDR+0xc, tmp[0]); //write SN
  371. WB(VGA_SHADOWADDR+0xc, tmp[0]);
  372. tmp[0]=(tmpi&0x0000ff00)>>8;
  373. WB(HDMIB_SHADOWADDR+0xd, tmp[0]); //write SN
  374. WB(VGA_SHADOWADDR+0xd, tmp[0]);
  375. tmp[0]=(tmpi&0x00ff0000)>>16;
  376. WB(HDMIB_SHADOWADDR+0xe, tmp[0]); //write SN
  377. WB(VGA_SHADOWADDR+0xe, tmp[0]);
  378. tmp[0]=(tmpi&0xff000000)>>24;
  379. WB(HDMIB_SHADOWADDR+0xf, tmp[0]); //write SN
  380. WB(VGA_SHADOWADDR+0xf, tmp[0]);
  381. DBG_MSG1(DBGCFG_EDID, "SN:%d", tmpi);
  382. for(i=0x4d;i<=0x59;i++){ //write Monitor SN 13 byte
  383. WB(HDMIB_SHADOWADDR+i, SN[i-0x4d]);
  384. WB(VGA_SHADOWADDR+i, SN[i-0x4d]);
  385. }
  386. WB(HDMIB_SHADOWADDR+0x4b, 0xff); //write 0x4b fix value 0xff
  387. WB(VGA_SHADOWADDR+0x4b,0xff);
  388. WB(HDMIB_SHADOWADDR+0x4c, 0x0); //write 0x4c fix value 0x00
  389. WB(VGA_SHADOWADDR+0x4c,0x0);
  390. tmp[0]=EdidHdmiBUpPartCheckSum(); //recompute HDMI B up part checksum
  391. WB(HDMIB_SHADOWADDR+0x7f, tmp[0]);
  392. tmp[0]=EdidVGAPartCheckSum(); //recompute VGA part checksum
  393. WB(VGA_SHADOWADDR+0x7f, tmp[0]);
  394. if(spi_write_flash((void*)SPI_EDID_FLASHADDR,(void*)(HDMIB_SHADOWADDR),0x80)==0){ //copy shadowB to flashA
  395. DBG_MSG1(DBGCFG_EDID, "HDMI Edid write flash fail !");
  396. return 1;
  397. }
  398. else{ //wirte ok!
  399. DBG_MSG1(DBGCFG_EDID, "HDMI Edid UpdateOK !");
  400. HDMI_UpdateOK=1;
  401. }
  402. if(spi_write_flash((void*)(SPI_EDID_FLASHADDR+0x200),(void*)(VGA_SHADOWADDR),0x80)==0){ //copy shadowB to flashA
  403. DBG_MSG1(DBGCFG_EDID, "VGA Edid write flash fail !");
  404. return 1;
  405. }
  406. else{ //wirte ok!
  407. DBG_MSG1(DBGCFG_EDID, "VGA Edid UpdateOK !");
  408. VGA_UpdateOK=1;
  409. }
  410. if((VGA_UpdateOK==1)&&(HDMI_UpdateOK==1)){
  411. HwI2CWriteDisable();
  412. ReInitAllEDID();
  413. #if 0
  414. ReInitSwitch();
  415. printk(KERN_EMERG "ReInitSwitch\n");
  416. #endif
  417. DBG_MSG1(DBGCFG_EDID, "EDID update disable !");
  418. //printk(KERN_EMERG "EDID update disable\n");
  419. fmode=0;
  420. //tv_SetEDIDstate(1); //callback UMF
  421. #if 0
  422. notice_EdidUpdateOk();
  423. #endif
  424. }
  425. return 0;
  426. }
  427. EXPORT_SYMBOL(EDID_URupdate);
  428. #if !DisableEdidOutsideUpdate
  429. static void Edid2FlashFun(void *Context){
  430. //UINT8 *mFlash, *mTmp;
  431. UINT32 i,j;
  432. UINT16 IntReg;
  433. // UINT16 tmpvalue;
  434. // UINT8 SNTmp[13]; //Serial Number Temp
  435. UINT8 CheckSumTmp=0;
  436. IntReg = MmioReadWordFun(Slave_IntStatus);
  437. //if((IntReg&0xFFF)!=0){
  438. MmioWriteByteFun(IntClearReg,MmioReadByteFun(IntClearReg)|0x7);
  439. /* read Chip data to shadow */
  440. ReadChipDatatoShadow();
  441. #if 0//debug0507
  442. for(i=0;i<0x100;i+=4){
  443. if(i%16==0)
  444. printk("\n");
  445. printk("%08x ",MmioReadFun(HDMIB_SHADOWADDR+i));
  446. }
  447. for(i=0;i<0x100;i+=4){
  448. if(MmioReadFun(mtmp+i)!=MmioReadFun(HDMIB_SHADOWADDR+i)){
  449. printk("\nHDMI Diff %x\n ",i);
  450. }
  451. }
  452. for(i=0x0;i<0x80;i+=4){
  453. if(MmioReadFun(mtmp+0x200+i)!=MmioReadFun(VGA_SHADOWADDR+i)){
  454. printk("\nVGA Diff %x\n ",i);
  455. }
  456. }
  457. memcpy((mtmp),HDMIB_SHADOWADDR,0x100);
  458. memcpy((mtmp+0x200),VGA_SHADOWADDR,0x80);
  459. HDMI_UpdateOK=1;
  460. #endif
  461. //compare HDMI A
  462. for(i=0x0;i<0x100;i+=4){
  463. if(MmioReadFun(mtmp+i)!=MmioReadFun(HDMIA_SHADOWADDR+i)){
  464. printk(KERN_EMERG "HDMIA diff i %x mtmp:%x Sha:%x",i,MmioReadFun(mtmp+i),MmioReadFun(HDMIA_SHADOWADDR+i));
  465. mdelay(100); //delay until i2c write finish
  466. //read again
  467. ReadChipDatatoShadow();
  468. /* additional check checksum */
  469. CheckSumTmp=EdidHdmiAUpPartCheckSum();
  470. if(CheckSumTmp!=RB(HDMIA_SHADOWADDR+0x7f)){
  471. printk(KERN_EMERG "HDMIA UpPart Edid CheckSum Error!\n!");
  472. break;//goto _EdidUpDate_end;
  473. }
  474. CheckSumTmp=EdidHdmiADownPartCheckSum();
  475. if(CheckSumTmp!=RB(HDMIA_SHADOWADDR+0xff)){
  476. printk(KERN_EMERG "HDMIA DownPart Edid CheckSum Error!\n!");
  477. break;//goto _EdidUpDate_end;
  478. }
  479. if( (RB(HDMIA_SHADOWADDR)!=0x00)||(RB(HDMIA_SHADOWADDR+1)!=0xff)){
  480. printk(KERN_EMERG "HDMIA Edid Header Error!\n!");
  481. break;//goto _EdidUpDate_end;
  482. }
  483. /* additional check checksum */
  484. if(spi_write_flash((void*)(SPI_EDID_FLASHADDR),(void*)HDMIA_SHADOWADDR,0x100)!=0){
  485. EdidOutsideUpdateInitFunction();
  486. printk(KERN_EMERG "HDMIA_UpdateOK !\n");
  487. //HDMI_UpdateOK=1;
  488. }else{ //fail
  489. printk(KERN_EMERG "Edid write flash fail !\n");
  490. }
  491. //ReInitHDMIEDID();
  492. break; //end for loop
  493. }
  494. }
  495. //compare HDMI B
  496. for(i=0x0;i<0x100;i+=4){ //compare HDMI B upper part
  497. if(MmioReadFun(mtmp+0x100+i)!=MmioReadFun(HDMIB_SHADOWADDR+i)){
  498. printk(KERN_EMERG "HDMIB diff i %x mtmp:%x Sha:%x",i,MmioReadFun(mtmp+0x100+i),MmioReadFun(HDMIB_SHADOWADDR+i));
  499. mdelay(100); //delay until i2c write finish
  500. //read again
  501. ReadChipDatatoShadow();
  502. /* additional check checksum */
  503. CheckSumTmp=EdidHdmiBUpPartCheckSum();
  504. if(CheckSumTmp!=RB(HDMIB_SHADOWADDR+0x7f)){
  505. printk(KERN_EMERG "HDMIB UpPart Edid CheckSum Error!\n!");
  506. break;//goto _EdidUpDate_end;
  507. }
  508. CheckSumTmp=EdidHdmiBDownPartCheckSum();
  509. if(CheckSumTmp!=RB(HDMIB_SHADOWADDR+0xff)){
  510. printk(KERN_EMERG "HDMIB DownPart Edid CheckSum Error!\n!");
  511. break;//goto _EdidUpDate_end;
  512. }
  513. if( (RB(HDMIB_SHADOWADDR)!=0x00)||(RB(HDMIB_SHADOWADDR+1)!=0xff)){
  514. printk(KERN_EMERG "HDMIB Edid Header Error!\n!");
  515. break;//goto _EdidUpDate_end;
  516. }
  517. /* additional check checksum */
  518. if(spi_write_flash((void*)(SPI_EDID_FLASHADDR),(void*)HDMIB_SHADOWADDR,0x100)!=0){
  519. printk(KERN_EMERG "HDMIB_UpdateOK !\n");
  520. EdidOutsideUpdateInitFunction();
  521. //HDMI_UpdateOK=1;
  522. }else{ //fail
  523. printk(KERN_EMERG "Edid write flash fail !\n");
  524. }
  525. //ReInitHDMIEDID();
  526. break; //end for loop
  527. }
  528. }
  529. for(i=0x0;i<0x80;i+=4){ //parsing VGA
  530. if(MmioReadFun(mtmp+0x200+i)!=MmioReadFun(VGA_SHADOWADDR+i)){ //if diff
  531. printk(KERN_EMERG "VGA diff i %x mtmp:%x Sha:%x",i,MmioReadFun(mtmp+0x200+i),MmioReadFun(VGA_SHADOWADDR+i));
  532. mdelay(100); //delay until i2c write finish
  533. //read again
  534. ReadChipDatatoShadow();
  535. /* additional check checksum */
  536. CheckSumTmp=EdidVGAPartCheckSum();
  537. if(CheckSumTmp!=RB(VGA_SHADOWADDR+0x7f)){
  538. printk(KERN_EMERG "VGA Edid CheckSum Error!\n!");
  539. break;//goto _EdidUpDate_end;
  540. }
  541. if( (RB(VGA_SHADOWADDR)!=0x00)||(RB(VGA_SHADOWADDR+1)!=0xff)){
  542. printk(KERN_EMERG "VGA Edid Header Error!\n!");
  543. break;//goto _EdidUpDate_end;
  544. }
  545. /* additional check checksum */
  546. if(spi_write_flash((void*)(SPI_EDID_FLASHADDR+0x200),(void*)VGA_SHADOWADDR,0x80)!=0){
  547. EdidOutsideUpdateInitFunction();
  548. printk(KERN_EMERG "VGA_UpdateOK !\n");
  549. //VGA_UpdateOK=1;
  550. }else{ //fail
  551. printk(KERN_EMERG "Edid write flash fail !\n");
  552. }
  553. break; //end for loop
  554. }
  555. }
  556. _EdidUpDate_end:
  557. //printk(KERN_EMERG "%x EDID IntStatus!\n",*(volatile UINT16 *)Slave_IntStatus);
  558. DBG_MSG1(DBGCFG_EDID, "%x EDID IntStatus!\n",*(volatile UINT16 *)Slave_IntStatus);
  559. if(fmode){
  560. schedule_delayed_work(&pEdidDev->EdidWork,HZ);
  561. }
  562. }
  563. #endif
  564. static INT32 Slave1OpenFun(struct inode *inode, struct file *pFile)
  565. {
  566. DBG_MSG1(DBGCFG_EDID, "Slave1OpenFun");
  567. pFile->private_data = pEdidDev;
  568. return 0;
  569. }
  570. static INT32 Slave1CloseFun(struct inode *inode, struct file *pFile)
  571. {
  572. DBG_MSG1(DBGCFG_EDID, "Slave1CloseFun");
  573. return 0;
  574. }
  575. static struct file_operations Slave1Fops = {
  576. .owner = THIS_MODULE,
  577. #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,8)
  578. .unlocked_ioctl=Slave1IoctlFun,
  579. #else
  580. .ioctl = Slave1IoctlFun,
  581. #endif
  582. .open = Slave1OpenFun,
  583. .release = Slave1CloseFun,
  584. };
  585. INT32 __init Slave1Init(void)
  586. {
  587. INT32 result=0;
  588. dev_t devno;
  589. UINT32 Data;
  590. //CUSTIMIZATION_TABLEPTR pCustom = (volatile CUSTIMIZATION_TABLEPTR)SPI_OPTIONDATA_SHADOWADDR;
  591. //UINT8 EEpromEnable;
  592. DBG_MSG1(DBGCFG_EDID, "Edid Init");
  593. #if 0
  594. if(spi_CheckCustom())
  595. EEpromEnable = pCustom->EDIDEepromEnable;
  596. else
  597. EEpromEnable = 0;
  598. #endif
  599. // TODO: What is CPU1 ISR 60 do ?
  600. // Disable CPU1 ISR 60
  601. DBG_MSG1(DBGCFG_EDID, "Disable CPU1 ISR 60");
  602. Data = MmioReadFun(0xBE01010C);
  603. Data &= ~0x10000000;
  604. MmioWriteFun(0xBE01010C,Data);
  605. pEdidDev = &EdidDev;
  606. memset(pEdidDev,0,sizeof(EDID_DEV));
  607. /* move to bootrom */
  608. /* if((EEpromEnable&0x7)==0x7)
  609. {
  610. DebugPrint("EEPROM Enable, Slave Disable");
  611. MmioWriteFun(S0_CONTROL,0x00000000);
  612. MmioWriteFun(S1_CONTROL,0x00000000);
  613. MmioWriteFun(S2_CONTROL,0x00000000);
  614. return 0;
  615. }
  616. for(i=0;i<0x40;i++)
  617. {
  618. Data = MmioReadFun(HDMIA_SHADOWADDR+i*4);
  619. MmioWriteByteFun(0xBE070034,i);
  620. MmioWriteFun(0xBE070038,Data);
  621. MmioWriteByteFun(0xBE07002C,MmioReadByteFun(0xBE07002C)|1);
  622. }
  623. for(i=0;i<0x40;i++)
  624. {
  625. Data = MmioReadFun(HDMIB_SHADOWADDR+i*4);
  626. MmioWriteByteFun(0xBE070034,i+0x40);
  627. MmioWriteFun(0xBE070038,Data);
  628. MmioWriteByteFun(0xBE07002C,MmioReadByteFun(0xBE07002C)|1);
  629. }
  630. for(i=0;i<0x20;i++)
  631. {
  632. Data = MmioReadFun(VGA_SHADOWADDR+i*4);
  633. MmioWriteByteFun(0xBE070034,i+0x80);
  634. MmioWriteFun(0xBE070038,Data);
  635. MmioWriteByteFun(0xBE07002C,MmioReadByteFun(0xBE07002C)|1);
  636. }
  637. Data = 0x000800D0;
  638. if((EEpromEnable&0x1)==0)
  639. {
  640. MmioWriteFun(S0_CONTROL,Data);
  641. }
  642. else
  643. {
  644. MmioWriteFun(S0_CONTROL,0x00000000);
  645. DebugPrint("EEPROM Enable, Slave0 Disable");
  646. }
  647. if((EEpromEnable&0x2)==0)
  648. {
  649. MmioWriteFun(S1_CONTROL,Data);
  650. }
  651. else
  652. {
  653. MmioWriteFun(S1_CONTROL,0x00000000);
  654. DebugPrint("EEPROM Enable, Slave1 Disable");
  655. }
  656. if((EEpromEnable&0x4)==0)
  657. {
  658. MmioWriteFun(S2_CONTROL,Data);
  659. }
  660. else
  661. {
  662. MmioWriteFun(S2_CONTROL,0x00000000);
  663. DebugPrint("EEPROM Enable, Slave2 Disable");
  664. }
  665. */
  666. #if 1
  667. mtmp = (void *)kmalloc(0x280, GFP_KERNEL);
  668. #else
  669. mtmp = (void *)drv_kmalloc(0x280, GFP_KERNEL, MODULEID_EDID);
  670. #endif
  671. if(mtmp==NULL)
  672. return 0;
  673. #if !DisableEdidOutsideUpdate
  674. INIT_DELAYED_WORK(&pEdidDev->EdidWork, (void *)Edid2FlashFun);
  675. #endif
  676. devno = MKDEV(I2C_DEV_MAJOR, 2); // I2C_DEV_MAJOR=91
  677. cdev_init(&pEdidDev->cdev, &Slave1Fops);
  678. pEdidDev->cdev.owner = THIS_MODULE;
  679. #if 0 //B0
  680. //if ((*(volatile UINT8 *)0xbe000005)>=0x20){ // B0 chip
  681. set_vi_handler(SLAVE_IRQ_FINAL,slave_dispatch);
  682. result = request_irq(SLAVE_IRQ_FINAL,Slave1InterruptFun,SA_SHIRQ,"edid",pEdidDev);
  683. if(result)
  684. {
  685. DBG_MSG1(DBGCFG_EDID, "request_irq fault");
  686. }
  687. /* enable INT only in FMode to fix frequently INT problem*/
  688. (*(volatile UINT16*)(0xbe010104))&=~EDID_HostINTmask;
  689. //}
  690. #endif
  691. result = cdev_add(&pEdidDev->cdev, devno, 1);
  692. #if 0
  693. GPIOWriteFun(20, 1);
  694. #endif
  695. #if SiS365_patch
  696. MmioWriteFun(Slave_MMIO_Raddr, 0x100); //2010.05.12, SiS365 hw bug2, set 0xbe060040[8] always to prevent hw EDID I2C stop reset index bug
  697. #endif
  698. //EDID_FMODE(1);
  699. //ComputEDIDCheckSum();
  700. //ReInitSwitch();
  701. //ReInitHDMIA();
  702. return result;
  703. }
  704. void __exit Slave1Exit(void)
  705. {
  706. DBG_MSG1(DBGCFG_EDID, "EdidExit");
  707. fmode=0;
  708. #if !DisableEdidOutsideUpdate
  709. cancel_delayed_work(&pEdidDev->EdidWork);
  710. #endif
  711. if(mtmp!=NULL)
  712. #if 1
  713. kfree(mtmp);
  714. #else
  715. drv_kfree(mtmp, MODULEID_EDID);
  716. #endif
  717. }
  718. #ifndef INIT_BY_KMF
  719. module_init (Slave1Init);
  720. module_exit (Slave1Exit);
  721. #endif