root/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nv42_tv_sample_load
  2. get_tv_detect_quirks
  3. nv17_tv_detect
  4. nv17_tv_get_ld_modes
  5. nv17_tv_get_hd_modes
  6. nv17_tv_get_modes
  7. nv17_tv_mode_valid
  8. nv17_tv_mode_fixup
  9. nv17_tv_dpms
  10. nv17_tv_prepare
  11. nv17_tv_mode_set
  12. nv17_tv_commit
  13. nv17_tv_save
  14. nv17_tv_restore
  15. nv17_tv_create_resources
  16. nv17_tv_set_property
  17. nv17_tv_destroy
  18. nv17_tv_create

   1 /*
   2  * Copyright (C) 2009 Francisco Jerez.
   3  * All Rights Reserved.
   4  *
   5  * Permission is hereby granted, free of charge, to any person obtaining
   6  * a copy of this software and associated documentation files (the
   7  * "Software"), to deal in the Software without restriction, including
   8  * without limitation the rights to use, copy, modify, merge, publish,
   9  * distribute, sublicense, and/or sell copies of the Software, and to
  10  * permit persons to whom the Software is furnished to do so, subject to
  11  * the following conditions:
  12  *
  13  * The above copyright notice and this permission notice (including the
  14  * next paragraph) shall be included in all copies or substantial
  15  * portions of the Software.
  16  *
  17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  20  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
  21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24  *
  25  */
  26 
  27 #include <drm/drm_crtc_helper.h>
  28 #include <drm/drm_probe_helper.h>
  29 #include "nouveau_drv.h"
  30 #include "nouveau_reg.h"
  31 #include "nouveau_encoder.h"
  32 #include "nouveau_connector.h"
  33 #include "nouveau_crtc.h"
  34 #include "hw.h"
  35 #include "tvnv17.h"
  36 
  37 MODULE_PARM_DESC(tv_norm, "Default TV norm.\n"
  38                  "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n"
  39                  "\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n"
  40                  "\t\tDefault: PAL\n"
  41                  "\t\t*NOTE* Ignored for cards with external TV encoders.");
  42 static char *nouveau_tv_norm;
  43 module_param_named(tv_norm, nouveau_tv_norm, charp, 0400);
  44 
  45 static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder)
  46 {
  47         struct drm_device *dev = encoder->dev;
  48         struct nouveau_drm *drm = nouveau_drm(dev);
  49         struct nvkm_gpio *gpio = nvxx_gpio(&drm->client.device);
  50         uint32_t testval, regoffset = nv04_dac_output_offset(encoder);
  51         uint32_t gpio0, gpio1, fp_htotal, fp_hsync_start, fp_hsync_end,
  52                 fp_control, test_ctrl, dacclk, ctv_14, ctv_1c, ctv_6c;
  53         uint32_t sample = 0;
  54         int head;
  55 
  56 #define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20)
  57         testval = RGB_TEST_DATA(0x82, 0xeb, 0x82);
  58         if (drm->vbios.tvdactestval)
  59                 testval = drm->vbios.tvdactestval;
  60 
  61         dacclk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset);
  62         head = (dacclk & 0x100) >> 8;
  63 
  64         /* Save the previous state. */
  65         gpio1 = nvkm_gpio_get(gpio, 0, DCB_GPIO_TVDAC1, 0xff);
  66         gpio0 = nvkm_gpio_get(gpio, 0, DCB_GPIO_TVDAC0, 0xff);
  67         fp_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL);
  68         fp_hsync_start = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START);
  69         fp_hsync_end = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END);
  70         fp_control = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL);
  71         test_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset);
  72         ctv_1c = NVReadRAMDAC(dev, head, 0x680c1c);
  73         ctv_14 = NVReadRAMDAC(dev, head, 0x680c14);
  74         ctv_6c = NVReadRAMDAC(dev, head, 0x680c6c);
  75 
  76         /* Prepare the DAC for load detection.  */
  77         nvkm_gpio_set(gpio, 0, DCB_GPIO_TVDAC1, 0xff, true);
  78         nvkm_gpio_set(gpio, 0, DCB_GPIO_TVDAC0, 0xff, true);
  79 
  80         NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, 1343);
  81         NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, 1047);
  82         NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, 1183);
  83         NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL,
  84                       NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS |
  85                       NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12 |
  86                       NV_PRAMDAC_FP_TG_CONTROL_READ_PROG |
  87                       NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS |
  88                       NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS);
  89 
  90         NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, 0);
  91 
  92         NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset,
  93                       (dacclk & ~0xff) | 0x22);
  94         msleep(1);
  95         NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset,
  96                       (dacclk & ~0xff) | 0x21);
  97 
  98         NVWriteRAMDAC(dev, head, 0x680c1c, 1 << 20);
  99         NVWriteRAMDAC(dev, head, 0x680c14, 4 << 16);
 100 
 101         /* Sample pin 0x4 (usually S-video luma). */
 102         NVWriteRAMDAC(dev, head, 0x680c6c, testval >> 10 & 0x3ff);
 103         msleep(20);
 104         sample |= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset)
 105                 & 0x4 << 28;
 106 
 107         /* Sample the remaining pins. */
 108         NVWriteRAMDAC(dev, head, 0x680c6c, testval & 0x3ff);
 109         msleep(20);
 110         sample |= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset)
 111                 & 0xa << 28;
 112 
 113         /* Restore the previous state. */
 114         NVWriteRAMDAC(dev, head, 0x680c1c, ctv_1c);
 115         NVWriteRAMDAC(dev, head, 0x680c14, ctv_14);
 116         NVWriteRAMDAC(dev, head, 0x680c6c, ctv_6c);
 117         NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, dacclk);
 118         NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, test_ctrl);
 119         NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, fp_control);
 120         NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, fp_hsync_end);
 121         NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, fp_hsync_start);
 122         NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, fp_htotal);
 123         nvkm_gpio_set(gpio, 0, DCB_GPIO_TVDAC1, 0xff, gpio1);
 124         nvkm_gpio_set(gpio, 0, DCB_GPIO_TVDAC0, 0xff, gpio0);
 125 
 126         return sample;
 127 }
 128 
 129 static bool
 130 get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask)
 131 {
 132         struct nouveau_drm *drm = nouveau_drm(dev);
 133         struct nvkm_device *device = nvxx_device(&drm->client.device);
 134 
 135         if (device->quirk && device->quirk->tv_pin_mask) {
 136                 *pin_mask = device->quirk->tv_pin_mask;
 137                 return false;
 138         }
 139 
 140         return true;
 141 }
 142 
 143 static enum drm_connector_status
 144 nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector)
 145 {
 146         struct drm_device *dev = encoder->dev;
 147         struct nouveau_drm *drm = nouveau_drm(dev);
 148         struct drm_mode_config *conf = &dev->mode_config;
 149         struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
 150         struct dcb_output *dcb = tv_enc->base.dcb;
 151         bool reliable = get_tv_detect_quirks(dev, &tv_enc->pin_mask);
 152 
 153         if (nv04_dac_in_use(encoder))
 154                 return connector_status_disconnected;
 155 
 156         if (reliable) {
 157                 if (drm->client.device.info.chipset == 0x42 ||
 158                     drm->client.device.info.chipset == 0x43)
 159                         tv_enc->pin_mask =
 160                                 nv42_tv_sample_load(encoder) >> 28 & 0xe;
 161                 else
 162                         tv_enc->pin_mask =
 163                                 nv17_dac_sample_load(encoder) >> 28 & 0xe;
 164         }
 165 
 166         switch (tv_enc->pin_mask) {
 167         case 0x2:
 168         case 0x4:
 169                 tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Composite;
 170                 break;
 171         case 0xc:
 172                 tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SVIDEO;
 173                 break;
 174         case 0xe:
 175                 if (dcb->tvconf.has_component_output)
 176                         tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Component;
 177                 else
 178                         tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SCART;
 179                 break;
 180         default:
 181                 tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Unknown;
 182                 break;
 183         }
 184 
 185         drm_object_property_set_value(&connector->base,
 186                                          conf->tv_subconnector_property,
 187                                          tv_enc->subconnector);
 188 
 189         if (!reliable) {
 190                 return connector_status_unknown;
 191         } else if (tv_enc->subconnector) {
 192                 NV_INFO(drm, "Load detected on output %c\n",
 193                         '@' + ffs(dcb->or));
 194                 return connector_status_connected;
 195         } else {
 196                 return connector_status_disconnected;
 197         }
 198 }
 199 
 200 static int nv17_tv_get_ld_modes(struct drm_encoder *encoder,
 201                                 struct drm_connector *connector)
 202 {
 203         struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
 204         const struct drm_display_mode *tv_mode;
 205         int n = 0;
 206 
 207         for (tv_mode = nv17_tv_modes; tv_mode->hdisplay; tv_mode++) {
 208                 struct drm_display_mode *mode;
 209 
 210                 mode = drm_mode_duplicate(encoder->dev, tv_mode);
 211 
 212                 mode->clock = tv_norm->tv_enc_mode.vrefresh *
 213                         mode->htotal / 1000 *
 214                         mode->vtotal / 1000;
 215 
 216                 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 217                         mode->clock *= 2;
 218 
 219                 if (mode->hdisplay == tv_norm->tv_enc_mode.hdisplay &&
 220                     mode->vdisplay == tv_norm->tv_enc_mode.vdisplay)
 221                         mode->type |= DRM_MODE_TYPE_PREFERRED;
 222 
 223                 drm_mode_probed_add(connector, mode);
 224                 n++;
 225         }
 226 
 227         return n;
 228 }
 229 
 230 static int nv17_tv_get_hd_modes(struct drm_encoder *encoder,
 231                                 struct drm_connector *connector)
 232 {
 233         struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
 234         struct drm_display_mode *output_mode = &tv_norm->ctv_enc_mode.mode;
 235         struct drm_display_mode *mode;
 236         const struct {
 237                 int hdisplay;
 238                 int vdisplay;
 239         } modes[] = {
 240                 { 640, 400 },
 241                 { 640, 480 },
 242                 { 720, 480 },
 243                 { 720, 576 },
 244                 { 800, 600 },
 245                 { 1024, 768 },
 246                 { 1280, 720 },
 247                 { 1280, 1024 },
 248                 { 1920, 1080 }
 249         };
 250         int i, n = 0;
 251 
 252         for (i = 0; i < ARRAY_SIZE(modes); i++) {
 253                 if (modes[i].hdisplay > output_mode->hdisplay ||
 254                     modes[i].vdisplay > output_mode->vdisplay)
 255                         continue;
 256 
 257                 if (modes[i].hdisplay == output_mode->hdisplay &&
 258                     modes[i].vdisplay == output_mode->vdisplay) {
 259                         mode = drm_mode_duplicate(encoder->dev, output_mode);
 260                         mode->type |= DRM_MODE_TYPE_PREFERRED;
 261 
 262                 } else {
 263                         mode = drm_cvt_mode(encoder->dev, modes[i].hdisplay,
 264                                             modes[i].vdisplay, 60, false,
 265                                             (output_mode->flags &
 266                                              DRM_MODE_FLAG_INTERLACE), false);
 267                 }
 268 
 269                 /* CVT modes are sometimes unsuitable... */
 270                 if (output_mode->hdisplay <= 720
 271                     || output_mode->hdisplay >= 1920) {
 272                         mode->htotal = output_mode->htotal;
 273                         mode->hsync_start = (mode->hdisplay + (mode->htotal
 274                                              - mode->hdisplay) * 9 / 10) & ~7;
 275                         mode->hsync_end = mode->hsync_start + 8;
 276                 }
 277 
 278                 if (output_mode->vdisplay >= 1024) {
 279                         mode->vtotal = output_mode->vtotal;
 280                         mode->vsync_start = output_mode->vsync_start;
 281                         mode->vsync_end = output_mode->vsync_end;
 282                 }
 283 
 284                 mode->type |= DRM_MODE_TYPE_DRIVER;
 285                 drm_mode_probed_add(connector, mode);
 286                 n++;
 287         }
 288 
 289         return n;
 290 }
 291 
 292 static int nv17_tv_get_modes(struct drm_encoder *encoder,
 293                              struct drm_connector *connector)
 294 {
 295         struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
 296 
 297         if (tv_norm->kind == CTV_ENC_MODE)
 298                 return nv17_tv_get_hd_modes(encoder, connector);
 299         else
 300                 return nv17_tv_get_ld_modes(encoder, connector);
 301 }
 302 
 303 static int nv17_tv_mode_valid(struct drm_encoder *encoder,
 304                               struct drm_display_mode *mode)
 305 {
 306         struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
 307 
 308         if (tv_norm->kind == CTV_ENC_MODE) {
 309                 struct drm_display_mode *output_mode =
 310                                                 &tv_norm->ctv_enc_mode.mode;
 311 
 312                 if (mode->clock > 400000)
 313                         return MODE_CLOCK_HIGH;
 314 
 315                 if (mode->hdisplay > output_mode->hdisplay ||
 316                     mode->vdisplay > output_mode->vdisplay)
 317                         return MODE_BAD;
 318 
 319                 if ((mode->flags & DRM_MODE_FLAG_INTERLACE) !=
 320                     (output_mode->flags & DRM_MODE_FLAG_INTERLACE))
 321                         return MODE_NO_INTERLACE;
 322 
 323                 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 324                         return MODE_NO_DBLESCAN;
 325 
 326         } else {
 327                 const int vsync_tolerance = 600;
 328 
 329                 if (mode->clock > 70000)
 330                         return MODE_CLOCK_HIGH;
 331 
 332                 if (abs(drm_mode_vrefresh(mode) * 1000 -
 333                         tv_norm->tv_enc_mode.vrefresh) > vsync_tolerance)
 334                         return MODE_VSYNC;
 335 
 336                 /* The encoder takes care of the actual interlacing */
 337                 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
 338                         return MODE_NO_INTERLACE;
 339         }
 340 
 341         return MODE_OK;
 342 }
 343 
 344 static bool nv17_tv_mode_fixup(struct drm_encoder *encoder,
 345                                const struct drm_display_mode *mode,
 346                                struct drm_display_mode *adjusted_mode)
 347 {
 348         struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
 349 
 350         if (nv04_dac_in_use(encoder))
 351                 return false;
 352 
 353         if (tv_norm->kind == CTV_ENC_MODE)
 354                 adjusted_mode->clock = tv_norm->ctv_enc_mode.mode.clock;
 355         else
 356                 adjusted_mode->clock = 90000;
 357 
 358         return true;
 359 }
 360 
 361 static void  nv17_tv_dpms(struct drm_encoder *encoder, int mode)
 362 {
 363         struct drm_device *dev = encoder->dev;
 364         struct nouveau_drm *drm = nouveau_drm(dev);
 365         struct nvkm_gpio *gpio = nvxx_gpio(&drm->client.device);
 366         struct nv17_tv_state *regs = &to_tv_enc(encoder)->state;
 367         struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
 368 
 369         if (nouveau_encoder(encoder)->last_dpms == mode)
 370                 return;
 371         nouveau_encoder(encoder)->last_dpms = mode;
 372 
 373         NV_INFO(drm, "Setting dpms mode %d on TV encoder (output %d)\n",
 374                  mode, nouveau_encoder(encoder)->dcb->index);
 375 
 376         regs->ptv_200 &= ~1;
 377 
 378         if (tv_norm->kind == CTV_ENC_MODE) {
 379                 nv04_dfp_update_fp_control(encoder, mode);
 380 
 381         } else {
 382                 nv04_dfp_update_fp_control(encoder, DRM_MODE_DPMS_OFF);
 383 
 384                 if (mode == DRM_MODE_DPMS_ON)
 385                         regs->ptv_200 |= 1;
 386         }
 387 
 388         nv_load_ptv(dev, regs, 200);
 389 
 390         nvkm_gpio_set(gpio, 0, DCB_GPIO_TVDAC1, 0xff, mode == DRM_MODE_DPMS_ON);
 391         nvkm_gpio_set(gpio, 0, DCB_GPIO_TVDAC0, 0xff, mode == DRM_MODE_DPMS_ON);
 392 
 393         nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON);
 394 }
 395 
 396 static void nv17_tv_prepare(struct drm_encoder *encoder)
 397 {
 398         struct drm_device *dev = encoder->dev;
 399         struct nouveau_drm *drm = nouveau_drm(dev);
 400         const struct drm_encoder_helper_funcs *helper = encoder->helper_private;
 401         struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
 402         int head = nouveau_crtc(encoder->crtc)->index;
 403         uint8_t *cr_lcd = &nv04_display(dev)->mode_reg.crtc_reg[head].CRTC[
 404                                                         NV_CIO_CRE_LCD__INDEX];
 405         uint32_t dacclk_off = NV_PRAMDAC_DACCLK +
 406                                         nv04_dac_output_offset(encoder);
 407         uint32_t dacclk;
 408 
 409         helper->dpms(encoder, DRM_MODE_DPMS_OFF);
 410 
 411         nv04_dfp_disable(dev, head);
 412 
 413         /* Unbind any FP encoders from this head if we need the FP
 414          * stuff enabled. */
 415         if (tv_norm->kind == CTV_ENC_MODE) {
 416                 struct drm_encoder *enc;
 417 
 418                 list_for_each_entry(enc, &dev->mode_config.encoder_list, head) {
 419                         struct dcb_output *dcb = nouveau_encoder(enc)->dcb;
 420 
 421                         if ((dcb->type == DCB_OUTPUT_TMDS ||
 422                              dcb->type == DCB_OUTPUT_LVDS) &&
 423                              !enc->crtc &&
 424                              nv04_dfp_get_bound_head(dev, dcb) == head) {
 425                                 nv04_dfp_bind_head(dev, dcb, head ^ 1,
 426                                                 drm->vbios.fp.dual_link);
 427                         }
 428                 }
 429 
 430         }
 431 
 432         if (tv_norm->kind == CTV_ENC_MODE)
 433                 *cr_lcd |= 0x1 | (head ? 0x0 : 0x8);
 434 
 435         /* Set the DACCLK register */
 436         dacclk = (NVReadRAMDAC(dev, 0, dacclk_off) & ~0x30) | 0x1;
 437 
 438         if (drm->client.device.info.family == NV_DEVICE_INFO_V0_CURIE)
 439                 dacclk |= 0x1a << 16;
 440 
 441         if (tv_norm->kind == CTV_ENC_MODE) {
 442                 dacclk |=  0x20;
 443 
 444                 if (head)
 445                         dacclk |= 0x100;
 446                 else
 447                         dacclk &= ~0x100;
 448 
 449         } else {
 450                 dacclk |= 0x10;
 451 
 452         }
 453 
 454         NVWriteRAMDAC(dev, 0, dacclk_off, dacclk);
 455 }
 456 
 457 static void nv17_tv_mode_set(struct drm_encoder *encoder,
 458                              struct drm_display_mode *drm_mode,
 459                              struct drm_display_mode *adjusted_mode)
 460 {
 461         struct drm_device *dev = encoder->dev;
 462         struct nouveau_drm *drm = nouveau_drm(dev);
 463         int head = nouveau_crtc(encoder->crtc)->index;
 464         struct nv04_crtc_reg *regs = &nv04_display(dev)->mode_reg.crtc_reg[head];
 465         struct nv17_tv_state *tv_regs = &to_tv_enc(encoder)->state;
 466         struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
 467         int i;
 468 
 469         regs->CRTC[NV_CIO_CRE_53] = 0x40; /* FP_HTIMING */
 470         regs->CRTC[NV_CIO_CRE_54] = 0; /* FP_VTIMING */
 471         regs->ramdac_630 = 0x2; /* turn off green mode (tv test pattern?) */
 472         regs->tv_setup = 1;
 473         regs->ramdac_8c0 = 0x0;
 474 
 475         if (tv_norm->kind == TV_ENC_MODE) {
 476                 tv_regs->ptv_200 = 0x13111100;
 477                 if (head)
 478                         tv_regs->ptv_200 |= 0x10;
 479 
 480                 tv_regs->ptv_20c = 0x808010;
 481                 tv_regs->ptv_304 = 0x2d00000;
 482                 tv_regs->ptv_600 = 0x0;
 483                 tv_regs->ptv_60c = 0x0;
 484                 tv_regs->ptv_610 = 0x1e00000;
 485 
 486                 if (tv_norm->tv_enc_mode.vdisplay == 576) {
 487                         tv_regs->ptv_508 = 0x1200000;
 488                         tv_regs->ptv_614 = 0x33;
 489 
 490                 } else if (tv_norm->tv_enc_mode.vdisplay == 480) {
 491                         tv_regs->ptv_508 = 0xf00000;
 492                         tv_regs->ptv_614 = 0x13;
 493                 }
 494 
 495                 if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_RANKINE) {
 496                         tv_regs->ptv_500 = 0xe8e0;
 497                         tv_regs->ptv_504 = 0x1710;
 498                         tv_regs->ptv_604 = 0x0;
 499                         tv_regs->ptv_608 = 0x0;
 500                 } else {
 501                         if (tv_norm->tv_enc_mode.vdisplay == 576) {
 502                                 tv_regs->ptv_604 = 0x20;
 503                                 tv_regs->ptv_608 = 0x10;
 504                                 tv_regs->ptv_500 = 0x19710;
 505                                 tv_regs->ptv_504 = 0x68f0;
 506 
 507                         } else if (tv_norm->tv_enc_mode.vdisplay == 480) {
 508                                 tv_regs->ptv_604 = 0x10;
 509                                 tv_regs->ptv_608 = 0x20;
 510                                 tv_regs->ptv_500 = 0x4b90;
 511                                 tv_regs->ptv_504 = 0x1b480;
 512                         }
 513                 }
 514 
 515                 for (i = 0; i < 0x40; i++)
 516                         tv_regs->tv_enc[i] = tv_norm->tv_enc_mode.tv_enc[i];
 517 
 518         } else {
 519                 struct drm_display_mode *output_mode =
 520                                                 &tv_norm->ctv_enc_mode.mode;
 521 
 522                 /* The registers in PRAMDAC+0xc00 control some timings and CSC
 523                  * parameters for the CTV encoder (It's only used for "HD" TV
 524                  * modes, I don't think I have enough working to guess what
 525                  * they exactly mean...), it's probably connected at the
 526                  * output of the FP encoder, but it also needs the analog
 527                  * encoder in its OR enabled and routed to the head it's
 528                  * using. It's enabled with the DACCLK register, bits [5:4].
 529                  */
 530                 for (i = 0; i < 38; i++)
 531                         regs->ctv_regs[i] = tv_norm->ctv_enc_mode.ctv_regs[i];
 532 
 533                 regs->fp_horiz_regs[FP_DISPLAY_END] = output_mode->hdisplay - 1;
 534                 regs->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1;
 535                 regs->fp_horiz_regs[FP_SYNC_START] =
 536                                                 output_mode->hsync_start - 1;
 537                 regs->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1;
 538                 regs->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay +
 539                         max((output_mode->hdisplay-600)/40 - 1, 1);
 540 
 541                 regs->fp_vert_regs[FP_DISPLAY_END] = output_mode->vdisplay - 1;
 542                 regs->fp_vert_regs[FP_TOTAL] = output_mode->vtotal - 1;
 543                 regs->fp_vert_regs[FP_SYNC_START] =
 544                                                 output_mode->vsync_start - 1;
 545                 regs->fp_vert_regs[FP_SYNC_END] = output_mode->vsync_end - 1;
 546                 regs->fp_vert_regs[FP_CRTC] = output_mode->vdisplay - 1;
 547 
 548                 regs->fp_control = NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS |
 549                         NV_PRAMDAC_FP_TG_CONTROL_READ_PROG |
 550                         NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12;
 551 
 552                 if (output_mode->flags & DRM_MODE_FLAG_PVSYNC)
 553                         regs->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS;
 554                 if (output_mode->flags & DRM_MODE_FLAG_PHSYNC)
 555                         regs->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS;
 556 
 557                 regs->fp_debug_0 = NV_PRAMDAC_FP_DEBUG_0_YWEIGHT_ROUND |
 558                         NV_PRAMDAC_FP_DEBUG_0_XWEIGHT_ROUND |
 559                         NV_PRAMDAC_FP_DEBUG_0_YINTERP_BILINEAR |
 560                         NV_PRAMDAC_FP_DEBUG_0_XINTERP_BILINEAR |
 561                         NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED |
 562                         NV_PRAMDAC_FP_DEBUG_0_YSCALE_ENABLE |
 563                         NV_PRAMDAC_FP_DEBUG_0_XSCALE_ENABLE;
 564 
 565                 regs->fp_debug_2 = 0;
 566 
 567                 regs->fp_margin_color = 0x801080;
 568 
 569         }
 570 }
 571 
 572 static void nv17_tv_commit(struct drm_encoder *encoder)
 573 {
 574         struct drm_device *dev = encoder->dev;
 575         struct nouveau_drm *drm = nouveau_drm(dev);
 576         struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
 577         struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
 578         const struct drm_encoder_helper_funcs *helper = encoder->helper_private;
 579 
 580         if (get_tv_norm(encoder)->kind == TV_ENC_MODE) {
 581                 nv17_tv_update_rescaler(encoder);
 582                 nv17_tv_update_properties(encoder);
 583         } else {
 584                 nv17_ctv_update_rescaler(encoder);
 585         }
 586 
 587         nv17_tv_state_load(dev, &to_tv_enc(encoder)->state);
 588 
 589         /* This could use refinement for flatpanels, but it should work */
 590         if (drm->client.device.info.chipset < 0x44)
 591                 NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL +
 592                                         nv04_dac_output_offset(encoder),
 593                                         0xf0000000);
 594         else
 595                 NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL +
 596                                         nv04_dac_output_offset(encoder),
 597                                         0x00100000);
 598 
 599         helper->dpms(encoder, DRM_MODE_DPMS_ON);
 600 
 601         NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n",
 602                 nouveau_encoder_connector_get(nv_encoder)->base.name,
 603                 nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
 604 }
 605 
 606 static void nv17_tv_save(struct drm_encoder *encoder)
 607 {
 608         struct drm_device *dev = encoder->dev;
 609         struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
 610 
 611         nouveau_encoder(encoder)->restore.output =
 612                                         NVReadRAMDAC(dev, 0,
 613                                         NV_PRAMDAC_DACCLK +
 614                                         nv04_dac_output_offset(encoder));
 615 
 616         nv17_tv_state_save(dev, &tv_enc->saved_state);
 617 
 618         tv_enc->state.ptv_200 = tv_enc->saved_state.ptv_200;
 619 }
 620 
 621 static void nv17_tv_restore(struct drm_encoder *encoder)
 622 {
 623         struct drm_device *dev = encoder->dev;
 624 
 625         NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK +
 626                                 nv04_dac_output_offset(encoder),
 627                                 nouveau_encoder(encoder)->restore.output);
 628 
 629         nv17_tv_state_load(dev, &to_tv_enc(encoder)->saved_state);
 630 
 631         nouveau_encoder(encoder)->last_dpms = NV_DPMS_CLEARED;
 632 }
 633 
 634 static int nv17_tv_create_resources(struct drm_encoder *encoder,
 635                                     struct drm_connector *connector)
 636 {
 637         struct drm_device *dev = encoder->dev;
 638         struct nouveau_drm *drm = nouveau_drm(dev);
 639         struct drm_mode_config *conf = &dev->mode_config;
 640         struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
 641         struct dcb_output *dcb = nouveau_encoder(encoder)->dcb;
 642         int num_tv_norms = dcb->tvconf.has_component_output ? NUM_TV_NORMS :
 643                                                         NUM_LD_TV_NORMS;
 644         int i;
 645 
 646         if (nouveau_tv_norm) {
 647                 for (i = 0; i < num_tv_norms; i++) {
 648                         if (!strcmp(nv17_tv_norm_names[i], nouveau_tv_norm)) {
 649                                 tv_enc->tv_norm = i;
 650                                 break;
 651                         }
 652                 }
 653 
 654                 if (i == num_tv_norms)
 655                         NV_WARN(drm, "Invalid TV norm setting \"%s\"\n",
 656                                 nouveau_tv_norm);
 657         }
 658 
 659         drm_mode_create_tv_properties(dev, num_tv_norms, nv17_tv_norm_names);
 660 
 661         drm_object_attach_property(&connector->base,
 662                                         conf->tv_select_subconnector_property,
 663                                         tv_enc->select_subconnector);
 664         drm_object_attach_property(&connector->base,
 665                                         conf->tv_subconnector_property,
 666                                         tv_enc->subconnector);
 667         drm_object_attach_property(&connector->base,
 668                                         conf->tv_mode_property,
 669                                         tv_enc->tv_norm);
 670         drm_object_attach_property(&connector->base,
 671                                         conf->tv_flicker_reduction_property,
 672                                         tv_enc->flicker);
 673         drm_object_attach_property(&connector->base,
 674                                         conf->tv_saturation_property,
 675                                         tv_enc->saturation);
 676         drm_object_attach_property(&connector->base,
 677                                         conf->tv_hue_property,
 678                                         tv_enc->hue);
 679         drm_object_attach_property(&connector->base,
 680                                         conf->tv_overscan_property,
 681                                         tv_enc->overscan);
 682 
 683         return 0;
 684 }
 685 
 686 static int nv17_tv_set_property(struct drm_encoder *encoder,
 687                                 struct drm_connector *connector,
 688                                 struct drm_property *property,
 689                                 uint64_t val)
 690 {
 691         struct drm_mode_config *conf = &encoder->dev->mode_config;
 692         struct drm_crtc *crtc = encoder->crtc;
 693         struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
 694         struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
 695         bool modes_changed = false;
 696 
 697         if (property == conf->tv_overscan_property) {
 698                 tv_enc->overscan = val;
 699                 if (encoder->crtc) {
 700                         if (tv_norm->kind == CTV_ENC_MODE)
 701                                 nv17_ctv_update_rescaler(encoder);
 702                         else
 703                                 nv17_tv_update_rescaler(encoder);
 704                 }
 705 
 706         } else if (property == conf->tv_saturation_property) {
 707                 if (tv_norm->kind != TV_ENC_MODE)
 708                         return -EINVAL;
 709 
 710                 tv_enc->saturation = val;
 711                 nv17_tv_update_properties(encoder);
 712 
 713         } else if (property == conf->tv_hue_property) {
 714                 if (tv_norm->kind != TV_ENC_MODE)
 715                         return -EINVAL;
 716 
 717                 tv_enc->hue = val;
 718                 nv17_tv_update_properties(encoder);
 719 
 720         } else if (property == conf->tv_flicker_reduction_property) {
 721                 if (tv_norm->kind != TV_ENC_MODE)
 722                         return -EINVAL;
 723 
 724                 tv_enc->flicker = val;
 725                 if (encoder->crtc)
 726                         nv17_tv_update_rescaler(encoder);
 727 
 728         } else if (property == conf->tv_mode_property) {
 729                 if (connector->dpms != DRM_MODE_DPMS_OFF)
 730                         return -EINVAL;
 731 
 732                 tv_enc->tv_norm = val;
 733 
 734                 modes_changed = true;
 735 
 736         } else if (property == conf->tv_select_subconnector_property) {
 737                 if (tv_norm->kind != TV_ENC_MODE)
 738                         return -EINVAL;
 739 
 740                 tv_enc->select_subconnector = val;
 741                 nv17_tv_update_properties(encoder);
 742 
 743         } else {
 744                 return -EINVAL;
 745         }
 746 
 747         if (modes_changed) {
 748                 drm_helper_probe_single_connector_modes(connector, 0, 0);
 749 
 750                 /* Disable the crtc to ensure a full modeset is
 751                  * performed whenever it's turned on again. */
 752                 if (crtc)
 753                         drm_crtc_helper_set_mode(crtc, &crtc->mode,
 754                                                  crtc->x, crtc->y,
 755                                                  crtc->primary->fb);
 756         }
 757 
 758         return 0;
 759 }
 760 
 761 static void nv17_tv_destroy(struct drm_encoder *encoder)
 762 {
 763         struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
 764 
 765         drm_encoder_cleanup(encoder);
 766         kfree(tv_enc);
 767 }
 768 
 769 static const struct drm_encoder_helper_funcs nv17_tv_helper_funcs = {
 770         .dpms = nv17_tv_dpms,
 771         .mode_fixup = nv17_tv_mode_fixup,
 772         .prepare = nv17_tv_prepare,
 773         .commit = nv17_tv_commit,
 774         .mode_set = nv17_tv_mode_set,
 775         .detect = nv17_tv_detect,
 776 };
 777 
 778 static const struct drm_encoder_slave_funcs nv17_tv_slave_funcs = {
 779         .get_modes = nv17_tv_get_modes,
 780         .mode_valid = nv17_tv_mode_valid,
 781         .create_resources = nv17_tv_create_resources,
 782         .set_property = nv17_tv_set_property,
 783 };
 784 
 785 static const struct drm_encoder_funcs nv17_tv_funcs = {
 786         .destroy = nv17_tv_destroy,
 787 };
 788 
 789 int
 790 nv17_tv_create(struct drm_connector *connector, struct dcb_output *entry)
 791 {
 792         struct drm_device *dev = connector->dev;
 793         struct drm_encoder *encoder;
 794         struct nv17_tv_encoder *tv_enc = NULL;
 795 
 796         tv_enc = kzalloc(sizeof(*tv_enc), GFP_KERNEL);
 797         if (!tv_enc)
 798                 return -ENOMEM;
 799 
 800         tv_enc->overscan = 50;
 801         tv_enc->flicker = 50;
 802         tv_enc->saturation = 50;
 803         tv_enc->hue = 0;
 804         tv_enc->tv_norm = TV_NORM_PAL;
 805         tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Unknown;
 806         tv_enc->select_subconnector = DRM_MODE_SUBCONNECTOR_Automatic;
 807         tv_enc->pin_mask = 0;
 808 
 809         encoder = to_drm_encoder(&tv_enc->base);
 810 
 811         tv_enc->base.dcb = entry;
 812         tv_enc->base.or = ffs(entry->or) - 1;
 813 
 814         drm_encoder_init(dev, encoder, &nv17_tv_funcs, DRM_MODE_ENCODER_TVDAC,
 815                          NULL);
 816         drm_encoder_helper_add(encoder, &nv17_tv_helper_funcs);
 817         to_encoder_slave(encoder)->slave_funcs = &nv17_tv_slave_funcs;
 818 
 819         tv_enc->base.enc_save = nv17_tv_save;
 820         tv_enc->base.enc_restore = nv17_tv_restore;
 821 
 822         encoder->possible_crtcs = entry->heads;
 823         encoder->possible_clones = 0;
 824 
 825         nv17_tv_create_resources(encoder, connector);
 826         drm_connector_attach_encoder(connector, encoder);
 827         return 0;
 828 }

/* [<][>][^][v][top][bottom][index][help] */