mt_chip.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #define pr_fmt(fmt) "["KBUILD_MODNAME"] " fmt
  2. #include <linux/io.h>
  3. #include <linux/module.h>
  4. #include <linux/device.h>
  5. #include <linux/fs.h>
  6. #include <linux/cdev.h>
  7. #include <linux/interrupt.h>
  8. #include <linux/spinlock.h>
  9. #include <linux/uaccess.h>
  10. #include <linux/platform_device.h>
  11. #include <linux/proc_fs.h>
  12. #include <linux/of.h>
  13. #include <linux/of_address.h>
  14. #include <linux/printk.h>
  15. #include <mt-plat/mt_io.h>
  16. #include "mt_chip_common.h"
  17. extern u32 __attribute__((weak)) get_devinfo_with_index(u32);
  18. void __iomem *APHW_CODE = NULL;
  19. void __iomem *APHW_SUBCODE = NULL;
  20. void __iomem *APHW_VER = NULL;
  21. void __iomem *APSW_VER = NULL;
  22. enum {
  23. CID_UNINIT = 0,
  24. CID_INITIALIZING = 1,
  25. CID_INITIALIZED = 2,
  26. } CID_INIT_STATE;
  27. static atomic_t g_cid_init = ATOMIC_INIT(CID_UNINIT);
  28. static void init_chip_id(unsigned int line)
  29. {
  30. if (CID_INITIALIZED == atomic_read(&g_cid_init))
  31. return;
  32. if (CID_INITIALIZING == atomic_read(&g_cid_init)) {
  33. pr_warn("%s (%d) state(%d)\n", __func__, line, atomic_read(&g_cid_init));
  34. return;
  35. }
  36. atomic_set(&g_cid_init, CID_INITIALIZING);
  37. #ifdef CONFIG_OF
  38. {
  39. struct device_node *node = of_find_compatible_node(NULL, NULL, "mediatek,chipid");
  40. if (node) {
  41. APHW_CODE = of_iomap(node, 0);
  42. WARN(!APHW_CODE, "unable to map APHW_CODE registers\n");
  43. APHW_SUBCODE = of_iomap(node, 1);
  44. WARN(!APHW_SUBCODE, "unable to map APHW_SUBCODE registers\n");
  45. APHW_VER = of_iomap(node, 2);
  46. WARN(!APHW_VER, "unable to map APHW_VER registers\n");
  47. APSW_VER = of_iomap(node, 3);
  48. WARN(!APSW_VER, "unable to map APSW_VER registers\n");
  49. atomic_set(&g_cid_init, CID_INITIALIZED);
  50. } else {
  51. atomic_set(&g_cid_init, CID_UNINIT);
  52. pr_warn("node not found\n");
  53. }
  54. }
  55. #endif
  56. }
  57. /* return hardware version */
  58. unsigned int __chip_hw_code(void)
  59. {
  60. init_chip_id(__LINE__);
  61. return (APHW_CODE) ? readl(IOMEM(APHW_CODE)) : (C_UNKNOWN_CHIP_ID);
  62. }
  63. unsigned int __chip_hw_ver(void)
  64. {
  65. init_chip_id(__LINE__);
  66. return (APHW_VER) ? readl(IOMEM(APHW_VER)) : (C_UNKNOWN_CHIP_ID);
  67. }
  68. unsigned int __chip_sw_ver(void)
  69. {
  70. init_chip_id(__LINE__);
  71. return (APSW_VER) ? readl(IOMEM(APSW_VER)) : (C_UNKNOWN_CHIP_ID);
  72. }
  73. EXPORT_SYMBOL(mt_get_chip_sw_ver);
  74. unsigned int __chip_hw_subcode(void)
  75. {
  76. init_chip_id(__LINE__);
  77. return (APHW_SUBCODE) ? readl(IOMEM(APHW_SUBCODE)) : (C_UNKNOWN_CHIP_ID);
  78. }
  79. unsigned int __chip_func_code(void)
  80. {
  81. unsigned int val = get_devinfo_with_index(47) & 0xFE000000; /* [31:25] */
  82. return (val >> 25);
  83. }
  84. unsigned int __chip_date_code(void)
  85. {
  86. return 0; /*not support*/
  87. }
  88. unsigned int __chip_proj_code(void)
  89. {
  90. return 0; /*not support*/
  91. }
  92. unsigned int __chip_fab_code(void)
  93. {
  94. return 0; /*not support*/
  95. }
  96. unsigned int mt_get_chip_id(void)
  97. {
  98. unsigned int chip_id = __chip_hw_code();
  99. /*convert id if necessary */
  100. return chip_id;
  101. }
  102. EXPORT_SYMBOL(mt_get_chip_id);
  103. unsigned int mt_get_chip_hw_code(void)
  104. {
  105. return __chip_hw_code();
  106. }
  107. EXPORT_SYMBOL(mt_get_chip_hw_code);
  108. unsigned int mt_get_chip_hw_ver(void)
  109. {
  110. return __chip_hw_ver();
  111. }
  112. unsigned int mt_get_chip_hw_subcode(void)
  113. {
  114. return __chip_hw_subcode();
  115. }
  116. unsigned int mt_get_chip_sw_ver(void)
  117. {
  118. return __chip_sw_ver();
  119. }
  120. static chip_info_cb g_cbs[CHIP_INFO_MAX] = {
  121. NULL,
  122. mt_get_chip_hw_code,
  123. mt_get_chip_hw_subcode,
  124. mt_get_chip_hw_ver,
  125. (chip_info_cb) mt_get_chip_sw_ver,
  126. __chip_hw_code,
  127. __chip_hw_subcode,
  128. __chip_hw_ver,
  129. __chip_sw_ver,
  130. __chip_func_code,
  131. NULL,
  132. NULL,
  133. NULL,
  134. NULL,
  135. };
  136. unsigned int mt_get_chip_info(unsigned int id)
  137. {
  138. if ((id <= CHIP_INFO_NONE) || (id >= CHIP_INFO_MAX))
  139. return 0;
  140. else if (NULL == g_cbs[id])
  141. return 0;
  142. return g_cbs[id] ();
  143. }
  144. EXPORT_SYMBOL(mt_get_chip_info);
  145. int __init chip_mod_init(void)
  146. {
  147. struct mt_chip_drv *p_drv = get_mt_chip_drv();
  148. pr_debug("CODE = %04x %04x %04x %04x, %04x %04x %04x %04x, %04X %04X\n",
  149. __chip_hw_code(), __chip_hw_subcode(), __chip_hw_ver(),
  150. __chip_sw_ver(), __chip_func_code(), __chip_proj_code(),
  151. __chip_date_code(), __chip_fab_code(), mt_get_chip_hw_ver(), mt_get_chip_sw_ver());
  152. p_drv->info_bit_mask |= CHIP_INFO_BIT(CHIP_INFO_HW_CODE) |
  153. CHIP_INFO_BIT(CHIP_INFO_HW_SUBCODE) |
  154. CHIP_INFO_BIT(CHIP_INFO_HW_VER) |
  155. CHIP_INFO_BIT(CHIP_INFO_SW_VER) | CHIP_INFO_BIT(CHIP_INFO_FUNCTION_CODE);
  156. p_drv->get_chip_info = mt_get_chip_info;
  157. pr_debug("CODE = %08X %p", p_drv->info_bit_mask, p_drv->get_chip_info);
  158. return 0;
  159. }
  160. core_initcall(chip_mod_init);
  161. MODULE_DESCRIPTION("MTK Chip Information");
  162. MODULE_LICENSE("GPL");