i915_irq.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916
  1. /* i915_irq.c -- IRQ support for the I915 -*- linux-c -*-
  2. */
  3. /*
  4. * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  5. * All Rights Reserved.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the
  9. * "Software"), to deal in the Software without restriction, including
  10. * without limitation the rights to use, copy, modify, merge, publish,
  11. * distribute, sub license, and/or sell copies of the Software, and to
  12. * permit persons to whom the Software is furnished to do so, subject to
  13. * the following conditions:
  14. *
  15. * The above copyright notice and this permission notice (including the
  16. * next paragraph) shall be included in all copies or substantial portions
  17. * of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  21. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  22. * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  23. * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  24. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  25. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  26. *
  27. */
  28. #include "drmP.h"
  29. #include "drm.h"
  30. #include "i915_drm.h"
  31. #include "i915_drv.h"
  32. #define USER_INT_FLAG (1<<1)
  33. #define VSYNC_PIPEB_FLAG (1<<5)
  34. #define VSYNC_PIPEA_FLAG (1<<7)
  35. #define MAX_NOPID ((u32)~0)
  36. /**
  37. * i915_get_pipe - return the the pipe associated with a given plane
  38. * @dev: DRM device
  39. * @plane: plane to look for
  40. *
  41. * The Intel Mesa & 2D drivers call the vblank routines with a plane number
  42. * rather than a pipe number, since they may not always be equal. This routine
  43. * maps the given @plane back to a pipe number.
  44. */
  45. static int
  46. i915_get_pipe(struct drm_device *dev, int plane)
  47. {
  48. drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  49. u32 dspcntr;
  50. dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR);
  51. return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0;
  52. }
  53. /**
  54. * i915_get_plane - return the the plane associated with a given pipe
  55. * @dev: DRM device
  56. * @pipe: pipe to look for
  57. *
  58. * The Intel Mesa & 2D drivers call the vblank routines with a plane number
  59. * rather than a plane number, since they may not always be equal. This routine
  60. * maps the given @pipe back to a plane number.
  61. */
  62. static int
  63. i915_get_plane(struct drm_device *dev, int pipe)
  64. {
  65. if (i915_get_pipe(dev, 0) == pipe)
  66. return 0;
  67. return 1;
  68. }
  69. /**
  70. * i915_pipe_enabled - check if a pipe is enabled
  71. * @dev: DRM device
  72. * @pipe: pipe to check
  73. *
  74. * Reading certain registers when the pipe is disabled can hang the chip.
  75. * Use this routine to make sure the PLL is running and the pipe is active
  76. * before reading such registers if unsure.
  77. */
  78. static int
  79. i915_pipe_enabled(struct drm_device *dev, int pipe)
  80. {
  81. drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  82. unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF;
  83. if (I915_READ(pipeconf) & PIPEACONF_ENABLE)
  84. return 1;
  85. return 0;
  86. }
  87. /**
  88. * Emit a synchronous flip.
  89. *
  90. * This function must be called with the drawable spinlock held.
  91. */
  92. static void
  93. i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw,
  94. int plane)
  95. {
  96. drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  97. drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
  98. u16 x1, y1, x2, y2;
  99. int pf_planes = 1 << plane;
  100. /* If the window is visible on the other plane, we have to flip on that
  101. * plane as well.
  102. */
  103. if (plane == 1) {
  104. x1 = sarea_priv->planeA_x;
  105. y1 = sarea_priv->planeA_y;
  106. x2 = x1 + sarea_priv->planeA_w;
  107. y2 = y1 + sarea_priv->planeA_h;
  108. } else {
  109. x1 = sarea_priv->planeB_x;
  110. y1 = sarea_priv->planeB_y;
  111. x2 = x1 + sarea_priv->planeB_w;
  112. y2 = y1 + sarea_priv->planeB_h;
  113. }
  114. if (x2 > 0 && y2 > 0) {
  115. int i, num_rects = drw->num_rects;
  116. struct drm_clip_rect *rect = drw->rects;
  117. for (i = 0; i < num_rects; i++)
  118. if (!(rect[i].x1 >= x2 || rect[i].y1 >= y2 ||
  119. rect[i].x2 <= x1 || rect[i].y2 <= y1)) {
  120. pf_planes = 0x3;
  121. break;
  122. }
  123. }
  124. i915_dispatch_flip(dev, pf_planes, 1);
  125. }
  126. /**
  127. * Emit blits for scheduled buffer swaps.
  128. *
  129. * This function will be called with the HW lock held.
  130. */
  131. static void i915_vblank_tasklet(struct drm_device *dev)
  132. {
  133. drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  134. struct list_head *list, *tmp, hits, *hit;
  135. int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages;
  136. unsigned counter[2];
  137. struct drm_drawable_info *drw;
  138. drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
  139. u32 cpp = dev_priv->cpp, offsets[3];
  140. u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
  141. XY_SRC_COPY_BLT_WRITE_ALPHA |
  142. XY_SRC_COPY_BLT_WRITE_RGB)
  143. : XY_SRC_COPY_BLT_CMD;
  144. u32 src_pitch = sarea_priv->pitch * cpp;
  145. u32 dst_pitch = sarea_priv->pitch * cpp;
  146. /* COPY rop (0xcc), map cpp to magic color depth constants */
  147. u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24);
  148. RING_LOCALS;
  149. if (sarea_priv->front_tiled) {
  150. cmd |= XY_SRC_COPY_BLT_DST_TILED;
  151. dst_pitch >>= 2;
  152. }
  153. if (sarea_priv->back_tiled) {
  154. cmd |= XY_SRC_COPY_BLT_SRC_TILED;
  155. src_pitch >>= 2;
  156. }
  157. counter[0] = drm_vblank_count(dev, 0);
  158. counter[1] = drm_vblank_count(dev, 1);
  159. DRM_DEBUG("\n");
  160. INIT_LIST_HEAD(&hits);
  161. nhits = nrects = 0;
  162. /* No irqsave/restore necessary. This tasklet may be run in an
  163. * interrupt context or normal context, but we don't have to worry
  164. * about getting interrupted by something acquiring the lock, because
  165. * we are the interrupt context thing that acquires the lock.
  166. */
  167. spin_lock(&dev_priv->swaps_lock);
  168. /* Find buffer swaps scheduled for this vertical blank */
  169. list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
  170. drm_i915_vbl_swap_t *vbl_swap =
  171. list_entry(list, drm_i915_vbl_swap_t, head);
  172. int pipe = i915_get_pipe(dev, vbl_swap->plane);
  173. if ((counter[pipe] - vbl_swap->sequence) > (1<<23))
  174. continue;
  175. list_del(list);
  176. dev_priv->swaps_pending--;
  177. drm_vblank_put(dev, pipe);
  178. spin_unlock(&dev_priv->swaps_lock);
  179. spin_lock(&dev->drw_lock);
  180. drw = drm_get_drawable_info(dev, vbl_swap->drw_id);
  181. if (!drw) {
  182. spin_unlock(&dev->drw_lock);
  183. drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
  184. spin_lock(&dev_priv->swaps_lock);
  185. continue;
  186. }
  187. list_for_each(hit, &hits) {
  188. drm_i915_vbl_swap_t *swap_cmp =
  189. list_entry(hit, drm_i915_vbl_swap_t, head);
  190. struct drm_drawable_info *drw_cmp =
  191. drm_get_drawable_info(dev, swap_cmp->drw_id);
  192. if (drw_cmp &&
  193. drw_cmp->rects[0].y1 > drw->rects[0].y1) {
  194. list_add_tail(list, hit);
  195. break;
  196. }
  197. }
  198. spin_unlock(&dev->drw_lock);
  199. /* List of hits was empty, or we reached the end of it */
  200. if (hit == &hits)
  201. list_add_tail(list, hits.prev);
  202. nhits++;
  203. spin_lock(&dev_priv->swaps_lock);
  204. }
  205. spin_unlock(&dev_priv->swaps_lock);
  206. if (nhits == 0)
  207. return;
  208. i915_kernel_lost_context(dev);
  209. upper[0] = upper[1] = 0;
  210. slice[0] = max(sarea_priv->planeA_h / nhits, 1);
  211. slice[1] = max(sarea_priv->planeB_h / nhits, 1);
  212. lower[0] = sarea_priv->planeA_y + slice[0];
  213. lower[1] = sarea_priv->planeB_y + slice[0];
  214. offsets[0] = sarea_priv->front_offset;
  215. offsets[1] = sarea_priv->back_offset;
  216. offsets[2] = sarea_priv->third_offset;
  217. num_pages = sarea_priv->third_handle ? 3 : 2;
  218. spin_lock(&dev->drw_lock);
  219. /* Emit blits for buffer swaps, partitioning both outputs into as many
  220. * slices as there are buffer swaps scheduled in order to avoid tearing
  221. * (based on the assumption that a single buffer swap would always
  222. * complete before scanout starts).
  223. */
  224. for (i = 0; i++ < nhits;
  225. upper[0] = lower[0], lower[0] += slice[0],
  226. upper[1] = lower[1], lower[1] += slice[1]) {
  227. int init_drawrect = 1;
  228. if (i == nhits)
  229. lower[0] = lower[1] = sarea_priv->height;
  230. list_for_each(hit, &hits) {
  231. drm_i915_vbl_swap_t *swap_hit =
  232. list_entry(hit, drm_i915_vbl_swap_t, head);
  233. struct drm_clip_rect *rect;
  234. int num_rects, plane, front, back;
  235. unsigned short top, bottom;
  236. drw = drm_get_drawable_info(dev, swap_hit->drw_id);
  237. if (!drw)
  238. continue;
  239. plane = swap_hit->plane;
  240. if (swap_hit->flip) {
  241. i915_dispatch_vsync_flip(dev, drw, plane);
  242. continue;
  243. }
  244. if (init_drawrect) {
  245. int width = sarea_priv->width;
  246. int height = sarea_priv->height;
  247. if (IS_I965G(dev)) {
  248. BEGIN_LP_RING(4);
  249. OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
  250. OUT_RING(0);
  251. OUT_RING(((width - 1) & 0xffff) | ((height - 1) << 16));
  252. OUT_RING(0);
  253. ADVANCE_LP_RING();
  254. } else {
  255. BEGIN_LP_RING(6);
  256. OUT_RING(GFX_OP_DRAWRECT_INFO);
  257. OUT_RING(0);
  258. OUT_RING(0);
  259. OUT_RING(((width - 1) & 0xffff) | ((height - 1) << 16));
  260. OUT_RING(0);
  261. OUT_RING(0);
  262. ADVANCE_LP_RING();
  263. }
  264. sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT;
  265. init_drawrect = 0;
  266. }
  267. rect = drw->rects;
  268. top = upper[plane];
  269. bottom = lower[plane];
  270. front = (dev_priv->sarea_priv->pf_current_page >>
  271. (2 * plane)) & 0x3;
  272. back = (front + 1) % num_pages;
  273. for (num_rects = drw->num_rects; num_rects--; rect++) {
  274. int y1 = max(rect->y1, top);
  275. int y2 = min(rect->y2, bottom);
  276. if (y1 >= y2)
  277. continue;
  278. BEGIN_LP_RING(8);
  279. OUT_RING(cmd);
  280. OUT_RING(ropcpp | dst_pitch);
  281. OUT_RING((y1 << 16) | rect->x1);
  282. OUT_RING((y2 << 16) | rect->x2);
  283. OUT_RING(offsets[front]);
  284. OUT_RING((y1 << 16) | rect->x1);
  285. OUT_RING(src_pitch);
  286. OUT_RING(offsets[back]);
  287. ADVANCE_LP_RING();
  288. }
  289. }
  290. }
  291. spin_unlock(&dev->drw_lock);
  292. list_for_each_safe(hit, tmp, &hits) {
  293. drm_i915_vbl_swap_t *swap_hit =
  294. list_entry(hit, drm_i915_vbl_swap_t, head);
  295. list_del(hit);
  296. drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER);
  297. }
  298. }
  299. u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
  300. {
  301. drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  302. unsigned long high_frame;
  303. unsigned long low_frame;
  304. u32 high1, high2, low, count;
  305. int pipe;
  306. pipe = i915_get_pipe(dev, plane);
  307. high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
  308. low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
  309. if (!i915_pipe_enabled(dev, pipe)) {
  310. printk(KERN_ERR "trying to get vblank count for disabled "
  311. "pipe %d\n", pipe);
  312. return 0;
  313. }
  314. /*
  315. * High & low register fields aren't synchronized, so make sure
  316. * we get a low value that's stable across two reads of the high
  317. * register.
  318. */
  319. do {
  320. high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
  321. PIPE_FRAME_HIGH_SHIFT);
  322. low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
  323. PIPE_FRAME_LOW_SHIFT);
  324. high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
  325. PIPE_FRAME_HIGH_SHIFT);
  326. } while (high1 != high2);
  327. count = (high1 << 8) | low;
  328. /* count may be reset by other driver(e.g. 2D driver),
  329. we have no way to know if it is wrapped or resetted
  330. when count is zero. do a rough guess.
  331. */
  332. if (count == 0 && dev->last_vblank[pipe] < dev->max_vblank_count/2)
  333. dev->last_vblank[pipe] = 0;
  334. return count;
  335. }
  336. irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
  337. {
  338. struct drm_device *dev = (struct drm_device *) arg;
  339. drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  340. u32 iir;
  341. u32 pipea_stats, pipeb_stats;
  342. int vblank = 0;
  343. iir = I915_READ(I915REG_INT_IDENTITY_R);
  344. if (iir == 0) {
  345. DRM_DEBUG ("iir 0x%08x im 0x%08x ie 0x%08x pipea 0x%08x pipeb 0x%08x\n",
  346. iir,
  347. I915_READ(I915REG_INT_MASK_R),
  348. I915_READ(I915REG_INT_ENABLE_R),
  349. I915_READ(I915REG_PIPEASTAT),
  350. I915_READ(I915REG_PIPEBSTAT));
  351. return IRQ_NONE;
  352. }
  353. /*
  354. * Clear the PIPE(A|B)STAT regs before the IIR otherwise
  355. * we may get extra interrupts.
  356. */
  357. if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
  358. pipea_stats = I915_READ(I915REG_PIPEASTAT);
  359. if (pipea_stats & (I915_START_VBLANK_INTERRUPT_STATUS|
  360. I915_VBLANK_INTERRUPT_STATUS))
  361. {
  362. vblank++;
  363. drm_handle_vblank(dev, i915_get_plane(dev, 0));
  364. }
  365. I915_WRITE(I915REG_PIPEASTAT, pipea_stats);
  366. }
  367. if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
  368. pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
  369. if (pipeb_stats & (I915_START_VBLANK_INTERRUPT_STATUS|
  370. I915_VBLANK_INTERRUPT_STATUS))
  371. {
  372. vblank++;
  373. drm_handle_vblank(dev, i915_get_plane(dev, 1));
  374. }
  375. I915_WRITE(I915REG_PIPEBSTAT, pipeb_stats);
  376. }
  377. if (dev_priv->sarea_priv)
  378. dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
  379. I915_WRITE(I915REG_INT_IDENTITY_R, iir);
  380. (void) I915_READ(I915REG_INT_IDENTITY_R); /* Flush posted write */
  381. if (iir & I915_USER_INTERRUPT) {
  382. DRM_WAKEUP(&dev_priv->irq_queue);
  383. }
  384. if (vblank) {
  385. if (dev_priv->swaps_pending > 0)
  386. drm_locked_tasklet(dev, i915_vblank_tasklet);
  387. }
  388. return IRQ_HANDLED;
  389. }
  390. static int i915_emit_irq(struct drm_device *dev)
  391. {
  392. drm_i915_private_t *dev_priv = dev->dev_private;
  393. RING_LOCALS;
  394. i915_kernel_lost_context(dev);
  395. DRM_DEBUG("\n");
  396. dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
  397. if (dev_priv->counter > 0x7FFFFFFFUL)
  398. dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
  399. BEGIN_LP_RING(6);
  400. OUT_RING(CMD_STORE_DWORD_IDX);
  401. OUT_RING(20);
  402. OUT_RING(dev_priv->counter);
  403. OUT_RING(0);
  404. OUT_RING(0);
  405. OUT_RING(GFX_OP_USER_INTERRUPT);
  406. ADVANCE_LP_RING();
  407. return dev_priv->counter;
  408. }
  409. static int i915_wait_irq(struct drm_device * dev, int irq_nr)
  410. {
  411. drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  412. int ret = 0;
  413. DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
  414. READ_BREADCRUMB(dev_priv));
  415. if (READ_BREADCRUMB(dev_priv) >= irq_nr)
  416. return 0;
  417. dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
  418. DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
  419. READ_BREADCRUMB(dev_priv) >= irq_nr);
  420. if (ret == -EBUSY) {
  421. DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
  422. READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
  423. }
  424. if (dev_priv->sarea_priv)
  425. dev_priv->sarea_priv->last_dispatch =
  426. READ_BREADCRUMB(dev_priv);
  427. return ret;
  428. }
  429. /* Needs the lock as it touches the ring.
  430. */
  431. int i915_irq_emit(struct drm_device *dev, void *data,
  432. struct drm_file *file_priv)
  433. {
  434. drm_i915_private_t *dev_priv = dev->dev_private;
  435. drm_i915_irq_emit_t *emit = data;
  436. int result;
  437. LOCK_TEST_WITH_RETURN(dev, file_priv);
  438. if (!dev_priv) {
  439. DRM_ERROR("called with no initialization\n");
  440. return -EINVAL;
  441. }
  442. result = i915_emit_irq(dev);
  443. if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) {
  444. DRM_ERROR("copy_to_user\n");
  445. return -EFAULT;
  446. }
  447. return 0;
  448. }
  449. /* Doesn't need the hardware lock.
  450. */
  451. int i915_irq_wait(struct drm_device *dev, void *data,
  452. struct drm_file *file_priv)
  453. {
  454. drm_i915_private_t *dev_priv = dev->dev_private;
  455. drm_i915_irq_wait_t *irqwait = data;
  456. if (!dev_priv) {
  457. DRM_ERROR("called with no initialization\n");
  458. return -EINVAL;
  459. }
  460. return i915_wait_irq(dev, irqwait->irq_seq);
  461. }
  462. int i915_enable_vblank(struct drm_device *dev, int plane)
  463. {
  464. drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  465. int pipe = i915_get_pipe(dev, plane);
  466. u32 pipestat_reg = 0;
  467. u32 pipestat;
  468. switch (pipe) {
  469. case 0:
  470. pipestat_reg = I915REG_PIPEASTAT;
  471. dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
  472. break;
  473. case 1:
  474. pipestat_reg = I915REG_PIPEBSTAT;
  475. dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
  476. break;
  477. default:
  478. DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
  479. pipe);
  480. break;
  481. }
  482. if (pipestat_reg)
  483. {
  484. pipestat = I915_READ (pipestat_reg);
  485. /*
  486. * Older chips didn't have the start vblank interrupt,
  487. * but
  488. */
  489. if (IS_I965G (dev))
  490. pipestat |= I915_START_VBLANK_INTERRUPT_ENABLE;
  491. else
  492. pipestat |= I915_VBLANK_INTERRUPT_ENABLE;
  493. /*
  494. * Clear any pending status
  495. */
  496. pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS |
  497. I915_VBLANK_INTERRUPT_STATUS);
  498. I915_WRITE(pipestat_reg, pipestat);
  499. }
  500. I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
  501. return 0;
  502. }
  503. void i915_disable_vblank(struct drm_device *dev, int plane)
  504. {
  505. drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  506. int pipe = i915_get_pipe(dev, plane);
  507. u32 pipestat_reg = 0;
  508. u32 pipestat;
  509. switch (pipe) {
  510. case 0:
  511. pipestat_reg = I915REG_PIPEASTAT;
  512. dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
  513. break;
  514. case 1:
  515. pipestat_reg = I915REG_PIPEBSTAT;
  516. dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
  517. break;
  518. default:
  519. DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
  520. pipe);
  521. break;
  522. }
  523. I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
  524. if (pipestat_reg)
  525. {
  526. pipestat = I915_READ (pipestat_reg);
  527. pipestat &= ~(I915_START_VBLANK_INTERRUPT_ENABLE |
  528. I915_VBLANK_INTERRUPT_ENABLE);
  529. /*
  530. * Clear any pending status
  531. */
  532. pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS |
  533. I915_VBLANK_INTERRUPT_STATUS);
  534. I915_WRITE(pipestat_reg, pipestat);
  535. }
  536. }
  537. static void i915_enable_interrupt (struct drm_device *dev)
  538. {
  539. drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  540. dev_priv->irq_enable_reg |= I915_USER_INTERRUPT;
  541. I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
  542. dev_priv->irq_enabled = 1;
  543. }
  544. /* Set the vblank monitor pipe
  545. */
  546. int i915_vblank_pipe_set(struct drm_device *dev, void *data,
  547. struct drm_file *file_priv)
  548. {
  549. drm_i915_private_t *dev_priv = dev->dev_private;
  550. drm_i915_vblank_pipe_t *pipe = data;
  551. if (!dev_priv) {
  552. DRM_ERROR("called with no initialization\n");
  553. return -EINVAL;
  554. }
  555. if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
  556. DRM_ERROR("called with invalid pipe 0x%x\n", pipe->pipe);
  557. return -EINVAL;
  558. }
  559. dev_priv->vblank_pipe = pipe->pipe;
  560. return 0;
  561. }
  562. int i915_vblank_pipe_get(struct drm_device *dev, void *data,
  563. struct drm_file *file_priv)
  564. {
  565. drm_i915_private_t *dev_priv = dev->dev_private;
  566. drm_i915_vblank_pipe_t *pipe = data;
  567. u16 flag;
  568. if (!dev_priv) {
  569. DRM_ERROR("called with no initialization\n");
  570. return -EINVAL;
  571. }
  572. flag = I915_READ(I915REG_INT_ENABLE_R);
  573. pipe->pipe = 0;
  574. if (flag & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT)
  575. pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
  576. if (flag & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
  577. pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
  578. return 0;
  579. }
  580. /**
  581. * Schedule buffer swap at given vertical blank.
  582. */
  583. int i915_vblank_swap(struct drm_device *dev, void *data,
  584. struct drm_file *file_priv)
  585. {
  586. drm_i915_private_t *dev_priv = dev->dev_private;
  587. drm_i915_vblank_swap_t *swap = data;
  588. drm_i915_vbl_swap_t *vbl_swap;
  589. unsigned int pipe, seqtype, curseq, plane;
  590. unsigned long irqflags;
  591. struct list_head *list;
  592. int ret;
  593. if (!dev_priv) {
  594. DRM_ERROR("%s called with no initialization\n", __func__);
  595. return -EINVAL;
  596. }
  597. if (!dev_priv->sarea_priv || dev_priv->sarea_priv->rotation) {
  598. DRM_DEBUG("Rotation not supported\n");
  599. return -EINVAL;
  600. }
  601. if (swap->seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE |
  602. _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS |
  603. _DRM_VBLANK_FLIP)) {
  604. DRM_ERROR("Invalid sequence type 0x%x\n", swap->seqtype);
  605. return -EINVAL;
  606. }
  607. plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
  608. pipe = i915_get_pipe(dev, plane);
  609. seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);
  610. if (!(dev_priv->vblank_pipe & (1 << pipe))) {
  611. DRM_ERROR("Invalid pipe %d\n", pipe);
  612. return -EINVAL;
  613. }
  614. spin_lock_irqsave(&dev->drw_lock, irqflags);
  615. /* It makes no sense to schedule a swap for a drawable that doesn't have
  616. * valid information at this point. E.g. this could mean that the X
  617. * server is too old to push drawable information to the DRM, in which
  618. * case all such swaps would become ineffective.
  619. */
  620. if (!drm_get_drawable_info(dev, swap->drawable)) {
  621. spin_unlock_irqrestore(&dev->drw_lock, irqflags);
  622. DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable);
  623. return -EINVAL;
  624. }
  625. spin_unlock_irqrestore(&dev->drw_lock, irqflags);
  626. drm_update_vblank_count(dev, pipe);
  627. curseq = drm_vblank_count(dev, pipe);
  628. if (seqtype == _DRM_VBLANK_RELATIVE)
  629. swap->sequence += curseq;
  630. if ((curseq - swap->sequence) <= (1<<23)) {
  631. if (swap->seqtype & _DRM_VBLANK_NEXTONMISS) {
  632. swap->sequence = curseq + 1;
  633. } else {
  634. DRM_DEBUG("Missed target sequence\n");
  635. return -EINVAL;
  636. }
  637. }
  638. if (swap->seqtype & _DRM_VBLANK_FLIP) {
  639. swap->sequence--;
  640. if ((curseq - swap->sequence) <= (1<<23)) {
  641. struct drm_drawable_info *drw;
  642. LOCK_TEST_WITH_RETURN(dev, file_priv);
  643. spin_lock_irqsave(&dev->drw_lock, irqflags);
  644. drw = drm_get_drawable_info(dev, swap->drawable);
  645. if (!drw) {
  646. spin_unlock_irqrestore(&dev->drw_lock,
  647. irqflags);
  648. DRM_DEBUG("Invalid drawable ID %d\n",
  649. swap->drawable);
  650. return -EINVAL;
  651. }
  652. i915_dispatch_vsync_flip(dev, drw, plane);
  653. spin_unlock_irqrestore(&dev->drw_lock, irqflags);
  654. return 0;
  655. }
  656. }
  657. spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
  658. list_for_each(list, &dev_priv->vbl_swaps.head) {
  659. vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);
  660. if (vbl_swap->drw_id == swap->drawable &&
  661. vbl_swap->plane == plane &&
  662. vbl_swap->sequence == swap->sequence) {
  663. vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP);
  664. spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
  665. DRM_DEBUG("Already scheduled\n");
  666. return 0;
  667. }
  668. }
  669. spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
  670. if (dev_priv->swaps_pending >= 100) {
  671. DRM_DEBUG("Too many swaps queued\n");
  672. return -EBUSY;
  673. }
  674. vbl_swap = drm_calloc(1, sizeof(*vbl_swap), DRM_MEM_DRIVER);
  675. if (!vbl_swap) {
  676. DRM_ERROR("Failed to allocate memory to queue swap\n");
  677. return -ENOMEM;
  678. }
  679. DRM_DEBUG("\n");
  680. ret = drm_vblank_get(dev, pipe);
  681. if (ret) {
  682. drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
  683. return ret;
  684. }
  685. vbl_swap->drw_id = swap->drawable;
  686. vbl_swap->plane = plane;
  687. vbl_swap->sequence = swap->sequence;
  688. vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP);
  689. if (vbl_swap->flip)
  690. swap->sequence++;
  691. spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
  692. list_add_tail(&vbl_swap->head, &dev_priv->vbl_swaps.head);
  693. dev_priv->swaps_pending++;
  694. spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
  695. return 0;
  696. }
  697. /* drm_dma.h hooks
  698. */
  699. void i915_driver_irq_preinstall(struct drm_device * dev)
  700. {
  701. drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  702. I915_WRITE16(I915REG_HWSTAM, 0xeffe);
  703. I915_WRITE16(I915REG_INT_MASK_R, 0x0);
  704. I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
  705. }
  706. int i915_driver_irq_postinstall(struct drm_device * dev)
  707. {
  708. drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  709. int ret, num_pipes = 2;
  710. spin_lock_init(&dev_priv->swaps_lock);
  711. INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
  712. dev_priv->swaps_pending = 0;
  713. dev_priv->user_irq_refcount = 0;
  714. dev_priv->irq_enable_reg = 0;
  715. ret = drm_vblank_init(dev, num_pipes);
  716. if (ret)
  717. return ret;
  718. dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
  719. i915_enable_interrupt(dev);
  720. DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
  721. /*
  722. * Initialize the hardware status page IRQ location.
  723. */
  724. I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21));
  725. return 0;
  726. }
  727. void i915_driver_irq_uninstall(struct drm_device * dev)
  728. {
  729. drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  730. u32 temp;
  731. if (!dev_priv)
  732. return;
  733. dev_priv->irq_enabled = 0;
  734. I915_WRITE(I915REG_HWSTAM, 0xffffffff);
  735. I915_WRITE(I915REG_INT_MASK_R, 0xffffffff);
  736. I915_WRITE(I915REG_INT_ENABLE_R, 0x0);
  737. temp = I915_READ(I915REG_PIPEASTAT);
  738. I915_WRITE(I915REG_PIPEASTAT, temp);
  739. temp = I915_READ(I915REG_PIPEBSTAT);
  740. I915_WRITE(I915REG_PIPEBSTAT, temp);
  741. temp = I915_READ(I915REG_INT_IDENTITY_R);
  742. I915_WRITE(I915REG_INT_IDENTITY_R, temp);
  743. }