From 46c3e64a4690e623629219bb794002e973e74da7 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Fri, 11 Mar 2016 10:55:22 +0000 Subject: [PATCH] atikms-4.4.5 git-svn-id: svn://kolibrios.org@6321 a494cfbc-eb01-0410-851d-a64ba20cac60 --- drivers/video/drm/radeon/atom.c | 2 +- drivers/video/drm/radeon/dce6_afmt.c | 8 + drivers/video/drm/radeon/evergreen_hdmi.c | 10 + drivers/video/drm/radeon/evergreend.h | 5 + drivers/video/drm/radeon/main.c | 2 +- drivers/video/drm/radeon/pci.c | 10 - drivers/video/drm/radeon/r600.c | 5 + drivers/video/drm/radeon/radeon.h | 17 +- drivers/video/drm/radeon/radeon_asic.c | 3 +- drivers/video/drm/radeon/radeon_atombios.c | 58 +++-- drivers/video/drm/radeon/radeon_audio.c | 22 +- drivers/video/drm/radeon/radeon_audio.h | 1 + drivers/video/drm/radeon/radeon_connectors.c | 24 ++ drivers/video/drm/radeon/radeon_cs.c | 7 - drivers/video/drm/radeon/radeon_display.c | 65 +++-- drivers/video/drm/radeon/radeon_gart.c | 2 +- drivers/video/drm/radeon/radeon_pm.c | 13 +- drivers/video/drm/radeon/radeon_sa.c | 5 + drivers/video/drm/radeon/radeon_vm.c | 12 +- drivers/video/drm/radeon/rdisplay.c | 2 +- drivers/video/drm/radeon/rdisplay_kms.c | 4 +- drivers/video/drm/radeon/sid.h | 5 + drivers/video/drm/radeon/utils.c | 238 +------------------ drivers/video/drm/radeon/vce_v1_0.c | 12 +- drivers/video/drm/ttm/ttm_tt.c | 1 + 25 files changed, 194 insertions(+), 339 deletions(-) diff --git a/drivers/video/drm/radeon/atom.c b/drivers/video/drm/radeon/atom.c index 3f489db2ee..7cbe60b930 100644 --- a/drivers/video/drm/radeon/atom.c +++ b/drivers/video/drm/radeon/atom.c @@ -93,7 +93,7 @@ static void debug_print_spaces(int n) } #define DEBUG(...) do if (atom_debug) { printk(KERN_DEBUG __VA_ARGS__); } while (0) -#define SDEBUG(...) do if (atom_debug) { printk(KERN_DEBUG); debug_print_spaces(debug_depth); printk(__VA_ARGS__); } while (0) +#define SDEBUG(...) do if (atom_debug) { printk(KERN_DEBUG); debug_print_spaces(debug_depth); printk(__VA_ARGS__);} while (0) #else #define DEBUG(...) do { } while (0) #define SDEBUG(...) do { } while (0) diff --git a/drivers/video/drm/radeon/dce6_afmt.c b/drivers/video/drm/radeon/dce6_afmt.c index 7520727713..367a916f36 100644 --- a/drivers/video/drm/radeon/dce6_afmt.c +++ b/drivers/video/drm/radeon/dce6_afmt.c @@ -301,6 +301,14 @@ void dce6_dp_audio_set_dto(struct radeon_device *rdev, * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator */ if (ASIC_IS_DCE8(rdev)) { + unsigned int div = (RREG32(DENTIST_DISPCLK_CNTL) & + DENTIST_DPREFCLK_WDIVIDER_MASK) >> + DENTIST_DPREFCLK_WDIVIDER_SHIFT; + div = radeon_audio_decode_dfs_div(div); + + if (div) + clock = clock * 100 / div; + WREG32(DCE8_DCCG_AUDIO_DTO1_PHASE, 24000); WREG32(DCE8_DCCG_AUDIO_DTO1_MODULE, clock); } else { diff --git a/drivers/video/drm/radeon/evergreen_hdmi.c b/drivers/video/drm/radeon/evergreen_hdmi.c index 9953356fe2..3cf04a2f44 100644 --- a/drivers/video/drm/radeon/evergreen_hdmi.c +++ b/drivers/video/drm/radeon/evergreen_hdmi.c @@ -289,6 +289,16 @@ void dce4_dp_audio_set_dto(struct radeon_device *rdev, * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator */ + if (ASIC_IS_DCE41(rdev)) { + unsigned int div = (RREG32(DCE41_DENTIST_DISPCLK_CNTL) & + DENTIST_DPREFCLK_WDIVIDER_MASK) >> + DENTIST_DPREFCLK_WDIVIDER_SHIFT; + div = radeon_audio_decode_dfs_div(div); + + if (div) + clock = 100 * clock / div; + } + WREG32(DCCG_AUDIO_DTO1_PHASE, 24000); WREG32(DCCG_AUDIO_DTO1_MODULE, clock); } diff --git a/drivers/video/drm/radeon/evergreend.h b/drivers/video/drm/radeon/evergreend.h index 4aa5f75557..13b6029d65 100644 --- a/drivers/video/drm/radeon/evergreend.h +++ b/drivers/video/drm/radeon/evergreend.h @@ -511,6 +511,11 @@ #define DCCG_AUDIO_DTO1_CNTL 0x05cc # define DCCG_AUDIO_DTO1_USE_512FBR_DTO (1 << 3) +#define DCE41_DENTIST_DISPCLK_CNTL 0x049c +# define DENTIST_DPREFCLK_WDIVIDER(x) (((x) & 0x7f) << 24) +# define DENTIST_DPREFCLK_WDIVIDER_MASK (0x7f << 24) +# define DENTIST_DPREFCLK_WDIVIDER_SHIFT 24 + /* DCE 4.0 AFMT */ #define HDMI_CONTROL 0x7030 # define HDMI_KEEPOUT_MODE (1 << 0) diff --git a/drivers/video/drm/radeon/main.c b/drivers/video/drm/radeon/main.c index 31189fef35..2133bae03f 100644 --- a/drivers/video/drm/radeon/main.c +++ b/drivers/video/drm/radeon/main.c @@ -5,7 +5,7 @@ #include "radeon.h" #include "bitmap.h" -#define DRV_NAME "atikms v4.4" +#define DRV_NAME "atikms v4.4.5-dbg1" void __init dmi_scan_machine(void); diff --git a/drivers/video/drm/radeon/pci.c b/drivers/video/drm/radeon/pci.c index 68d71bd440..446d40f585 100644 --- a/drivers/video/drm/radeon/pci.c +++ b/drivers/video/drm/radeon/pci.c @@ -1,5 +1,3 @@ -#define CONFIG_PCI - #include #include @@ -10,7 +8,6 @@ #include - extern int pci_scan_filter(u32 id, u32 busnr, u32 devfn); static LIST_HEAD(devices); @@ -669,13 +666,6 @@ void pci_iounmap(struct pci_dev *dev, void __iomem * addr) } -static inline void -_pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) -{ - region->start = res->start; - region->end = res->end; -} int pci_enable_rom(struct pci_dev *pdev) diff --git a/drivers/video/drm/radeon/r600.c b/drivers/video/drm/radeon/r600.c index 391722f025..fb5b53a40f 100644 --- a/drivers/video/drm/radeon/r600.c +++ b/drivers/video/drm/radeon/r600.c @@ -3128,6 +3128,11 @@ static int r600_startup(struct radeon_device *rdev) return r; } + r = radeon_audio_init(rdev); + if (r) { + DRM_ERROR("radeon: audio init failed\n"); + return r; + } return 0; } diff --git a/drivers/video/drm/radeon/radeon.h b/drivers/video/drm/radeon/radeon.h index f4d880831d..450a05a353 100644 --- a/drivers/video/drm/radeon/radeon.h +++ b/drivers/video/drm/radeon/radeon.h @@ -120,18 +120,6 @@ extern int radeon_backlight; extern int radeon_auxch; extern int radeon_mst; - -static inline u32 ioread32(const volatile void __iomem *addr) -{ - return in32((u32)addr); -} - -//static inline void iowrite32(uint32_t b, volatile void __iomem *addr) -//{ -// out32((u32)addr, b); -//} - - /* * Copy from radeon_drv.h so we don't have to include both and have conflicting * symbol; @@ -286,6 +274,7 @@ struct radeon_clock { uint32_t current_dispclk; uint32_t dp_extclk; uint32_t max_pixel_clock; + uint32_t vco_freq; }; /* @@ -2386,7 +2375,8 @@ struct radeon_device { struct r600_ih ih; /* r6/700 interrupt ring */ struct radeon_rlc rlc; struct radeon_mec mec; - struct work_struct hotplug_work; + struct delayed_work hotplug_work; + struct work_struct dp_work; struct work_struct audio_work; int num_crtc; /* number of crtcs */ struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ @@ -2937,5 +2927,6 @@ drm_get_resource_start(struct drm_device *dev, unsigned int resource); resource_size_t drm_get_resource_len(struct drm_device *dev, unsigned int resource); +#define ioread32(addr) readl(addr) #endif diff --git a/drivers/video/drm/radeon/radeon_asic.c b/drivers/video/drm/radeon/radeon_asic.c index 21126eebe2..fdcd4f4bd6 100644 --- a/drivers/video/drm/radeon/radeon_asic.c +++ b/drivers/video/drm/radeon/radeon_asic.c @@ -256,8 +256,7 @@ static struct radeon_asic r100_asic = { .set_clock_gating = &radeon_legacy_set_clock_gating, }, .pflip = { -// .pre_page_flip = &r100_pre_page_flip, -// .page_flip = &r100_page_flip, + }, }; diff --git a/drivers/video/drm/radeon/radeon_atombios.c b/drivers/video/drm/radeon/radeon_atombios.c index 8708127c54..c35e5cc723 100644 --- a/drivers/video/drm/radeon/radeon_atombios.c +++ b/drivers/video/drm/radeon/radeon_atombios.c @@ -437,7 +437,9 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, } /* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */ - if (((dev->pdev->device == 0x9802) || (dev->pdev->device == 0x9806)) && + if (((dev->pdev->device == 0x9802) || + (dev->pdev->device == 0x9805) || + (dev->pdev->device == 0x9806)) && (dev->pdev->subsystem_vendor == 0x1734) && (dev->pdev->subsystem_device == 0x11bd)) { if (*connector_type == DRM_MODE_CONNECTOR_VGA) { @@ -448,14 +450,6 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, } } - /* Fujitsu D3003-S2 board lists DVI-I as DVI-I and VGA */ - if ((dev->pdev->device == 0x9805) && - (dev->pdev->subsystem_vendor == 0x1734) && - (dev->pdev->subsystem_device == 0x11bd)) { - if (*connector_type == DRM_MODE_CONNECTOR_VGA) - return false; - } - return true; } @@ -1112,6 +1106,31 @@ union firmware_info { ATOM_FIRMWARE_INFO_V2_2 info_22; }; +union igp_info { + struct _ATOM_INTEGRATED_SYSTEM_INFO info; + struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; + struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6; + struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7; + struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8; +}; + +static void radeon_atombios_get_dentist_vco_freq(struct radeon_device *rdev) +{ + struct radeon_mode_info *mode_info = &rdev->mode_info; + int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); + union igp_info *igp_info; + u8 frev, crev; + u16 data_offset; + + if (atom_parse_data_header(mode_info->atom_context, index, NULL, + &frev, &crev, &data_offset)) { + igp_info = (union igp_info *)(mode_info->atom_context->bios + + data_offset); + rdev->clock.vco_freq = + le32_to_cpu(igp_info->info_6.ulDentistVCOFreq); + } +} + bool radeon_atom_get_clock_info(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; @@ -1263,20 +1282,25 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) rdev->mode_info.firmware_flags = le16_to_cpu(firmware_info->info.usFirmwareCapability.susAccess); + if (ASIC_IS_DCE8(rdev)) + rdev->clock.vco_freq = + le32_to_cpu(firmware_info->info_22.ulGPUPLL_OutputFreq); + else if (ASIC_IS_DCE5(rdev)) + rdev->clock.vco_freq = rdev->clock.current_dispclk; + else if (ASIC_IS_DCE41(rdev)) + radeon_atombios_get_dentist_vco_freq(rdev); + else + rdev->clock.vco_freq = rdev->clock.current_dispclk; + + if (rdev->clock.vco_freq == 0) + rdev->clock.vco_freq = 360000; /* 3.6 GHz */ + return true; } return false; } -union igp_info { - struct _ATOM_INTEGRATED_SYSTEM_INFO info; - struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; - struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6; - struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7; - struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8; -}; - bool radeon_atombios_sideport_present(struct radeon_device *rdev) { struct radeon_mode_info *mode_info = &rdev->mode_info; diff --git a/drivers/video/drm/radeon/radeon_audio.c b/drivers/video/drm/radeon/radeon_audio.c index 6fbe854e10..b214663b37 100644 --- a/drivers/video/drm/radeon/radeon_audio.c +++ b/drivers/video/drm/radeon/radeon_audio.c @@ -22,7 +22,7 @@ * Authors: Slava Grigorev */ -//#include +#include #include #include #include "radeon.h" @@ -739,9 +739,6 @@ static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct radeon_connector_atom_dig *dig_connector = - radeon_connector->con_priv; if (!dig || !dig->afmt) return; @@ -753,10 +750,7 @@ static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, radeon_audio_write_speaker_allocation(encoder); radeon_audio_write_sad_regs(encoder); radeon_audio_write_latency_fields(encoder, mode); - if (rdev->clock.dp_extclk || ASIC_IS_DCE5(rdev)) - radeon_audio_set_dto(encoder, rdev->clock.default_dispclk * 10); - else - radeon_audio_set_dto(encoder, dig_connector->dp_clock); + radeon_audio_set_dto(encoder, rdev->clock.vco_freq * 10); radeon_audio_set_audio_packet(encoder); radeon_audio_select_pin(encoder); @@ -781,3 +775,15 @@ void radeon_audio_dpms(struct drm_encoder *encoder, int mode) if (radeon_encoder->audio && radeon_encoder->audio->dpms) radeon_encoder->audio->dpms(encoder, mode == DRM_MODE_DPMS_ON); } + +unsigned int radeon_audio_decode_dfs_div(unsigned int div) +{ + if (div >= 8 && div < 64) + return (div - 8) * 25 + 200; + else if (div >= 64 && div < 96) + return (div - 64) * 50 + 1600; + else if (div >= 96 && div < 128) + return (div - 96) * 100 + 3200; + else + return 0; +} diff --git a/drivers/video/drm/radeon/radeon_audio.h b/drivers/video/drm/radeon/radeon_audio.h index 059cc30120..5c70cceaa4 100644 --- a/drivers/video/drm/radeon/radeon_audio.h +++ b/drivers/video/drm/radeon/radeon_audio.h @@ -79,5 +79,6 @@ void radeon_audio_fini(struct radeon_device *rdev); void radeon_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode); void radeon_audio_dpms(struct drm_encoder *encoder, int mode); +unsigned int radeon_audio_decode_dfs_div(unsigned int div); #endif diff --git a/drivers/video/drm/radeon/radeon_connectors.c b/drivers/video/drm/radeon/radeon_connectors.c index a35d0a508b..21dc1121d0 100644 --- a/drivers/video/drm/radeon/radeon_connectors.c +++ b/drivers/video/drm/radeon/radeon_connectors.c @@ -1138,6 +1138,10 @@ radeon_tv_detect(struct drm_connector *connector, bool force) if (!radeon_connector->dac_load_detect) return ret; + r = pm_runtime_get_sync(connector->dev->dev); + if (r < 0) + return connector_status_disconnected; + encoder = radeon_best_single_encoder(connector); if (!encoder) ret = connector_status_disconnected; @@ -1148,6 +1152,8 @@ radeon_tv_detect(struct drm_connector *connector, bool force) if (ret == connector_status_connected) ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false); radeon_connector_update_scratch_regs(connector, ret); + pm_runtime_mark_last_busy(connector->dev->dev); + pm_runtime_put_autosuspend(connector->dev->dev); return ret; } @@ -1209,6 +1215,14 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) enum drm_connector_status ret = connector_status_disconnected; bool dret = false, broken_edid = false; + r = pm_runtime_get_sync(connector->dev->dev); + if (r < 0) + return connector_status_disconnected; + + if (radeon_connector->detected_hpd_without_ddc) { + force = true; + radeon_connector->detected_hpd_without_ddc = false; + } if (!force && radeon_check_hpd_status_unchanged(connector)) { ret = connector->status; @@ -1373,6 +1387,9 @@ out: } exit: + pm_runtime_mark_last_busy(connector->dev->dev); + pm_runtime_put_autosuspend(connector->dev->dev); + return ret; } @@ -1621,6 +1638,10 @@ radeon_dp_detect(struct drm_connector *connector, bool force) if (radeon_dig_connector->is_mst) return connector_status_disconnected; + r = pm_runtime_get_sync(connector->dev->dev); + if (r < 0) + return connector_status_disconnected; + if (!force && radeon_check_hpd_status_unchanged(connector)) { ret = connector->status; goto out; @@ -1706,6 +1727,9 @@ radeon_dp_detect(struct drm_connector *connector, bool force) } out: + pm_runtime_mark_last_busy(connector->dev->dev); + pm_runtime_put_autosuspend(connector->dev->dev); + return ret; } diff --git a/drivers/video/drm/radeon/radeon_cs.c b/drivers/video/drm/radeon/radeon_cs.c index 9e89b8da46..ea3e7226d9 100644 --- a/drivers/video/drm/radeon/radeon_cs.c +++ b/drivers/video/drm/radeon/radeon_cs.c @@ -34,13 +34,6 @@ #define RADEON_CS_MAX_PRIORITY 32u #define RADEON_CS_NUM_BUCKETS (RADEON_CS_MAX_PRIORITY + 1) -static inline unsigned long -copy_from_user(void *to, const void __user *from, unsigned long n) -{ - memcpy(to, from, n); - return n; -} - /* This is based on the bucket sort with O(n) time complexity. * An item with priority "i" is added to bucket[i]. The lists are then * concatenated in descending order. diff --git a/drivers/video/drm/radeon/radeon_display.c b/drivers/video/drm/radeon/radeon_display.c index 4a1a86ee7c..10f69d17e3 100644 --- a/drivers/video/drm/radeon/radeon_display.c +++ b/drivers/video/drm/radeon/radeon_display.c @@ -1449,6 +1449,15 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, * \param dev Device to query. * \param crtc Crtc to query. * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). + * For driver internal use only also supports these flags: + * + * USE_REAL_VBLANKSTART to use the real start of vblank instead + * of a fudged earlier start of vblank. + * + * GET_DISTANCE_TO_VBLANKSTART to return distance to the + * fudged earlier start of vblank in *vpos and the distance + * to true start of vblank in *hpos. + * * \param *vpos Location where vertical scanout position should be stored. * \param *hpos Location where horizontal scanout position should go. * \param *stime Target location for timestamp taken immediately before @@ -1592,10 +1601,40 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, vbl_end = 0; } + /* Called from driver internal vblank counter query code? */ + if (flags & GET_DISTANCE_TO_VBLANKSTART) { + /* Caller wants distance from real vbl_start in *hpos */ + *hpos = *vpos - vbl_start; + } + + /* Fudge vblank to start a few scanlines earlier to handle the + * problem that vblank irqs fire a few scanlines before start + * of vblank. Some driver internal callers need the true vblank + * start to be used and signal this via the USE_REAL_VBLANKSTART flag. + * + * The cause of the "early" vblank irq is that the irq is triggered + * by the line buffer logic when the line buffer read position enters + * the vblank, whereas our crtc scanout position naturally lags the + * line buffer read position. + */ + if (!(flags & USE_REAL_VBLANKSTART)) + vbl_start -= rdev->mode_info.crtcs[pipe]->lb_vblank_lead_lines; + /* Test scanout position against vblank region. */ if ((*vpos < vbl_start) && (*vpos >= vbl_end)) in_vbl = false; + /* In vblank? */ + if (in_vbl) + ret |= DRM_SCANOUTPOS_IN_VBLANK; + + /* Called from driver internal vblank counter query code? */ + if (flags & GET_DISTANCE_TO_VBLANKSTART) { + /* Caller wants distance from fudged earlier vbl_start */ + *vpos -= vbl_start; + return ret; + } + /* Check if inside vblank area and apply corrective offsets: * vpos will then be >=0 in video scanout area, but negative * within vblank area, counting down the number of lines until @@ -1611,31 +1650,5 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, /* Correct for shifted end of vbl at vbl_end. */ *vpos = *vpos - vbl_end; - /* In vblank? */ - if (in_vbl) - ret |= DRM_SCANOUTPOS_IN_VBLANK; - - /* Is vpos outside nominal vblank area, but less than - * 1/100 of a frame height away from start of vblank? - * If so, assume this isn't a massively delayed vblank - * interrupt, but a vblank interrupt that fired a few - * microseconds before true start of vblank. Compensate - * by adding a full frame duration to the final timestamp. - * Happens, e.g., on ATI R500, R600. - * - * We only do this if DRM_CALLED_FROM_VBLIRQ. - */ - if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) { - vbl_start = mode->crtc_vdisplay; - vtotal = mode->crtc_vtotal; - - if (vbl_start - *vpos < vtotal / 100) { - *vpos -= vtotal; - - /* Signal this correction as "applied". */ - ret |= 0x8; - } - } - return ret; } diff --git a/drivers/video/drm/radeon/radeon_gart.c b/drivers/video/drm/radeon/radeon_gart.c index 12879ed02e..88e4622e98 100644 --- a/drivers/video/drm/radeon/radeon_gart.c +++ b/drivers/video/drm/radeon/radeon_gart.c @@ -29,7 +29,7 @@ #include #include "radeon.h" - +#undef CONFIG_X86 void* pci_alloc_consistent(struct pci_dev *hwdev, size_t size, addr_t *dma_handle) { diff --git a/drivers/video/drm/radeon/radeon_pm.c b/drivers/video/drm/radeon/radeon_pm.c index da5208ff15..7de076a8ff 100644 --- a/drivers/video/drm/radeon/radeon_pm.c +++ b/drivers/video/drm/radeon/radeon_pm.c @@ -897,12 +897,6 @@ force: /* update display watermarks based on new power state */ radeon_bandwidth_update(rdev); - /* update displays */ - radeon_dpm_display_configuration_changed(rdev); - - rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs; - rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count; - rdev->pm.dpm.single_display = single_display; /* wait for the rings to drain */ for (i = 0; i < RADEON_NUM_RINGS; i++) { @@ -919,6 +913,13 @@ force: radeon_dpm_post_set_power_state(rdev); + /* update displays */ + radeon_dpm_display_configuration_changed(rdev); + + rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs; + rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count; + rdev->pm.dpm.single_display = single_display; + if (rdev->asic->dpm.force_performance_level) { if (rdev->pm.dpm.thermal_active) { enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level; diff --git a/drivers/video/drm/radeon/radeon_sa.c b/drivers/video/drm/radeon/radeon_sa.c index 830d1e52ed..baa63f74b3 100644 --- a/drivers/video/drm/radeon/radeon_sa.c +++ b/drivers/video/drm/radeon/radeon_sa.c @@ -349,8 +349,13 @@ int radeon_sa_bo_new(struct radeon_device *rdev, /* see if we can skip over some allocations */ } while (radeon_sa_bo_next_hole(sa_manager, fences, tries)); + for (i = 0; i < RADEON_NUM_RINGS; ++i) + radeon_fence_ref(fences[i]); + spin_unlock(&sa_manager->wq.lock); r = radeon_fence_wait_any(rdev, fences, false); + for (i = 0; i < RADEON_NUM_RINGS; ++i) + radeon_fence_unref(&fences[i]); spin_lock(&sa_manager->wq.lock); /* if we have nothing to wait for block */ if (r == -ENOENT) { diff --git a/drivers/video/drm/radeon/radeon_vm.c b/drivers/video/drm/radeon/radeon_vm.c index bf9b403126..eaafe52eb0 100644 --- a/drivers/video/drm/radeon/radeon_vm.c +++ b/drivers/video/drm/radeon/radeon_vm.c @@ -455,15 +455,15 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, if (soffset) { /* make sure object fit at this offset */ - eoffset = soffset + size; + eoffset = soffset + size - 1; if (soffset >= eoffset) { r = -EINVAL; goto error_unreserve; } last_pfn = eoffset / RADEON_GPU_PAGE_SIZE; - if (last_pfn > rdev->vm_manager.max_pfn) { - dev_err(rdev->dev, "va above limit (0x%08X > 0x%08X)\n", + if (last_pfn >= rdev->vm_manager.max_pfn) { + dev_err(rdev->dev, "va above limit (0x%08X >= 0x%08X)\n", last_pfn, rdev->vm_manager.max_pfn); r = -EINVAL; goto error_unreserve; @@ -478,7 +478,7 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, eoffset /= RADEON_GPU_PAGE_SIZE; if (soffset || eoffset) { struct interval_tree_node *it; - it = interval_tree_iter_first(&vm->va, soffset, eoffset - 1); + it = interval_tree_iter_first(&vm->va, soffset, eoffset); if (it && it != &bo_va->it) { struct radeon_bo_va *tmp; tmp = container_of(it, struct radeon_bo_va, it); @@ -518,7 +518,7 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, if (soffset || eoffset) { spin_lock(&vm->status_lock); bo_va->it.start = soffset; - bo_va->it.last = eoffset - 1; + bo_va->it.last = eoffset; list_add(&bo_va->vm_status, &vm->cleared); spin_unlock(&vm->status_lock); interval_tree_insert(&bo_va->it, &vm->va); @@ -888,7 +888,7 @@ static void radeon_vm_fence_pts(struct radeon_vm *vm, unsigned i; start >>= radeon_vm_block_size; - end >>= radeon_vm_block_size; + end = (end - 1) >> radeon_vm_block_size; for (i = start; i <= end; ++i) radeon_bo_fence(vm->page_tables[i].bo, fence, true); diff --git a/drivers/video/drm/radeon/rdisplay.c b/drivers/video/drm/radeon/rdisplay.c index 821e7318fb..395b8b5619 100644 --- a/drivers/video/drm/radeon/rdisplay.c +++ b/drivers/video/drm/radeon/rdisplay.c @@ -3,7 +3,7 @@ #include #include "radeon.h" #include "radeon_object.h" -#include "bitmap.h" + #include #include "r100d.h" diff --git a/drivers/video/drm/radeon/rdisplay_kms.c b/drivers/video/drm/radeon/rdisplay_kms.c index 3da3a6cbe0..509f1fa3d4 100644 --- a/drivers/video/drm/radeon/rdisplay_kms.c +++ b/drivers/video/drm/radeon/rdisplay_kms.c @@ -5,7 +5,6 @@ #include "radeon_object.h" #include "drm_fb_helper.h" #include "hmm.h" -#include "bitmap.h" #include extern struct drm_framebuffer *main_fb; @@ -16,6 +15,9 @@ display_t *os_display; static cursor_t* __stdcall select_cursor_kms(cursor_t *cursor); static void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y); +extern int init_cursor(cursor_t *cursor); +extern void __stdcall restore_cursor(int x, int y); + int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled); void disable_mouse(void); diff --git a/drivers/video/drm/radeon/sid.h b/drivers/video/drm/radeon/sid.h index 4c4a7218a3..d1a7b58dd2 100644 --- a/drivers/video/drm/radeon/sid.h +++ b/drivers/video/drm/radeon/sid.h @@ -915,6 +915,11 @@ #define DCCG_AUDIO_DTO1_PHASE 0x05c0 #define DCCG_AUDIO_DTO1_MODULE 0x05c4 +#define DENTIST_DISPCLK_CNTL 0x0490 +# define DENTIST_DPREFCLK_WDIVIDER(x) (((x) & 0x7f) << 24) +# define DENTIST_DPREFCLK_WDIVIDER_MASK (0x7f << 24) +# define DENTIST_DPREFCLK_WDIVIDER_SHIFT 24 + #define AFMT_AUDIO_SRC_CONTROL 0x713c #define AFMT_AUDIO_SRC_SELECT(x) (((x) & 7) << 0) /* AFMT_AUDIO_SRC_SELECT diff --git a/drivers/video/drm/radeon/utils.c b/drivers/video/drm/radeon/utils.c index 116f1dffe4..bb0182b913 100644 --- a/drivers/video/drm/radeon/utils.c +++ b/drivers/video/drm/radeon/utils.c @@ -159,239 +159,6 @@ static inline char _tolower(const char c) } -//const char hex_asc[] = "0123456789abcdef"; - -/** - * hex_to_bin - convert a hex digit to its real value - * @ch: ascii character represents hex digit - * - * hex_to_bin() converts one hex digit to its actual value or -1 in case of bad - * input. - */ -int hex_to_bin(char ch) -{ - if ((ch >= '0') && (ch <= '9')) - return ch - '0'; - ch = tolower(ch); - if ((ch >= 'a') && (ch <= 'f')) - return ch - 'a' + 10; - return -1; -} -EXPORT_SYMBOL(hex_to_bin); - -/** - * hex2bin - convert an ascii hexadecimal string to its binary representation - * @dst: binary result - * @src: ascii hexadecimal string - * @count: result length - * - * Return 0 on success, -1 in case of bad input. - */ -int hex2bin(u8 *dst, const char *src, size_t count) -{ - while (count--) { - int hi = hex_to_bin(*src++); - int lo = hex_to_bin(*src++); - - if ((hi < 0) || (lo < 0)) - return -1; - - *dst++ = (hi << 4) | lo; - } - return 0; -} -EXPORT_SYMBOL(hex2bin); - -/** - * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory - * @buf: data blob to dump - * @len: number of bytes in the @buf - * @rowsize: number of bytes to print per line; must be 16 or 32 - * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1) - * @linebuf: where to put the converted data - * @linebuflen: total size of @linebuf, including space for terminating NUL - * @ascii: include ASCII after the hex output - * - * hex_dump_to_buffer() works on one "line" of output at a time, i.e., - * 16 or 32 bytes of input data converted to hex + ASCII output. - * - * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data - * to a hex + ASCII dump at the supplied memory location. - * The converted output is always NUL-terminated. - * - * E.g.: - * hex_dump_to_buffer(frame->data, frame->len, 16, 1, - * linebuf, sizeof(linebuf), true); - * - * example output buffer: - * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO - */ -int hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int groupsize, - char *linebuf, size_t linebuflen, bool ascii) -{ - const u8 *ptr = buf; - int ngroups; - u8 ch; - int j, lx = 0; - int ascii_column; - int ret; - - if (rowsize != 16 && rowsize != 32) - rowsize = 16; - - if (len > rowsize) /* limit to one line at a time */ - len = rowsize; - if (!is_power_of_2(groupsize) || groupsize > 8) - groupsize = 1; - if ((len % groupsize) != 0) /* no mixed size output */ - groupsize = 1; - - ngroups = len / groupsize; - ascii_column = rowsize * 2 + rowsize / groupsize + 1; - - if (!linebuflen) - goto overflow1; - - if (!len) - goto nil; - - if (groupsize == 8) { - const u64 *ptr8 = buf; - - for (j = 0; j < ngroups; j++) { - ret = snprintf(linebuf + lx, linebuflen - lx, - "%s%16.16llx", j ? " " : "", - (unsigned long long)*(ptr8 + j)); - if (ret >= linebuflen - lx) - goto overflow1; - lx += ret; - } - } else if (groupsize == 4) { - const u32 *ptr4 = buf; - - for (j = 0; j < ngroups; j++) { - ret = snprintf(linebuf + lx, linebuflen - lx, - "%s%8.8x", j ? " " : "", - *(ptr4 + j)); - if (ret >= linebuflen - lx) - goto overflow1; - lx += ret; - } - } else if (groupsize == 2) { - const u16 *ptr2 = buf; - - for (j = 0; j < ngroups; j++) { - ret = snprintf(linebuf + lx, linebuflen - lx, - "%s%4.4x", j ? " " : "", - *(ptr2 + j)); - if (ret >= linebuflen - lx) - goto overflow1; - lx += ret; - } - } else { - for (j = 0; j < len; j++) { - if (linebuflen < lx + 3) - goto overflow2; - ch = ptr[j]; - linebuf[lx++] = hex_asc_hi(ch); - linebuf[lx++] = hex_asc_lo(ch); - linebuf[lx++] = ' '; - } - if (j) - lx--; - } - if (!ascii) - goto nil; - - while (lx < ascii_column) { - if (linebuflen < lx + 2) - goto overflow2; - linebuf[lx++] = ' '; - } - for (j = 0; j < len; j++) { - if (linebuflen < lx + 2) - goto overflow2; - ch = ptr[j]; - linebuf[lx++] = (isascii(ch) && isprint(ch)) ? ch : '.'; - } -nil: - linebuf[lx] = '\0'; - return lx; -overflow2: - linebuf[lx++] = '\0'; -overflow1: - return ascii ? ascii_column + len : (groupsize * 2 + 1) * ngroups - 1; -} -/** - * print_hex_dump - print a text hex dump to syslog for a binary blob of data - * @level: kernel log level (e.g. KERN_DEBUG) - * @prefix_str: string to prefix each line with; - * caller supplies trailing spaces for alignment if desired - * @prefix_type: controls whether prefix of an offset, address, or none - * is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE) - * @rowsize: number of bytes to print per line; must be 16 or 32 - * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1) - * @buf: data blob to dump - * @len: number of bytes in the @buf - * @ascii: include ASCII after the hex output - * - * Given a buffer of u8 data, print_hex_dump() prints a hex + ASCII dump - * to the kernel log at the specified kernel log level, with an optional - * leading prefix. - * - * print_hex_dump() works on one "line" of output at a time, i.e., - * 16 or 32 bytes of input data converted to hex + ASCII output. - * print_hex_dump() iterates over the entire input @buf, breaking it into - * "line size" chunks to format and print. - * - * E.g.: - * print_hex_dump(KERN_DEBUG, "raw data: ", DUMP_PREFIX_ADDRESS, - * 16, 1, frame->data, frame->len, true); - * - * Example output using %DUMP_PREFIX_OFFSET and 1-byte mode: - * 0009ab42: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO - * Example output using %DUMP_PREFIX_ADDRESS and 4-byte mode: - * ffffffff88089af0: 73727170 77767574 7b7a7978 7f7e7d7c pqrstuvwxyz{|}~. - */ -void print_hex_dump(const char *level, const char *prefix_str, int prefix_type, - int rowsize, int groupsize, - const void *buf, size_t len, bool ascii) -{ - const u8 *ptr = buf; - int i, linelen, remaining = len; - unsigned char linebuf[32 * 3 + 2 + 32 + 1]; - - if (rowsize != 16 && rowsize != 32) - rowsize = 16; - - for (i = 0; i < len; i += rowsize) { - linelen = min(remaining, rowsize); - remaining -= rowsize; - - hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize, - linebuf, sizeof(linebuf), ascii); - - switch (prefix_type) { - case DUMP_PREFIX_ADDRESS: - printk("%s%s%p: %s\n", - level, prefix_str, ptr + i, linebuf); - break; - case DUMP_PREFIX_OFFSET: - printk("%s%s%.8x: %s\n", level, prefix_str, i, linebuf); - break; - default: - printk("%s%s%s\n", level, prefix_str, linebuf); - break; - } - } -} - -void print_hex_dump_bytes(const char *prefix_str, int prefix_type, - const void *buf, size_t len) -{ - print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, 16, 1, - buf, len, true); -} #define KMAP_MAX 256 @@ -1119,3 +886,8 @@ unsigned long gcd(unsigned long a, unsigned long b) return b; } +void vfree(const void *addr) +{ + KernelFree(addr); +} + diff --git a/drivers/video/drm/radeon/vce_v1_0.c b/drivers/video/drm/radeon/vce_v1_0.c index 07a0d378e1..a01efe39a8 100644 --- a/drivers/video/drm/radeon/vce_v1_0.c +++ b/drivers/video/drm/radeon/vce_v1_0.c @@ -178,12 +178,12 @@ int vce_v1_0_load_fw(struct radeon_device *rdev, uint32_t *data) return -EINVAL; } - for (i = 0; i < sign->num; ++i) { - if (sign->val[i].chip_id == chip_id) + for (i = 0; i < le32_to_cpu(sign->num); ++i) { + if (le32_to_cpu(sign->val[i].chip_id) == chip_id) break; } - if (i == sign->num) + if (i == le32_to_cpu(sign->num)) return -EINVAL; data += (256 - 64) / 4; @@ -191,18 +191,18 @@ int vce_v1_0_load_fw(struct radeon_device *rdev, uint32_t *data) data[1] = sign->val[i].nonce[1]; data[2] = sign->val[i].nonce[2]; data[3] = sign->val[i].nonce[3]; - data[4] = sign->len + 64; + data[4] = cpu_to_le32(le32_to_cpu(sign->len) + 64); memset(&data[5], 0, 44); memcpy(&data[16], &sign[1], rdev->vce_fw->size - sizeof(*sign)); - data += data[4] / 4; + data += le32_to_cpu(data[4]) / 4; data[0] = sign->val[i].sigval[0]; data[1] = sign->val[i].sigval[1]; data[2] = sign->val[i].sigval[2]; data[3] = sign->val[i].sigval[3]; - rdev->vce.keyselect = sign->val[i].keyselect; + rdev->vce.keyselect = le32_to_cpu(sign->val[i].keyselect); return 0; } diff --git a/drivers/video/drm/ttm/ttm_tt.c b/drivers/video/drm/ttm/ttm_tt.c index d54325af98..1e7f0d01aa 100644 --- a/drivers/video/drm/ttm/ttm_tt.c +++ b/drivers/video/drm/ttm/ttm_tt.c @@ -47,6 +47,7 @@ #include #include +#undef CONFIG_X86 /** * Allocates storage for pointers to the pages that back the ttm. */