mod_gate.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963
  1. #include <mach/power_gate.h>
  2. #include <mach/mod_gate.h>
  3. #include <linux/spinlock_types.h>
  4. #include <linux/spinlock.h>
  5. #include <linux/module.h>
  6. #include <mach/am_regs.h>
  7. #include <linux/device.h>
  8. #include <linux/err.h>
  9. #include <linux/hardirq.h>
  10. //#define PRINT_DEBUG_INFO
  11. #ifdef PRINT_DEBUG_INFO
  12. #define PRINT_INFO(...) printk(__VA_ARGS__)
  13. #else
  14. #define PRINT_INFO(...)
  15. #endif
  16. typedef struct{
  17. const char* name;
  18. const mod_type_t type;
  19. int ref;
  20. int flag;
  21. int dc_en;
  22. }mod_record_t;
  23. DEFINE_SPINLOCK(mod_lock);
  24. #define GATE_ON(_MOD) \
  25. do{ \
  26. if (0) printk(KERN_INFO "gate on %s %x, %x\n", GCLK_NAME_##_MOD, GCLK_REG_##_MOD, GCLK_MASK_##_MOD); \
  27. SET_CBUS_REG_MASK(GCLK_REG_##_MOD, GCLK_MASK_##_MOD); \
  28. }while(0)
  29. #define GATE_OFF(_MOD) \
  30. do{ \
  31. if (0) printk(KERN_INFO "gate off %s %x, %x\n", GCLK_NAME_##_MOD, GCLK_REG_##_MOD, GCLK_MASK_##_MOD); \
  32. CLEAR_CBUS_REG_MASK(GCLK_REG_##_MOD, GCLK_MASK_##_MOD); \
  33. }while(0)
  34. static mod_record_t mod_records[MOD_MAX_NUM + 1] = {
  35. {
  36. .name = "vdec",
  37. .type = MOD_VDEC,
  38. .ref = 0,
  39. .flag = 1,
  40. .dc_en = 0,
  41. },{
  42. .name = "audio",
  43. .type = MOD_AUDIO,
  44. .ref = 0,
  45. .flag = 1,
  46. .dc_en = 0,
  47. },{
  48. .name = "hdmi",
  49. .type = MOD_HDMI,
  50. .ref = 0,
  51. .flag = 1,
  52. .dc_en = 0,
  53. },{
  54. .name = "venc",
  55. .type = MOD_VENC,
  56. .ref = 0,
  57. .flag = 1,
  58. .dc_en = 0,
  59. },{
  60. .name = "tcon",
  61. .type = MOD_TCON,
  62. .ref = 0,
  63. .flag = 1,
  64. .dc_en = 0,
  65. },{
  66. .name = "lvds",
  67. .type = MOD_LVDS,
  68. .ref = 0,
  69. .flag = 1,
  70. .dc_en = 0,
  71. },{
  72. .name = "mipi",
  73. .type = MOD_MIPI,
  74. .ref = 0,
  75. .flag = 1,
  76. .dc_en = 0,
  77. },{
  78. .name = "bt656",
  79. .type = MOD_BT656,
  80. .ref = 0,
  81. .flag = 1,
  82. .dc_en = 0,
  83. },{
  84. .name = "spi",
  85. .type = MOD_SPI,
  86. .ref = 0,
  87. .flag = 1,
  88. .dc_en = 0,
  89. },{
  90. .name = "uart0",
  91. .type = MOD_UART0,
  92. .ref = 0,
  93. .flag = 1,
  94. .dc_en = 0,
  95. },{
  96. .name = "uart1",
  97. .type = MOD_UART1,
  98. .ref = 0,
  99. .flag = 1,
  100. .dc_en = 0,
  101. },{
  102. .name = "uart2",
  103. .type = MOD_UART2,
  104. .ref = 0,
  105. .flag = 1,
  106. .dc_en = 0,
  107. },{
  108. .name = "uart3",
  109. .type = MOD_UART3,
  110. .ref = 0,
  111. .flag = 1,
  112. .dc_en = 0,
  113. },{
  114. .name = "rom",
  115. .type = MOD_ROM,
  116. .ref = 0,
  117. .flag = 1,
  118. .dc_en = 0,
  119. },{
  120. .name = "efuse",
  121. .type = MOD_EFUSE,
  122. .ref = 0,
  123. .flag = 1,
  124. .dc_en = 0,
  125. },{
  126. .name = "random_num_gen",
  127. .type = MOD_RANDOM_NUM_GEN,
  128. .ref = 0,
  129. .flag = 1,
  130. .dc_en = 0,
  131. },{
  132. .name = "ethernet",
  133. .type = MOD_ETHERNET,
  134. .ref = 0,
  135. .flag = 1,
  136. .dc_en = 0,
  137. },{
  138. .name = "media_cpu",
  139. .type = MOD_MEDIA_CPU,
  140. .ref = 0,
  141. .flag = 1,
  142. .dc_en = 0,
  143. },{
  144. .name = "ge2d",
  145. .type = MOD_GE2D,
  146. .ref = 0,
  147. .flag = 1,
  148. .dc_en = 0,
  149. },{
  150. .name = "vdin",
  151. .type = MOD_VIDEO_IN,
  152. .ref = 0,
  153. .flag = 1,
  154. .dc_en = 0,
  155. },{
  156. .name = "viu2",
  157. .type = MOD_VIU2,
  158. .ref = 0,
  159. .flag = 1,
  160. .dc_en = 0,
  161. },{
  162. .name = "audio_in",
  163. .type = MOD_AUD_IN,
  164. .ref = 0,
  165. .flag = 1,
  166. .dc_en = 0,
  167. },{
  168. .name = "audio_out",
  169. .type = MOD_AUD_OUT,
  170. .ref = 0,
  171. .flag = 1,
  172. .dc_en = 0,
  173. },{
  174. .name = "ahb",
  175. .type = MOD_AHB,
  176. .ref = 0,
  177. .flag = 1,
  178. .dc_en = 0,
  179. },{
  180. .name = "demux",
  181. .type = MOD_DEMUX,
  182. .ref = 0,
  183. .flag = 1,
  184. .dc_en = 0,
  185. },{
  186. .name = "smart_card",
  187. .type = MOD_SMART_CARD,
  188. .ref = 0,
  189. .flag = 1,
  190. .dc_en = 0,
  191. },{
  192. .name = "sdhc",
  193. .type = MOD_SDHC,
  194. .ref = 0,
  195. .flag = 1,
  196. .dc_en = 0,
  197. },{
  198. .name = "stream",
  199. .type = MOD_STREAM,
  200. .ref = 0,
  201. .flag = 1,
  202. .dc_en = 0,
  203. },{
  204. .name = "blk_mov",
  205. .type = MOD_BLK_MOV,
  206. .ref = 0,
  207. .flag = 1,
  208. .dc_en = 0,
  209. },{
  210. .name = "dvin",
  211. .type = MOD_MISC_DVIN,
  212. .ref = 0,
  213. .flag = 1,
  214. .dc_en = 0,
  215. },{
  216. .name = "rdma",
  217. .type = MOD_MISC_RDMA,
  218. .ref = 0,
  219. .flag = 1,
  220. .dc_en = 0,
  221. },{
  222. .name = "usb0",
  223. .type = MOD_USB0,
  224. .ref = 0,
  225. .flag = 1,
  226. .dc_en = 0,
  227. },{
  228. .name = "usb1",
  229. .type = MOD_USB1,
  230. .ref = 0,
  231. .flag = 1,
  232. .dc_en = 0,
  233. },{
  234. .name = "sdio",
  235. .type = MOD_SDIO,
  236. .ref = 0,
  237. .flag = 1,
  238. .dc_en = 1,
  239. },{
  240. .name = "vi_core",
  241. .type = MOD_VI_CORE,
  242. .ref = 0,
  243. .flag = 1,
  244. .dc_en = 0,
  245. },{
  246. .name = "led_pwm",
  247. .type = MOD_LED_PWM,
  248. .ref = 0,
  249. .flag = 1,
  250. .dc_en = 1,
  251. },
  252. {
  253. .name = NULL,
  254. .type = -1,
  255. .ref = -1,
  256. .flag = -1,
  257. .dc_en = -1,
  258. }, //end of the record array
  259. };
  260. static int _switch_gate(mod_type_t type, int flag)
  261. {
  262. int ret = 0;
  263. switch(type) {
  264. case MOD_VDEC:
  265. PRINT_INFO("turn %s vdec module\n", flag?"on":"off");
  266. if (flag) {
  267. GATE_ON(DOS);
  268. } else {
  269. GATE_OFF(DOS);
  270. }
  271. break;
  272. case MOD_AUDIO:
  273. PRINT_INFO("turn %s audio module\n", flag?"on":"off");
  274. if (flag) {
  275. GATE_ON(AIU_AMCLK_MEASURE);
  276. GATE_ON(AIU_AIFIFO2);
  277. GATE_ON(AIU_AUD_MIXER);
  278. GATE_ON(AIU_MIXER_REG);
  279. GATE_ON(AIU_IEC958);
  280. GATE_ON(AIU_AI_TOP_GLUE);
  281. GATE_ON(AUD_BUF);
  282. GATE_ON(AIU_I2S_OUT);
  283. GATE_ON(AIU_AMCLK); //this gate should not be turned off
  284. GATE_ON(AIU_ICE958_AMCLK);
  285. GATE_ON(AIU_AOCLK);
  286. //GATE_ON(AUD_IN);
  287. GATE_ON(AIU_ADC);
  288. GATE_ON(AIU_AUDIN_SCLK);
  289. } else {
  290. GATE_OFF(AIU_AMCLK_MEASURE);
  291. GATE_OFF(AIU_AIFIFO2);
  292. GATE_OFF(AIU_AUD_MIXER);
  293. GATE_OFF(AIU_MIXER_REG);
  294. GATE_OFF(AIU_IEC958);
  295. GATE_OFF(AIU_AI_TOP_GLUE);
  296. GATE_OFF(AUD_BUF);
  297. GATE_OFF(AIU_I2S_OUT);
  298. GATE_OFF(AIU_AMCLK); //this gate should not be turned off
  299. GATE_OFF(AIU_ICE958_AMCLK);
  300. GATE_OFF(AIU_AOCLK);
  301. //GATE_OFF(AUD_IN);
  302. GATE_OFF(AIU_ADC);
  303. GATE_OFF(AIU_AUDIN_SCLK);
  304. }
  305. break;
  306. case MOD_HDMI:
  307. PRINT_INFO("turn %s hdmi module\n", flag?"on":"off");
  308. if (flag) {
  309. GATE_ON(HDMI_INTR_SYNC);
  310. GATE_ON(HDMI_PCLK);
  311. GATE_ON(VCLK1_HDMI);
  312. } else {
  313. GATE_OFF(HDMI_INTR_SYNC);
  314. GATE_OFF(HDMI_PCLK);
  315. GATE_OFF(VCLK1_HDMI);
  316. }
  317. break;
  318. case MOD_VENC:
  319. PRINT_INFO("turn %s venc module\n", flag?"on":"off");
  320. if (flag) {
  321. GATE_ON(VCLK2_VENCI);
  322. GATE_ON(VCLK2_VENCI1);
  323. GATE_ON(VCLK2_VENCP);
  324. GATE_ON(VCLK2_VENCP1);
  325. GATE_ON(VENC_P_TOP);
  326. GATE_ON(VENC_I_TOP);
  327. GATE_ON(VENCI_INT);
  328. GATE_ON(VENCP_INT);
  329. GATE_ON(VCLK2_ENCI);
  330. GATE_ON(VCLK2_ENCP);
  331. GATE_ON(VCLK2_VENCT);
  332. GATE_ON(VCLK2_VENCT1);
  333. GATE_ON(VCLK2_OTHER);
  334. GATE_ON(VCLK2_OTHER1);
  335. GATE_ON(ENC480P);
  336. GATE_ON(VENC_DAC);
  337. GATE_ON(DAC_CLK);
  338. } else {
  339. GATE_OFF(VCLK2_VENCI);
  340. GATE_OFF(VCLK2_VENCI1);
  341. GATE_OFF(VCLK2_VENCP);
  342. GATE_OFF(VCLK2_VENCP1);
  343. GATE_OFF(VENC_P_TOP);
  344. GATE_OFF(VENC_I_TOP);
  345. GATE_OFF(VENCI_INT);
  346. GATE_OFF(VENCP_INT);
  347. GATE_OFF(VCLK2_ENCI);
  348. GATE_OFF(VCLK2_ENCP);
  349. GATE_OFF(VCLK2_VENCT);
  350. GATE_OFF(VCLK2_VENCT1);
  351. GATE_OFF(VCLK2_OTHER);
  352. GATE_OFF(VCLK2_OTHER1);
  353. GATE_OFF(ENC480P);
  354. GATE_OFF(VENC_DAC);
  355. GATE_OFF(DAC_CLK);
  356. }
  357. break;
  358. case MOD_TCON:
  359. PRINT_INFO("turn %s tcon module\n", flag?"on":"off");
  360. if (flag) {
  361. GATE_ON(VENC_T_TOP);
  362. GATE_ON(VENCT_INT);
  363. GATE_ON(VCLK2_ENCT);
  364. } else {
  365. GATE_OFF(VENC_T_TOP);
  366. GATE_OFF(VENCT_INT);
  367. GATE_OFF(VCLK2_ENCT);
  368. }
  369. break;
  370. case MOD_LVDS:
  371. PRINT_INFO("turn %s lvds module\n", flag?"on":"off");
  372. if (flag) {
  373. GATE_ON(VENC_L_TOP);
  374. GATE_ON(VENCL_INT);
  375. GATE_ON(VCLK2_ENCL);
  376. } else {
  377. GATE_OFF(VENC_L_TOP);
  378. GATE_OFF(VENCL_INT);
  379. GATE_OFF(VCLK2_ENCL);
  380. }
  381. break;
  382. case MOD_MIPI:
  383. PRINT_INFO("turn %s mipi module\n", flag?"on":"off");
  384. if (flag) {
  385. GATE_ON(MIPI_APB_CLK);
  386. GATE_ON(MIPI_SYS_CLK);
  387. GATE_ON(MIPI_PHY);
  388. } else {
  389. GATE_OFF(MIPI_APB_CLK);
  390. GATE_OFF(MIPI_SYS_CLK);
  391. GATE_OFF(MIPI_PHY);
  392. }
  393. break;
  394. case MOD_BT656:
  395. PRINT_INFO("turn %s bt656 module\n", flag?"on":"off");
  396. if (flag) {
  397. GATE_ON(BT656_IN);
  398. } else {
  399. GATE_OFF(BT656_IN);
  400. }
  401. break;
  402. case MOD_SPI:
  403. PRINT_INFO("turn %s spi module\n", flag?"on":"off");
  404. if (flag) {
  405. GATE_ON(SPICC);
  406. GATE_ON(SPI1);
  407. GATE_ON(SPI2);
  408. } else {
  409. GATE_OFF(SPICC);
  410. GATE_OFF(SPI1);
  411. GATE_OFF(SPI2);
  412. }
  413. break;
  414. case MOD_UART0:
  415. PRINT_INFO("turn %s uart0 module\n", flag?"on":"off");
  416. if (flag) {
  417. GATE_ON(UART0);
  418. } else {
  419. GATE_OFF(UART0);
  420. }
  421. break;
  422. case MOD_UART1:
  423. PRINT_INFO("turn %s uart1 module\n", flag?"on":"off");
  424. if (flag) {
  425. GATE_ON(UART1);
  426. } else {
  427. GATE_OFF(UART1);
  428. }
  429. break;
  430. case MOD_UART2:
  431. PRINT_INFO("turn %s uart2 module\n", flag?"on":"off");
  432. if (flag) {
  433. GATE_ON(UART2);
  434. } else {
  435. GATE_OFF(UART2);
  436. }
  437. break;
  438. case MOD_UART3:
  439. PRINT_INFO("turn %s uart3 module\n", flag?"on":"off");
  440. if (flag) {
  441. GATE_ON(UART3);
  442. } else {
  443. GATE_OFF(UART3);
  444. }
  445. break;
  446. case MOD_ROM:
  447. PRINT_INFO("turn %s rom module\n", flag?"on":"off");
  448. if (flag) {
  449. GATE_ON(ROM_CLK);
  450. } else {
  451. GATE_OFF(ROM_CLK);
  452. }
  453. break;
  454. case MOD_EFUSE:
  455. PRINT_INFO("turn %s efuse module\n", flag?"on":"off");
  456. if (flag) {
  457. GATE_ON(EFUSE);
  458. } else {
  459. GATE_OFF(EFUSE);
  460. }
  461. break;
  462. case MOD_RANDOM_NUM_GEN:
  463. PRINT_INFO("turn %s random_num_gen module\n", flag?"on":"off");
  464. if (flag) {
  465. GATE_ON(RANDOM_NUM_GEN);
  466. } else {
  467. GATE_OFF(RANDOM_NUM_GEN);
  468. }
  469. break;
  470. case MOD_ETHERNET:
  471. PRINT_INFO("turn %s ethernet module\n", flag?"on":"off");
  472. if (flag) {
  473. GATE_ON(ETHERNET);
  474. } else {
  475. GATE_OFF(ETHERNET);
  476. }
  477. break;
  478. case MOD_MEDIA_CPU:
  479. PRINT_INFO("trun %s Audio DSP\n", flag? " on" : "off");
  480. if(flag){
  481. GATE_ON(MEDIA_CPU);
  482. }else{
  483. GATE_OFF(MEDIA_CPU);
  484. }
  485. break;
  486. case MOD_GE2D:
  487. PRINT_INFO("trun %s GE2D\n", flag? " on" : "off");
  488. if(flag){
  489. GATE_ON(GE2D);
  490. }else{
  491. GATE_OFF(GE2D);
  492. }
  493. break;
  494. case MOD_VIDEO_IN:
  495. PRINT_INFO("trun %s video_in\n", flag? " on" : "off");
  496. if(flag){
  497. GATE_ON(VIDEO_IN);
  498. }else{
  499. GATE_OFF(VIDEO_IN);
  500. }
  501. break;
  502. case MOD_VIU2:
  503. PRINT_INFO("trun %s viu2\n", flag? " on" : "off");
  504. if(flag){
  505. GATE_ON(VIU2);
  506. }else{
  507. GATE_OFF(VIU2);
  508. }
  509. break;
  510. case MOD_AUD_IN:
  511. PRINT_INFO("trun %s audio_in\n", flag? " on" : "off");
  512. #if 0
  513. if(flag){
  514. GATE_ON(AIU_ADC);
  515. GATE_ON(AIU_AUDIN_SCLK);
  516. }else{
  517. GATE_OFF(AIU_ADC);
  518. GATE_OFF(AIU_AUDIN_SCLK);
  519. }
  520. #endif
  521. break;
  522. case MOD_AUD_OUT:
  523. PRINT_INFO("trun %s audio_out\n", flag? " on" : "off");
  524. if(flag){
  525. }else{
  526. }
  527. break;
  528. case MOD_AHB:
  529. PRINT_INFO("trun %s ahb\n", flag? " on" : "off");
  530. if(flag){
  531. GATE_ON(AHB_ARB0);
  532. GATE_ON(AHB_BRIDGE);
  533. GATE_ON(AHB_DATA_BUS);
  534. GATE_ON(AHB_CONTROL_BUS);
  535. }else{
  536. GATE_OFF(AHB_ARB0);
  537. GATE_OFF(AHB_BRIDGE);
  538. GATE_OFF(AHB_DATA_BUS);
  539. GATE_OFF(AHB_CONTROL_BUS);
  540. }
  541. break;
  542. case MOD_DEMUX:
  543. PRINT_INFO("trun %s demux\n", flag? " on" : "off");
  544. if(flag){
  545. GATE_ON(DEMUX);
  546. }else{
  547. GATE_OFF(DEMUX);
  548. }
  549. break;
  550. case MOD_SMART_CARD:
  551. PRINT_INFO("trun %s smart card\n", flag? " on" : "off");
  552. if(flag){
  553. GATE_ON(SMART_CARD_MPEG_DOMAIN);
  554. }else{
  555. GATE_OFF(SMART_CARD_MPEG_DOMAIN);
  556. }
  557. break;
  558. case MOD_SDHC:
  559. PRINT_INFO("trun %s sdhc\n", flag? " on" : "off");
  560. if(flag){
  561. GATE_ON(SDHC);
  562. }else{
  563. GATE_OFF(SDHC);
  564. }
  565. break;
  566. case MOD_STREAM:
  567. PRINT_INFO("trun %s stream\n", flag? " on" : "off");
  568. if(flag){
  569. GATE_ON(STREAM);
  570. }else{
  571. GATE_OFF(STREAM);
  572. }
  573. break;
  574. case MOD_BLK_MOV:
  575. PRINT_INFO("trun %s blk_mov\n", flag? " on" : "off");
  576. if(flag){
  577. GATE_ON(BLK_MOV);
  578. }else{
  579. GATE_OFF(BLK_MOV);
  580. }
  581. break;
  582. case MOD_MISC_DVIN:
  583. PRINT_INFO("trun %s dvin\n", flag? " on" : "off");
  584. if(flag){
  585. GATE_ON(MISC_DVIN);
  586. }else{
  587. GATE_OFF(MISC_DVIN);
  588. }
  589. break;
  590. case MOD_MISC_RDMA:
  591. PRINT_INFO("trun %s rdma\n", flag? " on" : "off");
  592. if(flag){
  593. GATE_ON(MISC_RDMA);
  594. }else{
  595. GATE_OFF(MISC_RDMA);
  596. }
  597. break;
  598. case MOD_USB0:
  599. PRINT_INFO("trun %s rdma\n", flag? " on" : "off");
  600. if(flag){
  601. GATE_ON(USB0);
  602. GATE_ON(MISC_USB0_TO_DDR);
  603. }else{
  604. GATE_OFF(USB0);
  605. GATE_ON(MISC_USB0_TO_DDR);
  606. }
  607. break;
  608. case MOD_USB1:
  609. PRINT_INFO("trun %s rdma\n", flag? " on" : "off");
  610. if(flag){
  611. GATE_ON(USB1);
  612. GATE_ON(MISC_USB1_TO_DDR);
  613. }else{
  614. GATE_OFF(USB1);
  615. GATE_ON(MISC_USB1_TO_DDR);
  616. }
  617. break;
  618. case MOD_SDIO:
  619. PRINT_INFO("trun %s rdma\n", flag? " on" : "off");
  620. if(flag){
  621. GATE_ON(SDIO);
  622. }else{
  623. GATE_OFF(SDIO);
  624. }
  625. break;
  626. case MOD_VI_CORE:
  627. PRINT_INFO("trun %s vi core\n", flag? " on" : "off");
  628. if(flag){
  629. GATE_ON(VI_CORE);
  630. }else{
  631. GATE_OFF(VI_CORE);
  632. }
  633. break;
  634. case MOD_LED_PWM:
  635. PRINT_INFO("trun %s led pwm\n", flag? " on" : "off");
  636. if(flag){
  637. GATE_ON(LED_PWM);
  638. }else{
  639. GATE_OFF(LED_PWM);
  640. }
  641. break;
  642. default:
  643. PRINT_INFO("mod type not support\n");
  644. ret = -1;
  645. break;
  646. }
  647. return ret;
  648. }
  649. static int get_mod(mod_record_t* mod_record)
  650. {
  651. int ret = 0;
  652. unsigned long flags;
  653. PRINT_INFO("get mod %s\n", mod_record->name);
  654. spin_lock_irqsave(&mod_lock, flags);
  655. if(mod_record->ref > 0)
  656. mod_record->ref++;
  657. else {
  658. mod_record->ref = 1;
  659. mod_record->flag = 1;
  660. ret = _switch_gate(mod_record->type, 1);
  661. }
  662. spin_unlock_irqrestore(&mod_lock, flags);
  663. return ret;
  664. }
  665. static int put_mod(mod_record_t* mod_record)
  666. {
  667. int ret = 0;
  668. unsigned long flags;
  669. PRINT_INFO("put mod %s\n", mod_record->name);
  670. spin_lock_irqsave(&mod_lock, flags);
  671. mod_record->ref--;
  672. if(mod_record->ref <= 0) {
  673. ret = _switch_gate(mod_record->type, 0);
  674. mod_record->ref = 0;
  675. mod_record->flag = 0;
  676. }
  677. spin_unlock_irqrestore(&mod_lock, flags);
  678. return ret;
  679. }
  680. static void _switch_mod_gate_by_type(mod_type_t type, int flag, int dc_protect)
  681. {
  682. int i = 0;
  683. while(mod_records[i].name && i < MOD_MAX_NUM){
  684. if (type == mod_records[i].type) {
  685. if (mod_records[i].dc_en <= 0 && dc_protect)
  686. break;
  687. else {
  688. if (flag)
  689. get_mod(&mod_records[i]);
  690. else
  691. put_mod(&mod_records[i]);
  692. break;
  693. }
  694. }
  695. i++;
  696. }
  697. }
  698. void switch_mod_gate_by_type(mod_type_t type, int flag)
  699. {
  700. _switch_mod_gate_by_type(type, flag, 1);
  701. }
  702. EXPORT_SYMBOL(switch_mod_gate_by_type);
  703. static void _switch_mod_gate_by_name(const char* mod_name, int flag, int dc_protect)
  704. {
  705. int i = 0;
  706. //PRINT_INFO("arg mod_name is %s\n", mod_name);
  707. while(mod_records[i].name && i < MOD_MAX_NUM) {
  708. //PRINT_INFO("mod%d name is %s\n", i, mod_records[i].name);
  709. if (!strncmp(mod_name, mod_records[i].name, strlen(mod_name))) {
  710. if(mod_records[i].dc_en <= 0 && dc_protect)
  711. break;
  712. else {
  713. if (flag)
  714. get_mod(&mod_records[i]);
  715. else
  716. put_mod(&mod_records[i]);
  717. break;
  718. }
  719. }
  720. i++;
  721. }
  722. }
  723. void switch_mod_gate_by_name(const char* mod_name, int flag)
  724. {
  725. _switch_mod_gate_by_name(mod_name, flag, 1);
  726. }
  727. EXPORT_SYMBOL(switch_mod_gate_by_name);
  728. void power_gate_init(void)
  729. {
  730. GATE_INIT(DDR);
  731. GATE_INIT(DOS);
  732. GATE_INIT(MIPI_APB_CLK);
  733. GATE_INIT(MIPI_SYS_CLK);
  734. GATE_INIT(AHB_BRIDGE);
  735. GATE_INIT(ISA);
  736. GATE_INIT(APB_CBUS);
  737. GATE_INIT(_1200XXX);
  738. GATE_INIT(SPICC);
  739. GATE_INIT(I2C);
  740. GATE_INIT(SAR_ADC);
  741. GATE_INIT(SMART_CARD_MPEG_DOMAIN);
  742. GATE_INIT(RANDOM_NUM_GEN);
  743. GATE_INIT(UART0);
  744. GATE_INIT(SDHC);
  745. GATE_INIT(STREAM);
  746. GATE_INIT(ASYNC_FIFO);
  747. GATE_INIT(SDIO);
  748. GATE_INIT(AUD_BUF);
  749. GATE_INIT(HIU_PARSER);
  750. GATE_INIT(BT656_IN);
  751. GATE_INIT(ASSIST_MISC);
  752. GATE_INIT(VENC_I_TOP);
  753. GATE_INIT(VENC_P_TOP);
  754. GATE_INIT(VENC_T_TOP);
  755. GATE_INIT(VENC_DAC);
  756. GATE_INIT(VI_CORE);
  757. GATE_INIT(SPI2);
  758. GATE_INIT(SPI1);
  759. GATE_INIT(AUD_IN);
  760. GATE_INIT(ETHERNET);
  761. GATE_INIT(DEMUX);
  762. GATE_INIT(AIU_AI_TOP_GLUE);
  763. GATE_INIT(AIU_IEC958);
  764. GATE_INIT(AIU_I2S_OUT);
  765. GATE_INIT(AIU_AMCLK_MEASURE);
  766. GATE_INIT(AIU_AIFIFO2);
  767. GATE_INIT(AIU_AUD_MIXER);
  768. GATE_INIT(AIU_MIXER_REG);
  769. GATE_INIT(AIU_ADC);
  770. GATE_INIT(BLK_MOV);
  771. GATE_INIT(UART1);
  772. GATE_INIT(LED_PWM);
  773. GATE_INIT(VGHL_PWM);
  774. GATE_INIT(GE2D);
  775. GATE_INIT(USB0);
  776. GATE_INIT(USB1);
  777. GATE_INIT(RESET);
  778. GATE_INIT(NAND);
  779. GATE_INIT(HIU_PARSER_TOP);
  780. GATE_INIT(MIPI_PHY);
  781. GATE_INIT(VIDEO_IN);
  782. GATE_INIT(AHB_ARB0);
  783. GATE_INIT(EFUSE);
  784. GATE_INIT(ROM_CLK);
  785. GATE_INIT(AHB_DATA_BUS);
  786. GATE_INIT(AHB_CONTROL_BUS);
  787. GATE_INIT(HDMI_INTR_SYNC);
  788. GATE_INIT(HDMI_PCLK);
  789. GATE_INIT(MISC_USB1_TO_DDR);
  790. GATE_INIT(MISC_USB0_TO_DDR);
  791. GATE_INIT(MMC_PCLK);
  792. GATE_INIT(MISC_DVIN);
  793. GATE_INIT(MISC_RDMA);
  794. GATE_INIT(UART2);
  795. GATE_INIT(VENCI_INT);
  796. GATE_INIT(VIU2);
  797. GATE_INIT(VENCP_INT);
  798. GATE_INIT(VENCT_INT);
  799. GATE_INIT(VENCL_INT);
  800. GATE_INIT(VENC_L_TOP);
  801. GATE_INIT(UART3);
  802. GATE_INIT(VCLK2_VENCI);
  803. GATE_INIT(VCLK2_VENCI1);
  804. GATE_INIT(VCLK2_VENCP);
  805. GATE_INIT(VCLK2_VENCP1);
  806. GATE_INIT(VCLK2_VENCT);
  807. GATE_INIT(VCLK2_VENCT1);
  808. GATE_INIT(VCLK2_OTHER);
  809. GATE_INIT(VCLK2_ENCI);
  810. GATE_INIT(VCLK2_ENCP);
  811. GATE_INIT(DAC_CLK);
  812. GATE_INIT(AIU_AOCLK);
  813. GATE_INIT(AIU_AMCLK);
  814. GATE_INIT(AIU_ICE958_AMCLK);
  815. GATE_INIT(VCLK1_HDMI);
  816. GATE_INIT(AIU_AUDIN_SCLK);
  817. GATE_INIT(ENC480P);
  818. GATE_INIT(VCLK2_ENCT);
  819. GATE_INIT(VCLK2_ENCL);
  820. GATE_INIT(MMC_CLK);
  821. GATE_INIT(VCLK2_VENCL);
  822. GATE_INIT(VCLK2_OTHER1);
  823. GATE_INIT(MEDIA_CPU);
  824. }
  825. static struct class* mod_gate_clsp;
  826. static ssize_t show_mod_on(struct class* class, struct class_attribute* attr,
  827. char* buf)
  828. {
  829. ssize_t size = 0;
  830. int i = 0;
  831. while(mod_records[i].name && i < MOD_MAX_NUM) {
  832. if (mod_records[i].flag > 0)
  833. size += sprintf(buf + size, "%s\n", mod_records[i].name);
  834. i++;
  835. }
  836. return size;
  837. }
  838. static ssize_t store_mod_on(struct class* class, struct class_attribute* attr,
  839. const char* buf, size_t count )
  840. {
  841. char tmp_str[32];
  842. memset(tmp_str, 0, 32);
  843. strncpy(tmp_str, buf, 32);
  844. while(tmp_str[0] && tmp_str[strlen(tmp_str)-1] < 33 )
  845. tmp_str[strlen(tmp_str)-1] = 0;
  846. _switch_mod_gate_by_name(tmp_str, 1, 0);
  847. return count;
  848. }
  849. static ssize_t show_mod_off(struct class* class, struct class_attribute* attr,
  850. char* buf)
  851. {
  852. ssize_t size = 0;
  853. int i = 0;
  854. while(mod_records[i].name && i < MOD_MAX_NUM) {
  855. if (mod_records[i].flag <= 0)
  856. size += sprintf(buf + size, "%s\n", mod_records[i].name);
  857. i++;
  858. }
  859. return size;
  860. }
  861. static ssize_t store_mod_off(struct class* class, struct class_attribute* attr,
  862. const char* buf, size_t count )
  863. {
  864. char tmp_str[32];
  865. memset(tmp_str, 0, 32);
  866. strncpy(tmp_str, buf, 32);
  867. while(tmp_str[0] && tmp_str[strlen(tmp_str)-1] < 33 )
  868. tmp_str[strlen(tmp_str)-1] = 0;
  869. _switch_mod_gate_by_name(buf, 0, 0);
  870. return count;
  871. }
  872. static ssize_t show_dynamical_control(struct class* class, struct class_attribute* attr,
  873. char* buf)
  874. {
  875. ssize_t size = 0;
  876. int i = 0;
  877. while(mod_records[i].name && i < MOD_MAX_NUM) {
  878. if (mod_records[i].dc_en > 0)
  879. size += sprintf(buf + size, "%s\n", mod_records[i].name);
  880. i++;
  881. }
  882. return size;
  883. }
  884. static ssize_t store_dynamical_control(struct class* class, struct class_attribute* attr,
  885. const char* buf, size_t count )
  886. {
  887. int i = 0;
  888. char tmp_str[32];
  889. PRINT_INFO("arg mod_name is %s\n", buf);
  890. while(mod_records[i].name && i < MOD_MAX_NUM) {
  891. memset(tmp_str, 0, 32);
  892. strncpy(tmp_str, buf, 32);
  893. while(tmp_str[0] && tmp_str[strlen(tmp_str)-1] < 33 )
  894. tmp_str[strlen(tmp_str)-1] = 0;
  895. //PRINT_INFO("mod%d name is %s\n", i, mod_records[i].name);
  896. if (!strncmp(tmp_str, mod_records[i].name, strlen(tmp_str))) {
  897. mod_records[i].dc_en = 1;
  898. break;
  899. }
  900. i++;
  901. }
  902. return count;
  903. }
  904. static struct class_attribute aml_mod_attrs[]={
  905. __ATTR(mod_on, S_IRUGO | S_IWUSR, show_mod_on, store_mod_on),
  906. __ATTR(mod_off, S_IRUGO | S_IWUSR, show_mod_off, store_mod_off),
  907. __ATTR(dynamical_control, S_IRUGO | S_IWUSR, show_dynamical_control, store_dynamical_control),
  908. __ATTR_NULL,
  909. };
  910. static int __init mode_gate_mgr_init(void)
  911. {
  912. int ret = 0, i = 0;
  913. power_gate_init();
  914. mod_gate_clsp = class_create(THIS_MODULE, "aml_mod");
  915. if(IS_ERR(mod_gate_clsp)){
  916. ret = PTR_ERR(mod_gate_clsp);
  917. return ret;
  918. }
  919. for(i = 0; aml_mod_attrs[i].attr.name; i++){
  920. if(class_create_file(mod_gate_clsp, &aml_mod_attrs[i]) < 0)
  921. goto err;
  922. }
  923. return 0;
  924. err:
  925. for(i=0; aml_mod_attrs[i].attr.name; i++){
  926. class_remove_file(mod_gate_clsp, &aml_mod_attrs[i]);
  927. }
  928. class_destroy(mod_gate_clsp);
  929. return -1;
  930. }
  931. arch_initcall(mode_gate_mgr_init);