nv50_display.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. /*
  2. * Copyright (C) 2008 Maarten Maathuis.
  3. * All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining
  6. * a copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sublicense, and/or sell copies of the Software, and to
  10. * permit persons to whom the Software is furnished to do so, subject to
  11. * the following conditions:
  12. *
  13. * The above copyright notice and this permission notice (including the
  14. * next paragraph) shall be included in all copies or substantial
  15. * portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  20. * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
  21. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  23. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. *
  25. */
  26. #include "nouveau_drm.h"
  27. #include "nouveau_dma.h"
  28. #include "nv50_display.h"
  29. #include "nouveau_crtc.h"
  30. #include "nouveau_encoder.h"
  31. #include "nouveau_connector.h"
  32. #include "nouveau_fbcon.h"
  33. #include <drm/drm_crtc_helper.h>
  34. #include "nouveau_fence.h"
  35. #include <core/gpuobj.h>
  36. #include <core/class.h>
  37. #include <subdev/timer.h>
  38. static inline int
  39. nv50_sor_nr(struct drm_device *dev)
  40. {
  41. struct nouveau_device *device = nouveau_dev(dev);
  42. if (device->chipset < 0x90 ||
  43. device->chipset == 0x92 ||
  44. device->chipset == 0xa0)
  45. return 2;
  46. return 4;
  47. }
  48. u32
  49. nv50_display_active_crtcs(struct drm_device *dev)
  50. {
  51. struct nouveau_device *device = nouveau_dev(dev);
  52. u32 mask = 0;
  53. int i;
  54. if (device->chipset < 0x90 ||
  55. device->chipset == 0x92 ||
  56. device->chipset == 0xa0) {
  57. for (i = 0; i < 2; i++)
  58. mask |= nv_rd32(device, NV50_PDISPLAY_SOR_MODE_CTRL_C(i));
  59. } else {
  60. for (i = 0; i < 4; i++)
  61. mask |= nv_rd32(device, NV90_PDISPLAY_SOR_MODE_CTRL_C(i));
  62. }
  63. for (i = 0; i < 3; i++)
  64. mask |= nv_rd32(device, NV50_PDISPLAY_DAC_MODE_CTRL_C(i));
  65. return mask & 3;
  66. }
  67. int
  68. nv50_display_early_init(struct drm_device *dev)
  69. {
  70. return 0;
  71. }
  72. void
  73. nv50_display_late_takedown(struct drm_device *dev)
  74. {
  75. }
  76. int
  77. nv50_display_sync(struct drm_device *dev)
  78. {
  79. struct nv50_display *disp = nv50_display(dev);
  80. struct nouveau_channel *evo = disp->master;
  81. int ret;
  82. ret = RING_SPACE(evo, 6);
  83. if (ret == 0) {
  84. BEGIN_NV04(evo, 0, 0x0084, 1);
  85. OUT_RING (evo, 0x80000000);
  86. BEGIN_NV04(evo, 0, 0x0080, 1);
  87. OUT_RING (evo, 0);
  88. BEGIN_NV04(evo, 0, 0x0084, 1);
  89. OUT_RING (evo, 0x00000000);
  90. nv_wo32(disp->ramin, 0x2000, 0x00000000);
  91. FIRE_RING (evo);
  92. if (nv_wait_ne(disp->ramin, 0x2000, 0xffffffff, 0x00000000))
  93. return 0;
  94. }
  95. return 0;
  96. }
  97. int
  98. nv50_display_init(struct drm_device *dev)
  99. {
  100. struct nouveau_drm *drm = nouveau_drm(dev);
  101. struct nouveau_device *device = nouveau_dev(dev);
  102. struct nouveau_channel *evo;
  103. int ret, i;
  104. for (i = 0; i < 3; i++) {
  105. nv_wr32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(i), 0x00550000 |
  106. NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
  107. nv_wr32(device, NV50_PDISPLAY_DAC_CLK_CTRL1(i), 0x00000001);
  108. }
  109. for (i = 0; i < 2; i++) {
  110. nv_wr32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0x2000);
  111. if (!nv_wait(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
  112. NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) {
  113. NV_ERROR(drm, "timeout: CURSOR_CTRL2_STATUS == 0\n");
  114. NV_ERROR(drm, "CURSOR_CTRL2 = 0x%08x\n",
  115. nv_rd32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
  116. return -EBUSY;
  117. }
  118. nv_wr32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
  119. NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON);
  120. if (!nv_wait(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
  121. NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS,
  122. NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE)) {
  123. NV_ERROR(drm, "timeout: "
  124. "CURSOR_CTRL2_STATUS_ACTIVE(%d)\n", i);
  125. NV_ERROR(drm, "CURSOR_CTRL2(%d) = 0x%08x\n", i,
  126. nv_rd32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
  127. return -EBUSY;
  128. }
  129. }
  130. ret = nv50_evo_init(dev);
  131. if (ret)
  132. return ret;
  133. evo = nv50_display(dev)->master;
  134. ret = RING_SPACE(evo, 3);
  135. if (ret)
  136. return ret;
  137. BEGIN_NV04(evo, 0, NV50_EVO_UNK84, 2);
  138. OUT_RING (evo, NV50_EVO_UNK84_NOTIFY_DISABLED);
  139. OUT_RING (evo, NvEvoSync);
  140. return nv50_display_sync(dev);
  141. }
  142. void
  143. nv50_display_fini(struct drm_device *dev)
  144. {
  145. struct nouveau_drm *drm = nouveau_drm(dev);
  146. struct nouveau_device *device = nouveau_dev(dev);
  147. struct nv50_display *disp = nv50_display(dev);
  148. struct nouveau_channel *evo = disp->master;
  149. struct drm_crtc *drm_crtc;
  150. int ret, i;
  151. list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) {
  152. struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc);
  153. nv50_crtc_blank(crtc, true);
  154. }
  155. ret = RING_SPACE(evo, 2);
  156. if (ret == 0) {
  157. BEGIN_NV04(evo, 0, NV50_EVO_UPDATE, 1);
  158. OUT_RING(evo, 0);
  159. }
  160. FIRE_RING(evo);
  161. /* Almost like ack'ing a vblank interrupt, maybe in the spirit of
  162. * cleaning up?
  163. */
  164. list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) {
  165. struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc);
  166. uint32_t mask = NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(crtc->index);
  167. if (!crtc->base.enabled)
  168. continue;
  169. nv_wr32(device, NV50_PDISPLAY_INTR_1, mask);
  170. if (!nv_wait(device, NV50_PDISPLAY_INTR_1, mask, mask)) {
  171. NV_ERROR(drm, "timeout: (0x610024 & 0x%08x) == "
  172. "0x%08x\n", mask, mask);
  173. NV_ERROR(drm, "0x610024 = 0x%08x\n",
  174. nv_rd32(device, NV50_PDISPLAY_INTR_1));
  175. }
  176. }
  177. for (i = 0; i < 2; i++) {
  178. nv_wr32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0);
  179. if (!nv_wait(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
  180. NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) {
  181. NV_ERROR(drm, "timeout: CURSOR_CTRL2_STATUS == 0\n");
  182. NV_ERROR(drm, "CURSOR_CTRL2 = 0x%08x\n",
  183. nv_rd32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
  184. }
  185. }
  186. nv50_evo_fini(dev);
  187. for (i = 0; i < 3; i++) {
  188. if (!nv_wait(device, NV50_PDISPLAY_SOR_DPMS_STATE(i),
  189. NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) {
  190. NV_ERROR(drm, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", i);
  191. NV_ERROR(drm, "SOR_DPMS_STATE(%d) = 0x%08x\n", i,
  192. nv_rd32(device, NV50_PDISPLAY_SOR_DPMS_STATE(i)));
  193. }
  194. }
  195. }
  196. int
  197. nv50_display_create(struct drm_device *dev)
  198. {
  199. static const u16 oclass[] = {
  200. NVA3_DISP_CLASS,
  201. NV94_DISP_CLASS,
  202. NVA0_DISP_CLASS,
  203. NV84_DISP_CLASS,
  204. NV50_DISP_CLASS,
  205. };
  206. struct nouveau_drm *drm = nouveau_drm(dev);
  207. struct dcb_table *dcb = &drm->vbios.dcb;
  208. struct drm_connector *connector, *ct;
  209. struct nv50_display *priv;
  210. int ret, i;
  211. priv = kzalloc(sizeof(*priv), GFP_KERNEL);
  212. if (!priv)
  213. return -ENOMEM;
  214. nouveau_display(dev)->priv = priv;
  215. nouveau_display(dev)->dtor = nv50_display_destroy;
  216. nouveau_display(dev)->init = nv50_display_init;
  217. nouveau_display(dev)->fini = nv50_display_fini;
  218. /* attempt to allocate a supported evo display class */
  219. ret = -ENODEV;
  220. for (i = 0; ret && i < ARRAY_SIZE(oclass); i++) {
  221. ret = nouveau_object_new(nv_object(drm), NVDRM_DEVICE,
  222. 0xd1500000, oclass[i], NULL, 0,
  223. &priv->core);
  224. }
  225. if (ret)
  226. return ret;
  227. /* Create CRTC objects */
  228. for (i = 0; i < 2; i++) {
  229. ret = nv50_crtc_create(dev, i);
  230. if (ret)
  231. return ret;
  232. }
  233. /* We setup the encoders from the BIOS table */
  234. for (i = 0 ; i < dcb->entries; i++) {
  235. struct dcb_output *entry = &dcb->entry[i];
  236. if (entry->location != DCB_LOC_ON_CHIP) {
  237. NV_WARN(drm, "Off-chip encoder %d/%d unsupported\n",
  238. entry->type, ffs(entry->or) - 1);
  239. continue;
  240. }
  241. connector = nouveau_connector_create(dev, entry->connector);
  242. if (IS_ERR(connector))
  243. continue;
  244. switch (entry->type) {
  245. case DCB_OUTPUT_TMDS:
  246. case DCB_OUTPUT_LVDS:
  247. case DCB_OUTPUT_DP:
  248. nv50_sor_create(connector, entry);
  249. break;
  250. case DCB_OUTPUT_ANALOG:
  251. nv50_dac_create(connector, entry);
  252. break;
  253. default:
  254. NV_WARN(drm, "DCB encoder %d unknown\n", entry->type);
  255. continue;
  256. }
  257. }
  258. list_for_each_entry_safe(connector, ct,
  259. &dev->mode_config.connector_list, head) {
  260. if (!connector->encoder_ids[0]) {
  261. NV_WARN(drm, "%s has no encoders, removing\n",
  262. drm_get_connector_name(connector));
  263. connector->funcs->destroy(connector);
  264. }
  265. }
  266. ret = nv50_evo_create(dev);
  267. if (ret) {
  268. nv50_display_destroy(dev);
  269. return ret;
  270. }
  271. return 0;
  272. }
  273. void
  274. nv50_display_destroy(struct drm_device *dev)
  275. {
  276. struct nv50_display *disp = nv50_display(dev);
  277. nv50_evo_destroy(dev);
  278. kfree(disp);
  279. }
  280. struct nouveau_bo *
  281. nv50_display_crtc_sema(struct drm_device *dev, int crtc)
  282. {
  283. return nv50_display(dev)->crtc[crtc].sem.bo;
  284. }
  285. void
  286. nv50_display_flip_stop(struct drm_crtc *crtc)
  287. {
  288. struct nv50_display *disp = nv50_display(crtc->dev);
  289. struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
  290. struct nv50_display_crtc *dispc = &disp->crtc[nv_crtc->index];
  291. struct nouveau_channel *evo = dispc->sync;
  292. int ret;
  293. ret = RING_SPACE(evo, 8);
  294. if (ret) {
  295. WARN_ON(1);
  296. return;
  297. }
  298. BEGIN_NV04(evo, 0, 0x0084, 1);
  299. OUT_RING (evo, 0x00000000);
  300. BEGIN_NV04(evo, 0, 0x0094, 1);
  301. OUT_RING (evo, 0x00000000);
  302. BEGIN_NV04(evo, 0, 0x00c0, 1);
  303. OUT_RING (evo, 0x00000000);
  304. BEGIN_NV04(evo, 0, 0x0080, 1);
  305. OUT_RING (evo, 0x00000000);
  306. FIRE_RING (evo);
  307. }
  308. int
  309. nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
  310. struct nouveau_channel *chan)
  311. {
  312. struct nouveau_drm *drm = nouveau_drm(crtc->dev);
  313. struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb);
  314. struct nv50_display *disp = nv50_display(crtc->dev);
  315. struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
  316. struct nv50_display_crtc *dispc = &disp->crtc[nv_crtc->index];
  317. struct nouveau_channel *evo = dispc->sync;
  318. int ret;
  319. ret = RING_SPACE(evo, chan ? 25 : 27);
  320. if (unlikely(ret))
  321. return ret;
  322. /* synchronise with the rendering channel, if necessary */
  323. if (likely(chan)) {
  324. ret = RING_SPACE(chan, 10);
  325. if (ret) {
  326. WIND_RING(evo);
  327. return ret;
  328. }
  329. if (nv_device(drm->device)->chipset < 0xc0) {
  330. BEGIN_NV04(chan, 0, 0x0060, 2);
  331. OUT_RING (chan, NvEvoSema0 + nv_crtc->index);
  332. OUT_RING (chan, dispc->sem.offset);
  333. BEGIN_NV04(chan, 0, 0x006c, 1);
  334. OUT_RING (chan, 0xf00d0000 | dispc->sem.value);
  335. BEGIN_NV04(chan, 0, 0x0064, 2);
  336. OUT_RING (chan, dispc->sem.offset ^ 0x10);
  337. OUT_RING (chan, 0x74b1e000);
  338. BEGIN_NV04(chan, 0, 0x0060, 1);
  339. if (nv_device(drm->device)->chipset < 0x84)
  340. OUT_RING (chan, NvSema);
  341. else
  342. OUT_RING (chan, chan->vram);
  343. } else {
  344. u64 offset = nvc0_fence_crtc(chan, nv_crtc->index);
  345. offset += dispc->sem.offset;
  346. BEGIN_NVC0(chan, 0, 0x0010, 4);
  347. OUT_RING (chan, upper_32_bits(offset));
  348. OUT_RING (chan, lower_32_bits(offset));
  349. OUT_RING (chan, 0xf00d0000 | dispc->sem.value);
  350. OUT_RING (chan, 0x1002);
  351. BEGIN_NVC0(chan, 0, 0x0010, 4);
  352. OUT_RING (chan, upper_32_bits(offset));
  353. OUT_RING (chan, lower_32_bits(offset ^ 0x10));
  354. OUT_RING (chan, 0x74b1e000);
  355. OUT_RING (chan, 0x1001);
  356. }
  357. FIRE_RING (chan);
  358. } else {
  359. nouveau_bo_wr32(dispc->sem.bo, dispc->sem.offset / 4,
  360. 0xf00d0000 | dispc->sem.value);
  361. }
  362. /* queue the flip on the crtc's "display sync" channel */
  363. BEGIN_NV04(evo, 0, 0x0100, 1);
  364. OUT_RING (evo, 0xfffe0000);
  365. if (chan) {
  366. BEGIN_NV04(evo, 0, 0x0084, 1);
  367. OUT_RING (evo, 0x00000100);
  368. } else {
  369. BEGIN_NV04(evo, 0, 0x0084, 1);
  370. OUT_RING (evo, 0x00000010);
  371. /* allows gamma somehow, PDISP will bitch at you if
  372. * you don't wait for vblank before changing this..
  373. */
  374. BEGIN_NV04(evo, 0, 0x00e0, 1);
  375. OUT_RING (evo, 0x40000000);
  376. }
  377. BEGIN_NV04(evo, 0, 0x0088, 4);
  378. OUT_RING (evo, dispc->sem.offset);
  379. OUT_RING (evo, 0xf00d0000 | dispc->sem.value);
  380. OUT_RING (evo, 0x74b1e000);
  381. OUT_RING (evo, NvEvoSync);
  382. BEGIN_NV04(evo, 0, 0x00a0, 2);
  383. OUT_RING (evo, 0x00000000);
  384. OUT_RING (evo, 0x00000000);
  385. BEGIN_NV04(evo, 0, 0x00c0, 1);
  386. OUT_RING (evo, nv_fb->r_dma);
  387. BEGIN_NV04(evo, 0, 0x0110, 2);
  388. OUT_RING (evo, 0x00000000);
  389. OUT_RING (evo, 0x00000000);
  390. BEGIN_NV04(evo, 0, 0x0800, 5);
  391. OUT_RING (evo, nv_fb->nvbo->bo.offset >> 8);
  392. OUT_RING (evo, 0);
  393. OUT_RING (evo, (fb->height << 16) | fb->width);
  394. OUT_RING (evo, nv_fb->r_pitch);
  395. OUT_RING (evo, nv_fb->r_format);
  396. BEGIN_NV04(evo, 0, 0x0080, 1);
  397. OUT_RING (evo, 0x00000000);
  398. FIRE_RING (evo);
  399. dispc->sem.offset ^= 0x10;
  400. dispc->sem.value++;
  401. return 0;
  402. }