nouveau_i2c.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  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. i2c_drive_scl(void *data, int state)
  31. {
  32. struct nouveau_i2c_chan *port = data;
  33. if (port->type == 0) {
  34. u8 val = NVReadVgaCrtc(port->dev, 0, port->drive);
  35. if (state) val |= 0x20;
  36. else val &= 0xdf;
  37. NVWriteVgaCrtc(port->dev, 0, port->drive, val | 0x01);
  38. } else
  39. if (port->type == 4) {
  40. nv_mask(port->dev, port->drive, 0x2f, state ? 0x21 : 0x01);
  41. } else
  42. if (port->type == 5) {
  43. if (state) port->state |= 0x01;
  44. else port->state &= 0xfe;
  45. nv_wr32(port->dev, port->drive, 4 | port->state);
  46. }
  47. }
  48. static void
  49. i2c_drive_sda(void *data, int state)
  50. {
  51. struct nouveau_i2c_chan *port = data;
  52. if (port->type == 0) {
  53. u8 val = NVReadVgaCrtc(port->dev, 0, port->drive);
  54. if (state) val |= 0x10;
  55. else val &= 0xef;
  56. NVWriteVgaCrtc(port->dev, 0, port->drive, val | 0x01);
  57. } else
  58. if (port->type == 4) {
  59. nv_mask(port->dev, port->drive, 0x1f, state ? 0x11 : 0x01);
  60. } else
  61. if (port->type == 5) {
  62. if (state) port->state |= 0x02;
  63. else port->state &= 0xfd;
  64. nv_wr32(port->dev, port->drive, 4 | port->state);
  65. }
  66. }
  67. static int
  68. i2c_sense_scl(void *data)
  69. {
  70. struct nouveau_i2c_chan *port = data;
  71. struct drm_nouveau_private *dev_priv = port->dev->dev_private;
  72. if (port->type == 0) {
  73. return !!(NVReadVgaCrtc(port->dev, 0, port->sense) & 0x04);
  74. } else
  75. if (port->type == 4) {
  76. return !!(nv_rd32(port->dev, port->sense) & 0x00040000);
  77. } else
  78. if (port->type == 5) {
  79. if (dev_priv->card_type < NV_D0)
  80. return !!(nv_rd32(port->dev, port->sense) & 0x01);
  81. else
  82. return !!(nv_rd32(port->dev, port->sense) & 0x10);
  83. }
  84. return 0;
  85. }
  86. static int
  87. i2c_sense_sda(void *data)
  88. {
  89. struct nouveau_i2c_chan *port = data;
  90. struct drm_nouveau_private *dev_priv = port->dev->dev_private;
  91. if (port->type == 0) {
  92. return !!(NVReadVgaCrtc(port->dev, 0, port->sense) & 0x08);
  93. } else
  94. if (port->type == 4) {
  95. return !!(nv_rd32(port->dev, port->sense) & 0x00080000);
  96. } else
  97. if (port->type == 5) {
  98. if (dev_priv->card_type < NV_D0)
  99. return !!(nv_rd32(port->dev, port->sense) & 0x02);
  100. else
  101. return !!(nv_rd32(port->dev, port->sense) & 0x20);
  102. }
  103. return 0;
  104. }
  105. static const uint32_t nv50_i2c_port[] = {
  106. 0x00e138, 0x00e150, 0x00e168, 0x00e180,
  107. 0x00e254, 0x00e274, 0x00e764, 0x00e780,
  108. 0x00e79c, 0x00e7b8
  109. };
  110. static u8 *
  111. i2c_table(struct drm_device *dev, u8 *version)
  112. {
  113. u8 *dcb = dcb_table(dev), *i2c = NULL;
  114. if (dcb) {
  115. if (dcb[0] >= 0x15)
  116. i2c = ROMPTR(dev, dcb[2]);
  117. if (dcb[0] >= 0x30)
  118. i2c = ROMPTR(dev, dcb[4]);
  119. }
  120. /* early revisions had no version number, use dcb version */
  121. if (i2c) {
  122. *version = dcb[0];
  123. if (*version >= 0x30)
  124. *version = i2c[0];
  125. }
  126. return i2c;
  127. }
  128. int
  129. nouveau_i2c_init(struct drm_device *dev)
  130. {
  131. struct drm_nouveau_private *dev_priv = dev->dev_private;
  132. struct nvbios *bios = &dev_priv->vbios;
  133. struct nouveau_i2c_chan *port;
  134. u8 version = 0x00, entries, recordlen;
  135. u8 *i2c, *entry, legacy[2][4] = {};
  136. int ret, i;
  137. INIT_LIST_HEAD(&dev_priv->i2c_ports);
  138. i2c = i2c_table(dev, &version);
  139. if (!i2c) {
  140. u8 *bmp = &bios->data[bios->offset];
  141. if (bios->type != NVBIOS_BMP)
  142. return -ENODEV;
  143. legacy[0][0] = NV_CIO_CRE_DDC_WR__INDEX;
  144. legacy[0][1] = NV_CIO_CRE_DDC_STATUS__INDEX;
  145. legacy[1][0] = NV_CIO_CRE_DDC0_WR__INDEX;
  146. legacy[1][1] = NV_CIO_CRE_DDC0_STATUS__INDEX;
  147. /* BMP (from v4.0) has i2c info in the structure, it's in a
  148. * fixed location on earlier VBIOS
  149. */
  150. if (bmp[5] < 4)
  151. i2c = &bios->data[0x48];
  152. else
  153. i2c = &bmp[0x36];
  154. if (i2c[4]) legacy[0][0] = i2c[4];
  155. if (i2c[5]) legacy[0][1] = i2c[5];
  156. if (i2c[6]) legacy[1][0] = i2c[6];
  157. if (i2c[7]) legacy[1][1] = i2c[7];
  158. }
  159. if (version >= 0x30) {
  160. entry = i2c[1] + i2c;
  161. entries = i2c[2];
  162. recordlen = i2c[3];
  163. } else
  164. if (version) {
  165. entry = i2c;
  166. entries = 16;
  167. recordlen = 4;
  168. } else {
  169. entry = legacy[0];
  170. entries = 2;
  171. recordlen = 4;
  172. }
  173. for (i = 0; i < entries; i++, entry += recordlen) {
  174. port = kzalloc(sizeof(*port), GFP_KERNEL);
  175. if (port == NULL) {
  176. nouveau_i2c_fini(dev);
  177. return -ENOMEM;
  178. }
  179. port->type = entry[3];
  180. if (version < 0x30) {
  181. port->type &= 0x07;
  182. if (port->type == 0x07)
  183. port->type = 0xff;
  184. }
  185. if (port->type == 0xff) {
  186. kfree(port);
  187. continue;
  188. }
  189. switch (port->type) {
  190. case 0: /* NV04:NV50 */
  191. port->drive = entry[0];
  192. port->sense = entry[1];
  193. break;
  194. case 4: /* NV4E */
  195. port->drive = 0x600800 + entry[1];
  196. port->sense = port->drive;
  197. break;
  198. case 5: /* NV50- */
  199. port->drive = entry[0] & 0x0f;
  200. if (dev_priv->card_type < NV_D0) {
  201. if (port->drive >= ARRAY_SIZE(nv50_i2c_port))
  202. break;
  203. port->drive = nv50_i2c_port[port->drive];
  204. port->sense = port->drive;
  205. } else {
  206. port->drive = 0x00d014 + (port->drive * 0x20);
  207. port->sense = port->drive;
  208. }
  209. break;
  210. case 6: /* NV50- DP AUX */
  211. port->drive = entry[0];
  212. port->sense = port->drive;
  213. port->adapter.algo = &nouveau_dp_i2c_algo;
  214. break;
  215. default:
  216. break;
  217. }
  218. if (!port->adapter.algo && !port->drive) {
  219. NV_ERROR(dev, "I2C%d: type %d index %x/%x unknown\n",
  220. i, port->type, port->drive, port->sense);
  221. kfree(port);
  222. continue;
  223. }
  224. snprintf(port->adapter.name, sizeof(port->adapter.name),
  225. "nouveau-%s-%d", pci_name(dev->pdev), i);
  226. port->adapter.owner = THIS_MODULE;
  227. port->adapter.dev.parent = &dev->pdev->dev;
  228. port->dev = dev;
  229. port->index = i;
  230. port->dcb = ROM32(entry[0]);
  231. i2c_set_adapdata(&port->adapter, i2c);
  232. if (port->adapter.algo != &nouveau_dp_i2c_algo) {
  233. port->adapter.algo_data = &port->bit;
  234. port->bit.udelay = 10;
  235. port->bit.timeout = usecs_to_jiffies(2200);
  236. port->bit.data = port;
  237. port->bit.setsda = i2c_drive_sda;
  238. port->bit.setscl = i2c_drive_scl;
  239. port->bit.getsda = i2c_sense_sda;
  240. port->bit.getscl = i2c_sense_scl;
  241. i2c_drive_scl(port, 0);
  242. i2c_drive_sda(port, 1);
  243. i2c_drive_scl(port, 1);
  244. ret = i2c_bit_add_bus(&port->adapter);
  245. } else {
  246. port->adapter.algo = &nouveau_dp_i2c_algo;
  247. ret = i2c_add_adapter(&port->adapter);
  248. }
  249. if (ret) {
  250. NV_ERROR(dev, "I2C%d: failed register: %d\n", i, ret);
  251. kfree(port);
  252. continue;
  253. }
  254. list_add_tail(&port->head, &dev_priv->i2c_ports);
  255. }
  256. return 0;
  257. }
  258. void
  259. nouveau_i2c_fini(struct drm_device *dev)
  260. {
  261. struct drm_nouveau_private *dev_priv = dev->dev_private;
  262. struct nouveau_i2c_chan *port, *tmp;
  263. list_for_each_entry_safe(port, tmp, &dev_priv->i2c_ports, head) {
  264. i2c_del_adapter(&port->adapter);
  265. kfree(port);
  266. }
  267. }
  268. struct nouveau_i2c_chan *
  269. nouveau_i2c_find(struct drm_device *dev, u8 index)
  270. {
  271. struct drm_nouveau_private *dev_priv = dev->dev_private;
  272. struct nouveau_i2c_chan *port;
  273. if (index == NV_I2C_DEFAULT(0) ||
  274. index == NV_I2C_DEFAULT(1)) {
  275. u8 version, *i2c = i2c_table(dev, &version);
  276. if (i2c && version >= 0x30) {
  277. if (index == NV_I2C_DEFAULT(0))
  278. index = (i2c[4] & 0x0f);
  279. else
  280. index = (i2c[4] & 0xf0) >> 4;
  281. } else {
  282. index = 2;
  283. }
  284. }
  285. list_for_each_entry(port, &dev_priv->i2c_ports, head) {
  286. if (port->index == index)
  287. break;
  288. }
  289. if (&port->head == &dev_priv->i2c_ports)
  290. return NULL;
  291. if (dev_priv->card_type >= NV_50 && (port->dcb & 0x00000100)) {
  292. u32 reg = 0x00e500, val;
  293. if (port->type == 6) {
  294. reg += port->drive * 0x50;
  295. val = 0x2002;
  296. } else {
  297. reg += ((port->dcb & 0x1e00) >> 9) * 0x50;
  298. val = 0xe001;
  299. }
  300. /* nfi, but neither auxch or i2c work if it's 1 */
  301. nv_mask(dev, reg + 0x0c, 0x00000001, 0x00000000);
  302. /* nfi, but switches auxch vs normal i2c */
  303. nv_mask(dev, reg + 0x00, 0x0000f003, val);
  304. }
  305. return port;
  306. }
  307. bool
  308. nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr)
  309. {
  310. uint8_t buf[] = { 0 };
  311. struct i2c_msg msgs[] = {
  312. {
  313. .addr = addr,
  314. .flags = 0,
  315. .len = 1,
  316. .buf = buf,
  317. },
  318. {
  319. .addr = addr,
  320. .flags = I2C_M_RD,
  321. .len = 1,
  322. .buf = buf,
  323. }
  324. };
  325. return i2c_transfer(&i2c->adapter, msgs, 2) == 2;
  326. }
  327. int
  328. nouveau_i2c_identify(struct drm_device *dev, const char *what,
  329. struct i2c_board_info *info,
  330. bool (*match)(struct nouveau_i2c_chan *,
  331. struct i2c_board_info *),
  332. int index)
  333. {
  334. struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index);
  335. int i;
  336. if (!i2c) {
  337. NV_DEBUG(dev, "No bus when probing %s on %d\n", what, index);
  338. return -ENODEV;
  339. }
  340. NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, i2c->index);
  341. for (i = 0; info[i].addr; i++) {
  342. if (nouveau_probe_i2c_addr(i2c, info[i].addr) &&
  343. (!match || match(i2c, &info[i]))) {
  344. NV_INFO(dev, "Detected %s: %s\n", what, info[i].type);
  345. return i;
  346. }
  347. }
  348. NV_DEBUG(dev, "No devices found.\n");
  349. return -ENODEV;
  350. }