Loading drivers/gpu/drm/nouveau/nv17_tv.c +89 −1 Original line number Diff line number Diff line Loading @@ -33,14 +33,102 @@ #include "nouveau_hw.h" #include "nv17_tv.h" static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t testval, regoffset = nv04_dac_output_offset(encoder); uint32_t gpio0, gpio1, fp_htotal, fp_hsync_start, fp_hsync_end, fp_control, test_ctrl, dacclk, ctv_14, ctv_1c, ctv_6c; uint32_t sample = 0; int head; #define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20) testval = RGB_TEST_DATA(0x82, 0xeb, 0x82); if (dev_priv->vbios->tvdactestval) testval = dev_priv->vbios->tvdactestval; dacclk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); head = (dacclk & 0x100) >> 8; /* Save the previous state. */ gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1); gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0); fp_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL); fp_hsync_start = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START); fp_hsync_end = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END); fp_control = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL); test_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); ctv_1c = NVReadRAMDAC(dev, head, 0x680c1c); ctv_14 = NVReadRAMDAC(dev, head, 0x680c14); ctv_6c = NVReadRAMDAC(dev, head, 0x680c6c); /* Prepare the DAC for load detection. */ nv17_gpio_set(dev, DCB_GPIO_TVDAC1, true); nv17_gpio_set(dev, DCB_GPIO_TVDAC0, true); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, 1343); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, 1047); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, 1183); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12 | NV_PRAMDAC_FP_TG_CONTROL_READ_PROG | NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS | NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS); NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, 0); NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, (dacclk & ~0xff) | 0x22); msleep(1); NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, (dacclk & ~0xff) | 0x21); NVWriteRAMDAC(dev, head, 0x680c1c, 1 << 20); NVWriteRAMDAC(dev, head, 0x680c14, 4 << 16); /* Sample pin 0x4 (usually S-video luma). */ NVWriteRAMDAC(dev, head, 0x680c6c, testval >> 10 & 0x3ff); msleep(20); sample |= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset) & 0x4 << 28; /* Sample the remaining pins. */ NVWriteRAMDAC(dev, head, 0x680c6c, testval & 0x3ff); msleep(20); sample |= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset) & 0xa << 28; /* Restore the previous state. */ NVWriteRAMDAC(dev, head, 0x680c1c, ctv_1c); NVWriteRAMDAC(dev, head, 0x680c14, ctv_14); NVWriteRAMDAC(dev, head, 0x680c6c, ctv_6c); NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, dacclk); NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, test_ctrl); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, fp_control); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, fp_hsync_end); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, fp_hsync_start); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, fp_htotal); nv17_gpio_set(dev, DCB_GPIO_TVDAC1, gpio1); nv17_gpio_set(dev, DCB_GPIO_TVDAC0, gpio0); return sample; } static enum drm_connector_status nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) { struct drm_device *dev = encoder->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_mode_config *conf = &dev->mode_config; struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); struct dcb_entry *dcb = tv_enc->base.dcb; if (dev_priv->chipset == 0x42 || dev_priv->chipset == 0x43) tv_enc->pin_mask = nv42_tv_sample_load(encoder) >> 28 & 0xe; else tv_enc->pin_mask = nv17_dac_sample_load(encoder) >> 28 & 0xe; switch (tv_enc->pin_mask) { Loading Loading
drivers/gpu/drm/nouveau/nv17_tv.c +89 −1 Original line number Diff line number Diff line Loading @@ -33,14 +33,102 @@ #include "nouveau_hw.h" #include "nv17_tv.h" static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t testval, regoffset = nv04_dac_output_offset(encoder); uint32_t gpio0, gpio1, fp_htotal, fp_hsync_start, fp_hsync_end, fp_control, test_ctrl, dacclk, ctv_14, ctv_1c, ctv_6c; uint32_t sample = 0; int head; #define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20) testval = RGB_TEST_DATA(0x82, 0xeb, 0x82); if (dev_priv->vbios->tvdactestval) testval = dev_priv->vbios->tvdactestval; dacclk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); head = (dacclk & 0x100) >> 8; /* Save the previous state. */ gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1); gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0); fp_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL); fp_hsync_start = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START); fp_hsync_end = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END); fp_control = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL); test_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); ctv_1c = NVReadRAMDAC(dev, head, 0x680c1c); ctv_14 = NVReadRAMDAC(dev, head, 0x680c14); ctv_6c = NVReadRAMDAC(dev, head, 0x680c6c); /* Prepare the DAC for load detection. */ nv17_gpio_set(dev, DCB_GPIO_TVDAC1, true); nv17_gpio_set(dev, DCB_GPIO_TVDAC0, true); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, 1343); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, 1047); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, 1183); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12 | NV_PRAMDAC_FP_TG_CONTROL_READ_PROG | NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS | NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS); NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, 0); NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, (dacclk & ~0xff) | 0x22); msleep(1); NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, (dacclk & ~0xff) | 0x21); NVWriteRAMDAC(dev, head, 0x680c1c, 1 << 20); NVWriteRAMDAC(dev, head, 0x680c14, 4 << 16); /* Sample pin 0x4 (usually S-video luma). */ NVWriteRAMDAC(dev, head, 0x680c6c, testval >> 10 & 0x3ff); msleep(20); sample |= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset) & 0x4 << 28; /* Sample the remaining pins. */ NVWriteRAMDAC(dev, head, 0x680c6c, testval & 0x3ff); msleep(20); sample |= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset) & 0xa << 28; /* Restore the previous state. */ NVWriteRAMDAC(dev, head, 0x680c1c, ctv_1c); NVWriteRAMDAC(dev, head, 0x680c14, ctv_14); NVWriteRAMDAC(dev, head, 0x680c6c, ctv_6c); NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, dacclk); NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, test_ctrl); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, fp_control); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, fp_hsync_end); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, fp_hsync_start); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, fp_htotal); nv17_gpio_set(dev, DCB_GPIO_TVDAC1, gpio1); nv17_gpio_set(dev, DCB_GPIO_TVDAC0, gpio0); return sample; } static enum drm_connector_status nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) { struct drm_device *dev = encoder->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_mode_config *conf = &dev->mode_config; struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); struct dcb_entry *dcb = tv_enc->base.dcb; if (dev_priv->chipset == 0x42 || dev_priv->chipset == 0x43) tv_enc->pin_mask = nv42_tv_sample_load(encoder) >> 28 & 0xe; else tv_enc->pin_mask = nv17_dac_sample_load(encoder) >> 28 & 0xe; switch (tv_enc->pin_mask) { Loading