[PATCH] drm/radeon: fix 64 bit divide in SI spm code

2013-08-01 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Forgot to use the appropriate math64 function.

Signed-off-by: Alex Deucher 
---

This is already in my -fixes queue, but for those that are running into
issues, here's the fix.

 drivers/gpu/drm/radeon/si_dpm.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
index 7ad22e8..4182557 100644
--- a/drivers/gpu/drm/radeon/si_dpm.c
+++ b/drivers/gpu/drm/radeon/si_dpm.c
@@ -1767,7 +1767,7 @@ static void 
si_calculate_leakage_for_v_and_t_formula(const struct ni_leakage_coe
s64 temperature, t_slope, t_intercept, av, bv, t_ref;
s64 tmp;

-   i_leakage = drm_int2fixp(ileakage) / 100;
+   i_leakage = div64_s64(drm_int2fixp(ileakage), 100);
vddc = div64_s64(drm_int2fixp(v), 1000);
temperature = div64_s64(drm_int2fixp(t), 1000);

-- 
1.7.7.5



[pull] radeon drm-fixes-3.11

2013-07-30 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Hi Dave,

A few more fixes for radeon on top of the ones I sent yesterday.
- more fixes for SI dpm
- fix DP on some rv6xx boards

The following changes since commit 63f22d0e98cf74adf4ecfb25099607239b00c751:

  drm/radeon/dpm: fix and enable reclocking on SI (2013-07-29 18:14:42 -0400)

are available in the git repository at:
  git://people.freedesktop.org/~agd5f/linux drm-fixes-3.11

Alex Deucher (4):
  drm/radeon/atom: initialize more atom interpretor elements to 0
  drm: fix 64 bit drm fixed point helpers
  drm/radeon/dpm: fix calculations in 
si_calculate_leakage_for_v_and_t_formula
  drm/radeon/dpm: re-enable cac control on SI

 drivers/gpu/drm/radeon/atom.c   |5 +
 drivers/gpu/drm/radeon/si_dpm.c |   11 ++-
 include/drm/drm_fixed.h |   14 +++---
 3 files changed, 18 insertions(+), 12 deletions(-)


[pull] radeon drm-fixes-3.11

2013-07-29 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Hi Dave,

A few more radeon bug fixes, mostly for SI dpm.  At this point dpm is
pretty solid across the majority of asics.  I think we mostly just have
corner cases and fixing up some of the trickier features at this point.

The following changes since commit bf903e4141fce4b35072d5b8fa0ddd299aaf01ea:

  Merge tag 'drm-intel-fixes-2013-07-25' of 
git://people.freedesktop.org/~danvet/drm-intel into drm-fixes (2013-07-26 
20:38:14 +1000)

are available in the git repository at:

  git://people.freedesktop.org/~agd5f/linux drm-fixes-3.11

Alex Deucher (10):
  drm/radeon: fix audio dto programming on DCE4+
  drm/radeon/dpm: fix display gap programming on SI
  drm/radeon/dpm: fix si_calculate_memory_refresh_rate()
  drm/radeon/dpm: fix powertune handling for pci id 0x6835
  drm/radeon: properly handle cg on asics without UVD
  drm/radeon/atom: fix fb when fetching engine params
  drm/radeon/dpm: fix forcing performance state to low on cayman
  drm/radeon/si: disable cgcg and pg for now
  drm/radeon/dpm: disable cac setup on SI
  drm/radeon/dpm: fix and enable reclocking on SI

 drivers/gpu/drm/radeon/evergreen_hdmi.c  |2 +-
 drivers/gpu/drm/radeon/ni_dpm.c  |7 +-
 drivers/gpu/drm/radeon/radeon_atombios.c |2 +-
 drivers/gpu/drm/radeon/si.c  |   14 
 drivers/gpu/drm/radeon/si_dpm.c  |   34 ++---
 5 files changed, 24 insertions(+), 35 deletions(-)


[pull] radeon drm-fixes-3.11

2013-07-25 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Hi Dave,

  Just a few more patches to fix some issues with dpm on rv6xx.

The following changes since commit cef1d00cd56f600121ad121875655ad410a001b8:

  drm/radeon: fix combios tables on older cards (2013-07-22 15:57:14 -0400)

are available in the git repository at:
  git://people.freedesktop.org/~agd5f/linux drm-fixes-3.11

Alex Deucher (4):
  drm/radeon/dpm: fix a typo in the rv6xx mclk setup
  drm/radeon/dpm: fix displaygap programming on rv6xx
  drm/radeon/dpm: implement force performance levels for rv6xx
  drm/radeon/dpm: fix r600_enable_sclk_control()

 drivers/gpu/drm/radeon/r600_dpm.c|4 +-
 drivers/gpu/drm/radeon/radeon_asic.c |1 +
 drivers/gpu/drm/radeon/radeon_asic.h |2 +
 drivers/gpu/drm/radeon/rv6xx_dpm.c   |   41 +++--
 4 files changed, 43 insertions(+), 5 deletions(-)


[pull] radeon drm-fixes-3.11

2013-07-23 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Hi Dave,

  Just a few radeon bug fixes.

The following changes since commit 058ca4a22ebf22ea1cbedd6cc0340ed1e2e94ee1:

  Merge tag 'drm-intel-fixes-2013-07-22' of 
git://people.freedesktop.org/~danvet/drm-intel into drm-fixes (2013-07-22 
16:14:26 +1000)

are available in the git repository at:

  git://people.freedesktop.org/~agd5f/linux drm-fixes-3.11

Alex Deucher (4):
  drm/radeon: wait for 3D idle before using CP DMA
  drm/radeon/vm: only align the pt base to 32k
  drm/radeon: fix endian issues with DP handling (v3)
  drm/radeon: improve dac adjust heuristics for legacy pdac

Mark Kettenis (1):
  drm/radeon: fix combios tables on older cards

Ondrej Zary (1):
  drm/radeon: Another card with wrong primary dac adj

 drivers/gpu/drm/radeon/atombios_dp.c|   43 -
 drivers/gpu/drm/radeon/r600.c   |5 +-
 drivers/gpu/drm/radeon/radeon_combios.c |  159 ++-
 drivers/gpu/drm/radeon/radeon_gart.c|8 +-
 4 files changed, 98 insertions(+), 117 deletions(-)


[pull] radeon drm-fixes-3.11

2013-07-17 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Hi Dave,

Take two.  Just some DPM fixes.

The following changes since commit d1ce3d5496f2a7c90dd00a9133572f931d2acdcc:

  uvesafb: Really allow mtrr being 0, as documented and warn()ed (2013-07-16 
10:24:28 +1000)

are available in the git repository at:
  git://people.freedesktop.org/~agd5f/linux drm-fixes-3.11

Alex Deucher (5):
  drm/radeon: add a module parameter to disable aspm
  drm/radeon: fix an endian bug in atom table parsing
  drm/radeon/dpm: fix atom vram table parsing
  drm/radeon/dpm/atom: fix broken gcc harder
  drm/radeon/dpm: add debugfs support for RS780/RS880 (v3)

Andre Heider (1):
  drm/radeon/dpm/atom: restructure logic to work around a compiler bug

 drivers/gpu/drm/radeon/evergreen.c   |3 ++
 drivers/gpu/drm/radeon/radeon.h  |1 +
 drivers/gpu/drm/radeon/radeon_asic.c |1 +
 drivers/gpu/drm/radeon/radeon_asic.h |2 +
 drivers/gpu/drm/radeon/radeon_atombios.c |   40 ++---
 drivers/gpu/drm/radeon/radeon_drv.c  |4 +++
 drivers/gpu/drm/radeon/rs780_dpm.c   |   25 ++
 drivers/gpu/drm/radeon/rs780d.h  |3 ++
 drivers/gpu/drm/radeon/rv6xx_dpm.c   |   14 ++
 drivers/gpu/drm/radeon/rv770_dpm.c   |   14 ++
 drivers/gpu/drm/radeon/si.c  |3 ++
 11 files changed, 77 insertions(+), 33 deletions(-)


[pull] radeon drm-fixes-3.11

2013-07-17 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Hi Dave,

Just a few DPM fixes.

The following changes since commit d1ce3d5496f2a7c90dd00a9133572f931d2acdcc:

  uvesafb: Really allow mtrr being 0, as documented and warn()ed (2013-07-16 
10:24:28 +1000)

are available in the git repository at:
  git://people.freedesktop.org/~agd5f/linux drm-fixes-3.11

Alex Deucher (3):
  drm/radeon: add a module parameter to disable aspm
  drm/radeon: fix an endian bug in atom table parsing
  drm/radeon/dpm: fix atom vram table parsing

Andre Heider (1):
  drm/radeon/dpm/atom: restructure logic to work around a compiler bug

 drivers/gpu/drm/radeon/evergreen.c   |3 ++
 drivers/gpu/drm/radeon/radeon.h  |1 +
 drivers/gpu/drm/radeon/radeon_atombios.c |   33 -
 drivers/gpu/drm/radeon/radeon_drv.c  |4 +++
 drivers/gpu/drm/radeon/rv6xx_dpm.c   |   14 +++-
 drivers/gpu/drm/radeon/rv770_dpm.c   |   14 +++-
 drivers/gpu/drm/radeon/si.c  |3 ++
 7 files changed, 41 insertions(+), 31 deletions(-)


[pull] radeon drm-fixes-3.11

2013-07-15 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Hi Dave,

Bug fixes for radeon all over the place.  Big one is a fix for ttm which
causes hangs on boot for a number of systems.


The following changes since commit 774d8e34e46506222bb5e2888e3ef42b2775715f:

  Merge branch 'drm-next-3.11' of git://people.freedesktop.org/~agd5f/linux 
into drm-next (2013-07-09 10:49:39 +1000)

are available in the git repository at:

  git://people.freedesktop.org/~agd5f/linux drm-fixes-3.11

Alex Deucher (11):
  drm/radeon/hdmi: make sure we have an afmt block assigned
  drm/radeon/dpm: disable gfx PG on PALM
  drm/radeon: Disable dma rings for bo moves on r6xx
  drm/radeon: implement bo copy callback using CP DMA (v2)
  drm/radeon: use CP DMA on r6xx for bo moves
  drm/radeon: add fault decode function for cayman/TN (v2)
  drm/radeon: add fault decode function for SI (v2)
  drm/radeon: add fault decode function for CIK
  drm/radeon: allow selection of alignment in the sub-allocator
  drm/radeon: align VM PTBs (Page Table Blocks) to 32K
  drm/radeon/dpm/sumo: handle boost states properly when forcing a perf 
level

Christian K?nig (2):
  drm/radeon: fix UVD fence emit
  drm/radeon: never unpin UVD bo v3

Jerome Glisse (1):
  drm/radeon: use radeon device for request firmware

Maarten Lankhorst (1):
  drm/radeon: add missing ttm_eu_backoff_reservation to 
radeon_bo_list_validate

Sergey Senozhatsky (1):
  radeon kms: do not flush uninitialized hotplug work

 drivers/gpu/drm/radeon/cik.c|   59 ---
 drivers/gpu/drm/radeon/cikd.h   |   16 ++
 drivers/gpu/drm/radeon/evergreen.c  |   10 +-
 drivers/gpu/drm/radeon/evergreen_hdmi.c |6 +
 drivers/gpu/drm/radeon/ni.c |  182 +--
 drivers/gpu/drm/radeon/nid.h|   16 ++
 drivers/gpu/drm/radeon/r100.c   |   11 +-
 drivers/gpu/drm/radeon/r600.c   |  102 +--
 drivers/gpu/drm/radeon/r600_hdmi.c  |6 +
 drivers/gpu/drm/radeon/r600d.h  |1 +
 drivers/gpu/drm/radeon/radeon.h |9 +-
 drivers/gpu/drm/radeon/radeon_asic.c|   12 +-
 drivers/gpu/drm/radeon/radeon_asic.h|3 +
 drivers/gpu/drm/radeon/radeon_fence.c   |2 +-
 drivers/gpu/drm/radeon/radeon_gart.c|   11 +-
 drivers/gpu/drm/radeon/radeon_irq_kms.c |   11 +-
 drivers/gpu/drm/radeon/radeon_object.c  |1 +
 drivers/gpu/drm/radeon/radeon_object.h  |2 +-
 drivers/gpu/drm/radeon/radeon_ring.c|1 +
 drivers/gpu/drm/radeon/radeon_sa.c  |7 +-
 drivers/gpu/drm/radeon/radeon_uvd.c |  111 +---
 drivers/gpu/drm/radeon/rv770.c  |2 +-
 drivers/gpu/drm/radeon/si.c |  295 +--
 drivers/gpu/drm/radeon/sid.h|   14 ++
 drivers/gpu/drm/radeon/sumo_dpm.c   |   14 ++-
 25 files changed, 733 insertions(+), 171 deletions(-)


[PATCH 2/2] drm/radeon: align VM PTBs (Page Table Blocks) to 32K

2013-07-12 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Covers requirements of all current asics.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon.h  |5 +
 drivers/gpu/drm/radeon/radeon_gart.c |   12 ++--
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 39d2ce6..875af79 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -784,6 +784,11 @@ struct radeon_mec {
 /* number of entries in page table */
 #define RADEON_VM_PTE_COUNT (1 << RADEON_VM_BLOCK_SIZE)

+/* PTBs (Page Table Blocks) need to be aligned to 32K */
+#define RADEON_VM_PTB_ALIGN_SIZE   32768
+#define RADEON_VM_PTB_ALIGN_MASK (RADEON_VM_PTB_ALIGN_SIZE - 1)
+#define RADEON_VM_PTB_ALIGN(a) (((a) + RADEON_VM_PTB_ALIGN_MASK) & 
~RADEON_VM_PTB_ALIGN_MASK)
+
 struct radeon_vm {
struct list_headlist;
struct list_headva;
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index 5ce190b..d9d31a3 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -466,8 +466,8 @@ int radeon_vm_manager_init(struct radeon_device *rdev)
size += rdev->vm_manager.max_pfn * 8;
size *= 2;
r = radeon_sa_bo_manager_init(rdev, 
>vm_manager.sa_manager,
- RADEON_GPU_PAGE_ALIGN(size),
- RADEON_GPU_PAGE_SIZE,
+ RADEON_VM_PTB_ALIGN(size),
+ RADEON_VM_PTB_ALIGN_SIZE,
  RADEON_GEM_DOMAIN_VRAM);
if (r) {
dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n",
@@ -621,10 +621,10 @@ int radeon_vm_alloc_pt(struct radeon_device *rdev, struct 
radeon_vm *vm)
}

 retry:
-   pd_size = RADEON_GPU_PAGE_ALIGN(radeon_vm_directory_size(rdev));
+   pd_size = RADEON_VM_PTB_ALIGN(radeon_vm_directory_size(rdev));
r = radeon_sa_bo_new(rdev, >vm_manager.sa_manager,
 >page_directory, pd_size,
-RADEON_GPU_PAGE_SIZE, false);
+RADEON_VM_PTB_ALIGN_SIZE, false);
if (r == -ENOMEM) {
r = radeon_vm_evict(rdev, vm);
if (r)
@@ -953,8 +953,8 @@ static int radeon_vm_update_pdes(struct radeon_device *rdev,
 retry:
r = radeon_sa_bo_new(rdev, >vm_manager.sa_manager,
 >page_tables[pt_idx],
-RADEON_VM_PTE_COUNT * 8,
-RADEON_GPU_PAGE_SIZE, false);
+RADEON_VM_PTB_ALIGN(RADEON_VM_PTE_COUNT * 
8),
+RADEON_VM_PTB_ALIGN_SIZE, false);

if (r == -ENOMEM) {
r = radeon_vm_evict(rdev, vm);
-- 
1.7.7.5



[PATCH 1/2] drm/radeon: allow selection of alignment in the sub-allocator

2013-07-12 Thread alexdeuc...@gmail.com
From: Alex Deucher 

There are cases where we need more than 4k alignment.  No
functional change with this commit.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon.h|1 +
 drivers/gpu/drm/radeon/radeon_gart.c   |1 +
 drivers/gpu/drm/radeon/radeon_object.h |2 +-
 drivers/gpu/drm/radeon/radeon_ring.c   |1 +
 drivers/gpu/drm/radeon/radeon_sa.c |7 ---
 5 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 6fe4b1c..39d2ce6 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -455,6 +455,7 @@ struct radeon_sa_manager {
uint64_tgpu_addr;
void*cpu_ptr;
uint32_tdomain;
+   uint32_talign;
 };

 struct radeon_sa_bo;
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index 43ec4a4..5ce190b 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -467,6 +467,7 @@ int radeon_vm_manager_init(struct radeon_device *rdev)
size *= 2;
r = radeon_sa_bo_manager_init(rdev, 
>vm_manager.sa_manager,
  RADEON_GPU_PAGE_ALIGN(size),
+ RADEON_GPU_PAGE_SIZE,
  RADEON_GEM_DOMAIN_VRAM);
if (r) {
dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n",
diff --git a/drivers/gpu/drm/radeon/radeon_object.h 
b/drivers/gpu/drm/radeon/radeon_object.h
index 91519a5..49c82c4 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -174,7 +174,7 @@ static inline void * radeon_sa_bo_cpu_addr(struct 
radeon_sa_bo *sa_bo)

 extern int radeon_sa_bo_manager_init(struct radeon_device *rdev,
 struct radeon_sa_manager *sa_manager,
-unsigned size, u32 domain);
+unsigned size, u32 align, u32 domain);
 extern void radeon_sa_bo_manager_fini(struct radeon_device *rdev,
  struct radeon_sa_manager *sa_manager);
 extern int radeon_sa_bo_manager_start(struct radeon_device *rdev,
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index 5f1c51a..fb5ea62 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -224,6 +224,7 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
}
r = radeon_sa_bo_manager_init(rdev, >ring_tmp_bo,
  RADEON_IB_POOL_SIZE*64*1024,
+ RADEON_GPU_PAGE_SIZE,
  RADEON_GEM_DOMAIN_GTT);
if (r) {
return r;
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c 
b/drivers/gpu/drm/radeon/radeon_sa.c
index 0abe5a9..f0bac68 100644
--- a/drivers/gpu/drm/radeon/radeon_sa.c
+++ b/drivers/gpu/drm/radeon/radeon_sa.c
@@ -49,7 +49,7 @@ static void radeon_sa_bo_try_free(struct radeon_sa_manager 
*sa_manager);

 int radeon_sa_bo_manager_init(struct radeon_device *rdev,
  struct radeon_sa_manager *sa_manager,
- unsigned size, u32 domain)
+ unsigned size, u32 align, u32 domain)
 {
int i, r;

@@ -57,13 +57,14 @@ int radeon_sa_bo_manager_init(struct radeon_device *rdev,
sa_manager->bo = NULL;
sa_manager->size = size;
sa_manager->domain = domain;
+   sa_manager->align = align;
sa_manager->hole = _manager->olist;
INIT_LIST_HEAD(_manager->olist);
for (i = 0; i < RADEON_NUM_RINGS; ++i) {
INIT_LIST_HEAD(_manager->flist[i]);
}

-   r = radeon_bo_create(rdev, size, RADEON_GPU_PAGE_SIZE, true,
+   r = radeon_bo_create(rdev, size, align, true,
 domain, NULL, _manager->bo);
if (r) {
dev_err(rdev->dev, "(%d) failed to allocate bo for manager\n", 
r);
@@ -317,7 +318,7 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
unsigned tries[RADEON_NUM_RINGS];
int i, r;

-   BUG_ON(align > RADEON_GPU_PAGE_SIZE);
+   BUG_ON(align > sa_manager->align);
BUG_ON(size > sa_manager->size);

*sa_bo = kmalloc(sizeof(struct radeon_sa_bo), GFP_KERNEL);
-- 
1.7.7.5



[PATCH 3/3] drm/radeon: add fault decode function for CIK

2013-07-11 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Helpful for debugging GPUVM errors as we can see what
hw block and page generated the fault in the log.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/cik.c  |   32 ++--
 drivers/gpu/drm/radeon/cikd.h |   16 
 2 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 27891d8..68b4fc5 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -4442,6 +4442,29 @@ void cik_vm_fini(struct radeon_device *rdev)
 }

 /**
+ * cik_vm_decode_fault - print human readable fault info
+ *
+ * @rdev: radeon_device pointer
+ * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
+ * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
+ *
+ * Print human readable fault information (CIK).
+ */
+static void cik_vm_decode_fault(struct radeon_device *rdev,
+   u32 status, u32 addr, u32 mc_client)
+{
+   u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
+   u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
+   u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
+   char *block = (char *)_client;
+
+   printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n",
+  protections, vmid, addr,
+  (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
+  block, mc_id);
+}
+
+/**
  * cik_vm_flush - cik vm flush using the CP
  *
  * @rdev: radeon_device pointer
@@ -5496,6 +5519,7 @@ int cik_irq_process(struct radeon_device *rdev)
u32 ring_index;
bool queue_hotplug = false;
bool queue_reset = false;
+   u32 addr, status, mc_client;

if (!rdev->ih.enabled || rdev->shutdown)
return IRQ_NONE;
@@ -5731,11 +5755,15 @@ restart_ih:
break;
case 146:
case 147:
+   addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
+   status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
+   mc_client = 
RREG32(VM_CONTEXT1_PROTECTION_FAULT_MCCLIENT);
dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", 
src_id, src_data);
dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR 
  0x%08X\n",
-   RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
+   addr);
dev_err(rdev->dev, "  
VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
-   RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
+   status);
+   cik_vm_decode_fault(rdev, status, addr, mc_client);
/* reset addr and status */
WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
break;
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h
index 63514b9..7e9275e 100644
--- a/drivers/gpu/drm/radeon/cikd.h
+++ b/drivers/gpu/drm/radeon/cikd.h
@@ -136,6 +136,22 @@
 #define VM_INVALIDATE_RESPONSE 0x147c

 #defineVM_CONTEXT1_PROTECTION_FAULT_STATUS 0x14DC
+#definePROTECTIONS_MASK(0xf << 0)
+#definePROTECTIONS_SHIFT   0
+   /* bit 0: range
+* bit 1: pde0
+* bit 2: valid
+* bit 3: read
+* bit 4: write
+*/
+#defineMEMORY_CLIENT_ID_MASK   (0xff << 12)
+#defineMEMORY_CLIENT_ID_SHIFT  12
+#defineMEMORY_CLIENT_RW_MASK   (1 << 24)
+#defineMEMORY_CLIENT_RW_SHIFT  24
+#defineFAULT_VMID_MASK (0xf << 25)
+#defineFAULT_VMID_SHIFT25
+
+#defineVM_CONTEXT1_PROTECTION_FAULT_MCCLIENT   0x14E4

 #defineVM_CONTEXT1_PROTECTION_FAULT_ADDR   0x14FC

-- 
1.7.7.5



[PATCH 2/3] drm/radeon: add fault decode function for SI (v2)

2013-07-11 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Helpful for debugging GPUVM errors as we can see what
hw block and page generated the fault in the log.

v2: simplify fault decoding

Signed-off-by: Alex Deucher 
Reviewed-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/si.c  |  272 +-
 drivers/gpu/drm/radeon/sid.h |   14 ++
 2 files changed, 284 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index f305768..d3f0507 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -4390,6 +4390,270 @@ void si_vm_fini(struct radeon_device *rdev)
 }

 /**
+ * si_vm_decode_fault - print human readable fault info
+ *
+ * @rdev: radeon_device pointer
+ * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
+ * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
+ *
+ * Print human readable fault information (SI).
+ */
+static void si_vm_decode_fault(struct radeon_device *rdev,
+  u32 status, u32 addr)
+{
+   u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
+   u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
+   u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
+   char *block;
+
+   if (rdev->family == CHIP_TAHITI) {
+   switch (mc_id) {
+   case 160:
+   case 144:
+   case 96:
+   case 80:
+   case 224:
+   case 208:
+   case 32:
+   case 16:
+   block = "CB";
+   break;
+   case 161:
+   case 145:
+   case 97:
+   case 81:
+   case 225:
+   case 209:
+   case 33:
+   case 17:
+   block = "CB_FMASK";
+   break;
+   case 162:
+   case 146:
+   case 98:
+   case 82:
+   case 226:
+   case 210:
+   case 34:
+   case 18:
+   block = "CB_CMASK";
+   break;
+   case 163:
+   case 147:
+   case 99:
+   case 83:
+   case 227:
+   case 211:
+   case 35:
+   case 19:
+   block = "CB_IMMED";
+   break;
+   case 164:
+   case 148:
+   case 100:
+   case 84:
+   case 228:
+   case 212:
+   case 36:
+   case 20:
+   block = "DB";
+   break;
+   case 165:
+   case 149:
+   case 101:
+   case 85:
+   case 229:
+   case 213:
+   case 37:
+   case 21:
+   block = "DB_HTILE";
+   break;
+   case 167:
+   case 151:
+   case 103:
+   case 87:
+   case 231:
+   case 215:
+   case 39:
+   case 23:
+   block = "DB_STEN";
+   break;
+   case 72:
+   case 68:
+   case 64:
+   case 8:
+   case 4:
+   case 0:
+   case 136:
+   case 132:
+   case 128:
+   case 200:
+   case 196:
+   case 192:
+   block = "TC";
+   break;
+   case 112:
+   case 48:
+   block = "CP";
+   break;
+   case 49:
+   case 177:
+   case 50:
+   case 178:
+   block = "SH";
+   break;
+   case 53:
+   case 190:
+   block = "VGT";
+   break;
+   case 117:
+   block = "IH";
+   break;
+   case 51:
+   case 115:
+   block = "RLC";
+   break;
+   case 119:
+   case 183:
+   block = "DMA0";
+   break;
+   case 61:
+   block = "DMA1";
+   break;
+   case 248:
+   case 120:
+   block = "HDP";
+   break;
+   default:
+   block = "unknown";
+   break;
+   }
+   } else {
+   switch (mc_id) {
+   case 32:
+   case 16:
+   case 96:
+   case 80:
+   case 160:
+   case 144:
+   

[PATCH 1/3] drm/radeon: add fault decode function for cayman/TN (v2)

2013-07-11 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Helpful for debugging GPUVM errors as we can see what
hw block and page generated the fault in the log.

v2: simplify fault decoding

Signed-off-by: Alex Deucher 
Reviewed-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/evergreen.c |   10 ++-
 drivers/gpu/drm/radeon/ni.c|  161 
 drivers/gpu/drm/radeon/nid.h   |   16 
 3 files changed, 185 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 9e14007..bc6936a 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -139,6 +139,8 @@ void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
 void evergreen_program_aspm(struct radeon_device *rdev);
 extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
 int ring, u32 cp_int_cntl);
+extern void cayman_vm_decode_fault(struct radeon_device *rdev,
+  u32 status, u32 addr);

 static const u32 evergreen_golden_registers[] =
 {
@@ -4629,6 +4631,7 @@ int evergreen_irq_process(struct radeon_device *rdev)
bool queue_hotplug = false;
bool queue_hdmi = false;
bool queue_thermal = false;
+   u32 status, addr;

if (!rdev->ih.enabled || rdev->shutdown)
return IRQ_NONE;
@@ -4915,11 +4918,14 @@ restart_ih:
break;
case 146:
case 147:
+   addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
+   status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", 
src_id, src_data);
dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR 
  0x%08X\n",
-   RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
+   addr);
dev_err(rdev->dev, "  
VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
-   RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
+   status);
+   cayman_vm_decode_fault(rdev, status, addr);
/* reset addr and status */
WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
break;
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 465b17e..56bd4f3 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -2450,6 +2450,167 @@ void cayman_vm_fini(struct radeon_device *rdev)
 {
 }

+/**
+ * cayman_vm_decode_fault - print human readable fault info
+ *
+ * @rdev: radeon_device pointer
+ * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
+ * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
+ *
+ * Print human readable fault information (cayman/TN).
+ */
+void cayman_vm_decode_fault(struct radeon_device *rdev,
+   u32 status, u32 addr)
+{
+   u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
+   u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
+   u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
+   char *block;
+
+   switch (mc_id) {
+   case 32:
+   case 16:
+   case 96:
+   case 80:
+   case 160:
+   case 144:
+   case 224:
+   case 208:
+   block = "CB";
+   break;
+   case 33:
+   case 17:
+   case 97:
+   case 81:
+   case 161:
+   case 145:
+   case 225:
+   case 209:
+   block = "CB_FMASK";
+   break;
+   case 34:
+   case 18:
+   case 98:
+   case 82:
+   case 162:
+   case 146:
+   case 226:
+   case 210:
+   block = "CB_CMASK";
+   break;
+   case 35:
+   case 19:
+   case 99:
+   case 83:
+   case 163:
+   case 147:
+   case 227:
+   case 211:
+   block = "CB_IMMED";
+   break;
+   case 36:
+   case 20:
+   case 100:
+   case 84:
+   case 164:
+   case 148:
+   case 228:
+   case 212:
+   block = "DB";
+   break;
+   case 37:
+   case 21:
+   case 101:
+   case 85:
+   case 165:
+   case 149:
+   case 229:
+   case 213:
+   block = "DB_HTILE";
+   break;
+   case 38:
+   case 22:
+   case 102:
+   case 86:
+   case 166:
+   case 150:
+   case 230:
+   case 214:
+   block = "SX";
+   break;
+   case 39:
+   case 23:
+   case 103:
+   case 87:
+   case 167:
+   case 151:
+   case 231:
+   case 215:
+   block = "DB_STEN";
+   break;
+   case 40:
+   case 24:
+   case 104:
+   case 88:
+   case 232:
+ 

[PATCH 3/3] drm/radeon: use CP DMA on r6xx for bo moves

2013-07-11 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Lighter weight than using the 3D engine.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_asic.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index ea5c52b..fea997e 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1026,7 +1026,7 @@ static struct radeon_asic r600_asic = {
.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
.dma = _copy_dma,
.dma_ring_index = R600_RING_TYPE_DMA_INDEX,
-   .copy = _copy_blit,
+   .copy = _copy_cpdma,
.copy_ring_index = RADEON_RING_TYPE_GFX_INDEX,
},
.surface = {
@@ -1119,7 +1119,7 @@ static struct radeon_asic rv6xx_asic = {
.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
.dma = _copy_dma,
.dma_ring_index = R600_RING_TYPE_DMA_INDEX,
-   .copy = _copy_blit,
+   .copy = _copy_cpdma,
.copy_ring_index = RADEON_RING_TYPE_GFX_INDEX,
},
.surface = {
@@ -1229,7 +1229,7 @@ static struct radeon_asic rs780_asic = {
.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
.dma = _copy_dma,
.dma_ring_index = R600_RING_TYPE_DMA_INDEX,
-   .copy = _copy_blit,
+   .copy = _copy_cpdma,
.copy_ring_index = RADEON_RING_TYPE_GFX_INDEX,
},
.surface = {
-- 
1.7.7.5



[PATCH 2/3] drm/radeon: implement bo copy callback using CP DMA (v2)

2013-07-11 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Lighter weight than using the 3D engine.

v2: fix ring count

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/r600.c|   81 ++
 drivers/gpu/drm/radeon/r600d.h   |1 +
 drivers/gpu/drm/radeon/radeon_asic.h |3 +
 3 files changed, 85 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 2d3655f..f7d494f 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -3145,6 +3145,87 @@ int r600_copy_blit(struct radeon_device *rdev,
 }

 /**
+ * r600_copy_cpdma - copy pages using the CP DMA engine
+ *
+ * @rdev: radeon_device pointer
+ * @src_offset: src GPU address
+ * @dst_offset: dst GPU address
+ * @num_gpu_pages: number of GPU pages to xfer
+ * @fence: radeon fence object
+ *
+ * Copy GPU paging using the CP DMA engine (r6xx+).
+ * Used by the radeon ttm implementation to move pages if
+ * registered as the asic copy callback.
+ */
+int r600_copy_cpdma(struct radeon_device *rdev,
+   uint64_t src_offset, uint64_t dst_offset,
+   unsigned num_gpu_pages,
+   struct radeon_fence **fence)
+{
+   struct radeon_semaphore *sem = NULL;
+   int ring_index = rdev->asic->copy.blit_ring_index;
+   struct radeon_ring *ring = >ring[ring_index];
+   u32 size_in_bytes, cur_size_in_bytes, tmp;
+   int i, num_loops;
+   int r = 0;
+
+   r = radeon_semaphore_create(rdev, );
+   if (r) {
+   DRM_ERROR("radeon: moving bo (%d).\n", r);
+   return r;
+   }
+
+   size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
+   num_loops = DIV_ROUND_UP(size_in_bytes, 0x1f);
+   r = radeon_ring_lock(rdev, ring, num_loops * 6 + 21);
+   if (r) {
+   DRM_ERROR("radeon: moving bo (%d).\n", r);
+   radeon_semaphore_free(rdev, , NULL);
+   return r;
+   }
+
+   if (radeon_fence_need_sync(*fence, ring->idx)) {
+   radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring,
+   ring->idx);
+   radeon_fence_note_sync(*fence, ring->idx);
+   } else {
+   radeon_semaphore_free(rdev, , NULL);
+   }
+
+   for (i = 0; i < num_loops; i++) {
+   cur_size_in_bytes = size_in_bytes;
+   if (cur_size_in_bytes > 0x1f)
+   cur_size_in_bytes = 0x1f;
+   size_in_bytes -= cur_size_in_bytes;
+   tmp = upper_32_bits(src_offset) & 0xff;
+   if (size_in_bytes == 0)
+   tmp |= PACKET3_CP_DMA_CP_SYNC;
+   radeon_ring_write(ring, PACKET3(PACKET3_CP_DMA, 4));
+   radeon_ring_write(ring, src_offset & 0x);
+   radeon_ring_write(ring, tmp);
+   radeon_ring_write(ring, dst_offset & 0x);
+   radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff);
+   radeon_ring_write(ring, cur_size_in_bytes);
+   src_offset += cur_size_in_bytes;
+   dst_offset += cur_size_in_bytes;
+   }
+   radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+   radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 
2);
+   radeon_ring_write(ring, WAIT_CP_DMA_IDLE_bit);
+
+   r = radeon_fence_emit(rdev, fence, ring->idx);
+   if (r) {
+   radeon_ring_unlock_undo(rdev, ring);
+   return r;
+   }
+
+   radeon_ring_unlock_commit(rdev, ring);
+   radeon_semaphore_free(rdev, , *fence);
+
+   return r;
+}
+
+/**
  * r600_copy_dma - copy pages using the DMA engine
  *
  * @rdev: radeon_device pointer
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index f1b3084..8e3fe81 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -602,6 +602,7 @@
 #defineL2_BUSY (1 << 0)

 #defineWAIT_UNTIL  0x8040
+#define WAIT_CP_DMA_IDLE_bit(1 << 8)
 #define WAIT_2D_IDLE_bit(1 << 14)
 #define WAIT_3D_IDLE_bit(1 << 15)
 #define WAIT_2D_IDLECLEAN_bit   (1 << 16)
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h 
b/drivers/gpu/drm/radeon/radeon_asic.h
index 45d0693..b04b578 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -340,6 +340,9 @@ int r600_uvd_ring_test(struct radeon_device *rdev, struct 
radeon_ring *ring);
 int r600_copy_blit(struct radeon_device *rdev,
   uint64_t src_offset, uint64_t dst_offset,
   unsigned num_gpu_pages, struct radeon_fence **fence);
+int r600_copy_cpdma(struct radeon_device *rdev,
+   

[PATCH 1/3] drm/radeon: Disable dma rings for bo moves on r6xx

2013-07-11 Thread alexdeuc...@gmail.com
From: Alex Deucher 

They still seem to cause instability on some r6xx parts.
As a follow up, we can switch to using CP DMA for bo
moves on r6xx as a lighter weight alternative to using
the 3D engine.

A version of this patch should also go to stable kernels.

Tested-by: J.N. 
Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_asic.c |   12 ++--
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index 0970774..ea5c52b 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1026,8 +1026,8 @@ static struct radeon_asic r600_asic = {
.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
.dma = _copy_dma,
.dma_ring_index = R600_RING_TYPE_DMA_INDEX,
-   .copy = _copy_dma,
-   .copy_ring_index = R600_RING_TYPE_DMA_INDEX,
+   .copy = _copy_blit,
+   .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX,
},
.surface = {
.set_reg = r600_set_surface_reg,
@@ -1119,8 +1119,8 @@ static struct radeon_asic rv6xx_asic = {
.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
.dma = _copy_dma,
.dma_ring_index = R600_RING_TYPE_DMA_INDEX,
-   .copy = _copy_dma,
-   .copy_ring_index = R600_RING_TYPE_DMA_INDEX,
+   .copy = _copy_blit,
+   .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX,
},
.surface = {
.set_reg = r600_set_surface_reg,
@@ -1229,8 +1229,8 @@ static struct radeon_asic rs780_asic = {
.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
.dma = _copy_dma,
.dma_ring_index = R600_RING_TYPE_DMA_INDEX,
-   .copy = _copy_dma,
-   .copy_ring_index = R600_RING_TYPE_DMA_INDEX,
+   .copy = _copy_blit,
+   .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX,
},
.surface = {
.set_reg = r600_set_surface_reg,
-- 
1.7.7.5



[pull] radeon drm-next-3.11

2013-07-08 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Hi Dave,

A few more DPM fixes based on user testing.

The following changes since commit 9b5de59629d2e58eab41e2f0e5cc60b3c395f1c3:

  drm/radeon/dpm: implement force performance level for TN (2013-07-05 18:10:06 
-0400)

are available in the git repository at:
  git://people.freedesktop.org/~agd5f/linux drm-next-3.11

Alex Deucher (9):
  drm/radeon/dpm: fix display_gap programming on rv7xx
  drm/radeon: remove stray line in old pm code
  drm/radeon/dpm: add helper to calculate vblank time
  drm/radeon/dpm: add checks against vblank time
  drm/radeon/dpm: implement vblank_too_short callback for 7xx
  drm/radeon/dpm: implement vblank_too_short callback for evergreen
  drm/radeon/dpm: implement vblank_too_short callback for btc
  drm/radeon/dpm: implement vblank_too_short callback for cayman
  drm/radeon/dpm: implement vblank_too_short callback for si

 drivers/gpu/drm/radeon/atombios_crtc.c |3 +++
 drivers/gpu/drm/radeon/btc_dpm.c   |   16 +++-
 drivers/gpu/drm/radeon/cypress_dpm.c   |   13 +
 drivers/gpu/drm/radeon/ni_dpm.c|   16 +++-
 drivers/gpu/drm/radeon/ni_dpm.h|2 ++
 drivers/gpu/drm/radeon/r600_dpm.c  |   24 
 drivers/gpu/drm/radeon/r600_dpm.h  |1 +
 drivers/gpu/drm/radeon/radeon.h|2 ++
 drivers/gpu/drm/radeon/radeon_asic.c   |5 +
 drivers/gpu/drm/radeon/radeon_asic.h   |4 
 drivers/gpu/drm/radeon/radeon_mode.h   |1 +
 drivers/gpu/drm/radeon/radeon_pm.c |   15 +++
 drivers/gpu/drm/radeon/rv770_dpm.c |   15 +--
 drivers/gpu/drm/radeon/si_dpm.c|3 ++-
 14 files changed, 111 insertions(+), 9 deletions(-)


[pull] radeon drm-next-3.11

2013-07-05 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Hi Dave,

A few more DPM patches and some bug fixes.  Adds a sysfs interface to force
dpm performance levels.

The following changes since commit 338a95a95508537e23c82d59a2d87be6fde4b6ff:

  drm/radeon/sumo: implement support for disable_gfx_power_gating_in_uvd flag 
(2013-07-03 17:37:31 -0400)

are available in the git repository at:
  git://people.freedesktop.org/~agd5f/linux drm-next-3.11

Alex Deucher (9):
  drm/radeon: set default clocks for SI when DPM is disabled
  drm/radeon: add support for 3d perf states on older asics
  drm/radeon: fix surface setup on r1xx
  drm/radeon/dpm: add infrastructure to force performance levels
  drm/radeon/dpm: implement force performance levels for 7xx/eg/btc
  drm/radeon/dpm: implement force performance level for cayman
  drm/radeon/dpm: implement force performance level for SI
  drm/radeon/dpm: implement force performance level for ON/LN
  drm/radeon/dpm: implement force performance level for TN

 drivers/gpu/drm/radeon/btc_dpm.c |4 +-
 drivers/gpu/drm/radeon/cypress_dpm.c |4 +-
 drivers/gpu/drm/radeon/evergreen.c   |8 ++--
 drivers/gpu/drm/radeon/ni_dpm.c  |   38 ---
 drivers/gpu/drm/radeon/ppsmc.h   |3 +
 drivers/gpu/drm/radeon/r100.c|   11 ++---
 drivers/gpu/drm/radeon/radeon.h  |   11 
 drivers/gpu/drm/radeon/radeon_asic.c |7 +++
 drivers/gpu/drm/radeon/radeon_asic.h |   10 
 drivers/gpu/drm/radeon/radeon_atombios.c |4 ++
 drivers/gpu/drm/radeon/radeon_pm.c   |   77 +++---
 drivers/gpu/drm/radeon/rv770_dpm.c   |   31 +---
 drivers/gpu/drm/radeon/rv770_dpm.h   |3 +-
 drivers/gpu/drm/radeon/si_dpm.c  |   42 +
 drivers/gpu/drm/radeon/sumo_dpm.c|   44 +
 drivers/gpu/drm/radeon/trinity_dpm.c |   32 
 drivers/gpu/drm/radeon/trinity_dpm.h |1 +
 drivers/gpu/drm/radeon/trinity_smc.c |7 +++
 18 files changed, 291 insertions(+), 46 deletions(-)


[PATCH] drm/radeon: default to 1024M gart size on rv770+

2013-07-05 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Newer asics have a lot of vram so it's less of an
issue to waste a little more space for the gart
page table.  This gives us some additional gart space
before having to migrate to non-gart system ram
for games, etc. where we use up most of vram.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_device.c |   22 +-
 drivers/gpu/drm/radeon/radeon_drv.c|4 ++--
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 82335e3..0ed11dd 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1003,16 +1003,28 @@ static void radeon_check_arguments(struct radeon_device 
*rdev)
radeon_vram_limit = 0;
}

+   if (radeon_gart_size == -1) {
+   /* default to a larger gart size on newer asics */
+   if (rdev->family >= CHIP_RV770)
+   radeon_gart_size = 1024;
+   else
+   radeon_gart_size = 512;
+   }
/* gtt size must be power of two and greater or equal to 32M */
if (radeon_gart_size < 32) {
-   dev_warn(rdev->dev, "gart size (%d) too small forcing to 
512M\n",
+   dev_warn(rdev->dev, "gart size (%d) too small\n",
radeon_gart_size);
-   radeon_gart_size = 512;
-
+   if (rdev->family >= CHIP_RV770)
+   radeon_gart_size = 1024;
+   else
+   radeon_gart_size = 512;
} else if (!radeon_check_pot_argument(radeon_gart_size)) {
dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n",
radeon_gart_size);
-   radeon_gart_size = 512;
+   if (rdev->family >= CHIP_RV770)
+   radeon_gart_size = 1024;
+   else
+   radeon_gart_size = 512;
}
rdev->mc.gtt_size = (uint64_t)radeon_gart_size << 20;

@@ -1144,7 +1156,7 @@ int radeon_device_init(struct radeon_device *rdev,
rdev->family = flags & RADEON_FAMILY_MASK;
rdev->is_atom_bios = false;
rdev->usec_timeout = RADEON_MAX_USEC_TIMEOUT;
-   rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+   rdev->mc.gtt_size = 512 * 1024 * 1024;
rdev->accel_working = false;
/* set up ring ids */
for (i = 0; i < RADEON_NUM_RINGS; i++) {
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c 
b/drivers/gpu/drm/radeon/radeon_drv.c
index e5419b3..91d1401 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -154,7 +154,7 @@ int radeon_dynclks = -1;
 int radeon_r4xx_atom = 0;
 int radeon_agpmode = 0;
 int radeon_vram_limit = 0;
-int radeon_gart_size = 512; /* default gart size */
+int radeon_gart_size = -1; /* auto */
 int radeon_benchmarking = 0;
 int radeon_testing = 0;
 int radeon_connector_table = 0;
@@ -186,7 +186,7 @@ module_param_named(vramlimit, radeon_vram_limit, int, 0600);
 MODULE_PARM_DESC(agpmode, "AGP Mode (-1 == PCI)");
 module_param_named(agpmode, radeon_agpmode, int, 0444);

-MODULE_PARM_DESC(gartsize, "Size of PCIE/IGP gart to setup in megabytes (32, 
64, etc)");
+MODULE_PARM_DESC(gartsize, "Size of PCIE/IGP gart to setup in megabytes (32, 
64, etc., -1 = auto)");
 module_param_named(gartsize, radeon_gart_size, int, 0600);

 MODULE_PARM_DESC(benchmark, "Run benchmark");
-- 
1.7.7.5



[pull] radeon drm-next-3.11

2013-07-03 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Hi Dave,

A few more DPM fixes.

The following changes since commit 7982128c3d447df27db963af67bc6b8dc7efb1de:

  drm/radeon/dpm: add debugfs support for SI (2013-07-01 16:09:06 -0400)

are available in the git repository at:
  git://people.freedesktop.org/~agd5f/linux drm-next-3.11

Alex Deucher (6):
  drm/radeon/dpm: clarify debugfs warning
  drm/radeon: fix endian bug in radeon_atom_get_mclk_range_table()
  drm/radeon/aruba: disable additional rlc features
  drm/radeon/sumo: disable PG when changing UVD clocks
  drm/radeon/tn: disable PG when changing UVD clocks
  drm/radeon/sumo: implement support for disable_gfx_power_gating_in_uvd 
flag

Mike Lothian (1):
  drm/radeon/dpm: fix compilation with certain versions of gcc

 drivers/gpu/drm/radeon/evergreen.c   |2 --
 drivers/gpu/drm/radeon/ni_dpm.c  |1 +
 drivers/gpu/drm/radeon/radeon_atombios.c |2 +-
 drivers/gpu/drm/radeon/radeon_pm.c   |2 +-
 drivers/gpu/drm/radeon/rv6xx_dpm.c   |1 +
 drivers/gpu/drm/radeon/rv770_dpm.c   |1 +
 drivers/gpu/drm/radeon/si_dpm.c  |1 +
 drivers/gpu/drm/radeon/sumo_dpm.c|   24 ++--
 drivers/gpu/drm/radeon/trinity_dpm.c |9 +
 9 files changed, 37 insertions(+), 6 deletions(-)


[pull] radeon drm-next-3.11

2013-07-01 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Hi Dave,

A few more patches for 3.11:
- add debugfs interface to check current DPM state
- Fix a bug that caused problems with DPM on BTC+ asics.

The following changes since commit f7d452f4fd5d86f764807a1234a407deb5b105ef:

  Merge branch 'drm-nouveau-next' of 
git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next (2013-07-01 
14:10:20 +1000)

are available in the git repository at:

  git://people.freedesktop.org/~agd5f/linux drm-next-3.11

Alex Deucher (12):
  drm/radeon: remove sumo dpm/uvd bringup leftovers
  drm/radeon/atom: fix endian bug in radeon_atom_init_mc_reg_table()
  drm/radeon: fix typo in radeon_atom_init_mc_reg_table()
  drm/radeon/dpm: re-enable state transitions for BTC
  drm/radeon/dpm: re-enable state transitions for Cayman
  drm/radeon/dpm: add infrastructure to support debugfs info
  drm/radeon/dpm: add debugfs support for rv6xx
  drm/radeon/dpm: add debugfs support for 7xx/evergreen/btc
  drm/radeon/dpm: add debugfs support for ON/LN
  drm/radeon/dpm: add debugfs support for TN
  drm/radeon/dpm: add debugfs support for cayman
  drm/radeon/dpm: add debugfs support for SI

 drivers/gpu/drm/radeon/btc_dpm.c |3 --
 drivers/gpu/drm/radeon/ni_dpm.c  |   25 +---
 drivers/gpu/drm/radeon/nid.h |4 ++
 drivers/gpu/drm/radeon/radeon.h  |2 +
 drivers/gpu/drm/radeon/radeon_asic.c |8 +
 drivers/gpu/drm/radeon/radeon_asic.h |   12 
 drivers/gpu/drm/radeon/radeon_atombios.c |3 +-
 drivers/gpu/drm/radeon/radeon_pm.c   |   40 ++
 drivers/gpu/drm/radeon/rv6xx_dpm.c   |   25 
 drivers/gpu/drm/radeon/rv770_dpm.c   |   30 
 drivers/gpu/drm/radeon/rv770d.h  |4 ++
 drivers/gpu/drm/radeon/si_dpm.c  |   19 
 drivers/gpu/drm/radeon/sid.h |4 ++
 drivers/gpu/drm/radeon/sumo_dpm.c|   45 ++---
 drivers/gpu/drm/radeon/trinity_dpm.c |   21 ++
 15 files changed, 206 insertions(+), 39 deletions(-)


[pull] radeon drm-next-3.11

2013-06-27 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Hi Dave,

This is the pull request for radeon for 3.11.  Highlights include:

- Support for CIK (Sea Islands) asics: 3D, compute, UVD
- DPM (Dynamic Power Management) support for 6xx-SI
- ASPM support for 6xx-SI
- Assorted bug fixes

DPM is disabled by default for now until it gets further testing.  DPM
on 6xx and NI asics are still a bit problematic, but other asic families
are generally working well.  You can enable DPM by setting the dpm module
parameter to 1.

The following changes since commit 9b1be4dc02bb6b9761fbd8927c1750d75ddd2a8c:

  drm/radeon: fix UVD on big endian (2013-06-12 08:17:21 -0400)

are available in the git repository at:
  git://people.freedesktop.org/~agd5f/linux drm-next-3.11

Alex Deucher (166):
  drm/radeon: fix AVI infoframe generation
  drm/radeon: add backlight quirk for hybrid mac
  drm/radeon: add a reset work handler
  drm/radeon: add CIK chip families
  drm/radeon: add DCE8 macro for CIK
  drm/radeon: adapt to PCI BAR changes on CIK
  drm/radeon: add gpu init support for CIK (v9)
  drm/radeon: Add support for CIK GPU reset (v2)
  drm/radeon: add support for MC/VM setup on CIK (v6)
  drm/radeon/cik: stop page faults from hanging the system (v2)
  drm/radeon: add initial ucode loading for CIK (v5)
  drm/radeon: add support mc ucode loading on CIK (v2)
  drm/radeon: Add CP init for CIK (v7)
  drm/radeon: add IB and fence dispatch functions for CIK gfx (v7)
  drm/radeon: add ring and IB tests for CIK (v3)
  drm/radeon: implement async vm_flush for the CP (v7)
  drm/radeon: Add support for RLC init on CIK (v4)
  drm/radeon: add support for interrupts on CIK (v5)
  drm/radeon/cik: log and handle VM page fault interrupts
  drm/radeon/cik: add support for sDMA dma engines (v8)
  drm/radeon: implement async vm_flush for the sDMA (v6)
  drm/radeon/cik: add support for doing async VM pt updates (v5)
  drm/radeon/cik: fill in startup/shutdown callbacks (v5)
  drm/radeon: upstream ObjectID.h updates (v2)
  drm/radeon: upstream atombios.h updates (v2)
  drm/radeon: atombios power table updates (v2)
  drm/radeon: handle the integrated thermal controller on CI
  drm/radeon: update power state parsing for CI
  drm/radeon/dce8: add support for display watermark setup
  drm/radeon/cik: add hw cursor support (v2)
  drm/radeon/dce8: properly handle interlaced timing
  drm/radeon/dce8: crtc_set_base updates
  drm/radeon/atom: add DCE8 encoder support
  drm/radeon/atom: add support for new DVO tables
  drm/radeon: update DISPCLK programming for DCE8
  drm/radeon: add support pll selection for DCE8 (v4)
  drm/radeon: Handle PPLL0 powerdown on DCE8
  drm/radeon: use frac fb div on DCE8
  drm/radeon: add SS override support for KB/KV
  drm/radeon: Update radeon_info_ioctl for CIK (v2)
  drm/radeon: add get_gpu_clock_counter() callback for cik
  drm/radeon: update CIK soft reset
  drm/radeon: add indirect register accessors for SMC registers
  drm/radeon: add get_xclk() callback for CIK
  drm/radeon/cik: add pcie_port indirect register accessors
  drm/radeon: update radeon_atom_get_clock_dividers() for SI
  drm/radeon: update radeon_atom_get_clock_dividers for CIK
  drm/radeon/cik: add srbm_select function
  drm/radeon: use callbacks for ring pointer handling (v3)
  drm/radeon: implement simple doorbell page allocator
  drm/radeon/cik: Add support for compute queues (v4)
  drm/radeon/cik: switch to type3 nop packet for compute rings (v2)
  drm/radeon: fix up ring functions for compute rings
  drm/radeon/cik: add support for compute interrupts
  drm/radeon/cik: add support for golden register init
  drm/radeon: add radeon_asic struct for CIK (v12)
  drm/radeon: add cik tile mode array query
  drm/radeon: add current Bonaire PCI ids
  drm/radeon: add current KB pci ids
  drm/radeon/kms: add accessors for RCU indirect space
  drm/radeon/evergreen: add indirect register accessors for CG registers
  drm/radeon: make get_temperature functions a callback
  drm/radeon: add support for thermal sensor on tn
  drm/radeon/kms: move ucode defines to a separate header
  drm/radeon: properly set up the RLC on ON/LN/TN (v3)
  drm/radeon/kms: add atom helper functions for dpm (v3)
  drm/radeon/kms: add new asic struct for rv6xx (v4)
  drm/radeon/kms: add common dpm infrastructure
  drm/radeon/kms: fix up rs780/rs880 display watermark calc for dpm
  drm/radeon/kms: fix up 6xx/7xx display watermark calc for dpm
  drm/radeon/kms: fix up dce4/5 display watermark calc for dpm
  drm/radeon/kms: fix up dce6 display watermark calc for dpm
  drm/radeon/kms: add common r600 dpm functions
  drm/radeon/kms: add dpm support for rs780/rs880
  drm/radeon/kms: add dpm support for rv6xx 

[PATCH 111/165] drm/radeon/dpm: remove local sumo_get_xclk()

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Use the new asic callback instead.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/sumo_dpm.c|   19 +++
 drivers/gpu/drm/radeon/sumo_dpm.h|1 -
 drivers/gpu/drm/radeon/sumo_smc.c|2 +-
 drivers/gpu/drm/radeon/trinity_dpm.c |6 +++---
 4 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c 
b/drivers/gpu/drm/radeon/sumo_dpm.c
index 10700e1..80fb3ac 100644
--- a/drivers/gpu/drm/radeon/sumo_dpm.c
+++ b/drivers/gpu/drm/radeon/sumo_dpm.c
@@ -84,11 +84,6 @@ struct sumo_power_info *sumo_get_pi(struct radeon_device 
*rdev)
return pi;
 }

-u32 sumo_get_xclk(struct radeon_device *rdev)
-{
-   return rdev->clock.spll.reference_freq;
-}
-
 static void sumo_gfx_clockgating_enable(struct radeon_device *rdev, bool 
enable)
 {
if (enable)
@@ -124,7 +119,7 @@ static void sumo_mg_clockgating_enable(struct radeon_device 
*rdev, bool enable)
 static void sumo_program_git(struct radeon_device *rdev)
 {
u32 p, u;
-   u32 xclk = sumo_get_xclk(rdev);
+   u32 xclk = radeon_get_xclk(rdev);

r600_calculate_u_and_p(SUMO_GICST_DFLT,
   xclk, 16, , );
@@ -135,7 +130,7 @@ static void sumo_program_git(struct radeon_device *rdev)
 static void sumo_program_grsd(struct radeon_device *rdev)
 {
u32 p, u;
-   u32 xclk = sumo_get_xclk(rdev);
+   u32 xclk = radeon_get_xclk(rdev);
u32 grs = 256 * 25 / 100;

r600_calculate_u_and_p(1, xclk, 14, , );
@@ -155,7 +150,7 @@ static void sumo_gfx_powergating_initialize(struct 
radeon_device *rdev)
u32 p, u;
u32 p_c, p_p, d_p;
u32 r_t, i_t;
-   u32 xclk = sumo_get_xclk(rdev);
+   u32 xclk = radeon_get_xclk(rdev);

if (rdev->family == CHIP_PALM) {
p_c = 4;
@@ -319,7 +314,7 @@ static void sumo_calculate_bsp(struct radeon_device *rdev,
   u32 high_clk)
 {
struct sumo_power_info *pi = sumo_get_pi(rdev);
-   u32 xclk = sumo_get_xclk(rdev);
+   u32 xclk = radeon_get_xclk(rdev);

pi->pasi = 65535 * 100 / high_clk;
pi->asi = 65535 * 100 / high_clk;
@@ -466,7 +461,7 @@ void sumo_clear_vc(struct radeon_device *rdev)
 void sumo_program_sstp(struct radeon_device *rdev)
 {
u32 p, u;
-   u32 xclk = sumo_get_xclk(rdev);
+   u32 xclk = radeon_get_xclk(rdev);

r600_calculate_u_and_p(SUMO_SST_DFLT,
   xclk, 16, , );
@@ -909,7 +904,7 @@ static void sumo_start_am(struct radeon_device *rdev)

 static void sumo_program_ttp(struct radeon_device *rdev)
 {
-   u32 xclk = sumo_get_xclk(rdev);
+   u32 xclk = radeon_get_xclk(rdev);
u32 p, u;
u32 cg_sclk_dpm_ctrl_5 = RREG32(CG_SCLK_DPM_CTRL_5);

@@ -955,7 +950,7 @@ static void sumo_program_dc_hto(struct radeon_device *rdev)
 {
u32 cg_sclk_dpm_ctrl_4 = RREG32(CG_SCLK_DPM_CTRL_4);
u32 p, u;
-   u32 xclk = sumo_get_xclk(rdev);
+   u32 xclk = radeon_get_xclk(rdev);

r600_calculate_u_and_p(10,
   xclk, 14, , );
diff --git a/drivers/gpu/drm/radeon/sumo_dpm.h 
b/drivers/gpu/drm/radeon/sumo_dpm.h
index a3a7a61..07dda29 100644
--- a/drivers/gpu/drm/radeon/sumo_dpm.h
+++ b/drivers/gpu/drm/radeon/sumo_dpm.h
@@ -188,7 +188,6 @@ struct sumo_power_info {
 #define SUMO_GFXPOWERGATINGT_DFLT  100

 /* sumo_dpm.c */
-u32 sumo_get_xclk(struct radeon_device *rdev);
 void sumo_gfx_clockgating_initialize(struct radeon_device *rdev);
 void sumo_program_vc(struct radeon_device *rdev, u32 vrc);
 void sumo_clear_vc(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/sumo_smc.c 
b/drivers/gpu/drm/radeon/sumo_smc.c
index bc1a510..9cbf0b2 100644
--- a/drivers/gpu/drm/radeon/sumo_smc.c
+++ b/drivers/gpu/drm/radeon/sumo_smc.c
@@ -146,7 +146,7 @@ void sumo_enable_boost_timer(struct radeon_device *rdev)
 {
struct sumo_power_info *pi = sumo_get_pi(rdev);
u32 period, unit, timer_value;
-   u32 xclk = sumo_get_xclk(rdev);
+   u32 xclk = radeon_get_xclk(rdev);

unit = (RREG32_RCU(RCU_LCLK_SCALING_CNTL) & 
LCLK_SCALING_TIMER_PRESCALER_MASK)
>> LCLK_SCALING_TIMER_PRESCALER_SHIFT;
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c 
b/drivers/gpu/drm/radeon/trinity_dpm.c
index 1699e93..b2dc905 100644
--- a/drivers/gpu/drm/radeon/trinity_dpm.c
+++ b/drivers/gpu/drm/radeon/trinity_dpm.c
@@ -361,7 +361,7 @@ static void trinity_gfx_powergating_initialize(struct 
radeon_device *rdev)
u32 p, u;
u32 value;
struct atom_clock_dividers dividers;
-   u32 xclk = sumo_get_xclk(rdev);
+   u32 xclk = radeon_get_xclk(rdev);
u32 sssd = 1;
int ret;
u32 hw_rev = (RREG32(HW_REV) & ATI_REV_ID_MASK) >> ATI_REV_ID_SHIFT;
@@ -880,7 +880,7 @@ static void trinity_setup_uvd_dpm_interval(struct 
radeon_device *rdev,
u32 p, u;
u32 tp 

[PATCH 110/165] drm/radeon: add missing UVD clock set in cayman dpm code

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/ni_dpm.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c
index 01ecb80..a88f0cb 100644
--- a/drivers/gpu/drm/radeon/ni_dpm.c
+++ b/drivers/gpu/drm/radeon/ni_dpm.c
@@ -3667,9 +3667,11 @@ int ni_dpm_set_power_state(struct radeon_device *rdev)
 {
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
struct radeon_ps *new_ps = _pi->requested_rps;
+   struct radeon_ps *old_ps = _pi->current_rps;
int ret;

ni_restrict_performance_levels_before_switch(rdev);
+   rv770_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
ni_enable_power_containment(rdev, new_ps, false);
ni_enable_smc_cac(rdev, new_ps, false);
rv770_halt_smc(rdev);
@@ -3684,6 +3686,7 @@ int ni_dpm_set_power_state(struct radeon_device *rdev)
ni_populate_smc_tdp_limits(rdev, new_ps);
rv770_resume_smc(rdev);
rv770_set_sw_state(rdev);
+   rv770_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
ni_enable_smc_cac(rdev, new_ps, true);
ni_enable_power_containment(rdev, new_ps, true);

-- 
1.7.7.5



[PATCH 109/165] drm/radeon/dpm: remove broken dyn state remnants

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Now that the proper fix has been implemented I can
remove the last remnants of the initial implementation.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon.h|1 -
 drivers/gpu/drm/radeon/radeon_pm.c |   24 +---
 2 files changed, 5 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 657d224..0c6676a 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1307,7 +1307,6 @@ struct radeon_dpm {
struct radeon_ps*boot_ps;
/* default uvd power state */
struct radeon_ps*uvd_ps;
-   struct radeon_pshw_ps;
enum radeon_pm_state_type state;
enum radeon_pm_state_type user_state;
u32 platform_caps;
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c 
b/drivers/gpu/drm/radeon/radeon_pm.c
index a50efb0..c8688b3 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -687,17 +687,6 @@ restart_search:
return NULL;
 }

-static void radeon_dpm_update_requested_ps(struct radeon_device *rdev,
-  struct radeon_ps *ps)
-{
-   /* copy the ps to the hw ps and point the requested ps
-* at the hw state in case the driver wants to modify
-* the state dynamically.
-*/
-   rdev->pm.dpm.hw_ps = *ps;
-   rdev->pm.dpm.requested_ps = >pm.dpm.hw_ps;
-}
-
 static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev)
 {
int i;
@@ -719,7 +708,7 @@ static void radeon_dpm_change_power_state_locked(struct 
radeon_device *rdev)

ps = radeon_dpm_pick_power_state(rdev, dpm_state);
if (ps)
-   radeon_dpm_update_requested_ps(rdev, ps);
+   rdev->pm.dpm.requested_ps = ps;
else
return;

@@ -770,11 +759,9 @@ static void radeon_dpm_change_power_state_locked(struct 
radeon_device *rdev)
down_write(>pm.mclk_lock);
mutex_lock(>ring_lock);

-   if (rdev->asic->dpm.pre_set_power_state) {
-   ret = radeon_dpm_pre_set_power_state(rdev);
-   if (ret)
-   goto done;
-   }
+   ret = radeon_dpm_pre_set_power_state(rdev);
+   if (ret)
+   goto done;

/* update display watermarks based on new power state */
radeon_bandwidth_update(rdev);
@@ -797,8 +784,7 @@ static void radeon_dpm_change_power_state_locked(struct 
radeon_device *rdev)
/* update current power state */
rdev->pm.dpm.current_ps = rdev->pm.dpm.requested_ps;

-   if (rdev->asic->dpm.post_set_power_state)
-   radeon_dpm_post_set_power_state(rdev);
+   radeon_dpm_post_set_power_state(rdev);

 done:
mutex_unlock(>ring_lock);
-- 
1.7.7.5



[PATCH 108/165] drm/radeon/dpm: add pre/post_set_power_state callback (cayman)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

This properly implemented dynamic state adjustment by
using a working copy of the requested and current
power states.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/ni_dpm.c  |   65 --
 drivers/gpu/drm/radeon/ni_dpm.h  |3 +-
 drivers/gpu/drm/radeon/radeon_asic.c |2 +
 drivers/gpu/drm/radeon/radeon_asic.h |2 +
 4 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c
index ebc9837..01ecb80 100644
--- a/drivers/gpu/drm/radeon/ni_dpm.c
+++ b/drivers/gpu/drm/radeon/ni_dpm.c
@@ -791,7 +791,6 @@ static void ni_calculate_leakage_for_v_and_t(struct 
radeon_device *rdev,
 static void ni_apply_state_adjust_rules(struct radeon_device *rdev,
struct radeon_ps *rps)
 {
-   struct ni_power_info *ni_pi = ni_get_pi(rdev);
struct ni_ps *ps = ni_get_ps(rps);
struct radeon_clock_and_voltage_limits *max_limits;
bool disable_mclk_switching;
@@ -799,11 +798,6 @@ static void ni_apply_state_adjust_rules(struct 
radeon_device *rdev,
u16 vddc, vddci;
int i;

-   /* point to the hw copy since this function will modify the ps */
-   ni_pi->hw_ps = *ps;
-   rdev->pm.dpm.hw_ps.ps_priv = _pi->hw_ps;
-   ps = _pi->hw_ps;
-
if (rdev->pm.dpm.new_active_crtc_count > 1)
disable_mclk_switching = true;
else
@@ -3502,6 +3496,30 @@ void ni_dpm_setup_asic(struct radeon_device *rdev)
rv770_enable_acpi_pm(rdev);
 }

+static void ni_update_current_ps(struct radeon_device *rdev,
+struct radeon_ps *rps)
+{
+   struct ni_ps *new_ps = ni_get_ps(rps);
+   struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+struct ni_power_info *ni_pi = ni_get_pi(rdev);
+
+   eg_pi->current_rps = *rps;
+   ni_pi->current_ps = *new_ps;
+   eg_pi->current_rps.ps_priv = _pi->current_ps;
+}
+
+static void ni_update_requested_ps(struct radeon_device *rdev,
+  struct radeon_ps *rps)
+{
+   struct ni_ps *new_ps = ni_get_ps(rps);
+   struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+struct ni_power_info *ni_pi = ni_get_pi(rdev);
+
+   eg_pi->requested_rps = *rps;
+   ni_pi->requested_ps = *new_ps;
+   eg_pi->requested_rps.ps_priv = _pi->requested_ps;
+}
+
 int ni_dpm_enable(struct radeon_device *rdev)
 {
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
@@ -3576,6 +3594,8 @@ int ni_dpm_enable(struct radeon_device *rdev)

rv770_enable_auto_throttle_source(rdev, 
RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);

+   ni_update_current_ps(rdev, boot_ps);
+
return 0;
 }

@@ -3613,6 +3633,8 @@ void ni_dpm_disable(struct radeon_device *rdev)
btc_reset_to_default(rdev);
ni_stop_smc(rdev);
ni_force_switch_to_arb_f0(rdev);
+
+   ni_update_current_ps(rdev, boot_ps);
 }

 int ni_power_control_set_level(struct radeon_device *rdev)
@@ -3628,14 +3650,25 @@ int ni_power_control_set_level(struct radeon_device 
*rdev)
return 0;
 }

+int ni_dpm_pre_set_power_state(struct radeon_device *rdev)
+{
+   struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+   struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
+   struct radeon_ps *new_ps = _ps;
+
+   ni_update_requested_ps(rdev, new_ps);
+
+   ni_apply_state_adjust_rules(rdev, _pi->requested_rps);
+
+   return 0;
+}
+
 int ni_dpm_set_power_state(struct radeon_device *rdev)
 {
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
-   struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps;
+   struct radeon_ps *new_ps = _pi->requested_rps;
int ret;

-   ni_apply_state_adjust_rules(rdev, new_ps);
-
ni_restrict_performance_levels_before_switch(rdev);
ni_enable_power_containment(rdev, new_ps, false);
ni_enable_smc_cac(rdev, new_ps, false);
@@ -3657,6 +3690,14 @@ int ni_dpm_set_power_state(struct radeon_device *rdev)
return 0;
 }

+void ni_dpm_post_set_power_state(struct radeon_device *rdev)
+{
+   struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+   struct radeon_ps *new_ps = _pi->requested_rps;
+
+   ni_update_current_ps(rdev, new_ps);
+}
+
 void ni_dpm_reset_asic(struct radeon_device *rdev)
 {
ni_restrict_performance_levels_before_switch(rdev);
@@ -4078,7 +4119,8 @@ void ni_dpm_print_power_state(struct radeon_device *rdev,

 u32 ni_dpm_get_sclk(struct radeon_device *rdev, bool low)
 {
-   struct ni_ps *requested_state = ni_get_ps(rdev->pm.dpm.requested_ps);
+   struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+   struct ni_ps *requested_state = ni_get_ps(_pi->requested_rps);

if (low)
return requested_state->performance_levels[0].sclk;
@@ -4088,7 +4130,8 @@ 

[PATCH 107/165] drm/radeon/dpm: add pre/post_set_power_state callback (BTC)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

This properly implemented dynamic state adjustment by
using a working copy of the requested and current
power states.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/btc_dpm.c |   81 +
 drivers/gpu/drm/radeon/cypress_dpm.h |5 ++-
 drivers/gpu/drm/radeon/radeon_asic.c |6 ++-
 drivers/gpu/drm/radeon/radeon_asic.h |4 ++
 4 files changed, 83 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c
index 30aed00..7c7d58f 100644
--- a/drivers/gpu/drm/radeon/btc_dpm.c
+++ b/drivers/gpu/drm/radeon/btc_dpm.c
@@ -2062,18 +2062,12 @@ static void btc_init_stutter_mode(struct radeon_device 
*rdev)
 static void btc_apply_state_adjust_rules(struct radeon_device *rdev,
 struct radeon_ps *rps)
 {
-   struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
struct rv7xx_ps *ps = rv770_get_ps(rps);
struct radeon_clock_and_voltage_limits *max_limits;
bool disable_mclk_switching;
u32 mclk, sclk;
u16 vddc, vddci;

-   /* point to the hw copy since this function will modify the ps */
-   eg_pi->hw_ps = *ps;
-   rdev->pm.dpm.hw_ps.ps_priv = _pi->hw_ps;
-   ps = _pi->hw_ps;
-
if (rdev->pm.dpm.new_active_crtc_count > 1)
disable_mclk_switching = true;
else
@@ -,6 +2216,28 @@ static void btc_apply_state_adjust_rules(struct 
radeon_device *rdev,
ps->high.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
 }

+static void btc_update_current_ps(struct radeon_device *rdev,
+ struct radeon_ps *rps)
+{
+   struct rv7xx_ps *new_ps = rv770_get_ps(rps);
+   struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+   eg_pi->current_rps = *rps;
+   eg_pi->current_ps = *new_ps;
+   eg_pi->current_rps.ps_priv = _pi->current_ps;
+}
+
+static void btc_update_requested_ps(struct radeon_device *rdev,
+   struct radeon_ps *rps)
+{
+   struct rv7xx_ps *new_ps = rv770_get_ps(rps);
+   struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+   eg_pi->requested_rps = *rps;
+   eg_pi->requested_ps = *new_ps;
+   eg_pi->requested_rps.ps_priv = _pi->requested_ps;
+}
+
 void btc_dpm_reset_asic(struct radeon_device *rdev)
 {
rv770_restrict_performance_levels_before_switch(rdev);
@@ -2230,13 +2246,24 @@ void btc_dpm_reset_asic(struct radeon_device *rdev)
rv770_set_boot_state(rdev);
 }

-int btc_dpm_set_power_state(struct radeon_device *rdev)
+int btc_dpm_pre_set_power_state(struct radeon_device *rdev)
 {
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
-   struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps;
-   struct radeon_ps *old_ps = rdev->pm.dpm.current_ps;
+   struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
+   struct radeon_ps *new_ps = _ps;
+
+   btc_update_requested_ps(rdev, new_ps);
+
+   btc_apply_state_adjust_rules(rdev, _pi->requested_rps);

-   btc_apply_state_adjust_rules(rdev, new_ps);
+   return 0;
+}
+
+int btc_dpm_set_power_state(struct radeon_device *rdev)
+{
+   struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+   struct radeon_ps *new_ps = _pi->requested_rps;
+   struct radeon_ps *old_ps = _pi->current_rps;

btc_disable_ulv(rdev);
btc_set_boot_state_timing(rdev);
@@ -2269,6 +2296,14 @@ int btc_dpm_set_power_state(struct radeon_device *rdev)
return 0;
 }

+void btc_dpm_post_set_power_state(struct radeon_device *rdev)
+{
+   struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+   struct radeon_ps *new_ps = _pi->requested_rps;
+
+   btc_update_current_ps(rdev, new_ps);
+}
+
 int btc_dpm_enable(struct radeon_device *rdev)
 {
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
@@ -2364,6 +2399,8 @@ int btc_dpm_enable(struct radeon_device *rdev)

btc_init_stutter_mode(rdev);

+   btc_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
+
return 0;
 };

@@ -2402,6 +2439,8 @@ void btc_dpm_disable(struct radeon_device *rdev)
btc_reset_to_default(rdev);
btc_stop_smc(rdev);
cypress_enable_spread_spectrum(rdev, false);
+
+   btc_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
 }

 void btc_dpm_setup_asic(struct radeon_device *rdev)
@@ -2586,3 +2625,25 @@ void btc_dpm_fini(struct radeon_device *rdev)
kfree(rdev->pm.dpm.priv);
r600_free_extended_power_table(rdev);
 }
+
+u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low)
+{
+   struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+   struct rv7xx_ps *requested_state = rv770_get_ps(_pi->requested_rps);
+
+   if (low)
+   return requested_state->low.sclk;
+   else
+   return requested_state->high.sclk;
+}
+
+u32 

[PATCH 106/165] drm/radeon/dpm: add pre/post_set_power_state callback (TN)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

This properly implemented dynamic state adjustment by
using a working copy of the requested and current
power states.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_asic.c |2 +
 drivers/gpu/drm/radeon/radeon_asic.h |2 +
 drivers/gpu/drm/radeon/trinity_dpm.c |   73 -
 drivers/gpu/drm/radeon/trinity_dpm.h |6 ++-
 4 files changed, 61 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index c5d70da..c78519c 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1971,7 +1971,9 @@ static struct radeon_asic trinity_asic = {
.setup_asic = _dpm_setup_asic,
.enable = _dpm_enable,
.disable = _dpm_disable,
+   .pre_set_power_state = _dpm_pre_set_power_state,
.set_power_state = _dpm_set_power_state,
+   .post_set_power_state = _dpm_post_set_power_state,
.display_configuration_changed = 
_dpm_display_configuration_changed,
.fini = _dpm_fini,
.get_sclk = _dpm_get_sclk,
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h 
b/drivers/gpu/drm/radeon/radeon_asic.h
index 817fc26..14d992d 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -598,7 +598,9 @@ void ni_dpm_print_power_state(struct radeon_device *rdev,
 int trinity_dpm_init(struct radeon_device *rdev);
 int trinity_dpm_enable(struct radeon_device *rdev);
 void trinity_dpm_disable(struct radeon_device *rdev);
+int trinity_dpm_pre_set_power_state(struct radeon_device *rdev);
 int trinity_dpm_set_power_state(struct radeon_device *rdev);
+void trinity_dpm_post_set_power_state(struct radeon_device *rdev);
 void trinity_dpm_setup_asic(struct radeon_device *rdev);
 void trinity_dpm_display_configuration_changed(struct radeon_device *rdev);
 void trinity_dpm_fini(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c 
b/drivers/gpu/drm/radeon/trinity_dpm.c
index 103efbc..1699e93 100644
--- a/drivers/gpu/drm/radeon/trinity_dpm.c
+++ b/drivers/gpu/drm/radeon/trinity_dpm.c
@@ -832,15 +832,6 @@ static void trinity_unforce_levels(struct radeon_device 
*rdev)
trinity_dpm_no_forced_level(rdev);
 }

-static void trinity_update_current_power_levels(struct radeon_device *rdev,
-   struct radeon_ps *rps)
-{
-   struct trinity_ps *new_ps = trinity_get_ps(rps);
-   struct trinity_power_info *pi = trinity_get_pi(rdev);
-
-   pi->current_ps = *new_ps;
-}
-
 static void trinity_program_power_levels_0_to_n(struct radeon_device *rdev,
struct radeon_ps *new_rps,
struct radeon_ps *old_rps)
@@ -1046,6 +1037,28 @@ static int trinity_set_thermal_temperature_range(struct 
radeon_device *rdev,
return 0;
 }

+static void trinity_update_current_ps(struct radeon_device *rdev,
+ struct radeon_ps *rps)
+{
+   struct trinity_ps *new_ps = trinity_get_ps(rps);
+   struct trinity_power_info *pi = trinity_get_pi(rdev);
+
+   pi->current_rps = *rps;
+   pi->current_ps = *new_ps;
+   pi->current_rps.ps_priv = >current_ps;
+}
+
+static void trinity_update_requested_ps(struct radeon_device *rdev,
+   struct radeon_ps *rps)
+{
+   struct trinity_ps *new_ps = trinity_get_ps(rps);
+   struct trinity_power_info *pi = trinity_get_pi(rdev);
+
+   pi->requested_rps = *rps;
+   pi->requested_ps = *new_ps;
+   pi->requested_rps.ps_priv = >requested_ps;
+}
+
 int trinity_dpm_enable(struct radeon_device *rdev)
 {
struct trinity_power_info *pi = trinity_get_pi(rdev);
@@ -1077,6 +1090,8 @@ int trinity_dpm_enable(struct radeon_device *rdev)
radeon_irq_set(rdev);
}

+   trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
+
return 0;
 }

@@ -1099,6 +1114,8 @@ void trinity_dpm_disable(struct radeon_device *rdev)
rdev->irq.dpm_thermal = false;
radeon_irq_set(rdev);
}
+
+   trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
 }

 static void trinity_get_min_sclk_divider(struct radeon_device *rdev)
@@ -1127,14 +1144,26 @@ static void trinity_setup_nbp_sim(struct radeon_device 
*rdev,
}
 }

-int trinity_dpm_set_power_state(struct radeon_device *rdev)
+int trinity_dpm_pre_set_power_state(struct radeon_device *rdev)
 {
struct trinity_power_info *pi = trinity_get_pi(rdev);
-   struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps;
-   struct radeon_ps *old_ps = rdev->pm.dpm.current_ps;
+   struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
+   struct radeon_ps *new_ps = _ps;
+
+   

[PATCH 105/165] drm/radeon/dpm: add pre/post_set_power_state callback (sumo)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

This properly implemented dynamic state adjustment by
using a working copy of the requested and current
power states.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_asic.c |2 +
 drivers/gpu/drm/radeon/radeon_asic.h |2 +
 drivers/gpu/drm/radeon/sumo_dpm.c|   74 -
 drivers/gpu/drm/radeon/sumo_dpm.h|6 ++-
 4 files changed, 62 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index 5014bd1..c5d70da 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1552,7 +1552,9 @@ static struct radeon_asic sumo_asic = {
.setup_asic = _dpm_setup_asic,
.enable = _dpm_enable,
.disable = _dpm_disable,
+   .pre_set_power_state = _dpm_pre_set_power_state,
.set_power_state = _dpm_set_power_state,
+   .post_set_power_state = _dpm_post_set_power_state,
.display_configuration_changed = 
_dpm_display_configuration_changed,
.fini = _dpm_fini,
.get_sclk = _dpm_get_sclk,
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h 
b/drivers/gpu/drm/radeon/radeon_asic.h
index d7d4662..817fc26 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -541,7 +541,9 @@ void btc_dpm_fini(struct radeon_device *rdev);
 int sumo_dpm_init(struct radeon_device *rdev);
 int sumo_dpm_enable(struct radeon_device *rdev);
 void sumo_dpm_disable(struct radeon_device *rdev);
+int sumo_dpm_pre_set_power_state(struct radeon_device *rdev);
 int sumo_dpm_set_power_state(struct radeon_device *rdev);
+void sumo_dpm_post_set_power_state(struct radeon_device *rdev);
 void sumo_dpm_setup_asic(struct radeon_device *rdev);
 void sumo_dpm_display_configuration_changed(struct radeon_device *rdev);
 void sumo_dpm_fini(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c 
b/drivers/gpu/drm/radeon/sumo_dpm.c
index f5de850..10700e1 100644
--- a/drivers/gpu/drm/radeon/sumo_dpm.c
+++ b/drivers/gpu/drm/radeon/sumo_dpm.c
@@ -727,15 +727,6 @@ static void sumo_enable_boost(struct radeon_device *rdev,
sumo_boost_state_enable(rdev, false);
 }

-static void sumo_update_current_power_levels(struct radeon_device *rdev,
-struct radeon_ps *rps)
-{
-   struct sumo_ps *new_ps = sumo_get_ps(rps);
-   struct sumo_power_info *pi = sumo_get_pi(rdev);
-
-   pi->current_ps = *new_ps;
-}
-
 static void sumo_set_forced_level(struct radeon_device *rdev, u32 index)
 {
WREG32_P(CG_SCLK_DPM_CTRL_3, FORCE_SCLK_STATE(index), 
~FORCE_SCLK_STATE_MASK);
@@ -1089,11 +1080,6 @@ static void sumo_apply_state_adjust_rules(struct 
radeon_device *rdev,
u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */
u32 i;

-   /* point to the hw copy since this function will modify the ps */
-   pi->hw_ps = *ps;
-   rdev->pm.dpm.hw_ps.ps_priv = >hw_ps;
-   ps = >hw_ps;
-
if (new_rps->class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
return sumo_patch_thermal_state(rdev, ps, current_ps);

@@ -1192,6 +1178,28 @@ static int sumo_set_thermal_temperature_range(struct 
radeon_device *rdev,
return 0;
 }

+static void sumo_update_current_ps(struct radeon_device *rdev,
+  struct radeon_ps *rps)
+{
+   struct sumo_ps *new_ps = sumo_get_ps(rps);
+   struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+   pi->current_rps = *rps;
+   pi->current_ps = *new_ps;
+   pi->current_rps.ps_priv = >current_ps;
+}
+
+static void sumo_update_requested_ps(struct radeon_device *rdev,
+struct radeon_ps *rps)
+{
+   struct sumo_ps *new_ps = sumo_get_ps(rps);
+   struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+   pi->requested_rps = *rps;
+   pi->requested_ps = *new_ps;
+   pi->requested_rps.ps_priv = >requested_ps;
+}
+
 int sumo_dpm_enable(struct radeon_device *rdev)
 {
struct sumo_power_info *pi = sumo_get_pi(rdev);
@@ -1230,6 +1238,8 @@ int sumo_dpm_enable(struct radeon_device *rdev)
radeon_irq_set(rdev);
}

+   sumo_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
+
return 0;
 }

@@ -1252,19 +1262,34 @@ void sumo_dpm_disable(struct radeon_device *rdev)
rdev->irq.dpm_thermal = false;
radeon_irq_set(rdev);
}
+
+   sumo_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
 }

-int sumo_dpm_set_power_state(struct radeon_device *rdev)
+int sumo_dpm_pre_set_power_state(struct radeon_device *rdev)
 {
struct sumo_power_info *pi = sumo_get_pi(rdev);
-   struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps;
-   struct radeon_ps *old_ps = rdev->pm.dpm.current_ps;
+   struct radeon_ps requested_ps = 

[PATCH 104/165] drm/radeon/dpm: add pre/post_set_power_state callbacks (6xx-eg)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

For r6xx-evergreen, they are no-ops as they don't support
any dynamic state adjustment.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/r600_dpm.c|   10 ++
 drivers/gpu/drm/radeon/radeon_asic.c |8 
 drivers/gpu/drm/radeon/radeon_asic.h |2 ++
 3 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r600_dpm.c 
b/drivers/gpu/drm/radeon/r600_dpm.c
index c9f9647..bcb1967 100644
--- a/drivers/gpu/drm/radeon/r600_dpm.c
+++ b/drivers/gpu/drm/radeon/r600_dpm.c
@@ -662,6 +662,16 @@ void r600_stop_dpm(struct radeon_device *rdev)
r600_dynamicpm_enable(rdev, false);
 }

+int r600_dpm_pre_set_power_state(struct radeon_device *rdev)
+{
+   return 0;
+}
+
+void r600_dpm_post_set_power_state(struct radeon_device *rdev)
+{
+
+}
+
 bool r600_is_uvd_state(u32 class, u32 class2)
 {
if (class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index e6703ef..5014bd1 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1110,7 +1110,9 @@ static struct radeon_asic rv6xx_asic = {
.setup_asic = _setup_asic,
.enable = _dpm_enable,
.disable = _dpm_disable,
+   .pre_set_power_state = _dpm_pre_set_power_state,
.set_power_state = _dpm_set_power_state,
+   .post_set_power_state = _dpm_post_set_power_state,
.display_configuration_changed = 
_dpm_display_configuration_changed,
.fini = _dpm_fini,
.get_sclk = _dpm_get_sclk,
@@ -1211,7 +1213,9 @@ static struct radeon_asic rs780_asic = {
.setup_asic = _dpm_setup_asic,
.enable = _dpm_enable,
.disable = _dpm_disable,
+   .pre_set_power_state = _dpm_pre_set_power_state,
.set_power_state = _dpm_set_power_state,
+   .post_set_power_state = _dpm_post_set_power_state,
.display_configuration_changed = 
_dpm_display_configuration_changed,
.fini = _dpm_fini,
.get_sclk = _dpm_get_sclk,
@@ -1322,7 +1326,9 @@ static struct radeon_asic rv770_asic = {
.setup_asic = _dpm_setup_asic,
.enable = _dpm_enable,
.disable = _dpm_disable,
+   .pre_set_power_state = _dpm_pre_set_power_state,
.set_power_state = _dpm_set_power_state,
+   .post_set_power_state = _dpm_post_set_power_state,
.display_configuration_changed = 
_dpm_display_configuration_changed,
.fini = _dpm_fini,
.get_sclk = _dpm_get_sclk,
@@ -1433,7 +1439,9 @@ static struct radeon_asic evergreen_asic = {
.setup_asic = _dpm_setup_asic,
.enable = _dpm_enable,
.disable = _dpm_disable,
+   .pre_set_power_state = _dpm_pre_set_power_state,
.set_power_state = _dpm_set_power_state,
+   .post_set_power_state = _dpm_post_set_power_state,
.display_configuration_changed = 
_dpm_display_configuration_changed,
.fini = _dpm_fini,
.get_sclk = _dpm_get_sclk,
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h 
b/drivers/gpu/drm/radeon/radeon_asic.h
index 2fef64d..d7d4662 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -396,6 +396,8 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev);
 u32 r600_get_xclk(struct radeon_device *rdev);
 uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev);
 int rv6xx_get_temp(struct radeon_device *rdev);
+int r600_dpm_pre_set_power_state(struct radeon_device *rdev);
+void r600_dpm_post_set_power_state(struct radeon_device *rdev);
 /* rv6xx dpm */
 int rv6xx_dpm_init(struct radeon_device *rdev);
 int rv6xx_dpm_enable(struct radeon_device *rdev);
-- 
1.7.7.5



[PATCH 103/165] drm/radeon/dpm: add new pre/post_set_power_state callbacks

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Needed to properly handle dynamic state adjustment.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon.h|4 
 drivers/gpu/drm/radeon/radeon_pm.c |   11 +++
 2 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 16c7d52..657d224 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1616,7 +1616,9 @@ struct radeon_asic {
void (*setup_asic)(struct radeon_device *rdev);
int (*enable)(struct radeon_device *rdev);
void (*disable)(struct radeon_device *rdev);
+   int (*pre_set_power_state)(struct radeon_device *rdev);
int (*set_power_state)(struct radeon_device *rdev);
+   void (*post_set_power_state)(struct radeon_device *rdev);
void (*display_configuration_changed)(struct radeon_device 
*rdev);
void (*fini)(struct radeon_device *rdev);
u32 (*get_sclk)(struct radeon_device *rdev, bool low);
@@ -2326,7 +2328,9 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t 
v);
 #define radeon_dpm_setup_asic(rdev) rdev->asic->dpm.setup_asic((rdev))
 #define radeon_dpm_enable(rdev) rdev->asic->dpm.enable((rdev))
 #define radeon_dpm_disable(rdev) rdev->asic->dpm.disable((rdev))
+#define radeon_dpm_pre_set_power_state(rdev) 
rdev->asic->dpm.pre_set_power_state((rdev))
 #define radeon_dpm_set_power_state(rdev) 
rdev->asic->dpm.set_power_state((rdev))
+#define radeon_dpm_post_set_power_state(rdev) 
rdev->asic->dpm.post_set_power_state((rdev))
 #define radeon_dpm_display_configuration_changed(rdev) 
rdev->asic->dpm.display_configuration_changed((rdev))
 #define radeon_dpm_fini(rdev) rdev->asic->dpm.fini((rdev))
 #define radeon_dpm_get_sclk(rdev, l) rdev->asic->dpm.get_sclk((rdev), (l))
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c 
b/drivers/gpu/drm/radeon/radeon_pm.c
index 01ff18b..a50efb0 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -703,6 +703,7 @@ static void radeon_dpm_change_power_state_locked(struct 
radeon_device *rdev)
int i;
struct radeon_ps *ps;
enum radeon_pm_state_type dpm_state;
+   int ret;

/* if dpm init failed */
if (!rdev->pm.dpm_enabled)
@@ -769,6 +770,12 @@ static void radeon_dpm_change_power_state_locked(struct 
radeon_device *rdev)
down_write(>pm.mclk_lock);
mutex_lock(>ring_lock);

+   if (rdev->asic->dpm.pre_set_power_state) {
+   ret = radeon_dpm_pre_set_power_state(rdev);
+   if (ret)
+   goto done;
+   }
+
/* update display watermarks based on new power state */
radeon_bandwidth_update(rdev);
/* update displays */
@@ -790,6 +797,10 @@ static void radeon_dpm_change_power_state_locked(struct 
radeon_device *rdev)
/* update current power state */
rdev->pm.dpm.current_ps = rdev->pm.dpm.requested_ps;

+   if (rdev->asic->dpm.post_set_power_state)
+   radeon_dpm_post_set_power_state(rdev);
+
+done:
mutex_unlock(>ring_lock);
up_write(>pm.mclk_lock);
mutex_unlock(>ddev->struct_mutex);
-- 
1.7.7.5



[PATCH 102/165] drm/radeon/dpm/tn: restructure code

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Needed to properly handle dynamic state adjustment.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/trinity_dpm.c |   93 +++---
 1 files changed, 52 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c 
b/drivers/gpu/drm/radeon/trinity_dpm.c
index 0c1b50a..103efbc 100644
--- a/drivers/gpu/drm/radeon/trinity_dpm.c
+++ b/drivers/gpu/drm/radeon/trinity_dpm.c
@@ -337,7 +337,9 @@ static const u32 trinity_override_mgpg_sequences[] =
 static void trinity_program_clk_gating_hw_sequence(struct radeon_device *rdev,
   const u32 *seq, u32 count);
 static void trinity_override_dynamic_mg_powergating(struct radeon_device 
*rdev);
-static void trinity_apply_state_adjust_rules(struct radeon_device *rdev);
+static void trinity_apply_state_adjust_rules(struct radeon_device *rdev,
+struct radeon_ps *new_rps,
+struct radeon_ps *old_rps);

 struct trinity_ps *trinity_get_ps(struct radeon_ps *rps)
 {
@@ -830,18 +832,21 @@ static void trinity_unforce_levels(struct radeon_device 
*rdev)
trinity_dpm_no_forced_level(rdev);
 }

-static void trinity_update_current_power_levels(struct radeon_device *rdev)
+static void trinity_update_current_power_levels(struct radeon_device *rdev,
+   struct radeon_ps *rps)
 {
-   struct trinity_ps *new_ps = trinity_get_ps(rdev->pm.dpm.requested_ps);
+   struct trinity_ps *new_ps = trinity_get_ps(rps);
struct trinity_power_info *pi = trinity_get_pi(rdev);

pi->current_ps = *new_ps;
 }

-static void trinity_program_power_levels_0_to_n(struct radeon_device *rdev)
+static void trinity_program_power_levels_0_to_n(struct radeon_device *rdev,
+   struct radeon_ps *new_rps,
+   struct radeon_ps *old_rps)
 {
-   struct trinity_ps *new_ps = trinity_get_ps(rdev->pm.dpm.requested_ps);
-   struct trinity_ps *old_ps = trinity_get_ps(rdev->pm.dpm.current_ps);
+   struct trinity_ps *new_ps = trinity_get_ps(new_rps);
+   struct trinity_ps *old_ps = trinity_get_ps(old_rps);
u32 i;
u32 n_current_state_levels = (old_ps == NULL) ? 1 : old_ps->num_levels;

@@ -919,19 +924,19 @@ static bool trinity_uvd_clocks_equal(struct radeon_ps 
*rps1,
 }

 static void trinity_setup_uvd_clocks(struct radeon_device *rdev,
-struct radeon_ps *current_rps,
-struct radeon_ps *new_rps)
+struct radeon_ps *new_rps,
+struct radeon_ps *old_rps)
 {
struct trinity_power_info *pi = trinity_get_pi(rdev);

if (pi->uvd_dpm) {
if (trinity_uvd_clocks_zero(new_rps) &&
-   !trinity_uvd_clocks_zero(current_rps)) {
+   !trinity_uvd_clocks_zero(old_rps)) {
trinity_setup_uvd_dpm_interval(rdev, 0);
} else if (!trinity_uvd_clocks_zero(new_rps)) {
trinity_setup_uvd_clock_table(rdev, new_rps);

-   if (trinity_uvd_clocks_zero(current_rps)) {
+   if (trinity_uvd_clocks_zero(old_rps)) {
u32 tmp = RREG32(CG_MISC_REG);
tmp &= 0xfffd;
WREG32(CG_MISC_REG, tmp);
@@ -944,37 +949,39 @@ static void trinity_setup_uvd_clocks(struct radeon_device 
*rdev,
trinity_uvd_dpm_config(rdev);
} else {
if (trinity_uvd_clocks_zero(new_rps) ||
-   trinity_uvd_clocks_equal(new_rps, current_rps))
+   trinity_uvd_clocks_equal(new_rps, old_rps))
return;

radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
}
 }

-static void trinity_set_uvd_clock_before_set_eng_clock(struct radeon_device 
*rdev)
+static void trinity_set_uvd_clock_before_set_eng_clock(struct radeon_device 
*rdev,
+  struct radeon_ps 
*new_rps,
+  struct radeon_ps 
*old_rps)
 {
-   struct trinity_ps *new_ps = trinity_get_ps(rdev->pm.dpm.requested_ps);
-   struct trinity_ps *current_ps = trinity_get_ps(rdev->pm.dpm.current_ps);
+   struct trinity_ps *new_ps = trinity_get_ps(new_rps);
+   struct trinity_ps *current_ps = trinity_get_ps(new_rps);

if (new_ps->levels[new_ps->num_levels - 1].sclk >=
current_ps->levels[current_ps->num_levels - 1].sclk)
return;

-   trinity_setup_uvd_clocks(rdev, rdev->pm.dpm.current_ps,
-rdev->pm.dpm.requested_ps);
+   

[PATCH 101/165] drm/radeon/dpm/sumo: restructure code

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Needed to properly handle dynamic state adjustment.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/sumo_dpm.c |  143 +
 1 files changed, 81 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c 
b/drivers/gpu/drm/radeon/sumo_dpm.c
index 3805302..f5de850 100644
--- a/drivers/gpu/drm/radeon/sumo_dpm.c
+++ b/drivers/gpu/drm/radeon/sumo_dpm.c
@@ -342,10 +342,11 @@ static void sumo_init_bsp(struct radeon_device *rdev)
 }


-static void sumo_program_bsp(struct radeon_device *rdev)
+static void sumo_program_bsp(struct radeon_device *rdev,
+struct radeon_ps *rps)
 {
struct sumo_power_info *pi = sumo_get_pi(rdev);
-   struct sumo_ps *ps = sumo_get_ps(rdev->pm.dpm.requested_ps);
+   struct sumo_ps *ps = sumo_get_ps(rps);
u32 i;
u32 highest_engine_clock = ps->levels[ps->num_levels - 1].sclk;

@@ -384,10 +385,11 @@ static void sumo_write_at(struct radeon_device *rdev,
WREG32(CG_AT_7, value);
 }

-static void sumo_program_at(struct radeon_device *rdev)
+static void sumo_program_at(struct radeon_device *rdev,
+   struct radeon_ps *rps)
 {
struct sumo_power_info *pi = sumo_get_pi(rdev);
-   struct sumo_ps *ps = sumo_get_ps(rdev->pm.dpm.requested_ps);
+   struct sumo_ps *ps = sumo_get_ps(rps);
u32 asi;
u32 i;
u32 m_a;
@@ -662,10 +664,11 @@ static void sumo_enable_power_level_0(struct 
radeon_device *rdev)
sumo_power_level_enable(rdev, 0, true);
 }

-static void sumo_patch_boost_state(struct radeon_device *rdev)
+static void sumo_patch_boost_state(struct radeon_device *rdev,
+  struct radeon_ps *rps)
 {
struct sumo_power_info *pi = sumo_get_pi(rdev);
-   struct sumo_ps *new_ps = sumo_get_ps(rdev->pm.dpm.requested_ps);
+   struct sumo_ps *new_ps = sumo_get_ps(rps);

if (new_ps->flags & SUMO_POWERSTATE_FLAGS_BOOST_STATE) {
pi->boost_pl = new_ps->levels[new_ps->num_levels - 1];
@@ -675,10 +678,12 @@ static void sumo_patch_boost_state(struct radeon_device 
*rdev)
}
 }

-static void sumo_pre_notify_alt_vddnb_change(struct radeon_device *rdev)
+static void sumo_pre_notify_alt_vddnb_change(struct radeon_device *rdev,
+struct radeon_ps *new_rps,
+struct radeon_ps *old_rps)
 {
-   struct sumo_ps *new_ps = sumo_get_ps(rdev->pm.dpm.requested_ps);
-   struct sumo_ps *old_ps = sumo_get_ps(rdev->pm.dpm.current_ps);
+   struct sumo_ps *new_ps = sumo_get_ps(new_rps);
+   struct sumo_ps *old_ps = sumo_get_ps(old_rps);
u32 nbps1_old = 0;
u32 nbps1_new = 0;

@@ -691,10 +696,12 @@ static void sumo_pre_notify_alt_vddnb_change(struct 
radeon_device *rdev)
sumo_smu_notify_alt_vddnb_change(rdev, 0, 0);
 }

-static void sumo_post_notify_alt_vddnb_change(struct radeon_device *rdev)
+static void sumo_post_notify_alt_vddnb_change(struct radeon_device *rdev,
+ struct radeon_ps *new_rps,
+ struct radeon_ps *old_rps)
 {
-   struct sumo_ps *new_ps = sumo_get_ps(rdev->pm.dpm.requested_ps);
-   struct sumo_ps *old_ps = sumo_get_ps(rdev->pm.dpm.current_ps);
+   struct sumo_ps *new_ps = sumo_get_ps(new_rps);
+   struct sumo_ps *old_ps = sumo_get_ps(old_rps);
u32 nbps1_old = 0;
u32 nbps1_new = 0;

@@ -707,9 +714,11 @@ static void sumo_post_notify_alt_vddnb_change(struct 
radeon_device *rdev)
sumo_smu_notify_alt_vddnb_change(rdev, 1, 1);
 }

-static void sumo_enable_boost(struct radeon_device *rdev, bool enable)
+static void sumo_enable_boost(struct radeon_device *rdev,
+ struct radeon_ps *rps,
+ bool enable)
 {
-   struct sumo_ps *new_ps = sumo_get_ps(rdev->pm.dpm.requested_ps);
+   struct sumo_ps *new_ps = sumo_get_ps(rps);

if (enable) {
if (new_ps->flags & SUMO_POWERSTATE_FLAGS_BOOST_STATE)
@@ -718,9 +727,10 @@ static void sumo_enable_boost(struct radeon_device *rdev, 
bool enable)
sumo_boost_state_enable(rdev, false);
 }

-static void sumo_update_current_power_levels(struct radeon_device *rdev)
+static void sumo_update_current_power_levels(struct radeon_device *rdev,
+struct radeon_ps *rps)
 {
-   struct sumo_ps *new_ps = sumo_get_ps(rdev->pm.dpm.requested_ps);
+   struct sumo_ps *new_ps = sumo_get_ps(rps);
struct sumo_power_info *pi = sumo_get_pi(rdev);

pi->current_ps = *new_ps;
@@ -736,9 +746,10 @@ static void sumo_set_forced_level_0(struct radeon_device 
*rdev)
sumo_set_forced_level(rdev, 0);
 }

-static void sumo_program_wl(struct radeon_device *rdev)
+static void 

[PATCH 100/165] drm/radeon/dpm/cayman: restructure code

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Needed to properly handle dynamic state adjustment.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/ni_dpm.c |   69 --
 1 files changed, 36 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c
index 9f68115..ebc9837 100644
--- a/drivers/gpu/drm/radeon/ni_dpm.c
+++ b/drivers/gpu/drm/radeon/ni_dpm.c
@@ -788,10 +788,10 @@ static void ni_calculate_leakage_for_v_and_t(struct 
radeon_device *rdev,
ni_calculate_leakage_for_v_and_t_formula(coeff, v, t, i_leakage, 
leakage);
 }

-static void ni_apply_state_adjust_rules(struct radeon_device *rdev)
+static void ni_apply_state_adjust_rules(struct radeon_device *rdev,
+   struct radeon_ps *rps)
 {
struct ni_power_info *ni_pi = ni_get_pi(rdev);
-   struct radeon_ps *rps = rdev->pm.dpm.requested_ps;
struct ni_ps *ps = ni_get_ps(rps);
struct radeon_clock_and_voltage_limits *max_limits;
bool disable_mclk_switching;
@@ -1434,13 +1434,13 @@ static int ni_calculate_adjusted_tdp_limits(struct 
radeon_device *rdev,
return 0;
 }

-static int ni_populate_smc_tdp_limits(struct radeon_device *rdev)
+static int ni_populate_smc_tdp_limits(struct radeon_device *rdev,
+ struct radeon_ps *radeon_state)
 {
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
struct ni_power_info *ni_pi = ni_get_pi(rdev);

if (ni_pi->enable_power_containment) {
-   struct radeon_ps *radeon_state = rdev->pm.dpm.requested_ps;
NISLANDS_SMC_STATETABLE *smc_table = _pi->smc_statetable;
u32 scaling_factor = ni_get_smc_power_scaling_factor(rdev);
u32 tdp_limit;
@@ -1647,10 +1647,9 @@ static int ni_do_program_memory_timing_parameters(struct 
radeon_device *rdev,
return ret;
 }

-static int ni_program_memory_timing_parameters(struct radeon_device *rdev)
+static int ni_program_memory_timing_parameters(struct radeon_device *rdev,
+  struct radeon_ps 
*radeon_new_state)
 {
-   struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
-
return ni_do_program_memory_timing_parameters(rdev, radeon_new_state,
  
NISLANDS_DRIVER_STATE_ARB_INDEX);
 }
@@ -2576,7 +2575,9 @@ static int ni_populate_sq_ramping_values(struct 
radeon_device *rdev,
return 0;
 }

-static int ni_enable_power_containment(struct radeon_device *rdev, bool enable)
+static int ni_enable_power_containment(struct radeon_device *rdev,
+  struct radeon_ps *radeon_new_state,
+  bool enable)
 {
 struct ni_power_info *ni_pi = ni_get_pi(rdev);
PPSMC_Result smc_result;
@@ -2584,8 +2585,6 @@ static int ni_enable_power_containment(struct 
radeon_device *rdev, bool enable)

if (ni_pi->enable_power_containment) {
if (enable) {
-   struct radeon_ps *radeon_new_state = 
rdev->pm.dpm.requested_ps;
-
if (!r600_is_uvd_state(radeon_new_state->class, 
radeon_new_state->class2)) {
smc_result = rv770_send_msg_to_smc(rdev, 
PPSMC_TDPClampingActive);
if (smc_result != PPSMC_Result_OK) {
@@ -2665,10 +2664,10 @@ static int ni_convert_power_state_to_smc(struct 
radeon_device *rdev,
return ni_populate_smc_t(rdev, radeon_state, smc_state);
 }

-static int ni_upload_sw_state(struct radeon_device *rdev)
+static int ni_upload_sw_state(struct radeon_device *rdev,
+ struct radeon_ps *radeon_new_state)
 {
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
-   struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
u16 address = pi->state_table_start +
offsetof(NISLANDS_SMC_STATETABLE, driverState);
u16 state_size = sizeof(NISLANDS_SMC_SWSTATE) +
@@ -2974,12 +2973,12 @@ static void ni_convert_mc_reg_table_to_smc(struct 
radeon_device *rdev,
}
 }

-static int ni_populate_mc_reg_table(struct radeon_device *rdev)
+static int ni_populate_mc_reg_table(struct radeon_device *rdev,
+   struct radeon_ps *radeon_boot_state)
 {
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
 struct ni_power_info *ni_pi = ni_get_pi(rdev);
-struct radeon_ps *radeon_boot_state = rdev->pm.dpm.boot_ps;
struct ni_ps *boot_state = ni_get_ps(radeon_boot_state);
SMC_NIslands_MCRegisters *mc_reg_table = _pi->smc_mc_reg_table;

@@ -3005,12 +3004,12 @@ static int ni_populate_mc_reg_table(struct 
radeon_device *rdev)
   pi->sram_end);
 }

-static int 

[PATCH 099/165] drm/radeon/dpm/btc: restructure code

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Needed to properly handle dynamic state adjustment.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/btc_dpm.c |   30 +++---
 drivers/gpu/drm/radeon/btc_dpm.h |3 ++-
 drivers/gpu/drm/radeon/ni_dpm.c  |3 ++-
 3 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c
index 73a0ba3..30aed00 100644
--- a/drivers/gpu/drm/radeon/btc_dpm.c
+++ b/drivers/gpu/drm/radeon/btc_dpm.c
@@ -1604,11 +1604,11 @@ bool btc_dpm_enabled(struct radeon_device *rdev)
return false;
 }

-static int btc_init_smc_table(struct radeon_device *rdev)
+static int btc_init_smc_table(struct radeon_device *rdev,
+ struct radeon_ps *radeon_boot_state)
 {
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
-   struct radeon_ps *radeon_boot_state = rdev->pm.dpm.boot_ps;
RV770_SMC_STATETABLE *table = >smc_statetable;
int ret;

@@ -1668,11 +1668,11 @@ static int btc_init_smc_table(struct radeon_device 
*rdev)
   pi->sram_end);
 }

-static void btc_set_at_for_uvd(struct radeon_device *rdev)
+static void btc_set_at_for_uvd(struct radeon_device *rdev,
+  struct radeon_ps *radeon_new_state)
 {
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
-   struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
int idx = 0;

if (r600_is_uvd_state(radeon_new_state->class, 
radeon_new_state->class2))
@@ -1692,9 +1692,9 @@ static void btc_set_at_for_uvd(struct radeon_device *rdev)

 }

-void btc_notify_uvd_to_smc(struct radeon_device *rdev)
+void btc_notify_uvd_to_smc(struct radeon_device *rdev,
+  struct radeon_ps *radeon_new_state)
 {
-   struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);

if (r600_is_uvd_state(radeon_new_state->class, 
radeon_new_state->class2)) {
@@ -1814,11 +1814,11 @@ static int btc_enable_ulv(struct radeon_device *rdev)
return 0;
 }

-static int btc_set_power_state_conditionally_enable_ulv(struct radeon_device 
*rdev)
+static int btc_set_power_state_conditionally_enable_ulv(struct radeon_device 
*rdev,
+   struct radeon_ps 
*radeon_new_state)
 {
int ret = 0;
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
-   struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;

if (eg_pi->ulv.supported) {
if (btc_is_state_ulv_compatible(rdev, radeon_new_state)) {
@@ -2059,10 +2059,10 @@ static void btc_init_stutter_mode(struct radeon_device 
*rdev)
}
 }

-static void btc_apply_state_adjust_rules(struct radeon_device *rdev)
+static void btc_apply_state_adjust_rules(struct radeon_device *rdev,
+struct radeon_ps *rps)
 {
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
-   struct radeon_ps *rps = rdev->pm.dpm.requested_ps;
struct rv7xx_ps *ps = rv770_get_ps(rps);
struct radeon_clock_and_voltage_limits *max_limits;
bool disable_mclk_switching;
@@ -2236,7 +2236,7 @@ int btc_dpm_set_power_state(struct radeon_device *rdev)
struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps;
struct radeon_ps *old_ps = rdev->pm.dpm.current_ps;

-   btc_apply_state_adjust_rules(rdev);
+   btc_apply_state_adjust_rules(rdev, new_ps);

btc_disable_ulv(rdev);
btc_set_boot_state_timing(rdev);
@@ -2247,9 +2247,9 @@ int btc_dpm_set_power_state(struct radeon_device *rdev)

rv770_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
rv770_halt_smc(rdev);
-   btc_set_at_for_uvd(rdev);
+   btc_set_at_for_uvd(rdev, new_ps);
if (eg_pi->smu_uvd_hs)
-   btc_notify_uvd_to_smc(rdev);
+   btc_notify_uvd_to_smc(rdev, new_ps);
cypress_upload_sw_state(rdev, new_ps);

if (eg_pi->dynamic_ac_timing)
@@ -2264,7 +2264,7 @@ int btc_dpm_set_power_state(struct radeon_device *rdev)
if (eg_pi->pcie_performance_request)
cypress_notify_link_speed_change_after_state_change(rdev, 
new_ps, old_ps);

-   btc_set_power_state_conditionally_enable_ulv(rdev);
+   btc_set_power_state_conditionally_enable_ulv(rdev, new_ps);

return 0;
 }
@@ -2323,7 +2323,7 @@ int btc_dpm_enable(struct radeon_device *rdev)
return -EINVAL;

cypress_get_table_locations(rdev);
-   btc_init_smc_table(rdev);
+   btc_init_smc_table(rdev, boot_ps);

if (eg_pi->dynamic_ac_timing)
cypress_populate_mc_reg_table(rdev, boot_ps);
diff --git 

[PATCH 098/165] drm/radeon/dpm/evergreen: restructure code

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Needed to properly handle dynamic state adjustment.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/btc_dpm.c |   13 ---
 drivers/gpu/drm/radeon/cypress_dpm.c |   62 +
 drivers/gpu/drm/radeon/cypress_dpm.h |   20 ---
 3 files changed, 53 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c
index 3ae4de6..73a0ba3 100644
--- a/drivers/gpu/drm/radeon/btc_dpm.c
+++ b/drivers/gpu/drm/radeon/btc_dpm.c
@@ -2243,26 +2243,26 @@ int btc_dpm_set_power_state(struct radeon_device *rdev)
rv770_restrict_performance_levels_before_switch(rdev);

if (eg_pi->pcie_performance_request)
-   cypress_notify_link_speed_change_before_state_change(rdev);
+   cypress_notify_link_speed_change_before_state_change(rdev, 
new_ps, old_ps);

rv770_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
rv770_halt_smc(rdev);
btc_set_at_for_uvd(rdev);
if (eg_pi->smu_uvd_hs)
btc_notify_uvd_to_smc(rdev);
-   cypress_upload_sw_state(rdev);
+   cypress_upload_sw_state(rdev, new_ps);

if (eg_pi->dynamic_ac_timing)
-   cypress_upload_mc_reg_table(rdev);
+   cypress_upload_mc_reg_table(rdev, new_ps);

-   cypress_program_memory_timing_parameters(rdev);
+   cypress_program_memory_timing_parameters(rdev, new_ps);

rv770_resume_smc(rdev);
rv770_set_sw_state(rdev);
rv770_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);

if (eg_pi->pcie_performance_request)
-   cypress_notify_link_speed_change_after_state_change(rdev);
+   cypress_notify_link_speed_change_after_state_change(rdev, 
new_ps, old_ps);

btc_set_power_state_conditionally_enable_ulv(rdev);

@@ -2273,6 +2273,7 @@ int btc_dpm_enable(struct radeon_device *rdev)
 {
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+   struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;

if (pi->gfx_clock_gating)
btc_cg_clock_gating_default(rdev);
@@ -2325,7 +2326,7 @@ int btc_dpm_enable(struct radeon_device *rdev)
btc_init_smc_table(rdev);

if (eg_pi->dynamic_ac_timing)
-   cypress_populate_mc_reg_table(rdev);
+   cypress_populate_mc_reg_table(rdev, boot_ps);

cypress_program_response_times(rdev);
r7xx_start_smc(rdev);
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c 
b/drivers/gpu/drm/radeon/cypress_dpm.c
index c9026ed..1ce1f08 100644
--- a/drivers/gpu/drm/radeon/cypress_dpm.c
+++ b/drivers/gpu/drm/radeon/cypress_dpm.c
@@ -353,10 +353,10 @@ static u32 cypress_get_maximum_link_speed(struct 
radeon_ps *radeon_state)
return 0;
 }

-void cypress_notify_link_speed_change_after_state_change(struct radeon_device 
*rdev)
+void cypress_notify_link_speed_change_after_state_change(struct radeon_device 
*rdev,
+struct radeon_ps 
*radeon_new_state,
+struct radeon_ps 
*radeon_current_state)
 {
-   struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
-   struct radeon_ps *radeon_current_state = rdev->pm.dpm.current_ps;
u32 pcie_link_speed_target =  
cypress_get_maximum_link_speed(radeon_new_state);
u32 pcie_link_speed_current = 
cypress_get_maximum_link_speed(radeon_current_state);
u8 request;
@@ -373,10 +373,10 @@ void 
cypress_notify_link_speed_change_after_state_change(struct radeon_device *r
}
 }

-void cypress_notify_link_speed_change_before_state_change(struct radeon_device 
*rdev)
+void cypress_notify_link_speed_change_before_state_change(struct radeon_device 
*rdev,
+ struct radeon_ps 
*radeon_new_state,
+ struct radeon_ps 
*radeon_current_state)
 {
-   struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
-   struct radeon_ps *radeon_current_state = rdev->pm.dpm.current_ps;
u32 pcie_link_speed_target =  
cypress_get_maximum_link_speed(radeon_new_state);
u32 pcie_link_speed_current = 
cypress_get_maximum_link_speed(radeon_current_state);
u8 request;
@@ -856,10 +856,10 @@ static void cypress_convert_mc_reg_table_to_smc(struct 
radeon_device *rdev,
  _reg_table->data[4]);
 }

-int cypress_upload_sw_state(struct radeon_device *rdev)
+int cypress_upload_sw_state(struct radeon_device *rdev,
+   struct radeon_ps *radeon_new_state)
 {
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
-   struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
u16 address = pi->state_table_start +

[PATCH 097/165] drm/radeon/dpm/rv7xx: restructure code

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Needed to properly handle dynamic state adjustment.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/btc_dpm.c |6 ++-
 drivers/gpu/drm/radeon/cypress_dpm.c |6 ++-
 drivers/gpu/drm/radeon/rv740_dpm.c   |1 -
 drivers/gpu/drm/radeon/rv770_dpm.c   |   77 ++
 drivers/gpu/drm/radeon/rv770_dpm.h   |8 +++-
 5 files changed, 55 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c
index 79f5ed4..3ae4de6 100644
--- a/drivers/gpu/drm/radeon/btc_dpm.c
+++ b/drivers/gpu/drm/radeon/btc_dpm.c
@@ -2233,6 +2233,8 @@ void btc_dpm_reset_asic(struct radeon_device *rdev)
 int btc_dpm_set_power_state(struct radeon_device *rdev)
 {
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+   struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps;
+   struct radeon_ps *old_ps = rdev->pm.dpm.current_ps;

btc_apply_state_adjust_rules(rdev);

@@ -2243,7 +2245,7 @@ int btc_dpm_set_power_state(struct radeon_device *rdev)
if (eg_pi->pcie_performance_request)
cypress_notify_link_speed_change_before_state_change(rdev);

-   rv770_set_uvd_clock_before_set_eng_clock(rdev);
+   rv770_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
rv770_halt_smc(rdev);
btc_set_at_for_uvd(rdev);
if (eg_pi->smu_uvd_hs)
@@ -2257,7 +2259,7 @@ int btc_dpm_set_power_state(struct radeon_device *rdev)

rv770_resume_smc(rdev);
rv770_set_sw_state(rdev);
-   rv770_set_uvd_clock_after_set_eng_clock(rdev);
+   rv770_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);

if (eg_pi->pcie_performance_request)
cypress_notify_link_speed_change_after_state_change(rdev);
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c 
b/drivers/gpu/drm/radeon/cypress_dpm.c
index 22297b1..c9026ed 100644
--- a/drivers/gpu/drm/radeon/cypress_dpm.c
+++ b/drivers/gpu/drm/radeon/cypress_dpm.c
@@ -1930,13 +1930,15 @@ void cypress_dpm_disable(struct radeon_device *rdev)
 int cypress_dpm_set_power_state(struct radeon_device *rdev)
 {
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+   struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps;
+   struct radeon_ps *old_ps = rdev->pm.dpm.current_ps;

rv770_restrict_performance_levels_before_switch(rdev);

if (eg_pi->pcie_performance_request)
cypress_notify_link_speed_change_before_state_change(rdev);

-   rv770_set_uvd_clock_before_set_eng_clock(rdev);
+   rv770_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
rv770_halt_smc(rdev);
cypress_upload_sw_state(rdev);

@@ -1947,7 +1949,7 @@ int cypress_dpm_set_power_state(struct radeon_device 
*rdev)

rv770_resume_smc(rdev);
rv770_set_sw_state(rdev);
-   rv770_set_uvd_clock_after_set_eng_clock(rdev);
+   rv770_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);

if (eg_pi->pcie_performance_request)
cypress_notify_link_speed_change_after_state_change(rdev);
diff --git a/drivers/gpu/drm/radeon/rv740_dpm.c 
b/drivers/gpu/drm/radeon/rv740_dpm.c
index d0d750e..7aa1608 100644
--- a/drivers/gpu/drm/radeon/rv740_dpm.c
+++ b/drivers/gpu/drm/radeon/rv740_dpm.c
@@ -29,7 +29,6 @@
 #include "rv770_dpm.h"
 #include "atom.h"

-struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
 struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);

 u32 rv740_get_decoded_reference_divider(u32 encoded_ref)
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c 
b/drivers/gpu/drm/radeon/rv770_dpm.c
index f5efa4c..db1dfbc 100644
--- a/drivers/gpu/drm/radeon/rv770_dpm.c
+++ b/drivers/gpu/drm/radeon/rv770_dpm.c
@@ -1155,10 +1155,10 @@ static int rv770_populate_smc_mvdd_table(struct 
radeon_device *rdev,
return 0;
 }

-static int rv770_init_smc_table(struct radeon_device *rdev)
+static int rv770_init_smc_table(struct radeon_device *rdev,
+   struct radeon_ps *radeon_boot_state)
 {
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
-   struct radeon_ps *radeon_boot_state = rdev->pm.dpm.boot_ps;
struct rv7xx_ps *boot_state = rv770_get_ps(radeon_boot_state);
RV770_SMC_STATETABLE *table = >smc_statetable;
int ret;
@@ -1364,10 +1364,9 @@ static void rv770_enable_dynamic_pcie_gen2(struct 
radeon_device *rdev,
WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE);
 }

-static void r7xx_program_memory_timing_parameters(struct radeon_device *rdev)
+static void r7xx_program_memory_timing_parameters(struct radeon_device *rdev,
+ struct radeon_ps 
*radeon_new_state)
 {
-   struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
-
if ((rdev->family == CHIP_RV730) ||
(rdev->family == CHIP_RV710) ||
(rdev->family == CHIP_RV740))
@@ 

[PATCH 096/165] drm/radeon/dpm/rv6xx: restructure code

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Needed to properly handle dynamic state adjustment.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/rv6xx_dpm.c |  115 +--
 1 files changed, 69 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/radeon/rv6xx_dpm.c 
b/drivers/gpu/drm/radeon/rv6xx_dpm.c
index fa4beb2..e8f07b1 100644
--- a/drivers/gpu/drm/radeon/rv6xx_dpm.c
+++ b/drivers/gpu/drm/radeon/rv6xx_dpm.c
@@ -961,9 +961,11 @@ static void rv6xx_program_voltage_gpio_pins(struct 
radeon_device *rdev)
 rv6xx_get_master_voltage_mask(rdev));
 }

-static void rv6xx_enable_static_voltage_control(struct radeon_device *rdev, 
bool enable)
+static void rv6xx_enable_static_voltage_control(struct radeon_device *rdev,
+   struct radeon_ps *new_ps,
+   bool enable)
 {
-   struct rv6xx_ps *new_state = rv6xx_get_ps(rdev->pm.dpm.requested_ps);
+   struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);

if (enable)
radeon_atom_set_voltage(rdev,
@@ -1039,9 +1041,10 @@ static void rv6xx_calculate_ap(struct radeon_device 
*rdev,

 }

-static void rv6xx_calculate_stepping_parameters(struct radeon_device *rdev)
+static void rv6xx_calculate_stepping_parameters(struct radeon_device *rdev,
+   struct radeon_ps *new_ps)
 {
-   struct rv6xx_ps *new_state = rv6xx_get_ps(rdev->pm.dpm.requested_ps);
+   struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);

rv6xx_calculate_engine_speed_stepping_parameters(rdev, new_state);
rv6xx_calculate_memory_clock_stepping_parameters(rdev, new_state);
@@ -1191,10 +1194,12 @@ static void rv6xx_program_display_gap(struct 
radeon_device *rdev)
WREG32(CG_DISPLAY_GAP_CNTL, tmp);
 }

-static void rv6xx_set_sw_voltage_to_safe(struct radeon_device *rdev)
+static void rv6xx_set_sw_voltage_to_safe(struct radeon_device *rdev,
+struct radeon_ps *new_ps,
+struct radeon_ps *old_ps)
 {
-   struct rv6xx_ps *new_state = rv6xx_get_ps(rdev->pm.dpm.requested_ps);
-   struct rv6xx_ps *old_state = rv6xx_get_ps(rdev->pm.dpm.current_ps);
+   struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);
+   struct rv6xx_ps *old_state = rv6xx_get_ps(old_ps);
u16 safe_voltage;

safe_voltage = (new_state->low.vddc >= old_state->low.vddc) ?
@@ -1207,9 +1212,10 @@ static void rv6xx_set_sw_voltage_to_safe(struct 
radeon_device *rdev)
 ~SW_GPIO_INDEX_MASK);
 }

-static void rv6xx_set_sw_voltage_to_low(struct radeon_device *rdev)
+static void rv6xx_set_sw_voltage_to_low(struct radeon_device *rdev,
+   struct radeon_ps *old_ps)
 {
-   struct rv6xx_ps *old_state = rv6xx_get_ps(rdev->pm.dpm.current_ps);
+   struct rv6xx_ps *old_state = rv6xx_get_ps(old_ps);

rv6xx_program_voltage_stepping_entry(rdev, R600_POWER_LEVEL_CTXSW,
 old_state->low.vddc);
@@ -1218,10 +1224,12 @@ static void rv6xx_set_sw_voltage_to_low(struct 
radeon_device *rdev)
~SW_GPIO_INDEX_MASK);
 }

-static void rv6xx_set_safe_backbias(struct radeon_device *rdev)
+static void rv6xx_set_safe_backbias(struct radeon_device *rdev,
+   struct radeon_ps *new_ps,
+   struct radeon_ps *old_ps)
 {
-   struct rv6xx_ps *new_state = rv6xx_get_ps(rdev->pm.dpm.requested_ps);
-   struct rv6xx_ps *old_state = rv6xx_get_ps(rdev->pm.dpm.current_ps);
+   struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);
+   struct rv6xx_ps *old_state = rv6xx_get_ps(old_ps);

if ((new_state->low.flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE) &&
(old_state->low.flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE))
@@ -1230,10 +1238,12 @@ static void rv6xx_set_safe_backbias(struct 
radeon_device *rdev)
WREG32_P(GENERAL_PWRMGT, 0, ~BACKBIAS_VALUE);
 }

-static void rv6xx_set_safe_pcie_gen2(struct radeon_device *rdev)
+static void rv6xx_set_safe_pcie_gen2(struct radeon_device *rdev,
+struct radeon_ps *new_ps,
+struct radeon_ps *old_ps)
 {
-   struct rv6xx_ps *new_state = rv6xx_get_ps(rdev->pm.dpm.requested_ps);
-   struct rv6xx_ps *old_state = rv6xx_get_ps(rdev->pm.dpm.current_ps);
+   struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);
+   struct rv6xx_ps *old_state = rv6xx_get_ps(old_ps);

if ((new_state->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) !=
(old_state->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2))
@@ -1290,10 +1300,12 @@ static int rv6xx_step_sw_voltage(struct radeon_device 
*rdev,
return 0;
 }

-static int rv6xx_step_voltage_if_increasing(struct radeon_device *rdev)
+static 

[PATCH 095/165] drm/radeon/dpm/rs780: restructure code

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Needed to properly handle dynamic state adjustment.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/rs780_dpm.c |   52 ++--
 1 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/radeon/rs780_dpm.c 
b/drivers/gpu/drm/radeon/rs780_dpm.c
index a1497a6..8af1a04 100644
--- a/drivers/gpu/drm/radeon/rs780_dpm.c
+++ b/drivers/gpu/drm/radeon/rs780_dpm.c
@@ -71,10 +71,11 @@ static void rs780_get_pm_mode_parameters(struct 
radeon_device *rdev)

 static void rs780_voltage_scaling_enable(struct radeon_device *rdev, bool 
enable);

-static int rs780_initialize_dpm_power_state(struct radeon_device *rdev)
+static int rs780_initialize_dpm_power_state(struct radeon_device *rdev,
+   struct radeon_ps *boot_ps)
 {
struct atom_clock_dividers dividers;
-   struct igp_ps *default_state = rs780_get_ps(rdev->pm.dpm.boot_ps);
+   struct igp_ps *default_state = rs780_get_ps(boot_ps);
int i, ret;

ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
@@ -104,7 +105,8 @@ static int rs780_initialize_dpm_power_state(struct 
radeon_device *rdev)
return 0;
 }

-static int rs780_initialize_dpm_parameters(struct radeon_device *rdev)
+static int rs780_initialize_dpm_parameters(struct radeon_device *rdev,
+  struct radeon_ps *boot_ps)
 {
int ret = 0;
int i;
@@ -140,7 +142,7 @@ static int rs780_initialize_dpm_parameters(struct 
radeon_device *rdev)
r600_vid_rt_set_vrt(rdev, R600_VOLTAGERESPONSETIME_DFLT);
r600_vid_rt_set_ssu(rdev, R600_SPLLSTEPUNIT_DFLT);

-   ret = rs780_initialize_dpm_power_state(rdev);
+   ret = rs780_initialize_dpm_power_state(rdev, boot_ps);

r600_power_level_set_voltage_index(rdev, R600_POWER_LEVEL_LOW, 0);
r600_power_level_set_voltage_index(rdev, R600_POWER_LEVEL_MEDIUM,  0);
@@ -401,11 +403,13 @@ static void rs780_force_voltage_to_high(struct 
radeon_device *rdev)
WREG32_P(GFX_MACRO_BYPASS_CNTL, 0, ~SPLL_BYPASS_CNTL);
 }

-static int rs780_set_engine_clock_scaling(struct radeon_device *rdev)
+static int rs780_set_engine_clock_scaling(struct radeon_device *rdev,
+ struct radeon_ps *new_ps,
+ struct radeon_ps *old_ps)
 {
struct atom_clock_dividers min_dividers, max_dividers, 
current_max_dividers;
-   struct igp_ps *new_state = rs780_get_ps(rdev->pm.dpm.requested_ps);
-   struct igp_ps *old_state = rs780_get_ps(rdev->pm.dpm.current_ps);
+   struct igp_ps *new_state = rs780_get_ps(new_ps);
+   struct igp_ps *old_state = rs780_get_ps(old_ps);
int ret;

if ((new_state->sclk_high == old_state->sclk_high) &&
@@ -451,10 +455,12 @@ static int rs780_set_engine_clock_scaling(struct 
radeon_device *rdev)
return 0;
 }

-static void rs780_set_engine_clock_spc(struct radeon_device *rdev)
+static void rs780_set_engine_clock_spc(struct radeon_device *rdev,
+  struct radeon_ps *new_ps,
+  struct radeon_ps *old_ps)
 {
-   struct igp_ps *new_state = rs780_get_ps(rdev->pm.dpm.requested_ps);
-   struct igp_ps *old_state = rs780_get_ps(rdev->pm.dpm.current_ps);
+   struct igp_ps *new_state = rs780_get_ps(new_ps);
+   struct igp_ps *old_state = rs780_get_ps(old_ps);
struct igp_power_info *pi = rs780_get_pi(rdev);

if ((new_state->sclk_high == old_state->sclk_high) &&
@@ -468,10 +474,12 @@ static void rs780_set_engine_clock_spc(struct 
radeon_device *rdev)

 }

-static void rs780_activate_engine_clk_scaling(struct radeon_device *rdev)
+static void rs780_activate_engine_clk_scaling(struct radeon_device *rdev,
+ struct radeon_ps *new_ps,
+ struct radeon_ps *old_ps)
 {
-   struct igp_ps *new_state = rs780_get_ps(rdev->pm.dpm.requested_ps);
-   struct igp_ps *old_state = rs780_get_ps(rdev->pm.dpm.current_ps);
+   struct igp_ps *new_state = rs780_get_ps(new_ps);
+   struct igp_ps *old_state = rs780_get_ps(old_ps);

if ((new_state->sclk_high == old_state->sclk_high) &&
(new_state->sclk_low == old_state->sclk_low))
@@ -493,9 +501,10 @@ static u32 rs780_get_voltage_for_vddc_level(struct 
radeon_device *rdev,
return pi->max_voltage;
 }

-static void rs780_enable_voltage_scaling(struct radeon_device *rdev)
+static void rs780_enable_voltage_scaling(struct radeon_device *rdev,
+struct radeon_ps *new_ps)
 {
-   struct igp_ps *new_state = rs780_get_ps(rdev->pm.dpm.requested_ps);
+   struct igp_ps *new_state = rs780_get_ps(new_ps);
struct igp_power_info *pi = rs780_get_pi(rdev);
enum rs780_vddc_level vddc_high, 

[PATCH 094/165] drm/radeon/cayman: update tdp limits in set_power_state

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/ni_dpm.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c
index 635bf04..44016f2 100644
--- a/drivers/gpu/drm/radeon/ni_dpm.c
+++ b/drivers/gpu/drm/radeon/ni_dpm.c
@@ -3644,6 +3644,7 @@ int ni_dpm_set_power_state(struct radeon_device *rdev)
ret = ni_program_memory_timing_parameters(rdev);
if (ret)
return ret;
+   ni_populate_smc_tdp_limits(rdev);
rv770_resume_smc(rdev);
rv770_set_sw_state(rdev);
ni_enable_smc_cac(rdev, true);
-- 
1.7.7.5



[PATCH 093/165] drm/radeon/kms: add dpm support for cayman

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

This adds dpm support for cayman asics.  This includes:
- clockgating
- dynamic engine clock scaling
- dynamic memory clock scaling
- dynamic voltage scaling
- dynamic pcie gen1/gen2 switching (requires additional acpi support)
- power containment
- shader power scaling

Set radeon.dpm=1 to enable.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/Makefile   |2 +-
 drivers/gpu/drm/radeon/btc_dpm.c  |   36 +-
 drivers/gpu/drm/radeon/btc_dpm.h  |   20 +-
 drivers/gpu/drm/radeon/cypress_dpm.c  |   11 +-
 drivers/gpu/drm/radeon/cypress_dpm.h  |4 +
 drivers/gpu/drm/radeon/ni.c   |4 +-
 drivers/gpu/drm/radeon/ni_dpm.c   | 4093 +
 drivers/gpu/drm/radeon/ni_dpm.h   |  233 ++
 drivers/gpu/drm/radeon/nid.h  |  552 +
 drivers/gpu/drm/radeon/nislands_smc.h |  329 +++
 drivers/gpu/drm/radeon/ppsmc.h|   12 +
 drivers/gpu/drm/radeon/radeon_asic.c  |   12 +
 drivers/gpu/drm/radeon/radeon_asic.h  |   10 +
 drivers/gpu/drm/radeon/radeon_pm.c|1 +
 drivers/gpu/drm/radeon/radeon_ucode.h |5 +
 drivers/gpu/drm/radeon/rv770_smc.c|   27 +
 16 files changed, 5323 insertions(+), 28 deletions(-)
 create mode 100644 drivers/gpu/drm/radeon/ni_dpm.c
 create mode 100644 drivers/gpu/drm/radeon/ni_dpm.h
 create mode 100644 drivers/gpu/drm/radeon/nislands_smc.h

diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 2239ec2..32d1c7f 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -79,7 +79,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \
rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o 
\
-   trinity_smc.o
+   trinity_smc.o ni_dpm.o

 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c
index 989592e..79f5ed4 100644
--- a/drivers/gpu/drm/radeon/btc_dpm.c
+++ b/drivers/gpu/drm/radeon/btc_dpm.c
@@ -1152,7 +1152,7 @@ static const u32 turks_sysls_enable[] =

 #endif

-u32 btc_valid_sclk[] =
+u32 btc_valid_sclk[40] =
 {
5000,   1,  15000,  2,  25000,  3,  35000,  4,  45000,  
5,
55000,  6,  65000,  7,  75000,  8,  85000,  9,  95000,  
10,
@@ -1168,8 +1168,8 @@ static const struct radeon_blacklist_clocks 
btc_blacklist_clocks[] =
 { 25000, 3, RADEON_SCLK_UP }
 };

-static void btc_apply_voltage_dependency_rules(struct 
radeon_clock_voltage_dependency_table *table,
-  u32 clock, u16 max_voltage, u16 
*voltage)
+void btc_apply_voltage_dependency_rules(struct 
radeon_clock_voltage_dependency_table *table,
+   u32 clock, u16 max_voltage, u16 
*voltage)
 {
u32 i;

@@ -1219,9 +1219,9 @@ static u32 btc_get_valid_sclk(struct radeon_device *rdev,
max_sclk, requested_sclk);
 }

-static void btc_skip_blacklist_clocks(struct radeon_device *rdev,
- const u32 max_sclk, const u32 max_mclk,
- u32 *sclk, u32 *mclk)
+void btc_skip_blacklist_clocks(struct radeon_device *rdev,
+  const u32 max_sclk, const u32 max_mclk,
+  u32 *sclk, u32 *mclk)
 {
int i, num_blacklist_clocks;

@@ -1246,9 +1246,9 @@ static void btc_skip_blacklist_clocks(struct 
radeon_device *rdev,
}
 }

-static void btc_adjust_clock_combinations(struct radeon_device *rdev,
- const struct 
radeon_clock_and_voltage_limits *max_limits,
- struct rv7xx_pl *pl)
+void btc_adjust_clock_combinations(struct radeon_device *rdev,
+  const struct radeon_clock_and_voltage_limits 
*max_limits,
+  struct rv7xx_pl *pl)
 {

if ((pl->mclk == 0) || (pl->sclk == 0))
@@ -1285,9 +1285,9 @@ static u16 btc_find_voltage(struct atom_voltage_table 
*table, u16 voltage)
return table->entries[table->count - 1].value;
 }

-static void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
- u16 max_vddc, u16 max_vddci,
- u16 *vddc, u16 *vddci)
+void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
+  u16 max_vddc, u16 max_vddci,
+  u16 *vddc, u16 *vddci)
 {
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
u16 new_voltage;
@@ -1417,8 +1417,8 @@ static int btc_populate_smc_acpi_state(struct 

[PATCH 092/165] drm/radeon/dpm: fixup dynamic state adjust for btc (v2)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Use a dedicated copy of the current power state since
we may have to adjust it on the fly.

v2: fix up redundant state sets

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/btc_dpm.c |  340 ++
 drivers/gpu/drm/radeon/btc_dpm.h |2 +
 drivers/gpu/drm/radeon/cypress_dpm.h |1 +
 drivers/gpu/drm/radeon/radeon.h  |   13 ++
 drivers/gpu/drm/radeon/radeon_pm.c   |   43 -
 drivers/gpu/drm/radeon/rv770_dpm.c   |   10 +
 6 files changed, 400 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c
index 2662ef0..989592e 100644
--- a/drivers/gpu/drm/radeon/btc_dpm.c
+++ b/drivers/gpu/drm/radeon/btc_dpm.c
@@ -1152,6 +1152,164 @@ static const u32 turks_sysls_enable[] =

 #endif

+u32 btc_valid_sclk[] =
+{
+   5000,   1,  15000,  2,  25000,  3,  35000,  4,  45000,  
5,
+   55000,  6,  65000,  7,  75000,  8,  85000,  9,  95000,  
10,
+   105000, 11, 11500,  12, 125000, 13, 135000, 14, 145000, 
15,
+   155000, 16, 165000, 17, 175000, 18, 185000, 19, 195000, 
20
+};
+
+static const struct radeon_blacklist_clocks btc_blacklist_clocks[] =
+{
+{ 1, 3, RADEON_SCLK_UP },
+{ 15000, 3, RADEON_SCLK_UP },
+{ 2, 3, RADEON_SCLK_UP },
+{ 25000, 3, RADEON_SCLK_UP }
+};
+
+static void btc_apply_voltage_dependency_rules(struct 
radeon_clock_voltage_dependency_table *table,
+  u32 clock, u16 max_voltage, u16 
*voltage)
+{
+   u32 i;
+
+   if ((table == NULL) || (table->count == 0))
+   return;
+
+   for (i= 0; i < table->count; i++) {
+   if (clock <= table->entries[i].clk) {
+   if (*voltage < table->entries[i].v)
+   *voltage = (u16)((table->entries[i].v < 
max_voltage) ?
+ table->entries[i].v : 
max_voltage);
+   return;
+   }
+   }
+
+   *voltage = (*voltage > max_voltage) ? *voltage : max_voltage;
+}
+
+static u32 btc_find_valid_clock(struct radeon_clock_array *clocks,
+   u32 max_clock, u32 requested_clock)
+{
+   unsigned int i;
+
+   if ((clocks == NULL) || (clocks->count == 0))
+   return (requested_clock < max_clock) ? requested_clock : 
max_clock;
+
+   for (i = 0; i < clocks->count; i++) {
+   if (clocks->values[i] >= requested_clock)
+   return (clocks->values[i] < max_clock) ? 
clocks->values[i] : max_clock;
+   }
+
+   return (clocks->values[clocks->count - 1] < max_clock) ?
+   clocks->values[clocks->count - 1] : max_clock;
+}
+
+static u32 btc_get_valid_mclk(struct radeon_device *rdev,
+ u32 max_mclk, u32 requested_mclk)
+{
+   return btc_find_valid_clock(>pm.dpm.dyn_state.valid_mclk_values,
+   max_mclk, requested_mclk);
+}
+
+static u32 btc_get_valid_sclk(struct radeon_device *rdev,
+ u32 max_sclk, u32 requested_sclk)
+{
+   return btc_find_valid_clock(>pm.dpm.dyn_state.valid_sclk_values,
+   max_sclk, requested_sclk);
+}
+
+static void btc_skip_blacklist_clocks(struct radeon_device *rdev,
+ const u32 max_sclk, const u32 max_mclk,
+ u32 *sclk, u32 *mclk)
+{
+   int i, num_blacklist_clocks;
+
+   if ((sclk == NULL) || (mclk == NULL))
+   return;
+
+   num_blacklist_clocks = ARRAY_SIZE(btc_blacklist_clocks);
+
+   for (i = 0; i < num_blacklist_clocks; i++) {
+   if ((btc_blacklist_clocks[i].sclk == *sclk) &&
+   (btc_blacklist_clocks[i].mclk == *mclk))
+   break;
+   }
+
+   if (i < num_blacklist_clocks) {
+   if (btc_blacklist_clocks[i].action == RADEON_SCLK_UP) {
+   *sclk = btc_get_valid_sclk(rdev, max_sclk, *sclk + 1);
+
+   if (*sclk < max_sclk)
+   btc_skip_blacklist_clocks(rdev, max_sclk, 
max_mclk, sclk, mclk);
+   }
+   }
+}
+
+static void btc_adjust_clock_combinations(struct radeon_device *rdev,
+ const struct 
radeon_clock_and_voltage_limits *max_limits,
+ struct rv7xx_pl *pl)
+{
+
+   if ((pl->mclk == 0) || (pl->sclk == 0))
+   return;
+
+   if (pl->mclk == pl->sclk)
+   return;
+
+   if (pl->mclk > pl->sclk) {
+   if (((pl->mclk + (pl->sclk - 1)) / pl->sclk) > 
rdev->pm.dpm.dyn_state.mclk_sclk_ratio)
+   pl->sclk = btc_get_valid_sclk(rdev,
+

[PATCH 091/165] drm/radeon/dpm: fixup dynamic state adjust for TN

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Use a dedicated copy of the current power state since
we may have to adjust it on the fly.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/trinity_dpm.c |5 +
 drivers/gpu/drm/radeon/trinity_dpm.h |1 +
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c 
b/drivers/gpu/drm/radeon/trinity_dpm.c
index 1b3822f..0c1b50a 100644
--- a/drivers/gpu/drm/radeon/trinity_dpm.c
+++ b/drivers/gpu/drm/radeon/trinity_dpm.c
@@ -1379,6 +1379,11 @@ static void trinity_apply_state_adjust_rules(struct 
radeon_device *rdev)
bool force_high;
u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count;

+   /* point to the hw copy since this function will modify the ps */
+   pi->hw_ps = *ps;
+   rdev->pm.dpm.hw_ps.ps_priv = >hw_ps;
+   ps = >hw_ps;
+
if (rps->class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
return trinity_patch_thermal_state(rdev, ps, current_ps);

diff --git a/drivers/gpu/drm/radeon/trinity_dpm.h 
b/drivers/gpu/drm/radeon/trinity_dpm.h
index 31100ac..c663aed 100644
--- a/drivers/gpu/drm/radeon/trinity_dpm.h
+++ b/drivers/gpu/drm/radeon/trinity_dpm.h
@@ -110,6 +110,7 @@ struct trinity_power_info {
bool enable_dpm;
bool enable_sclk_ds;
bool uvd_dpm;
+   struct trinity_ps hw_ps;
 };

 #define TRINITY_AT_DFLT30
-- 
1.7.7.5



[PATCH 090/165] drm/radeon/dpm: fixup dynamic state adjust for sumo

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Use a dedicated copy of the current power state since
we may have to adjust it on the fly.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon.h|1 +
 drivers/gpu/drm/radeon/radeon_pm.c |   13 -
 drivers/gpu/drm/radeon/sumo_dpm.c  |5 +
 drivers/gpu/drm/radeon/sumo_dpm.h  |1 +
 4 files changed, 19 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 53aba4f..a4d8d97 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1294,6 +1294,7 @@ struct radeon_dpm {
struct radeon_ps*boot_ps;
/* default uvd power state */
struct radeon_ps*uvd_ps;
+   struct radeon_pshw_ps;
enum radeon_pm_state_type state;
enum radeon_pm_state_type user_state;
u32 platform_caps;
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c 
b/drivers/gpu/drm/radeon/radeon_pm.c
index 9ac261f..7ee8cf6 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -687,6 +687,17 @@ restart_search:
return NULL;
 }

+static void radeon_dpm_update_requested_ps(struct radeon_device *rdev,
+  struct radeon_ps *ps)
+{
+   /* copy the ps to the hw ps and point the requested ps
+* at the hw state in case the driver wants to modify
+* the state dynamically.
+*/
+   rdev->pm.dpm.hw_ps = *ps;
+   rdev->pm.dpm.requested_ps = >pm.dpm.hw_ps;
+}
+
 static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev)
 {
int i;
@@ -707,7 +718,7 @@ static void radeon_dpm_change_power_state_locked(struct 
radeon_device *rdev)

ps = radeon_dpm_pick_power_state(rdev, dpm_state);
if (ps)
-   rdev->pm.dpm.requested_ps = ps;
+   radeon_dpm_update_requested_ps(rdev, ps);
else
return;

diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c 
b/drivers/gpu/drm/radeon/sumo_dpm.c
index cef25c4..3805302 100644
--- a/drivers/gpu/drm/radeon/sumo_dpm.c
+++ b/drivers/gpu/drm/radeon/sumo_dpm.c
@@ -1072,6 +1072,11 @@ static void sumo_apply_state_adjust_rules(struct 
radeon_device *rdev)
u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */
u32 i;

+   /* point to the hw copy since this function will modify the ps */
+   pi->hw_ps = *ps;
+   rdev->pm.dpm.hw_ps.ps_priv = >hw_ps;
+   ps = >hw_ps;
+
if (rps->class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
return sumo_patch_thermal_state(rdev, ps, current_ps);

diff --git a/drivers/gpu/drm/radeon/sumo_dpm.h 
b/drivers/gpu/drm/radeon/sumo_dpm.h
index d041a6c..a40b62a 100644
--- a/drivers/gpu/drm/radeon/sumo_dpm.h
+++ b/drivers/gpu/drm/radeon/sumo_dpm.h
@@ -129,6 +129,7 @@ struct sumo_power_info {
bool enable_dynamic_patch_ps;
bool enable_dpm;
bool enable_boost;
+   struct sumo_ps hw_ps;
 };

 #define SUMO_UTC_DFLT_00 0x48
-- 
1.7.7.5



[PATCH 089/165] drm/radeon/dpm: track whether we are on AC or battery

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Driver needs this information to validate power states.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon.h|1 +
 drivers/gpu/drm/radeon/radeon_pm.c |7 +++
 2 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 5bdb0bd..53aba4f 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1314,6 +1314,7 @@ struct radeon_dpm {
u32 tdp_adjustment;
u16 load_line_slope;
bool power_control;
+   bool ac_power;
/* special states active */
boolthermal_active;
booluvd_active;
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c 
b/drivers/gpu/drm/radeon/radeon_pm.c
index 5987580..9ac261f 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -1218,6 +1218,7 @@ static void radeon_pm_compute_clocks_dpm(struct 
radeon_device *rdev)

mutex_lock(>pm.mutex);

+   /* update active crtc counts */
rdev->pm.dpm.new_active_crtcs = 0;
rdev->pm.dpm.new_active_crtc_count = 0;
list_for_each_entry(crtc,
@@ -1229,6 +1230,12 @@ static void radeon_pm_compute_clocks_dpm(struct 
radeon_device *rdev)
}
}

+   /* update battery/ac status */
+   if (power_supply_is_system_supplied() > 0)
+   rdev->pm.dpm.ac_power = true;
+   else
+   rdev->pm.dpm.ac_power = false;
+
radeon_dpm_change_power_state_locked(rdev);

mutex_unlock(>pm.mutex);
-- 
1.7.7.5



[PATCH 088/165] drm/radeon/dpm: add helpers for extended power tables (v2)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

This data will be needed for dpm on newer asics.

v2: fix typo in rebase

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/r600_dpm.c |  179 +
 drivers/gpu/drm/radeon/r600_dpm.h |3 +
 drivers/gpu/drm/radeon/radeon.h   |   70 ++
 3 files changed, 252 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r600_dpm.c 
b/drivers/gpu/drm/radeon/r600_dpm.c
index bf396a0..c9f9647 100644
--- a/drivers/gpu/drm/radeon/r600_dpm.c
+++ b/drivers/gpu/drm/radeon/r600_dpm.c
@@ -721,3 +721,182 @@ bool r600_is_internal_thermal_sensor(enum 
radeon_int_thermal_type sensor)
return false;
}
 }
+
+union power_info {
+   struct _ATOM_POWERPLAY_INFO info;
+   struct _ATOM_POWERPLAY_INFO_V2 info_2;
+   struct _ATOM_POWERPLAY_INFO_V3 info_3;
+   struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
+   struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
+   struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
+   struct _ATOM_PPLIB_POWERPLAYTABLE4 pplib4;
+   struct _ATOM_PPLIB_POWERPLAYTABLE5 pplib5;
+};
+
+union fan_info {
+   struct _ATOM_PPLIB_FANTABLE fan;
+   struct _ATOM_PPLIB_FANTABLE2 fan2;
+};
+
+static int r600_parse_clk_voltage_dep_table(struct 
radeon_clock_voltage_dependency_table *radeon_table,
+   
ATOM_PPLIB_Clock_Voltage_Dependency_Table *atom_table)
+{
+   u32 size = atom_table->ucNumEntries *
+   sizeof(struct radeon_clock_voltage_dependency_entry);
+   int i;
+
+   radeon_table->entries = kzalloc(size, GFP_KERNEL);
+   if (!radeon_table->entries)
+   return -ENOMEM;
+
+   for (i = 0; i < atom_table->ucNumEntries; i++) {
+   radeon_table->entries[i].clk = 
le16_to_cpu(atom_table->entries[i].usClockLow) |
+   (atom_table->entries[i].ucClockHigh << 16);
+   radeon_table->entries[i].v = 
le16_to_cpu(atom_table->entries[i].usVoltage);
+   }
+   radeon_table->count = atom_table->ucNumEntries;
+
+   return 0;
+}
+
+int r600_parse_extended_power_table(struct radeon_device *rdev)
+{
+   struct radeon_mode_info *mode_info = >mode_info;
+   union power_info *power_info;
+   union fan_info *fan_info;
+   ATOM_PPLIB_Clock_Voltage_Dependency_Table *dep_table;
+   int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
+u16 data_offset;
+   u8 frev, crev;
+   int ret, i;
+
+   if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
+  , , _offset))
+   return -EINVAL;
+   power_info = (union power_info *)(mode_info->atom_context->bios + 
data_offset);
+
+   /* fan table */
+   if (power_info->pplib.usTableSize >= sizeof(struct 
_ATOM_PPLIB_POWERPLAYTABLE3)) {
+   if (power_info->pplib3.usFanTableOffset) {
+   fan_info = (union fan_info 
*)(mode_info->atom_context->bios + data_offset +
+ 
le16_to_cpu(power_info->pplib3.usFanTableOffset));
+   rdev->pm.dpm.fan.t_hyst = fan_info->fan.ucTHyst;
+   rdev->pm.dpm.fan.t_min = 
le16_to_cpu(fan_info->fan.usTMin);
+   rdev->pm.dpm.fan.t_med = 
le16_to_cpu(fan_info->fan.usTMed);
+   rdev->pm.dpm.fan.t_high = 
le16_to_cpu(fan_info->fan.usTHigh);
+   rdev->pm.dpm.fan.pwm_min = 
le16_to_cpu(fan_info->fan.usPWMMin);
+   rdev->pm.dpm.fan.pwm_med = 
le16_to_cpu(fan_info->fan.usPWMMed);
+   rdev->pm.dpm.fan.pwm_high = 
le16_to_cpu(fan_info->fan.usPWMHigh);
+   if (fan_info->fan.ucFanTableFormat >= 2)
+   rdev->pm.dpm.fan.t_max = 
le16_to_cpu(fan_info->fan2.usTMax);
+   else
+   rdev->pm.dpm.fan.t_max = 10900;
+   rdev->pm.dpm.fan.cycle_delay = 10;
+   rdev->pm.dpm.fan.ucode_fan_control = true;
+   }
+   }
+
+   /* clock dependancy tables */
+   if (power_info->pplib.usTableSize >= sizeof(struct 
_ATOM_PPLIB_POWERPLAYTABLE4)) {
+   if (power_info->pplib4.usVddcDependencyOnSCLKOffset) {
+   dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table 
*)
+   (mode_info->atom_context->bios + data_offset +
+
le16_to_cpu(power_info->pplib4.usVddcDependencyOnSCLKOffset));
+   ret = 
r600_parse_clk_voltage_dep_table(>pm.dpm.dyn_state.vddc_dependency_on_sclk,
+  dep_table);
+   if (ret)
+   return ret;
+   }
+   if (power_info->pplib4.usVddciDependencyOnMCLKOffset) {
+   

[PATCH 087/165] drm/radeon/kms: enable UVD as needed (v9)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

When using UVD, the driver must switch to a special UVD power
state.  In the CS ioctl, switch to the power state and schedule
work to change the power state back, when the work comes up,
check if uvd is still busy and if not, switch back to the user
state, otherwise, reschedule the work.

Note:  We really need some better way to decide when to
switch out of the uvd power state.  Switching power states
while playback is active make uvd angry.

V2: fix locking.

V3: switch from timer to delayed work

V4: check fence driver for UVD jobs, reduce timeout to
1 second and rearm timeout on activity

v5: rebase on new dpm tree

v6: rebase on interim uvd on demand changes

v7: fix UVD when DPM is disabled

v8: unify non-DPM and DPM UVD handling

v9: remove leftover idle work struct

Signed-off-by: Alex Deucher 
Signed-off-by: Christian K?nig 
---
 drivers/gpu/drm/radeon/radeon.h |1 +
 drivers/gpu/drm/radeon/radeon_cs.c  |1 +
 drivers/gpu/drm/radeon/radeon_pm.c  |   12 +++-
 drivers/gpu/drm/radeon/radeon_uvd.c |   24 +++-
 4 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 037773d..3b345cc 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1246,6 +1246,7 @@ struct radeon_dpm {
int current_active_crtc_count;
/* special states active */
boolthermal_active;
+   booluvd_active;
/* thermal handling */
struct radeon_dpm_thermal thermal;
 };
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index 7e265a5..4f6b22b 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -550,6 +550,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
return r;
}

+   /* XXX pick SD/HD/MVC */
if (parser.ring == R600_RING_TYPE_UVD_INDEX)
radeon_uvd_note_usage(rdev);

diff --git a/drivers/gpu/drm/radeon/radeon_pm.c 
b/drivers/gpu/drm/radeon/radeon_pm.c
index e6fce0b..5987580 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -699,7 +699,8 @@ static void radeon_dpm_change_power_state_locked(struct 
radeon_device *rdev)

if (rdev->pm.dpm.user_state != rdev->pm.dpm.state) {
/* add other state override checks here */
-   if (!rdev->pm.dpm.thermal_active)
+   if ((!rdev->pm.dpm.thermal_active) &&
+   (!rdev->pm.dpm.uvd_active))
rdev->pm.dpm.state = rdev->pm.dpm.user_state;
}
dpm_state = rdev->pm.dpm.state;
@@ -769,8 +770,16 @@ void radeon_dpm_enable_power_state(struct radeon_device 
*rdev,
case POWER_STATE_TYPE_INTERNAL_THERMAL:
rdev->pm.dpm.thermal_active = true;
break;
+   case POWER_STATE_TYPE_INTERNAL_UVD:
+   case POWER_STATE_TYPE_INTERNAL_UVD_SD:
+   case POWER_STATE_TYPE_INTERNAL_UVD_HD:
+   case POWER_STATE_TYPE_INTERNAL_UVD_HD2:
+   case POWER_STATE_TYPE_INTERNAL_UVD_MVC:
+   rdev->pm.dpm.uvd_active = true;
+   break;
default:
rdev->pm.dpm.thermal_active = false;
+   rdev->pm.dpm.uvd_active = false;
break;
}
rdev->pm.dpm.state = dpm_state;
@@ -1223,6 +1232,7 @@ static void radeon_pm_compute_clocks_dpm(struct 
radeon_device *rdev)
radeon_dpm_change_power_state_locked(rdev);

mutex_unlock(>pm.mutex);
+
 }

 void radeon_pm_compute_clocks(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c 
b/drivers/gpu/drm/radeon/radeon_uvd.c
index fdc77d1..ce5a10c 100644
--- a/drivers/gpu/drm/radeon/radeon_uvd.c
+++ b/drivers/gpu/drm/radeon/radeon_uvd.c
@@ -699,11 +699,19 @@ static void radeon_uvd_idle_work_handler(struct 
work_struct *work)
struct radeon_device *rdev =
container_of(work, struct radeon_device, uvd.idle_work.work);

-   if (radeon_fence_count_emitted(rdev, R600_RING_TYPE_UVD_INDEX) == 0)
-   radeon_set_uvd_clocks(rdev, 0, 0);
-   else
+   if (radeon_fence_count_emitted(rdev, R600_RING_TYPE_UVD_INDEX) == 0) {
+   if ((rdev->pm.pm_method == PM_METHOD_DPM) && 
rdev->pm.dpm_enabled) {
+   mutex_lock(>pm.mutex);
+   rdev->pm.dpm.uvd_active = false;
+   mutex_unlock(>pm.mutex);
+   radeon_pm_compute_clocks(rdev);
+   } else {
+   radeon_set_uvd_clocks(rdev, 0, 0);
+   }
+   } else {
schedule_delayed_work(>uvd.idle_work,
  msecs_to_jiffies(UVD_IDLE_TIMEOUT_MS));
+   }
 }

 void radeon_uvd_note_usage(struct 

[PATCH 086/165] drm/radeon: add dpm UVD handling for TN asics (v2)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

v2: fix typo noticed by Dan Carpenter

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/ppsmc.h   |1 +
 drivers/gpu/drm/radeon/trinity_dpm.c |  220 ++
 drivers/gpu/drm/radeon/trinity_dpm.h |   18 +++
 drivers/gpu/drm/radeon/trinity_smc.c |5 +
 drivers/gpu/drm/radeon/trinityd.h|5 +
 5 files changed, 249 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/ppsmc.h b/drivers/gpu/drm/radeon/ppsmc.h
index 8ef479a..3d0786f 100644
--- a/drivers/gpu/drm/radeon/ppsmc.h
+++ b/drivers/gpu/drm/radeon/ppsmc.h
@@ -75,6 +75,7 @@ typedef uint8_t PPSMC_Result;
 #define PPSMC_MSG_PG_SIMD_Config((uint32_t) 0x108)
 #define PPSMC_MSG_DCE_RemoveVoltageAdjustment   ((uint32_t) 0x11d)
 #define PPSMC_MSG_DCE_AllowVoltageAdjustment((uint32_t) 0x11e)
+#define PPSMC_MSG_UVD_DPM_Config((uint32_t) 0x124)


 typedef uint16_t PPSMC_Msg;
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c 
b/drivers/gpu/drm/radeon/trinity_dpm.c
index c4779a6..1b3822f 100644
--- a/drivers/gpu/drm/radeon/trinity_dpm.c
+++ b/drivers/gpu/drm/radeon/trinity_dpm.c
@@ -866,6 +866,117 @@ static void trinity_program_bootup_state(struct 
radeon_device *rdev)
trinity_power_level_enable_disable(rdev, i, false);
 }

+static void trinity_setup_uvd_clock_table(struct radeon_device *rdev,
+ struct radeon_ps *rps)
+{
+   struct trinity_ps *ps = trinity_get_ps(rps);
+   u32 uvdstates = (ps->vclk_low_divider |
+ps->vclk_high_divider << 8 |
+ps->dclk_low_divider << 16 |
+ps->dclk_high_divider << 24);
+
+   WREG32_SMC(SMU_UVD_DPM_STATES, uvdstates);
+}
+
+static void trinity_setup_uvd_dpm_interval(struct radeon_device *rdev,
+  u32 interval)
+{
+   u32 p, u;
+   u32 tp = RREG32_SMC(PM_TP);
+   u32 val;
+   u32 xclk = sumo_get_xclk(rdev);
+
+   r600_calculate_u_and_p(interval, xclk, 16, , );
+
+   val = (p + tp - 1) / tp;
+
+   WREG32_SMC(SMU_UVD_DPM_CNTL, val);
+}
+
+static bool trinity_uvd_clocks_zero(struct radeon_ps *rps)
+{
+   if ((rps->vclk == 0) && (rps->dclk == 0))
+   return true;
+   else
+   return false;
+}
+
+static bool trinity_uvd_clocks_equal(struct radeon_ps *rps1,
+struct radeon_ps *rps2)
+{
+   struct trinity_ps *ps1 = trinity_get_ps(rps1);
+   struct trinity_ps *ps2 = trinity_get_ps(rps2);
+
+   if ((rps1->vclk == rps2->vclk) &&
+   (rps1->dclk == rps2->dclk) &&
+   (ps1->vclk_low_divider == ps2->vclk_low_divider) &&
+   (ps1->vclk_high_divider == ps2->vclk_high_divider) &&
+   (ps1->dclk_low_divider == ps2->dclk_low_divider) &&
+   (ps1->dclk_high_divider == ps2->dclk_high_divider))
+   return true;
+   else
+   return false;
+}
+
+static void trinity_setup_uvd_clocks(struct radeon_device *rdev,
+struct radeon_ps *current_rps,
+struct radeon_ps *new_rps)
+{
+   struct trinity_power_info *pi = trinity_get_pi(rdev);
+
+   if (pi->uvd_dpm) {
+   if (trinity_uvd_clocks_zero(new_rps) &&
+   !trinity_uvd_clocks_zero(current_rps)) {
+   trinity_setup_uvd_dpm_interval(rdev, 0);
+   } else if (!trinity_uvd_clocks_zero(new_rps)) {
+   trinity_setup_uvd_clock_table(rdev, new_rps);
+
+   if (trinity_uvd_clocks_zero(current_rps)) {
+   u32 tmp = RREG32(CG_MISC_REG);
+   tmp &= 0xfffd;
+   WREG32(CG_MISC_REG, tmp);
+
+   radeon_set_uvd_clocks(rdev, new_rps->vclk, 
new_rps->dclk);
+
+   trinity_setup_uvd_dpm_interval(rdev, 3000);
+   }
+   }
+   trinity_uvd_dpm_config(rdev);
+   } else {
+   if (trinity_uvd_clocks_zero(new_rps) ||
+   trinity_uvd_clocks_equal(new_rps, current_rps))
+   return;
+
+   radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
+   }
+}
+
+static void trinity_set_uvd_clock_before_set_eng_clock(struct radeon_device 
*rdev)
+{
+   struct trinity_ps *new_ps = trinity_get_ps(rdev->pm.dpm.requested_ps);
+   struct trinity_ps *current_ps = trinity_get_ps(rdev->pm.dpm.current_ps);
+
+   if (new_ps->levels[new_ps->num_levels - 1].sclk >=
+   current_ps->levels[current_ps->num_levels - 1].sclk)
+   return;
+
+   trinity_setup_uvd_clocks(rdev, rdev->pm.dpm.current_ps,
+rdev->pm.dpm.requested_ps);
+}
+
+static void 

[PATCH 085/165] drm/radeon: add dpm UVD handling for sumo asics

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/sumo_dpm.c |   55 +
 drivers/gpu/drm/radeon/sumod.h|   10 +++
 2 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c 
b/drivers/gpu/drm/radeon/sumo_dpm.c
index f103880..cef25c4 100644
--- a/drivers/gpu/drm/radeon/sumo_dpm.c
+++ b/drivers/gpu/drm/radeon/sumo_dpm.c
@@ -811,6 +811,40 @@ static void sumo_program_bootup_state(struct radeon_device 
*rdev)
sumo_power_level_enable(rdev, i, false);
 }

+static void sumo_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev)
+{
+   struct sumo_ps *new_ps = sumo_get_ps(rdev->pm.dpm.requested_ps);
+   struct sumo_ps *current_ps = sumo_get_ps(rdev->pm.dpm.current_ps);
+
+   if ((rdev->pm.dpm.requested_ps->vclk == rdev->pm.dpm.current_ps->vclk) 
&&
+   (rdev->pm.dpm.requested_ps->dclk == rdev->pm.dpm.current_ps->dclk))
+   return;
+
+   if (new_ps->levels[new_ps->num_levels - 1].sclk >=
+   current_ps->levels[current_ps->num_levels - 1].sclk)
+   return;
+
+   radeon_set_uvd_clocks(rdev, rdev->pm.dpm.requested_ps->vclk,
+ rdev->pm.dpm.requested_ps->dclk);
+}
+
+static void sumo_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev)
+{
+   struct sumo_ps *new_ps = sumo_get_ps(rdev->pm.dpm.requested_ps);
+   struct sumo_ps *current_ps = sumo_get_ps(rdev->pm.dpm.current_ps);
+
+   if ((rdev->pm.dpm.requested_ps->vclk == rdev->pm.dpm.current_ps->vclk) 
&&
+   (rdev->pm.dpm.requested_ps->dclk == rdev->pm.dpm.current_ps->dclk))
+   return;
+
+   if (new_ps->levels[new_ps->num_levels - 1].sclk <
+   current_ps->levels[current_ps->num_levels - 1].sclk)
+   return;
+
+   radeon_set_uvd_clocks(rdev, rdev->pm.dpm.requested_ps->vclk,
+ rdev->pm.dpm.requested_ps->dclk);
+}
+
 void sumo_take_smu_control(struct radeon_device *rdev, bool enable)
 {
 /* This bit selects who handles display phy powergating.
@@ -1096,6 +1130,22 @@ static void sumo_cleanup_asic(struct radeon_device *rdev)
sumo_take_smu_control(rdev, false);
 }

+static void sumo_uvd_init(struct radeon_device *rdev)
+{
+   u32 tmp;
+
+   tmp = RREG32(CG_VCLK_CNTL);
+   tmp &= ~VCLK_DIR_CNTL_EN;
+   WREG32(CG_VCLK_CNTL, tmp);
+
+   tmp = RREG32(CG_DCLK_CNTL);
+   tmp &= ~DCLK_DIR_CNTL_EN;
+   WREG32(CG_DCLK_CNTL, tmp);
+
+   /* 100 Mhz */
+   radeon_set_uvd_clocks(rdev, 1, 1);
+}
+
 static int sumo_set_thermal_temperature_range(struct radeon_device *rdev,
  int min_temp, int max_temp)
 {
@@ -1188,6 +1238,8 @@ int sumo_dpm_set_power_state(struct radeon_device *rdev)

if (pi->enable_dynamic_patch_ps)
sumo_apply_state_adjust_rules(rdev);
+   if (pi->enable_dpm)
+   sumo_set_uvd_clock_before_set_eng_clock(rdev);
sumo_update_current_power_levels(rdev);
if (pi->enable_boost) {
sumo_enable_boost(rdev, false);
@@ -1211,6 +1263,8 @@ int sumo_dpm_set_power_state(struct radeon_device *rdev)
}
if (pi->enable_boost)
sumo_enable_boost(rdev, true);
+   if (pi->enable_dpm)
+   sumo_set_uvd_clock_after_set_eng_clock(rdev);

return 0;
 }
@@ -1237,6 +1291,7 @@ void sumo_dpm_setup_asic(struct radeon_device *rdev)
sumo_program_acpi_power_level(rdev);
sumo_enable_acpi_pm(rdev);
sumo_take_smu_control(rdev, true);
+   sumo_uvd_init(rdev);
 }

 void sumo_dpm_display_configuration_changed(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/sumod.h b/drivers/gpu/drm/radeon/sumod.h
index a5deba6..7c9c2d4 100644
--- a/drivers/gpu/drm/radeon/sumod.h
+++ b/drivers/gpu/drm/radeon/sumod.h
@@ -136,6 +136,16 @@
 #define CG_SCLK_STATUS  0x604
 #   define SCLK_OVERCLK_DETECT  (1 << 2)

+#define CG_DCLK_CNTL0x610
+#   define DCLK_DIVIDER_MASK0x7f
+#   define DCLK_DIR_CNTL_EN (1 << 8)
+#define CG_DCLK_STATUS  0x614
+#   define DCLK_STATUS  (1 << 0)
+#define CG_VCLK_CNTL0x618
+#   define VCLK_DIVIDER_MASK0x7f
+#   define VCLK_DIR_CNTL_EN (1 << 8)
+#define CG_VCLK_STATUS  0x61c
+
 #define GENERAL_PWRMGT  0x63c
 #   define STATIC_PM_EN (1 << 1)

-- 
1.7.7.5



[PATCH 084/165] drm/radeon: add dpm UVD handling for evergreen/btc asics

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/btc_dpm.c |   62 ++
 drivers/gpu/drm/radeon/btc_dpm.h |4 ++
 drivers/gpu/drm/radeon/cypress_dpm.c |   10 +-
 drivers/gpu/drm/radeon/cypress_dpm.h |   10 +
 drivers/gpu/drm/radeon/rv770_dpm.c   |   30 +---
 drivers/gpu/drm/radeon/rv770_dpm.h   |4 ++
 drivers/gpu/drm/radeon/rv770_smc.h   |1 +
 7 files changed, 107 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c
index 6780120..2662ef0 100644
--- a/drivers/gpu/drm/radeon/btc_dpm.c
+++ b/drivers/gpu/drm/radeon/btc_dpm.c
@@ -1510,6 +1510,46 @@ static int btc_init_smc_table(struct radeon_device *rdev)
   pi->sram_end);
 }

+static void btc_set_at_for_uvd(struct radeon_device *rdev)
+{
+   struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+   struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+   struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
+   int idx = 0;
+
+   if (r600_is_uvd_state(radeon_new_state->class, 
radeon_new_state->class2))
+   idx = 1;
+
+   if ((idx == 1) && !eg_pi->smu_uvd_hs) {
+   pi->rlp = 10;
+   pi->rmp = 100;
+   pi->lhp = 100;
+   pi->lmp = 10;
+   } else {
+   pi->rlp = eg_pi->ats[idx].rlp;
+   pi->rmp = eg_pi->ats[idx].rmp;
+   pi->lhp = eg_pi->ats[idx].lhp;
+   pi->lmp = eg_pi->ats[idx].lmp;
+   }
+
+}
+
+static void btc_notify_uvd_to_smc(struct radeon_device *rdev)
+{
+   struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
+   struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+   if (r600_is_uvd_state(radeon_new_state->class, 
radeon_new_state->class2)) {
+   rv770_write_smc_soft_register(rdev,
+ 
RV770_SMC_SOFT_REGISTER_uvd_enabled, 1);
+   eg_pi->uvd_enabled = true;
+   } else {
+   rv770_write_smc_soft_register(rdev,
+ 
RV770_SMC_SOFT_REGISTER_uvd_enabled, 0);
+   eg_pi->uvd_enabled = false;
+   }
+}
+
 static int btc_reset_to_default(struct radeon_device *rdev)
 {
if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_ResetToDefaults) != 
PPSMC_Result_OK)
@@ -1880,7 +1920,11 @@ int btc_dpm_set_power_state(struct radeon_device *rdev)
if (eg_pi->pcie_performance_request)
cypress_notify_link_speed_change_before_state_change(rdev);

+   rv770_set_uvd_clock_before_set_eng_clock(rdev);
rv770_halt_smc(rdev);
+   btc_set_at_for_uvd(rdev);
+   if (eg_pi->smu_uvd_hs)
+   btc_notify_uvd_to_smc(rdev);
cypress_upload_sw_state(rdev);

if (eg_pi->dynamic_ac_timing)
@@ -1890,6 +1934,7 @@ int btc_dpm_set_power_state(struct radeon_device *rdev)

rv770_resume_smc(rdev);
rv770_set_sw_state(rdev);
+   rv770_set_uvd_clock_after_set_eng_clock(rdev);

if (eg_pi->pcie_performance_request)
cypress_notify_link_speed_change_after_state_change(rdev);
@@ -2093,6 +2138,23 @@ int btc_dpm_init(struct radeon_device *rdev)
pi->mclk_edc_enable_threshold = 4;
eg_pi->mclk_edc_wr_enable_threshold = 4;

+   pi->rlp = RV770_RLP_DFLT;
+   pi->rmp = RV770_RMP_DFLT;
+   pi->lhp = RV770_LHP_DFLT;
+   pi->lmp = RV770_LMP_DFLT;
+
+   eg_pi->ats[0].rlp = RV770_RLP_DFLT;
+   eg_pi->ats[0].rmp = RV770_RMP_DFLT;
+   eg_pi->ats[0].lhp = RV770_LHP_DFLT;
+   eg_pi->ats[0].lmp = RV770_LMP_DFLT;
+
+   eg_pi->ats[1].rlp = BTC_RLP_UVD_DFLT;
+   eg_pi->ats[1].rmp = BTC_RMP_UVD_DFLT;
+   eg_pi->ats[1].lhp = BTC_LHP_UVD_DFLT;
+   eg_pi->ats[1].lmp = BTC_LMP_UVD_DFLT;
+
+   eg_pi->smu_uvd_hs = true;
+
pi->voltage_control =
radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC);

diff --git a/drivers/gpu/drm/radeon/btc_dpm.h b/drivers/gpu/drm/radeon/btc_dpm.h
index a095d40..56b1957 100644
--- a/drivers/gpu/drm/radeon/btc_dpm.h
+++ b/drivers/gpu/drm/radeon/btc_dpm.h
@@ -23,6 +23,10 @@
 #ifndef __BTC_DPM_H__
 #define __BTC_DPM_H__

+#define BTC_RLP_UVD_DFLT  20
+#define BTC_RMP_UVD_DFLT  50
+#define BTC_LHP_UVD_DFLT  50
+#define BTC_LMP_UVD_DFLT  20
 #define BARTS_MGCGCGTSSMCTRL_DFLT 0x81944000
 #define TURKS_MGCGCGTSSMCTRL_DFLT 0x6e944000
 #define CAICOS_MGCGCGTSSMCTRL_DFLT0x46944040
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c 
b/drivers/gpu/drm/radeon/cypress_dpm.c
index 2345c81..403ee15 100644
--- a/drivers/gpu/drm/radeon/cypress_dpm.c
+++ b/drivers/gpu/drm/radeon/cypress_dpm.c
@@ -690,7 

[PATCH 083/165] drm/radeon: add dpm UVD handling for r7xx asics

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/rv770_dpm.c |   34 ++
 drivers/gpu/drm/radeon/rv770_dpm.h |2 ++
 2 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c 
b/drivers/gpu/drm/radeon/rv770_dpm.c
index 8ea6d69..42f559a 100644
--- a/drivers/gpu/drm/radeon/rv770_dpm.c
+++ b/drivers/gpu/drm/radeon/rv770_dpm.c
@@ -1427,6 +1427,38 @@ int rv770_set_boot_state(struct radeon_device *rdev)
return 0;
 }

+void rv770_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev)
+{
+   struct rv7xx_ps *new_state = rv770_get_ps(rdev->pm.dpm.requested_ps);
+   struct rv7xx_ps *current_state = rv770_get_ps(rdev->pm.dpm.current_ps);
+
+   if ((rdev->pm.dpm.requested_ps->vclk == rdev->pm.dpm.current_ps->vclk) 
&&
+   (rdev->pm.dpm.requested_ps->dclk == rdev->pm.dpm.current_ps->dclk))
+   return;
+
+   if (new_state->high.sclk >= current_state->high.sclk)
+   return;
+
+   radeon_set_uvd_clocks(rdev, rdev->pm.dpm.requested_ps->vclk,
+ rdev->pm.dpm.requested_ps->dclk);
+}
+
+void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev)
+{
+   struct rv7xx_ps *new_state = rv770_get_ps(rdev->pm.dpm.requested_ps);
+   struct rv7xx_ps *current_state = rv770_get_ps(rdev->pm.dpm.current_ps);
+
+   if ((rdev->pm.dpm.requested_ps->vclk == rdev->pm.dpm.current_ps->vclk) 
&&
+   (rdev->pm.dpm.requested_ps->dclk == rdev->pm.dpm.current_ps->dclk))
+   return;
+
+   if (new_state->high.sclk < current_state->high.sclk)
+   return;
+
+   radeon_set_uvd_clocks(rdev, rdev->pm.dpm.requested_ps->vclk,
+ rdev->pm.dpm.requested_ps->dclk);
+}
+
 int rv770_restrict_performance_levels_before_switch(struct radeon_device *rdev)
 {
if (rv770_send_msg_to_smc(rdev, (PPSMC_Msg)(PPSMC_MSG_NoForcedLevel)) 
!= PPSMC_Result_OK)
@@ -1950,6 +1982,7 @@ int rv770_dpm_set_power_state(struct radeon_device *rdev)
struct rv7xx_power_info *pi = rv770_get_pi(rdev);

rv770_restrict_performance_levels_before_switch(rdev);
+   rv770_set_uvd_clock_before_set_eng_clock(rdev);
rv770_halt_smc(rdev);
rv770_upload_sw_state(rdev);
r7xx_program_memory_timing_parameters(rdev);
@@ -1959,6 +1992,7 @@ int rv770_dpm_set_power_state(struct radeon_device *rdev)
rv770_set_sw_state(rdev);
if (pi->dcodt)
rv770_program_dcodt_after_state_switch(rdev);
+   rv770_set_uvd_clock_after_set_eng_clock(rdev);

return 0;
 }
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.h 
b/drivers/gpu/drm/radeon/rv770_dpm.h
index bd6ea7b..e42c064 100644
--- a/drivers/gpu/drm/radeon/rv770_dpm.h
+++ b/drivers/gpu/drm/radeon/rv770_dpm.h
@@ -262,6 +262,8 @@ int rv770_resume_smc(struct radeon_device *rdev);
 int rv770_set_sw_state(struct radeon_device *rdev);
 int rv770_set_boot_state(struct radeon_device *rdev);
 int rv7xx_parse_power_table(struct radeon_device *rdev);
+void rv770_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev);
+void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev);

 /* smc */
 int rv770_read_smc_soft_register(struct radeon_device *rdev,
-- 
1.7.7.5



[PATCH 082/165] drm/radeon/dpm: let atom control display phy powergating

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/sumo_dpm.c |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c 
b/drivers/gpu/drm/radeon/sumo_dpm.c
index 67c85c7..f103880 100644
--- a/drivers/gpu/drm/radeon/sumo_dpm.c
+++ b/drivers/gpu/drm/radeon/sumo_dpm.c
@@ -813,6 +813,12 @@ static void sumo_program_bootup_state(struct radeon_device 
*rdev)

 void sumo_take_smu_control(struct radeon_device *rdev, bool enable)
 {
+/* This bit selects who handles display phy powergating.
+ * Clear the bit to let atom handle it.
+ * Set it to let the driver handle it.
+ * For now we just let atom handle it.
+ */
+#if 0
u32 v = RREG32(DOUT_SCRATCH3);

if (enable)
@@ -821,6 +827,7 @@ void sumo_take_smu_control(struct radeon_device *rdev, bool 
enable)
v &= 0xFFFB;

WREG32(DOUT_SCRATCH3, v);
+#endif
 }

 static void sumo_enable_sclk_ds(struct radeon_device *rdev, bool enable)
-- 
1.7.7.5



[PATCH 081/165] drm/radeon/kms: add dpm support for trinity asics

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

This adds dpm support for trinity asics.  This includes:
- clockgating
- powergating
- dynamic engine clock scaling
- dynamic voltage scaling

set radeon.dpm=1 to enable it.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/Makefile  |3 +-
 drivers/gpu/drm/radeon/evergreen.c   |   13 +-
 drivers/gpu/drm/radeon/evergreend.h  |   10 +
 drivers/gpu/drm/radeon/ppsmc.h   |   10 +-
 drivers/gpu/drm/radeon/radeon_asic.c |   12 +
 drivers/gpu/drm/radeon/radeon_asic.h |   12 +
 drivers/gpu/drm/radeon/radeon_pm.c   |1 +
 drivers/gpu/drm/radeon/sumo_dpm.c|   90 +-
 drivers/gpu/drm/radeon/sumo_dpm.h|   21 +-
 drivers/gpu/drm/radeon/sumo_smc.c|2 -
 drivers/gpu/drm/radeon/trinity_dpm.c | 1613 ++
 drivers/gpu/drm/radeon/trinity_dpm.h |  110 +++
 drivers/gpu/drm/radeon/trinity_smc.c |  110 +++
 drivers/gpu/drm/radeon/trinityd.h|  223 +
 14 files changed, 2179 insertions(+), 51 deletions(-)
 create mode 100644 drivers/gpu/drm/radeon/trinity_dpm.c
 create mode 100644 drivers/gpu/drm/radeon/trinity_dpm.h
 create mode 100644 drivers/gpu/drm/radeon/trinity_smc.c
 create mode 100644 drivers/gpu/drm/radeon/trinityd.h

diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 7c77e1d..2239ec2 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -78,7 +78,8 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \
si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \
-   rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o
+   rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o 
\
+   trinity_smc.o

 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index c91b1e5..6449953 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -4187,8 +4187,12 @@ int evergreen_irq_set(struct radeon_device *rdev)
hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN;
hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN;
hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN;
-   thermal_int = RREG32(CG_THERMAL_INT) &
-   ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
+   if (rdev->family == CHIP_ARUBA)
+   thermal_int = RREG32(TN_CG_THERMAL_INT_CTRL) &
+   ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
+   else
+   thermal_int = RREG32(CG_THERMAL_INT) &
+   ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);

afmt1 = RREG32(AFMT_AUDIO_PACKET_CONTROL + 
EVERGREEN_CRTC0_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
afmt2 = RREG32(AFMT_AUDIO_PACKET_CONTROL + 
EVERGREEN_CRTC1_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
@@ -4360,7 +4364,10 @@ int evergreen_irq_set(struct radeon_device *rdev)
WREG32(DC_HPD4_INT_CONTROL, hpd4);
WREG32(DC_HPD5_INT_CONTROL, hpd5);
WREG32(DC_HPD6_INT_CONTROL, hpd6);
-   WREG32(CG_THERMAL_INT, thermal_int);
+   if (rdev->family == CHIP_ARUBA)
+   WREG32(TN_CG_THERMAL_INT_CTRL, thermal_int);
+   else
+   WREG32(CG_THERMAL_INT, thermal_int);

WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 
afmt1);
WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 
afmt2);
diff --git a/drivers/gpu/drm/radeon/evergreend.h 
b/drivers/gpu/drm/radeon/evergreend.h
index 93b91a3..35e6153 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -823,6 +823,16 @@
 #defineTHERM_INT_MASK_HIGH (1 << 24)
 #defineTHERM_INT_MASK_LOW  (1 << 25)

+#defineTN_CG_THERMAL_INT_CTRL  0x738
+#defineTN_DIG_THERM_INTH(x)((x) << 0)
+#defineTN_DIG_THERM_INTH_MASK  0x00FF
+#defineTN_DIG_THERM_INTH_SHIFT 0
+#defineTN_DIG_THERM_INTL(x)((x) << 8)
+#defineTN_DIG_THERM_INTL_MASK  0xFF00
+#defineTN_DIG_THERM_INTL_SHIFT 8
+#defineTN_THERM_INT_MASK_HIGH  (1 << 24)
+#defineTN_THERM_INT_MASK_LOW   (1 << 25)
+
 #defineCG_MULT_THERMAL_STATUS  0x740
 #defineASIC_T(x)   ((x) << 16)
 #defineASIC_T_MASK 0x07FF
diff --git a/drivers/gpu/drm/radeon/ppsmc.h b/drivers/gpu/drm/radeon/ppsmc.h

[PATCH 080/165] drm/radeon/kms: add dpm support for sumo asics

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

This adds dpm support for sumo asics.  This includes:
- clockgating
- powergating
- dynamic engine clock scaling
- dynamic voltage scaling

set radeon.dpm=1 to enable it.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/Makefile  |2 +-
 drivers/gpu/drm/radeon/radeon_asic.c |   12 +
 drivers/gpu/drm/radeon/radeon_asic.h |   11 +
 drivers/gpu/drm/radeon/radeon_pm.c   |3 +
 drivers/gpu/drm/radeon/sumo_dpm.c| 1677 ++
 drivers/gpu/drm/radeon/sumo_dpm.h|  199 
 drivers/gpu/drm/radeon/sumo_smc.c|  224 +
 drivers/gpu/drm/radeon/sumod.h   |  362 
 8 files changed, 2489 insertions(+), 1 deletions(-)
 create mode 100644 drivers/gpu/drm/radeon/sumo_dpm.c
 create mode 100644 drivers/gpu/drm/radeon/sumo_dpm.h
 create mode 100644 drivers/gpu/drm/radeon/sumo_smc.c
 create mode 100644 drivers/gpu/drm/radeon/sumod.h

diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index af3dd8f..7c77e1d 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -78,7 +78,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \
si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \
-   rv770_smc.o cypress_dpm.o btc_dpm.o
+   rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o

 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index 20f65ad..8b541b4 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1539,6 +1539,18 @@ static struct radeon_asic sumo_asic = {
.set_uvd_clocks = _set_uvd_clocks,
.get_temperature = _get_temp,
},
+   .dpm = {
+   .init = _dpm_init,
+   .setup_asic = _dpm_setup_asic,
+   .enable = _dpm_enable,
+   .disable = _dpm_disable,
+   .set_power_state = _dpm_set_power_state,
+   .display_configuration_changed = 
_dpm_display_configuration_changed,
+   .fini = _dpm_fini,
+   .get_sclk = _dpm_get_sclk,
+   .get_mclk = _dpm_get_mclk,
+   .print_power_state = _dpm_print_power_state,
+   },
.pflip = {
.pre_page_flip = _pre_page_flip,
.page_flip = _page_flip,
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h 
b/drivers/gpu/drm/radeon/radeon_asic.h
index 214429b..f6c0984 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -536,6 +536,17 @@ int btc_dpm_enable(struct radeon_device *rdev);
 void btc_dpm_disable(struct radeon_device *rdev);
 int btc_dpm_set_power_state(struct radeon_device *rdev);
 void btc_dpm_fini(struct radeon_device *rdev);
+int sumo_dpm_init(struct radeon_device *rdev);
+int sumo_dpm_enable(struct radeon_device *rdev);
+void sumo_dpm_disable(struct radeon_device *rdev);
+int sumo_dpm_set_power_state(struct radeon_device *rdev);
+void sumo_dpm_setup_asic(struct radeon_device *rdev);
+void sumo_dpm_display_configuration_changed(struct radeon_device *rdev);
+void sumo_dpm_fini(struct radeon_device *rdev);
+u32 sumo_dpm_get_sclk(struct radeon_device *rdev, bool low);
+u32 sumo_dpm_get_mclk(struct radeon_device *rdev, bool low);
+void sumo_dpm_print_power_state(struct radeon_device *rdev,
+   struct radeon_ps *ps);

 /*
  * cayman
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c 
b/drivers/gpu/drm/radeon/radeon_pm.c
index 0a770b5..b924bcc1 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -1049,6 +1049,9 @@ int radeon_pm_init(struct radeon_device *rdev)
case CHIP_JUNIPER:
case CHIP_CYPRESS:
case CHIP_HEMLOCK:
+   case CHIP_PALM:
+   case CHIP_SUMO:
+   case CHIP_SUMO2:
case CHIP_BARTS:
case CHIP_TURKS:
case CHIP_CAICOS:
diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c 
b/drivers/gpu/drm/radeon/sumo_dpm.c
new file mode 100644
index 000..4f49450
--- /dev/null
+++ b/drivers/gpu/drm/radeon/sumo_dpm.c
@@ -0,0 +1,1677 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this 

[PATCH 079/165] drm/radeon/kms: add dpm support for btc (v2)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

This adds dpm support for btc asics.  This includes:
- clockgating
- dynamic engine clock scaling
- dynamic memory clock scaling
- dynamic voltage scaling
- dynamic pcie gen1/gen2 switching (requires additional acpi support)

Set radeon.dpm=1 to enable.

v2: reduce stack usage

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/Makefile   |2 +-
 drivers/gpu/drm/radeon/btc_dpm.c  | 2183 +
 drivers/gpu/drm/radeon/btc_dpm.h  |   32 +
 drivers/gpu/drm/radeon/btcd.h |  181 +++
 drivers/gpu/drm/radeon/ni.c   |   21 +
 drivers/gpu/drm/radeon/radeon_asic.c  |   12 +
 drivers/gpu/drm/radeon/radeon_asic.h  |6 +
 drivers/gpu/drm/radeon/radeon_pm.c|3 +
 drivers/gpu/drm/radeon/radeon_ucode.h |   15 +
 drivers/gpu/drm/radeon/rv770_smc.c|   81 ++
 10 files changed, 2535 insertions(+), 1 deletions(-)
 create mode 100644 drivers/gpu/drm/radeon/btc_dpm.c
 create mode 100644 drivers/gpu/drm/radeon/btc_dpm.h
 create mode 100644 drivers/gpu/drm/radeon/btcd.h

diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 7092c96..af3dd8f 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -78,7 +78,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \
si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \
-   rv770_smc.o cypress_dpm.o
+   rv770_smc.o cypress_dpm.o btc_dpm.o

 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c
new file mode 100644
index 000..6780120
--- /dev/null
+++ b/drivers/gpu/drm/radeon/btc_dpm.c
@@ -0,0 +1,2183 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Alex Deucher
+ */
+
+#include "drmP.h"
+#include "radeon.h"
+#include "btcd.h"
+#include "r600_dpm.h"
+#include "cypress_dpm.h"
+#include "btc_dpm.h"
+#include "atom.h"
+
+#define MC_CG_ARB_FREQ_F0   0x0a
+#define MC_CG_ARB_FREQ_F1   0x0b
+#define MC_CG_ARB_FREQ_F2   0x0c
+#define MC_CG_ARB_FREQ_F3   0x0d
+
+#define MC_CG_SEQ_DRAMCONF_S0   0x05
+#define MC_CG_SEQ_DRAMCONF_S1   0x06
+#define MC_CG_SEQ_YCLK_SUSPEND  0x04
+#define MC_CG_SEQ_YCLK_RESUME   0x0a
+
+#define SMC_RAM_END 0x8000
+
+#ifndef BTC_MGCG_SEQUENCE
+#define BTC_MGCG_SEQUENCE  300
+
+struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
+struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
+struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
+
+
+//* BARTS **//
+static const u32 barts_cgcg_cgls_default[] =
+{
+   /* Register,   Value, Mask bits */
+   0x08f8, 0x0010, 0x,
+   0x08fc, 0x, 0x,
+   0x08f8, 0x0011, 0x,
+   0x08fc, 0x, 0x,
+   0x08f8, 0x0012, 0x,
+   0x08fc, 0x, 0x,
+   0x08f8, 0x0013, 0x,
+   0x08fc, 0x, 0x,
+   0x08f8, 0x0014, 0x,
+   0x08fc, 0x, 0x,
+   0x08f8, 0x0015, 0x,
+   0x08fc, 0x, 0x,
+   0x08f8, 0x0016, 0x,
+   0x08fc, 0x, 0x,
+   0x08f8, 0x0017, 0x,
+   0x08fc, 0x, 0x,
+   0x08f8, 0x0018, 0x,
+   0x08fc, 0x, 0x,
+   0x08f8, 0x0019, 0x,
+   0x08fc, 0x, 0x,
+   0x08f8, 0x001a, 0x,
+   

[PATCH 078/165] drm/radeon/kms: add dpm support for evergreen (v2)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

This adds dpm support for evergreen asics.  This includes:
- clockgating
- dynamic engine clock scaling
- dynamic memory clock scaling
- dynamic voltage scaling
- dynamic pcie gen1/gen2 switching (requires additional acpi support)

Set radeon.dpm=1 to enable.

v2: reduce stack usage, rename ulv struct

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/Makefile|2 +-
 drivers/gpu/drm/radeon/cypress_dpm.c   | 2103 
 drivers/gpu/drm/radeon/cypress_dpm.h   |  134 ++
 drivers/gpu/drm/radeon/evergreen.c |   22 +
 drivers/gpu/drm/radeon/evergreen_smc.h |   67 +
 drivers/gpu/drm/radeon/evergreend.h|  305 +
 drivers/gpu/drm/radeon/r600.c  |   14 +-
 drivers/gpu/drm/radeon/radeon.h|   13 +
 drivers/gpu/drm/radeon/radeon_acpi.c   |   23 +
 drivers/gpu/drm/radeon/radeon_asic.c   |   12 +
 drivers/gpu/drm/radeon/radeon_asic.h   |7 +
 drivers/gpu/drm/radeon/radeon_pm.c |5 +
 drivers/gpu/drm/radeon/radeon_ucode.h  |   20 +
 drivers/gpu/drm/radeon/rv770_dpm.c |   45 +-
 drivers/gpu/drm/radeon/rv770_dpm.h |4 +
 drivers/gpu/drm/radeon/rv770_smc.c |  109 ++
 16 files changed, 2875 insertions(+), 10 deletions(-)
 create mode 100644 drivers/gpu/drm/radeon/cypress_dpm.c
 create mode 100644 drivers/gpu/drm/radeon/cypress_dpm.h
 create mode 100644 drivers/gpu/drm/radeon/evergreen_smc.h

diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index c97753d..7092c96 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -78,7 +78,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \
si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \
-   rv770_smc.o
+   rv770_smc.o cypress_dpm.o

 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c 
b/drivers/gpu/drm/radeon/cypress_dpm.c
new file mode 100644
index 000..2345c81
--- /dev/null
+++ b/drivers/gpu/drm/radeon/cypress_dpm.c
@@ -0,0 +1,2103 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Alex Deucher
+ */
+
+#include "drmP.h"
+#include "radeon.h"
+#include "evergreend.h"
+#include "r600_dpm.h"
+#include "cypress_dpm.h"
+#include "atom.h"
+
+#define SMC_RAM_END 0x8000
+
+#define MC_CG_ARB_FREQ_F0   0x0a
+#define MC_CG_ARB_FREQ_F1   0x0b
+#define MC_CG_ARB_FREQ_F2   0x0c
+#define MC_CG_ARB_FREQ_F3   0x0d
+
+#define MC_CG_SEQ_DRAMCONF_S0   0x05
+#define MC_CG_SEQ_DRAMCONF_S1   0x06
+#define MC_CG_SEQ_YCLK_SUSPEND  0x04
+#define MC_CG_SEQ_YCLK_RESUME   0x0a
+
+struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
+struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
+struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
+
+static u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev,
+  u32 memory_clock, bool strobe_mode);
+
+static void cypress_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
+bool enable)
+{
+   struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+   u32 tmp, bif;
+
+   tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+   if (enable) {
+   if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
+   (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
+   if (!pi->boot_in_gen2) {
+   bif = RREG32(CG_BIF_REQ_AND_RSP) & 
~CG_CLIENT_REQ_MASK;
+   bif |= CG_CLIENT_REQ(0xd);
+ 

[PATCH 077/165] drm/radeon/kms: add dpm support for rv7xx (v2)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

This adds dpm support for rv7xx asics.  This includes:
- clockgating
- dynamic engine clock scaling
- dynamic memory clock scaling
- dynamic voltage scaling
- dynamic pcie gen1/gen2 switching

Set radeon.dpm=1 to enable.

v2: reduce stack usage

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/Makefile   |3 +-
 drivers/gpu/drm/radeon/ppsmc.h|   76 ++
 drivers/gpu/drm/radeon/r600.c |   48 +-
 drivers/gpu/drm/radeon/r600d.h|2 +
 drivers/gpu/drm/radeon/radeon.h   |1 +
 drivers/gpu/drm/radeon/radeon_asic.c  |   12 +
 drivers/gpu/drm/radeon/radeon_asic.h  |   12 +
 drivers/gpu/drm/radeon/radeon_pm.c|4 +
 drivers/gpu/drm/radeon/radeon_ucode.h |   21 +
 drivers/gpu/drm/radeon/rv730_dpm.c|  508 +++
 drivers/gpu/drm/radeon/rv730d.h   |  165 +++
 drivers/gpu/drm/radeon/rv740_dpm.c|  417 ++
 drivers/gpu/drm/radeon/rv740d.h   |  117 ++
 drivers/gpu/drm/radeon/rv770_dpm.c| 2325 +
 drivers/gpu/drm/radeon/rv770_dpm.h|  272 
 drivers/gpu/drm/radeon/rv770_smc.c|  404 ++
 drivers/gpu/drm/radeon/rv770_smc.h|  208 +++
 drivers/gpu/drm/radeon/rv770d.h   |  279 -
 18 files changed, 4861 insertions(+), 13 deletions(-)
 create mode 100644 drivers/gpu/drm/radeon/ppsmc.h
 create mode 100644 drivers/gpu/drm/radeon/rv730_dpm.c
 create mode 100644 drivers/gpu/drm/radeon/rv730d.h
 create mode 100644 drivers/gpu/drm/radeon/rv740_dpm.c
 create mode 100644 drivers/gpu/drm/radeon/rv740d.h
 create mode 100644 drivers/gpu/drm/radeon/rv770_dpm.c
 create mode 100644 drivers/gpu/drm/radeon/rv770_dpm.h
 create mode 100644 drivers/gpu/drm/radeon/rv770_smc.c
 create mode 100644 drivers/gpu/drm/radeon/rv770_smc.h

diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 3aa20dc..c97753d 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -77,7 +77,8 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \
atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \
si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
-   r600_dpm.o rs780_dpm.o rv6xx_dpm.o
+   r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \
+   rv770_smc.o

 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
diff --git a/drivers/gpu/drm/radeon/ppsmc.h b/drivers/gpu/drm/radeon/ppsmc.h
new file mode 100644
index 000..638de17
--- /dev/null
+++ b/drivers/gpu/drm/radeon/ppsmc.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef PP_SMC_H
+#define PP_SMC_H
+
+#pragma pack(push, 1)
+
+#define PPSMC_SWSTATE_FLAG_DC   0x01
+
+#define PPSMC_THERMAL_PROTECT_TYPE_INTERNAL 0x00
+#define PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL 0x01
+#define PPSMC_THERMAL_PROTECT_TYPE_NONE 0xff
+
+#define PPSMC_SYSTEMFLAG_GPIO_DC0x01
+#define PPSMC_SYSTEMFLAG_STEPVDDC   0x02
+#define PPSMC_SYSTEMFLAG_GDDR5  0x04
+#define PPSMC_SYSTEMFLAG_DISABLE_BABYSTEP   0x08
+#define PPSMC_SYSTEMFLAG_REGULATOR_HOT  0x10
+
+#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_MASK  0x07
+#define PPSMC_EXTRAFLAGS_AC2DC_DONT_WAIT_FOR_VBLANK 0x08
+#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTODPMLOWSTATE   0x00
+#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTOINITIALSTATE  0x01
+
+#define PPSMC_DISPLAY_WATERMARK_LOW 0
+#define PPSMC_DISPLAY_WATERMARK_HIGH1
+
+#define PPSMC_STATEFLAG_AUTO_PULSE_SKIP0x01
+
+#define PPSMC_Result_OK ((uint8_t)0x01)
+#define 

[PATCH 076/165] drm/radeon/kms: add dpm support for rv6xx

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

This adds dpm support for rv6xx asics.  This includes:
- clockgating
- dynamic engine clock scaling
- dynamic memory clock scaling
- dynamic voltage scaling
- dynamic pcie gen1/gen2 switching

Set radeon.dpm=1 to enable.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/Makefile  |2 +-
 drivers/gpu/drm/radeon/r600.c|   27 +
 drivers/gpu/drm/radeon/r600_dpm.c|   45 +
 drivers/gpu/drm/radeon/r600_dpm.h|8 +
 drivers/gpu/drm/radeon/r600d.h   |   13 +
 drivers/gpu/drm/radeon/radeon.h  |3 +
 drivers/gpu/drm/radeon/radeon_asic.c |   12 +
 drivers/gpu/drm/radeon/radeon_asic.h |   12 +
 drivers/gpu/drm/radeon/radeon_atombios.c |4 +-
 drivers/gpu/drm/radeon/radeon_irq_kms.c  |2 +
 drivers/gpu/drm/radeon/radeon_mode.h |2 +
 drivers/gpu/drm/radeon/radeon_pm.c   |9 +
 drivers/gpu/drm/radeon/rs780_dpm.c   |   12 +
 drivers/gpu/drm/radeon/rv6xx_dpm.c   | 1991 ++
 drivers/gpu/drm/radeon/rv6xx_dpm.h   |   95 ++
 drivers/gpu/drm/radeon/rv6xxd.h  |  246 
 16 files changed, 2480 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/radeon/rv6xx_dpm.c
 create mode 100644 drivers/gpu/drm/radeon/rv6xx_dpm.h
 create mode 100644 drivers/gpu/drm/radeon/rv6xxd.h

diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index e44b046..3aa20dc 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -77,7 +77,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \
atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \
si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
-   r600_dpm.o rs780_dpm.o
+   r600_dpm.o rs780_dpm.o rv6xx_dpm.o

 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 4678ed1..7ea81c8 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -3998,6 +3998,7 @@ int r600_irq_set(struct radeon_device *rdev)
u32 hdmi0, hdmi1;
u32 d1grph = 0, d2grph = 0;
u32 dma_cntl;
+   u32 thermal_int = 0;

if (!rdev->irq.installed) {
WARN(1, "Can't enable IRQ/MSI because no handler is 
installed\n");
@@ -4032,8 +4033,18 @@ int r600_irq_set(struct radeon_device *rdev)
hdmi0 = RREG32(HDMI0_AUDIO_PACKET_CONTROL) & 
~HDMI0_AZ_FORMAT_WTRIG_MASK;
hdmi1 = RREG32(HDMI1_AUDIO_PACKET_CONTROL) & 
~HDMI0_AZ_FORMAT_WTRIG_MASK;
}
+
dma_cntl = RREG32(DMA_CNTL) & ~TRAP_ENABLE;

+   if ((rdev->family > CHIP_R600) && (rdev->family < CHIP_RV770)) {
+   thermal_int = RREG32(CG_THERMAL_INT) &
+   ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
+   if (rdev->irq.dpm_thermal) {
+   DRM_DEBUG("dpm thermal\n");
+   thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
+   }
+   }
+
if (atomic_read(>irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
DRM_DEBUG("r600_irq_set: sw int\n");
cp_int_cntl |= RB_INT_ENABLE;
@@ -4115,6 +4126,9 @@ int r600_irq_set(struct radeon_device *rdev)
WREG32(HDMI0_AUDIO_PACKET_CONTROL, hdmi0);
WREG32(HDMI1_AUDIO_PACKET_CONTROL, hdmi1);
}
+   if ((rdev->family > CHIP_R600) && (rdev->family < CHIP_RV770)) {
+   WREG32(CG_THERMAL_INT, thermal_int);
+   }

return 0;
 }
@@ -4306,6 +4320,7 @@ int r600_irq_process(struct radeon_device *rdev)
u32 ring_index;
bool queue_hotplug = false;
bool queue_hdmi = false;
+   bool queue_thermal = false;

if (!rdev->ih.enabled || rdev->shutdown)
return IRQ_NONE;
@@ -4473,6 +4488,16 @@ restart_ih:
DRM_DEBUG("IH: DMA trap\n");
radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX);
break;
+   case 230: /* thermal low to high */
+   DRM_DEBUG("IH: thermal low to high\n");
+   rdev->pm.dpm.thermal.high_to_low = false;
+   queue_thermal = true;
+   break;
+   case 231: /* thermal high to low */
+   DRM_DEBUG("IH: thermal high to low\n");
+   rdev->pm.dpm.thermal.high_to_low = true;
+   queue_thermal = true;
+   break;
case 233: /* GUI IDLE */
DRM_DEBUG("IH: GUI idle\n");
break;
@@ -4489,6 +4514,8 @@ restart_ih:
schedule_work(>hotplug_work);
if (queue_hdmi)

[PATCH 075/165] drm/radeon/kms: add dpm support for rs780/rs880

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

This adds dpm support for rs780/rs880 asics.  This includes:
- clockgating
- dynamic engine clock scaling
- dynamic voltage scaling

set radeon.dpm=1 to enable it.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/Makefile  |2 +-
 drivers/gpu/drm/radeon/radeon_asic.c |   12 +
 drivers/gpu/drm/radeon/radeon_asic.h |   12 +
 drivers/gpu/drm/radeon/radeon_pm.c   |7 +
 drivers/gpu/drm/radeon/rs780_dpm.c   |  894 ++
 drivers/gpu/drm/radeon/rs780_dpm.h   |  109 
 drivers/gpu/drm/radeon/rs780d.h  |  168 +++
 7 files changed, 1203 insertions(+), 1 deletions(-)
 create mode 100644 drivers/gpu/drm/radeon/rs780_dpm.c
 create mode 100644 drivers/gpu/drm/radeon/rs780_dpm.h
 create mode 100644 drivers/gpu/drm/radeon/rs780d.h

diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index a131a13..e44b046 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -77,7 +77,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \
atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \
si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
-   r600_dpm.o
+   r600_dpm.o rs780_dpm.o

 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index d9c8e9a..db3c930 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1194,6 +1194,18 @@ static struct radeon_asic rs780_asic = {
.set_clock_gating = NULL,
.get_temperature = _get_temp,
},
+   .dpm = {
+   .init = _dpm_init,
+   .setup_asic = _dpm_setup_asic,
+   .enable = _dpm_enable,
+   .disable = _dpm_disable,
+   .set_power_state = _dpm_set_power_state,
+   .display_configuration_changed = 
_dpm_display_configuration_changed,
+   .fini = _dpm_fini,
+   .get_sclk = _dpm_get_sclk,
+   .get_mclk = _dpm_get_mclk,
+   .print_power_state = _dpm_print_power_state,
+   },
.pflip = {
.pre_page_flip = _pre_page_flip,
.page_flip = _page_flip,
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h 
b/drivers/gpu/drm/radeon/radeon_asic.h
index 8507cae..134bf57 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -396,6 +396,18 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev);
 u32 r600_get_xclk(struct radeon_device *rdev);
 uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev);
 int rv6xx_get_temp(struct radeon_device *rdev);
+/* rs780 dpm */
+int rs780_dpm_init(struct radeon_device *rdev);
+int rs780_dpm_enable(struct radeon_device *rdev);
+void rs780_dpm_disable(struct radeon_device *rdev);
+int rs780_dpm_set_power_state(struct radeon_device *rdev);
+void rs780_dpm_setup_asic(struct radeon_device *rdev);
+void rs780_dpm_display_configuration_changed(struct radeon_device *rdev);
+void rs780_dpm_fini(struct radeon_device *rdev);
+u32 rs780_dpm_get_sclk(struct radeon_device *rdev, bool low);
+u32 rs780_dpm_get_mclk(struct radeon_device *rdev, bool low);
+void rs780_dpm_print_power_state(struct radeon_device *rdev,
+struct radeon_ps *ps);

 /* uvd */
 int r600_uvd_init(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c 
b/drivers/gpu/drm/radeon/radeon_pm.c
index 4f5422e..853a8a2 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -1030,6 +1030,13 @@ int radeon_pm_init(struct radeon_device *rdev)
 {
/* enable dpm on rv6xx+ */
switch (rdev->family) {
+   case CHIP_RS780:
+   case CHIP_RS880:
+   if (radeon_dpm == 1)
+   rdev->pm.pm_method = PM_METHOD_DPM;
+   else
+   rdev->pm.pm_method = PM_METHOD_PROFILE;
+   break;
default:
/* default to profile method */
rdev->pm.pm_method = PM_METHOD_PROFILE;
diff --git a/drivers/gpu/drm/radeon/rs780_dpm.c 
b/drivers/gpu/drm/radeon/rs780_dpm.c
new file mode 100644
index 000..f594900
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rs780_dpm.c
@@ -0,0 +1,894 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * 

[PATCH 074/165] drm/radeon/kms: add common r600 dpm functions

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

These are shared by rs780/rs880, rv6xx, and newer chips.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/Makefile   |3 +-
 drivers/gpu/drm/radeon/r600_dpm.c |  678 +
 drivers/gpu/drm/radeon/r600_dpm.h |  210 
 drivers/gpu/drm/radeon/r600d.h|  213 
 drivers/gpu/drm/radeon/radeon.h   |   13 +
 5 files changed, 1116 insertions(+), 1 deletions(-)
 create mode 100644 drivers/gpu/drm/radeon/r600_dpm.c
 create mode 100644 drivers/gpu/drm/radeon/r600_dpm.h

diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 292fd25..a131a13 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -76,7 +76,8 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
evergreen.o evergreen_cs.o evergreen_blit_shaders.o 
evergreen_blit_kms.o \
evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \
atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \
-   si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o
+   si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
+   r600_dpm.o

 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
diff --git a/drivers/gpu/drm/radeon/r600_dpm.c 
b/drivers/gpu/drm/radeon/r600_dpm.c
new file mode 100644
index 000..91bc5ab
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_dpm.c
@@ -0,0 +1,678 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Alex Deucher
+ */
+
+#include "drmP.h"
+#include "radeon.h"
+#include "r600d.h"
+#include "r600_dpm.h"
+#include "atom.h"
+
+const u32 r600_utc[R600_PM_NUMBER_OF_TC] =
+{
+   R600_UTC_DFLT_00,
+   R600_UTC_DFLT_01,
+   R600_UTC_DFLT_02,
+   R600_UTC_DFLT_03,
+   R600_UTC_DFLT_04,
+   R600_UTC_DFLT_05,
+   R600_UTC_DFLT_06,
+   R600_UTC_DFLT_07,
+   R600_UTC_DFLT_08,
+   R600_UTC_DFLT_09,
+   R600_UTC_DFLT_10,
+   R600_UTC_DFLT_11,
+   R600_UTC_DFLT_12,
+   R600_UTC_DFLT_13,
+   R600_UTC_DFLT_14,
+};
+
+const u32 r600_dtc[R600_PM_NUMBER_OF_TC] =
+{
+   R600_DTC_DFLT_00,
+   R600_DTC_DFLT_01,
+   R600_DTC_DFLT_02,
+   R600_DTC_DFLT_03,
+   R600_DTC_DFLT_04,
+   R600_DTC_DFLT_05,
+   R600_DTC_DFLT_06,
+   R600_DTC_DFLT_07,
+   R600_DTC_DFLT_08,
+   R600_DTC_DFLT_09,
+   R600_DTC_DFLT_10,
+   R600_DTC_DFLT_11,
+   R600_DTC_DFLT_12,
+   R600_DTC_DFLT_13,
+   R600_DTC_DFLT_14,
+};
+
+void r600_dpm_print_class_info(u32 class, u32 class2)
+{
+   printk("\tui class: ");
+   switch (class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) {
+   case ATOM_PPLIB_CLASSIFICATION_UI_NONE:
+   default:
+   printk("none\n");
+   break;
+   case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY:
+   printk("battery\n");
+   break;
+   case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED:
+   printk("balanced\n");
+   break;
+   case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE:
+   printk("performance\n");
+   break;
+   }
+   printk("\tinternal class: ");
+   if (((class & ~ATOM_PPLIB_CLASSIFICATION_UI_MASK) == 0) &&
+   (class2 == 0))
+   printk("none");
+   else {
+   if (class & ATOM_PPLIB_CLASSIFICATION_BOOT)
+   printk("boot ");
+   if (class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
+   printk("thermal ");
+   if (class & ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE)
+   printk("limited_pwr ");
+   if (class & ATOM_PPLIB_CLASSIFICATION_REST)
+   printk("rest ");
+   if 

[PATCH 073/165] drm/radeon/kms: fix up dce6 display watermark calc for dpm

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Calculate the low and high watermarks based on the low and high
clocks for the current power state.  The dynamic pm hw will select
the appropriate watermark based on the internal dpm state.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/si.c |   96 +++---
 1 files changed, 71 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 813a8a9..882509a 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -1792,7 +1792,8 @@ static void dce6_program_watermarks(struct radeon_device 
*rdev,
 u32 lb_size, u32 num_heads)
 {
struct drm_display_mode *mode = _crtc->base.mode;
-   struct dce6_wm_params wm;
+   struct dce6_wm_params wm_low, wm_high;
+   u32 dram_channels;
u32 pixel_period;
u32 line_time = 0;
u32 latency_watermark_a = 0, latency_watermark_b = 0;
@@ -1808,38 +1809,83 @@ static void dce6_program_watermarks(struct 
radeon_device *rdev,
priority_a_cnt = 0;
priority_b_cnt = 0;

-   wm.yclk = rdev->pm.current_mclk * 10;
-   wm.sclk = rdev->pm.current_sclk * 10;
-   wm.disp_clk = mode->clock;
-   wm.src_width = mode->crtc_hdisplay;
-   wm.active_time = mode->crtc_hdisplay * pixel_period;
-   wm.blank_time = line_time - wm.active_time;
-   wm.interlaced = false;
-   if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-   wm.interlaced = true;
-   wm.vsc = radeon_crtc->vsc;
-   wm.vtaps = 1;
-   if (radeon_crtc->rmx_type != RMX_OFF)
-   wm.vtaps = 2;
-   wm.bytes_per_pixel = 4; /* XXX: get this from fb config */
-   wm.lb_size = lb_size;
if (rdev->family == CHIP_ARUBA)
-   wm.dram_channels = 
evergreen_get_number_of_dram_channels(rdev);
+   dram_channels = 
evergreen_get_number_of_dram_channels(rdev);
else
-   wm.dram_channels = si_get_number_of_dram_channels(rdev);
-   wm.num_heads = num_heads;
+   dram_channels = si_get_number_of_dram_channels(rdev);
+
+   /* watermark for high clocks */
+   if ((rdev->pm.pm_method == PM_METHOD_DPM) && 
rdev->pm.dpm_enabled) {
+   wm_high.yclk =
+   radeon_dpm_get_mclk(rdev, false) * 10;
+   wm_high.sclk =
+   radeon_dpm_get_sclk(rdev, false) * 10;
+   } else {
+   wm_high.yclk = rdev->pm.current_mclk * 10;
+   wm_high.sclk = rdev->pm.current_sclk * 10;
+   }
+
+   wm_high.disp_clk = mode->clock;
+   wm_high.src_width = mode->crtc_hdisplay;
+   wm_high.active_time = mode->crtc_hdisplay * pixel_period;
+   wm_high.blank_time = line_time - wm_high.active_time;
+   wm_high.interlaced = false;
+   if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+   wm_high.interlaced = true;
+   wm_high.vsc = radeon_crtc->vsc;
+   wm_high.vtaps = 1;
+   if (radeon_crtc->rmx_type != RMX_OFF)
+   wm_high.vtaps = 2;
+   wm_high.bytes_per_pixel = 4; /* XXX: get this from fb config */
+   wm_high.lb_size = lb_size;
+   wm_high.dram_channels = dram_channels;
+   wm_high.num_heads = num_heads;
+
+   /* watermark for low clocks */
+   if ((rdev->pm.pm_method == PM_METHOD_DPM) && 
rdev->pm.dpm_enabled) {
+   wm_low.yclk =
+   radeon_dpm_get_mclk(rdev, true) * 10;
+   wm_low.sclk =
+   radeon_dpm_get_sclk(rdev, true) * 10;
+   } else {
+   wm_low.yclk = rdev->pm.current_mclk * 10;
+   wm_low.sclk = rdev->pm.current_sclk * 10;
+   }
+
+   wm_low.disp_clk = mode->clock;
+   wm_low.src_width = mode->crtc_hdisplay;
+   wm_low.active_time = mode->crtc_hdisplay * pixel_period;
+   wm_low.blank_time = line_time - wm_low.active_time;
+   wm_low.interlaced = false;
+   if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+   wm_low.interlaced = true;
+   wm_low.vsc = radeon_crtc->vsc;
+   wm_low.vtaps = 1;
+   if (radeon_crtc->rmx_type != RMX_OFF)
+   wm_low.vtaps = 2;
+   wm_low.bytes_per_pixel = 4; /* XXX: get this from fb config */
+   wm_low.lb_size = lb_size;
+   wm_low.dram_channels = dram_channels;
+ 

[PATCH 072/165] drm/radeon/kms: fix up dce4/5 display watermark calc for dpm

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Calculate the low and high watermarks based on the low and high
clocks for the current power state.  The dynamic pm hw will select
the appropriate watermark based on the internal dpm state.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/evergreen.c |   89 ++-
 1 files changed, 66 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index b9f64f0..63a1e6e 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2122,7 +2122,8 @@ static void evergreen_program_watermarks(struct 
radeon_device *rdev,
 u32 lb_size, u32 num_heads)
 {
struct drm_display_mode *mode = _crtc->base.mode;
-   struct evergreen_wm_params wm;
+   struct evergreen_wm_params wm_low, wm_high;
+   u32 dram_channels;
u32 pixel_period;
u32 line_time = 0;
u32 latency_watermark_a = 0, latency_watermark_b = 0;
@@ -2138,39 +2139,81 @@ static void evergreen_program_watermarks(struct 
radeon_device *rdev,
line_time = min((u32)mode->crtc_htotal * pixel_period, 
(u32)65535);
priority_a_cnt = 0;
priority_b_cnt = 0;
+   dram_channels = evergreen_get_number_of_dram_channels(rdev);
+
+   /* watermark for high clocks */
+   if ((rdev->pm.pm_method == PM_METHOD_DPM) && 
rdev->pm.dpm_enabled) {
+   wm_high.yclk =
+   radeon_dpm_get_mclk(rdev, false) * 10;
+   wm_high.sclk =
+   radeon_dpm_get_sclk(rdev, false) * 10;
+   } else {
+   wm_high.yclk = rdev->pm.current_mclk * 10;
+   wm_high.sclk = rdev->pm.current_sclk * 10;
+   }

-   wm.yclk = rdev->pm.current_mclk * 10;
-   wm.sclk = rdev->pm.current_sclk * 10;
-   wm.disp_clk = mode->clock;
-   wm.src_width = mode->crtc_hdisplay;
-   wm.active_time = mode->crtc_hdisplay * pixel_period;
-   wm.blank_time = line_time - wm.active_time;
-   wm.interlaced = false;
+   wm_high.disp_clk = mode->clock;
+   wm_high.src_width = mode->crtc_hdisplay;
+   wm_high.active_time = mode->crtc_hdisplay * pixel_period;
+   wm_high.blank_time = line_time - wm_high.active_time;
+   wm_high.interlaced = false;
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-   wm.interlaced = true;
-   wm.vsc = radeon_crtc->vsc;
-   wm.vtaps = 1;
+   wm_high.interlaced = true;
+   wm_high.vsc = radeon_crtc->vsc;
+   wm_high.vtaps = 1;
if (radeon_crtc->rmx_type != RMX_OFF)
-   wm.vtaps = 2;
-   wm.bytes_per_pixel = 4; /* XXX: get this from fb config */
-   wm.lb_size = lb_size;
-   wm.dram_channels = evergreen_get_number_of_dram_channels(rdev);
-   wm.num_heads = num_heads;
+   wm_high.vtaps = 2;
+   wm_high.bytes_per_pixel = 4; /* XXX: get this from fb config */
+   wm_high.lb_size = lb_size;
+   wm_high.dram_channels = dram_channels;
+   wm_high.num_heads = num_heads;
+
+   /* watermark for low clocks */
+   if ((rdev->pm.pm_method == PM_METHOD_DPM) && 
rdev->pm.dpm_enabled) {
+   wm_low.yclk =
+   radeon_dpm_get_mclk(rdev, true) * 10;
+   wm_low.sclk =
+   radeon_dpm_get_sclk(rdev, true) * 10;
+   } else {
+   wm_low.yclk = rdev->pm.current_mclk * 10;
+   wm_low.sclk = rdev->pm.current_sclk * 10;
+   }
+
+   wm_low.disp_clk = mode->clock;
+   wm_low.src_width = mode->crtc_hdisplay;
+   wm_low.active_time = mode->crtc_hdisplay * pixel_period;
+   wm_low.blank_time = line_time - wm_low.active_time;
+   wm_low.interlaced = false;
+   if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+   wm_low.interlaced = true;
+   wm_low.vsc = radeon_crtc->vsc;
+   wm_low.vtaps = 1;
+   if (radeon_crtc->rmx_type != RMX_OFF)
+   wm_low.vtaps = 2;
+   wm_low.bytes_per_pixel = 4; /* XXX: get this from fb config */
+   wm_low.lb_size = lb_size;
+   wm_low.dram_channels = dram_channels;
+   wm_low.num_heads = num_heads;

/* set for high clocks */
-   latency_watermark_a = min(evergreen_latency_watermark(), 
(u32)65535);
+   latency_watermark_a = 

[PATCH 071/165] drm/radeon/kms: fix up 6xx/7xx display watermark calc for dpm

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Calculate the low and high watermarks based on the low and high
clocks for the current power state.  The dynamic pm hw will select
the appropriate watermark based on the internal dpm state.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/rv515.c |  224 +++
 1 files changed, 132 insertions(+), 92 deletions(-)

diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index 21c7d7b..8ea1573 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -937,13 +937,16 @@ struct rv515_watermark {
 };

 static void rv515_crtc_bandwidth_compute(struct radeon_device *rdev,
- struct radeon_crtc *crtc,
- struct rv515_watermark *wm)
+struct radeon_crtc *crtc,
+struct rv515_watermark *wm,
+bool low)
 {
struct drm_display_mode *mode = >base.mode;
fixed20_12 a, b, c;
fixed20_12 pclk, request_fifo_depth, tolerable_latency, estimated_width;
fixed20_12 consumption_time, line_time, chunk_time, read_delay_latency;
+   fixed20_12 sclk;
+   u32 selected_sclk;

if (!crtc->base.enabled) {
/* FIXME: wouldn't it better to set priority mark to maximum */
@@ -951,6 +954,18 @@ static void rv515_crtc_bandwidth_compute(struct 
radeon_device *rdev,
return;
}

+   /* rv6xx, rv7xx */
+   if ((rdev->family >= CHIP_RV610) &&
+   (rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled)
+   selected_sclk = radeon_dpm_get_sclk(rdev, low);
+   else
+   selected_sclk = rdev->pm.current_sclk;
+
+   /* sclk in Mhz */
+   a.full = dfixed_const(100);
+   sclk.full = dfixed_const(selected_sclk);
+   sclk.full = dfixed_div(sclk, a);
+
if (crtc->vsc.full > dfixed_const(2))
wm->num_line_pair.full = dfixed_const(2);
else
@@ -1016,7 +1031,7 @@ static void rv515_crtc_bandwidth_compute(struct 
radeon_device *rdev,
 * sclk = system clock(Mhz)
 */
a.full = dfixed_const(600 * 1000);
-   chunk_time.full = dfixed_div(a, rdev->pm.sclk);
+   chunk_time.full = dfixed_div(a, sclk);
read_delay_latency.full = dfixed_const(1000);

/* Determine the worst case latency
@@ -1077,152 +1092,177 @@ static void rv515_crtc_bandwidth_compute(struct 
radeon_device *rdev,
}
 }

-void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
+static void rv515_compute_mode_priority(struct radeon_device *rdev,
+   struct rv515_watermark *wm0,
+   struct rv515_watermark *wm1,
+   struct drm_display_mode *mode0,
+   struct drm_display_mode *mode1,
+   u32 *d1mode_priority_a_cnt,
+   u32 *d2mode_priority_a_cnt)
 {
-   struct drm_display_mode *mode0 = NULL;
-   struct drm_display_mode *mode1 = NULL;
-   struct rv515_watermark wm0;
-   struct rv515_watermark wm1;
-   u32 tmp;
-   u32 d1mode_priority_a_cnt = MODE_PRIORITY_OFF;
-   u32 d2mode_priority_a_cnt = MODE_PRIORITY_OFF;
fixed20_12 priority_mark02, priority_mark12, fill_rate;
fixed20_12 a, b;

-   if (rdev->mode_info.crtcs[0]->base.enabled)
-   mode0 = >mode_info.crtcs[0]->base.mode;
-   if (rdev->mode_info.crtcs[1]->base.enabled)
-   mode1 = >mode_info.crtcs[1]->base.mode;
-   rs690_line_buffer_adjust(rdev, mode0, mode1);
-
-   rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], );
-   rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], );
-
-   tmp = wm0.lb_request_fifo_depth;
-   tmp |= wm1.lb_request_fifo_depth << 16;
-   WREG32(LB_MAX_REQ_OUTSTANDING, tmp);
+   *d1mode_priority_a_cnt = MODE_PRIORITY_OFF;
+   *d2mode_priority_a_cnt = MODE_PRIORITY_OFF;

if (mode0 && mode1) {
-   if (dfixed_trunc(wm0.dbpp) > 64)
-   a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair);
+   if (dfixed_trunc(wm0->dbpp) > 64)
+   a.full = dfixed_div(wm0->dbpp, wm0->num_line_pair);
else
-   a.full = wm0.num_line_pair.full;
-   if (dfixed_trunc(wm1.dbpp) > 64)
-   b.full = dfixed_div(wm1.dbpp, wm1.num_line_pair);
+   a.full = wm0->num_line_pair.full;
+   if (dfixed_trunc(wm1->dbpp) > 64)
+   b.full = dfixed_div(wm1->dbpp, wm1->num_line_pair);
else
-   b.full = wm1.num_line_pair.full;
+   b.full = wm1->num_line_pair.full;
 

[PATCH 070/165] drm/radeon/kms: fix up rs780/rs880 display watermark calc for dpm

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

calculate the low and high watermarks based on the low and high
clocks for the current power state.  The dynamic pm hw will select
the appropriate watermark based on the internal dpm state.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/rs690.c |  291 +++-
 1 files changed, 167 insertions(+), 124 deletions(-)

diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index 55880d5..d8ddfb3 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -248,13 +248,16 @@ struct rs690_watermark {
 };

 static void rs690_crtc_bandwidth_compute(struct radeon_device *rdev,
- struct radeon_crtc *crtc,
- struct rs690_watermark *wm)
+struct radeon_crtc *crtc,
+struct rs690_watermark *wm,
+bool low)
 {
struct drm_display_mode *mode = >base.mode;
fixed20_12 a, b, c;
fixed20_12 pclk, request_fifo_depth, tolerable_latency, estimated_width;
fixed20_12 consumption_time, line_time, chunk_time, read_delay_latency;
+   fixed20_12 sclk, core_bandwidth, max_bandwidth;
+   u32 selected_sclk;

if (!crtc->base.enabled) {
/* FIXME: wouldn't it better to set priority mark to maximum */
@@ -262,6 +265,21 @@ static void rs690_crtc_bandwidth_compute(struct 
radeon_device *rdev,
return;
}

+   if (((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880)) &&
+   (rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled)
+   selected_sclk = radeon_dpm_get_sclk(rdev, low);
+   else
+   selected_sclk = rdev->pm.current_sclk;
+
+   /* sclk in Mhz */
+   a.full = dfixed_const(100);
+   sclk.full = dfixed_const(selected_sclk);
+   sclk.full = dfixed_div(sclk, a);
+
+   /* core_bandwidth = sclk(Mhz) * 16 */
+   a.full = dfixed_const(16);
+   core_bandwidth.full = dfixed_div(rdev->pm.sclk, a);
+
if (crtc->vsc.full > dfixed_const(2))
wm->num_line_pair.full = dfixed_const(2);
else
@@ -322,36 +340,36 @@ static void rs690_crtc_bandwidth_compute(struct 
radeon_device *rdev,
wm->active_time.full = dfixed_div(wm->active_time, a);

/* Maximun bandwidth is the minimun bandwidth of all component */
-   rdev->pm.max_bandwidth = rdev->pm.core_bandwidth;
+   max_bandwidth = core_bandwidth;
if (rdev->mc.igp_sideport_enabled) {
-   if (rdev->pm.max_bandwidth.full > 
rdev->pm.sideport_bandwidth.full &&
+   if (max_bandwidth.full > rdev->pm.sideport_bandwidth.full &&
rdev->pm.sideport_bandwidth.full)
-   rdev->pm.max_bandwidth = rdev->pm.sideport_bandwidth;
+   max_bandwidth = rdev->pm.sideport_bandwidth;
read_delay_latency.full = dfixed_const(370 * 800 * 1000);
read_delay_latency.full = dfixed_div(read_delay_latency,
rdev->pm.igp_sideport_mclk);
} else {
-   if (rdev->pm.max_bandwidth.full > rdev->pm.k8_bandwidth.full &&
+   if (max_bandwidth.full > rdev->pm.k8_bandwidth.full &&
rdev->pm.k8_bandwidth.full)
-   rdev->pm.max_bandwidth = rdev->pm.k8_bandwidth;
-   if (rdev->pm.max_bandwidth.full > rdev->pm.ht_bandwidth.full &&
+   max_bandwidth = rdev->pm.k8_bandwidth;
+   if (max_bandwidth.full > rdev->pm.ht_bandwidth.full &&
rdev->pm.ht_bandwidth.full)
-   rdev->pm.max_bandwidth = rdev->pm.ht_bandwidth;
+   max_bandwidth = rdev->pm.ht_bandwidth;
read_delay_latency.full = dfixed_const(5000);
}

/* sclk = system clocks(ns) = 1000 / max_bandwidth / 16 */
a.full = dfixed_const(16);
-   rdev->pm.sclk.full = dfixed_mul(rdev->pm.max_bandwidth, a);
+   sclk.full = dfixed_mul(max_bandwidth, a);
a.full = dfixed_const(1000);
-   rdev->pm.sclk.full = dfixed_div(a, rdev->pm.sclk);
+   sclk.full = dfixed_div(a, sclk);
/* Determine chunk time
 * ChunkTime = the time it takes the DCP to send one chunk of data
 * to the LB which consists of pipeline delay and inter chunk gap
 * sclk = system clock(ns)
 */
a.full = dfixed_const(256 * 13);
-   chunk_time.full = dfixed_mul(rdev->pm.sclk, a);
+   chunk_time.full = dfixed_mul(sclk, a);
a.full = dfixed_const(10);
chunk_time.full = dfixed_div(chunk_time, a);

@@ -415,175 +433,200 @@ static void rs690_crtc_bandwidth_compute(struct 
radeon_device *rdev,
}
 }

-void rs690_bandwidth_update(struct radeon_device *rdev)
+static void 

[PATCH 069/165] drm/radeon/kms: add common dpm infrastructure

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

This adds the common dpm (dynamic power management)
infrastructure:
- dpm callbacks
- dpm init/fini/suspend/resume
- dpm power state selection

No device specific code is enabled yet.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon.h |  100 +++-
 drivers/gpu/drm/radeon/radeon_drv.c |4 +
 drivers/gpu/drm/radeon/radeon_pm.c  |  496 ++-
 3 files changed, 591 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 6c445f5..c43673c 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -96,6 +96,7 @@ extern int radeon_pcie_gen2;
 extern int radeon_msi;
 extern int radeon_lockup_timeout;
 extern int radeon_fastfb;
+extern int radeon_dpm;

 /*
  * Copy from radeon_drv.h so we don't have to include both and have conflicting
@@ -1048,6 +1049,7 @@ struct radeon_wb {
 enum radeon_pm_method {
PM_METHOD_PROFILE,
PM_METHOD_DYNPM,
+   PM_METHOD_DPM,
 };

 enum radeon_dynpm_state {
@@ -1073,11 +1075,23 @@ enum radeon_voltage_type {
 };

 enum radeon_pm_state_type {
+   /* not used for dpm */
POWER_STATE_TYPE_DEFAULT,
POWER_STATE_TYPE_POWERSAVE,
+   /* user selectable states */
POWER_STATE_TYPE_BATTERY,
POWER_STATE_TYPE_BALANCED,
POWER_STATE_TYPE_PERFORMANCE,
+   /* internal states */
+   POWER_STATE_TYPE_INTERNAL_UVD,
+   POWER_STATE_TYPE_INTERNAL_UVD_SD,
+   POWER_STATE_TYPE_INTERNAL_UVD_HD,
+   POWER_STATE_TYPE_INTERNAL_UVD_HD2,
+   POWER_STATE_TYPE_INTERNAL_UVD_MVC,
+   POWER_STATE_TYPE_INTERNAL_BOOT,
+   POWER_STATE_TYPE_INTERNAL_THERMAL,
+   POWER_STATE_TYPE_INTERNAL_ACPI,
+   POWER_STATE_TYPE_INTERNAL_ULV,
 };

 enum radeon_pm_profile_type {
@@ -1106,12 +1120,16 @@ struct radeon_pm_profile {

 enum radeon_int_thermal_type {
THERMAL_TYPE_NONE,
+   THERMAL_TYPE_EXTERNAL,
+   THERMAL_TYPE_EXTERNAL_GPIO,
THERMAL_TYPE_RV6XX,
THERMAL_TYPE_RV770,
+   THERMAL_TYPE_ADT7473_WITH_INTERNAL,
THERMAL_TYPE_EVERGREEN,
THERMAL_TYPE_SUMO,
THERMAL_TYPE_NI,
THERMAL_TYPE_SI,
+   THERMAL_TYPE_EMC2103_WITH_INTERNAL,
THERMAL_TYPE_CI,
 };

@@ -1166,6 +1184,60 @@ struct radeon_power_state {
  */
 #define RADEON_MODE_OVERCLOCK_MARGIN 500 /* 5 MHz */

+struct radeon_ps {
+   u32 caps; /* vbios flags */
+   u32 class; /* vbios flags */
+   u32 class2; /* vbios flags */
+   /* UVD clocks */
+   u32 vclk;
+   u32 dclk;
+   /* asic priv */
+   void *ps_priv;
+};
+
+struct radeon_dpm_thermal {
+   /* thermal interrupt work */
+   struct work_struct work;
+   /* low temperature threshold */
+   intmin_temp;
+   /* high temperature threshold */
+   intmax_temp;
+   /* was interrupt low to high or high to low */
+   bool   high_to_low;
+};
+
+struct radeon_dpm {
+   struct radeon_ps*ps;
+   /* number of valid power states */
+   int num_ps;
+   /* current power state that is active */
+   struct radeon_ps*current_ps;
+   /* requested power state */
+   struct radeon_ps*requested_ps;
+   /* boot up power state */
+   struct radeon_ps*boot_ps;
+   /* default uvd power state */
+   struct radeon_ps*uvd_ps;
+   enum radeon_pm_state_type state;
+   enum radeon_pm_state_type user_state;
+   u32 platform_caps;
+   u32 voltage_response_time;
+   u32 backbias_response_time;
+   void*priv;
+   u32 new_active_crtcs;
+   int new_active_crtc_count;
+   u32 current_active_crtcs;
+   int current_active_crtc_count;
+   /* special states active */
+   boolthermal_active;
+   /* thermal handling */
+   struct radeon_dpm_thermal thermal;
+};
+
+void radeon_dpm_enable_power_state(struct radeon_device *rdev,
+   enum radeon_pm_state_type dpm_state);
+
+
 struct radeon_pm {
struct mutexmutex;
/* write locked while reprogramming mclk */
@@ -1219,6 +1291,9 @@ struct radeon_pm {
/* internal thermal controller on rv6xx+ */
enum radeon_int_thermal_type int_thermal_type;
struct device   *int_hwmon_dev;
+   /* dpm */
+   booldpm_enabled;
+   struct radeon_dpm   dpm;
 };

 int radeon_pm_get_type_index(struct radeon_device *rdev,
@@ -1416,7 +1491,7 @@ struct radeon_asic {
bool (*sense)(struct radeon_device *rdev, enum radeon_hpd_id 
hpd);
void (*set_polarity)(struct radeon_device *rdev, enum 

[PATCH 068/165] drm/radeon/kms: add new asic struct for rv6xx (v3)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Has a different dpm controller than r600.

v2: rebase on gpu reset changes
v3: rebase on get_xclk changes

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_asic.c |   96 --
 1 files changed, 91 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index 5736377..d9c8e9a 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1025,6 +1025,93 @@ static struct radeon_asic r600_asic = {
},
 };

+static struct radeon_asic rv6xx_asic = {
+   .init = _init,
+   .fini = _fini,
+   .suspend = _suspend,
+   .resume = _resume,
+   .vga_set_state = _vga_set_state,
+   .asic_reset = _asic_reset,
+   .ioctl_wait_idle = r600_ioctl_wait_idle,
+   .gui_idle = _gui_idle,
+   .mc_wait_for_idle = _mc_wait_for_idle,
+   .get_xclk = _get_xclk,
+   .get_gpu_clock_counter = _get_gpu_clock_counter,
+   .gart = {
+   .tlb_flush = _pcie_gart_tlb_flush,
+   .set_page = _gart_set_page,
+   },
+   .ring = {
+   [RADEON_RING_TYPE_GFX_INDEX] = {
+   .ib_execute = _ring_ib_execute,
+   .emit_fence = _fence_ring_emit,
+   .emit_semaphore = _semaphore_ring_emit,
+   .cs_parse = _cs_parse,
+   .ring_test = _ring_test,
+   .ib_test = _ib_test,
+   .is_lockup = _gfx_is_lockup,
+   },
+   [R600_RING_TYPE_DMA_INDEX] = {
+   .ib_execute = _dma_ring_ib_execute,
+   .emit_fence = _dma_fence_ring_emit,
+   .emit_semaphore = _dma_semaphore_ring_emit,
+   .cs_parse = _dma_cs_parse,
+   .ring_test = _dma_ring_test,
+   .ib_test = _dma_ib_test,
+   .is_lockup = _dma_is_lockup,
+   }
+   },
+   .irq = {
+   .set = _irq_set,
+   .process = _irq_process,
+   },
+   .display = {
+   .bandwidth_update = _bandwidth_update,
+   .get_vblank_counter = _get_vblank_counter,
+   .wait_for_vblank = _wait_for_vblank,
+   .set_backlight_level = _set_backlight_level,
+   .get_backlight_level = _get_backlight_level,
+   },
+   .copy = {
+   .blit = _copy_blit,
+   .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+   .dma = _copy_dma,
+   .dma_ring_index = R600_RING_TYPE_DMA_INDEX,
+   .copy = _copy_dma,
+   .copy_ring_index = R600_RING_TYPE_DMA_INDEX,
+   },
+   .surface = {
+   .set_reg = r600_set_surface_reg,
+   .clear_reg = r600_clear_surface_reg,
+   },
+   .hpd = {
+   .init = _hpd_init,
+   .fini = _hpd_fini,
+   .sense = _hpd_sense,
+   .set_polarity = _hpd_set_polarity,
+   },
+   .pm = {
+   .misc = _pm_misc,
+   .prepare = _pm_prepare,
+   .finish = _pm_finish,
+   .init_profile = _pm_init_profile,
+   .get_dynpm_state = _pm_get_dynpm_state,
+   .get_engine_clock = _atom_get_engine_clock,
+   .set_engine_clock = _atom_set_engine_clock,
+   .get_memory_clock = _atom_get_memory_clock,
+   .set_memory_clock = _atom_set_memory_clock,
+   .get_pcie_lanes = _get_pcie_lanes,
+   .set_pcie_lanes = _set_pcie_lanes,
+   .set_clock_gating = NULL,
+   .get_temperature = _get_temp,
+   },
+   .pflip = {
+   .pre_page_flip = _pre_page_flip,
+   .page_flip = _page_flip,
+   .post_page_flip = _post_page_flip,
+   },
+};
+
 static struct radeon_asic rs780_asic = {
.init = _init,
.fini = _fini,
@@ -2286,16 +2373,15 @@ int radeon_asic_init(struct radeon_device *rdev)
rdev->asic = _asic;
break;
case CHIP_R600:
+   rdev->asic = _asic;
+   break;
case CHIP_RV610:
case CHIP_RV630:
case CHIP_RV620:
case CHIP_RV635:
case CHIP_RV670:
-   rdev->asic = _asic;
-   if (rdev->family == CHIP_R600)
-   rdev->has_uvd = false;
-   else
-   rdev->has_uvd = true;
+   rdev->asic = _asic;
+   rdev->has_uvd = true;
break;
case CHIP_RS780:
case CHIP_RS880:
-- 
1.7.7.5



[PATCH 067/165] drm/radeon/kms: add atom helper functions for dpm (v3)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

dpm needs access to atombios data and command tables
for setup and calculation of a number of parameters.

v2: endian fix
v3: fix mc reg table bug

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon.h  |   33 ++
 drivers/gpu/drm/radeon/radeon_atombios.c |  660 +-
 drivers/gpu/drm/radeon/radeon_mode.h |   57 +++
 3 files changed, 743 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index f4cb768..6c445f5 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -219,6 +219,39 @@ int radeon_atom_get_clock_dividers(struct radeon_device 
*rdev,
   bool strobe_mode,
   struct atom_clock_dividers *dividers);
 void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 
voltage_type);
+int radeon_atom_get_voltage_gpio_settings(struct radeon_device *rdev,
+ u16 voltage_level, u8 voltage_type,
+ u32 *gpio_value, u32 *gpio_mask);
+void radeon_atom_set_engine_dram_timings(struct radeon_device *rdev,
+u32 eng_clock, u32 mem_clock);
+int radeon_atom_get_voltage_step(struct radeon_device *rdev,
+u8 voltage_type, u16 *voltage_step);
+int radeon_atom_round_to_true_voltage(struct radeon_device *rdev,
+ u8 voltage_type,
+ u16 nominal_voltage,
+ u16 *true_voltage);
+int radeon_atom_get_min_voltage(struct radeon_device *rdev,
+   u8 voltage_type, u16 *min_voltage);
+int radeon_atom_get_max_voltage(struct radeon_device *rdev,
+   u8 voltage_type, u16 *max_voltage);
+int radeon_atom_get_voltage_table(struct radeon_device *rdev,
+ u8 voltage_type,
+ struct atom_voltage_table *voltage_table);
+bool radeon_atom_is_voltage_gpio(struct radeon_device *rdev, u8 voltage_type);
+void radeon_atom_update_memory_dll(struct radeon_device *rdev,
+  u32 mem_clock);
+void radeon_atom_set_ac_timing(struct radeon_device *rdev,
+  u32 mem_clock);
+int radeon_atom_init_mc_reg_table(struct radeon_device *rdev,
+ u8 module_index,
+ struct atom_mc_reg_table *reg_table);
+int radeon_atom_get_memory_info(struct radeon_device *rdev,
+   u8 module_index, struct atom_memory_info 
*mem_info);
+int radeon_atom_get_mclk_range_table(struct radeon_device *rdev,
+bool gddr5, u8 module_index,
+struct atom_memory_clock_range_table 
*mclk_range_table);
+int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type,
+u16 voltage_id, u16 *voltage);
 void rs690_pm_info(struct radeon_device *rdev);
 extern void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw,
unsigned *bankh, unsigned *mtaspect,
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c 
b/drivers/gpu/drm/radeon/radeon_atombios.c
index bf3b924..90401fd 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -56,10 +56,6 @@ extern void
 radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum,
  uint32_t supported_device);

-/* local */
-static int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 
voltage_type,
-   u16 voltage_id, u16 *voltage);
-
 union atom_supported_devices {
struct _ATOM_SUPPORTED_DEVICES_INFO info;
struct _ATOM_SUPPORTED_DEVICES_INFO_2 info_2;
@@ -1516,6 +1512,10 @@ bool radeon_atombios_get_asic_ss_info(struct 
radeon_device *rdev,

le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadSpectrumPercentage);
ss->type = 
ss_info->info_2.asSpreadSpectrum[i].ucSpreadSpectrumMode;
ss->rate = 
le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadRateIn10Hz);
+   if ((crev == 2) &&
+   ((id == ASIC_INTERNAL_ENGINE_SS) ||
+(id == ASIC_INTERNAL_MEMORY_SS)))
+   ss->rate /= 100;
return true;
}
}
@@ -1530,6 +1530,9 @@ bool radeon_atombios_get_asic_ss_info(struct 
radeon_device *rdev,
 

[PATCH 066/165] drm/radeon: properly set up the RLC on ON/LN/TN (v3)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

This is required for certain advanced functionality.

v2: save/restore list takes dword offsets
v3: rebase on gpu reset changes

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/clearstate_cayman.h| 1081 +
 drivers/gpu/drm/radeon/clearstate_defs.h  |   44 +
 drivers/gpu/drm/radeon/clearstate_evergreen.h | 1080 
 drivers/gpu/drm/radeon/evergreen.c|  339 
 drivers/gpu/drm/radeon/evergreend.h   |   19 +
 drivers/gpu/drm/radeon/ni.c   |  141 -
 drivers/gpu/drm/radeon/r600.c |   43 +-
 drivers/gpu/drm/radeon/r600d.h|4 -
 drivers/gpu/drm/radeon/radeon.h   |   13 +-
 9 files changed, 2721 insertions(+), 43 deletions(-)
 create mode 100644 drivers/gpu/drm/radeon/clearstate_cayman.h
 create mode 100644 drivers/gpu/drm/radeon/clearstate_defs.h
 create mode 100644 drivers/gpu/drm/radeon/clearstate_evergreen.h

diff --git a/drivers/gpu/drm/radeon/clearstate_cayman.h 
b/drivers/gpu/drm/radeon/clearstate_cayman.h
new file mode 100644
index 000..c003394
--- /dev/null
+++ b/drivers/gpu/drm/radeon/clearstate_cayman.h
@@ -0,0 +1,1081 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+static const u32 SECT_CONTEXT_def_1[] =
+{
+0x, // DB_RENDER_CONTROL
+0x, // DB_COUNT_CONTROL
+0x, // DB_DEPTH_VIEW
+0x, // DB_RENDER_OVERRIDE
+0x, // DB_RENDER_OVERRIDE2
+0x, // DB_HTILE_DATA_BASE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0x, // DB_STENCIL_CLEAR
+0x, // DB_DEPTH_CLEAR
+0x, // PA_SC_SCREEN_SCISSOR_TL
+0x40004000, // PA_SC_SCREEN_SCISSOR_BR
+0, // HOLE
+0x, // DB_DEPTH_INFO
+0x, // DB_Z_INFO
+0x, // DB_STENCIL_INFO
+0x, // DB_Z_READ_BASE
+0x, // DB_STENCIL_READ_BASE
+0x, // DB_Z_WRITE_BASE
+0x, // DB_STENCIL_WRITE_BASE
+0x, // DB_DEPTH_SIZE
+0x, // DB_DEPTH_SLICE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0, // HOLE
+0x, // SQ_ALU_CONST_BUFFER_SIZE_PS_0
+0x, // SQ_ALU_CONST_BUFFER_SIZE_PS_1
+0x, // SQ_ALU_CONST_BUFFER_SIZE_PS_2
+0x, // SQ_ALU_CONST_BUFFER_SIZE_PS_3
+0x, // SQ_ALU_CONST_BUFFER_SIZE_PS_4
+0x, // SQ_ALU_CONST_BUFFER_SIZE_PS_5
+0x, // SQ_ALU_CONST_BUFFER_SIZE_PS_6
+0x, // SQ_ALU_CONST_BUFFER_SIZE_PS_7
+0x, // SQ_ALU_CONST_BUFFER_SIZE_PS_8
+0x, // SQ_ALU_CONST_BUFFER_SIZE_PS_9
+0x, // SQ_ALU_CONST_BUFFER_SIZE_PS_10
+0x, // SQ_ALU_CONST_BUFFER_SIZE_PS_11
+0x, // SQ_ALU_CONST_BUFFER_SIZE_PS_12
+0x, // SQ_ALU_CONST_BUFFER_SIZE_PS_13
+0x, // SQ_ALU_CONST_BUFFER_SIZE_PS_14
+0x, // SQ_ALU_CONST_BUFFER_SIZE_PS_15
+0x, // SQ_ALU_CONST_BUFFER_SIZE_VS_0
+

[PATCH 065/165] drm/radeon/kms: move ucode defines to a separate header

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Avoids confusion and duplication.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/evergreen.c|4 +--
 drivers/gpu/drm/radeon/ni.c   |   13 +
 drivers/gpu/drm/radeon/r600.c |   25 +
 drivers/gpu/drm/radeon/radeon_ucode.h |   47 +
 4 files changed, 56 insertions(+), 33 deletions(-)
 create mode 100644 drivers/gpu/drm/radeon/radeon_ucode.h

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 9009dd4..6b559cb5 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -33,9 +33,7 @@
 #include "avivod.h"
 #include "evergreen_reg.h"
 #include "evergreen_blit_shaders.h"
-
-#define EVERGREEN_PFP_UCODE_SIZE 1120
-#define EVERGREEN_PM4_UCODE_SIZE 1376
+#include "radeon_ucode.h"

 static const u32 crtc_offsets[6] =
 {
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index f889461..9284346 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -33,6 +33,7 @@
 #include "atom.h"
 #include "ni_reg.h"
 #include "cayman_blit_shaders.h"
+#include "radeon_ucode.h"

 extern bool evergreen_is_display_hung(struct radeon_device *rdev);
 extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev);
@@ -47,18 +48,6 @@ extern void evergreen_pcie_gen2_enable(struct radeon_device 
*rdev);
 extern void si_rlc_fini(struct radeon_device *rdev);
 extern int si_rlc_init(struct radeon_device *rdev);

-#define EVERGREEN_PFP_UCODE_SIZE 1120
-#define EVERGREEN_PM4_UCODE_SIZE 1376
-#define EVERGREEN_RLC_UCODE_SIZE 768
-#define BTC_MC_UCODE_SIZE 6024
-
-#define CAYMAN_PFP_UCODE_SIZE 2176
-#define CAYMAN_PM4_UCODE_SIZE 2176
-#define CAYMAN_RLC_UCODE_SIZE 1024
-#define CAYMAN_MC_UCODE_SIZE 6037
-
-#define ARUBA_RLC_UCODE_SIZE 1536
-
 /* Firmware Names */
 MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
 MODULE_FIRMWARE("radeon/BARTS_me.bin");
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 6948eb8..6089261 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -38,18 +38,7 @@
 #include "r600d.h"
 #include "atom.h"
 #include "avivod.h"
-
-#define PFP_UCODE_SIZE 576
-#define PM4_UCODE_SIZE 1792
-#define RLC_UCODE_SIZE 768
-#define R700_PFP_UCODE_SIZE 848
-#define R700_PM4_UCODE_SIZE 1360
-#define R700_RLC_UCODE_SIZE 1024
-#define EVERGREEN_PFP_UCODE_SIZE 1120
-#define EVERGREEN_PM4_UCODE_SIZE 1376
-#define EVERGREEN_RLC_UCODE_SIZE 768
-#define CAYMAN_RLC_UCODE_SIZE 1024
-#define ARUBA_RLC_UCODE_SIZE 1536
+#include "radeon_ucode.h"

 /* Firmware Names */
 MODULE_FIRMWARE("radeon/R600_pfp.bin");
@@ -2246,9 +2235,9 @@ int r600_init_microcode(struct radeon_device *rdev)
me_req_size = R700_PM4_UCODE_SIZE * 4;
rlc_req_size = R700_RLC_UCODE_SIZE * 4;
} else {
-   pfp_req_size = PFP_UCODE_SIZE * 4;
-   me_req_size = PM4_UCODE_SIZE * 12;
-   rlc_req_size = RLC_UCODE_SIZE * 4;
+   pfp_req_size = R600_PFP_UCODE_SIZE * 4;
+   me_req_size = R600_PM4_UCODE_SIZE * 12;
+   rlc_req_size = R600_RLC_UCODE_SIZE * 4;
}

DRM_INFO("Loading %s Microcode\n", chip_name);
@@ -2331,13 +2320,13 @@ static int r600_cp_load_microcode(struct radeon_device 
*rdev)

fw_data = (const __be32 *)rdev->me_fw->data;
WREG32(CP_ME_RAM_WADDR, 0);
-   for (i = 0; i < PM4_UCODE_SIZE * 3; i++)
+   for (i = 0; i < R600_PM4_UCODE_SIZE * 3; i++)
WREG32(CP_ME_RAM_DATA,
   be32_to_cpup(fw_data++));

fw_data = (const __be32 *)rdev->pfp_fw->data;
WREG32(CP_PFP_UCODE_ADDR, 0);
-   for (i = 0; i < PFP_UCODE_SIZE; i++)
+   for (i = 0; i < R600_PFP_UCODE_SIZE; i++)
WREG32(CP_PFP_UCODE_DATA,
   be32_to_cpup(fw_data++));

@@ -3839,7 +3828,7 @@ static int r600_rlc_init(struct radeon_device *rdev)
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
}
} else {
-   for (i = 0; i < RLC_UCODE_SIZE; i++) {
+   for (i = 0; i < R600_RLC_UCODE_SIZE; i++) {
WREG32(RLC_UCODE_ADDR, i);
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
}
diff --git a/drivers/gpu/drm/radeon/radeon_ucode.h 
b/drivers/gpu/drm/radeon/radeon_ucode.h
new file mode 100644
index 000..d2642b0
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_ucode.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the 

[PATCH 064/165] drm/radeon: add support for thermal sensor on tn

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/ni.c  |8 
 drivers/gpu/drm/radeon/nid.h |3 +++
 drivers/gpu/drm/radeon/radeon_asic.c |1 +
 drivers/gpu/drm/radeon/radeon_asic.h |1 +
 4 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 8458330..f889461 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -692,6 +692,14 @@ out:
return err;
 }

+int tn_get_temp(struct radeon_device *rdev)
+{
+   u32 temp = RREG32_SMC(TN_CURRENT_GNB_TEMP) & 0x7ff;
+   int actual_temp = (temp / 8) - 49;
+
+   return actual_temp * 1000;
+}
+
 /*
  * Core functions
  */
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
index e226faf..7b8da52 100644
--- a/drivers/gpu/drm/radeon/nid.h
+++ b/drivers/gpu/drm/radeon/nid.h
@@ -489,6 +489,9 @@
 #   define CACHE_FLUSH_AND_INV_EVENT_TS (0x14 << 0)
 #   define CACHE_FLUSH_AND_INV_EVENT(0x16 << 0)

+/* TN SMU registers */
+#defineTN_CURRENT_GNB_TEMP 0x1F390
+
 /*
  * UVD
  */
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index f127ea2..5736377 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1783,6 +1783,7 @@ static struct radeon_asic trinity_asic = {
.set_pcie_lanes = NULL,
.set_clock_gating = NULL,
.set_uvd_clocks = _set_uvd_clocks,
+   .get_temperature = _get_temp,
},
.pflip = {
.pre_page_flip = _pre_page_flip,
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h 
b/drivers/gpu/drm/radeon/radeon_asic.h
index f1dcb07..8507cae 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -486,6 +486,7 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, 
bool enable);
 void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct 
drm_display_mode *mode);
 int evergreen_get_temp(struct radeon_device *rdev);
 int sumo_get_temp(struct radeon_device *rdev);
+int tn_get_temp(struct radeon_device *rdev);

 /*
  * cayman
-- 
1.7.7.5



[PATCH 063/165] drm/radeon: make get_temperature functions a callback

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon.h  |7 ++-
 drivers/gpu/drm/radeon/radeon_asic.c |8 
 drivers/gpu/drm/radeon/radeon_asic.h |5 +
 drivers/gpu/drm/radeon/radeon_pm.c   |   26 --
 4 files changed, 19 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index e73c972..40053c8 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -220,11 +220,6 @@ int radeon_atom_get_clock_dividers(struct radeon_device 
*rdev,
   struct atom_clock_dividers *dividers);
 void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 
voltage_type);
 void rs690_pm_info(struct radeon_device *rdev);
-extern int rv6xx_get_temp(struct radeon_device *rdev);
-extern int rv770_get_temp(struct radeon_device *rdev);
-extern int evergreen_get_temp(struct radeon_device *rdev);
-extern int sumo_get_temp(struct radeon_device *rdev);
-extern int si_get_temp(struct radeon_device *rdev);
 extern void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw,
unsigned *bankh, unsigned *mtaspect,
unsigned *tile_split);
@@ -1396,6 +1391,7 @@ struct radeon_asic {
void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes);
void (*set_clock_gating)(struct radeon_device *rdev, int 
enable);
int (*set_uvd_clocks)(struct radeon_device *rdev, u32 vclk, u32 
dclk);
+   int (*get_temperature)(struct radeon_device *rdev);
} pm;
/* pageflipping */
struct {
@@ -2065,6 +2061,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t 
v);
 #define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->pm.set_pcie_lanes((rdev), 
(l))
 #define radeon_set_clock_gating(rdev, e) 
(rdev)->asic->pm.set_clock_gating((rdev), (e))
 #define radeon_set_uvd_clocks(rdev, v, d) 
(rdev)->asic->pm.set_uvd_clocks((rdev), (v), (d))
+#define radeon_get_temperature(rdev) (rdev)->asic->pm.get_temperature((rdev))
 #define radeon_set_surface_reg(rdev, r, f, p, o, s) 
((rdev)->asic->surface.set_reg((rdev), (r), (f), (p), (o), (s)))
 #define radeon_clear_surface_reg(rdev, r) 
((rdev)->asic->surface.clear_reg((rdev), (r)))
 #define radeon_bandwidth_update(rdev) 
(rdev)->asic->display.bandwidth_update((rdev))
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index d60adb3..f127ea2 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1016,6 +1016,7 @@ static struct radeon_asic r600_asic = {
.get_pcie_lanes = _get_pcie_lanes,
.set_pcie_lanes = _set_pcie_lanes,
.set_clock_gating = NULL,
+   .get_temperature = _get_temp,
},
.pflip = {
.pre_page_flip = _pre_page_flip,
@@ -1104,6 +1105,7 @@ static struct radeon_asic rs780_asic = {
.get_pcie_lanes = NULL,
.set_pcie_lanes = NULL,
.set_clock_gating = NULL,
+   .get_temperature = _get_temp,
},
.pflip = {
.pre_page_flip = _pre_page_flip,
@@ -1202,6 +1204,7 @@ static struct radeon_asic rv770_asic = {
.set_pcie_lanes = _set_pcie_lanes,
.set_clock_gating = _atom_set_clock_gating,
.set_uvd_clocks = _set_uvd_clocks,
+   .get_temperature = _get_temp,
},
.pflip = {
.pre_page_flip = _pre_page_flip,
@@ -1300,6 +1303,7 @@ static struct radeon_asic evergreen_asic = {
.set_pcie_lanes = _set_pcie_lanes,
.set_clock_gating = NULL,
.set_uvd_clocks = _set_uvd_clocks,
+   .get_temperature = _get_temp,
},
.pflip = {
.pre_page_flip = _pre_page_flip,
@@ -1398,6 +1402,7 @@ static struct radeon_asic sumo_asic = {
.set_pcie_lanes = NULL,
.set_clock_gating = NULL,
.set_uvd_clocks = _set_uvd_clocks,
+   .get_temperature = _get_temp,
},
.pflip = {
.pre_page_flip = _pre_page_flip,
@@ -1496,6 +1501,7 @@ static struct radeon_asic btc_asic = {
.set_pcie_lanes = _set_pcie_lanes,
.set_clock_gating = NULL,
.set_uvd_clocks = _set_uvd_clocks,
+   .get_temperature = _get_temp,
},
.pflip = {
.pre_page_flip = _pre_page_flip,
@@ -1637,6 +1643,7 @@ static struct radeon_asic cayman_asic = {
.set_pcie_lanes = _set_pcie_lanes,
.set_clock_gating = NULL,
.set_uvd_clocks = _set_uvd_clocks,
+   .get_temperature = _get_temp,
},
.pflip = {
.pre_page_flip = 

[PATCH 062/165] drm/radeon/evergreen: add indirect register accessors for CG registers

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/evergreen_reg.h |3 +++
 drivers/gpu/drm/radeon/radeon.h|   17 +
 2 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h 
b/drivers/gpu/drm/radeon/evergreen_reg.h
index 50948ac..76630c6b 100644
--- a/drivers/gpu/drm/radeon/evergreen_reg.h
+++ b/drivers/gpu/drm/radeon/evergreen_reg.h
@@ -44,6 +44,9 @@
 #define EVERGREEN_AUDIO_PLL1_DIV   0x5b4
 #define EVERGREEN_AUDIO_PLL1_UNK   0x5bc

+#define EVERGREEN_CG_IND_ADDR   0x8f8
+#define EVERGREEN_CG_IND_DATA   0x8fc
+
 #define EVERGREEN_AUDIO_ENABLE 0x5e78
 #define EVERGREEN_AUDIO_VENDOR_ID  0x5ec0

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 0814aa7..e73c972 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1853,6 +1853,8 @@ void cik_mm_wdoorbell(struct radeon_device *rdev, u32 
offset, u32 v);
 #define WREG32_SMC(reg, v) tn_smc_wreg(rdev, (reg), (v))
 #define RREG32_RCU(reg) r600_rcu_rreg(rdev, (reg))
 #define WREG32_RCU(reg, v) r600_rcu_wreg(rdev, (reg), (v))
+#define RREG32_CG(reg) eg_cg_rreg(rdev, (reg))
+#define WREG32_CG(reg, v) eg_cg_wreg(rdev, (reg), (v))
 #define WREG32_P(reg, val, mask)   \
do {\
uint32_t tmp_ = RREG32(reg);\
@@ -1924,6 +1926,21 @@ static inline void r600_rcu_wreg(struct radeon_device 
*rdev, u32 reg, u32 v)
WREG32(R600_RCU_DATA, (v));
 }

+static inline u32 eg_cg_rreg(struct radeon_device *rdev, u32 reg)
+{
+   u32 r;
+
+   WREG32(EVERGREEN_CG_IND_ADDR, ((reg) & 0x));
+   r = RREG32(EVERGREEN_CG_IND_DATA);
+   return r;
+}
+
+static inline void eg_cg_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+   WREG32(EVERGREEN_CG_IND_ADDR, ((reg) & 0x));
+   WREG32(EVERGREEN_CG_IND_DATA, (v));
+}
+
 void r100_pll_errata_after_index(struct radeon_device *rdev);


-- 
1.7.7.5



[PATCH 061/165] drm/radeon/kms: add accessors for RCU indirect space

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/evergreen.c |6 ++
 drivers/gpu/drm/radeon/r600_reg.h  |3 +++
 drivers/gpu/drm/radeon/radeon.h|   17 +
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 0f89ce3..9009dd4 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3120,10 +3120,8 @@ static void evergreen_gpu_init(struct radeon_device 
*rdev)
u32 efuse_straps_4;
u32 efuse_straps_3;

-   WREG32(RCU_IND_INDEX, 0x204);
-   efuse_straps_4 = RREG32(RCU_IND_DATA);
-   WREG32(RCU_IND_INDEX, 0x203);
-   efuse_straps_3 = RREG32(RCU_IND_DATA);
+   efuse_straps_4 = RREG32_RCU(0x204);
+   efuse_straps_3 = RREG32_RCU(0x203);
tmp = (((efuse_straps_4 & 0xf) << 4) |
  ((efuse_straps_3 & 0xf000) >> 28));
} else {
diff --git a/drivers/gpu/drm/radeon/r600_reg.h 
b/drivers/gpu/drm/radeon/r600_reg.h
index 909219b..58c86cc 100644
--- a/drivers/gpu/drm/radeon/r600_reg.h
+++ b/drivers/gpu/drm/radeon/r600_reg.h
@@ -31,6 +31,9 @@
 #define R600_PCIE_PORT_INDEX0x0038
 #define R600_PCIE_PORT_DATA 0x003c

+#define R600_RCU_INDEX  0x0100
+#define R600_RCU_DATA   0x0104
+
 #define R600_MC_VM_FB_LOCATION 0x2180
 #defineR600_MC_FB_BASE_MASK0x
 #defineR600_MC_FB_BASE_SHIFT   0
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 83f62aa..0814aa7 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1851,6 +1851,8 @@ void cik_mm_wdoorbell(struct radeon_device *rdev, u32 
offset, u32 v);
 #define WREG32_PCIE_PORT(reg, v) rdev->pciep_wreg(rdev, (reg), (v))
 #define RREG32_SMC(reg) tn_smc_rreg(rdev, (reg))
 #define WREG32_SMC(reg, v) tn_smc_wreg(rdev, (reg), (v))
+#define RREG32_RCU(reg) r600_rcu_rreg(rdev, (reg))
+#define WREG32_RCU(reg, v) r600_rcu_wreg(rdev, (reg), (v))
 #define WREG32_P(reg, val, mask)   \
do {\
uint32_t tmp_ = RREG32(reg);\
@@ -1907,6 +1909,21 @@ static inline void tn_smc_wreg(struct radeon_device 
*rdev, u32 reg, u32 v)
WREG32(TN_SMC_IND_DATA_0, (v));
 }

+static inline u32 r600_rcu_rreg(struct radeon_device *rdev, u32 reg)
+{
+   u32 r;
+
+   WREG32(R600_RCU_INDEX, ((reg) & 0x1fff));
+   r = RREG32(R600_RCU_DATA);
+   return r;
+}
+
+static inline void r600_rcu_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+   WREG32(R600_RCU_INDEX, ((reg) & 0x1fff));
+   WREG32(R600_RCU_DATA, (v));
+}
+
 void r100_pll_errata_after_index(struct radeon_device *rdev);


-- 
1.7.7.5



[PATCH 060/165] drm/radeon: add current KB pci ids

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 include/drm/drm_pciids.h |   16 
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h
index 23f89df..34efaf6 100644
--- a/include/drm/drm_pciids.h
+++ b/include/drm/drm_pciids.h
@@ -588,6 +588,22 @@
{0x1002, 0x9808, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
{0x1002, 0x9809, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
{0x1002, 0x980A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+   {0x1002, 0x9830, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_KABINI|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+   {0x1002, 0x9831, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+   {0x1002, 0x9832, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_KABINI|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+   {0x1002, 0x9833, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+   {0x1002, 0x9834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_KABINI|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+   {0x1002, 0x9835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+   {0x1002, 0x9836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_KABINI|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+   {0x1002, 0x9837, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+   {0x1002, 0x9838, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_KABINI|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+   {0x1002, 0x9839, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_KABINI|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+   {0x1002, 0x983a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+   {0x1002, 0x983b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_KABINI|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+   {0x1002, 0x983c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+   {0x1002, 0x983d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+   {0x1002, 0x983e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+   {0x1002, 0x983f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
{0x1002, 0x9900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
{0x1002, 0x9901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
{0x1002, 0x9903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
-- 
1.7.7.5



[PATCH 059/165] drm/radeon: add current Bonaire PCI ids

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 include/drm/drm_pciids.h |8 
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h
index bb1bc48..23f89df 100644
--- a/include/drm/drm_pciids.h
+++ b/include/drm/drm_pciids.h
@@ -152,6 +152,14 @@
{0x1002, 0x6621, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_OLAND|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6623, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_OLAND|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6631, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_OLAND|RADEON_NEW_MEMMAP}, \
+   {0x1002, 0x6640, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_BONAIRE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+   {0x1002, 0x6641, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_BONAIRE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+   {0x1002, 0x6649, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \
+   {0x1002, 0x6650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \
+   {0x1002, 0x6651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \
+   {0x1002, 0x6658, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \
+   {0x1002, 0x665c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \
+   {0x1002, 0x665d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6664, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
-- 
1.7.7.5



[PATCH 058/165] drm/radeon: add cik tile mode array query

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/cik.c|4 
 drivers/gpu/drm/radeon/radeon.h |1 +
 drivers/gpu/drm/radeon/radeon_drv.c |3 ++-
 drivers/gpu/drm/radeon/radeon_kms.c |   14 +++---
 4 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index e899c44..2cf3521 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -1059,6 +1059,7 @@ static void cik_tiling_mode_table_init(struct 
radeon_device *rdev)
gb_tile_moden = 0;
break;
}
+   rdev->config.cik.tile_mode_array[reg_offset] = 
gb_tile_moden;
WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
}
for (reg_offset = 0; reg_offset < 
num_secondary_tile_mode_states; reg_offset++) {
@@ -1277,6 +1278,7 @@ static void cik_tiling_mode_table_init(struct 
radeon_device *rdev)
gb_tile_moden = 0;
break;
}
+   rdev->config.cik.tile_mode_array[reg_offset] = 
gb_tile_moden;
WREG32(GB_TILE_MODE0 + (reg_offset * 4), 
gb_tile_moden);
}
} else if (num_rbs < 4) {
@@ -1402,6 +1404,7 @@ static void cik_tiling_mode_table_init(struct 
radeon_device *rdev)
gb_tile_moden = 0;
break;
}
+   rdev->config.cik.tile_mode_array[reg_offset] = 
gb_tile_moden;
WREG32(GB_TILE_MODE0 + (reg_offset * 4), 
gb_tile_moden);
}
}
@@ -1619,6 +1622,7 @@ static void cik_tiling_mode_table_init(struct 
radeon_device *rdev)
gb_tile_moden = 0;
break;
}
+   rdev->config.cik.tile_mode_array[reg_offset] = 
gb_tile_moden;
WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
}
for (reg_offset = 0; reg_offset < 
num_secondary_tile_mode_states; reg_offset++) {
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index d40d506..83f62aa 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1588,6 +1588,7 @@ struct cik_asic {
unsigned multi_gpu_tile_size;

unsigned tile_config;
+   uint32_t tile_mode_array[32];
 };

 union radeon_asic_config {
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c 
b/drivers/gpu/drm/radeon/radeon_drv.c
index 094e7e5..02709e4 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -74,9 +74,10 @@
  *   2.31.0 - Add fastfb support for rs690
  *   2.32.0 - new info request for rings working
  *   2.33.0 - Add SI tiling mode array query
+ *   2.34.0 - Add CIK tiling mode array query
  */
 #define KMS_DRIVER_MAJOR   2
-#define KMS_DRIVER_MINOR   33
+#define KMS_DRIVER_MINOR   34
 #define KMS_DRIVER_PATCHLEVEL  0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c 
b/drivers/gpu/drm/radeon/radeon_kms.c
index c650228..49ff3d1 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -423,15 +423,15 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
break;
case RADEON_INFO_SI_TILE_MODE_ARRAY:
if (rdev->family >= CHIP_BONAIRE) {
-   DRM_DEBUG_KMS("tile mode array is not implemented 
yet\n");
+   value = rdev->config.cik.tile_mode_array;
+   value_size = sizeof(uint32_t)*32;
+   } else if (rdev->family >= CHIP_TAHITI) {
+   value = rdev->config.si.tile_mode_array;
+   value_size = sizeof(uint32_t)*32;
+   } else {
+   DRM_DEBUG_KMS("tile mode array is si+ only!\n");
return -EINVAL;
}
-   if (rdev->family < CHIP_TAHITI) {
-   DRM_DEBUG_KMS("tile mode array is si only!\n");
-   return -EINVAL;
-   }
-   value = rdev->config.si.tile_mode_array;
-   value_size = sizeof(uint32_t)*32;
break;
default:
DRM_DEBUG_KMS("Invalid request %d\n", info->request);
-- 
1.7.7.5



[PATCH 057/165] drm/radeon: add radeon_asic struct for CIK (v11)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

v2: fix up for latest reset changes
v3: use CP for pt updates for now
v4: update for 2 level PTs
v5: update for ib_parse removal
v6: vm_flush api change
v7: rebase
v8: fix gfx ring function pointers
v9: fix vm_set_page function params
v10: update for compute changes
v11: cleanup for release

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_asic.c |  287 ++
 drivers/gpu/drm/radeon/radeon_asic.h |   47 ++
 2 files changed, 334 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index 717b537..d60adb3 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1923,6 +1923,280 @@ static struct radeon_asic si_asic = {
},
 };

+static struct radeon_asic ci_asic = {
+   .init = _init,
+   .fini = _fini,
+   .suspend = _suspend,
+   .resume = _resume,
+   .asic_reset = _asic_reset,
+   .vga_set_state = _vga_set_state,
+   .ioctl_wait_idle = NULL,
+   .gui_idle = _gui_idle,
+   .mc_wait_for_idle = _mc_wait_for_idle,
+   .get_xclk = _get_xclk,
+   .get_gpu_clock_counter = _get_gpu_clock_counter,
+   .gart = {
+   .tlb_flush = _pcie_gart_tlb_flush,
+   .set_page = _gart_set_page,
+   },
+   .vm = {
+   .init = _vm_init,
+   .fini = _vm_fini,
+   .pt_ring_index = R600_RING_TYPE_DMA_INDEX,
+   .set_page = _vm_set_page,
+   },
+   .ring = {
+   [RADEON_RING_TYPE_GFX_INDEX] = {
+   .ib_execute = _ring_ib_execute,
+   .ib_parse = _ib_parse,
+   .emit_fence = _fence_gfx_ring_emit,
+   .emit_semaphore = _semaphore_ring_emit,
+   .cs_parse = NULL,
+   .ring_test = _ring_test,
+   .ib_test = _ib_test,
+   .is_lockup = _gfx_is_lockup,
+   .vm_flush = _vm_flush,
+   },
+   [CAYMAN_RING_TYPE_CP1_INDEX] = {
+   .ib_execute = _ring_ib_execute,
+   .ib_parse = _ib_parse,
+   .emit_fence = _fence_compute_ring_emit,
+   .emit_semaphore = _semaphore_ring_emit,
+   .cs_parse = NULL,
+   .ring_test = _ring_test,
+   .ib_test = _ib_test,
+   .is_lockup = _gfx_is_lockup,
+   .vm_flush = _vm_flush,
+   },
+   [CAYMAN_RING_TYPE_CP2_INDEX] = {
+   .ib_execute = _ring_ib_execute,
+   .ib_parse = _ib_parse,
+   .emit_fence = _fence_compute_ring_emit,
+   .emit_semaphore = _semaphore_ring_emit,
+   .cs_parse = NULL,
+   .ring_test = _ring_test,
+   .ib_test = _ib_test,
+   .is_lockup = _gfx_is_lockup,
+   .vm_flush = _vm_flush,
+   },
+   [R600_RING_TYPE_DMA_INDEX] = {
+   .ib_execute = _sdma_ring_ib_execute,
+   .ib_parse = _ib_parse,
+   .emit_fence = _sdma_fence_ring_emit,
+   .emit_semaphore = _sdma_semaphore_ring_emit,
+   .cs_parse = NULL,
+   .ring_test = _sdma_ring_test,
+   .ib_test = _sdma_ib_test,
+   .is_lockup = _sdma_is_lockup,
+   .vm_flush = _dma_vm_flush,
+   },
+   [CAYMAN_RING_TYPE_DMA1_INDEX] = {
+   .ib_execute = _sdma_ring_ib_execute,
+   .ib_parse = _ib_parse,
+   .emit_fence = _sdma_fence_ring_emit,
+   .emit_semaphore = _sdma_semaphore_ring_emit,
+   .cs_parse = NULL,
+   .ring_test = _sdma_ring_test,
+   .ib_test = _sdma_ib_test,
+   .is_lockup = _sdma_is_lockup,
+   .vm_flush = _dma_vm_flush,
+   },
+   [R600_RING_TYPE_UVD_INDEX] = {
+   .ib_execute = _uvd_ib_execute,
+   .emit_fence = _uvd_fence_emit,
+   .emit_semaphore = _uvd_semaphore_emit,
+   .cs_parse = _uvd_cs_parse,
+   .ring_test = _uvd_ring_test,
+   .ib_test = _uvd_ib_test,
+   .is_lockup = _ring_test_lockup,
+   }
+   },
+   .irq = {
+   .set = _irq_set,
+   .process = _irq_process,
+   },
+   .display = {
+   .bandwidth_update = _bandwidth_update,
+   .get_vblank_counter = 

[PATCH 056/165] drm/radeon/cik: add support for golden register init

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/cik.c |  438 ++
 1 files changed, 438 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 5923ef7..e899c44 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -99,6 +99,439 @@ void cik_pciep_wreg(struct radeon_device *rdev, u32 reg, 
u32 v)
(void)RREG32(PCIE_DATA);
 }

+static const u32 bonaire_golden_spm_registers[] =
+{
+   0x30800, 0xe0ff, 0xe000
+};
+
+static const u32 bonaire_golden_common_registers[] =
+{
+   0xc770, 0x, 0x0800,
+   0xc774, 0x, 0x0800,
+   0xc798, 0x, 0x7fbf,
+   0xc79c, 0x, 0x7faf
+};
+
+static const u32 bonaire_golden_registers[] =
+{
+   0x3354, 0x0333, 0x0333,
+   0x3350, 0x000c0fc0, 0x00040200,
+   0x9a10, 0x0001, 0x00058208,
+   0x3c000, 0x1fff, 0x0014,
+   0x3c200, 0xfdfc0fff, 0x0100,
+   0x3c234, 0x4000, 0x4200,
+   0x9830, 0x, 0x,
+   0x9834, 0xf00f, 0x0400,
+   0x9838, 0x0002021c, 0x00020200,
+   0xc78, 0x0080, 0x,
+   0x5bb0, 0x00f0, 0x0070,
+   0x5bc0, 0xf0311fff, 0x8030,
+   0x98f8, 0x73773777, 0x12010001,
+   0x350c, 0x0081, 0x408af000,
+   0x7030, 0x31000111, 0x0011,
+   0x2f48, 0x73773777, 0x12010001,
+   0x220c, 0x7fb6, 0x0021a1b1,
+   0x2210, 0x7fb6, 0x002021b1,
+   0x2180, 0x7fb6, 0x2191,
+   0x2218, 0x7fb6, 0x002121b1,
+   0x221c, 0x7fb6, 0x002021b1,
+   0x21dc, 0x7fb6, 0x2191,
+   0x21e0, 0x7fb6, 0x2191,
+   0x3628, 0x003f, 0x000a,
+   0x362c, 0x003f, 0x000a,
+   0x2ae4, 0x00073ffe, 0x22a2,
+   0x240c, 0x07ff, 0x,
+   0x8a14, 0xf03f, 0x0007,
+   0x8bf0, 0x2001, 0x0001,
+   0x8b24, 0x, 0x00ff,
+   0x30a04, 0xff0f, 0x,
+   0x28a4c, 0x07ff, 0x0600,
+   0x4d8, 0x0fff, 0x0100,
+   0x3e78, 0x0001, 0x0002,
+   0x9100, 0x0300, 0x0362c688,
+   0x8c00, 0x00ff, 0x0001,
+   0xe40, 0x1fff, 0x1fff,
+   0x9060, 0x007f, 0x0020,
+   0x9508, 0x0001, 0x0001,
+   0xac14, 0x03ff, 0x00f3,
+   0xac0c, 0x, 0x1032
+};
+
+static const u32 bonaire_mgcg_cgcg_init[] =
+{
+   0xc420, 0x, 0xfffc,
+   0x30800, 0x, 0xe000,
+   0x3c2a0, 0x, 0x0100,
+   0x3c208, 0x, 0x0100,
+   0x3c2c0, 0x, 0xc100,
+   0x3c2c8, 0x, 0xc100,
+   0x3c2c4, 0x, 0xc100,
+   0x55e4, 0x, 0x00600100,
+   0x3c280, 0x, 0x0100,
+   0x3c214, 0x, 0x06000100,
+   0x3c220, 0x, 0x0100,
+   0x3c218, 0x, 0x06000100,
+   0x3c204, 0x, 0x0100,
+   0x3c2e0, 0x, 0x0100,
+   0x3c224, 0x, 0x0100,
+   0x3c200, 0x, 0x0100,
+   0x3c230, 0x, 0x0100,
+   0x3c234, 0x, 0x0100,
+   0x3c250, 0x, 0x0100,
+   0x3c254, 0x, 0x0100,
+   0x3c258, 0x, 0x0100,
+   0x3c25c, 0x, 0x0100,
+   0x3c260, 0x, 0x0100,
+   0x3c27c, 0x, 0x0100,
+   0x3c278, 0x, 0x0100,
+   0x3c210, 0x, 0x06000100,
+   0x3c290, 0x, 0x0100,
+   0x3c274, 0x, 0x0100,
+   0x3c2b4, 0x, 0x0100,
+   0x3c2b0, 0x, 0x0100,
+   0x3c270, 0x, 0x0100,
+   0x30800, 0x, 0xe000,
+   0x3c020, 0x, 0x0001,
+   0x3c024, 0x, 0x00030002,
+   0x3c028, 0x, 0x00040007,
+   0x3c02c, 0x, 0x00060005,
+   0x3c030, 0x, 0x00090008,
+   0x3c034, 0x, 0x0001,
+   0x3c038, 0x, 0x00030002,
+   0x3c03c, 0x, 0x00040007,
+   0x3c040, 0x, 0x00060005,
+   0x3c044, 0x, 0x00090008,
+   0x3c048, 0x, 0x0001,
+   0x3c04c, 0x, 0x00030002,
+   0x3c050, 0x, 0x00040007,
+   0x3c054, 0x, 0x00060005,
+   0x3c058, 0x, 0x00090008,
+   0x3c05c, 0x, 0x0001,
+   0x3c060, 0x, 0x00030002,
+   0x3c064, 0x, 0x00040007,
+   0x3c068, 0x, 0x00060005,
+   0x3c06c, 0x, 0x00090008,
+   0x3c070, 0x, 0x0001,
+   0x3c074, 0x, 0x00030002,
+   0x3c078, 0x, 0x00040007,
+   0x3c07c, 0x, 0x00060005,
+   0x3c080, 0x, 0x00090008,
+   0x3c084, 0x, 0x0001,
+   0x3c088, 0x, 0x00030002,
+ 

[PATCH 055/165] drm/radeon/cik: add support for compute interrupts

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/cik.c |  121 --
 1 files changed, 116 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 596bfed..5923ef7 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -4631,6 +4631,8 @@ int cik_irq_set(struct radeon_device *rdev)
 {
u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE |
PRIV_INSTR_INT_ENABLE | PRIV_REG_INT_ENABLE;
+   u32 cp_m1p0, cp_m1p1, cp_m1p2, cp_m1p3;
+   u32 cp_m2p0, cp_m2p1, cp_m2p2, cp_m2p3;
u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0;
u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6;
u32 grbm_int_cntl = 0;
@@ -4658,13 +4660,106 @@ int cik_irq_set(struct radeon_device *rdev)
dma_cntl = RREG32(SDMA0_CNTL + SDMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
dma_cntl1 = RREG32(SDMA0_CNTL + SDMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;

+   cp_m1p0 = RREG32(CP_ME1_PIPE0_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
+   cp_m1p1 = RREG32(CP_ME1_PIPE1_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
+   cp_m1p2 = RREG32(CP_ME1_PIPE2_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
+   cp_m1p3 = RREG32(CP_ME1_PIPE3_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
+   cp_m2p0 = RREG32(CP_ME2_PIPE0_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
+   cp_m2p1 = RREG32(CP_ME2_PIPE1_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
+   cp_m2p2 = RREG32(CP_ME2_PIPE2_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
+   cp_m2p3 = RREG32(CP_ME2_PIPE3_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
+
/* enable CP interrupts on all rings */
if (atomic_read(>irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
DRM_DEBUG("cik_irq_set: sw int gfx\n");
cp_int_cntl |= TIME_STAMP_INT_ENABLE;
}
-   /* TODO: compute queues! */
-   /* CP_ME[1-2]_PIPE[0-3]_INT_CNTL */
+   if (atomic_read(>irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) {
+   struct radeon_ring *ring = 
>ring[CAYMAN_RING_TYPE_CP1_INDEX];
+   DRM_DEBUG("si_irq_set: sw int cp1\n");
+   if (ring->me == 1) {
+   switch (ring->pipe) {
+   case 0:
+   cp_m1p0 |= TIME_STAMP_INT_ENABLE;
+   break;
+   case 1:
+   cp_m1p1 |= TIME_STAMP_INT_ENABLE;
+   break;
+   case 2:
+   cp_m1p2 |= TIME_STAMP_INT_ENABLE;
+   break;
+   case 3:
+   cp_m1p2 |= TIME_STAMP_INT_ENABLE;
+   break;
+   default:
+   DRM_DEBUG("si_irq_set: sw int cp1 invalid pipe 
%d\n", ring->pipe);
+   break;
+   }
+   } else if (ring->me == 2) {
+   switch (ring->pipe) {
+   case 0:
+   cp_m2p0 |= TIME_STAMP_INT_ENABLE;
+   break;
+   case 1:
+   cp_m2p1 |= TIME_STAMP_INT_ENABLE;
+   break;
+   case 2:
+   cp_m2p2 |= TIME_STAMP_INT_ENABLE;
+   break;
+   case 3:
+   cp_m2p2 |= TIME_STAMP_INT_ENABLE;
+   break;
+   default:
+   DRM_DEBUG("si_irq_set: sw int cp1 invalid pipe 
%d\n", ring->pipe);
+   break;
+   }
+   } else {
+   DRM_DEBUG("si_irq_set: sw int cp1 invalid me %d\n", 
ring->me);
+   }
+   }
+   if (atomic_read(>irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) {
+   struct radeon_ring *ring = 
>ring[CAYMAN_RING_TYPE_CP2_INDEX];
+   DRM_DEBUG("si_irq_set: sw int cp2\n");
+   if (ring->me == 1) {
+   switch (ring->pipe) {
+   case 0:
+   cp_m1p0 |= TIME_STAMP_INT_ENABLE;
+   break;
+   case 1:
+   cp_m1p1 |= TIME_STAMP_INT_ENABLE;
+   break;
+   case 2:
+   cp_m1p2 |= TIME_STAMP_INT_ENABLE;
+   break;
+   case 3:
+   cp_m1p2 |= TIME_STAMP_INT_ENABLE;
+   break;
+   default:
+   DRM_DEBUG("si_irq_set: sw int cp2 invalid pipe 
%d\n", ring->pipe);
+   break;

[PATCH 054/165] drm/radeon: fix up ring functions for compute rings

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

The compute rings use RELEASE_MEM rather then EOP
packets for writing fences and there is no SYNC_PFP_ME
packet on the compute rings.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/cik.c |   53 +
 1 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 08dc4c2..596bfed 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -1706,7 +1706,7 @@ int cik_ring_test(struct radeon_device *rdev, struct 
radeon_ring *ring)
 }

 /**
- * cik_fence_ring_emit - emit a fence on the gfx ring
+ * cik_fence_gfx_ring_emit - emit a fence on the gfx ring
  *
  * @rdev: radeon_device pointer
  * @fence: radeon fence object
@@ -1714,8 +1714,8 @@ int cik_ring_test(struct radeon_device *rdev, struct 
radeon_ring *ring)
  * Emits a fence sequnce number on the gfx ring and flushes
  * GPU caches.
  */
-void cik_fence_ring_emit(struct radeon_device *rdev,
-struct radeon_fence *fence)
+void cik_fence_gfx_ring_emit(struct radeon_device *rdev,
+struct radeon_fence *fence)
 {
struct radeon_ring *ring = >ring[fence->ring];
u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
@@ -1742,6 +1742,44 @@ void cik_fence_ring_emit(struct radeon_device *rdev,
radeon_ring_write(ring, 0);
 }

+/**
+ * cik_fence_compute_ring_emit - emit a fence on the compute ring
+ *
+ * @rdev: radeon_device pointer
+ * @fence: radeon fence object
+ *
+ * Emits a fence sequnce number on the compute ring and flushes
+ * GPU caches.
+ */
+void cik_fence_compute_ring_emit(struct radeon_device *rdev,
+struct radeon_fence *fence)
+{
+   struct radeon_ring *ring = >ring[fence->ring];
+   u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
+
+   /* RELEASE_MEM - flush caches, send int */
+   radeon_ring_write(ring, PACKET3(PACKET3_RELEASE_MEM, 5));
+   radeon_ring_write(ring, (EOP_TCL1_ACTION_EN |
+EOP_TC_ACTION_EN |
+EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) |
+EVENT_INDEX(5)));
+   radeon_ring_write(ring, DATA_SEL(1) | INT_SEL(2));
+   radeon_ring_write(ring, addr & 0xfffc);
+   radeon_ring_write(ring, upper_32_bits(addr));
+   radeon_ring_write(ring, fence->seq);
+   radeon_ring_write(ring, 0);
+   /* HDP flush */
+   /* We should be using the new WAIT_REG_MEM special op packet here
+* but it causes the CP to hang
+*/
+   radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+   radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+WRITE_DATA_DST_SEL(0)));
+   radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
+   radeon_ring_write(ring, 0);
+   radeon_ring_write(ring, 0);
+}
+
 void cik_semaphore_ring_emit(struct radeon_device *rdev,
 struct radeon_ring *ring,
 struct radeon_semaphore *semaphore,
@@ -4051,9 +4089,12 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, 
struct radeon_vm *vm)
radeon_ring_write(ring, 0);
radeon_ring_write(ring, 1 << vm->id);

-   /* sync PFP to ME, otherwise we might get invalid PFP reads */
-   radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
-   radeon_ring_write(ring, 0x0);
+   /* compute doesn't have PFP */
+   if (ridx == RADEON_RING_TYPE_GFX_INDEX) {
+   /* sync PFP to ME, otherwise we might get invalid PFP reads */
+   radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
+   radeon_ring_write(ring, 0x0);
+   }
 }

 /**
-- 
1.7.7.5



[PATCH 053/165] drm/radeon/cik: switch to type3 nop packet for compute rings

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Type 2 packets are deprecated on CIK MEC and we should use
type 3 nop packets.  Setting the count field to the max value
(0x3fff) indicates that only one dword should be skipped
like a type 2 packet.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/cik.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 9d2d6bb..08dc4c2 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -5470,7 +5470,7 @@ static int cik_startup(struct radeon_device *rdev)
ring = >ring[CAYMAN_RING_TYPE_CP1_INDEX];
r = radeon_ring_init(rdev, ring, ring->ring_size, 
RADEON_WB_CP1_RPTR_OFFSET,
 CP_HQD_PQ_RPTR, CP_HQD_PQ_WPTR,
-0, 0xf, RADEON_CP_PACKET2);
+0, 0xf, PACKET3(PACKET3_NOP, 0x3FFF));
if (r)
return r;
ring->me = 1; /* first MEC */
@@ -5484,7 +5484,7 @@ static int cik_startup(struct radeon_device *rdev)
ring = >ring[CAYMAN_RING_TYPE_CP2_INDEX];
r = radeon_ring_init(rdev, ring, ring->ring_size, 
RADEON_WB_CP2_RPTR_OFFSET,
 CP_HQD_PQ_RPTR, CP_HQD_PQ_WPTR,
-0, 0x, RADEON_CP_PACKET2);
+0, 0x, PACKET3(PACKET3_NOP, 0x3FFF));
if (r)
return r;
/* dGPU only have 1 MEC */
-- 
1.7.7.5



[PATCH 052/165] drm/radeon/cik: Add support for compute queues (v2)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

On CIK, the compute rings work slightly differently than
on previous asics, however the basic concepts are the same.

The main differences:
- New MEC engines for compute queues
- Multiple queues per MEC:
  - CI/KB: 1 MEC, 4 pipes per MEC, 8 queues per pipe = 32 queues
  -KV: 2 MEC, 4 pipes per MEC, 8 queues per pipe = 64 queues
- Queues can be allocated and scheduled by another queue
- New doorbell aperture allows you to assign space in the aperture
  for the wptr which allows for userspace access to queues

v2: add wptr shadow, fix eop setup

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/cik.c   |  528 +++-
 drivers/gpu/drm/radeon/cikd.h  |   62 +
 drivers/gpu/drm/radeon/radeon.h|   19 ++
 drivers/gpu/drm/radeon/radeon_cs.c |4 +-
 4 files changed, 601 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 5c28fa5..9d2d6bb 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -1687,6 +1687,7 @@ int cik_ring_test(struct radeon_device *rdev, struct 
radeon_ring *ring)
radeon_ring_write(ring, ((scratch - PACKET3_SET_UCONFIG_REG_START) >> 
2));
radeon_ring_write(ring, 0xDEADBEEF);
radeon_ring_unlock_commit(rdev, ring);
+
for (i = 0; i < rdev->usec_timeout; i++) {
tmp = RREG32(scratch);
if (tmp == 0xDEADBEEF)
@@ -2112,6 +2113,51 @@ static int cik_cp_gfx_resume(struct radeon_device *rdev)
return 0;
 }

+static u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
+struct radeon_ring *ring)
+{
+   u32 rptr;
+
+
+
+   if (rdev->wb.enabled) {
+   rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
+   } else {
+   cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
+   rptr = RREG32(CP_HQD_PQ_RPTR);
+   cik_srbm_select(rdev, 0, 0, 0, 0);
+   }
+   rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+
+   return rptr;
+}
+
+static u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
+struct radeon_ring *ring)
+{
+   u32 wptr;
+
+   if (rdev->wb.enabled) {
+   wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]);
+   } else {
+   cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
+   wptr = RREG32(CP_HQD_PQ_WPTR);
+   cik_srbm_select(rdev, 0, 0, 0, 0);
+   }
+   wptr = (wptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+
+   return wptr;
+}
+
+static void cik_compute_ring_set_wptr(struct radeon_device *rdev,
+ struct radeon_ring *ring)
+{
+   u32 wptr = (ring->wptr << ring->ptr_reg_shift) & ring->ptr_reg_mask;
+
+   rdev->wb.wb[ring->wptr_offs/4] = cpu_to_le32(wptr);
+   WDOORBELL32(ring->doorbell_offset, wptr);
+}
+
 /**
  * cik_cp_compute_enable - enable/disable the compute CP MEs
  *
@@ -2176,7 +,8 @@ static int cik_cp_compute_load_microcode(struct 
radeon_device *rdev)
  */
 static int cik_cp_compute_start(struct radeon_device *rdev)
 {
-   //todo
+   cik_cp_compute_enable(rdev, true);
+
return 0;
 }

@@ -2190,10 +2237,171 @@ static int cik_cp_compute_start(struct radeon_device 
*rdev)
  */
 static void cik_cp_compute_fini(struct radeon_device *rdev)
 {
+   int i, idx, r;
+
cik_cp_compute_enable(rdev, false);
-   //todo
+
+   for (i = 0; i < 2; i++) {
+   if (i == 0)
+   idx = CAYMAN_RING_TYPE_CP1_INDEX;
+   else
+   idx = CAYMAN_RING_TYPE_CP2_INDEX;
+
+   if (rdev->ring[idx].mqd_obj) {
+   r = radeon_bo_reserve(rdev->ring[idx].mqd_obj, false);
+   if (unlikely(r != 0))
+   dev_warn(rdev->dev, "(%d) reserve MQD bo 
failed\n", r);
+
+   radeon_bo_unpin(rdev->ring[idx].mqd_obj);
+   radeon_bo_unreserve(rdev->ring[idx].mqd_obj);
+
+   radeon_bo_unref(>ring[idx].mqd_obj);
+   rdev->ring[idx].mqd_obj = NULL;
+   }
+   }
+}
+
+static void cik_mec_fini(struct radeon_device *rdev)
+{
+   int r;
+
+   if (rdev->mec.hpd_eop_obj) {
+   r = radeon_bo_reserve(rdev->mec.hpd_eop_obj, false);
+   if (unlikely(r != 0))
+   dev_warn(rdev->dev, "(%d) reserve HPD EOP bo failed\n", 
r);
+   radeon_bo_unpin(rdev->mec.hpd_eop_obj);
+   radeon_bo_unreserve(rdev->mec.hpd_eop_obj);
+
+   radeon_bo_unref(>mec.hpd_eop_obj);
+   rdev->mec.hpd_eop_obj = NULL;
+   }
+}
+
+#define MEC_HPD_SIZE 2048
+
+static int cik_mec_init(struct radeon_device *rdev)
+{
+   int r;
+   u32 *hpd;
+
+   /*
+* 

[PATCH 051/165] drm/radeon: implement simple doorbell page allocator

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

The doorbell aperture is a PCI BAR whose pages can be
mapped to compute resources for things like wptrs
for userspace queues.

This patch maps the BAR and sets up a simple allocator
to allocate pages from the BAR.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/cik.c   |   38 +
 drivers/gpu/drm/radeon/radeon.h|   21 +++
 drivers/gpu/drm/radeon/radeon_device.c |   94 
 3 files changed, 153 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index bb7dbc4..5c28fa5 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -121,6 +121,44 @@ u32 cik_get_xclk(struct radeon_device *rdev)
return reference_clock;
 }

+/**
+ * cik_mm_rdoorbell - read a doorbell dword
+ *
+ * @rdev: radeon_device pointer
+ * @offset: byte offset into the aperture
+ *
+ * Returns the value in the doorbell aperture at the
+ * requested offset (CIK).
+ */
+u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 offset)
+{
+   if (offset < rdev->doorbell.size) {
+   return readl(((void __iomem *)rdev->doorbell.ptr) + offset);
+   } else {
+   DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", 
offset);
+   return 0;
+   }
+}
+
+/**
+ * cik_mm_wdoorbell - write a doorbell dword
+ *
+ * @rdev: radeon_device pointer
+ * @offset: byte offset into the aperture
+ * @v: value to write
+ *
+ * Writes @v to the doorbell aperture at the
+ * requested offset (CIK).
+ */
+void cik_mm_wdoorbell(struct radeon_device *rdev, u32 offset, u32 v)
+{
+   if (offset < rdev->doorbell.size) {
+   writel(v, ((void __iomem *)rdev->doorbell.ptr) + offset);
+   } else {
+   DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", 
offset);
+   }
+}
+
 #define BONAIRE_IO_MC_REGS_SIZE 36

 static const u32 bonaire_io_mc_regs[BONAIRE_IO_MC_REGS_SIZE][2] =
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index ad4e68a..a2a3430 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -556,6 +556,20 @@ struct radeon_scratch {
 int radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg);
 void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg);

+/*
+ * GPU doorbell structures, functions & helpers
+ */
+struct radeon_doorbell {
+   u32 num_pages;
+   boolfree[1024];
+   /* doorbell mmio */
+   resource_size_t base;
+   resource_size_t size;
+   void __iomem*ptr;
+};
+
+int radeon_doorbell_get(struct radeon_device *rdev, u32 *page);
+void radeon_doorbell_free(struct radeon_device *rdev, u32 doorbell);

 /*
  * IRQS.
@@ -1711,6 +1725,7 @@ struct radeon_device {
struct radeon_gart  gart;
struct radeon_mode_info mode_info;
struct radeon_scratch   scratch;
+   struct radeon_doorbell  doorbell;
struct radeon_mman  mman;
struct radeon_fence_driver  fence_drv[RADEON_NUM_RINGS];
wait_queue_head_t   fence_queue;
@@ -1784,6 +1799,9 @@ void r100_mm_wreg(struct radeon_device *rdev, uint32_t 
reg, uint32_t v,
 u32 r100_io_rreg(struct radeon_device *rdev, u32 reg);
 void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v);

+u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 offset);
+void cik_mm_wdoorbell(struct radeon_device *rdev, u32 offset, u32 v);
+
 /*
  * Cast helper
  */
@@ -1833,6 +1851,9 @@ void r100_io_wreg(struct radeon_device *rdev, u32 reg, 
u32 v);
 #define RREG32_IO(reg) r100_io_rreg(rdev, (reg))
 #define WREG32_IO(reg, v) r100_io_wreg(rdev, (reg), (v))

+#define RDOORBELL32(offset) cik_mm_rdoorbell(rdev, (offset))
+#define WDOORBELL32(offset, v) cik_mm_wdoorbell(rdev, (offset), (v))
+
 /*
  * Indirect registers accessor
  */
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 4e97ff7..82335e3 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -232,6 +232,94 @@ void radeon_scratch_free(struct radeon_device *rdev, 
uint32_t reg)
 }

 /*
+ * GPU doorbell aperture helpers function.
+ */
+/**
+ * radeon_doorbell_init - Init doorbell driver information.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Init doorbell driver information (CIK)
+ * Returns 0 on success, error on failure.
+ */
+int radeon_doorbell_init(struct radeon_device *rdev)
+{
+   int i;
+
+   /* doorbell bar mapping */
+   rdev->doorbell.base = pci_resource_start(rdev->pdev, 2);
+   rdev->doorbell.size = pci_resource_len(rdev->pdev, 2);
+
+   /* limit to 4 MB for now */
+   if (rdev->doorbell.size > (4 * 1024 * 1024))
+   rdev->doorbell.size = 4 * 1024 * 1024;
+
+   

[PATCH 050/165] drm/radeon: use callbacks for ring pointer handling

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Add callbacks to the radeon_ring struct to handle
rptr/wptr fetchs and wptr updates.
We currently use one version for all rings, but this
allows us to override with a ring specific versions.

Needed for compute rings on CIK.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon.h  |5 +++
 drivers/gpu/drm/radeon/radeon_ring.c |   55 +
 2 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9af0fa6..ad4e68a 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -695,6 +695,11 @@ struct radeon_ring {
u32 idx;
u64 last_semaphore_signal_addr;
u64 last_semaphore_wait_addr;
+   struct {
+   u32 (*get_rptr)(struct radeon_device *rdev, 
struct radeon_ring *ring);
+   u32 (*get_wptr)(struct radeon_device *rdev, 
struct radeon_ring *ring);
+   void(*set_wptr)(struct radeon_device *rdev, 
struct radeon_ring *ring);
+   } funcs;
 };

 /*
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index e17faa7..53018e9 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -357,6 +357,38 @@ bool radeon_ring_supports_scratch_reg(struct radeon_device 
*rdev,
}
 }

+static u32 radeon_ring_get_rptr(struct radeon_device *rdev,
+   struct radeon_ring *ring)
+{
+   u32 rptr;
+
+   if (rdev->wb.enabled && ring != >ring[R600_RING_TYPE_UVD_INDEX])
+   rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
+   else
+   rptr = RREG32(ring->rptr_reg);
+   rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+
+   return rptr;
+}
+
+static u32 radeon_ring_get_wptr(struct radeon_device *rdev,
+   struct radeon_ring *ring)
+{
+   u32 wptr;
+
+   wptr = RREG32(ring->wptr_reg);
+   wptr = (wptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+
+   return wptr;
+}
+
+static void radeon_ring_set_wptr(struct radeon_device *rdev,
+struct radeon_ring *ring)
+{
+   WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & 
ring->ptr_reg_mask);
+   (void)RREG32(ring->wptr_reg);
+}
+
 /**
  * radeon_ring_free_size - update the free size
  *
@@ -367,13 +399,7 @@ bool radeon_ring_supports_scratch_reg(struct radeon_device 
*rdev,
  */
 void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring 
*ring)
 {
-   u32 rptr;
-
-   if (rdev->wb.enabled && ring != >ring[R600_RING_TYPE_UVD_INDEX])
-   rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
-   else
-   rptr = RREG32(ring->rptr_reg);
-   ring->rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+   ring->rptr = ring->funcs.get_rptr(rdev, ring);
/* This works because ring_size is a power of 2 */
ring->ring_free_dw = (ring->rptr + (ring->ring_size / 4));
ring->ring_free_dw -= ring->wptr;
@@ -458,8 +484,7 @@ void radeon_ring_commit(struct radeon_device *rdev, struct 
radeon_ring *ring)
radeon_ring_write(ring, ring->nop);
}
DRM_MEMORYBARRIER();
-   WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & 
ring->ptr_reg_mask);
-   (void)RREG32(ring->wptr_reg);
+   ring->funcs.set_wptr(rdev, ring);
 }

 /**
@@ -561,7 +586,6 @@ void radeon_ring_lockup_update(struct radeon_ring *ring)
 bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring 
*ring)
 {
unsigned long cjiffies, elapsed;
-   uint32_t rptr;

cjiffies = jiffies;
if (!time_after(cjiffies, ring->last_activity)) {
@@ -569,8 +593,7 @@ bool radeon_ring_test_lockup(struct radeon_device *rdev, 
struct radeon_ring *rin
radeon_ring_lockup_update(ring);
return false;
}
-   rptr = RREG32(ring->rptr_reg);
-   ring->rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+   ring->rptr = ring->funcs.get_rptr(rdev, ring);
if (ring->rptr != ring->last_rptr) {
/* CP is still working no lockup */
radeon_ring_lockup_update(ring);
@@ -708,6 +731,10 @@ int radeon_ring_init(struct radeon_device *rdev, struct 
radeon_ring *ring, unsig
ring->ptr_reg_shift = ptr_reg_shift;
ring->ptr_reg_mask = ptr_reg_mask;
ring->nop = nop;
+   /* set the ptr callbacks */
+   ring->funcs.get_rptr = _ring_get_rptr;
+   ring->funcs.get_wptr = _ring_get_wptr;
+   ring->funcs.set_wptr = _ring_set_wptr;
/* Allocate ring buffer */
if (ring->ring_obj == NULL) {
r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, 

[PATCH 049/165] drm/radeon/cik: add srbm_select function

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Allows us to select instanced registers based on:
- ME (micro engine
- Pipe
- Queue
- VMID

Switch MC setup to use this new function.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/cik.c |   27 +--
 1 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 29e0cdd..bb7dbc4 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -163,6 +163,29 @@ static const u32 
bonaire_io_mc_regs[BONAIRE_IO_MC_REGS_SIZE][2] =
{0x009f, 0x00b48000}
 };

+/**
+ * cik_srbm_select - select specific register instances
+ *
+ * @rdev: radeon_device pointer
+ * @me: selected ME (micro engine)
+ * @pipe: pipe
+ * @queue: queue
+ * @vmid: VMID
+ *
+ * Switches the currently active registers instances.  Some
+ * registers are instanced per VMID, others are instanced per
+ * me/pipe/queue combination.
+ */
+static void cik_srbm_select(struct radeon_device *rdev,
+   u32 me, u32 pipe, u32 queue, u32 vmid)
+{
+   u32 srbm_gfx_cntl = (PIPEID(pipe & 0x3) |
+MEID(me & 0x3) |
+VMID(vmid & 0xf) |
+QUEUEID(queue & 0x7));
+   WREG32(SRBM_GFX_CNTL, srbm_gfx_cntl);
+}
+
 /* ucode loading */
 /**
  * ci_mc_load_microcode - load MC ucode into the hw
@@ -3351,7 +3374,7 @@ static int cik_pcie_gart_enable(struct radeon_device 
*rdev)
/* XXX SH_MEM regs */
/* where to put LDS, scratch, GPUVM in FSA64 space */
for (i = 0; i < 16; i++) {
-   WREG32(SRBM_GFX_CNTL, VMID(i));
+   cik_srbm_select(rdev, 0, 0, 0, i);
/* CP and shaders */
WREG32(SH_MEM_CONFIG, 0);
WREG32(SH_MEM_APE1_BASE, 1);
@@ -3364,7 +3387,7 @@ static int cik_pcie_gart_enable(struct radeon_device 
*rdev)
WREG32(SDMA0_GFX_APE1_CNTL + SDMA1_REGISTER_OFFSET, 0);
/* XXX SDMA RLC - todo */
}
-   WREG32(SRBM_GFX_CNTL, 0);
+   cik_srbm_select(rdev, 0, 0, 0, 0);

cik_pcie_gart_tlb_flush(rdev);
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
-- 
1.7.7.5



[PATCH 048/165] drm/radeon: add UVD support for CIK (v3)

2013-06-26 Thread alexdeuc...@gmail.com
From: Christian K?nig 

v2: agd5f: fix clock dividers setup for bonaire
v3: agd5f: rebase

Signed-off-by: Christian K?nig 
Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/cik.c |  111 ++
 drivers/gpu/drm/radeon/cikd.h|   28 +
 drivers/gpu/drm/radeon/radeon_asic.h |2 +
 drivers/gpu/drm/radeon/radeon_uvd.c  |8 +++
 4 files changed, 149 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index e8ea845..29e0cdd 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -1495,6 +1495,9 @@ static void cik_gpu_init(struct radeon_device *rdev)
WREG32(DMIF_ADDR_CALC, gb_addr_config);
WREG32(SDMA0_TILING_CONFIG + SDMA0_REGISTER_OFFSET, gb_addr_config & 
0x70);
WREG32(SDMA0_TILING_CONFIG + SDMA1_REGISTER_OFFSET, gb_addr_config & 
0x70);
+   WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
+   WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
+   WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);

cik_tiling_mode_table_init(rdev);

@@ -4906,6 +4909,16 @@ static int cik_startup(struct radeon_device *rdev)
return r;
}

+   r = cik_uvd_resume(rdev);
+   if (!r) {
+   r = radeon_fence_driver_start_ring(rdev,
+  R600_RING_TYPE_UVD_INDEX);
+   if (r)
+   dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
+   }
+   if (r)
+   rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
+
/* Enable IRQ */
if (!rdev->irq.installed) {
r = radeon_irq_kms_init(rdev);
@@ -4952,6 +4965,18 @@ static int cik_startup(struct radeon_device *rdev)
if (r)
return r;

+   ring = >ring[R600_RING_TYPE_UVD_INDEX];
+   if (ring->ring_size) {
+   r = radeon_ring_init(rdev, ring, ring->ring_size,
+R600_WB_UVD_RPTR_OFFSET,
+UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
+0, 0xf, RADEON_CP_PACKET2);
+   if (!r)
+   r = r600_uvd_init(rdev);
+   if (r)
+   DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
+   }
+
r = radeon_ib_pool_init(rdev);
if (r) {
dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
@@ -5013,6 +5038,8 @@ int cik_suspend(struct radeon_device *rdev)
radeon_vm_manager_fini(rdev);
cik_cp_enable(rdev, false);
cik_sdma_enable(rdev, false);
+   r600_uvd_rbc_stop(rdev);
+   radeon_uvd_suspend(rdev);
cik_irq_suspend(rdev);
radeon_wb_disable(rdev);
cik_pcie_gart_disable(rdev);
@@ -5096,6 +5123,13 @@ int cik_init(struct radeon_device *rdev)
ring->ring_obj = NULL;
r600_ring_init(rdev, ring, 256 * 1024);

+   r = radeon_uvd_init(rdev);
+   if (!r) {
+   ring = >ring[R600_RING_TYPE_UVD_INDEX];
+   ring->ring_obj = NULL;
+   r600_ring_init(rdev, ring, 4096);
+   }
+
rdev->ih.ring_obj = NULL;
r600_ih_ring_init(rdev, 64 * 1024);

@@ -5150,6 +5184,7 @@ void cik_fini(struct radeon_device *rdev)
radeon_vm_manager_fini(rdev);
radeon_ib_pool_fini(rdev);
radeon_irq_kms_fini(rdev);
+   radeon_uvd_fini(rdev);
cik_pcie_gart_fini(rdev);
r600_vram_scratch_fini(rdev);
radeon_gem_fini(rdev);
@@ -5717,3 +5752,79 @@ uint64_t cik_get_gpu_clock_counter(struct radeon_device 
*rdev)
return clock;
 }

+static int cik_set_uvd_clock(struct radeon_device *rdev, u32 clock,
+  u32 cntl_reg, u32 status_reg)
+{
+   int r, i;
+   struct atom_clock_dividers dividers;
+   uint32_t tmp;
+
+   r = radeon_atom_get_clock_dividers(rdev, 
COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK,
+  clock, false, );
+   if (r)
+   return r;
+
+   tmp = RREG32_SMC(cntl_reg);
+   tmp &= ~(DCLK_DIR_CNTL_EN|DCLK_DIVIDER_MASK);
+   tmp |= dividers.post_divider;
+   WREG32_SMC(cntl_reg, tmp);
+
+   for (i = 0; i < 100; i++) {
+   if (RREG32_SMC(status_reg) & DCLK_STATUS)
+   break;
+   mdelay(10);
+   }
+   if (i == 100)
+   return -ETIMEDOUT;
+
+   return 0;
+}
+
+int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
+{
+   int r = 0;
+
+   r = cik_set_uvd_clock(rdev, vclk, CG_VCLK_CNTL, CG_VCLK_STATUS);
+   if (r)
+   return r;
+
+   r = cik_set_uvd_clock(rdev, dclk, CG_DCLK_CNTL, CG_DCLK_STATUS);
+   return r;
+}
+
+int cik_uvd_resume(struct radeon_device *rdev)
+{
+   uint64_t addr;
+   uint32_t size;
+   int r;
+
+   r = 

[PATCH 047/165] drm/radeon: update radeon_atom_get_clock_dividers for CIK

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

CIK uses a slightly different variant of the table structs
and params.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_atombios.c |   20 +++-
 drivers/gpu/drm/radeon/radeon_mode.h |3 +++
 2 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c 
b/drivers/gpu/drm/radeon/radeon_atombios.c
index 774e354..bf3b924 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -2700,6 +2700,8 @@ union get_clock_dividers {
struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 v3;
struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 v4;
struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 v5;
+   struct _COMPUTE_GPU_CLOCK_INPUT_PARAMETERS_V1_6 v6_in;
+   struct _COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6 v6_out;
 };

 int radeon_atom_get_clock_dividers(struct radeon_device *rdev,
@@ -2794,9 +2796,25 @@ int radeon_atom_get_clock_dividers(struct radeon_device 
*rdev,

atom_execute_table(rdev->mode_info.atom_context, index, 
(uint32_t *));

-   dividers->post_div = args.v4.ucPostDiv;
+   dividers->post_divider = dividers->post_div = args.v4.ucPostDiv;
dividers->real_clock = le32_to_cpu(args.v4.ulClock);
break;
+   case 6:
+   /* CI */
+   /* COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK, 
COMPUTE_GPUCLK_INPUT_FLAG_SCLK */
+   args.v6_in.ulClock.ulComputeClockFlag = clock_type;
+   args.v6_in.ulClock.ulClockFreq = cpu_to_le32(clock);/* 10 
khz */
+
+   atom_execute_table(rdev->mode_info.atom_context, index, 
(uint32_t *));
+
+   dividers->whole_fb_div = 
le16_to_cpu(args.v6_out.ulFbDiv.usFbDiv);
+   dividers->frac_fb_div = 
le16_to_cpu(args.v6_out.ulFbDiv.usFbDivFrac);
+   dividers->ref_div = args.v6_out.ucPllRefDiv;
+   dividers->post_div = args.v6_out.ucPllPostDiv;
+   dividers->flags = args.v6_out.ucPllCntlFlag;
+   dividers->real_clock = le32_to_cpu(args.v6_out.ulClock.ulClock);
+   dividers->post_divider = args.v6_out.ulClock.ucPostDiv;
+   break;
default:
return -EINVAL;
}
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h 
b/drivers/gpu/drm/radeon/radeon_mode.h
index 4ed0a4c..576511f 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -514,6 +514,9 @@ struct atom_clock_dividers {
bool enable_dithen;
u32 vco_mode;
u32 real_clock;
+   /* added for CI */
+   u32 post_divider;
+   u32 flags;
 };

 extern enum radeon_tv_std
-- 
1.7.7.5



[PATCH 046/165] drm/radeon: update radeon_atom_get_clock_dividers() for SI

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

SI uses v5 of the command table and uses a different table
for memory PLLs.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_atombios.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c 
b/drivers/gpu/drm/radeon/radeon_atombios.c
index 3236755..774e354 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -2732,7 +2732,8 @@ int radeon_atom_get_clock_dividers(struct radeon_device 
*rdev,
break;
case 2:
case 3:
-   /* r6xx, r7xx, evergreen, ni */
+   case 5:
+   /* r6xx, r7xx, evergreen, ni, si */
if (rdev->family <= CHIP_RV770) {
args.v2.ucAction = clock_type;
args.v2.ulClock = cpu_to_le32(clock);   /* 10 khz */
@@ -2765,6 +2766,9 @@ int radeon_atom_get_clock_dividers(struct radeon_device 
*rdev,
dividers->vco_mode = (args.v3.ucCntlFlag &
  
ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
} else {
+   /* for SI we use ComputeMemoryClockParam for 
memory plls */
+   if (rdev->family >= CHIP_TAHITI)
+   return -EINVAL;
args.v5.ulClockParams = cpu_to_le32((clock_type 
<< 24) | clock);
if (strobe_mode)
args.v5.ucInputFlag = 
ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN;
-- 
1.7.7.5



[PATCH 045/165] drm/radeon/cik: add pcie_port indirect register accessors

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/cik.c |   21 +
 drivers/gpu/drm/radeon/cikd.h|3 +++
 drivers/gpu/drm/radeon/radeon_asic.c |6 +-
 drivers/gpu/drm/radeon/radeon_asic.h |2 ++
 4 files changed, 31 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 0db0ebc..e8ea845 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -78,6 +78,27 @@ extern void si_rlc_fini(struct radeon_device *rdev);
 extern int si_rlc_init(struct radeon_device *rdev);
 static void cik_rlc_stop(struct radeon_device *rdev);

+/*
+ * Indirect registers accessor
+ */
+u32 cik_pciep_rreg(struct radeon_device *rdev, u32 reg)
+{
+   u32 r;
+
+   WREG32(PCIE_INDEX, reg);
+   (void)RREG32(PCIE_INDEX);
+   r = RREG32(PCIE_DATA);
+   return r;
+}
+
+void cik_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+   WREG32(PCIE_INDEX, reg);
+   (void)RREG32(PCIE_INDEX);
+   WREG32(PCIE_DATA, v);
+   (void)RREG32(PCIE_DATA);
+}
+
 /**
  * cik_get_xclk - get the xclk
  *
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h
index f00e273..d23809a 100644
--- a/drivers/gpu/drm/radeon/cikd.h
+++ b/drivers/gpu/drm/radeon/cikd.h
@@ -35,6 +35,9 @@
 #define CG_CLKPIN_CNTL0xC05001A0
 #   define XTALIN_DIVIDE  (1 << 1)

+#define PCIE_INDEX 0x38
+#define PCIE_DATA  0x3C
+
 #define VGA_HDP_CONTROL0x328
 #defineVGA_MEMORY_DISABLE  (1 << 4)

diff --git a/drivers/gpu/drm/radeon/radeon_asic.c 
b/drivers/gpu/drm/radeon/radeon_asic.c
index a2802b47..717b537 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -126,7 +126,11 @@ static void radeon_register_accessor_init(struct 
radeon_device *rdev)
rdev->mc_rreg = _mc_rreg;
rdev->mc_wreg = _mc_wreg;
}
-   if (rdev->family >= CHIP_R600) {
+
+   if (rdev->family >= CHIP_BONAIRE) {
+   rdev->pciep_rreg = _pciep_rreg;
+   rdev->pciep_wreg = _pciep_wreg;
+   } else if (rdev->family >= CHIP_R600) {
rdev->pciep_rreg = _pciep_rreg;
rdev->pciep_wreg = _pciep_wreg;
}
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h 
b/drivers/gpu/drm/radeon/radeon_asic.h
index 05f75f7..8c19e36 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -558,5 +558,7 @@ int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, 
u32 dclk);
  */
 uint64_t cik_get_gpu_clock_counter(struct radeon_device *rdev);
 u32 cik_get_xclk(struct radeon_device *rdev);
+uint32_t cik_pciep_rreg(struct radeon_device *rdev, uint32_t reg);
+void cik_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);

 #endif
-- 
1.7.7.5



[PATCH 044/165] drm/radeon: add get_xclk() callback for CIK

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/cik.c |   22 ++
 drivers/gpu/drm/radeon/cikd.h|7 +++
 drivers/gpu/drm/radeon/radeon_asic.h |1 +
 3 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index aaf7bba..0db0ebc 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -78,6 +78,28 @@ extern void si_rlc_fini(struct radeon_device *rdev);
 extern int si_rlc_init(struct radeon_device *rdev);
 static void cik_rlc_stop(struct radeon_device *rdev);

+/**
+ * cik_get_xclk - get the xclk
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Returns the reference clock used by the gfx engine
+ * (CIK).
+ */
+u32 cik_get_xclk(struct radeon_device *rdev)
+{
+u32 reference_clock = rdev->clock.spll.reference_freq;
+
+   if (rdev->flags & RADEON_IS_IGP) {
+   if (RREG32_SMC(GENERAL_PWRMGT) & GPU_COUNTER_CLK)
+   return reference_clock / 2;
+   } else {
+   if (RREG32_SMC(CG_CLKPIN_CNTL) & XTALIN_DIVIDE)
+   return reference_clock / 4;
+   }
+   return reference_clock;
+}
+
 #define BONAIRE_IO_MC_REGS_SIZE 36

 static const u32 bonaire_io_mc_regs[BONAIRE_IO_MC_REGS_SIZE][2] =
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h
index 8afb334..f00e273 100644
--- a/drivers/gpu/drm/radeon/cikd.h
+++ b/drivers/gpu/drm/radeon/cikd.h
@@ -28,6 +28,13 @@

 #define CIK_RB_BITMAP_WIDTH_PER_SH  2

+/* SMC IND registers */
+#define GENERAL_PWRMGT0xC020
+#   define GPU_COUNTER_CLK(1 << 15)
+
+#define CG_CLKPIN_CNTL0xC05001A0
+#   define XTALIN_DIVIDE  (1 << 1)
+
 #define VGA_HDP_CONTROL0x328
 #defineVGA_MEMORY_DISABLE  (1 << 4)

diff --git a/drivers/gpu/drm/radeon/radeon_asic.h 
b/drivers/gpu/drm/radeon/radeon_asic.h
index 248da72..05f75f7 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -557,5 +557,6 @@ int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, 
u32 dclk);
  * cik
  */
 uint64_t cik_get_gpu_clock_counter(struct radeon_device *rdev);
+u32 cik_get_xclk(struct radeon_device *rdev);

 #endif
-- 
1.7.7.5



[PATCH 043/165] drm/radeon: add indirect register accessors for SMC registers

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/evergreen_reg.h |4 
 drivers/gpu/drm/radeon/radeon.h|   17 +
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h 
b/drivers/gpu/drm/radeon/evergreen_reg.h
index 881aba2..50948ac 100644
--- a/drivers/gpu/drm/radeon/evergreen_reg.h
+++ b/drivers/gpu/drm/radeon/evergreen_reg.h
@@ -24,6 +24,10 @@
 #ifndef __EVERGREEN_REG_H__
 #define __EVERGREEN_REG_H__

+/* trinity */
+#define TN_SMC_IND_INDEX_0  0x200
+#define TN_SMC_IND_DATA_0   0x204
+
 /* evergreen */
 #define EVERGREEN_VGA_MEMORY_BASE_ADDRESS   0x310
 #define EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH  0x324
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index b329e99..9af0fa6 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1806,6 +1806,8 @@ void r100_io_wreg(struct radeon_device *rdev, u32 reg, 
u32 v);
 #define WREG32_PCIE(reg, v) rv370_pcie_wreg(rdev, (reg), (v))
 #define RREG32_PCIE_PORT(reg) rdev->pciep_rreg(rdev, (reg))
 #define WREG32_PCIE_PORT(reg, v) rdev->pciep_wreg(rdev, (reg), (v))
+#define RREG32_SMC(reg) tn_smc_rreg(rdev, (reg))
+#define WREG32_SMC(reg, v) tn_smc_wreg(rdev, (reg), (v))
 #define WREG32_P(reg, val, mask)   \
do {\
uint32_t tmp_ = RREG32(reg);\
@@ -1844,6 +1846,21 @@ static inline void rv370_pcie_wreg(struct radeon_device 
*rdev, uint32_t reg, uin
WREG32(RADEON_PCIE_DATA, (v));
 }

+static inline u32 tn_smc_rreg(struct radeon_device *rdev, u32 reg)
+{
+   u32 r;
+
+   WREG32(TN_SMC_IND_INDEX_0, (reg));
+   r = RREG32(TN_SMC_IND_DATA_0);
+   return r;
+}
+
+static inline void tn_smc_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+   WREG32(TN_SMC_IND_INDEX_0, (reg));
+   WREG32(TN_SMC_IND_DATA_0, (v));
+}
+
 void r100_pll_errata_after_index(struct radeon_device *rdev);


-- 
1.7.7.5



[PATCH 042/165] drm/radeon: update CIK soft reset

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Update to the newer programming model.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/cik.c  |  387 +
 drivers/gpu/drm/radeon/cikd.h |   12 ++
 2 files changed, 253 insertions(+), 146 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index d241cfd..aaf7bba 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -72,9 +72,11 @@ extern int r600_ih_ring_alloc(struct radeon_device *rdev);
 extern void r600_ih_ring_fini(struct radeon_device *rdev);
 extern void evergreen_mc_stop(struct radeon_device *rdev, struct 
evergreen_mc_save *save);
 extern void evergreen_mc_resume(struct radeon_device *rdev, struct 
evergreen_mc_save *save);
+extern bool evergreen_is_display_hung(struct radeon_device *rdev);
 extern void si_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc 
*mc);
 extern void si_rlc_fini(struct radeon_device *rdev);
 extern int si_rlc_init(struct radeon_device *rdev);
+static void cik_rlc_stop(struct radeon_device *rdev);

 #define BONAIRE_IO_MC_REGS_SIZE 36

@@ -2733,56 +2735,9 @@ int cik_sdma_ib_test(struct radeon_device *rdev, struct 
radeon_ring *ring)
return r;
 }

-/**
- * cik_gpu_is_lockup - check if the 3D engine is locked up
- *
- * @rdev: radeon_device pointer
- * @ring: radeon_ring structure holding ring information
- *
- * Check if the 3D engine is locked up (CIK).
- * Returns true if the engine is locked, false if not.
- */
-bool cik_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
-{
-   u32 srbm_status, srbm_status2;
-   u32 grbm_status, grbm_status2;
-   u32 grbm_status_se0, grbm_status_se1, grbm_status_se2, grbm_status_se3;
-
-   srbm_status = RREG32(SRBM_STATUS);
-   srbm_status2 = RREG32(SRBM_STATUS2);
-   grbm_status = RREG32(GRBM_STATUS);
-   grbm_status2 = RREG32(GRBM_STATUS2);
-   grbm_status_se0 = RREG32(GRBM_STATUS_SE0);
-   grbm_status_se1 = RREG32(GRBM_STATUS_SE1);
-   grbm_status_se2 = RREG32(GRBM_STATUS_SE2);
-   grbm_status_se3 = RREG32(GRBM_STATUS_SE3);
-   if (!(grbm_status & GUI_ACTIVE)) {
-   radeon_ring_lockup_update(ring);
-   return false;
-   }
-   /* force CP activities */
-   radeon_ring_force_activity(rdev, ring);
-   return radeon_ring_test_lockup(rdev, ring);
-}

-/**
- * cik_gfx_gpu_soft_reset - soft reset the 3D engine and CPG
- *
- * @rdev: radeon_device pointer
- *
- * Soft reset the GFX engine and CPG blocks (CIK).
- * XXX: deal with reseting RLC and CPF
- * Returns 0 for success.
- */
-static int cik_gfx_gpu_soft_reset(struct radeon_device *rdev)
+static void cik_print_gpu_status_regs(struct radeon_device *rdev)
 {
-   struct evergreen_mc_save save;
-   u32 grbm_reset = 0;
-
-   if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
-   return 0;
-
-   dev_info(rdev->dev, "GPU GFX softreset \n");
dev_info(rdev->dev, "  GRBM_STATUS=0x%08X\n",
RREG32(GRBM_STATUS));
dev_info(rdev->dev, "  GRBM_STATUS2=0x%08X\n",
@@ -2799,132 +2754,270 @@ static int cik_gfx_gpu_soft_reset(struct 
radeon_device *rdev)
RREG32(SRBM_STATUS));
dev_info(rdev->dev, "  SRBM_STATUS2=0x%08X\n",
RREG32(SRBM_STATUS2));
-   evergreen_mc_stop(rdev, );
-   if (radeon_mc_wait_for_idle(rdev)) {
-   dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
-   }
-   /* Disable CP parsing/prefetching */
-   WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
+   dev_info(rdev->dev, "  SDMA0_STATUS_REG   = 0x%08X\n",
+   RREG32(SDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET));
+   dev_info(rdev->dev, "  SDMA1_STATUS_REG   = 0x%08X\n",
+RREG32(SDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET));
+}

-   /* reset all the gfx block and all CPG blocks */
-   grbm_reset = SOFT_RESET_CPG | SOFT_RESET_GFX;
+/**
+ * cik_gpu_check_soft_reset - check which blocks are busy
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Check which blocks are busy and return the relevant reset
+ * mask to be used by cik_gpu_soft_reset().
+ * Returns a mask of the blocks to be reset.
+ */
+static u32 cik_gpu_check_soft_reset(struct radeon_device *rdev)
+{
+   u32 reset_mask = 0;
+   u32 tmp;

-   dev_info(rdev->dev, "  GRBM_SOFT_RESET=0x%08X\n", grbm_reset);
-   WREG32(GRBM_SOFT_RESET, grbm_reset);
-   (void)RREG32(GRBM_SOFT_RESET);
-   udelay(50);
-   WREG32(GRBM_SOFT_RESET, 0);
-   (void)RREG32(GRBM_SOFT_RESET);
-   /* Wait a little for things to settle down */
-   udelay(50);
-   dev_info(rdev->dev, "  GRBM_STATUS=0x%08X\n",
-   RREG32(GRBM_STATUS));
-   dev_info(rdev->dev, "  GRBM_STATUS2=0x%08X\n",
-   RREG32(GRBM_STATUS2));
-   dev_info(rdev->dev, "  GRBM_STATUS_SE0=0x%08X\n",
-   

[PATCH 041/165] drm/radeon: add get_gpu_clock_counter() callback for cik

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Used for GPU clock counter snapshots.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/cik.c |   21 +
 drivers/gpu/drm/radeon/cikd.h|4 +++-
 drivers/gpu/drm/radeon/radeon_asic.h |5 +
 3 files changed, 29 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 228d399..d241cfd 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -5558,3 +5558,24 @@ void dce8_bandwidth_update(struct radeon_device *rdev)
dce8_program_watermarks(rdev, rdev->mode_info.crtcs[i], 
lb_size, num_heads);
}
 }
+
+/**
+ * cik_get_gpu_clock_counter - return GPU clock counter snapshot
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Fetches a GPU clock counter snapshot (SI).
+ * Returns the 64 bit clock counter snapshot.
+ */
+uint64_t cik_get_gpu_clock_counter(struct radeon_device *rdev)
+{
+   uint64_t clock;
+
+   mutex_lock(>gpu_clock_mutex);
+   WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1);
+   clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) |
+   ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL);
+   mutex_unlock(>gpu_clock_mutex);
+   return clock;
+}
+
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h
index 3349e37..daa51ac 100644
--- a/drivers/gpu/drm/radeon/cikd.h
+++ b/drivers/gpu/drm/radeon/cikd.h
@@ -730,7 +730,9 @@

 #define RLC_GPM_UCODE_ADDR0xC388
 #define RLC_GPM_UCODE_DATA0xC38C
-
+#define RLC_GPU_CLOCK_COUNT_LSB   0xC390
+#define RLC_GPU_CLOCK_COUNT_MSB   0xC394
+#define RLC_CAPTURE_GPU_CLOCK_COUNT   0xC398
 #define RLC_UCODE_CNTL0xC39C

 #define RLC_CGCG_CGLS_CTRL0xC424
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h 
b/drivers/gpu/drm/radeon/radeon_asic.h
index a72759e..248da72 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -553,4 +553,9 @@ u32 si_get_xclk(struct radeon_device *rdev);
 uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev);
 int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);

+/*
+ * cik
+ */
+uint64_t cik_get_gpu_clock_counter(struct radeon_device *rdev);
+
 #endif
-- 
1.7.7.5



[PATCH 040/165] drm/radeon: Update radeon_info_ioctl for CIK (v2)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

v2: rebase changes, fix a couple missed cases

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_kms.c |   33 ++---
 1 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_kms.c 
b/drivers/gpu/drm/radeon/radeon_kms.c
index 4f2d4f4..c650228 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -229,7 +229,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
*value = rdev->accel_working;
break;
case RADEON_INFO_TILING_CONFIG:
-   if (rdev->family >= CHIP_TAHITI)
+   if (rdev->family >= CHIP_BONAIRE)
+   *value = rdev->config.cik.tile_config;
+   else if (rdev->family >= CHIP_TAHITI)
*value = rdev->config.si.tile_config;
else if (rdev->family >= CHIP_CAYMAN)
*value = rdev->config.cayman.tile_config;
@@ -281,7 +283,10 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
*value = rdev->clock.spll.reference_freq * 10;
break;
case RADEON_INFO_NUM_BACKENDS:
-   if (rdev->family >= CHIP_TAHITI)
+   if (rdev->family >= CHIP_BONAIRE)
+   *value = rdev->config.cik.max_backends_per_se *
+   rdev->config.cik.max_shader_engines;
+   else if (rdev->family >= CHIP_TAHITI)
*value = rdev->config.si.max_backends_per_se *
rdev->config.si.max_shader_engines;
else if (rdev->family >= CHIP_CAYMAN)
@@ -298,7 +303,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
}
break;
case RADEON_INFO_NUM_TILE_PIPES:
-   if (rdev->family >= CHIP_TAHITI)
+   if (rdev->family >= CHIP_BONAIRE)
+   *value = rdev->config.cik.max_tile_pipes;
+   else if (rdev->family >= CHIP_TAHITI)
*value = rdev->config.si.max_tile_pipes;
else if (rdev->family >= CHIP_CAYMAN)
*value = rdev->config.cayman.max_tile_pipes;
@@ -316,7 +323,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
*value = 1;
break;
case RADEON_INFO_BACKEND_MAP:
-   if (rdev->family >= CHIP_TAHITI)
+   if (rdev->family >= CHIP_BONAIRE)
+   return -EINVAL;
+   else if (rdev->family >= CHIP_TAHITI)
*value = rdev->config.si.backend_map;
else if (rdev->family >= CHIP_CAYMAN)
*value = rdev->config.cayman.backend_map;
@@ -343,7 +352,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
*value = RADEON_IB_VM_MAX_SIZE;
break;
case RADEON_INFO_MAX_PIPES:
-   if (rdev->family >= CHIP_TAHITI)
+   if (rdev->family >= CHIP_BONAIRE)
+   *value = rdev->config.cik.max_cu_per_sh;
+   else if (rdev->family >= CHIP_TAHITI)
*value = rdev->config.si.max_cu_per_sh;
else if (rdev->family >= CHIP_CAYMAN)
*value = rdev->config.cayman.max_pipes_per_simd;
@@ -367,7 +378,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
value64 = radeon_get_gpu_clock_counter(rdev);
break;
case RADEON_INFO_MAX_SE:
-   if (rdev->family >= CHIP_TAHITI)
+   if (rdev->family >= CHIP_BONAIRE)
+   *value = rdev->config.cik.max_shader_engines;
+   else if (rdev->family >= CHIP_TAHITI)
*value = rdev->config.si.max_shader_engines;
else if (rdev->family >= CHIP_CAYMAN)
*value = rdev->config.cayman.max_shader_engines;
@@ -377,7 +390,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
*value = 1;
break;
case RADEON_INFO_MAX_SH_PER_SE:
-   if (rdev->family >= CHIP_TAHITI)
+   if (rdev->family >= CHIP_BONAIRE)
+   *value = rdev->config.cik.max_sh_per_se;
+   else if (rdev->family >= CHIP_TAHITI)
*value = rdev->config.si.max_sh_per_se;
else
return -EINVAL;
@@ -407,6 +422,10 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
}
break;
case RADEON_INFO_SI_TILE_MODE_ARRAY:
+   if (rdev->family >= CHIP_BONAIRE) {
+   

[PATCH 039/165] drm/radeon: add SS override support for KB/KV

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_atombios.c |   17 +
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c 
b/drivers/gpu/drm/radeon/radeon_atombios.c
index 88a55af..3236755 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -1269,6 +1269,7 @@ union igp_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)
@@ -1438,6 +1439,22 @@ static void radeon_atombios_get_igp_ss_overrides(struct 
radeon_device *rdev,
break;
}
break;
+   case 8:
+   switch (id) {
+   case ASIC_INTERNAL_SS_ON_TMDS:
+   percentage = 
le16_to_cpu(igp_info->info_8.usDVISSPercentage);
+   rate = 
le16_to_cpu(igp_info->info_8.usDVISSpreadRateIn10Hz);
+   break;
+   case ASIC_INTERNAL_SS_ON_HDMI:
+   percentage = 
le16_to_cpu(igp_info->info_8.usHDMISSPercentage);
+   rate = 
le16_to_cpu(igp_info->info_8.usHDMISSpreadRateIn10Hz);
+   break;
+   case ASIC_INTERNAL_SS_ON_LVDS:
+   percentage = 
le16_to_cpu(igp_info->info_8.usLvdsSSPercentage);
+   rate = 
le16_to_cpu(igp_info->info_8.usLvdsSSpreadRateIn10Hz);
+   break;
+   }
+   break;
default:
DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
break;
-- 
1.7.7.5



[PATCH 038/165] drm/radeon: use frac fb div on DCE8

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/atombios_crtc.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c 
b/drivers/gpu/drm/radeon/atombios_crtc.c
index 24eee7c..c7ad4b9 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -555,7 +555,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
if (rdev->family < CHIP_RV770)
radeon_crtc->pll_flags |= 
RADEON_PLL_PREFER_MINM_OVER_MAXP;
/* use frac fb div on APUs */
-   if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
+   if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev) || 
ASIC_IS_DCE8(rdev))
radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
/* use frac fb div on RS780/RS880 */
if ((rdev->family == CHIP_RS780) || (rdev->family == 
CHIP_RS880))
-- 
1.7.7.5



[PATCH 037/165] drm/radeon: Handle PPLL0 powerdown on DCE8

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Only Bonaire has PPLL0.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/atombios_crtc.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c 
b/drivers/gpu/drm/radeon/atombios_crtc.c
index 590e4eb..24eee7c 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1931,7 +1931,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
break;
case ATOM_PPLL0:
/* disable the ppll */
-   if (ASIC_IS_DCE61(rdev))
+   if ((rdev->family == CHIP_ARUBA) || (rdev->family == 
CHIP_BONAIRE))
atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, 
radeon_crtc->pll_id,
  0, 0, ATOM_DISABLE, 0, 0, 0, 
0, 0, false, );
break;
-- 
1.7.7.5



[PATCH 036/165] drm/radeon: add support pll selection for DCE8 (v4)

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

v2: make PPLL0 is available for non-DP on CI
v3: rebase changes, update documentation
v4: fix kabini

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/atombios_crtc.c |   48 +++-
 1 files changed, 47 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c 
b/drivers/gpu/drm/radeon/atombios_crtc.c
index 586c452..590e4eb 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1621,6 +1621,12 @@ static int radeon_get_shared_nondp_ppll(struct drm_crtc 
*crtc)
  *
  * Asic specific PLL information
  *
+ * DCE 8.x
+ * KB/KV
+ * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP)
+ * CI
+ * - PPLL0, PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and 
DAC
+ *
  * DCE 6.1
  * - PPLL2 is only available to UNIPHYA (both DP and non-DP)
  * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP)
@@ -1647,7 +1653,47 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
u32 pll_in_use;
int pll;

-   if (ASIC_IS_DCE61(rdev)) {
+   if (ASIC_IS_DCE8(rdev)) {
+   if 
(ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
+   if (rdev->clock.dp_extclk)
+   /* skip PPLL programming if using ext clock */
+   return ATOM_PPLL_INVALID;
+   else {
+   /* use the same PPLL for all DP monitors */
+   pll = radeon_get_shared_dp_ppll(crtc);
+   if (pll != ATOM_PPLL_INVALID)
+   return pll;
+   }
+   } else {
+   /* use the same PPLL for all monitors with the same 
clock */
+   pll = radeon_get_shared_nondp_ppll(crtc);
+   if (pll != ATOM_PPLL_INVALID)
+   return pll;
+   }
+   /* otherwise, pick one of the plls */
+   if ((rdev->family == CHIP_KAVERI) ||
+   (rdev->family == CHIP_KABINI)) {
+   /* KB/KV has PPLL1 and PPLL2 */
+   pll_in_use = radeon_get_pll_use_mask(crtc);
+   if (!(pll_in_use & (1 << ATOM_PPLL2)))
+   return ATOM_PPLL2;
+   if (!(pll_in_use & (1 << ATOM_PPLL1)))
+   return ATOM_PPLL1;
+   DRM_ERROR("unable to allocate a PPLL\n");
+   return ATOM_PPLL_INVALID;
+   } else {
+   /* CI has PPLL0, PPLL1, and PPLL2 */
+   pll_in_use = radeon_get_pll_use_mask(crtc);
+   if (!(pll_in_use & (1 << ATOM_PPLL2)))
+   return ATOM_PPLL2;
+   if (!(pll_in_use & (1 << ATOM_PPLL1)))
+   return ATOM_PPLL1;
+   if (!(pll_in_use & (1 << ATOM_PPLL0)))
+   return ATOM_PPLL0;
+   DRM_ERROR("unable to allocate a PPLL\n");
+   return ATOM_PPLL_INVALID;
+   }
+   } else if (ASIC_IS_DCE61(rdev)) {
struct radeon_encoder_atom_dig *dig =
radeon_encoder->enc_priv;

-- 
1.7.7.5



[PATCH 035/165] drm/radeon: update DISPCLK programming for DCE8

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/atombios_crtc.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c 
b/drivers/gpu/drm/radeon/atombios_crtc.c
index 4ba5184..586c452 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -743,7 +743,7 @@ static void atombios_crtc_set_disp_eng_pll(struct 
radeon_device *rdev,
 * SetPixelClock provides the dividers
 */
args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk);
-   if (ASIC_IS_DCE61(rdev))
+   if (ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev))
args.v6.ucPpll = ATOM_EXT_PLL1;
else if (ASIC_IS_DCE6(rdev))
args.v6.ucPpll = ATOM_PPLL0;
-- 
1.7.7.5



[PATCH 034/165] drm/radeon/atom: add support for new DVO tables

2013-06-26 Thread alexdeuc...@gmail.com
From: Alex Deucher 

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/atombios_encoders.c |9 -
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c 
b/drivers/gpu/drm/radeon/atombios_encoders.c
index 1bf13b3..092275d 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -487,11 +487,11 @@ static u8 radeon_atom_get_bpc(struct drm_encoder *encoder)
}
 }

-
 union dvo_encoder_control {
ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds;
DVO_ENCODER_CONTROL_PS_ALLOCATION dvo;
DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3;
+   DVO_ENCODER_CONTROL_PS_ALLOCATION_V1_4 dvo_v4;
 };

 void
@@ -541,6 +541,13 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action)
args.dvo_v3.usPixelClock = 
cpu_to_le16(radeon_encoder->pixel_clock / 10);
args.dvo_v3.ucDVOConfig = 0; /* XXX */
break;
+   case 4:
+   /* DCE8 */
+   args.dvo_v4.ucAction = action;
+   args.dvo_v4.usPixelClock = 
cpu_to_le16(radeon_encoder->pixel_clock / 10);
+   args.dvo_v4.ucDVOConfig = 0; /* XXX */
+   args.dvo_v4.ucBitPerColor = 
radeon_atom_get_bpc(encoder);
+   break;
default:
DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
break;
-- 
1.7.7.5



  1   2   3   4   5   6   >