Commit 74e16974 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-next-3.9' of git://people.freedesktop.org/~agd5f/linux into drm-next

More drm-next bits for radeon.  Just bug fixes.

* 'drm-next-3.9' of git://people.freedesktop.org/~agd5f/linux:
  drm/radeon: properly validate the atpx interface
  drm/radeon: switch get_gpu_clock() to a callback (v2)
  drm/radeon: add a asic callback to get the xclk
  drm/radeon: Avoid NULL pointer dereference from atom_index_iio() allocation failure
  drm/radeon: remove overzealous warning in hdmi handling
  drm/radeon: fix multi-head power profile stability on BTC+ asics
parents e9f211ad 43a23aa4
...@@ -1238,6 +1238,8 @@ static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; ...@@ -1238,6 +1238,8 @@ static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 };
static void atom_index_iio(struct atom_context *ctx, int base) static void atom_index_iio(struct atom_context *ctx, int base)
{ {
ctx->iio = kzalloc(2 * 256, GFP_KERNEL); ctx->iio = kzalloc(2 * 256, GFP_KERNEL);
if (!ctx->iio)
return;
while (CU8(base) == ATOM_IIO_START) { while (CU8(base) == ATOM_IIO_START) {
ctx->iio[CU8(base + 1)] = base + 2; ctx->iio[CU8(base + 1)] = base + 2;
base += 2; base += 2;
...@@ -1287,6 +1289,10 @@ struct atom_context *atom_parse(struct card_info *card, void *bios) ...@@ -1287,6 +1289,10 @@ struct atom_context *atom_parse(struct card_info *card, void *bios)
ctx->cmd_table = CU16(base + ATOM_ROM_CMD_PTR); ctx->cmd_table = CU16(base + ATOM_ROM_CMD_PTR);
ctx->data_table = CU16(base + ATOM_ROM_DATA_PTR); ctx->data_table = CU16(base + ATOM_ROM_DATA_PTR);
atom_index_iio(ctx, CU16(ctx->data_table + ATOM_DATA_IIO_PTR) + 4); atom_index_iio(ctx, CU16(ctx->data_table + ATOM_DATA_IIO_PTR) + 4);
if (!ctx->iio) {
atom_destroy(ctx);
return NULL;
}
str = CSTR(CU16(base + ATOM_ROM_MSG_PTR)); str = CSTR(CU16(base + ATOM_ROM_MSG_PTR));
while (*str && ((*str == '\n') || (*str == '\r'))) while (*str && ((*str == '\n') || (*str == '\r')))
...@@ -1335,8 +1341,7 @@ int atom_asic_init(struct atom_context *ctx) ...@@ -1335,8 +1341,7 @@ int atom_asic_init(struct atom_context *ctx)
void atom_destroy(struct atom_context *ctx) void atom_destroy(struct atom_context *ctx)
{ {
if (ctx->iio) kfree(ctx->iio);
kfree(ctx->iio);
kfree(ctx); kfree(ctx);
} }
......
...@@ -403,6 +403,19 @@ void evergreen_pm_misc(struct radeon_device *rdev) ...@@ -403,6 +403,19 @@ void evergreen_pm_misc(struct radeon_device *rdev)
rdev->pm.current_vddc = voltage->voltage; rdev->pm.current_vddc = voltage->voltage;
DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage); DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage);
} }
/* starting with BTC, there is one state that is used for both
* MH and SH. Difference is that we always use the high clock index for
* mclk and vddci.
*/
if ((rdev->pm.pm_method == PM_METHOD_PROFILE) &&
(rdev->family >= CHIP_BARTS) &&
rdev->pm.active_crtc_count &&
((rdev->pm.profile_index == PM_PROFILE_MID_MH_IDX) ||
(rdev->pm.profile_index == PM_PROFILE_LOW_MH_IDX)))
voltage = &rdev->pm.power_state[req_ps_idx].
clock_info[rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx].voltage;
/* 0xff01 is a flag rather then an actual voltage */ /* 0xff01 is a flag rather then an actual voltage */
if (voltage->vddci == 0xff01) if (voltage->vddci == 0xff01)
return; return;
......
...@@ -109,6 +109,19 @@ void r600_fini(struct radeon_device *rdev); ...@@ -109,6 +109,19 @@ void r600_fini(struct radeon_device *rdev);
void r600_irq_disable(struct radeon_device *rdev); void r600_irq_disable(struct radeon_device *rdev);
static void r600_pcie_gen2_enable(struct radeon_device *rdev); static void r600_pcie_gen2_enable(struct radeon_device *rdev);
/**
* r600_get_xclk - get the xclk
*
* @rdev: radeon_device pointer
*
* Returns the reference clock used by the gfx engine
* (r6xx, IGPs, APUs).
*/
u32 r600_get_xclk(struct radeon_device *rdev)
{
return rdev->clock.spll.reference_freq;
}
/* get temperature in millidegrees */ /* get temperature in millidegrees */
int rv6xx_get_temp(struct radeon_device *rdev) int rv6xx_get_temp(struct radeon_device *rdev)
{ {
...@@ -4448,14 +4461,14 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev) ...@@ -4448,14 +4461,14 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev)
} }
/** /**
* r600_get_gpu_clock - return GPU clock counter snapshot * r600_get_gpu_clock_counter - return GPU clock counter snapshot
* *
* @rdev: radeon_device pointer * @rdev: radeon_device pointer
* *
* Fetches a GPU clock counter snapshot (R6xx-cayman). * Fetches a GPU clock counter snapshot (R6xx-cayman).
* Returns the 64 bit clock counter snapshot. * Returns the 64 bit clock counter snapshot.
*/ */
uint64_t r600_get_gpu_clock(struct radeon_device *rdev) uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev)
{ {
uint64_t clock; uint64_t clock;
......
...@@ -544,7 +544,6 @@ void r600_hdmi_disable(struct drm_encoder *encoder) ...@@ -544,7 +544,6 @@ void r600_hdmi_disable(struct drm_encoder *encoder)
/* Called for ATOM_ENCODER_MODE_HDMI only */ /* Called for ATOM_ENCODER_MODE_HDMI only */
if (!dig || !dig->afmt) { if (!dig || !dig->afmt) {
WARN_ON(1);
return; return;
} }
if (!dig->afmt->enabled) if (!dig->afmt->enabled)
......
...@@ -1178,6 +1178,10 @@ struct radeon_asic { ...@@ -1178,6 +1178,10 @@ struct radeon_asic {
bool (*gui_idle)(struct radeon_device *rdev); bool (*gui_idle)(struct radeon_device *rdev);
/* wait for mc_idle */ /* wait for mc_idle */
int (*mc_wait_for_idle)(struct radeon_device *rdev); int (*mc_wait_for_idle)(struct radeon_device *rdev);
/* get the reference clock */
u32 (*get_xclk)(struct radeon_device *rdev);
/* get the gpu clock counter */
uint64_t (*get_gpu_clock_counter)(struct radeon_device *rdev);
/* gart */ /* gart */
struct { struct {
void (*tlb_flush)(struct radeon_device *rdev); void (*tlb_flush)(struct radeon_device *rdev);
...@@ -1859,6 +1863,8 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); ...@@ -1859,6 +1863,8 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
#define radeon_post_page_flip(rdev, crtc) (rdev)->asic->pflip.post_page_flip((rdev), (crtc)) #define radeon_post_page_flip(rdev, crtc) (rdev)->asic->pflip.post_page_flip((rdev), (crtc))
#define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc)) #define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc))
#define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev)) #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev))
#define radeon_get_xclk(rdev) (rdev)->asic->get_xclk((rdev))
#define radeon_get_gpu_clock_counter(rdev) (rdev)->asic->get_gpu_clock_counter((rdev))
/* Common functions */ /* Common functions */
/* AGP */ /* AGP */
......
...@@ -934,6 +934,8 @@ static struct radeon_asic r600_asic = { ...@@ -934,6 +934,8 @@ static struct radeon_asic r600_asic = {
.ioctl_wait_idle = r600_ioctl_wait_idle, .ioctl_wait_idle = r600_ioctl_wait_idle,
.gui_idle = &r600_gui_idle, .gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &r600_mc_wait_for_idle, .mc_wait_for_idle = &r600_mc_wait_for_idle,
.get_xclk = &r600_get_xclk,
.get_gpu_clock_counter = &r600_get_gpu_clock_counter,
.gart = { .gart = {
.tlb_flush = &r600_pcie_gart_tlb_flush, .tlb_flush = &r600_pcie_gart_tlb_flush,
.set_page = &rs600_gart_set_page, .set_page = &rs600_gart_set_page,
...@@ -1018,6 +1020,8 @@ static struct radeon_asic rs780_asic = { ...@@ -1018,6 +1020,8 @@ static struct radeon_asic rs780_asic = {
.ioctl_wait_idle = r600_ioctl_wait_idle, .ioctl_wait_idle = r600_ioctl_wait_idle,
.gui_idle = &r600_gui_idle, .gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &r600_mc_wait_for_idle, .mc_wait_for_idle = &r600_mc_wait_for_idle,
.get_xclk = &r600_get_xclk,
.get_gpu_clock_counter = &r600_get_gpu_clock_counter,
.gart = { .gart = {
.tlb_flush = &r600_pcie_gart_tlb_flush, .tlb_flush = &r600_pcie_gart_tlb_flush,
.set_page = &rs600_gart_set_page, .set_page = &rs600_gart_set_page,
...@@ -1102,6 +1106,8 @@ static struct radeon_asic rv770_asic = { ...@@ -1102,6 +1106,8 @@ static struct radeon_asic rv770_asic = {
.ioctl_wait_idle = r600_ioctl_wait_idle, .ioctl_wait_idle = r600_ioctl_wait_idle,
.gui_idle = &r600_gui_idle, .gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &r600_mc_wait_for_idle, .mc_wait_for_idle = &r600_mc_wait_for_idle,
.get_xclk = &rv770_get_xclk,
.get_gpu_clock_counter = &r600_get_gpu_clock_counter,
.gart = { .gart = {
.tlb_flush = &r600_pcie_gart_tlb_flush, .tlb_flush = &r600_pcie_gart_tlb_flush,
.set_page = &rs600_gart_set_page, .set_page = &rs600_gart_set_page,
...@@ -1186,6 +1192,8 @@ static struct radeon_asic evergreen_asic = { ...@@ -1186,6 +1192,8 @@ static struct radeon_asic evergreen_asic = {
.ioctl_wait_idle = r600_ioctl_wait_idle, .ioctl_wait_idle = r600_ioctl_wait_idle,
.gui_idle = &r600_gui_idle, .gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &evergreen_mc_wait_for_idle, .mc_wait_for_idle = &evergreen_mc_wait_for_idle,
.get_xclk = &rv770_get_xclk,
.get_gpu_clock_counter = &r600_get_gpu_clock_counter,
.gart = { .gart = {
.tlb_flush = &evergreen_pcie_gart_tlb_flush, .tlb_flush = &evergreen_pcie_gart_tlb_flush,
.set_page = &rs600_gart_set_page, .set_page = &rs600_gart_set_page,
...@@ -1270,6 +1278,8 @@ static struct radeon_asic sumo_asic = { ...@@ -1270,6 +1278,8 @@ static struct radeon_asic sumo_asic = {
.ioctl_wait_idle = r600_ioctl_wait_idle, .ioctl_wait_idle = r600_ioctl_wait_idle,
.gui_idle = &r600_gui_idle, .gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &evergreen_mc_wait_for_idle, .mc_wait_for_idle = &evergreen_mc_wait_for_idle,
.get_xclk = &r600_get_xclk,
.get_gpu_clock_counter = &r600_get_gpu_clock_counter,
.gart = { .gart = {
.tlb_flush = &evergreen_pcie_gart_tlb_flush, .tlb_flush = &evergreen_pcie_gart_tlb_flush,
.set_page = &rs600_gart_set_page, .set_page = &rs600_gart_set_page,
...@@ -1354,6 +1364,8 @@ static struct radeon_asic btc_asic = { ...@@ -1354,6 +1364,8 @@ static struct radeon_asic btc_asic = {
.ioctl_wait_idle = r600_ioctl_wait_idle, .ioctl_wait_idle = r600_ioctl_wait_idle,
.gui_idle = &r600_gui_idle, .gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &evergreen_mc_wait_for_idle, .mc_wait_for_idle = &evergreen_mc_wait_for_idle,
.get_xclk = &rv770_get_xclk,
.get_gpu_clock_counter = &r600_get_gpu_clock_counter,
.gart = { .gart = {
.tlb_flush = &evergreen_pcie_gart_tlb_flush, .tlb_flush = &evergreen_pcie_gart_tlb_flush,
.set_page = &rs600_gart_set_page, .set_page = &rs600_gart_set_page,
...@@ -1438,6 +1450,8 @@ static struct radeon_asic cayman_asic = { ...@@ -1438,6 +1450,8 @@ static struct radeon_asic cayman_asic = {
.ioctl_wait_idle = r600_ioctl_wait_idle, .ioctl_wait_idle = r600_ioctl_wait_idle,
.gui_idle = &r600_gui_idle, .gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &evergreen_mc_wait_for_idle, .mc_wait_for_idle = &evergreen_mc_wait_for_idle,
.get_xclk = &rv770_get_xclk,
.get_gpu_clock_counter = &r600_get_gpu_clock_counter,
.gart = { .gart = {
.tlb_flush = &cayman_pcie_gart_tlb_flush, .tlb_flush = &cayman_pcie_gart_tlb_flush,
.set_page = &rs600_gart_set_page, .set_page = &rs600_gart_set_page,
...@@ -1565,6 +1579,8 @@ static struct radeon_asic trinity_asic = { ...@@ -1565,6 +1579,8 @@ static struct radeon_asic trinity_asic = {
.ioctl_wait_idle = r600_ioctl_wait_idle, .ioctl_wait_idle = r600_ioctl_wait_idle,
.gui_idle = &r600_gui_idle, .gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &evergreen_mc_wait_for_idle, .mc_wait_for_idle = &evergreen_mc_wait_for_idle,
.get_xclk = &r600_get_xclk,
.get_gpu_clock_counter = &r600_get_gpu_clock_counter,
.gart = { .gart = {
.tlb_flush = &cayman_pcie_gart_tlb_flush, .tlb_flush = &cayman_pcie_gart_tlb_flush,
.set_page = &rs600_gart_set_page, .set_page = &rs600_gart_set_page,
...@@ -1692,6 +1708,8 @@ static struct radeon_asic si_asic = { ...@@ -1692,6 +1708,8 @@ static struct radeon_asic si_asic = {
.ioctl_wait_idle = r600_ioctl_wait_idle, .ioctl_wait_idle = r600_ioctl_wait_idle,
.gui_idle = &r600_gui_idle, .gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &evergreen_mc_wait_for_idle, .mc_wait_for_idle = &evergreen_mc_wait_for_idle,
.get_xclk = &si_get_xclk,
.get_gpu_clock_counter = &si_get_gpu_clock_counter,
.gart = { .gart = {
.tlb_flush = &si_pcie_gart_tlb_flush, .tlb_flush = &si_pcie_gart_tlb_flush,
.set_page = &rs600_gart_set_page, .set_page = &rs600_gart_set_page,
......
...@@ -389,7 +389,8 @@ void r600_kms_blit_copy(struct radeon_device *rdev, ...@@ -389,7 +389,8 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
unsigned num_gpu_pages, unsigned num_gpu_pages,
struct radeon_sa_bo *vb); struct radeon_sa_bo *vb);
int r600_mc_wait_for_idle(struct radeon_device *rdev); int r600_mc_wait_for_idle(struct radeon_device *rdev);
uint64_t r600_get_gpu_clock(struct radeon_device *rdev); u32 r600_get_xclk(struct radeon_device *rdev);
uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev);
/* /*
* rv770,rv730,rv710,rv740 * rv770,rv730,rv710,rv740
...@@ -407,6 +408,7 @@ int rv770_copy_dma(struct radeon_device *rdev, ...@@ -407,6 +408,7 @@ int rv770_copy_dma(struct radeon_device *rdev,
uint64_t src_offset, uint64_t dst_offset, uint64_t src_offset, uint64_t dst_offset,
unsigned num_gpu_pages, unsigned num_gpu_pages,
struct radeon_fence **fence); struct radeon_fence **fence);
u32 rv770_get_xclk(struct radeon_device *rdev);
/* /*
* evergreen * evergreen
...@@ -515,11 +517,12 @@ void si_vm_set_page(struct radeon_device *rdev, ...@@ -515,11 +517,12 @@ void si_vm_set_page(struct radeon_device *rdev,
uint32_t incr, uint32_t flags); uint32_t incr, uint32_t flags);
void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
uint64_t si_get_gpu_clock(struct radeon_device *rdev);
int si_copy_dma(struct radeon_device *rdev, int si_copy_dma(struct radeon_device *rdev,
uint64_t src_offset, uint64_t dst_offset, uint64_t src_offset, uint64_t dst_offset,
unsigned num_gpu_pages, unsigned num_gpu_pages,
struct radeon_fence **fence); struct radeon_fence **fence);
void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
u32 si_get_xclk(struct radeon_device *rdev);
uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev);
#endif #endif
...@@ -43,6 +43,12 @@ struct atpx_verify_interface { ...@@ -43,6 +43,12 @@ struct atpx_verify_interface {
u32 function_bits; /* supported functions bit vector */ u32 function_bits; /* supported functions bit vector */
} __packed; } __packed;
struct atpx_px_params {
u16 size; /* structure size in bytes (includes size field) */
u32 valid_flags; /* which flags are valid */
u32 flags; /* flags */
} __packed;
struct atpx_power_control { struct atpx_power_control {
u16 size; u16 size;
u8 dgpu_state; u8 dgpu_state;
...@@ -122,10 +128,62 @@ static void radeon_atpx_parse_functions(struct radeon_atpx_functions *f, u32 mas ...@@ -122,10 +128,62 @@ static void radeon_atpx_parse_functions(struct radeon_atpx_functions *f, u32 mas
f->disp_detetion_ports = mask & ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED; f->disp_detetion_ports = mask & ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED;
} }
/**
* radeon_atpx_validate_functions - validate ATPX functions
*
* @atpx: radeon atpx struct
*
* Validate that required functions are enabled (all asics).
* returns 0 on success, error on failure.
*/
static int radeon_atpx_validate(struct radeon_atpx *atpx)
{
/* make sure required functions are enabled */
/* dGPU power control is required */
atpx->functions.power_cntl = true;
if (atpx->functions.px_params) {
union acpi_object *info;
struct atpx_px_params output;
size_t size;
u32 valid_bits;
info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL);
if (!info)
return -EIO;
memset(&output, 0, sizeof(output));
size = *(u16 *) info->buffer.pointer;
if (size < 10) {
printk("ATPX buffer is too small: %zu\n", size);
kfree(info);
return -EINVAL;
}
size = min(sizeof(output), size);
memcpy(&output, info->buffer.pointer, size);
valid_bits = output.flags & output.valid_flags;
/* if separate mux flag is set, mux controls are required */
if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) {
atpx->functions.i2c_mux_cntl = true;
atpx->functions.disp_mux_cntl = true;
}
/* if any outputs are muxed, mux controls are required */
if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED |
ATPX_TV_SIGNAL_MUXED |
ATPX_DFP_SIGNAL_MUXED))
atpx->functions.disp_mux_cntl = true;
kfree(info);
}
return 0;
}
/** /**
* radeon_atpx_verify_interface - verify ATPX * radeon_atpx_verify_interface - verify ATPX
* *
* @handle: acpi handle
* @atpx: radeon atpx struct * @atpx: radeon atpx struct
* *
* Execute the ATPX_FUNCTION_VERIFY_INTERFACE ATPX function * Execute the ATPX_FUNCTION_VERIFY_INTERFACE ATPX function
...@@ -406,8 +464,19 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) ...@@ -406,8 +464,19 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
*/ */
static int radeon_atpx_init(void) static int radeon_atpx_init(void)
{ {
int r;
/* set up the ATPX handle */ /* set up the ATPX handle */
return radeon_atpx_verify_interface(&radeon_atpx_priv.atpx); r = radeon_atpx_verify_interface(&radeon_atpx_priv.atpx);
if (r)
return r;
/* validate the atpx setup */
r = radeon_atpx_validate(&radeon_atpx_priv.atpx);
if (r)
return r;
return 0;
} }
/** /**
......
...@@ -759,6 +759,11 @@ int radeon_atombios_init(struct radeon_device *rdev) ...@@ -759,6 +759,11 @@ int radeon_atombios_init(struct radeon_device *rdev)
atom_card_info->pll_write = cail_pll_write; atom_card_info->pll_write = cail_pll_write;
rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios);
if (!rdev->mode_info.atom_context) {
radeon_atombios_fini(rdev);
return -ENOMEM;
}
mutex_init(&rdev->mode_info.atom_context->mutex); mutex_init(&rdev->mode_info.atom_context->mutex);
radeon_atom_initialize_bios_scratch_regs(rdev->ddev); radeon_atom_initialize_bios_scratch_regs(rdev->ddev);
atom_allocate_fb_scratch(rdev->mode_info.atom_context); atom_allocate_fb_scratch(rdev->mode_info.atom_context);
...@@ -778,9 +783,11 @@ void radeon_atombios_fini(struct radeon_device *rdev) ...@@ -778,9 +783,11 @@ void radeon_atombios_fini(struct radeon_device *rdev)
{ {
if (rdev->mode_info.atom_context) { if (rdev->mode_info.atom_context) {
kfree(rdev->mode_info.atom_context->scratch); kfree(rdev->mode_info.atom_context->scratch);
kfree(rdev->mode_info.atom_context);
} }
kfree(rdev->mode_info.atom_context);
rdev->mode_info.atom_context = NULL;
kfree(rdev->mode_info.atom_card_info); kfree(rdev->mode_info.atom_card_info);
rdev->mode_info.atom_card_info = NULL;
} }
/* COMBIOS */ /* COMBIOS */
......
...@@ -185,11 +185,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) ...@@ -185,11 +185,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
if (info->request == RADEON_INFO_TIMESTAMP) { if (info->request == RADEON_INFO_TIMESTAMP) {
if (rdev->family >= CHIP_R600) { if (rdev->family >= CHIP_R600) {
value_ptr64 = (uint64_t*)((unsigned long)info->value); value_ptr64 = (uint64_t*)((unsigned long)info->value);
if (rdev->family >= CHIP_TAHITI) { value64 = radeon_get_gpu_clock_counter(rdev);
value64 = si_get_gpu_clock(rdev);
} else {
value64 = r600_get_gpu_clock(rdev);
}
if (DRM_COPY_TO_USER(value_ptr64, &value64, sizeof(value64))) { if (DRM_COPY_TO_USER(value_ptr64, &value64, sizeof(value64))) {
DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__);
...@@ -282,7 +278,10 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) ...@@ -282,7 +278,10 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
break; break;
case RADEON_INFO_CLOCK_CRYSTAL_FREQ: case RADEON_INFO_CLOCK_CRYSTAL_FREQ:
/* return clock value in KHz */ /* return clock value in KHz */
value = rdev->clock.spll.reference_freq * 10; if (rdev->asic->get_xclk)
value = radeon_get_xclk(rdev) * 10;
else
value = rdev->clock.spll.reference_freq * 10;
break; break;
case RADEON_INFO_NUM_BACKENDS: case RADEON_INFO_NUM_BACKENDS:
if (rdev->family >= CHIP_TAHITI) if (rdev->family >= CHIP_TAHITI)
......
...@@ -169,7 +169,7 @@ static void radeon_set_power_state(struct radeon_device *rdev) ...@@ -169,7 +169,7 @@ static void radeon_set_power_state(struct radeon_device *rdev)
/* starting with BTC, there is one state that is used for both /* starting with BTC, there is one state that is used for both
* MH and SH. Difference is that we always use the high clock index for * MH and SH. Difference is that we always use the high clock index for
* mclk. * mclk and vddci.
*/ */
if ((rdev->pm.pm_method == PM_METHOD_PROFILE) && if ((rdev->pm.pm_method == PM_METHOD_PROFILE) &&
(rdev->family >= CHIP_BARTS) && (rdev->family >= CHIP_BARTS) &&
......
...@@ -43,6 +43,31 @@ static void rv770_gpu_init(struct radeon_device *rdev); ...@@ -43,6 +43,31 @@ static void rv770_gpu_init(struct radeon_device *rdev);
void rv770_fini(struct radeon_device *rdev); void rv770_fini(struct radeon_device *rdev);
static void rv770_pcie_gen2_enable(struct radeon_device *rdev); static void rv770_pcie_gen2_enable(struct radeon_device *rdev);
#define PCIE_BUS_CLK 10000
#define TCLK (PCIE_BUS_CLK / 10)
/**
* rv770_get_xclk - get the xclk
*
* @rdev: radeon_device pointer
*
* Returns the reference clock used by the gfx engine
* (r7xx-cayman).
*/
u32 rv770_get_xclk(struct radeon_device *rdev)
{
u32 reference_clock = rdev->clock.spll.reference_freq;
u32 tmp = RREG32(CG_CLKPIN_CNTL);
if (tmp & MUX_TCLK_TO_XCLK)
return TCLK;
if (tmp & XTALIN_DIVIDE)
return reference_clock / 4;
return reference_clock;
}
u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
{ {
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
......
...@@ -128,6 +128,10 @@ ...@@ -128,6 +128,10 @@
#define GUI_ACTIVE (1<<31) #define GUI_ACTIVE (1<<31)
#define GRBM_STATUS2 0x8014 #define GRBM_STATUS2 0x8014
#define CG_CLKPIN_CNTL 0x660
# define MUX_TCLK_TO_XCLK (1 << 8)
# define XTALIN_DIVIDE (1 << 9)
#define CG_MULT_THERMAL_STATUS 0x740 #define CG_MULT_THERMAL_STATUS 0x740
#define ASIC_T(x) ((x) << 16) #define ASIC_T(x) ((x) << 16)
#define ASIC_T_MASK 0x3FF0000 #define ASIC_T_MASK 0x3FF0000
......
...@@ -70,6 +70,33 @@ extern u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev); ...@@ -70,6 +70,33 @@ extern u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev);
extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev); extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev);
extern bool evergreen_is_display_hung(struct radeon_device *rdev); extern bool evergreen_is_display_hung(struct radeon_device *rdev);
#define PCIE_BUS_CLK 10000
#define TCLK (PCIE_BUS_CLK / 10)
/**
* si_get_xclk - get the xclk
*
* @rdev: radeon_device pointer
*
* Returns the reference clock used by the gfx engine
* (SI).
*/
u32 si_get_xclk(struct radeon_device *rdev)
{
u32 reference_clock = rdev->clock.spll.reference_freq;
u32 tmp;
tmp = RREG32(CG_CLKPIN_CNTL_2);
if (tmp & MUX_TCLK_TO_XCLK)
return TCLK;
tmp = RREG32(CG_CLKPIN_CNTL);
if (tmp & XTALIN_DIVIDE)
return reference_clock / 4;
return reference_clock;
}
/* get temperature in millidegrees */ /* get temperature in millidegrees */
int si_get_temp(struct radeon_device *rdev) int si_get_temp(struct radeon_device *rdev)
{ {
...@@ -4582,14 +4609,14 @@ void si_fini(struct radeon_device *rdev) ...@@ -4582,14 +4609,14 @@ void si_fini(struct radeon_device *rdev)
} }
/** /**
* si_get_gpu_clock - return GPU clock counter snapshot * si_get_gpu_clock_counter - return GPU clock counter snapshot
* *
* @rdev: radeon_device pointer * @rdev: radeon_device pointer
* *
* Fetches a GPU clock counter snapshot (SI). * Fetches a GPU clock counter snapshot (SI).
* Returns the 64 bit clock counter snapshot. * Returns the 64 bit clock counter snapshot.
*/ */
uint64_t si_get_gpu_clock(struct radeon_device *rdev) uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev)
{ {
uint64_t clock; uint64_t clock;
......
...@@ -58,6 +58,11 @@ ...@@ -58,6 +58,11 @@
#define VGA_HDP_CONTROL 0x328 #define VGA_HDP_CONTROL 0x328
#define VGA_MEMORY_DISABLE (1 << 4) #define VGA_MEMORY_DISABLE (1 << 4)
#define CG_CLKPIN_CNTL 0x660
# define XTALIN_DIVIDE (1 << 1)
#define CG_CLKPIN_CNTL_2 0x664
# define MUX_TCLK_TO_XCLK (1 << 8)
#define DMIF_ADDR_CONFIG 0xBD4 #define DMIF_ADDR_CONFIG 0xBD4
#define SRBM_STATUS 0xE50 #define SRBM_STATUS 0xE50
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment