Linux Audio

Check our new training course

Loading...
v3.1
 1#include "drmP.h"
 2#include "drm.h"
 3#include "nouveau_drv.h"
 4#include "nouveau_drm.h"
 
 5
 6int
 7nv04_timer_init(struct drm_device *dev)
 8{
 
 
 
 9	nv_wr32(dev, NV04_PTIMER_INTR_EN_0, 0x00000000);
10	nv_wr32(dev, NV04_PTIMER_INTR_0, 0xFFFFFFFF);
11
12	/* Just use the pre-existing values when possible for now; these regs
13	 * are not written in nv (driver writer missed a /4 on the address), and
14	 * writing 8 and 3 to the correct regs breaks the timings on the LVDS
15	 * hardware sequencing microcode.
16	 * A correct solution (involving calculations with the GPU PLL) can
17	 * be done when kernel modesetting lands
18	 */
19	if (!nv_rd32(dev, NV04_PTIMER_NUMERATOR) ||
20				!nv_rd32(dev, NV04_PTIMER_DENOMINATOR)) {
21		nv_wr32(dev, NV04_PTIMER_NUMERATOR, 0x00000008);
22		nv_wr32(dev, NV04_PTIMER_DENOMINATOR, 0x00000003);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23	}
24
 
 
 
 
 
 
 
 
 
 
 
 
25	return 0;
26}
27
28uint64_t
29nv04_timer_read(struct drm_device *dev)
30{
31	uint32_t low;
32	/* From kmmio dumps on nv28 this looks like how the blob does this.
33	 * It reads the high dword twice, before and after.
34	 * The only explanation seems to be that the 64-bit timer counter
35	 * advances between high and low dword reads and may corrupt the
36	 * result. Not confirmed.
37	 */
38	uint32_t high2 = nv_rd32(dev, NV04_PTIMER_TIME_1);
39	uint32_t high1;
40	do {
41		high1 = high2;
42		low = nv_rd32(dev, NV04_PTIMER_TIME_0);
43		high2 = nv_rd32(dev, NV04_PTIMER_TIME_1);
44	} while (high1 != high2);
45	return (((uint64_t)high2) << 32) | (uint64_t)low;
46}
47
48void
49nv04_timer_takedown(struct drm_device *dev)
50{
51}
v3.5.6
 1#include "drmP.h"
 2#include "drm.h"
 3#include "nouveau_drv.h"
 4#include "nouveau_drm.h"
 5#include "nouveau_hw.h"
 6
 7int
 8nv04_timer_init(struct drm_device *dev)
 9{
10	struct drm_nouveau_private *dev_priv = dev->dev_private;
11	u32 m, n, d;
12
13	nv_wr32(dev, NV04_PTIMER_INTR_EN_0, 0x00000000);
14	nv_wr32(dev, NV04_PTIMER_INTR_0, 0xFFFFFFFF);
15
16	/* aim for 31.25MHz, which gives us nanosecond timestamps */
17	d = 1000000 / 32;
18
19	/* determine base clock for timer source */
20	if (dev_priv->chipset < 0x40) {
21		n = nouveau_hw_get_clock(dev, PLL_CORE);
22	} else
23	if (dev_priv->chipset == 0x40) {
24		/*XXX: figure this out */
25		n = 0;
26	} else {
27		n = dev_priv->crystal;
28		m = 1;
29		while (n < (d * 2)) {
30			n += (n / m);
31			m++;
32		}
33
34		nv_wr32(dev, 0x009220, m - 1);
35	}
36
37	if (!n) {
38		NV_WARN(dev, "PTIMER: unknown input clock freq\n");
39		if (!nv_rd32(dev, NV04_PTIMER_NUMERATOR) ||
40		    !nv_rd32(dev, NV04_PTIMER_DENOMINATOR)) {
41			nv_wr32(dev, NV04_PTIMER_NUMERATOR, 1);
42			nv_wr32(dev, NV04_PTIMER_DENOMINATOR, 1);
43		}
44		return 0;
45	}
46
47	/* reduce ratio to acceptable values */
48	while (((n % 5) == 0) && ((d % 5) == 0)) {
49		n /= 5;
50		d /= 5;
51	}
52
53	while (((n % 2) == 0) && ((d % 2) == 0)) {
54		n /= 2;
55		d /= 2;
56	}
57
58	while (n > 0xffff || d > 0xffff) {
59		n >>= 1;
60		d >>= 1;
61	}
62
63	nv_wr32(dev, NV04_PTIMER_NUMERATOR, n);
64	nv_wr32(dev, NV04_PTIMER_DENOMINATOR, d);
65	return 0;
66}
67
68u64
69nv04_timer_read(struct drm_device *dev)
70{
71	u32 hi, lo;
72
 
 
 
 
 
 
 
73	do {
74		hi = nv_rd32(dev, NV04_PTIMER_TIME_1);
75		lo = nv_rd32(dev, NV04_PTIMER_TIME_0);
76	} while (hi != nv_rd32(dev, NV04_PTIMER_TIME_1));
77
78	return ((u64)hi << 32 | lo);
79}
80
81void
82nv04_timer_takedown(struct drm_device *dev)
83{
84}