List of commits:
Subject Hash Author Date (UTC)
page flip fix e51d9d4b1788c17633b0cdffd7a50309d51f8d0f Sylvain BERTRAND 2014-08-30 14:08:35
ack-ing the DCE irqs at the right time a12ec7f4781872de8d155e4e1d90b07df3e44c34 Sylvain BERTRAND 2014-08-28 15:23:29
normal programs use normal syscalls then ioctl 37589b6856d941efdc763eed41b237f4f62cb960 Sylvain BERTRAND 2014-07-08 19:01:52
new firware breaks the 3D pipeline 13db71ba4522d7266d68a21f43f25ee3781d0b92 Sylvain BERTRAND 2014-07-03 22:54:30
closed src or gnu gpl *not* v2 drivers are illegal dc1de426b639ffee863b0a211e9cf0e349f855f0 Sylvain BERTRAND 2014-07-03 17:59:46
compiling with 3.16 rc2 new mc fw code e00afdaeef8513da35c82cc82dcfee0745aa9129 Sylvain BERTRAND 2014-06-29 01:54:40
untested handling of new mc fw eb89a71b0af7781d1fc9ee226c1269b6d5183749 Sylvain BERTRAND 2014-06-29 01:26:15
become legal ef922b67f25aaf0c4f8cff5be572e53fb53bdfe5 Sylvain BERTRAND 2014-06-28 23:33:40
use usleep_range and fix a dp 1.1 time out d4183ce73e6ec7d7f3baf9d710dd2ba015b4a6a9 Sylvain BERTRAND 2014-02-19 20:09:44
fix dac a864ba601253674b679b07e4b1ddc00fb83a8cb6 Sylvain BERTRAND 2014-02-19 19:17:08
clear atombias dpm state and warn for instability 28b598d81f6a873f90d1a9325e3e1002743487a5 Sylvain BERTRAND 2014-02-19 19:10:43
CFG_MEM_SZ upper 16bits may have garbage f08f2e3471989e448d6d76ba02565fd9efc3293f Sylvain BERTRAND 2014-02-19 17:55:38
fix ena rbs mask performance critical bug 289497449dd0f2acb09e03f65988e22e45948fb6 Sylvain BERTRAND 2014-02-19 17:15:18
upstream confirm bug, fixed e2142c3fdfc01d51e7fec7687ec4d02f548ce763 Sylvain BERTRAND 2014-02-18 16:10:14
mainly bug fixing 1650d6a6e13bd81a4df9bfaa84a5daef2989ccdf Sylvain BERTRAND 2014-02-18 12:46:40
dump smc sw regs 5b42263039c858624ff411d94318f6ef5171a864 Sylvain BERTRAND 2014-02-17 12:22:26
disable switch to low power when no display 69f94e04ea89c1fe9ccaef153da5f5ade232c2a1 Sylvain BERTRAND 2014-02-17 09:59:28
finish smc switch to driver power state 6f99d0a01491dd671174919d842a771ac4a81a4b Sylvain BERTRAND 2014-02-17 09:47:02
pcie things and follow upstream for dyn pm init f4fb120597276a3badc08eec30783b10d111f756 Sylvain BERTRAND 2014-02-17 09:00:00
dump performance state tbls 06a22756b504ecf4523c86f657104e0b970195de Sylvain BERTRAND 2014-02-14 17:02:23
Commit e51d9d4b1788c17633b0cdffd7a50309d51f8d0f - page flip fix
Author: Sylvain BERTRAND
Author date (UTC): 2014-08-30 14:08
Committer name: Sylvain BERTRAND
Committer date (UTC): 2014-08-30 14:08
Parent(s): a12ec7f4781872de8d155e4e1d90b07df3e44c34
Signing key:
Tree: b5b594a1758919ba1a626b06ad7296a9c07d0bcf
File Lines added Lines deleted
drivers/gpu/alga/amd/atombios/dce.c 14 0
drivers/gpu/alga/amd/dce6/crtc.c 79 32
drivers/gpu/alga/amd/dce6/dce6.h 5 3
drivers/gpu/alga/amd/dce6/hpd.c 5 6
drivers/gpu/alga/amd/dce6/irq.c 6 5
drivers/gpu/alga/amd/dce6/mod.c 4 5
drivers/gpu/alga/amd/dce6/regs.h 29 0
drivers/gpu/alga/amd/si/drv.c 2 0
drivers/gpu/alga/amd/si/fops/dce.c 3 3
drivers/gpu/alga/amd/si/fops/fops.c 12 1
drivers/gpu/alga/amd/si/ih.c 16 6
drivers/gpu/alga/amd/si/intr_irq.c 0 1
include/uapi/alga/amd/si/ioctl.h 1 0
File drivers/gpu/alga/amd/atombios/dce.c changed (mode: 100644) (index 223ea69..da79a81)
... ... unlock_mutex:
1304 1304 } }
1305 1305 EXPORT_SYMBOL_GPL(atb_crtc_lock); EXPORT_SYMBOL_GPL(atb_crtc_lock);
1306 1306
1307 /*
1308 * The DCE vertical timings seems to:
1309 * - the vblank is cut in 2 parts: a top one and a bottom one
1310 * - the bottom vblank size (number of lines) seems to be the sync pulse
1311 * +-------------------------+
1312 * | vblank top |
1313 * +-------------------------+
1314 * | |
1315 * | frame |
1316 * | |
1317 * +-------------------------+
1318 * | vblank bot = sync pulse |
1319 * +-------------------------+
1320 */
1307 1321 long atb_crtc_timing(struct atombios *atb, u8 i, struct alga_timing *t) long atb_crtc_timing(struct atombios *atb, u8 i, struct alga_timing *t)
1308 1322 { {
1309 1323 u16 of; u16 of;
File drivers/gpu/alga/amd/dce6/crtc.c changed (mode: 100644) (index 5508ab8..69c3638)
... ... long crtc_fb(struct dce6 *dce, u8 i, struct sink_db_fb *db_fb)
29 29 u32 fb_swap; u32 fb_swap;
30 30 u32 viewport_h; u32 viewport_h;
31 31 u32 viewport_v; u32 viewport_v;
32 u32 tmp;
32 u32 grph_flip_ctl;
33 33
34 34 fb_swap = set(GSC_ENDIAN_SWAP, GSC_ENDIAN_NONE); fb_swap = set(GSC_ENDIAN_SWAP, GSC_ENDIAN_NONE);
35 35 switch (db_fb->pixel_fmt) { switch (db_fb->pixel_fmt) {
 
... ... long crtc_fb(struct dce6 *dce, u8 i, struct sink_db_fb *db_fb)
87 87
88 88 /* XXX: obsolete pageflip setup */ /* XXX: obsolete pageflip setup */
89 89 /* make sure flip is at vb rather than hb */ /* make sure flip is at vb rather than hb */
90 tmp = dce->ddev.rr32(dce->ddev.dev, regs_grph_flip_ctl[i]);
91 tmp &= ~GFC_SURF_UPDATE_H_RETRACE_ENA;
92 WR32(tmp, regs_grph_flip_ctl[i]);
90 grph_flip_ctl = dce->ddev.rr32(dce->ddev.dev, regs_grph_flip_ctl[i]);
91 grph_flip_ctl &= ~GFC_SURF_UPDATE_H_RETRACE_ENA;
92 WR32(grph_flip_ctl, regs_grph_flip_ctl[i]);
93 93
94 94 /* set pageflip to happen anywhere in vblank interval */ /* set pageflip to happen anywhere in vblank interval */
95 95 WR32(0, regs_master_update_mode[i]); WR32(0, regs_master_update_mode[i]);
 
... ... long dce6_crtcs_shutdown(struct dce6 *dce)
190 190 } }
191 191 EXPORT_SYMBOL_GPL(dce6_crtcs_shutdown); EXPORT_SYMBOL_GPL(dce6_crtcs_shutdown);
192 192
193 static void page_flip(struct dce6 *dce, u8 i)
193 static long page_flip(struct dce6 *dce, u8 i)
194 194 { {
195 u32 tmp;
195 u32 grph_update;
196 196 u64 swap; u64 swap;
197 197 struct crtc_surfs *css; struct crtc_surfs *css;
198 198 u32 j; u32 j;
199 long r;
200
201 r = 0;
199 202
200 203 css = &dce->dps[i].pf.crtc_surfs; css = &dce->dps[i].pf.crtc_surfs;
201 204
 
... ... static void page_flip(struct dce6 *dce, u8 i)
203 206 css->secondary = css->primary; css->secondary = css->primary;
204 207 css->primary = swap; css->primary = swap;
205 208
206 tmp = RR32(regs_grph_update[i]);
207 tmp |= GU_UPDATE_LOCK;
208 WR32(tmp, regs_grph_update[i]);
209 grph_update = RR32(regs_grph_update[i]);
210 grph_update |= GU_UPDATE_LOCK;
211 WR32(grph_update, regs_grph_update[i]);
209 212
210 213 WR32(upper_32_bits(css->primary), regs_grph_primary_surf_addr_high[i]); WR32(upper_32_bits(css->primary), regs_grph_primary_surf_addr_high[i]);
211 214 WR32(upper_32_bits(css->secondary), WR32(upper_32_bits(css->secondary),
 
... ... static void page_flip(struct dce6 *dce, u8 i)
215 218 WR32((u32)(css->secondary) & GSSA_SURF_ADDR_MASK, WR32((u32)(css->secondary) & GSSA_SURF_ADDR_MASK,
216 219 regs_grph_secondary_surf_addr[i]); regs_grph_secondary_surf_addr[i]);
217 220
221 /* wait for the notification to go high */
218 222 for (j = 0; j < USEC_TIMEOUT; ++j) { for (j = 0; j < USEC_TIMEOUT; ++j) {
219 223 if (RR32(regs_grph_update[i]) & GU_SURF_UPDATE_PENDING) if (RR32(regs_grph_update[i]) & GU_SURF_UPDATE_PENDING)
220 224 break; break;
221 225 udelay(1); udelay(1);
222 226 } }
223 if (j == USEC_TIMEOUT)
224 dev_warn(dce->ddev.dev, "dce6: page flip %u timed out\n", i);
227 if (j == USEC_TIMEOUT) {
228 dev_err(dce->ddev.dev, "dce6: page flip on %u timed out\n", i);
229 r = -DCE6_ERR;
230 }
225 231
226 tmp &= ~GU_UPDATE_LOCK;
227 WR32(tmp, regs_grph_update[i]);
232 grph_update &= ~GU_UPDATE_LOCK;
233 WR32(grph_update, regs_grph_update[i]);
234 return r;
228 235 } }
229 236
230 237 /* /*
 
... ... static void page_flip(struct dce6 *dce, u8 i)
233 240 */ */
234 241 void dce6_pf_irq(struct dce6 *dce, u8 i, struct timespec monotonic_raw_tp) void dce6_pf_irq(struct dce6 *dce, u8 i, struct timespec monotonic_raw_tp)
235 242 { {
236 u32 tmp;
237 u32 vblanks_n;
243 u32 crtc_int_mask;
244 u32 vblank_n;
245
246 vblank_n = RR32(regs_crtc_status_frame_cnt[i]);
247
248 /*
249 * XXX: we can be in the vblank handler only to notify a page flip
250 * completion.
251 * There are 2 things to keep in mind:
252 * - the vblank interrupt can happen a bit *before* the real vblank.
253 * (was told it's an hardware bug).
254 * - the page flip will be done in hardware during the vblank, you
255 * don't know when (insanity since they have the specs).
256 * It is supposed *not* to matter since, in vblank, the pixel of the
257 * visible frame buffer are supposed to be sent already to the display
258 * device.
259 * Meaning, starting to draw the next frame into the "maybe" not yet
260 * flipped visible framebuffer should have very little chance/no chance to
261 * glitch what's actually on screen.
262 * If it does glitch for whatever reason in some cases, will
263 * wait for the update pending bit to go low, hard way.
264 */
238 265
239 /* disabling page flip is disabling the vblank interrupt */
240 tmp = RR32(regs_crtc_int_mask[i]);
241 tmp &= ~IM_VBLANK_INT_MASK;
242 WR32(tmp, regs_crtc_int_mask[i]);
266 /* page flip is done */
243 267
244 page_flip(dce, i);
268 /* we don't need the vblank interupt anymore */
269 crtc_int_mask = RR32(regs_crtc_int_mask[i]);
270 crtc_int_mask &= ~IM_VBLANK_INT_MASK;
271 WR32(crtc_int_mask, regs_crtc_int_mask[i]);
245 272
246 vblanks_n = RR32(regs_crtc_status_frame_cnt[i]);
247
248 273 spin_lock(&dce->dps[i].pf.lock); spin_lock(&dce->dps[i].pf.lock);
249 if (dce->dps[i].pf.notify)
250 dce->dps[i].pf.notify(i, vblanks_n, monotonic_raw_tp,
274 dce->dps[i].pf.notify(i, vblank_n, monotonic_raw_tp,
251 275 dce->dps[i].pf.data); dce->dps[i].pf.data);
252 276 dce->dps[i].pf.notify = NULL; dce->dps[i].pf.notify = NULL;
253 277 dce->dps[i].pf.data = NULL; dce->dps[i].pf.data = NULL;
 
... ... void dce6_pf_irq(struct dce6 *dce, u8 i, struct timespec monotonic_raw_tp)
255 279 } }
256 280 EXPORT_SYMBOL_GPL(dce6_pf_irq); EXPORT_SYMBOL_GPL(dce6_pf_irq);
257 281
258 /* XXX: the notify function will be run in hard irq context */
259 282 long dce6_pf(struct dce6 *dce, u8 i, long dce6_pf(struct dce6 *dce, u8 i,
260 283 void (*notify)(u8 i, u32 vblanks_n, struct timespec monotonic_raw_tp, void (*notify)(u8 i, u32 vblanks_n, struct timespec monotonic_raw_tp,
261 284 void *data), void *data) void *data), void *data)
262 285 { {
263 u32 tmp;
286 long r;
287 u32 crtc_int_mask;
288
289 r = 0;
264 290
265 291 lock(dce); lock(dce);
266 /* scheduling a page flip is enabling vblank interrupt */
267 tmp = RR32(regs_crtc_int_mask[i]);
268 tmp |= IM_VBLANK_INT_MASK;
269 WR32(tmp, regs_crtc_int_mask[i]);
270 292
293 /* if we are alreading waiting for a pf, notify the user */
271 294 spin_lock_irq(&dce->dps[i].pf.lock); spin_lock_irq(&dce->dps[i].pf.lock);
295 if (dce->dps[i].pf.notify) {
296 spin_unlock_irq(&dce->dps[i].pf.lock);
297 r = SI_DCE_PF_PENDING;
298 goto unlock_dce;
299 }
300 spin_unlock_irq(&dce->dps[i].pf.lock);
301
302 r = page_flip(dce, i);
303 if (r == -DCE6_ERR)
304 goto unlock_dce;
305
306 /* the notify function will be run in hard irq context */
272 307 dce->dps[i].pf.notify = notify; dce->dps[i].pf.notify = notify;
273 308 dce->dps[i].pf.data = data; dce->dps[i].pf.data = data;
274 spin_unlock_irq(&dce->dps[i].pf.lock);
275 309
310 /* a page flip happens in a vblank */
311 crtc_int_mask = RR32(regs_crtc_int_mask[i]);
312 crtc_int_mask |= IM_VBLANK_INT_MASK;
313 WR32(crtc_int_mask, regs_crtc_int_mask[i]);
314
315 unlock_dce:
276 316 unlock(dce); unlock(dce);
277 return 0;
317 return r;
278 318 } }
279 319 EXPORT_SYMBOL_GPL(dce6_pf); EXPORT_SYMBOL_GPL(dce6_pf);
280 320
 
... ... void dce6_pf_cancel_all(struct dce6 *dce)
288 328
289 329 lock(dce); lock(dce);
290 330 for (i = 0; i < dce->ddev.crtcs_n; ++i) { for (i = 0; i < dce->ddev.crtcs_n; ++i) {
331 u32 crtc_int_mask;
332
291 333 if ((dce->dps_used & BIT(i)) == 0) if ((dce->dps_used & BIT(i)) == 0)
292 334 continue; continue;
293 335
336 /* shut down the vblank interrupt */
337 crtc_int_mask = RR32(regs_crtc_int_mask[i]);
338 crtc_int_mask &= ~IM_VBLANK_INT_MASK;
339 WR32(crtc_int_mask, regs_crtc_int_mask[i]);
340
294 341 spin_lock_irq(&dce->dps[i].pf.lock); spin_lock_irq(&dce->dps[i].pf.lock);
295 342 dce->dps[i].pf.notify = NULL; dce->dps[i].pf.notify = NULL;
296 343 dce->dps[i].pf.data = NULL; dce->dps[i].pf.data = NULL;
File drivers/gpu/alga/amd/dce6/dce6.h changed (mode: 100644) (index 3fe78f9..17e1dd2)
... ... struct crtc_surfs {
26 26 u64 secondary; u64 secondary;
27 27 }; };
28 28
29 #define PF_STATE_NONE 0
30 #define PF_STATE_NOT_SUBMITED 1
31 #define PF_STATE_SUBMITED 2
29 32 struct pf { struct pf {
30 33 struct crtc_surfs crtc_surfs; struct crtc_surfs crtc_surfs;
31 /* this function will run in irq hard context */
34 /* this function will run in irq hard context */
32 35 spinlock_t lock; spinlock_t lock;
33 36 void (*notify)(u8 i, u32 v_blanks_n, struct timespec monotonic_raw_tp, void (*notify)(u8 i, u32 v_blanks_n, struct timespec monotonic_raw_tp,
34 37 void *data); void *data);
 
... ... struct dp {
64 67 }; };
65 68
66 69 struct irq { struct irq {
67 spinlock_t lock;
70 spinlock_t hpds_lock;
68 71 u8 hpds;/* protected by above spinlock */ u8 hpds;/* protected by above spinlock */
69
70 72 /* avoid child device registration after suspend "prepare" call */ /* avoid child device registration after suspend "prepare" call */
71 73 u8 hpd_dev_registration_lock;/* protected by the dce mutex */ u8 hpd_dev_registration_lock;/* protected by the dce mutex */
72 74 }; };
File drivers/gpu/alga/amd/dce6/hpd.c changed (mode: 100644) (index 42b29f7..1f050b9)
... ... long hpd_irq(struct dce6 *dce, u8 hpd)
226 226 if (dce->dps[i].connected != sense) { if (dce->dps[i].connected != sense) {
227 227 if (dce->irq.hpd_dev_registration_lock == 1 if (dce->irq.hpd_dev_registration_lock == 1
228 228 && sense == 1) { && sense == 1) {
229 dev_warn(dce->ddev.dev,
230 "dce6:attempt to register a display device on dp%u while suspending\n", i);
229 dev_warn(dce->ddev.dev, "dce6:attempt to register a display device on dp%u while suspending\n",
230 i);
231 231 } else { } else {
232 232 r = dp_toggle(dce, i); r = dp_toggle(dce, i);
233 233 } }
 
... ... EXPORT_SYMBOL_GPL(dce6_hpds_intr_ena);
260 260
261 261 void dce6_hpd_irq(struct dce6 *dce, u8 hpd) void dce6_hpd_irq(struct dce6 *dce, u8 hpd)
262 262 { {
263 unsigned long flgs;
264
265 spin_lock_irqsave(&dce->irq.lock, flgs);
263 /* we just flag the hpd and we will do the work in the irq thread */
264 spin_lock(&dce->irq.hpds_lock);
266 265 dce->irq.hpds |= BIT(hpd); dce->irq.hpds |= BIT(hpd);
267 spin_unlock_irqrestore(&dce->irq.lock, flgs);
266 spin_unlock(&dce->irq.hpds_lock);
268 267 } }
269 268 EXPORT_SYMBOL_GPL(dce6_hpd_irq); EXPORT_SYMBOL_GPL(dce6_hpd_irq);
File drivers/gpu/alga/amd/dce6/irq.c changed (mode: 100644) (index 1ce0190..4b13811)
... ... void dce6_irqs_ack(struct dce6 *dce)
63 63 } }
64 64 EXPORT_SYMBOL_GPL(dce6_irqs_ack); EXPORT_SYMBOL_GPL(dce6_irqs_ack);
65 65
66 /* this will be run in the irq thread, then not the hard context */
66 67 long dce6_irqs_thd(struct dce6 *dce) long dce6_irqs_thd(struct dce6 *dce)
67 68 { {
68 69 long r; long r;
69 70 u8 i; u8 i;
70 71 u8 hpds; u8 hpds;
71 unsigned long flgs;
72 72
73 spin_lock_irqsave(&dce->irq.lock, flgs);
73 /* grab the flagged hpd pins */
74 spin_lock_irq(&dce->irq.hpds_lock);
74 75 hpds = dce->irq.hpds; hpds = dce->irq.hpds;
75 76 dce->irq.hpds = 0; dce->irq.hpds = 0;
76 spin_unlock_irqrestore(&dce->irq.lock, flgs);
77 spin_unlock_irq(&dce->irq.hpds_lock);
77 78
78 79 r = 0; r = 0;
79 80 for (i = 0; i < HPDS_N; ++i) for (i = 0; i < HPDS_N; ++i)
80 81 if (hpds & BIT(i)) { if (hpds & BIT(i)) {
81 82 r = hpd_irq(dce, i); r = hpd_irq(dce, i);
82 83 if (r != 0) if (r != 0)
83 dev_err(dce->ddev.dev,
84 "dce6:unable to service hpd%u interrupt request\n", i);
84 dev_err(dce->ddev.dev, "dce6:unable to service hpd%u interrupt request\n",
85 i);
85 86 } }
86 87 return r; return r;
87 88 } }
File drivers/gpu/alga/amd/dce6/mod.c changed (mode: 100644) (index 29bb03e..48604d2)
... ... static void dps_connected_sysfs_shutdown(struct dce6 *dce)
557 557 } }
558 558 } }
559 559
560 static void dps_pf_init_once(struct dce6 *dce)
560 static void dps_used_pf_lock_init_once(struct dce6 *dce)
561 561 { {
562 562 u8 i; u8 i;
563
563 564 for (i = 0; i < dce->ddev.crtcs_n; ++i) { for (i = 0; i < dce->ddev.crtcs_n; ++i) {
564 565 if ((dce->dps_used & BIT(i)) == 0) if ((dce->dps_used & BIT(i)) == 0)
565 566 continue; continue;
 
... ... long dce6_init_once(struct dce6 *dce)
572 573 long r; long r;
573 574
574 575 mutex_init(&dce->mutex); mutex_init(&dce->mutex);
575 spin_lock_init(&dce->irq.lock);
576
576 spin_lock_init(&dce->irq.hpds_lock);
577 577 r = paths_parse(dce); r = paths_parse(dce);
578 578 if (r == -DCE6_ERR) if (r == -DCE6_ERR)
579 579 return -DCE6_ERR; return -DCE6_ERR;
580 580
581 dps_pf_init_once(dce);
582
581 dps_used_pf_lock_init_once(dce);
583 582 dce_dump(dce); dce_dump(dce);
584 583 return 0; return 0;
585 584 } }
File drivers/gpu/alga/amd/dce6/regs.h changed (mode: 100644) (index 8f31975..c17b9ad)
... ... static inline u32 get(u32 mask, u32 v)
475 475 #define VIEWPORT_START 0x6d70 #define VIEWPORT_START 0x6d70
476 476 #define VIEWPORT_SZ 0x6d74 #define VIEWPORT_SZ 0x6d74
477 477
478 /* 0x6e34 ... */
479 #define CRTC_VBLANK_START_END 0x6e34
480 /* VSTART is the first line of VBLANK */
481 #define CVSE_VSTART 0x00001fff
482 /* VEND is the first line after VBLANK space ??? */
483 #define CVSE_VEND 0x1fff0000
484
478 485 /* 0x6e70 ... */ /* 0x6e70 ... */
479 486 #define CRTC_CTL 0x6e70 #define CRTC_CTL 0x6e70
480 487 #define CC_MASTER_ENA BIT(0) #define CC_MASTER_ENA BIT(0)
481 488 #define CC_VBLANK BIT(1) #define CC_VBLANK BIT(1)
482 489 #define CC_DISP_READ_REQ_DIS BIT(24) #define CC_DISP_READ_REQ_DIS BIT(24)
490 #define CRTC_STATUS_POS 0x6e90
491 #define CSP_VPOS 0x00001fff
492 #define CSP_HPOS 0x1fff0000
483 493 #define CRTC_STATUS_FRAME_CNT 0x6e98 #define CRTC_STATUS_FRAME_CNT 0x6e98
484 494 #define CRTC_UPDATE_LOCK 0x6ed4 #define CRTC_UPDATE_LOCK 0x6ed4
485 495 #define MASTER_UPDATE_MODE 0x6ef8 #define MASTER_UPDATE_MODE 0x6ef8
486 496
497
498 static u32 regs_crtc_status_pos[CRTCS_N_MAX] __attribute__ ((unused)) = {
499 CRTC_STATUS_POS + CRTC0_REG_OF,
500 CRTC_STATUS_POS + CRTC1_REG_OF,
501 CRTC_STATUS_POS + CRTC2_REG_OF,
502 CRTC_STATUS_POS + CRTC3_REG_OF,
503 CRTC_STATUS_POS + CRTC4_REG_OF,
504 CRTC_STATUS_POS + CRTC5_REG_OF
505 };
506
507 static u32 regs_crtc_vblank_start_end[CRTCS_N_MAX] __attribute__ ((unused)) = {
508 CRTC_VBLANK_START_END + CRTC0_REG_OF,
509 CRTC_VBLANK_START_END + CRTC1_REG_OF,
510 CRTC_VBLANK_START_END + CRTC2_REG_OF,
511 CRTC_VBLANK_START_END + CRTC3_REG_OF,
512 CRTC_VBLANK_START_END + CRTC4_REG_OF,
513 CRTC_VBLANK_START_END + CRTC5_REG_OF
514 };
515
487 516 static u32 regs_lut_30_color[CRTCS_N_MAX] __attribute__ ((unused)) = { static u32 regs_lut_30_color[CRTCS_N_MAX] __attribute__ ((unused)) = {
488 517 LUT_30_COLOR + CRTC0_REG_OF, LUT_30_COLOR + CRTC0_REG_OF,
489 518 LUT_30_COLOR + CRTC1_REG_OF, LUT_30_COLOR + CRTC1_REG_OF,
File drivers/gpu/alga/amd/si/drv.c changed (mode: 100644) (index ff51883..ba36e3c)
... ... u32 rr32(struct pci_dev *dev, u32 aligned_of)
71 71 if (aligned_of <= (dd->regs_sz - sizeof(u32))) { if (aligned_of <= (dd->regs_sz - sizeof(u32))) {
72 72 val = readl(dd->regs + aligned_of); val = readl(dd->regs + aligned_of);
73 73 } else { } else {
74 /* FIXME: should have a spinlock to make it atomic */
74 75 writel((u32)(aligned_of >> 31), dd->regs + MM_IDX_HI); writel((u32)(aligned_of >> 31), dd->regs + MM_IDX_HI);
75 76 writel(lower_32_bits(aligned_of) & ~MI_VRAM, dd->regs + MM_IDX); writel(lower_32_bits(aligned_of) & ~MI_VRAM, dd->regs + MM_IDX);
76 77 val = readl(dd->regs + MM_DATA); val = readl(dd->regs + MM_DATA);
 
... ... void wr32(struct pci_dev *dev, u32 val, u32 aligned_of)
97 98 if (aligned_of <= (dd->regs_sz - sizeof(u32))) { if (aligned_of <= (dd->regs_sz - sizeof(u32))) {
98 99 writel(val, dd->regs + aligned_of); writel(val, dd->regs + aligned_of);
99 100 } else { } else {
101 /* FIXME: should have a spinlock to make it atomic */
100 102 writel((u32)(aligned_of >> 31), dd->regs + MM_IDX_HI); writel((u32)(aligned_of >> 31), dd->regs + MM_IDX_HI);
101 103 writel(lower_32_bits(aligned_of) & ~MI_VRAM, dd->regs + MM_IDX); writel(lower_32_bits(aligned_of) & ~MI_VRAM, dd->regs + MM_IDX);
102 104 writel(val, dd->regs + MM_DATA); writel(val, dd->regs + MM_DATA);
File drivers/gpu/alga/amd/si/fops/dce.c changed (mode: 100644) (index fac2c59..2589fff)
... ... long fops_dce_pf(struct pci_dev *dev, u8 __user *user_i, void *data)
125 125 dd = pci_get_drvdata(dev); dd = pci_get_drvdata(dev);
126 126
127 127 r = dce6_pf(dd->dce, i, pf_notify, data); r = dce6_pf(dd->dce, i, pf_notify, data);
128 if (r != 0)
129 return -ENODEV;
130 return 0;
128 if (r == -DCE6_ERR)
129 r = -ENODEV;
130 return r; /* pass-thru for other return codes */
131 131 } }
132 132
133 133 #define EDID_SZ_MAX ((255 + 1) * 128) #define EDID_SZ_MAX ((255 + 1) * 128)
File drivers/gpu/alga/amd/si/fops/fops.c changed (mode: 100644) (index 6c93db8..2c680c7)
... ... static int open(struct inode *i, struct file *f)
65 65 struct file_private_data *data; struct file_private_data *data;
66 66 struct dev_drv_data *dd; struct dev_drv_data *dd;
67 67
68 /* FIXME: should close file options/flags possibities */
69
68 70 dd = container_of(i->i_cdev, struct dev_drv_data, char_cdev); dd = container_of(i->i_cdev, struct dev_drv_data, char_cdev);
69 71
70 72 data = kzalloc(sizeof(*data), GFP_KERNEL); data = kzalloc(sizeof(*data), GFP_KERNEL);
 
... ... static int release(struct inode *i, struct file *f)
340 342 { {
341 343 struct file_private_data *data; struct file_private_data *data;
342 344
343
344 345 data = f->private_data; data = f->private_data;
345 346 spin_lock(&files_private_data_lock); spin_lock(&files_private_data_lock);
346 347 list_del(&data->n); list_del(&data->n);
 
... ... static ssize_t fops_read(struct file *f, char __user *buf, size_t buf_sz,
408 409
409 410 data = f->private_data; data = f->private_data;
410 411
412 if (*of != 0)
413 return -EINVAL;
414
411 415 spin_lock_irq(&data->evts_lock); spin_lock_irq(&data->evts_lock);
416
417 if (f->f_flags & O_NONBLOCK)
418 if (list_empty(&data->evts)) {
419 spin_unlock_irq(&data->evts_lock);
420 return -EAGAIN;
421 }
422
412 423 r = wait_event_interruptible_lock_irq(data->evts_wq, r = wait_event_interruptible_lock_irq(data->evts_wq,
413 424 !list_empty(&data->evts), data->evts_lock); !list_empty(&data->evts), data->evts_lock);
414 425 if (r == -ERESTARTSYS) { if (r == -ERESTARTSYS) {
File drivers/gpu/alga/amd/si/ih.c changed (mode: 100644) (index 675f6e3..d4ebc53)
... ... void ih_init(struct pci_dev *dev)
142 142 * [127:80] - reserved * [127:80] - reserved
143 143 */ */
144 144 static void vector(struct pci_dev *dev, u32 id, u32 data, u8 ring_id, static void vector(struct pci_dev *dev, u32 id, u32 data, u8 ring_id,
145 u8 *irq_thd)
145 u8 *irq_thd, u8 *dce6_irqs_acked)
146 146 { {
147 147 struct dev_drv_data *dd; struct dev_drv_data *dd;
148 148
 
... ... static void vector(struct pci_dev *dev, u32 id, u32 data, u8 ring_id,
150 150
151 151 switch (id) { switch (id) {
152 152 case VECTOR_ID_HPD: case VECTOR_ID_HPD:
153 if (!*dce6_irqs_acked) {
154 dce6_irqs_ack(dd->dce);
155 *dce6_irqs_acked = 1;
156 }
153 157 dce6_hpd_irq(dd->dce, data); dce6_hpd_irq(dd->dce, data);
154 158 *irq_thd = IRQ_THD_ENA; *irq_thd = IRQ_THD_ENA;
155 159 break; break;
 
... ... static void vector(struct pci_dev *dev, u32 id, u32 data, u8 ring_id,
159 163 case VECTOR_ID_D3: case VECTOR_ID_D3:
160 164 case VECTOR_ID_D4: case VECTOR_ID_D4:
161 165 case VECTOR_ID_D5: case VECTOR_ID_D5:
166 if (!*dce6_irqs_acked) {
167 dce6_irqs_ack(dd->dce);
168 *dce6_irqs_acked = 1;
169 }
162 170 if (data == Dx_VBLANK) {/* only page flipping in vblank */ if (data == Dx_VBLANK) {/* only page flipping in vblank */
163 171 struct timespec tp; struct timespec tp;
164 172 getrawmonotonic(&tp); getrawmonotonic(&tp);
165 173
166 174 dce6_pf_irq(dd->dce, id - 1, tp); dce6_pf_irq(dd->dce, id - 1, tp);
167 *irq_thd = IRQ_THD_DIS; /* useless to run the thread */
168 175 } }
169 176 break; break;
170 177 case VECTOR_ID_EOP: case VECTOR_ID_EOP:
 
... ... u8 ih_parse(struct pci_dev *dev)
245 252
246 253 spin_lock_irqsave(&dd->ih.lock, flgs); spin_lock_irqsave(&dd->ih.lock, flgs);
247 254 while (1) { while (1) {
255 u8 dce6_irqs_acked;
256
248 257 rmb(); rmb();
249 258
250 259 wp = le32_to_cpup(dd->ba.wb_map->cpu_addr + WB_IH_WPTR_OF); wp = le32_to_cpup(dd->ba.wb_map->cpu_addr + WB_IH_WPTR_OF);
 
... ... u8 ih_parse(struct pci_dev *dev)
254 263 if (rp == wp) if (rp == wp)
255 264 break; break;
256 265
257 /* must ack dce irqs ourself HERE AND NOW! */
258 dce6_irqs_ack(dd->dce);
259
266 ///* must ack dce irqs ourself HERE AND NOW! */
267 //dce6_irqs_ack(dd->dce);
268 dce6_irqs_acked = 0;
260 269 do { do {
261 270 u32 id; u32 id;
262 271 u32 data; u32 data;
 
... ... u8 ih_parse(struct pci_dev *dev)
269 278 ring_id = le32_to_cpup(dd->ba.ih_ring_map->cpu_addr + rp ring_id = le32_to_cpup(dd->ba.ih_ring_map->cpu_addr + rp
270 279 + sizeof(id) + sizeof(data)) & 0xff; + sizeof(id) + sizeof(data)) & 0xff;
271 280
272 vector(dev, id, data, ring_id, &irq_thd);
281 vector(dev, id, data, ring_id, &irq_thd,
282 &dce6_irqs_acked);
273 283
274 284 rp += VECTOR_SZ; rp += VECTOR_SZ;
275 285 rp &= IH_RING_MASK; rp &= IH_RING_MASK;
File drivers/gpu/alga/amd/si/intr_irq.c changed (mode: 100644) (index 10ea10a..e0af0b6)
... ... irqreturn_t irq(int irq, void *dev_id)
62 62 else else
63 63 return IRQ_NONE; return IRQ_NONE;
64 64 } }
65
File include/uapi/alga/amd/si/ioctl.h changed (mode: 100644) (index c93b72b..347efb3)
22 22 #define SI_CONTEXT_LOST 1/* for instance, back from suspend */ #define SI_CONTEXT_LOST 1/* for instance, back from suspend */
23 23 #define SI_RING_TIMEOUT 2 #define SI_RING_TIMEOUT 2
24 24 #define SI_FENCE_TIMEOUT 3 #define SI_FENCE_TIMEOUT 3
25 #define SI_DCE_PF_PENDING 4
25 26
26 27 struct si_timeout_info { struct si_timeout_info {
27 28 uint32_t n_max; uint32_t n_max;
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/sylware/linux-gpu-amd-si

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/sylware/linux-gpu-amd-si

Clone this repository using git:
git clone git://git.rocketgit.com/user/sylware/linux-gpu-amd-si

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main