]>
Commit | Line | Data |
---|---|---|
6ee73861 BS |
1 | #include "drmP.h" |
2 | #include "drm.h" | |
3 | #include "nouveau_drv.h" | |
4 | #include "nouveau_drm.h" | |
ff2b6c6e | 5 | #include "nouveau_hw.h" |
6ee73861 BS |
6 | |
7 | int | |
8 | nv04_timer_init(struct drm_device *dev) | |
9 | { | |
591b06d7 BS |
10 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
11 | u32 m, n, d; | |
12 | ||
6ee73861 BS |
13 | nv_wr32(dev, NV04_PTIMER_INTR_EN_0, 0x00000000); |
14 | nv_wr32(dev, NV04_PTIMER_INTR_0, 0xFFFFFFFF); | |
15 | ||
591b06d7 | 16 | /* aim for 31.25MHz, which gives us nanosecond timestamps */ |
afb0c796 | 17 | d = 1000000 / 32; |
591b06d7 BS |
18 | |
19 | /* determine base clock for timer source */ | |
20 | if (dev_priv->chipset < 0x40) { | |
ff2b6c6e | 21 | n = nouveau_hw_get_clock(dev, PLL_CORE); |
591b06d7 BS |
22 | } else |
23 | if (dev_priv->chipset == 0x40) { | |
24 | /*XXX: figure this out */ | |
25 | n = 0; | |
26 | } else { | |
afb0c796 | 27 | n = dev_priv->crystal; |
591b06d7 BS |
28 | m = 1; |
29 | while (n < (d * 2)) { | |
30 | n += (n / m); | |
31 | m++; | |
32 | } | |
33 | ||
34 | nv_wr32(dev, 0x009220, m - 1); | |
6ee73861 BS |
35 | } |
36 | ||
591b06d7 BS |
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); | |
6ee73861 BS |
65 | return 0; |
66 | } | |
67 | ||
591b06d7 | 68 | u64 |
6ee73861 BS |
69 | nv04_timer_read(struct drm_device *dev) |
70 | { | |
591b06d7 BS |
71 | u32 hi, lo; |
72 | ||
6ee73861 | 73 | do { |
591b06d7 BS |
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); | |
6ee73861 BS |
79 | } |
80 | ||
81 | void | |
82 | nv04_timer_takedown(struct drm_device *dev) | |
83 | { | |
84 | } |