From b5c6549818471087ab91d6bb37bc2be82042fab8 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Tue, 6 Sep 2011 08:36:54 +0000 Subject: [PATCH] sync video blitter git-svn-id: svn://kolibrios.org@2160 a494cfbc-eb01-0410-851d-a64ba20cac60 --- drivers/video/drm/drm_crtc.c | 2 + drivers/video/drm/drm_crtc_helper.c | 5 ++ drivers/video/drm/drm_edid.c | 36 ++++++-- drivers/video/drm/drm_fb_helper.c | 7 -- drivers/video/drm/radeon/atom.c | 3 + drivers/video/drm/radeon/atombios_crtc.c | 5 +- drivers/video/drm/radeon/atombios_dp.c | 22 ++++- drivers/video/drm/radeon/evergreen.c | 7 +- drivers/video/drm/radeon/evergreend.h | 2 + drivers/video/drm/radeon/ni.c | 2 + drivers/video/drm/radeon/pci.c | 68 +++++++-------- drivers/video/drm/radeon/r600.c | 19 +++-- drivers/video/drm/radeon/r600_blit_kms.c | 38 +++++++-- drivers/video/drm/radeon/radeon.h | 3 + drivers/video/drm/radeon/radeon_asic.c | 20 +++-- drivers/video/drm/radeon/radeon_clocks.c | 2 +- drivers/video/drm/radeon/radeon_combios.c | 5 +- drivers/video/drm/radeon/radeon_connectors.c | 54 +++++++++++- drivers/video/drm/radeon/radeon_device.c | 20 +++-- drivers/video/drm/radeon/radeon_display.c | 13 ++- drivers/video/drm/radeon/radeon_encoders.c | 3 + drivers/video/drm/radeon/radeon_i2c.c | 30 +++++-- drivers/video/drm/radeon/radeon_irq_kms.c | 89 ++------------------ drivers/video/drm/radeon/radeon_mode.h | 7 +- drivers/video/drm/radeon/radeon_reg.h | 2 +- drivers/video/drm/radeon/rs600.c | 2 +- drivers/video/drm/radeon/rv770.c | 1 + 27 files changed, 272 insertions(+), 195 deletions(-) diff --git a/drivers/video/drm/drm_crtc.c b/drivers/video/drm/drm_crtc.c index 34e24e1ef4..5cfec74362 100644 --- a/drivers/video/drm/drm_crtc.c +++ b/drivers/video/drm/drm_crtc.c @@ -499,6 +499,7 @@ void drm_connector_cleanup(struct drm_connector *connector) mutex_lock(&dev->mode_config.mutex); drm_mode_object_put(dev, &connector->base); list_del(&connector->head); + dev->mode_config.num_connector--; mutex_unlock(&dev->mode_config.mutex); } EXPORT_SYMBOL(drm_connector_cleanup); @@ -529,6 +530,7 @@ void drm_encoder_cleanup(struct drm_encoder *encoder) mutex_lock(&dev->mode_config.mutex); drm_mode_object_put(dev, &encoder->base); list_del(&encoder->head); + dev->mode_config.num_encoder--; mutex_unlock(&dev->mode_config.mutex); } EXPORT_SYMBOL(drm_encoder_cleanup); diff --git a/drivers/video/drm/drm_crtc_helper.c b/drivers/video/drm/drm_crtc_helper.c index d16f59035d..88cd1ccf2c 100644 --- a/drivers/video/drm/drm_crtc_helper.c +++ b/drivers/video/drm/drm_crtc_helper.c @@ -559,6 +559,11 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) mode_changed = true; } else if (set->fb == NULL) { mode_changed = true; + } else if (set->fb->depth != set->crtc->fb->depth) { + mode_changed = true; + } else if (set->fb->bits_per_pixel != + set->crtc->fb->bits_per_pixel) { + mode_changed = true; } else fb_changed = true; } diff --git a/drivers/video/drm/drm_edid.c b/drivers/video/drm/drm_edid.c index 0b619eb6ce..b2a2798f57 100644 --- a/drivers/video/drm/drm_edid.c +++ b/drivers/video/drm/drm_edid.c @@ -127,6 +127,23 @@ static const u8 edid_header[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; + /* + * Sanity check the header of the base EDID block. Return 8 if the header + * is perfect, down to 0 if it's totally wrong. + */ +int drm_edid_header_is_valid(const u8 *raw_edid) +{ + int i, score = 0; + + for (i = 0; i < sizeof(edid_header); i++) + if (raw_edid[i] == edid_header[i]) + score++; + + return score; +} +EXPORT_SYMBOL(drm_edid_header_is_valid); + + /* * Sanity check the EDID block (base or extension). Return 0 if the block * doesn't check out, or 1 if it's valid. @@ -139,12 +156,7 @@ drm_edid_block_valid(u8 *raw_edid) struct edid *edid = (struct edid *)raw_edid; if (raw_edid[0] == 0x00) { - int score = 0; - - for (i = 0; i < sizeof(edid_header); i++) - if (raw_edid[i] == edid_header[i]) - score++; - + int score = drm_edid_header_is_valid(raw_edid); if (score == 8) ; else if (score >= 6) { DRM_DEBUG("Fixing EDID header, your hardware may be failing\n"); @@ -185,8 +197,7 @@ drm_edid_block_valid(u8 *raw_edid) bad: if (raw_edid) { printk(KERN_ERR "Raw EDID:\n"); -// print_hex_dump_bytes(KERN_ERR, DUMP_PREFIX_NONE, raw_edid, EDID_LENGTH); - printk(KERN_ERR "\n"); +// print_hex_dump_bytes(KERN_ERR, DUMP_PREFIX_NONE, raw_edid, EDID_LENGTH); } return 0; } @@ -1449,6 +1460,8 @@ EXPORT_SYMBOL(drm_detect_monitor_audio); static void drm_add_display_info(struct edid *edid, struct drm_display_info *info) { + u8 *edid_ext; + info->width_mm = edid->width_cm * 10; info->height_mm = edid->height_cm * 10; @@ -1493,6 +1506,13 @@ static void drm_add_display_info(struct edid *edid, info->color_formats = DRM_COLOR_FORMAT_YCRCB444; if (info->color_formats & DRM_EDID_FEATURE_RGB_YCRCB422) info->color_formats = DRM_COLOR_FORMAT_YCRCB422; + + /* Get data from CEA blocks if present */ + edid_ext = drm_find_cea_extension(edid); + if (!edid_ext) + return; + + info->cea_rev = edid_ext[1]; } /** diff --git a/drivers/video/drm/drm_fb_helper.c b/drivers/video/drm/drm_fb_helper.c index 9d3d367bc8..7f19c5e460 100644 --- a/drivers/video/drm/drm_fb_helper.c +++ b/drivers/video/drm/drm_fb_helper.c @@ -580,10 +580,6 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, } /* push down into drivers */ - - DRM_INFO("enter fb probe\n"); - - new_fb = (*fb_helper->funcs->fb_probe)(fb_helper, &sizes); if (new_fb < 0) return new_fb; @@ -609,9 +605,6 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, if (new_fb) list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list); - - LEAVE(); - return 0; } EXPORT_SYMBOL(drm_fb_helper_single_fb_probe); diff --git a/drivers/video/drm/radeon/atom.c b/drivers/video/drm/radeon/atom.c index 3aff1262c1..214defe241 100644 --- a/drivers/video/drm/radeon/atom.c +++ b/drivers/video/drm/radeon/atom.c @@ -1228,6 +1228,9 @@ struct atom_context *atom_parse(struct card_info *card, void *bios) char name[512]; int i; + if (!ctx) + return NULL; + ctx->card = card; ctx->bios = bios; diff --git a/drivers/video/drm/radeon/atombios_crtc.c b/drivers/video/drm/radeon/atombios_crtc.c index ffeb585d93..ee0d41247a 100644 --- a/drivers/video/drm/radeon/atombios_crtc.c +++ b/drivers/video/drm/radeon/atombios_crtc.c @@ -764,7 +764,7 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc, } static void atombios_crtc_program_pll(struct drm_crtc *crtc, - int crtc_id, + u32 crtc_id, int pll_id, u32 encoder_mode, u32 encoder_id, @@ -851,8 +851,7 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc, args.v5.ucPpll = pll_id; break; case 6: - args.v6.ulCrtcPclkFreq.ucCRTC = crtc_id; - args.v6.ulCrtcPclkFreq.ulPixelClock = cpu_to_le32(clock / 10); + args.v6.ulDispEngClkFreq = cpu_to_le32(crtc_id << 24 | clock / 10); args.v6.ucRefDiv = ref_div; args.v6.usFbDiv = cpu_to_le16(fb_div); args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); diff --git a/drivers/video/drm/radeon/atombios_dp.c b/drivers/video/drm/radeon/atombios_dp.c index 5eb4e6bda6..4857c097c5 100644 --- a/drivers/video/drm/radeon/atombios_dp.c +++ b/drivers/video/drm/radeon/atombios_dp.c @@ -627,6 +627,7 @@ struct radeon_dp_link_train_info { u8 train_set[4]; u8 link_status[DP_LINK_STATUS_SIZE]; u8 tries; + bool use_dpencoder; }; static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info) @@ -646,7 +647,7 @@ static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp) int rtp = 0; /* set training pattern on the source */ - if (ASIC_IS_DCE4(dp_info->rdev)) { + if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) { switch (tp) { case DP_TRAINING_PATTERN_1: rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1; @@ -706,7 +707,7 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp); /* start training on the source */ - if (ASIC_IS_DCE4(dp_info->rdev)) + if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) atombios_dig_encoder_setup(dp_info->encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0); else @@ -731,7 +732,7 @@ static int radeon_dp_link_train_finish(struct radeon_dp_link_train_info *dp_info DP_TRAINING_PATTERN_DISABLE); /* disable the training pattern on the source */ - if (ASIC_IS_DCE4(dp_info->rdev)) + if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) atombios_dig_encoder_setup(dp_info->encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE, 0); else @@ -869,7 +870,8 @@ void radeon_dp_link_train(struct drm_encoder *encoder, struct radeon_connector *radeon_connector; struct radeon_connector_atom_dig *dig_connector; struct radeon_dp_link_train_info dp_info; - u8 tmp; + int index; + u8 tmp, frev, crev; if (!radeon_encoder->enc_priv) return; @@ -884,6 +886,18 @@ void radeon_dp_link_train(struct drm_encoder *encoder, (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_eDP)) return; + /* DPEncoderService newer than 1.1 can't program properly the + * training pattern. When facing such version use the + * DIGXEncoderControl (X== 1 | 2) + */ + dp_info.use_dpencoder = true; + index = GetIndexIntoMasterTable(COMMAND, DPEncoderService); + if (atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) { + if (crev > 1) { + dp_info.use_dpencoder = false; + } + } + dp_info.enc_id = 0; if (dig->dig_encoder) dp_info.enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; diff --git a/drivers/video/drm/radeon/evergreen.c b/drivers/video/drm/radeon/evergreen.c index 5348c0267d..58159300c2 100644 --- a/drivers/video/drm/radeon/evergreen.c +++ b/drivers/video/drm/radeon/evergreen.c @@ -733,7 +733,7 @@ static void evergreen_program_watermarks(struct radeon_device *rdev, !evergreen_average_bandwidth_vs_available_bandwidth(&wm) || !evergreen_check_latency_hiding(&wm) || (rdev->disp_priority == 2)) { - DRM_INFO("force priority to high\n"); + DRM_DEBUG_KMS("force priority to high\n"); priority_a_cnt |= PRIORITY_ALWAYS_ON; priority_b_cnt |= PRIORITY_ALWAYS_ON; } @@ -1347,6 +1347,7 @@ int evergreen_cp_resume(struct radeon_device *rdev) SOFT_RESET_PA | SOFT_RESET_SH | SOFT_RESET_VGT | + SOFT_RESET_SPI | SOFT_RESET_SX)); RREG32(GRBM_SOFT_RESET); mdelay(15); @@ -1372,9 +1373,6 @@ int evergreen_cp_resume(struct radeon_device *rdev) /* set the wb address wether it's enabled or not */ WREG32(CP_RB_RPTR_ADDR, -#ifdef __BIG_ENDIAN - RB_RPTR_SWAP(2) | -#endif ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); @@ -2037,6 +2035,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) rdev->config.evergreen.tile_config |= ((gb_addr_config & 0x30000000) >> 28) << 12; + rdev->config.evergreen.backend_map = gb_backend_map; WREG32(GB_BACKEND_MAP, gb_backend_map); WREG32(GB_ADDR_CONFIG, gb_addr_config); WREG32(DMIF_ADDR_CONFIG, gb_addr_config); diff --git a/drivers/video/drm/radeon/evergreend.h b/drivers/video/drm/radeon/evergreend.h index da2c7a7aed..287ec84818 100644 --- a/drivers/video/drm/radeon/evergreend.h +++ b/drivers/video/drm/radeon/evergreend.h @@ -351,6 +351,7 @@ #define COLOR_BUFFER_SIZE(x) ((x) << 0) #define POSITION_BUFFER_SIZE(x) ((x) << 8) #define SMX_BUFFER_SIZE(x) ((x) << 16) +#define SX_MEMORY_EXPORT_BASE 0x9010 #define SX_MISC 0x28350 #define CB_PERF_CTR0_SEL_0 0x9A20 @@ -1122,6 +1123,7 @@ #define CAYMAN_PA_SC_AA_CONFIG 0x28BE0 #define CAYMAN_MSAA_NUM_SAMPLES_SHIFT 0 #define CAYMAN_MSAA_NUM_SAMPLES_MASK 0x7 +#define CAYMAN_SX_SCATTER_EXPORT_BASE 0x28358 /* cayman packet3 addition */ #define CAYMAN_PACKET3_DEALLOC_STATE 0x14 diff --git a/drivers/video/drm/radeon/ni.c b/drivers/video/drm/radeon/ni.c index 974b46643a..7886c762f4 100644 --- a/drivers/video/drm/radeon/ni.c +++ b/drivers/video/drm/radeon/ni.c @@ -833,6 +833,7 @@ static void cayman_gpu_init(struct radeon_device *rdev) rdev->config.cayman.tile_config |= ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12; + rdev->config.cayman.backend_map = gb_backend_map; WREG32(GB_BACKEND_MAP, gb_backend_map); WREG32(GB_ADDR_CONFIG, gb_addr_config); WREG32(DMIF_ADDR_CONFIG, gb_addr_config); @@ -1147,6 +1148,7 @@ int cayman_cp_resume(struct radeon_device *rdev) SOFT_RESET_PA | SOFT_RESET_SH | SOFT_RESET_VGT | + SOFT_RESET_SPI | SOFT_RESET_SX)); RREG32(GRBM_SOFT_RESET); mdelay(15); diff --git a/drivers/video/drm/radeon/pci.c b/drivers/video/drm/radeon/pci.c index f40bce1284..213fdd0a03 100644 --- a/drivers/video/drm/radeon/pci.c +++ b/drivers/video/drm/radeon/pci.c @@ -2,8 +2,8 @@ #include #include #include -#include #include +#include #include static LIST_HEAD(devices); @@ -95,10 +95,10 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) res = &dev->resource[pos]; reg = PCI_BASE_ADDRESS_0 + (pos << 2); - l = PciRead32(dev->bus, dev->devfn, reg); - PciWrite32(dev->bus, dev->devfn, reg, ~0); - sz = PciRead32(dev->bus, dev->devfn, reg); - PciWrite32(dev->bus, dev->devfn, reg, l); + l = PciRead32(dev->busnr, dev->devfn, reg); + PciWrite32(dev->busnr, dev->devfn, reg, ~0); + sz = PciRead32(dev->busnr, dev->devfn, reg); + PciWrite32(dev->busnr, dev->devfn, reg, l); if (!sz || sz == 0xffffffff) continue; @@ -134,10 +134,10 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) { u32_t szhi, lhi; - lhi = PciRead32(dev->bus, dev->devfn, reg+4); - PciWrite32(dev->bus, dev->devfn, reg+4, ~0); - szhi = PciRead32(dev->bus, dev->devfn, reg+4); - PciWrite32(dev->bus, dev->devfn, reg+4, lhi); + lhi = PciRead32(dev->busnr, dev->devfn, reg+4); + PciWrite32(dev->busnr, dev->devfn, reg+4, ~0); + szhi = PciRead32(dev->busnr, dev->devfn, reg+4); + PciWrite32(dev->busnr, dev->devfn, reg+4, lhi); sz64 = ((u64_t)szhi << 32) | raw_sz; l64 = ((u64_t)lhi << 32) | l; sz64 = pci_size64(l64, sz64, PCI_BASE_ADDRESS_MEM_MASK); @@ -162,9 +162,9 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) else if (lhi) { /* 64-bit wide address, treat as disabled */ - PciWrite32(dev->bus, dev->devfn, reg, + PciWrite32(dev->busnr, dev->devfn, reg, l & ~(u32_t)PCI_BASE_ADDRESS_MEM_MASK); - PciWrite32(dev->bus, dev->devfn, reg+4, 0); + PciWrite32(dev->busnr, dev->devfn, reg+4, 0); res->start = 0; res->end = sz; } @@ -177,10 +177,10 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) dev->rom_base_reg = rom; res = &dev->resource[PCI_ROM_RESOURCE]; - l = PciRead32(dev->bus, dev->devfn, rom); - PciWrite32(dev->bus, dev->devfn, rom, ~PCI_ROM_ADDRESS_ENABLE); - sz = PciRead32(dev->bus, dev->devfn, rom); - PciWrite32(dev->bus, dev->devfn, rom, l); + l = PciRead32(dev->busnr, dev->devfn, rom); + PciWrite32(dev->busnr, dev->devfn, rom, ~PCI_ROM_ADDRESS_ENABLE); + sz = PciRead32(dev->busnr, dev->devfn, rom); + PciWrite32(dev->busnr, dev->devfn, rom, l); if (l == 0xffffffff) l = 0; @@ -205,19 +205,19 @@ static void pci_read_irq(struct pci_dev *dev) { u8_t irq; - irq = PciRead8(dev->bus, dev->devfn, PCI_INTERRUPT_PIN); + irq = PciRead8(dev->busnr, dev->devfn, PCI_INTERRUPT_PIN); dev->pin = irq; if (irq) - irq = PciRead8(dev->bus, dev->devfn, PCI_INTERRUPT_LINE); + irq = PciRead8(dev->busnr, dev->devfn, PCI_INTERRUPT_LINE); dev->irq = irq; }; -static int pci_setup_device(struct pci_dev *dev) +int pci_setup_device(struct pci_dev *dev) { u32_t class; - class = PciRead32(dev->bus, dev->devfn, PCI_CLASS_REVISION); + class = PciRead32(dev->busnr, dev->devfn, PCI_CLASS_REVISION); dev->revision = class & 0xff; class >>= 8; /* upper 3 bytes */ dev->class = class; @@ -236,8 +236,8 @@ static int pci_setup_device(struct pci_dev *dev) goto bad; pci_read_irq(dev); pci_read_bases(dev, 6, PCI_ROM_ADDRESS); - dev->subsystem_vendor = PciRead16(dev->bus, dev->devfn,PCI_SUBSYSTEM_VENDOR_ID); - dev->subsystem_device = PciRead16(dev->bus, dev->devfn, PCI_SUBSYSTEM_ID); + dev->subsystem_vendor = PciRead16(dev->busnr, dev->devfn,PCI_SUBSYSTEM_VENDOR_ID); + dev->subsystem_device = PciRead16(dev->busnr, dev->devfn, PCI_SUBSYSTEM_ID); /* * Do the ugly legacy mode stuff here rather than broken chip @@ -249,7 +249,7 @@ static int pci_setup_device(struct pci_dev *dev) { u8_t progif; - progif = PciRead8(dev->bus, dev->devfn,PCI_CLASS_PROG); + progif = PciRead8(dev->busnr, dev->devfn,PCI_CLASS_PROG); if ((progif & 1) == 0) { dev->resource[0].start = 0x1F0; @@ -287,11 +287,11 @@ static int pci_setup_device(struct pci_dev *dev) goto bad; pci_read_irq(dev); pci_read_bases(dev, 1, 0); - dev->subsystem_vendor = PciRead16(dev->bus, + dev->subsystem_vendor = PciRead16(dev->busnr, dev->devfn, PCI_CB_SUBSYSTEM_VENDOR_ID); - dev->subsystem_device = PciRead16(dev->bus, + dev->subsystem_device = PciRead16(dev->busnr, dev->devfn, PCI_CB_SUBSYSTEM_ID); break; @@ -312,7 +312,7 @@ static int pci_setup_device(struct pci_dev *dev) return 0; }; -static pci_dev_t* pci_scan_device(u32_t bus, int devfn) +static pci_dev_t* pci_scan_device(u32_t busnr, int devfn) { pci_dev_t *dev; @@ -321,7 +321,7 @@ static pci_dev_t* pci_scan_device(u32_t bus, int devfn) int timeout = 10; - id = PciRead32(bus,devfn, PCI_VENDOR_ID); + id = PciRead32(busnr, devfn, PCI_VENDOR_ID); /* some broken boards return 0 or ~0 if a slot is empty: */ if (id == 0xffffffff || id == 0x00000000 || @@ -334,18 +334,18 @@ static pci_dev_t* pci_scan_device(u32_t bus, int devfn) delay(timeout/10); timeout *= 2; - id = PciRead32(bus, devfn, PCI_VENDOR_ID); + id = PciRead32(busnr, devfn, PCI_VENDOR_ID); /* Card hasn't responded in 60 seconds? Must be stuck. */ if (timeout > 60 * 100) { printk(KERN_WARNING "Device %04x:%02x:%02x.%d not " - "responding\n", bus,PCI_SLOT(devfn),PCI_FUNC(devfn)); + "responding\n", busnr,PCI_SLOT(devfn),PCI_FUNC(devfn)); return NULL; } }; - hdr = PciRead8(bus, devfn, PCI_HEADER_TYPE); + hdr = PciRead8(busnr, devfn, PCI_HEADER_TYPE); dev = (pci_dev_t*)kzalloc(sizeof(pci_dev_t), 0); @@ -354,7 +354,7 @@ static pci_dev_t* pci_scan_device(u32_t bus, int devfn) if(unlikely(dev == NULL)) return NULL; - dev->pci_dev.bus = bus; + dev->pci_dev.busnr = busnr; dev->pci_dev.devfn = devfn; dev->pci_dev.hdr_type = hdr & 0x7f; dev->pci_dev.multifunction = !!(hdr & 0x80); @@ -505,9 +505,9 @@ int pci_find_capability(struct pci_dev *dev, int cap) { int pos; - pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type); + pos = __pci_bus_find_cap_start(dev->busnr, dev->devfn, dev->hdr_type); if (pos) - pos = __pci_find_next_cap(dev->bus, dev->devfn, pos, cap); + pos = __pci_find_next_cap(dev->busnr, dev->devfn, pos, cap); return pos; } @@ -646,7 +646,7 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) int idx; struct resource *r; - cmd = PciRead16(dev->bus, dev->devfn, PCI_COMMAND); + cmd = PciRead16(dev->busnr, dev->devfn, PCI_COMMAND); old_cmd = cmd; for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) { @@ -674,7 +674,7 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) if (cmd != old_cmd) { printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); - PciWrite16(dev->bus, dev->devfn, PCI_COMMAND, cmd); + PciWrite16(dev->busnr, dev->devfn, PCI_COMMAND, cmd); } return 0; } diff --git a/drivers/video/drm/radeon/r600.c b/drivers/video/drm/radeon/r600.c index 6de2cc9e9a..b24047af01 100644 --- a/drivers/video/drm/radeon/r600.c +++ b/drivers/video/drm/radeon/r600.c @@ -1179,6 +1179,7 @@ void r600_gpu_init(struct radeon_device *rdev) R6XX_MAX_BACKENDS_MASK) >> 16)), (cc_rb_backend_disable >> 16)); rdev->config.r600.tile_config = tiling_config; + rdev->config.r600.backend_map = backend_map; tiling_config |= BACKEND_MAP(backend_map); WREG32(GB_TILING_CONFIG, tiling_config); WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff); @@ -1729,9 +1730,6 @@ int r600_cp_resume(struct radeon_device *rdev) /* set the wb address whether it's enabled or not */ WREG32(CP_RB_RPTR_ADDR, -#ifdef __BIG_ENDIAN - RB_RPTR_SWAP(2) | -#endif ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); @@ -2437,10 +2435,6 @@ int r600_irq_init(struct radeon_device *rdev) /* RPTR_REARM only works if msi's are enabled */ if (rdev->msi_enabled) ih_cntl |= RPTR_REARM; - -#ifdef __BIG_ENDIAN - ih_cntl |= IH_MC_SWAP(IH_MC_SWAP_32BIT); -#endif WREG32(IH_CNTL, ih_cntl); /* force the active interrupt state to all disabled */ @@ -2717,6 +2711,8 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) * adjusted or added to on newer asics */ +#define DRM_DEBUG(...) + int r600_irq_process(struct radeon_device *rdev) { u32 wptr; @@ -2729,9 +2725,13 @@ int r600_irq_process(struct radeon_device *rdev) if (!rdev->ih.enabled || rdev->shutdown) return IRQ_NONE; + /* No MSIs, need a dummy read to flush PCI DMAs */ + if (!rdev->msi_enabled) + RREG32(IH_RB_WPTR); + wptr = r600_get_ih_wptr(rdev); rptr = rdev->ih.rptr; - DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); +// DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); spin_lock_irqsave(&rdev->ih.lock, flags); @@ -2741,6 +2741,9 @@ int r600_irq_process(struct radeon_device *rdev) } restart_ih: + /* Order reading of wptr vs. reading of IH ring data */ + rmb(); + /* display interrupts */ r600_irq_ack(rdev); diff --git a/drivers/video/drm/radeon/r600_blit_kms.c b/drivers/video/drm/radeon/r600_blit_kms.c index cd3e8b7df7..0bbd16f882 100644 --- a/drivers/video/drm/radeon/r600_blit_kms.c +++ b/drivers/video/drm/radeon/r600_blit_kms.c @@ -483,8 +483,6 @@ int r600_blit_init(struct radeon_device *rdev) u32 packet2s[16]; int num_packet2s = 0; - ENTER(); - /* pin copy shader into vram if already initialized */ if (rdev->r600_blit.shader_obj) goto done; @@ -562,7 +560,6 @@ done: } // radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); - LEAVE(); return 0; } @@ -850,7 +847,7 @@ void r600_kms_video_blit(struct radeon_device *rdev, u64 vb_gpu_addr; u32 *vb; - DRM_DEBUG("emitting video copy\n"); +// DRM_DEBUG("emitting video copy\n"); vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used); if ((rdev->r600_blit.vb_used + 48) > rdev->r600_blit.vb_total) { @@ -909,8 +906,22 @@ extern struct radeon_device *main_device; int r600_video_blit(uint64_t src_offset, int x, int y, int w, int h, int pitch) { - int r; struct radeon_device *rdev = main_device; + static struct radeon_fence *fence; + unsigned long irq_flags; + + int r; + + if(fence == NULL) + { + r = radeon_fence_create(rdev, &fence); + if (r) { + printf("%s epic fail", __FUNCTION__); + return r; + } + }; + + fence->evnt = CreateEvent(NULL, 0); mutex_lock(&rdev->r600_blit.mutex); rdev->r600_blit.vb_ib = NULL; @@ -922,10 +933,19 @@ int r600_video_blit(uint64_t src_offset, int x, int y, return r; } - r600_kms_video_blit(rdev, src_offset,x,y,w,h,pitch); - r600_blit_done_copy(rdev, NULL); + r600_blit_done_copy(rdev, fence); mutex_unlock(&rdev->r600_blit.mutex); + + r = radeon_fence_wait(fence, false); + + write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); + list_del(&fence->list); + fence->emited = false; + fence->signaled = false; + write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); + + return r; }; int r600_create_video(int w, int h, u32_t *outp) @@ -965,8 +985,8 @@ int r600_create_video(int w, int h, u32_t *outp) outp[2] = uaddr; outp[3] = pitch; - dbgprintf("Create video surface %x, mapped at %x pitch %d\n", - (uint32_t)saddr, uaddr, pitch); +// dbgprintf("Create video surface %x, mapped at %x pitch %d\n", +// (uint32_t)saddr, uaddr, pitch); return 0; fail: diff --git a/drivers/video/drm/radeon/radeon.h b/drivers/video/drm/radeon/radeon.h index 1da24645d5..fdb5afc79e 100644 --- a/drivers/video/drm/radeon/radeon.h +++ b/drivers/video/drm/radeon/radeon.h @@ -1056,6 +1056,7 @@ struct r600_asic { unsigned tiling_npipes; unsigned tiling_group_size; unsigned tile_config; + unsigned backend_map; struct r100_gpu_lockup lockup; }; @@ -1081,6 +1082,7 @@ struct rv770_asic { unsigned tiling_npipes; unsigned tiling_group_size; unsigned tile_config; + unsigned backend_map; struct r100_gpu_lockup lockup; }; @@ -1107,6 +1109,7 @@ struct evergreen_asic { unsigned tiling_npipes; unsigned tiling_group_size; unsigned tile_config; + unsigned backend_map; struct r100_gpu_lockup lockup; }; diff --git a/drivers/video/drm/radeon/radeon_asic.c b/drivers/video/drm/radeon/radeon_asic.c index 3412a781d9..a20a78165c 100644 --- a/drivers/video/drm/radeon/radeon_asic.c +++ b/drivers/video/drm/radeon/radeon_asic.c @@ -320,6 +320,7 @@ static struct radeon_asic r420_asic = { .hpd_sense = &r100_hpd_sense, .hpd_set_polarity = &r100_hpd_set_polarity, .ioctl_wait_idle = NULL, + .gui_idle = &r100_gui_idle, }; static struct radeon_asic rs400_asic = { @@ -358,6 +359,7 @@ static struct radeon_asic rs400_asic = { .hpd_sense = &r100_hpd_sense, .hpd_set_polarity = &r100_hpd_set_polarity, .ioctl_wait_idle = NULL, + .gui_idle = &r100_gui_idle, }; static struct radeon_asic rs600_asic = { @@ -396,6 +398,7 @@ static struct radeon_asic rs600_asic = { .hpd_sense = &rs600_hpd_sense, .hpd_set_polarity = &rs600_hpd_set_polarity, .ioctl_wait_idle = NULL, + .gui_idle = &r100_gui_idle, }; static struct radeon_asic rs690_asic = { @@ -434,6 +437,7 @@ static struct radeon_asic rs690_asic = { .hpd_sense = &rs600_hpd_sense, .hpd_set_polarity = &rs600_hpd_set_polarity, .ioctl_wait_idle = NULL, + .gui_idle = &r100_gui_idle, }; static struct radeon_asic rv515_asic = { @@ -472,6 +476,7 @@ static struct radeon_asic rv515_asic = { .hpd_sense = &rs600_hpd_sense, .hpd_set_polarity = &rs600_hpd_set_polarity, .ioctl_wait_idle = NULL, + .gui_idle = &r100_gui_idle, }; static struct radeon_asic r520_asic = { @@ -510,6 +515,7 @@ static struct radeon_asic r520_asic = { .hpd_sense = &rs600_hpd_sense, .hpd_set_polarity = &rs600_hpd_set_polarity, .ioctl_wait_idle = NULL, + .gui_idle = &r100_gui_idle, }; static struct radeon_asic r600_asic = { @@ -529,7 +535,7 @@ static struct radeon_asic r600_asic = { .fence_ring_emit = &r600_fence_ring_emit, // .cs_parse = &r600_cs_parse, .copy_blit = &r600_copy_blit, - .copy_dma = &r600_copy_blit, + .copy_dma = NULL, .copy = &r600_copy_blit, .get_engine_clock = &radeon_atom_get_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock, @@ -566,7 +572,7 @@ static struct radeon_asic rs780_asic = { .fence_ring_emit = &r600_fence_ring_emit, // .cs_parse = &r600_cs_parse, .copy_blit = &r600_copy_blit, - .copy_dma = &r600_copy_blit, + .copy_dma = NULL, .copy = &r600_copy_blit, .get_engine_clock = &radeon_atom_get_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock, @@ -601,7 +607,7 @@ static struct radeon_asic rv770_asic = { .fence_ring_emit = &r600_fence_ring_emit, // .cs_parse = &r600_cs_parse, .copy_blit = &r600_copy_blit, - .copy_dma = &r600_copy_blit, + .copy_dma = NULL, .copy = &r600_copy_blit, .get_engine_clock = &radeon_atom_get_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock, @@ -636,7 +642,7 @@ static struct radeon_asic evergreen_asic = { .fence_ring_emit = &r600_fence_ring_emit, // .cs_parse = &evergreen_cs_parse, .copy_blit = &evergreen_copy_blit, - .copy_dma = &evergreen_copy_blit, + .copy_dma = NULL, .copy = &evergreen_copy_blit, .get_engine_clock = &radeon_atom_get_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock, @@ -672,7 +678,7 @@ static struct radeon_asic sumo_asic = { .fence_ring_emit = &r600_fence_ring_emit, // .cs_parse = &r600_cs_parse, .copy_blit = &evergreen_copy_blit, - .copy_dma = &evergreen_copy_blit, + .copy_dma = NULL, .copy = &evergreen_copy_blit, .get_engine_clock = &radeon_atom_get_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock, @@ -707,7 +713,7 @@ static struct radeon_asic btc_asic = { .fence_ring_emit = &r600_fence_ring_emit, // .cs_parse = &evergreen_cs_parse, .copy_blit = &evergreen_copy_blit, - .copy_dma = &evergreen_copy_blit, + .copy_dma = NULL, .copy = &evergreen_copy_blit, .get_engine_clock = &radeon_atom_get_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock, @@ -742,7 +748,7 @@ static struct radeon_asic cayman_asic = { .fence_ring_emit = &r600_fence_ring_emit, // .cs_parse = &evergreen_cs_parse, .copy_blit = &evergreen_copy_blit, - .copy_dma = &evergreen_copy_blit, + .copy_dma = NULL, .copy = &evergreen_copy_blit, .get_engine_clock = &radeon_atom_get_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock, diff --git a/drivers/video/drm/radeon/radeon_clocks.c b/drivers/video/drm/radeon/radeon_clocks.c index d64be21d03..8b6e590fde 100644 --- a/drivers/video/drm/radeon/radeon_clocks.c +++ b/drivers/video/drm/radeon/radeon_clocks.c @@ -96,7 +96,7 @@ uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev) * Read XTAL (ref clock), SCLK and MCLK from Open Firmware device * tree. Hopefully, ATI OF driver is kind enough to fill these */ -static bool __devinit radeon_read_clocks_OF(struct drm_device *dev) +static bool radeon_read_clocks_OF(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; struct device_node *dp = rdev->pdev->dev.of_node; diff --git a/drivers/video/drm/radeon/radeon_combios.c b/drivers/video/drm/radeon/radeon_combios.c index 4e697706d0..9529590e03 100644 --- a/drivers/video/drm/radeon/radeon_combios.c +++ b/drivers/video/drm/radeon/radeon_combios.c @@ -779,7 +779,8 @@ void radeon_combios_i2c_init(struct radeon_device *rdev) } } } - } else if (rdev->family >= CHIP_R200) { + } else if ((rdev->family == CHIP_R200) || + (rdev->family >= CHIP_R300)) { /* 0x68 */ i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); @@ -2556,6 +2557,7 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) u16 offset, misc, misc2 = 0; u8 rev, blocks, tmp; int state_index = 0; + struct radeon_i2c_bus_rec i2c_bus; rdev->pm.default_power_state_index = -1; @@ -2574,7 +2576,6 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE); if (offset) { u8 thermal_controller = 0, gpio = 0, i2c_addr = 0, clk_bit = 0, data_bit = 0; - struct radeon_i2c_bus_rec i2c_bus; rev = RBIOS8(offset); diff --git a/drivers/video/drm/radeon/radeon_connectors.c b/drivers/video/drm/radeon/radeon_connectors.c index 84a31d1edd..40a44696a4 100644 --- a/drivers/video/drm/radeon/radeon_connectors.c +++ b/drivers/video/drm/radeon/radeon_connectors.c @@ -430,6 +430,45 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr return 0; } +/* + * Some integrated ATI Radeon chipset implementations (e. g. + * Asus M2A-VM HDMI) may indicate the availability of a DDC, + * even when there's no monitor connected. For these connectors + * following DDC probe extension will be applied: check also for the + * availability of EDID with at least a correct EDID header. Only then, + * DDC is assumed to be available. This prevents drm_get_edid() and + * drm_edid_block_valid() from periodically dumping data and kernel + * errors into the logs and onto the terminal. + */ +static bool radeon_connector_needs_extended_probe(struct radeon_device *dev, + uint32_t supported_device, + int connector_type) +{ + /* Asus M2A-VM HDMI board sends data to i2c bus even, + * if HDMI add-on card is not plugged in or HDMI is disabled in + * BIOS. Valid DDC can only be assumed, if also a valid EDID header + * can be retrieved via i2c bus during DDC probe */ + if ((dev->pdev->device == 0x791e) && + (dev->pdev->subsystem_vendor == 0x1043) && + (dev->pdev->subsystem_device == 0x826d)) { + if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) && + (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) + return true; + } + /* ECS A740GM-M with ATI RADEON 2100 sends data to i2c bus + * for a DVI connector that is not implemented */ + if ((dev->pdev->device == 0x796e) && + (dev->pdev->subsystem_vendor == 0x1019) && + (dev->pdev->subsystem_device == 0x2615)) { + if ((connector_type == DRM_MODE_CONNECTOR_DVID) && + (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) + return true; + } + + /* Default: no EDID header probe required for DDC probing */ + return false; +} + static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, struct drm_connector *connector) { @@ -661,7 +700,8 @@ radeon_vga_detect(struct drm_connector *connector, bool force) ret = connector_status_disconnected; if (radeon_connector->ddc_bus) - dret = radeon_ddc_probe(radeon_connector); + dret = radeon_ddc_probe(radeon_connector, + radeon_connector->requires_extended_probe); if (dret) { if (radeon_connector->edid) { kfree(radeon_connector->edid); @@ -833,7 +873,8 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) bool dret = false; if (radeon_connector->ddc_bus) - dret = radeon_ddc_probe(radeon_connector); + dret = radeon_ddc_probe(radeon_connector, + radeon_connector->requires_extended_probe); if (dret) { if (radeon_connector->edid) { kfree(radeon_connector->edid); @@ -1251,7 +1292,8 @@ radeon_dp_detect(struct drm_connector *connector, bool force) if (radeon_dp_getdpcd(radeon_connector)) ret = connector_status_connected; } else { - if (radeon_ddc_probe(radeon_connector)) + if (radeon_ddc_probe(radeon_connector, + radeon_connector->requires_extended_probe)) ret = connector_status_connected; } } @@ -1406,6 +1448,9 @@ radeon_add_atom_connector(struct drm_device *dev, radeon_connector->shared_ddc = shared_ddc; radeon_connector->connector_object_id = connector_object_id; radeon_connector->hpd = *hpd; + radeon_connector->requires_extended_probe = + radeon_connector_needs_extended_probe(rdev, supported_device, + connector_type); radeon_connector->router = *router; if (router->ddc_valid || router->cd_valid) { radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); @@ -1752,6 +1797,9 @@ radeon_add_legacy_connector(struct drm_device *dev, radeon_connector->devices = supported_device; radeon_connector->connector_object_id = connector_object_id; radeon_connector->hpd = *hpd; + radeon_connector->requires_extended_probe = + radeon_connector_needs_extended_probe(rdev, supported_device, + connector_type); switch (connector_type) { case DRM_MODE_CONNECTOR_VGA: drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); diff --git a/drivers/video/drm/radeon/radeon_device.c b/drivers/video/drm/radeon/radeon_device.c index 55279be2ce..653b5a69c7 100644 --- a/drivers/video/drm/radeon/radeon_device.c +++ b/drivers/video/drm/radeon/radeon_device.c @@ -38,7 +38,7 @@ #include -int radeon_no_wb; +int radeon_no_wb = 1; int radeon_modeset = -1; int radeon_dynclks = -1; int radeon_r4xx_atom = 0; @@ -56,6 +56,7 @@ int radeon_hw_i2c = 0; int radeon_pcie_gen2 = 0; int radeon_disp_priority = 0; +int irq_override = 0; extern display_t *rdisplay; @@ -899,6 +900,16 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent) else init_display(dev->dev_private, &usermode); + + uint32_t route0 = PciRead32(0, 31<<3, 0x60); + + uint32_t route1 = PciRead32(0, 31<<3, 0x68); + + uint8_t elcr0 = in8(0x4D0); + uint8_t elcr1 = in8(0x4D1); + + dbgprintf("pci route: %x %x elcr: %x %x\n", route0, route1, elcr0, elcr1); + LEAVE(); return 0; @@ -1042,12 +1053,7 @@ int _stdcall display_handler(ioctl_t *io) static char log[256]; static pci_dev_t device; -u32_t -#if defined(__GNUC__) && __GNUC__ >= 4 -// has sense only if -fwhole-program is used, like Makefile.lto -__attribute__((externally_visible)) -#endif -drvEntry(int action, char *cmdline) +u32_t drvEntry(int action, char *cmdline) { struct radeon_device *rdev = NULL; diff --git a/drivers/video/drm/radeon/radeon_display.c b/drivers/video/drm/radeon/radeon_display.c index 98e595703e..0f34b71457 100644 --- a/drivers/video/drm/radeon/radeon_display.c +++ b/drivers/video/drm/radeon/radeon_display.c @@ -515,8 +515,17 @@ static int radeon_ddc_dump(struct drm_connector *connector) if (!radeon_connector->ddc_bus) return -1; edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); + /* Log EDID retrieval status here. In particular with regard to + * connectors with requires_extended_probe flag set, that will prevent + * function radeon_dvi_detect() to fetch EDID on this connector, + * as long as there is no valid EDID header found */ if (edid) { + DRM_INFO("Radeon display connector %s: Found valid EDID", + drm_get_connector_name(connector)); kfree(edid); + } else { + DRM_INFO("Radeon display connector %s: No monitor connected or invalid EDID", + drm_get_connector_name(connector)); } return ret; } @@ -1014,8 +1023,6 @@ int radeon_modeset_init(struct radeon_device *rdev) int i; int ret; - ENTER(); - drm_mode_config_init(rdev->ddev); rdev->mode_info.mode_config_initialized = true; @@ -1072,8 +1079,6 @@ int radeon_modeset_init(struct radeon_device *rdev) radeon_fbdev_init(rdev); // drm_kms_helper_poll_init(rdev->ddev); - LEAVE(); - return 0; } diff --git a/drivers/video/drm/radeon/radeon_encoders.c b/drivers/video/drm/radeon/radeon_encoders.c index 28ba395c98..f16185323b 100644 --- a/drivers/video/drm/radeon/radeon_encoders.c +++ b/drivers/video/drm/radeon/radeon_encoders.c @@ -2323,6 +2323,9 @@ radeon_add_atom_encoder(struct drm_device *dev, default: encoder->possible_crtcs = 0x3; break; + case 4: + encoder->possible_crtcs = 0xf; + break; case 6: encoder->possible_crtcs = 0x3f; break; diff --git a/drivers/video/drm/radeon/radeon_i2c.c b/drivers/video/drm/radeon/radeon_i2c.c index 63a8bd7b92..eb20f4c290 100644 --- a/drivers/video/drm/radeon/radeon_i2c.c +++ b/drivers/video/drm/radeon/radeon_i2c.c @@ -32,17 +32,17 @@ * radeon_ddc_probe * */ -bool radeon_ddc_probe(struct radeon_connector *radeon_connector) +bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_extended_probe) { - u8 out_buf[] = { 0x0, 0x0}; - u8 buf[2]; + u8 out = 0x0; + u8 buf[8]; int ret; struct i2c_msg msgs[] = { { .addr = 0x50, .flags = 0, .len = 1, - .buf = out_buf, + .buf = &out, }, { .addr = 0x50, @@ -52,15 +52,31 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector) } }; + /* Read 8 bytes from i2c for extended probe of EDID header */ + if (requires_extended_probe) + msgs[1].len = 8; + /* on hw with routers, select right port */ if (radeon_connector->router.ddc_valid) radeon_router_select_ddc_port(radeon_connector); ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); - if (ret == 2) + if (ret != 2) + /* Couldn't find an accessible DDC on this connector */ + return false; + if (requires_extended_probe) { + /* Probe also for valid EDID header + * EDID header starts with: + * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00. + * Only the first 6 bytes must be valid as + * drm_edid_block_valid() can fix the last 2 bytes */ + if (drm_edid_header_is_valid(buf) < 6) { + /* Couldn't find an accessible EDID on this + * connector */ + return false; + } + } return true; - - return false; } /* bit banging i2c */ diff --git a/drivers/video/drm/radeon/radeon_irq_kms.c b/drivers/video/drm/radeon/radeon_irq_kms.c index 9a87383a99..b99ed49919 100644 --- a/drivers/video/drm/radeon/radeon_irq_kms.c +++ b/drivers/video/drm/radeon/radeon_irq_kms.c @@ -34,57 +34,7 @@ struct radeon_device *main_device; -#if 0 - -irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - struct radeon_device *rdev = dev->dev_private; - - return radeon_irq_process(rdev); -} - -/* - * Handle hotplug events outside the interrupt handler proper. - */ -static void radeon_hotplug_work_func(struct work_struct *work) -{ - struct radeon_device *rdev = container_of(work, struct radeon_device, - hotplug_work); - struct drm_device *dev = rdev->ddev; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_connector *connector; - - if (mode_config->num_connector) { - list_for_each_entry(connector, &mode_config->connector_list, head) - radeon_connector_hotplug(connector); - } - /* Just fire off a uevent and let userspace tell us what to do */ - drm_helper_hpd_irq_event(dev); -} - - -void radeon_driver_irq_uninstall_kms(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - unsigned i; - - if (rdev == NULL) { - return; - } - /* Disable *all* interrupts */ - rdev->irq.sw_int = false; - rdev->irq.gui_idle = false; - for (i = 0; i < rdev->num_crtc; i++) - rdev->irq.crtc_vblank_int[i] = false; - for (i = 0; i < 6; i++) { - rdev->irq.hpd[i] = false; - rdev->irq.pflip[i] = false; - } - radeon_irq_set(rdev); -} - -#endif +extern int irq_override; void irq_handler_kms() { @@ -145,7 +95,10 @@ int radeon_irq_kms_init(struct radeon_device *rdev) radeon_irq_preinstall(rdev); - irq_line = rdev->pdev->irq; + if (irq_override) + irq_line = irq_override; + else + irq_line = rdev->pdev->irq; dbgprintf("%s install irq %d\n", __FUNCTION__, irq_line); @@ -190,36 +143,4 @@ void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev) spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags); } -#if 0 -void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc) -{ - unsigned long irqflags; - if (crtc < 0 || crtc >= rdev->num_crtc) - return; - - spin_lock_irqsave(&rdev->irq.pflip_lock[crtc], irqflags); - if (rdev->ddev->irq_enabled && (++rdev->irq.pflip_refcount[crtc] == 1)) { - rdev->irq.pflip[crtc] = true; - radeon_irq_set(rdev); - } - spin_unlock_irqrestore(&rdev->irq.pflip_lock[crtc], irqflags); -} - -void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc) -{ - unsigned long irqflags; - - if (crtc < 0 || crtc >= rdev->num_crtc) - return; - - spin_lock_irqsave(&rdev->irq.pflip_lock[crtc], irqflags); - BUG_ON(rdev->ddev->irq_enabled && rdev->irq.pflip_refcount[crtc] <= 0); - if (rdev->ddev->irq_enabled && (--rdev->irq.pflip_refcount[crtc] == 0)) { - rdev->irq.pflip[crtc] = false; - radeon_irq_set(rdev); - } - spin_unlock_irqrestore(&rdev->irq.pflip_lock[crtc], irqflags); -} - -#endif diff --git a/drivers/video/drm/radeon/radeon_mode.h b/drivers/video/drm/radeon/radeon_mode.h index 164e9129d7..0e33ea6f56 100644 --- a/drivers/video/drm/radeon/radeon_mode.h +++ b/drivers/video/drm/radeon/radeon_mode.h @@ -280,6 +280,7 @@ struct radeon_crtc { fixed20_12 hsc; struct drm_display_mode native_mode; int pll_id; + int deferred_flip_completion; }; struct radeon_encoder_primary_dac { @@ -435,6 +436,9 @@ struct radeon_connector { struct radeon_i2c_chan *ddc_bus; /* some systems have an hdmi and vga port with a shared ddc line */ bool shared_ddc; + /* for some Radeon chip families we apply an additional EDID header + check as part of the DDC probe */ + bool requires_extended_probe; bool use_digital; /* we need to mind the EDID between detect and get modes due to analog/digital/tvencoder */ @@ -511,7 +515,8 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c, u8 val); extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector); extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); -extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); +extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, + bool requires_extended_probe); extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector); diff --git a/drivers/video/drm/radeon/radeon_reg.h b/drivers/video/drm/radeon/radeon_reg.h index df348871ce..404b4af74d 100644 --- a/drivers/video/drm/radeon/radeon_reg.h +++ b/drivers/video/drm/radeon/radeon_reg.h @@ -3295,7 +3295,7 @@ # define RADEON_RB_BUFSZ_MASK (0x3f << 0) # define RADEON_RB_BLKSZ_SHIFT 8 # define RADEON_RB_BLKSZ_MASK (0x3f << 8) -# define RADEON_BUF_SWAP_32BIT (1 << 17) +# define RADEON_BUF_SWAP_32BIT (2 << 16) # define RADEON_MAX_FETCH_SHIFT 18 # define RADEON_MAX_FETCH_MASK (0x3 << 18) # define RADEON_RB_NO_UPDATE (1 << 27) diff --git a/drivers/video/drm/radeon/rs600.c b/drivers/video/drm/radeon/rs600.c index e4eeb4e09b..6080af30b4 100644 --- a/drivers/video/drm/radeon/rs600.c +++ b/drivers/video/drm/radeon/rs600.c @@ -361,7 +361,7 @@ int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) addr = addr & 0xFFFFFFFFFFFFF000ULL; addr |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED; addr |= R600_PTE_READABLE | R600_PTE_WRITEABLE; - writeq(addr, ((void __iomem *)ptr) + (i * 8)); + writeq(addr, ptr + (i * 8)); return 0; } diff --git a/drivers/video/drm/radeon/rv770.c b/drivers/video/drm/radeon/rv770.c index ae22de669e..cef1cf5f66 100644 --- a/drivers/video/drm/radeon/rv770.c +++ b/drivers/video/drm/radeon/rv770.c @@ -701,6 +701,7 @@ static void rv770_gpu_init(struct radeon_device *rdev) (cc_rb_backend_disable >> 16)); rdev->config.rv770.tile_config = gb_tiling_config; + rdev->config.rv770.backend_map = backend_map; gb_tiling_config |= BACKEND_MAP(backend_map); WREG32(GB_TILING_CONFIG, gb_tiling_config);