1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include "drmP.h"
28#include "drm_crtc_helper.h"
29#include "nouveau_drv.h"
30#include "nouveau_encoder.h"
31#include "nouveau_crtc.h"
32#include "nouveau_hw.h"
33#include "nv17_tv.h"
34
35char *nv17_tv_norm_names[NUM_TV_NORMS] = {
36 [TV_NORM_PAL] = "PAL",
37 [TV_NORM_PAL_M] = "PAL-M",
38 [TV_NORM_PAL_N] = "PAL-N",
39 [TV_NORM_PAL_NC] = "PAL-Nc",
40 [TV_NORM_NTSC_M] = "NTSC-M",
41 [TV_NORM_NTSC_J] = "NTSC-J",
42 [TV_NORM_HD480I] = "hd480i",
43 [TV_NORM_HD480P] = "hd480p",
44 [TV_NORM_HD576I] = "hd576i",
45 [TV_NORM_HD576P] = "hd576p",
46 [TV_NORM_HD720P] = "hd720p",
47 [TV_NORM_HD1080I] = "hd1080i"
48};
49
50
51
52struct nv17_tv_norm_params nv17_tv_norms[NUM_TV_NORMS] = {
53 [TV_NORM_PAL] = { TV_ENC_MODE, {
54 .tv_enc_mode = { 720, 576, 50000, {
55 0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18,
56 0x7e, 0x40, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3,
57 0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c,
58 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3,
59 0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5,
60 0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0,
61 0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b,
62 0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0
63 } } } },
64
65 [TV_NORM_PAL_M] = { TV_ENC_MODE, {
66 .tv_enc_mode = { 720, 480, 59940, {
67 0x21, 0xe6, 0xef, 0xe3, 0x0, 0x0, 0xb, 0x18,
68 0x7e, 0x44, 0x76, 0x32, 0x25, 0x0, 0x3c, 0x0,
69 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83,
70 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
71 0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5,
72 0x0, 0x18, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0,
73 0x0, 0xb4, 0x0, 0x15, 0x40, 0x10, 0x0, 0x9c,
74 0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
75 } } } },
76
77 [TV_NORM_PAL_N] = { TV_ENC_MODE, {
78 .tv_enc_mode = { 720, 576, 50000, {
79 0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18,
80 0x7e, 0x40, 0x8a, 0x32, 0x25, 0x0, 0x3c, 0x0,
81 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c,
82 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
83 0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5,
84 0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0,
85 0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b,
86 0xbd, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
87 } } } },
88
89 [TV_NORM_PAL_NC] = { TV_ENC_MODE, {
90 .tv_enc_mode = { 720, 576, 50000, {
91 0x21, 0xf6, 0x94, 0x46, 0x0, 0x0, 0xb, 0x18,
92 0x7e, 0x44, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3,
93 0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c,
94 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3,
95 0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5,
96 0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0,
97 0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b,
98 0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0
99 } } } },
100
101 [TV_NORM_NTSC_M] = { TV_ENC_MODE, {
102 .tv_enc_mode = { 720, 480, 59940, {
103 0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18,
104 0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x3c, 0x0,
105 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83,
106 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
107 0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5,
108 0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0,
109 0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0x9c,
110 0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
111 } } } },
112
113 [TV_NORM_NTSC_J] = { TV_ENC_MODE, {
114 .tv_enc_mode = { 720, 480, 59940, {
115 0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18,
116 0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x32, 0x0,
117 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83,
118 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
119 0xcf, 0x4, 0xcf, 0x1, 0x2, 0x0, 0xa, 0x5,
120 0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0,
121 0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0xa4,
122 0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
123 } } } },
124
125 [TV_NORM_HD480I] = { TV_ENC_MODE, {
126 .tv_enc_mode = { 720, 480, 59940, {
127 0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18,
128 0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x32, 0x0,
129 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83,
130 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
131 0xcf, 0x4, 0xcf, 0x1, 0x2, 0x0, 0xa, 0x5,
132 0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0,
133 0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0xa4,
134 0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
135 } } } },
136
137 [TV_NORM_HD576I] = { TV_ENC_MODE, {
138 .tv_enc_mode = { 720, 576, 50000, {
139 0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18,
140 0x7e, 0x40, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3,
141 0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c,
142 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3,
143 0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5,
144 0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0,
145 0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b,
146 0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0
147 } } } },
148
149
150 [TV_NORM_HD480P] = { CTV_ENC_MODE, {
151 .ctv_enc_mode = {
152 .mode = { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000,
153 720, 735, 743, 858, 0, 480, 490, 494, 525, 0,
154 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
155 .ctv_regs = { 0x3540000, 0x0, 0x0, 0x314,
156 0x354003a, 0x40000, 0x6f0344, 0x18100000,
157 0x10160004, 0x10060005, 0x1006000c, 0x10060020,
158 0x10060021, 0x140e0022, 0x10060202, 0x1802020a,
159 0x1810020b, 0x10000fff, 0x10000fff, 0x10000fff,
160 0x10000fff, 0x10000fff, 0x10000fff, 0x70,
161 0x3ff0000, 0x57, 0x2e001e, 0x258012c,
162 0xa0aa04ec, 0x30, 0x80960019, 0x12c0300,
163 0x2019, 0x600, 0x32060019, 0x0, 0x0, 0x400
164 } } } },
165
166 [TV_NORM_HD576P] = { CTV_ENC_MODE, {
167 .ctv_enc_mode = {
168 .mode = { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000,
169 720, 730, 738, 864, 0, 576, 581, 585, 625, 0,
170 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
171 .ctv_regs = { 0x3540000, 0x0, 0x0, 0x314,
172 0x354003a, 0x40000, 0x6f0344, 0x18100000,
173 0x10060001, 0x10060009, 0x10060026, 0x10060027,
174 0x140e0028, 0x10060268, 0x1810026d, 0x10000fff,
175 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff,
176 0x10000fff, 0x10000fff, 0x10000fff, 0x69,
177 0x3ff0000, 0x57, 0x2e001e, 0x258012c,
178 0xa0aa04ec, 0x30, 0x80960019, 0x12c0300,
179 0x2019, 0x600, 0x32060019, 0x0, 0x0, 0x400
180 } } } },
181
182 [TV_NORM_HD720P] = { CTV_ENC_MODE, {
183 .ctv_enc_mode = {
184 .mode = { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250,
185 1280, 1349, 1357, 1650, 0, 720, 725, 730, 750, 0,
186 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
187 .ctv_regs = { 0x1260394, 0x0, 0x0, 0x622,
188 0x66b0021, 0x6004a, 0x1210626, 0x8170000,
189 0x70004, 0x70016, 0x70017, 0x40f0018,
190 0x702e8, 0x81702ed, 0xfff, 0xfff,
191 0xfff, 0xfff, 0xfff, 0xfff,
192 0xfff, 0xfff, 0xfff, 0x0,
193 0x2e40001, 0x58, 0x2e001e, 0x258012c,
194 0xa0aa04ec, 0x30, 0x810c0039, 0x12c0300,
195 0xc0002039, 0x600, 0x32060039, 0x0, 0x0, 0x0
196 } } } },
197
198 [TV_NORM_HD1080I] = { CTV_ENC_MODE, {
199 .ctv_enc_mode = {
200 .mode = { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250,
201 1920, 1961, 2049, 2200, 0, 1080, 1084, 1088, 1125, 0,
202 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC
203 | DRM_MODE_FLAG_INTERLACE) },
204 .ctv_regs = { 0xac0420, 0x44c0478, 0x4a4, 0x4fc0868,
205 0x8940028, 0x60054, 0xe80870, 0xbf70000,
206 0xbc70004, 0x70005, 0x70012, 0x70013,
207 0x40f0014, 0x70230, 0xbf70232, 0xbf70233,
208 0x1c70237, 0x70238, 0x70244, 0x70245,
209 0x40f0246, 0x70462, 0x1f70464, 0x0,
210 0x2e40001, 0x58, 0x2e001e, 0x258012c,
211 0xa0aa04ec, 0x30, 0x815f004c, 0x12c0300,
212 0xc000204c, 0x600, 0x3206004c, 0x0, 0x0, 0x0
213 } } } }
214};
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249#define calc_overscan(o) interpolate(0x100, 0xe1, 0xc1, o)
250
251#define id1 (1LL << 8)
252#define id2 (1LL << 16)
253#define id3 (1LL << 24)
254#define id4 (1LL << 32)
255#define id5 (1LL << 48)
256
257static struct filter_params{
258 int64_t k1;
259 int64_t ki;
260 int64_t ki2;
261 int64_t ki3;
262 int64_t kr;
263 int64_t kir;
264 int64_t ki2r;
265 int64_t ki3r;
266 int64_t kf;
267 int64_t kif;
268 int64_t ki2f;
269 int64_t ki3f;
270 int64_t krf;
271 int64_t kirf;
272 int64_t ki2rf;
273 int64_t ki3rf;
274} fparams[2][4] = {
275
276 {
277 {64.311690 * id5, -39.516924 * id5, 6.586143 * id5, 0.000002 * id5,
278 0.051285 * id4, 26.168746 * id4, -4.361449 * id4, -0.000001 * id4,
279 9.308169 * id3, 78.180965 * id3, -13.030158 * id3, -0.000001 * id3,
280 -8.801540 * id1, -46.572890 * id1, 7.762145 * id1, -0.000000 * id1},
281 {-44.565569 * id5, -68.081246 * id5, 39.812074 * id5, -4.009316 * id5,
282 29.832207 * id4, 50.047322 * id4, -25.380017 * id4, 2.546422 * id4,
283 104.605622 * id3, 141.908641 * id3, -74.322319 * id3, 7.484316 * id3,
284 -37.081621 * id1, -90.397510 * id1, 42.784229 * id1, -4.289952 * id1},
285 {-56.793244 * id5, 31.153584 * id5, -5.192247 * id5, -0.000003 * id5,
286 33.541131 * id4, -34.149302 * id4, 5.691537 * id4, 0.000002 * id4,
287 87.196610 * id3, -88.995169 * id3, 14.832456 * id3, 0.000012 * id3,
288 17.288138 * id1, 71.864786 * id1, -11.977408 * id1, -0.000009 * id1},
289 {51.787796 * id5, 21.211771 * id5, -18.993730 * id5, 1.853310 * id5,
290 -41.470726 * id4, -17.775823 * id4, 13.057821 * id4, -1.15823 * id4,
291 -154.235673 * id3, -44.878641 * id3, 40.656077 * id3, -3.695595 * id3,
292 112.201065 * id1, 39.992155 * id1, -25.155714 * id1, 2.113984 * id1},
293 },
294
295
296 {
297 {67.601979 * id5, 0.428319 * id5, -0.071318 * id5, -0.000012 * id5,
298 -3.402339 * id4, 0.000209 * id4, -0.000092 * id4, 0.000010 * id4,
299 -9.180996 * id3, 6.111270 * id3, -1.024457 * id3, 0.001043 * id3,
300 6.060315 * id1, -0.017425 * id1, 0.007830 * id1, -0.000869 * id1},
301 {6.755647 * id5, 5.841348 * id5, 1.469734 * id5, -0.149656 * id5,
302 8.293120 * id4, -1.192888 * id4, -0.947652 * id4, 0.094507 * id4,
303 37.526655 * id3, 10.257875 * id3, -10.823275 * id3, 1.081497 * id3,
304 -2.361928 * id1, -2.059432 * id1, 1.840671 * id1, -0.168100 * id1},
305 {-14.780391 * id5, -16.042148 * id5, 2.673692 * id5, -0.000000 * id5,
306 39.541978 * id4, 5.680053 * id4, -0.946676 * id4, 0.000000 * id4,
307 152.994486 * id3, 12.625439 * id3, -2.119579 * id3, 0.002708 * id3,
308 -38.125089 * id1, -0.855880 * id1, 0.155359 * id1, -0.002245 * id1},
309 {-27.476193 * id5, -1.454976 * id5, 1.286557 * id5, 0.025346 * id5,
310 20.687300 * id4, 3.014003 * id4, -0.557786 * id4, -0.01311 * id4,
311 60.008737 * id3, -0.738273 * id3, 5.408217 * id3, -0.796798 * id3,
312 -17.296835 * id1, 4.438577 * id1, -2.809420 * id1, 0.385491 * id1},
313 }
314};
315
316static void tv_setup_filter(struct drm_encoder *encoder)
317{
318 struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
319 struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
320 struct drm_display_mode *mode = &encoder->crtc->mode;
321 uint32_t (*filters[])[4][7] = {&tv_enc->state.hfilter,
322 &tv_enc->state.vfilter};
323 int i, j, k;
324 int32_t overscan = calc_overscan(tv_enc->overscan);
325 int64_t flicker = (tv_enc->flicker - 50) * (id3 / 100);
326 uint64_t rs[] = {mode->hdisplay * id3,
327 mode->vdisplay * id3};
328
329 do_div(rs[0], overscan * tv_norm->tv_enc_mode.hdisplay);
330 do_div(rs[1], overscan * tv_norm->tv_enc_mode.vdisplay);
331
332 for (k = 0; k < 2; k++) {
333 rs[k] = max((int64_t)rs[k], id2);
334
335 for (j = 0; j < 4; j++) {
336 struct filter_params *p = &fparams[k][j];
337
338 for (i = 0; i < 7; i++) {
339 int64_t c = (p->k1 + p->ki*i + p->ki2*i*i +
340 p->ki3*i*i*i)
341 + (p->kr + p->kir*i + p->ki2r*i*i +
342 p->ki3r*i*i*i) * rs[k]
343 + (p->kf + p->kif*i + p->ki2f*i*i +
344 p->ki3f*i*i*i) * flicker
345 + (p->krf + p->kirf*i + p->ki2rf*i*i +
346 p->ki3rf*i*i*i) * flicker * rs[k];
347
348 (*filters[k])[j][i] = (c + id5/2) >> 39
349 & (0x1 << 31 | 0x7f << 9);
350 }
351 }
352 }
353}
354
355
356
357static void tv_save_filter(struct drm_device *dev, uint32_t base,
358 uint32_t regs[4][7])
359{
360 int i, j;
361 uint32_t offsets[] = { base, base + 0x1c, base + 0x40, base + 0x5c };
362
363 for (i = 0; i < 4; i++) {
364 for (j = 0; j < 7; j++)
365 regs[i][j] = nv_read_ptv(dev, offsets[i]+4*j);
366 }
367}
368
369static void tv_load_filter(struct drm_device *dev, uint32_t base,
370 uint32_t regs[4][7])
371{
372 int i, j;
373 uint32_t offsets[] = { base, base + 0x1c, base + 0x40, base + 0x5c };
374
375 for (i = 0; i < 4; i++) {
376 for (j = 0; j < 7; j++)
377 nv_write_ptv(dev, offsets[i]+4*j, regs[i][j]);
378 }
379}
380
381void nv17_tv_state_save(struct drm_device *dev, struct nv17_tv_state *state)
382{
383 int i;
384
385 for (i = 0; i < 0x40; i++)
386 state->tv_enc[i] = nv_read_tv_enc(dev, i);
387
388 tv_save_filter(dev, NV_PTV_HFILTER, state->hfilter);
389 tv_save_filter(dev, NV_PTV_HFILTER2, state->hfilter2);
390 tv_save_filter(dev, NV_PTV_VFILTER, state->vfilter);
391
392 nv_save_ptv(dev, state, 200);
393 nv_save_ptv(dev, state, 204);
394 nv_save_ptv(dev, state, 208);
395 nv_save_ptv(dev, state, 20c);
396 nv_save_ptv(dev, state, 304);
397 nv_save_ptv(dev, state, 500);
398 nv_save_ptv(dev, state, 504);
399 nv_save_ptv(dev, state, 508);
400 nv_save_ptv(dev, state, 600);
401 nv_save_ptv(dev, state, 604);
402 nv_save_ptv(dev, state, 608);
403 nv_save_ptv(dev, state, 60c);
404 nv_save_ptv(dev, state, 610);
405 nv_save_ptv(dev, state, 614);
406}
407
408void nv17_tv_state_load(struct drm_device *dev, struct nv17_tv_state *state)
409{
410 int i;
411
412 for (i = 0; i < 0x40; i++)
413 nv_write_tv_enc(dev, i, state->tv_enc[i]);
414
415 tv_load_filter(dev, NV_PTV_HFILTER, state->hfilter);
416 tv_load_filter(dev, NV_PTV_HFILTER2, state->hfilter2);
417 tv_load_filter(dev, NV_PTV_VFILTER, state->vfilter);
418
419 nv_load_ptv(dev, state, 200);
420 nv_load_ptv(dev, state, 204);
421 nv_load_ptv(dev, state, 208);
422 nv_load_ptv(dev, state, 20c);
423 nv_load_ptv(dev, state, 304);
424 nv_load_ptv(dev, state, 500);
425 nv_load_ptv(dev, state, 504);
426 nv_load_ptv(dev, state, 508);
427 nv_load_ptv(dev, state, 600);
428 nv_load_ptv(dev, state, 604);
429 nv_load_ptv(dev, state, 608);
430 nv_load_ptv(dev, state, 60c);
431 nv_load_ptv(dev, state, 610);
432 nv_load_ptv(dev, state, 614);
433
434
435 nv_write_tv_enc(dev, 0x3e, 1);
436 nv_write_tv_enc(dev, 0x3e, 0);
437}
438
439
440
441const struct drm_display_mode nv17_tv_modes[] = {
442 { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 0,
443 320, 344, 392, 560, 0, 200, 200, 202, 220, 0,
444 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC
445 | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) },
446 { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 0,
447 320, 344, 392, 560, 0, 240, 240, 246, 263, 0,
448 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC
449 | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) },
450 { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 0,
451 400, 432, 496, 640, 0, 300, 300, 303, 314, 0,
452 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC
453 | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) },
454 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 0,
455 640, 672, 768, 880, 0, 480, 480, 492, 525, 0,
456 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
457 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 0,
458 720, 752, 872, 960, 0, 480, 480, 493, 525, 0,
459 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
460 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 0,
461 720, 776, 856, 960, 0, 576, 576, 588, 597, 0,
462 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
463 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 0,
464 800, 840, 920, 1040, 0, 600, 600, 604, 618, 0,
465 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
466 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 0,
467 1024, 1064, 1200, 1344, 0, 768, 768, 777, 806, 0,
468 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
469 {}
470};
471
472void nv17_tv_update_properties(struct drm_encoder *encoder)
473{
474 struct drm_device *dev = encoder->dev;
475 struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
476 struct nv17_tv_state *regs = &tv_enc->state;
477 struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
478 int subconnector = tv_enc->select_subconnector ?
479 tv_enc->select_subconnector :
480 tv_enc->subconnector;
481
482 switch (subconnector) {
483 case DRM_MODE_SUBCONNECTOR_Composite:
484 {
485 regs->ptv_204 = 0x2;
486
487
488 if (tv_enc->pin_mask & 0x4)
489 regs->ptv_204 |= 0x010000;
490 else if (tv_enc->pin_mask & 0x2)
491 regs->ptv_204 |= 0x100000;
492 else
493 regs->ptv_204 |= 0x110000;
494
495 regs->tv_enc[0x7] = 0x10;
496 break;
497 }
498 case DRM_MODE_SUBCONNECTOR_SVIDEO:
499 regs->ptv_204 = 0x11012;
500 regs->tv_enc[0x7] = 0x18;
501 break;
502
503 case DRM_MODE_SUBCONNECTOR_Component:
504 regs->ptv_204 = 0x111333;
505 regs->tv_enc[0x7] = 0x14;
506 break;
507
508 case DRM_MODE_SUBCONNECTOR_SCART:
509 regs->ptv_204 = 0x111012;
510 regs->tv_enc[0x7] = 0x18;
511 break;
512 }
513
514 regs->tv_enc[0x20] = interpolate(0, tv_norm->tv_enc_mode.tv_enc[0x20],
515 255, tv_enc->saturation);
516 regs->tv_enc[0x22] = interpolate(0, tv_norm->tv_enc_mode.tv_enc[0x22],
517 255, tv_enc->saturation);
518 regs->tv_enc[0x25] = tv_enc->hue * 255 / 100;
519
520 nv_load_ptv(dev, regs, 204);
521 nv_load_tv_enc(dev, regs, 7);
522 nv_load_tv_enc(dev, regs, 20);
523 nv_load_tv_enc(dev, regs, 22);
524 nv_load_tv_enc(dev, regs, 25);
525}
526
527void nv17_tv_update_rescaler(struct drm_encoder *encoder)
528{
529 struct drm_device *dev = encoder->dev;
530 struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
531 struct nv17_tv_state *regs = &tv_enc->state;
532
533 regs->ptv_208 = 0x40 | (calc_overscan(tv_enc->overscan) << 8);
534
535 tv_setup_filter(encoder);
536
537 nv_load_ptv(dev, regs, 208);
538 tv_load_filter(dev, NV_PTV_HFILTER, regs->hfilter);
539 tv_load_filter(dev, NV_PTV_HFILTER2, regs->hfilter2);
540 tv_load_filter(dev, NV_PTV_VFILTER, regs->vfilter);
541}
542
543void nv17_ctv_update_rescaler(struct drm_encoder *encoder)
544{
545 struct drm_device *dev = encoder->dev;
546 struct drm_nouveau_private *dev_priv = dev->dev_private;
547 struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
548 int head = nouveau_crtc(encoder->crtc)->index;
549 struct nv04_crtc_reg *regs = &dev_priv->mode_reg.crtc_reg[head];
550 struct drm_display_mode *crtc_mode = &encoder->crtc->mode;
551 struct drm_display_mode *output_mode =
552 &get_tv_norm(encoder)->ctv_enc_mode.mode;
553 int overscan, hmargin, vmargin, hratio, vratio;
554
555
556 if (output_mode->flags & DRM_MODE_FLAG_INTERLACE)
557 overscan = 100;
558 else
559 overscan = tv_enc->overscan;
560
561 hmargin = (output_mode->hdisplay - crtc_mode->hdisplay) / 2;
562 vmargin = (output_mode->vdisplay - crtc_mode->vdisplay) / 2;
563
564 hmargin = interpolate(0, min(hmargin, output_mode->hdisplay/20),
565 hmargin, overscan);
566 vmargin = interpolate(0, min(vmargin, output_mode->vdisplay/20),
567 vmargin, overscan);
568
569 hratio = crtc_mode->hdisplay * 0x800 /
570 (output_mode->hdisplay - 2*hmargin);
571 vratio = crtc_mode->vdisplay * 0x800 /
572 (output_mode->vdisplay - 2*vmargin) & ~3;
573
574 regs->fp_horiz_regs[FP_VALID_START] = hmargin;
575 regs->fp_horiz_regs[FP_VALID_END] = output_mode->hdisplay - hmargin - 1;
576 regs->fp_vert_regs[FP_VALID_START] = vmargin;
577 regs->fp_vert_regs[FP_VALID_END] = output_mode->vdisplay - vmargin - 1;
578
579 regs->fp_debug_1 = NV_PRAMDAC_FP_DEBUG_1_YSCALE_TESTMODE_ENABLE |
580 XLATE(vratio, 0, NV_PRAMDAC_FP_DEBUG_1_YSCALE_VALUE) |
581 NV_PRAMDAC_FP_DEBUG_1_XSCALE_TESTMODE_ENABLE |
582 XLATE(hratio, 0, NV_PRAMDAC_FP_DEBUG_1_XSCALE_VALUE);
583
584 NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HVALID_START,
585 regs->fp_horiz_regs[FP_VALID_START]);
586 NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HVALID_END,
587 regs->fp_horiz_regs[FP_VALID_END]);
588 NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_VVALID_START,
589 regs->fp_vert_regs[FP_VALID_START]);
590 NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_VVALID_END,
591 regs->fp_vert_regs[FP_VALID_END]);
592 NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_1, regs->fp_debug_1);
593}
594