0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #include <drm/drm_crtc_helper.h>
0028 #include "nouveau_drv.h"
0029 #include "nouveau_encoder.h"
0030 #include "nouveau_crtc.h"
0031 #include "hw.h"
0032 #include "tvnv17.h"
0033
0034 const char * const nv17_tv_norm_names[NUM_TV_NORMS] = {
0035 [TV_NORM_PAL] = "PAL",
0036 [TV_NORM_PAL_M] = "PAL-M",
0037 [TV_NORM_PAL_N] = "PAL-N",
0038 [TV_NORM_PAL_NC] = "PAL-Nc",
0039 [TV_NORM_NTSC_M] = "NTSC-M",
0040 [TV_NORM_NTSC_J] = "NTSC-J",
0041 [TV_NORM_HD480I] = "hd480i",
0042 [TV_NORM_HD480P] = "hd480p",
0043 [TV_NORM_HD576I] = "hd576i",
0044 [TV_NORM_HD576P] = "hd576p",
0045 [TV_NORM_HD720P] = "hd720p",
0046 [TV_NORM_HD1080I] = "hd1080i"
0047 };
0048
0049
0050
0051 struct nv17_tv_norm_params nv17_tv_norms[NUM_TV_NORMS] = {
0052 [TV_NORM_PAL] = { TV_ENC_MODE, {
0053 .tv_enc_mode = { 720, 576, 50000, {
0054 0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18,
0055 0x7e, 0x40, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3,
0056 0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c,
0057 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3,
0058 0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5,
0059 0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0,
0060 0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b,
0061 0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0
0062 } } } },
0063
0064 [TV_NORM_PAL_M] = { TV_ENC_MODE, {
0065 .tv_enc_mode = { 720, 480, 59940, {
0066 0x21, 0xe6, 0xef, 0xe3, 0x0, 0x0, 0xb, 0x18,
0067 0x7e, 0x44, 0x76, 0x32, 0x25, 0x0, 0x3c, 0x0,
0068 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83,
0069 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
0070 0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5,
0071 0x0, 0x18, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0,
0072 0x0, 0xb4, 0x0, 0x15, 0x40, 0x10, 0x0, 0x9c,
0073 0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
0074 } } } },
0075
0076 [TV_NORM_PAL_N] = { TV_ENC_MODE, {
0077 .tv_enc_mode = { 720, 576, 50000, {
0078 0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18,
0079 0x7e, 0x40, 0x8a, 0x32, 0x25, 0x0, 0x3c, 0x0,
0080 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c,
0081 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
0082 0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5,
0083 0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0,
0084 0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b,
0085 0xbd, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
0086 } } } },
0087
0088 [TV_NORM_PAL_NC] = { TV_ENC_MODE, {
0089 .tv_enc_mode = { 720, 576, 50000, {
0090 0x21, 0xf6, 0x94, 0x46, 0x0, 0x0, 0xb, 0x18,
0091 0x7e, 0x44, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3,
0092 0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c,
0093 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3,
0094 0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5,
0095 0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0,
0096 0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b,
0097 0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0
0098 } } } },
0099
0100 [TV_NORM_NTSC_M] = { TV_ENC_MODE, {
0101 .tv_enc_mode = { 720, 480, 59940, {
0102 0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18,
0103 0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x3c, 0x0,
0104 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83,
0105 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
0106 0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5,
0107 0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0,
0108 0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0x9c,
0109 0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
0110 } } } },
0111
0112 [TV_NORM_NTSC_J] = { TV_ENC_MODE, {
0113 .tv_enc_mode = { 720, 480, 59940, {
0114 0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18,
0115 0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x32, 0x0,
0116 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83,
0117 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
0118 0xcf, 0x4, 0xcf, 0x1, 0x2, 0x0, 0xa, 0x5,
0119 0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0,
0120 0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0xa4,
0121 0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
0122 } } } },
0123
0124 [TV_NORM_HD480I] = { TV_ENC_MODE, {
0125 .tv_enc_mode = { 720, 480, 59940, {
0126 0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18,
0127 0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x32, 0x0,
0128 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83,
0129 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
0130 0xcf, 0x4, 0xcf, 0x1, 0x2, 0x0, 0xa, 0x5,
0131 0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0,
0132 0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0xa4,
0133 0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
0134 } } } },
0135
0136 [TV_NORM_HD576I] = { TV_ENC_MODE, {
0137 .tv_enc_mode = { 720, 576, 50000, {
0138 0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18,
0139 0x7e, 0x40, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3,
0140 0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c,
0141 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3,
0142 0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5,
0143 0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0,
0144 0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b,
0145 0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0
0146 } } } },
0147
0148
0149 [TV_NORM_HD480P] = { CTV_ENC_MODE, {
0150 .ctv_enc_mode = {
0151 .mode = { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000,
0152 720, 735, 743, 858, 0, 480, 490, 494, 525, 0,
0153 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0154 .ctv_regs = { 0x3540000, 0x0, 0x0, 0x314,
0155 0x354003a, 0x40000, 0x6f0344, 0x18100000,
0156 0x10160004, 0x10060005, 0x1006000c, 0x10060020,
0157 0x10060021, 0x140e0022, 0x10060202, 0x1802020a,
0158 0x1810020b, 0x10000fff, 0x10000fff, 0x10000fff,
0159 0x10000fff, 0x10000fff, 0x10000fff, 0x70,
0160 0x3ff0000, 0x57, 0x2e001e, 0x258012c,
0161 0xa0aa04ec, 0x30, 0x80960019, 0x12c0300,
0162 0x2019, 0x600, 0x32060019, 0x0, 0x0, 0x400
0163 } } } },
0164
0165 [TV_NORM_HD576P] = { CTV_ENC_MODE, {
0166 .ctv_enc_mode = {
0167 .mode = { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000,
0168 720, 730, 738, 864, 0, 576, 581, 585, 625, 0,
0169 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0170 .ctv_regs = { 0x3540000, 0x0, 0x0, 0x314,
0171 0x354003a, 0x40000, 0x6f0344, 0x18100000,
0172 0x10060001, 0x10060009, 0x10060026, 0x10060027,
0173 0x140e0028, 0x10060268, 0x1810026d, 0x10000fff,
0174 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff,
0175 0x10000fff, 0x10000fff, 0x10000fff, 0x69,
0176 0x3ff0000, 0x57, 0x2e001e, 0x258012c,
0177 0xa0aa04ec, 0x30, 0x80960019, 0x12c0300,
0178 0x2019, 0x600, 0x32060019, 0x0, 0x0, 0x400
0179 } } } },
0180
0181 [TV_NORM_HD720P] = { CTV_ENC_MODE, {
0182 .ctv_enc_mode = {
0183 .mode = { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250,
0184 1280, 1349, 1357, 1650, 0, 720, 725, 730, 750, 0,
0185 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0186 .ctv_regs = { 0x1260394, 0x0, 0x0, 0x622,
0187 0x66b0021, 0x6004a, 0x1210626, 0x8170000,
0188 0x70004, 0x70016, 0x70017, 0x40f0018,
0189 0x702e8, 0x81702ed, 0xfff, 0xfff,
0190 0xfff, 0xfff, 0xfff, 0xfff,
0191 0xfff, 0xfff, 0xfff, 0x0,
0192 0x2e40001, 0x58, 0x2e001e, 0x258012c,
0193 0xa0aa04ec, 0x30, 0x810c0039, 0x12c0300,
0194 0xc0002039, 0x600, 0x32060039, 0x0, 0x0, 0x0
0195 } } } },
0196
0197 [TV_NORM_HD1080I] = { CTV_ENC_MODE, {
0198 .ctv_enc_mode = {
0199 .mode = { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250,
0200 1920, 1961, 2049, 2200, 0, 1080, 1084, 1088, 1125, 0,
0201 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC
0202 | DRM_MODE_FLAG_INTERLACE) },
0203 .ctv_regs = { 0xac0420, 0x44c0478, 0x4a4, 0x4fc0868,
0204 0x8940028, 0x60054, 0xe80870, 0xbf70000,
0205 0xbc70004, 0x70005, 0x70012, 0x70013,
0206 0x40f0014, 0x70230, 0xbf70232, 0xbf70233,
0207 0x1c70237, 0x70238, 0x70244, 0x70245,
0208 0x40f0246, 0x70462, 0x1f70464, 0x0,
0209 0x2e40001, 0x58, 0x2e001e, 0x258012c,
0210 0xa0aa04ec, 0x30, 0x815f004c, 0x12c0300,
0211 0xc000204c, 0x600, 0x3206004c, 0x0, 0x0, 0x0
0212 } } } }
0213 };
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248 #define calc_overscan(o) interpolate(0x100, 0xe1, 0xc1, o)
0249
0250 #define id1 (1LL << 8)
0251 #define id2 (1LL << 16)
0252 #define id3 (1LL << 24)
0253 #define id4 (1LL << 32)
0254 #define id5 (1LL << 48)
0255
0256 static struct filter_params{
0257 int64_t k1;
0258 int64_t ki;
0259 int64_t ki2;
0260 int64_t ki3;
0261 int64_t kr;
0262 int64_t kir;
0263 int64_t ki2r;
0264 int64_t ki3r;
0265 int64_t kf;
0266 int64_t kif;
0267 int64_t ki2f;
0268 int64_t ki3f;
0269 int64_t krf;
0270 int64_t kirf;
0271 int64_t ki2rf;
0272 int64_t ki3rf;
0273 } fparams[2][4] = {
0274
0275 {
0276 {64.311690 * id5, -39.516924 * id5, 6.586143 * id5, 0.000002 * id5,
0277 0.051285 * id4, 26.168746 * id4, -4.361449 * id4, -0.000001 * id4,
0278 9.308169 * id3, 78.180965 * id3, -13.030158 * id3, -0.000001 * id3,
0279 -8.801540 * id1, -46.572890 * id1, 7.762145 * id1, -0.000000 * id1},
0280 {-44.565569 * id5, -68.081246 * id5, 39.812074 * id5, -4.009316 * id5,
0281 29.832207 * id4, 50.047322 * id4, -25.380017 * id4, 2.546422 * id4,
0282 104.605622 * id3, 141.908641 * id3, -74.322319 * id3, 7.484316 * id3,
0283 -37.081621 * id1, -90.397510 * id1, 42.784229 * id1, -4.289952 * id1},
0284 {-56.793244 * id5, 31.153584 * id5, -5.192247 * id5, -0.000003 * id5,
0285 33.541131 * id4, -34.149302 * id4, 5.691537 * id4, 0.000002 * id4,
0286 87.196610 * id3, -88.995169 * id3, 14.832456 * id3, 0.000012 * id3,
0287 17.288138 * id1, 71.864786 * id1, -11.977408 * id1, -0.000009 * id1},
0288 {51.787796 * id5, 21.211771 * id5, -18.993730 * id5, 1.853310 * id5,
0289 -41.470726 * id4, -17.775823 * id4, 13.057821 * id4, -1.15823 * id4,
0290 -154.235673 * id3, -44.878641 * id3, 40.656077 * id3, -3.695595 * id3,
0291 112.201065 * id1, 39.992155 * id1, -25.155714 * id1, 2.113984 * id1},
0292 },
0293
0294
0295 {
0296 {67.601979 * id5, 0.428319 * id5, -0.071318 * id5, -0.000012 * id5,
0297 -3.402339 * id4, 0.000209 * id4, -0.000092 * id4, 0.000010 * id4,
0298 -9.180996 * id3, 6.111270 * id3, -1.024457 * id3, 0.001043 * id3,
0299 6.060315 * id1, -0.017425 * id1, 0.007830 * id1, -0.000869 * id1},
0300 {6.755647 * id5, 5.841348 * id5, 1.469734 * id5, -0.149656 * id5,
0301 8.293120 * id4, -1.192888 * id4, -0.947652 * id4, 0.094507 * id4,
0302 37.526655 * id3, 10.257875 * id3, -10.823275 * id3, 1.081497 * id3,
0303 -2.361928 * id1, -2.059432 * id1, 1.840671 * id1, -0.168100 * id1},
0304 {-14.780391 * id5, -16.042148 * id5, 2.673692 * id5, -0.000000 * id5,
0305 39.541978 * id4, 5.680053 * id4, -0.946676 * id4, 0.000000 * id4,
0306 152.994486 * id3, 12.625439 * id3, -2.119579 * id3, 0.002708 * id3,
0307 -38.125089 * id1, -0.855880 * id1, 0.155359 * id1, -0.002245 * id1},
0308 {-27.476193 * id5, -1.454976 * id5, 1.286557 * id5, 0.025346 * id5,
0309 20.687300 * id4, 3.014003 * id4, -0.557786 * id4, -0.01311 * id4,
0310 60.008737 * id3, -0.738273 * id3, 5.408217 * id3, -0.796798 * id3,
0311 -17.296835 * id1, 4.438577 * id1, -2.809420 * id1, 0.385491 * id1},
0312 }
0313 };
0314
0315 static void tv_setup_filter(struct drm_encoder *encoder)
0316 {
0317 struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
0318 struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
0319 struct drm_display_mode *mode = &encoder->crtc->mode;
0320 uint32_t (*filters[])[4][7] = {&tv_enc->state.hfilter,
0321 &tv_enc->state.vfilter};
0322 int i, j, k;
0323 int32_t overscan = calc_overscan(tv_enc->overscan);
0324 int64_t flicker = (tv_enc->flicker - 50) * (id3 / 100);
0325 uint64_t rs[] = {mode->hdisplay * id3,
0326 mode->vdisplay * id3};
0327
0328 do_div(rs[0], overscan * tv_norm->tv_enc_mode.hdisplay);
0329 do_div(rs[1], overscan * tv_norm->tv_enc_mode.vdisplay);
0330
0331 for (k = 0; k < 2; k++) {
0332 rs[k] = max((int64_t)rs[k], id2);
0333
0334 for (j = 0; j < 4; j++) {
0335 struct filter_params *p = &fparams[k][j];
0336
0337 for (i = 0; i < 7; i++) {
0338 int64_t c = (p->k1 + p->ki*i + p->ki2*i*i +
0339 p->ki3*i*i*i)
0340 + (p->kr + p->kir*i + p->ki2r*i*i +
0341 p->ki3r*i*i*i) * rs[k]
0342 + (p->kf + p->kif*i + p->ki2f*i*i +
0343 p->ki3f*i*i*i) * flicker
0344 + (p->krf + p->kirf*i + p->ki2rf*i*i +
0345 p->ki3rf*i*i*i) * flicker * rs[k];
0346
0347 (*filters[k])[j][i] = (c + id5/2) >> 39
0348 & (0x1 << 31 | 0x7f << 9);
0349 }
0350 }
0351 }
0352 }
0353
0354
0355
0356 static void tv_save_filter(struct drm_device *dev, uint32_t base,
0357 uint32_t regs[4][7])
0358 {
0359 int i, j;
0360 uint32_t offsets[] = { base, base + 0x1c, base + 0x40, base + 0x5c };
0361
0362 for (i = 0; i < 4; i++) {
0363 for (j = 0; j < 7; j++)
0364 regs[i][j] = nv_read_ptv(dev, offsets[i]+4*j);
0365 }
0366 }
0367
0368 static void tv_load_filter(struct drm_device *dev, uint32_t base,
0369 uint32_t regs[4][7])
0370 {
0371 int i, j;
0372 uint32_t offsets[] = { base, base + 0x1c, base + 0x40, base + 0x5c };
0373
0374 for (i = 0; i < 4; i++) {
0375 for (j = 0; j < 7; j++)
0376 nv_write_ptv(dev, offsets[i]+4*j, regs[i][j]);
0377 }
0378 }
0379
0380 void nv17_tv_state_save(struct drm_device *dev, struct nv17_tv_state *state)
0381 {
0382 int i;
0383
0384 for (i = 0; i < 0x40; i++)
0385 state->tv_enc[i] = nv_read_tv_enc(dev, i);
0386
0387 tv_save_filter(dev, NV_PTV_HFILTER, state->hfilter);
0388 tv_save_filter(dev, NV_PTV_HFILTER2, state->hfilter2);
0389 tv_save_filter(dev, NV_PTV_VFILTER, state->vfilter);
0390
0391 nv_save_ptv(dev, state, 200);
0392 nv_save_ptv(dev, state, 204);
0393 nv_save_ptv(dev, state, 208);
0394 nv_save_ptv(dev, state, 20c);
0395 nv_save_ptv(dev, state, 304);
0396 nv_save_ptv(dev, state, 500);
0397 nv_save_ptv(dev, state, 504);
0398 nv_save_ptv(dev, state, 508);
0399 nv_save_ptv(dev, state, 600);
0400 nv_save_ptv(dev, state, 604);
0401 nv_save_ptv(dev, state, 608);
0402 nv_save_ptv(dev, state, 60c);
0403 nv_save_ptv(dev, state, 610);
0404 nv_save_ptv(dev, state, 614);
0405 }
0406
0407 void nv17_tv_state_load(struct drm_device *dev, struct nv17_tv_state *state)
0408 {
0409 int i;
0410
0411 for (i = 0; i < 0x40; i++)
0412 nv_write_tv_enc(dev, i, state->tv_enc[i]);
0413
0414 tv_load_filter(dev, NV_PTV_HFILTER, state->hfilter);
0415 tv_load_filter(dev, NV_PTV_HFILTER2, state->hfilter2);
0416 tv_load_filter(dev, NV_PTV_VFILTER, state->vfilter);
0417
0418 nv_load_ptv(dev, state, 200);
0419 nv_load_ptv(dev, state, 204);
0420 nv_load_ptv(dev, state, 208);
0421 nv_load_ptv(dev, state, 20c);
0422 nv_load_ptv(dev, state, 304);
0423 nv_load_ptv(dev, state, 500);
0424 nv_load_ptv(dev, state, 504);
0425 nv_load_ptv(dev, state, 508);
0426 nv_load_ptv(dev, state, 600);
0427 nv_load_ptv(dev, state, 604);
0428 nv_load_ptv(dev, state, 608);
0429 nv_load_ptv(dev, state, 60c);
0430 nv_load_ptv(dev, state, 610);
0431 nv_load_ptv(dev, state, 614);
0432
0433
0434 nv_write_tv_enc(dev, 0x3e, 1);
0435 nv_write_tv_enc(dev, 0x3e, 0);
0436 }
0437
0438
0439
0440 const struct drm_display_mode nv17_tv_modes[] = {
0441 { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 0,
0442 320, 344, 392, 560, 0, 200, 200, 202, 220, 0,
0443 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC
0444 | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) },
0445 { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 0,
0446 320, 344, 392, 560, 0, 240, 240, 246, 263, 0,
0447 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC
0448 | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) },
0449 { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 0,
0450 400, 432, 496, 640, 0, 300, 300, 303, 314, 0,
0451 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC
0452 | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) },
0453 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 0,
0454 640, 672, 768, 880, 0, 480, 480, 492, 525, 0,
0455 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0456 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 0,
0457 720, 752, 872, 960, 0, 480, 480, 493, 525, 0,
0458 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0459 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 0,
0460 720, 776, 856, 960, 0, 576, 576, 588, 597, 0,
0461 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0462 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 0,
0463 800, 840, 920, 1040, 0, 600, 600, 604, 618, 0,
0464 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
0465 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 0,
0466 1024, 1064, 1200, 1344, 0, 768, 768, 777, 806, 0,
0467 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
0468 {}
0469 };
0470
0471 void nv17_tv_update_properties(struct drm_encoder *encoder)
0472 {
0473 struct drm_device *dev = encoder->dev;
0474 struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
0475 struct nv17_tv_state *regs = &tv_enc->state;
0476 struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
0477 int subconnector = tv_enc->select_subconnector ?
0478 tv_enc->select_subconnector :
0479 tv_enc->subconnector;
0480
0481 switch (subconnector) {
0482 case DRM_MODE_SUBCONNECTOR_Composite:
0483 {
0484 regs->ptv_204 = 0x2;
0485
0486
0487 if (tv_enc->pin_mask & 0x4)
0488 regs->ptv_204 |= 0x010000;
0489 else if (tv_enc->pin_mask & 0x2)
0490 regs->ptv_204 |= 0x100000;
0491 else
0492 regs->ptv_204 |= 0x110000;
0493
0494 regs->tv_enc[0x7] = 0x10;
0495 break;
0496 }
0497 case DRM_MODE_SUBCONNECTOR_SVIDEO:
0498 regs->ptv_204 = 0x11012;
0499 regs->tv_enc[0x7] = 0x18;
0500 break;
0501
0502 case DRM_MODE_SUBCONNECTOR_Component:
0503 regs->ptv_204 = 0x111333;
0504 regs->tv_enc[0x7] = 0x14;
0505 break;
0506
0507 case DRM_MODE_SUBCONNECTOR_SCART:
0508 regs->ptv_204 = 0x111012;
0509 regs->tv_enc[0x7] = 0x18;
0510 break;
0511 }
0512
0513 regs->tv_enc[0x20] = interpolate(0, tv_norm->tv_enc_mode.tv_enc[0x20],
0514 255, tv_enc->saturation);
0515 regs->tv_enc[0x22] = interpolate(0, tv_norm->tv_enc_mode.tv_enc[0x22],
0516 255, tv_enc->saturation);
0517 regs->tv_enc[0x25] = tv_enc->hue * 255 / 100;
0518
0519 nv_load_ptv(dev, regs, 204);
0520 nv_load_tv_enc(dev, regs, 7);
0521 nv_load_tv_enc(dev, regs, 20);
0522 nv_load_tv_enc(dev, regs, 22);
0523 nv_load_tv_enc(dev, regs, 25);
0524 }
0525
0526 void nv17_tv_update_rescaler(struct drm_encoder *encoder)
0527 {
0528 struct drm_device *dev = encoder->dev;
0529 struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
0530 struct nv17_tv_state *regs = &tv_enc->state;
0531
0532 regs->ptv_208 = 0x40 | (calc_overscan(tv_enc->overscan) << 8);
0533
0534 tv_setup_filter(encoder);
0535
0536 nv_load_ptv(dev, regs, 208);
0537 tv_load_filter(dev, NV_PTV_HFILTER, regs->hfilter);
0538 tv_load_filter(dev, NV_PTV_HFILTER2, regs->hfilter2);
0539 tv_load_filter(dev, NV_PTV_VFILTER, regs->vfilter);
0540 }
0541
0542 void nv17_ctv_update_rescaler(struct drm_encoder *encoder)
0543 {
0544 struct drm_device *dev = encoder->dev;
0545 struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
0546 int head = nouveau_crtc(encoder->crtc)->index;
0547 struct nv04_crtc_reg *regs = &nv04_display(dev)->mode_reg.crtc_reg[head];
0548 struct drm_display_mode *crtc_mode = &encoder->crtc->mode;
0549 struct drm_display_mode *output_mode =
0550 &get_tv_norm(encoder)->ctv_enc_mode.mode;
0551 int overscan, hmargin, vmargin, hratio, vratio;
0552
0553
0554 if (output_mode->flags & DRM_MODE_FLAG_INTERLACE)
0555 overscan = 100;
0556 else
0557 overscan = tv_enc->overscan;
0558
0559 hmargin = (output_mode->hdisplay - crtc_mode->hdisplay) / 2;
0560 vmargin = (output_mode->vdisplay - crtc_mode->vdisplay) / 2;
0561
0562 hmargin = interpolate(0, min(hmargin, output_mode->hdisplay/20),
0563 hmargin, overscan);
0564 vmargin = interpolate(0, min(vmargin, output_mode->vdisplay/20),
0565 vmargin, overscan);
0566
0567 hratio = crtc_mode->hdisplay * 0x800 /
0568 (output_mode->hdisplay - 2*hmargin);
0569 vratio = crtc_mode->vdisplay * 0x800 /
0570 (output_mode->vdisplay - 2*vmargin) & ~3;
0571
0572 regs->fp_horiz_regs[FP_VALID_START] = hmargin;
0573 regs->fp_horiz_regs[FP_VALID_END] = output_mode->hdisplay - hmargin - 1;
0574 regs->fp_vert_regs[FP_VALID_START] = vmargin;
0575 regs->fp_vert_regs[FP_VALID_END] = output_mode->vdisplay - vmargin - 1;
0576
0577 regs->fp_debug_1 = NV_PRAMDAC_FP_DEBUG_1_YSCALE_TESTMODE_ENABLE |
0578 XLATE(vratio, 0, NV_PRAMDAC_FP_DEBUG_1_YSCALE_VALUE) |
0579 NV_PRAMDAC_FP_DEBUG_1_XSCALE_TESTMODE_ENABLE |
0580 XLATE(hratio, 0, NV_PRAMDAC_FP_DEBUG_1_XSCALE_VALUE);
0581
0582 NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HVALID_START,
0583 regs->fp_horiz_regs[FP_VALID_START]);
0584 NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HVALID_END,
0585 regs->fp_horiz_regs[FP_VALID_END]);
0586 NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_VVALID_START,
0587 regs->fp_vert_regs[FP_VALID_START]);
0588 NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_VVALID_END,
0589 regs->fp_vert_regs[FP_VALID_END]);
0590 NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_1, regs->fp_debug_1);
0591 }