nouveau_i2c.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /*
  2. * Copyright 2009 Red Hat Inc.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. * Authors: Ben Skeggs
  23. */
  24. #include <linux/module.h>
  25. #include "drmP.h"
  26. #include "nouveau_drv.h"
  27. #include "nouveau_i2c.h"
  28. #include "nouveau_hw.h"
  29. static void
  30. nv04_i2c_setscl(void *data, int state)
  31. {
  32. struct nouveau_i2c_chan *i2c = data;
  33. struct drm_device *dev = i2c->dev;
  34. uint8_t val;
  35. val = (NVReadVgaCrtc(dev, 0, i2c->wr) & 0xd0) | (state ? 0x20 : 0);
  36. NVWriteVgaCrtc(dev, 0, i2c->wr, val | 0x01);
  37. }
  38. static void
  39. nv04_i2c_setsda(void *data, int state)
  40. {
  41. struct nouveau_i2c_chan *i2c = data;
  42. struct drm_device *dev = i2c->dev;
  43. uint8_t val;
  44. val = (NVReadVgaCrtc(dev, 0, i2c->wr) & 0xe0) | (state ? 0x10 : 0);
  45. NVWriteVgaCrtc(dev, 0, i2c->wr, val | 0x01);
  46. }
  47. static int
  48. nv04_i2c_getscl(void *data)
  49. {
  50. struct nouveau_i2c_chan *i2c = data;
  51. struct drm_device *dev = i2c->dev;
  52. return !!(NVReadVgaCrtc(dev, 0, i2c->rd) & 4);
  53. }
  54. static int
  55. nv04_i2c_getsda(void *data)
  56. {
  57. struct nouveau_i2c_chan *i2c = data;
  58. struct drm_device *dev = i2c->dev;
  59. return !!(NVReadVgaCrtc(dev, 0, i2c->rd) & 8);
  60. }
  61. static void
  62. nv4e_i2c_setscl(void *data, int state)
  63. {
  64. struct nouveau_i2c_chan *i2c = data;
  65. struct drm_device *dev = i2c->dev;
  66. uint8_t val;
  67. val = (nv_rd32(dev, i2c->wr) & 0xd0) | (state ? 0x20 : 0);
  68. nv_wr32(dev, i2c->wr, val | 0x01);
  69. }
  70. static void
  71. nv4e_i2c_setsda(void *data, int state)
  72. {
  73. struct nouveau_i2c_chan *i2c = data;
  74. struct drm_device *dev = i2c->dev;
  75. uint8_t val;
  76. val = (nv_rd32(dev, i2c->wr) & 0xe0) | (state ? 0x10 : 0);
  77. nv_wr32(dev, i2c->wr, val | 0x01);
  78. }
  79. static int
  80. nv4e_i2c_getscl(void *data)
  81. {
  82. struct nouveau_i2c_chan *i2c = data;
  83. struct drm_device *dev = i2c->dev;
  84. return !!((nv_rd32(dev, i2c->rd) >> 16) & 4);
  85. }
  86. static int
  87. nv4e_i2c_getsda(void *data)
  88. {
  89. struct nouveau_i2c_chan *i2c = data;
  90. struct drm_device *dev = i2c->dev;
  91. return !!((nv_rd32(dev, i2c->rd) >> 16) & 8);
  92. }
  93. static const uint32_t nv50_i2c_port[] = {
  94. 0x00e138, 0x00e150, 0x00e168, 0x00e180,
  95. 0x00e254, 0x00e274, 0x00e764, 0x00e780,
  96. 0x00e79c, 0x00e7b8
  97. };
  98. #define NV50_I2C_PORTS ARRAY_SIZE(nv50_i2c_port)
  99. static int
  100. nv50_i2c_getscl(void *data)
  101. {
  102. struct nouveau_i2c_chan *i2c = data;
  103. struct drm_device *dev = i2c->dev;
  104. return !!(nv_rd32(dev, i2c->rd) & 1);
  105. }
  106. static int
  107. nv50_i2c_getsda(void *data)
  108. {
  109. struct nouveau_i2c_chan *i2c = data;
  110. struct drm_device *dev = i2c->dev;
  111. return !!(nv_rd32(dev, i2c->rd) & 2);
  112. }
  113. static void
  114. nv50_i2c_setscl(void *data, int state)
  115. {
  116. struct nouveau_i2c_chan *i2c = data;
  117. nv_wr32(i2c->dev, i2c->wr, 4 | (i2c->data ? 2 : 0) | (state ? 1 : 0));
  118. }
  119. static void
  120. nv50_i2c_setsda(void *data, int state)
  121. {
  122. struct nouveau_i2c_chan *i2c = data;
  123. nv_mask(i2c->dev, i2c->wr, 0x00000006, 4 | (state ? 2 : 0));
  124. i2c->data = state;
  125. }
  126. static int
  127. nvd0_i2c_getscl(void *data)
  128. {
  129. struct nouveau_i2c_chan *i2c = data;
  130. return !!(nv_rd32(i2c->dev, i2c->rd) & 0x10);
  131. }
  132. static int
  133. nvd0_i2c_getsda(void *data)
  134. {
  135. struct nouveau_i2c_chan *i2c = data;
  136. return !!(nv_rd32(i2c->dev, i2c->rd) & 0x20);
  137. }
  138. int
  139. nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index)
  140. {
  141. struct drm_nouveau_private *dev_priv = dev->dev_private;
  142. struct nouveau_i2c_chan *i2c;
  143. int ret;
  144. if (entry->chan)
  145. return -EEXIST;
  146. if (dev_priv->card_type >= NV_50 &&
  147. dev_priv->card_type <= NV_C0 && entry->read >= NV50_I2C_PORTS) {
  148. NV_ERROR(dev, "unknown i2c port %d\n", entry->read);
  149. return -EINVAL;
  150. }
  151. i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
  152. if (i2c == NULL)
  153. return -ENOMEM;
  154. switch (entry->port_type) {
  155. case 0:
  156. i2c->bit.setsda = nv04_i2c_setsda;
  157. i2c->bit.setscl = nv04_i2c_setscl;
  158. i2c->bit.getsda = nv04_i2c_getsda;
  159. i2c->bit.getscl = nv04_i2c_getscl;
  160. i2c->rd = entry->read;
  161. i2c->wr = entry->write;
  162. break;
  163. case 4:
  164. i2c->bit.setsda = nv4e_i2c_setsda;
  165. i2c->bit.setscl = nv4e_i2c_setscl;
  166. i2c->bit.getsda = nv4e_i2c_getsda;
  167. i2c->bit.getscl = nv4e_i2c_getscl;
  168. i2c->rd = 0x600800 + entry->read;
  169. i2c->wr = 0x600800 + entry->write;
  170. break;
  171. case 5:
  172. i2c->bit.setsda = nv50_i2c_setsda;
  173. i2c->bit.setscl = nv50_i2c_setscl;
  174. if (dev_priv->card_type < NV_D0) {
  175. i2c->bit.getsda = nv50_i2c_getsda;
  176. i2c->bit.getscl = nv50_i2c_getscl;
  177. i2c->rd = nv50_i2c_port[entry->read];
  178. i2c->wr = i2c->rd;
  179. } else {
  180. i2c->bit.getsda = nvd0_i2c_getsda;
  181. i2c->bit.getscl = nvd0_i2c_getscl;
  182. i2c->rd = 0x00d014 + (entry->read * 0x20);
  183. i2c->wr = i2c->rd;
  184. }
  185. break;
  186. case 6:
  187. i2c->rd = entry->read;
  188. i2c->wr = entry->write;
  189. break;
  190. default:
  191. NV_ERROR(dev, "DCB I2C port type %d unknown\n",
  192. entry->port_type);
  193. kfree(i2c);
  194. return -EINVAL;
  195. }
  196. snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
  197. "nouveau-%s-%d", pci_name(dev->pdev), index);
  198. i2c->adapter.owner = THIS_MODULE;
  199. i2c->adapter.dev.parent = &dev->pdev->dev;
  200. i2c->dev = dev;
  201. i2c_set_adapdata(&i2c->adapter, i2c);
  202. if (entry->port_type < 6) {
  203. i2c->adapter.algo_data = &i2c->bit;
  204. i2c->bit.udelay = 40;
  205. i2c->bit.timeout = usecs_to_jiffies(5000);
  206. i2c->bit.data = i2c;
  207. ret = i2c_bit_add_bus(&i2c->adapter);
  208. } else {
  209. i2c->adapter.algo = &nouveau_dp_i2c_algo;
  210. ret = i2c_add_adapter(&i2c->adapter);
  211. }
  212. if (ret) {
  213. NV_ERROR(dev, "Failed to register i2c %d\n", index);
  214. kfree(i2c);
  215. return ret;
  216. }
  217. entry->chan = i2c;
  218. return 0;
  219. }
  220. void
  221. nouveau_i2c_fini(struct drm_device *dev, struct dcb_i2c_entry *entry)
  222. {
  223. if (!entry->chan)
  224. return;
  225. i2c_del_adapter(&entry->chan->adapter);
  226. kfree(entry->chan);
  227. entry->chan = NULL;
  228. }
  229. struct nouveau_i2c_chan *
  230. nouveau_i2c_find(struct drm_device *dev, int index)
  231. {
  232. struct drm_nouveau_private *dev_priv = dev->dev_private;
  233. struct dcb_i2c_entry *i2c = &dev_priv->vbios.dcb.i2c[index];
  234. if (index >= DCB_MAX_NUM_I2C_ENTRIES)
  235. return NULL;
  236. if (dev_priv->card_type >= NV_50 && (i2c->entry & 0x00000100)) {
  237. uint32_t reg = 0xe500, val;
  238. if (i2c->port_type == 6) {
  239. reg += i2c->read * 0x50;
  240. val = 0x2002;
  241. } else {
  242. reg += ((i2c->entry & 0x1e00) >> 9) * 0x50;
  243. val = 0xe001;
  244. }
  245. /* nfi, but neither auxch or i2c work if it's 1 */
  246. nv_mask(dev, reg + 0x0c, 0x00000001, 0x00000000);
  247. /* nfi, but switches auxch vs normal i2c */
  248. nv_mask(dev, reg + 0x00, 0x0000f003, val);
  249. }
  250. if (!i2c->chan && nouveau_i2c_init(dev, i2c, index))
  251. return NULL;
  252. return i2c->chan;
  253. }
  254. bool
  255. nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr)
  256. {
  257. uint8_t buf[] = { 0 };
  258. struct i2c_msg msgs[] = {
  259. {
  260. .addr = addr,
  261. .flags = 0,
  262. .len = 1,
  263. .buf = buf,
  264. },
  265. {
  266. .addr = addr,
  267. .flags = I2C_M_RD,
  268. .len = 1,
  269. .buf = buf,
  270. }
  271. };
  272. return i2c_transfer(&i2c->adapter, msgs, 2) == 2;
  273. }
  274. int
  275. nouveau_i2c_identify(struct drm_device *dev, const char *what,
  276. struct i2c_board_info *info,
  277. bool (*match)(struct nouveau_i2c_chan *,
  278. struct i2c_board_info *),
  279. int index)
  280. {
  281. struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index);
  282. int i;
  283. NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index);
  284. for (i = 0; info[i].addr; i++) {
  285. if (nouveau_probe_i2c_addr(i2c, info[i].addr) &&
  286. (!match || match(i2c, &info[i]))) {
  287. NV_INFO(dev, "Detected %s: %s\n", what, info[i].type);
  288. return i;
  289. }
  290. }
  291. NV_DEBUG(dev, "No devices found.\n");
  292. return -ENODEV;
  293. }