All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/89] Basic Skylake enabling
@ 2014-09-04 11:26 Damien Lespiau
  2014-09-04 11:26 ` [PATCH 01/89] drm/i915/skl: Add the Skylake PCI ids Damien Lespiau
                   ` (89 more replies)
  0 siblings, 90 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

Hi,

This series implements basic enabling for Skylake (SKL), bringing us to roughly
feature parity with earlier platforms.

Skylake (SKL) is the latest Intel® Processor containing Intel® HD Graphics.

The major GPU hardware features include:
- Gen9 Intel® HD Graphics graphics
- The addition of a 3rd display plane (not concurrent with the cursor)
- Five HDMI/DP/eDP display ports

The bulk of the series is on the display side where things have changed quite a
bit with new DPLL, watermarks and display planes code. The remaining of the
patches deals with incremental changes in various features of the device: RC6,
forcewake engines, power wells, execlists, ...

Big thanks to everyone who contributed for their tireless efforts.

-- 
Damien

Daisy Sun (1):
  drm/i915/skl: SKL FBC enablement

Damien Lespiau (49):
  drm/i915/skl: Add the Skylake PCI ids
  drm/i915/skl: Add an IS_GEN9() define
  drm/i915/skl: Fence registers on SKL are the same as SNB
  drm/i915/skl: Provide a placeholder for init_clock_gating()
  drm/i915/skl: Use gen8_ring_dispatch_execbuffer() on GEN9
  drm/i915/skl: Skylake shares the interrupt logic with Broadwell
  drm/i915/skl: Framebuffers need to be aligned to 256Kb on Skylake
  drm/i915/skl: Implement thew new update_plane() for primary planes
  drm/i915/skl: Don't create a VGA connector on Skylake
  drm/i915/skl: Don't try to read out the PCH transcoder state if not
    present
  drm/i915/skl: Program the DDI buffer translation tables
  drm/i915/skl: Add support for DP voltage swings and pre-emphasis
  drm/i915/skl: Skylake doesn't need the DP AUX clock divider programmed
  drm/i915/skl: Skylake moves AUX_CTL from PCH to CPU
  drm/i915/skl: Add the additional graphics stolen sizes
  drm/i915/skl: gen9 uses the same bind_vma() vfuncs as gen6+
  drm/i915/skl: Implement the get_aux_clock_divider() DP vfunc
  drm/i915/skl: Provide a get_aux_send_ctl() vfunc for skylake
  drm/i915/skl: Initialize PPGTT like gen8
  drm/i915/skl: Allow the reg_read ioctl to return RCS_TIMESTAMP
  drm/i915/skl: report the same INSTDONE registers as gen8
  drm/i915/skl: Report the PDP regs as in gen8
  drm/i915/skl: SKL shares the same underrun interrupt as BDW
  drm/i915/skl: Adjust the display engine interrupts
  drm/i915/skl: Implement WaDisableSDEUnitClockGating:skl
  drm/i915/skl: Implement Wa4x4STCOptimizationDisable:skl
  drm/i915/skl: Implement WaDisableDgMirrorFixInHalfSliceChicken5:skl
  drm/i915/skl: Skylake has 2 "sprite" planes per pipe
  drm/i915/skl: Implement drm_plane vfuncs
  drm/i915/skl: Adjust assert_sprites_disabled()
  drm/i915/skl: Introduce a I915_MAX_PLANES macro
  drm/i915/skl: Introduce intel_num_planes()
  drm/i915/skl: Move gen9 pm initialization into its own branch
  drm/i915/skl: Add DDB allocation management structures
  drm/i915/skl: Allocate DDB portions for display planes
  drm/i915/skl: Program the DDB allocation
  drm/i915: Rewrite ABS_DIFF() in a safer manner
  drm/i915/skl: Provide skl-specific pll hw state cross-checking
  drm/i915/skl: Implement queue_flip
  drm/i915/skl: Store the new WM state at the very end of the update
  drm/i915: Introduce a for_each_plane() macro
  drm/i915/skl: Flush the WM configuration
  drm/i915/skl: Read back the DDB allocation hw state
  drm/i915/skl: Augment the latency debugfs files for SKL
  drm/i915/skl: Expose skl_ddb_get_hw_state()
  drm/i915/skl: Add a debugfs file to dump the DDB allocation
  drm/i915/skl: Check the DDB state at modeset
  drm/i915/skl: Retrieve the frequency limits
  drm/i915/skl: Disable contexts if execlists aren't enabled

Imre Deak (1):
  drm/i915/skl: don't set the AsyncFlip performance mode for Gen9+

Jesse Barnes (4):
  drm/i915/skl: fetch, enable/disable pfit as needed
  drm/i915/skl: add turbo support
  drm/i915: only reset media, blt, and render engines on GPU hangs
  drm/i915/skl: AUX irqs have moved

Michael H. Nguyen (1):
  drm/i915/skl: Add Gen9 LRC size

Pradeep Bhat (5):
  drm/i915/skl: Read the Memory Latency Values for WM computation
  drm/i915/skl: Register definitions and macros for SKL Watermark regs
  drm/i915/skl: Definition of SKL WM param structs for pipe/plane
  drm/i915/skl: SKL Watermark Computation
  drm/i915/skl: Read the pipe WM HW state

Robert Beckett (1):
  drm/i915/skl: i915_swizzle_info gen9 fix

Satheeshakrishna M (20):
  drm/i915/skl: Add an IS_SKYLAKE macro
  drm/i915/skl: SKL pipe misc programming
  drm/i915/skl: vfuncs for skl eld and global resource
  drm/i915/skl: SKL backlight enabling
  drm/i915/skl: Restore pipe B/C interrupts
  drm/i915/skl: Sunrise Point PCH detection
  drm/i915/skl: Register definitions for SKL Clocks
  drm/i915/skl: Structure/enum definitions for SKL clocks
  drm/i915/skl: CD clock back calculation for SKL
  drm/i915/skl: Determine enabled PLL and its linkrate/pixel clock
  drm/i915/skl: Query DPLL attached to port on SKL
  drm/i915/skl: Define shared DPLLs for Skylake
  drm/i915/skl: Adjust the port PLL selection code
  drm/i915/skl: Always use DPLL0 for eDP
  drm/i915/skl: Implementation of SKL DPLL programming
  drm/i915/skl: Adding power domains for AUX controllers
  drm/i915/skl: Register definition for SKL power well
  drm/i915/skl: Implementation of SKL display power well support
  drm/i915/skl: Enable/disable power well for aux transaction
  drm/i915/skl: Enabling MISC IO power well

Vandana Kannan (3):
  drm/i915/gen9: Add 2us read latency to WM level
  drm/i915/gen9: Disable WM if corresponding latency is 0
  drm/i915/skl: Apply eDP WA only for gen < 9

Zhe Wang (4):
  drm/i915/skl: Gen9 Forcewake
  drm/i915/skl: Enable Gen9 RC6
  drm/i915/skl: Gen9 multi-engine forcewake
  drm/i915: Gen9 shadowed registers

 arch/x86/kernel/early-quirks.c          |   23 +
 drivers/gpu/drm/i915/i915_debugfs.c     |  123 ++-
 drivers/gpu/drm/i915/i915_dma.c         |    2 +-
 drivers/gpu/drm/i915/i915_drv.c         |   26 +-
 drivers/gpu/drm/i915/i915_drv.h         |  117 ++-
 drivers/gpu/drm/i915/i915_gem.c         |    1 +
 drivers/gpu/drm/i915/i915_gem_context.c |    2 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c     |   20 +-
 drivers/gpu/drm/i915/i915_gpu_error.c   |    3 +
 drivers/gpu/drm/i915/i915_irq.c         |   54 +-
 drivers/gpu/drm/i915/i915_reg.h         |  359 +++++++-
 drivers/gpu/drm/i915/intel_ddi.c        |  629 +++++++++++++-
 drivers/gpu/drm/i915/intel_display.c    |  358 +++++++-
 drivers/gpu/drm/i915/intel_dp.c         |  136 ++-
 drivers/gpu/drm/i915/intel_drv.h        |   28 +-
 drivers/gpu/drm/i915/intel_lrc.c        |    8 +-
 drivers/gpu/drm/i915/intel_panel.c      |    2 +-
 drivers/gpu/drm/i915/intel_pm.c         | 1385 +++++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/intel_ringbuffer.c |    4 +-
 drivers/gpu/drm/i915/intel_sprite.c     |  206 ++++-
 drivers/gpu/drm/i915/intel_uncore.c     |  324 +++++++-
 include/drm/i915_pciids.h               |   17 +
 22 files changed, 3651 insertions(+), 176 deletions(-)

-- 
1.8.3.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* [PATCH 01/89] drm/i915/skl: Add the Skylake PCI ids
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 11:26 ` [PATCH 02/89] drm/i915/skl: Add an IS_GEN9() define Damien Lespiau
                   ` (88 subsequent siblings)
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

v2: Squash in 2nd patch from Damien for more ids (Daniel)
v3: info->has*ring -> info->ring_mask conversion. Also add VEBOX support.
v4: Fold in update from Damien
v5: Rebase and add GEN_DEFAULT_PIPEOFFSETS
v6: Add more PCI ID (Vandana)
v7: Rebase and add IVB_CURSOR_OFFSETS
v8: Renamed the macro from _PCI_IDS to _IDS for consistency

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c | 14 +++++++++++++-
 include/drm/i915_pciids.h       | 17 +++++++++++++++++
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 8ff3755..0f6de1e7 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -356,6 +356,17 @@ static const struct intel_device_info intel_cherryview_info = {
 	CURSOR_OFFSETS,
 };
 
+static const struct intel_device_info intel_skylake_info = {
+	.is_preliminary = 1,
+	.gen = 9, .num_pipes = 3,
+	.need_gfx_hws = 1, .has_hotplug = 1,
+	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
+	.has_llc = 1,
+	.has_ddi = 1,
+	GEN_DEFAULT_PIPEOFFSETS,
+	IVB_CURSOR_OFFSETS,
+};
+
 /*
  * Make sure any device matches here are from most specific to most
  * general.  For example, since the Quanta match is based on the subsystem
@@ -392,7 +403,8 @@ static const struct intel_device_info intel_cherryview_info = {
 	INTEL_BDW_GT12D_IDS(&intel_broadwell_d_info),	\
 	INTEL_BDW_GT3M_IDS(&intel_broadwell_gt3m_info),	\
 	INTEL_BDW_GT3D_IDS(&intel_broadwell_gt3d_info), \
-	INTEL_CHV_IDS(&intel_cherryview_info)
+	INTEL_CHV_IDS(&intel_cherryview_info),	\
+	INTEL_SKL_IDS(&intel_skylake_info)
 
 static const struct pci_device_id pciidlist[] = {		/* aka */
 	INTEL_PCI_IDS,
diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h
index a70d456..180ad0e 100644
--- a/include/drm/i915_pciids.h
+++ b/include/drm/i915_pciids.h
@@ -259,4 +259,21 @@
 	INTEL_VGA_DEVICE(0x22b2, info), \
 	INTEL_VGA_DEVICE(0x22b3, info)
 
+#define INTEL_SKL_IDS(info) \
+	INTEL_VGA_DEVICE(0x1916, info), /* ULT GT2 */ \
+	INTEL_VGA_DEVICE(0x1906, info), /* ULT GT1 */ \
+	INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */ \
+	INTEL_VGA_DEVICE(0x1921, info), /* ULT GT2F */ \
+	INTEL_VGA_DEVICE(0x190E, info), /* ULX GT1 */ \
+	INTEL_VGA_DEVICE(0x191E, info), /* ULX GT2 */ \
+	INTEL_VGA_DEVICE(0x1912, info), /* DT  GT2 */ \
+	INTEL_VGA_DEVICE(0x1902, info), /* DT  GT1 */ \
+	INTEL_VGA_DEVICE(0x191B, info), /* Halo GT2 */ \
+	INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */ \
+	INTEL_VGA_DEVICE(0x190B, info), /* Halo GT1 */ \
+	INTEL_VGA_DEVICE(0x191A, info), /* SRV GT2 */ \
+	INTEL_VGA_DEVICE(0x192A, info), /* SRV GT3 */ \
+	INTEL_VGA_DEVICE(0x190A, info), /* SRV GT1 */ \
+	INTEL_VGA_DEVICE(0x191D, info)  /* WKS GT2 */
+
 #endif /* _I915_PCIIDS_H */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 02/89] drm/i915/skl: Add an IS_GEN9() define
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
  2014-09-04 11:26 ` [PATCH 01/89] drm/i915/skl: Add the Skylake PCI ids Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 11:26 ` [PATCH 03/89] drm/i915/skl: Add an IS_SKYLAKE macro Damien Lespiau
                   ` (87 subsequent siblings)
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e845a81..854d65c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2114,6 +2114,7 @@ struct drm_i915_cmd_table {
 #define IS_GEN6(dev)	(INTEL_INFO(dev)->gen == 6)
 #define IS_GEN7(dev)	(INTEL_INFO(dev)->gen == 7)
 #define IS_GEN8(dev)	(INTEL_INFO(dev)->gen == 8)
+#define IS_GEN9(dev)	(INTEL_INFO(dev)->gen == 9)
 
 #define RENDER_RING		(1<<RCS)
 #define BSD_RING		(1<<VCS)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 03/89] drm/i915/skl: Add an IS_SKYLAKE macro
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
  2014-09-04 11:26 ` [PATCH 01/89] drm/i915/skl: Add the Skylake PCI ids Damien Lespiau
  2014-09-04 11:26 ` [PATCH 02/89] drm/i915/skl: Add an IS_GEN9() define Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 11:26 ` [PATCH 04/89] drm/i915/skl: SKL FBC enablement Damien Lespiau
                   ` (86 subsequent siblings)
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

Adding new macro IS_SKYLAKE for skylake specific implementation.

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c | 1 +
 drivers/gpu/drm/i915/i915_drv.h | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 0f6de1e7..35cf643 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -358,6 +358,7 @@ static const struct intel_device_info intel_cherryview_info = {
 
 static const struct intel_device_info intel_skylake_info = {
 	.is_preliminary = 1,
+	.is_skylake = 1,
 	.gen = 9, .num_pipes = 3,
 	.need_gfx_hws = 1, .has_hotplug = 1,
 	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 854d65c..4cc028a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -545,6 +545,7 @@ struct intel_uncore {
 	func(is_ivybridge) sep \
 	func(is_valleyview) sep \
 	func(is_haswell) sep \
+	func(is_skylake) sep \
 	func(is_preliminary) sep \
 	func(has_fbc) sep \
 	func(has_pipe_cxsr) sep \
@@ -2084,6 +2085,7 @@ struct drm_i915_cmd_table {
 #define IS_CHERRYVIEW(dev)	(INTEL_INFO(dev)->is_valleyview && IS_GEN8(dev))
 #define IS_HASWELL(dev)	(INTEL_INFO(dev)->is_haswell)
 #define IS_BROADWELL(dev)	(!INTEL_INFO(dev)->is_valleyview && IS_GEN8(dev))
+#define IS_SKYLAKE(dev)	(INTEL_INFO(dev)->is_skylake)
 #define IS_MOBILE(dev)		(INTEL_INFO(dev)->is_mobile)
 #define IS_HSW_EARLY_SDV(dev)	(IS_HASWELL(dev) && \
 				 (INTEL_DEVID(dev) & 0xFF00) == 0x0C00)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 04/89] drm/i915/skl: SKL FBC enablement
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (2 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 03/89] drm/i915/skl: Add an IS_SKYLAKE macro Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 11:26 ` [PATCH 05/89] drm/i915/skl: i915_swizzle_info gen9 fix Damien Lespiau
                   ` (85 subsequent siblings)
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

From: Daisy Sun <daisy.sun@intel.com>

Enable FBC feature on Skylake

Issue: VIZ-3788
Signed-off-by: Daisy Sun <daisy.sun@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 35cf643..3d7f823 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -364,6 +364,7 @@ static const struct intel_device_info intel_skylake_info = {
 	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
 	.has_llc = 1,
 	.has_ddi = 1,
+	.has_fbc = 1,
 	GEN_DEFAULT_PIPEOFFSETS,
 	IVB_CURSOR_OFFSETS,
 };
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 05/89] drm/i915/skl: i915_swizzle_info gen9 fix
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (3 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 04/89] drm/i915/skl: SKL FBC enablement Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 13:14   ` Daniel Vetter
  2014-09-04 11:26 ` [PATCH 06/89] drm/i915/skl: Fence registers on SKL are the same as SNB Damien Lespiau
                   ` (84 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

From: Robert Beckett <robert.beckett@intel.com>

Fix ARB_MODE register read for gen >= 8 in i915_swizzle_info

Signed-off-by: Robert Beckett <robert.beckett@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index d8389b2..88a4643 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1971,7 +1971,7 @@ static int i915_swizzle_info(struct seq_file *m, void *data)
 			   I915_READ(MAD_DIMM_C2));
 		seq_printf(m, "TILECTL = 0x%08x\n",
 			   I915_READ(TILECTL));
-		if (IS_GEN8(dev))
+		if (INTEL_INFO(dev)->gen >= 8)
 			seq_printf(m, "GAMTARBMODE = 0x%08x\n",
 				   I915_READ(GAMTARBMODE));
 		else
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 06/89] drm/i915/skl: Fence registers on SKL are the same as SNB
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (4 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 05/89] drm/i915/skl: i915_swizzle_info gen9 fix Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 11:26 ` [PATCH 07/89] drm/i915/skl: Provide a placeholder for init_clock_gating() Damien Lespiau
                   ` (83 subsequent siblings)
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

v1: Rebased on top of the i915_gpu_error.c extraction.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c       | 1 +
 drivers/gpu/drm/i915/i915_gpu_error.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6c68570..41edc40 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3148,6 +3148,7 @@ static void i915_gem_write_fence(struct drm_device *dev, int reg,
 	     obj->stride, obj->tiling_mode);
 
 	switch (INTEL_INFO(dev)->gen) {
+	case 9:
 	case 8:
 	case 7:
 	case 6:
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 2c87a79..68fd767 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -765,6 +765,7 @@ static void i915_gem_record_fences(struct drm_device *dev,
 
 	/* Fences */
 	switch (INTEL_INFO(dev)->gen) {
+	case 9:
 	case 8:
 	case 7:
 	case 6:
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 07/89] drm/i915/skl: Provide a placeholder for init_clock_gating()
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (5 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 06/89] drm/i915/skl: Fence registers on SKL are the same as SNB Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 11:26 ` [PATCH 08/89] drm/i915/skl: Use gen8_ring_dispatch_execbuffer() on GEN9 Damien Lespiau
                   ` (82 subsequent siblings)
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

v2: Rebase on top of the broadwell_init_clock_gating() name change

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 49af81f..23eea92 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -66,6 +66,10 @@
  * i915.i915_enable_fbc parameter
  */
 
+static void gen9_init_clock_gating(struct drm_device *dev)
+{
+}
+
 static void i8xx_disable_fbc(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -7395,6 +7399,8 @@ void intel_init_pm(struct drm_device *dev)
 			dev_priv->display.init_clock_gating = haswell_init_clock_gating;
 		else if (INTEL_INFO(dev)->gen == 8)
 			dev_priv->display.init_clock_gating = broadwell_init_clock_gating;
+		else if (INTEL_INFO(dev)->gen == 9)
+			dev_priv->display.init_clock_gating = gen9_init_clock_gating;
 	} else if (IS_CHERRYVIEW(dev)) {
 		dev_priv->display.update_wm = cherryview_update_wm;
 		dev_priv->display.update_sprite_wm = valleyview_update_sprite_wm;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 08/89] drm/i915/skl: Use gen8_ring_dispatch_execbuffer() on GEN9
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (6 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 07/89] drm/i915/skl: Provide a placeholder for init_clock_gating() Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-16 14:53   ` Thomas Wood
  2014-09-04 11:26 ` [PATCH 09/89] drm/i915/skl: Skylake shares the interrupt logic with Broadwell Damien Lespiau
                   ` (81 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_ringbuffer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index f8aadc3..7b3d0ca 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2361,7 +2361,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
 
 	if (IS_HASWELL(dev))
 		ring->dispatch_execbuffer = hsw_ring_dispatch_execbuffer;
-	else if (IS_GEN8(dev))
+	else if (INTEL_INFO(dev)->gen >= 8)
 		ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
 	else if (INTEL_INFO(dev)->gen >= 6)
 		ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 09/89] drm/i915/skl: Skylake shares the interrupt logic with Broadwell
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (7 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 08/89] drm/i915/skl: Use gen8_ring_dispatch_execbuffer() on GEN9 Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 11:26 ` [PATCH 10/89] drm/i915/skl: don't set the AsyncFlip performance mode for Gen9+ Damien Lespiau
                   ` (80 subsequent siblings)
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b964824..e9979f5 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -4749,7 +4749,7 @@ void intel_irq_init(struct drm_device *dev)
 		dev->driver->enable_vblank = valleyview_enable_vblank;
 		dev->driver->disable_vblank = valleyview_disable_vblank;
 		dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
-	} else if (IS_GEN8(dev)) {
+	} else if (INTEL_INFO(dev)->gen >= 8) {
 		dev->driver->irq_handler = gen8_irq_handler;
 		dev->driver->irq_preinstall = gen8_irq_reset;
 		dev->driver->irq_postinstall = gen8_irq_postinstall;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 10/89] drm/i915/skl: don't set the AsyncFlip performance mode for Gen9+
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (8 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 09/89] drm/i915/skl: Skylake shares the interrupt logic with Broadwell Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 11:26 ` [PATCH 11/89] drm/i915/skl: Framebuffers need to be aligned to 256Kb on Skylake Damien Lespiau
                   ` (79 subsequent siblings)
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

From: Imre Deak <imre.deak@intel.com>

The following sets the AsyncFlip performance mode for everything above
Gen6:

commit 4790cb36b3eede8fb0cca529dc1d31b9936fa24b
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sun Jan 20 16:11:20 2013 +0000

    drm/i915: Disable AsyncFlip performance optimisations

Starting from Gen9 the MI_MODE register layout changes and doesn't
include the above bit.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_ringbuffer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 7b3d0ca..4e8b2ea 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -815,7 +815,7 @@ static int init_render_ring(struct intel_engine_cs *ring)
 	 *
 	 * WaDisableAsyncFlipPerfMode:snb,ivb,hsw,vlv,bdw,chv
 	 */
-	if (INTEL_INFO(dev)->gen >= 6)
+	if (INTEL_INFO(dev)->gen >= 6 && INTEL_INFO(dev)->gen < 9)
 		I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE));
 
 	/* Required for the hardware to program scanline values for waiting */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 11/89] drm/i915/skl: Framebuffers need to be aligned to 256Kb on Skylake
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (9 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 10/89] drm/i915/skl: don't set the AsyncFlip performance mode for Gen9+ Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-16 14:54   ` Thomas Wood
  2014-09-04 11:26 ` [PATCH 12/89] drm/i915/skl: Implement thew new update_plane() for primary planes Damien Lespiau
                   ` (78 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 22d3902..02236f9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2199,7 +2199,9 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
 
 	switch (obj->tiling_mode) {
 	case I915_TILING_NONE:
-		if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
+		if (INTEL_INFO(dev)->gen >= 9)
+			alignment = 256 * 1024;
+		else if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
 			alignment = 128 * 1024;
 		else if (INTEL_INFO(dev)->gen >= 4)
 			alignment = 4 * 1024;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 12/89] drm/i915/skl: Implement thew new update_plane() for primary planes
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (10 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 11/89] drm/i915/skl: Framebuffers need to be aligned to 256Kb on Skylake Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-17  0:49   ` Rodrigo Vivi
  2014-09-04 11:26 ` [PATCH 13/89] drm/i915/skl: Don't create a VGA connector on Skylake Damien Lespiau
                   ` (77 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

Skylake makes primary planes the same as sprite planes and call the
result "universal planes".

This commit emulates a primary plane with plane 0, taking the
opportunity to redefine primary and sprite registers to be identical now
that the underlying hardware is. It also makes sense as plenty of fields
have changed.

v2: Rebase on top of the vma code.

v3: Follow upstream evolution:
- Drop return values.
- Remove pipe checks since redudant and BUG instead.
- Remove tiling checks and BUG instead.
- Drop commented out DISP_MODIFY usage.

v4: s/plane/primary_plane/

v5: Misc fixes:
- Fix the fields we need to clear up
- Disable trickle feed
- Correctly use PLANE_OFFSET for the panning

v6: (Jesse)
Use pipe src size when programming plane size. This makes cloned configs
work correctly w/o the use of a panel fitter.

v7: Rebase on top of Ville's rmw elimination series

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v1,5,6,7)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v2,3)
---
 drivers/gpu/drm/i915/i915_reg.h      | 110 ++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_display.c |  88 +++++++++++++++++++++++++++-
 2 files changed, 195 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 15c0eaa..087085c 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -26,8 +26,8 @@
 #define _I915_REG_H_
 
 #define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a)))
+#define _PLANE(plane, a, b) _PIPE(plane, a, b)
 #define _TRANSCODER(tran, a, b) ((a) + (tran)*((b)-(a)))
-
 #define _PORT(port, a, b) ((a) + (port)*((b)-(a)))
 #define _PIPE3(pipe, a, b, c) ((pipe) == PIPE_A ? (a) : \
 			       (pipe) == PIPE_B ? (b) : (c))
@@ -4495,6 +4495,114 @@ enum punit_power_well {
 #define SPCONSTALPHA(pipe, plane) _PIPE(pipe * 2 + plane, _SPACONSTALPHA, _SPBCONSTALPHA)
 #define SPGAMC(pipe, plane) _PIPE(pipe * 2 + plane, _SPAGAMC, _SPBGAMC)
 
+/* Skylake plane registers */
+
+#define _PLANE_CTL_1_A				0x70180
+#define _PLANE_CTL_2_A				0x70280
+#define _PLANE_CTL_3_A				0x70380
+#define   PLANE_CTL_ENABLE			(1 << 31)
+#define   PLANE_CTL_PIPE_GAMMA_ENABLE		(1 << 30)
+#define   PLANE_CTL_FORMAT_MASK			(0xf << 24)
+#define   PLANE_CTL_FORMAT_YUV422		(  0 << 24)
+#define   PLANE_CTL_FORMAT_NV12			(  1 << 24)
+#define   PLANE_CTL_FORMAT_XRGB_2101010		(  2 << 24)
+#define   PLANE_CTL_FORMAT_XRGB_8888		(  4 << 24)
+#define   PLANE_CTL_FORMAT_XRGB_16161616F	(  6 << 24)
+#define   PLANE_CTL_FORMAT_AYUV			(  8 << 24)
+#define   PLANE_CTL_FORMAT_INDEXED		( 12 << 24)
+#define   PLANE_CTL_FORMAT_RGB_565		( 14 << 24)
+#define   PLANE_CTL_PIPE_CSC_ENABLE		(1 << 23)
+#define   PLANE_CTL_KEY_ENABLE			(1 << 22)
+#define   PLANE_CTL_ORDER_BGRX			(0 << 20)
+#define   PLANE_CTL_ORDER_RGBX			(1 << 20)
+#define   PLANE_CTL_YUV422_ORDER_MASK		(0x3 << 16)
+#define   PLANE_CTL_YUV422_YUYV			(  0 << 16)
+#define   PLANE_CTL_YUV422_UYVY			(  1 << 16)
+#define   PLANE_CTL_YUV422_YVYU			(  2 << 16)
+#define   PLANE_CTL_YUV422_VYUY			(  3 << 16)
+#define   PLANE_CTL_DECOMPRESSION_ENABLE	(1 << 15)
+#define   PLANE_CTL_TRICKLE_FEED_DISABLE	(1 << 14)
+#define   PLANE_CTL_PLANE_GAMMA_DISABLE		(1 << 13)
+#define   PLANE_CTL_TILED_MASK			(0x7 << 10)
+#define   PLANE_CTL_TILED_LINEAR		(  0 << 10)
+#define   PLANE_CTL_TILED_X			(  1 << 10)
+#define   PLANE_CTL_TILED_Y			(  4 << 10)
+#define   PLANE_CTL_TILED_YF			(  5 << 10)
+#define   PLANE_CTL_ALPHA_MASK			(0x3 << 4)
+#define   PLANE_CTL_ALPHA_DISABLE		(  0 << 4)
+#define   PLANE_CTL_ALPHA_SW_PREMULTIPLY	(  2 << 4)
+#define   PLANE_CTL_ALPHA_HW_PREMULTIPLY	(  3 << 4)
+#define _PLANE_STRIDE_1_A			0x70188
+#define _PLANE_STRIDE_2_A			0x70288
+#define _PLANE_STRIDE_3_A			0x70388
+#define _PLANE_POS_1_A				0x7018c
+#define _PLANE_POS_2_A				0x7028c
+#define _PLANE_POS_3_A				0x7038c
+#define _PLANE_SIZE_1_A				0x70190
+#define _PLANE_SIZE_2_A				0x70290
+#define _PLANE_SIZE_3_A				0x70390
+#define _PLANE_SURF_1_A				0x7019c
+#define _PLANE_SURF_2_A				0x7029c
+#define _PLANE_SURF_3_A				0x7039c
+#define _PLANE_OFFSET_1_A			0x701a4
+#define _PLANE_OFFSET_2_A			0x702a4
+#define _PLANE_OFFSET_3_A			0x703a4
+
+#define _PLANE_CTL_1_B				0x71180
+#define _PLANE_CTL_2_B				0x71280
+#define _PLANE_CTL_3_B				0x71380
+#define _PLANE_CTL_1(pipe)	_PIPE(pipe, _PLANE_CTL_1_A, _PLANE_CTL_1_B)
+#define _PLANE_CTL_2(pipe)	_PIPE(pipe, _PLANE_CTL_2_A, _PLANE_CTL_2_B)
+#define _PLANE_CTL_3(pipe)	_PIPE(pipe, _PLANE_CTL_3_A, _PLANE_CTL_3_B)
+#define PLANE_CTL(pipe, plane)	\
+	_PLANE(plane, _PLANE_CTL_1(pipe), _PLANE_CTL_2(pipe))
+
+#define _PLANE_STRIDE_1_B			0x71188
+#define _PLANE_STRIDE_2_B			0x71288
+#define _PLANE_STRIDE_3_B			0x71388
+#define _PLANE_STRIDE_1(pipe)	\
+	_PIPE(pipe, _PLANE_STRIDE_1_A, _PLANE_STRIDE_1_B)
+#define _PLANE_STRIDE_2(pipe)	\
+	_PIPE(pipe, _PLANE_STRIDE_2_A, _PLANE_STRIDE_2_B)
+#define _PLANE_STRIDE_3(pipe)	\
+	_PIPE(pipe, _PLANE_STRIDE_3_A, _PLANE_STRIDE_3_B)
+#define PLANE_STRIDE(pipe, plane)	\
+	_PLANE(plane, _PLANE_STRIDE_1(pipe), _PLANE_STRIDE_2(pipe))
+
+#define _PLANE_POS_1_B				0x7118c
+#define _PLANE_POS_2_B				0x7128c
+#define _PLANE_POS_3_B				0x7138c
+#define _PLANE_POS_1(pipe)	_PIPE(pipe, _PLANE_POS_1_A, _PLANE_POS_1_B)
+#define _PLANE_POS_2(pipe)	_PIPE(pipe, _PLANE_POS_2_A, _PLANE_POS_2_B)
+#define _PLANE_POS_3(pipe)	_PIPE(pipe, _PLANE_POS_3_A, _PLANE_POS_3_B)
+#define PLANE_POS(pipe, plane)	\
+	_PLANE(plane, _PLANE_POS_1(pipe), _PLANE_POS_2(pipe))
+
+#define _PLANE_SIZE_1_B				0x71190
+#define _PLANE_SIZE_2_B				0x71290
+#define _PLANE_SIZE_3_B				0x71390
+#define _PLANE_SIZE_1(pipe)	_PIPE(pipe, _PLANE_SIZE_1_A, _PLANE_SIZE_1_B)
+#define _PLANE_SIZE_2(pipe)	_PIPE(pipe, _PLANE_SIZE_2_A, _PLANE_SIZE_2_B)
+#define _PLANE_SIZE_3(pipe)	_PIPE(pipe, _PLANE_SIZE_3_A, _PLANE_SIZE_3_B)
+#define PLANE_SIZE(pipe, plane)	\
+	_PLANE(plane, _PLANE_SIZE_1(pipe), _PLANE_SIZE_2(pipe))
+
+#define _PLANE_SURF_1_B				0x7119c
+#define _PLANE_SURF_2_B				0x7129c
+#define _PLANE_SURF_3_B				0x7139c
+#define _PLANE_SURF_1(pipe)	_PIPE(pipe, _PLANE_SURF_1_A, _PLANE_SURF_1_B)
+#define _PLANE_SURF_2(pipe)	_PIPE(pipe, _PLANE_SURF_2_A, _PLANE_SURF_2_B)
+#define _PLANE_SURF_3(pipe)	_PIPE(pipe, _PLANE_SURF_3_A, _PLANE_SURF_3_B)
+#define PLANE_SURF(pipe, plane)	\
+	_PLANE(plane, _PLANE_SURF_1(pipe), _PLANE_SURF_2(pipe))
+
+#define _PLANE_OFFSET_1_B			0x711a4
+#define _PLANE_OFFSET_2_B			0x712a4
+#define _PLANE_OFFSET_1(pipe) _PIPE(pipe, _PLANE_OFFSET_1_A, _PLANE_OFFSET_1_B)
+#define _PLANE_OFFSET_2(pipe) _PIPE(pipe, _PLANE_OFFSET_2_A, _PLANE_OFFSET_2_B)
+#define PLANE_OFFSET(pipe, plane)	\
+	_PLANE(plane, _PLANE_OFFSET_1(pipe), _PLANE_OFFSET_2(pipe))
+
 /* VBIOS regs */
 #define VGACNTRL		0x71400
 # define VGA_DISP_DISABLE			(1 << 31)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 02236f9..f98d1c4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2640,6 +2640,86 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
 	POSTING_READ(reg);
 }
 
+static void skylake_update_primary_plane(struct drm_crtc *crtc,
+					 struct drm_framebuffer *fb,
+					 int x, int y)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_framebuffer *intel_fb;
+	struct drm_i915_gem_object *obj;
+	int pipe = intel_crtc->pipe;
+	u32 plane_ctl, stride;
+
+	if (!intel_crtc->primary_enabled) {
+		I915_WRITE(PLANE_CTL(pipe, 0), 0);
+		I915_WRITE(PLANE_SURF(pipe, 0), 0);
+		POSTING_READ(PLANE_CTL(pipe, 0));
+		return;
+	}
+
+	plane_ctl = PLANE_CTL_ENABLE |
+		    PLANE_CTL_PIPE_GAMMA_ENABLE |
+		    PLANE_CTL_PIPE_CSC_ENABLE;
+
+	switch (fb->pixel_format) {
+	case DRM_FORMAT_RGB565:
+		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
+		break;
+	case DRM_FORMAT_XRGB8888:
+		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
+		break;
+	case DRM_FORMAT_XBGR8888:
+		plane_ctl |= PLANE_CTL_ORDER_RGBX;
+		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
+		break;
+	case DRM_FORMAT_XRGB2101010:
+		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
+		break;
+	case DRM_FORMAT_XBGR2101010:
+		plane_ctl |= PLANE_CTL_ORDER_RGBX;
+		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
+		break;
+	default:
+		BUG();
+	}
+
+	intel_fb = to_intel_framebuffer(fb);
+	obj = intel_fb->obj;
+	switch (obj->tiling_mode) {
+	case I915_TILING_NONE:
+		stride = fb->pitches[0] >> 6;
+		break;
+	case I915_TILING_X:
+		plane_ctl |= PLANE_CTL_TILED_X;
+		stride = fb->pitches[0] >> 9;
+		break;
+	default:
+		BUG();
+	}
+
+	plane_ctl &= ~PLANE_CTL_TRICKLE_FEED_DISABLE;
+	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
+
+	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
+
+	DRM_DEBUG_KMS("Writing base %08lX %d,%d,%d,%d pitch=%d\n",
+		      i915_gem_obj_ggtt_offset(obj),
+		      x, y, fb->width, fb->height,
+		      fb->pitches[0]);
+
+	I915_WRITE(PLANE_POS(pipe, 0), 0);
+	I915_WRITE(PLANE_OFFSET(pipe, 0), (y << 16) | x);
+	I915_WRITE(PLANE_SIZE(pipe, 0),
+		   (intel_crtc->config.pipe_src_h - 1) << 16 |
+		   (intel_crtc->config.pipe_src_w - 1));
+	I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
+	I915_WRITE(PLANE_SURF(pipe, 0), i915_gem_obj_ggtt_offset(obj));
+
+	POSTING_READ(PLANE_SURF(pipe, 0));
+}
+
 /* Assume fb object is pinned & idle & fenced and just update base pointers */
 static int
 intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
@@ -12481,8 +12561,12 @@ static void intel_init_display(struct drm_device *dev)
 		dev_priv->display.crtc_enable = haswell_crtc_enable;
 		dev_priv->display.crtc_disable = haswell_crtc_disable;
 		dev_priv->display.off = ironlake_crtc_off;
-		dev_priv->display.update_primary_plane =
-			ironlake_update_primary_plane;
+		if (INTEL_INFO(dev)->gen >= 9)
+			dev_priv->display.update_primary_plane =
+				skylake_update_primary_plane;
+		else
+			dev_priv->display.update_primary_plane =
+				ironlake_update_primary_plane;
 	} else if (HAS_PCH_SPLIT(dev)) {
 		dev_priv->display.get_pipe_config = ironlake_get_pipe_config;
 		dev_priv->display.get_plane_config = ironlake_get_plane_config;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 13/89] drm/i915/skl: Don't create a VGA connector on Skylake
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (11 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 12/89] drm/i915/skl: Implement thew new update_plane() for primary planes Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 11:26 ` [PATCH 14/89] drm/i915/skl: Don't try to read out the PCH transcoder state if not present Damien Lespiau
                   ` (76 subsequent siblings)
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

v2: Rebase on top of the intel_crt_present() addition
v3: Fix rebase error (we were patching the wrong function)

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f98d1c4..fbc4b2f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12218,6 +12218,9 @@ static bool intel_crt_present(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
+	if (INTEL_INFO(dev)->gen >= 9)
+		return false;
+
 	if (IS_ULT(dev))
 		return false;
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 14/89] drm/i915/skl: Don't try to read out the PCH transcoder state if not present
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (12 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 13/89] drm/i915/skl: Don't create a VGA connector on Skylake Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 11:26 ` [PATCH 15/89] drm/i915/skl: Program the DDI buffer translation tables Damien Lespiau
                   ` (75 subsequent siblings)
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

When the platform doesn't have a FDI link, don't try to read out the
state of a potential PCH transcoder.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      | 2 ++
 drivers/gpu/drm/i915/intel_display.c | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4cc028a..cf4fc86 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2175,6 +2175,8 @@ struct drm_i915_cmd_table {
 #define HAS_PSR(dev)		(IS_HASWELL(dev) || IS_BROADWELL(dev))
 #define HAS_RUNTIME_PM(dev)	(IS_GEN6(dev) || IS_HASWELL(dev) || \
 				 IS_BROADWELL(dev) || IS_VALLEYVIEW(dev))
+#define HAS_FDI(dev)		(HAS_PCH_SPLIT(dev) && \
+				 INTEL_INFO(dev)->gen < 9)
 
 #define INTEL_PCH_DEVICE_ID_MASK		0xff00
 #define INTEL_PCH_IBX_DEVICE_ID_TYPE		0x3b00
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index fbc4b2f..6ad8098 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7825,7 +7825,8 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
 	 * DDI E. So just check whether this pipe is wired to DDI E and whether
 	 * the PCH transcoder is on.
 	 */
-	if ((port == PORT_E) && I915_READ(LPT_TRANSCONF) & TRANS_ENABLE) {
+	if (HAS_FDI(dev) &&
+	    (port == PORT_E) && I915_READ(LPT_TRANSCONF) & TRANS_ENABLE) {
 		pipe_config->has_pch_encoder = true;
 
 		tmp = I915_READ(FDI_RX_CTL(PIPE_A));
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 15/89] drm/i915/skl: Program the DDI buffer translation tables
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (13 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 14/89] drm/i915/skl: Don't try to read out the PCH transcoder state if not present Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 18:58   ` [PATCH 15/89 v7] " Damien Lespiau
  2014-09-04 11:26 ` [PATCH 16/89] drm/i915/skl: Add support for DP voltage swings and pre-emphasis Damien Lespiau
                   ` (74 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

Jani cleaned up the mess between the length of the various DDI buf translation
arrays and the number of DDI Translation levels/entries. So now
ARRAY_SIZE(skl_ddi_translations_hdmi) is the number of possible entries
(instead of needing to remember to divide by 2)

The SKL DP/eDP 1.3/HDMI DDI buf patch needed an update then.

--
Damien
---
 drivers/gpu/drm/i915/intel_ddi.c | 40 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index eed9a2a..64eda53 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -127,6 +127,32 @@ static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
 	{ 0x80FFFFFF, 0x001B0002 },	/* 9:	1000	1000	0	*/
 };
 
+static const struct ddi_buf_trans skl_ddi_translations_dp[] = {
+	{ 0x00000018, 0x000000a0 },
+	{ 0x00004014, 0x00000098 },
+	{ 0x00006012, 0x00000088 },
+	{ 0x00008010, 0x00000080 },
+	{ 0x00000018, 0x00000098 },
+	{ 0x00004014, 0x00000088 },
+	{ 0x00006012, 0x00000080 },
+	{ 0x00000018, 0x00000088 },
+	{ 0x00004014, 0x00000080 },
+};
+
+static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = {
+					/* Idx	NT mV   T mV    db  */
+	{ 0x00000018, 0x000000a0 },	/* 0:	400	400	0   */
+	{ 0x00004014, 0x00000098 },	/* 1:	400	600	3.5 */
+	{ 0x00006012, 0x00000088 },	/* 2:	400	800	6   */
+	{ 0x00000018, 0x0000003c },	/* 3:	450	450	0   */
+	{ 0x00000018, 0x00000098 },	/* 4:	600	600	0   */
+	{ 0x00003015, 0x00000088 },	/* 5:	600	800	2.5 */
+	{ 0x00005013, 0x00000080 },	/* 6:	600	1000	4.5 */
+	{ 0x00000018, 0x00000088 },	/* 7:	800	800	0   */
+	{ 0x00000096, 0x00000080 },	/* 8:	800	1000	2   */
+	{ 0x00000018, 0x00000080 },	/* 9:	1200	1200	0   */
+};
+
 enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
@@ -169,7 +195,14 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port)
 	const struct ddi_buf_trans *ddi_translations_hdmi;
 	const struct ddi_buf_trans *ddi_translations;
 
-	if (IS_BROADWELL(dev)) {
+	if (IS_SKYLAKE(dev)) {
+		ddi_translations_fdi = NULL;
+		ddi_translations_dp = skl_ddi_translations_dp;
+		ddi_translations_edp = skl_ddi_translations_dp;
+		ddi_translations_hdmi = skl_ddi_translations_hdmi;
+		n_hdmi_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
+		hdmi_800mV_0dB = 7;
+	} else if (IS_BROADWELL(dev)) {
 		ddi_translations_fdi = bdw_ddi_translations_fdi;
 		ddi_translations_dp = bdw_ddi_translations_dp;
 		ddi_translations_edp = bdw_ddi_translations_edp;
@@ -208,7 +241,10 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port)
 			ddi_translations = ddi_translations_dp;
 		break;
 	case PORT_E:
-		ddi_translations = ddi_translations_fdi;
+		if (ddi_translations_fdi)
+			ddi_translations = ddi_translations_fdi;
+		else
+			ddi_translations = ddi_translations_dp;
 		break;
 	default:
 		BUG();
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 16/89] drm/i915/skl: Add support for DP voltage swings and pre-emphasis
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (14 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 15/89] drm/i915/skl: Program the DDI buffer translation tables Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 11:26 ` [PATCH 17/89] drm/i915/skl: Skylake doesn't need the DP AUX clock divider programmed Damien Lespiau
                   ` (73 subsequent siblings)
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

They are similar to Haswell.

v2: Rebased on top of drm-intel-nightly
v3: Rebased on top of Sonika's DP train defines renaming

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index f79473b..dc7440e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2432,7 +2432,9 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	enum port port = dp_to_dig_port(intel_dp)->port;
 
-	if (IS_VALLEYVIEW(dev))
+	if (INTEL_INFO(dev)->gen >= 9)
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+	else if (IS_VALLEYVIEW(dev))
 		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
 	else if (IS_GEN7(dev) && port == PORT_A)
 		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
@@ -2448,7 +2450,18 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	enum port port = dp_to_dig_port(intel_dp)->port;
 
-	if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+	if (INTEL_INFO(dev)->gen >= 9) {
+		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			return DP_TRAIN_PRE_EMPH_LEVEL_3;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			return DP_TRAIN_PRE_EMPH_LEVEL_2;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			return DP_TRAIN_PRE_EMPH_LEVEL_1;
+		default:
+			return DP_TRAIN_PRE_EMPH_LEVEL_0;
+		}
+	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
 		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
 			return DP_TRAIN_PRE_EMPH_LEVEL_3;
@@ -2930,7 +2943,7 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
 	uint32_t signal_levels, mask;
 	uint8_t train_set = intel_dp->train_set[0];
 
-	if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+	if (IS_HASWELL(dev) || IS_BROADWELL(dev) || INTEL_INFO(dev)->gen >= 9) {
 		signal_levels = intel_hsw_signal_levels(train_set);
 		mask = DDI_BUF_EMP_MASK;
 	} else if (IS_CHERRYVIEW(dev)) {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 17/89] drm/i915/skl: Skylake doesn't need the DP AUX clock divider programmed
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (15 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 16/89] drm/i915/skl: Add support for DP voltage swings and pre-emphasis Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 11:26 ` [PATCH 18/89] drm/i915/skl: Skylake moves AUX_CTL from PCH to CPU Damien Lespiau
                   ` (72 subsequent siblings)
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

DP_AUX_CTL doesn't have the "2X Bit Clock divider" bitfield any more. I
don't see any other register where we should program it, so I assume the
hardware knows how to derive it now.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index dc7440e..6b1da40 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -446,7 +446,10 @@ static uint32_t ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index)
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = intel_dig_port->base.base.dev;
 
-	if (index)
+	if (INTEL_INFO(dev)->gen >= 9) {
+		/* Skylake doesn't need the AUX clock divider programmed */
+		return 0;
+	} else if (index)
 		return 0;
 
 	if (intel_dig_port->port == PORT_A) {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 18/89] drm/i915/skl: Skylake moves AUX_CTL from PCH to CPU
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (16 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 17/89] drm/i915/skl: Skylake doesn't need the DP AUX clock divider programmed Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 11:26 ` [PATCH 19/89] drm/i915/skl: Add the additional graphics stolen sizes Damien Lespiau
                   ` (71 subsequent siblings)
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

So we can apply the old aux_ctl = dp_ctl + 0x10 rule again.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 6b1da40..a95fb47 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -749,7 +749,16 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
 		BUG();
 	}
 
-	if (!HAS_DDI(dev))
+	/*
+	 * The AUX_CTL register is usually DP_CTL + 0x10.
+	 *
+	 * On Haswell and Broadwell though:
+	 *   - Both port A DDI_BUF_CTL and DDI_AUX_CTL are on the CPU
+	 *   - Port B/C/D AUX channels are on the PCH, DDI_BUF_CTL on the CPU
+	 *
+	 * Skylake moves AUX_CTL back next to DDI_BUF_CTL, on the CPU.
+	 */
+	if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
 		intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10;
 
 	intel_dp->aux.name = name;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 19/89] drm/i915/skl: Add the additional graphics stolen sizes
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (17 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 18/89] drm/i915/skl: Skylake moves AUX_CTL from PCH to CPU Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 11:26 ` [PATCH 20/89] drm/i915/skl: gen9 uses the same bind_vma() vfuncs as gen6+ Damien Lespiau
                   ` (70 subsequent siblings)
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

Skylake introduces new stolen memory sizes starting at 0xf0 (4MB) and
growing by 4MB increments from there.

v2: Rebase on top of the early-quirk changes from Ville.

v3: Rebase on top of the PCI_IDS/IDS macro rename

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 arch/x86/kernel/early-quirks.c      | 23 +++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_gtt.c | 17 ++++++++++++++++-
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index 2e1a685..fe9f0b7 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -455,6 +455,23 @@ struct intel_stolen_funcs {
 	u32 (*base)(int num, int slot, int func, size_t size);
 };
 
+static size_t __init gen9_stolen_size(int num, int slot, int func)
+{
+	u16 gmch_ctrl;
+
+	gmch_ctrl = read_pci_config_16(num, slot, func, SNB_GMCH_CTRL);
+	gmch_ctrl >>= BDW_GMCH_GMS_SHIFT;
+	gmch_ctrl &= BDW_GMCH_GMS_MASK;
+
+	if (gmch_ctrl < 0xf0)
+		return gmch_ctrl << 25; /* 32 MB units */
+	else
+		/* 4MB increments starting at 0xf0 for 4MB */
+		return (gmch_ctrl - 0xf0 + 1) << 22;
+}
+
+typedef size_t (*stolen_size_fn)(int num, int slot, int func);
+
 static const struct intel_stolen_funcs i830_stolen_funcs __initconst = {
 	.base = i830_stolen_base,
 	.size = i830_stolen_size,
@@ -490,6 +507,11 @@ static const struct intel_stolen_funcs gen8_stolen_funcs __initconst = {
 	.size = gen8_stolen_size,
 };
 
+static const struct intel_stolen_funcs gen9_stolen_funcs __initconst = {
+	.base = intel_stolen_base,
+	.size = gen9_stolen_size,
+};
+
 static const struct intel_stolen_funcs chv_stolen_funcs __initconst = {
 	.base = intel_stolen_base,
 	.size = chv_stolen_size,
@@ -523,6 +545,7 @@ static const struct pci_device_id intel_stolen_ids[] __initconst = {
 	INTEL_BDW_M_IDS(&gen8_stolen_funcs),
 	INTEL_BDW_D_IDS(&gen8_stolen_funcs),
 	INTEL_CHV_IDS(&chv_stolen_funcs),
+	INTEL_SKL_IDS(&gen9_stolen_funcs),
 };
 
 static void __init intel_graphics_stolen(int num, int slot, int func)
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 6f410cf..d78695d 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1847,6 +1847,18 @@ static size_t chv_get_stolen_size(u16 gmch_ctrl)
 		return (gmch_ctrl - 0x17 + 9) << 22;
 }
 
+static size_t gen9_get_stolen_size(u16 gen9_gmch_ctl)
+{
+	gen9_gmch_ctl >>= BDW_GMCH_GMS_SHIFT;
+	gen9_gmch_ctl &= BDW_GMCH_GMS_MASK;
+
+	if (gen9_gmch_ctl < 0xf0)
+		return gen9_gmch_ctl << 25; /* 32 MB units */
+	else
+		/* 4MB increments starting at 0xf0 for 4MB */
+		return (gen9_gmch_ctl - 0xf0 + 1) << 22;
+}
+
 static int ggtt_probe_common(struct drm_device *dev,
 			     size_t gtt_size)
 {
@@ -1943,7 +1955,10 @@ static int gen8_gmch_probe(struct drm_device *dev,
 
 	pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
 
-	if (IS_CHERRYVIEW(dev)) {
+	if (INTEL_INFO(dev)->gen >= 9) {
+		*stolen = gen9_get_stolen_size(snb_gmch_ctl);
+		gtt_size = gen8_get_total_gtt_size(snb_gmch_ctl);
+	} else if (IS_CHERRYVIEW(dev)) {
 		*stolen = chv_get_stolen_size(snb_gmch_ctl);
 		gtt_size = chv_get_total_gtt_size(snb_gmch_ctl);
 	} else {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 20/89] drm/i915/skl: gen9 uses the same bind_vma() vfuncs as gen6+
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (18 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 19/89] drm/i915/skl: Add the additional graphics stolen sizes Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 11:26 ` [PATCH 21/89] drm/i915/skl: Implement the get_aux_clock_divider() DP vfunc Damien Lespiau
                   ` (69 subsequent siblings)
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

Temporary plug a BUG() while waiting for a better solution. See:

  http://lists.freedesktop.org/archives/intel-gfx/2014-January/038132.html

However Chris was looking at cleaning-up this as well, so went for the
easy intermediate solution instead.

Reviewed-by: Ben Widawsky <ben@bwidawsk.net>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index d78695d..688dd00 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2130,6 +2130,7 @@ static struct i915_vma *__i915_gem_vma_create(struct drm_i915_gem_object *obj,
 	vma->obj = obj;
 
 	switch (INTEL_INFO(vm->dev)->gen) {
+	case 9:
 	case 8:
 	case 7:
 	case 6:
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 21/89] drm/i915/skl: Implement the get_aux_clock_divider() DP vfunc
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (19 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 20/89] drm/i915/skl: gen9 uses the same bind_vma() vfuncs as gen6+ Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-17  1:12   ` Rodrigo Vivi
  2014-09-04 11:26 ` [PATCH 22/89] drm/i915/skl: Provide a get_aux_send_ctl() vfunc for skylake Damien Lespiau
                   ` (68 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

We need to provide a vfunc that will make the code in intel_dp_aux_ch()
loop once to start the AUX transaction. The return value (clock divider)
is unused on SKL, so just return 1.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index a95fb47..4560ced 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -489,6 +489,16 @@ static uint32_t vlv_get_aux_clock_divider(struct intel_dp *intel_dp, int index)
 	return index ? 0 : 100;
 }
 
+static uint32_t skl_get_aux_clock_divider(struct intel_dp *intel_dp, int index)
+{
+	/*
+	 * SKL doesn't need us to program the AUX clock divider (Hardware will
+	 * derive the clock from CDCLK automatically). We still implement the
+	 * get_aux_clock_divider vfunc to plug-in into the existing code.
+	 */
+	return index ? 0 : 1;
+}
+
 static uint32_t i9xx_get_aux_send_ctl(struct intel_dp *intel_dp,
 				      bool has_aux_irq,
 				      int send_bytes,
@@ -4726,7 +4736,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	int type;
 
 	/* intel_dp vfuncs */
-	if (IS_VALLEYVIEW(dev))
+	if (INTEL_INFO(dev)->gen >= 9)
+		intel_dp->get_aux_clock_divider = skl_get_aux_clock_divider;
+	else if (IS_VALLEYVIEW(dev))
 		intel_dp->get_aux_clock_divider = vlv_get_aux_clock_divider;
 	else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
 		intel_dp->get_aux_clock_divider = hsw_get_aux_clock_divider;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 22/89] drm/i915/skl: Provide a get_aux_send_ctl() vfunc for skylake
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (20 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 21/89] drm/i915/skl: Implement the get_aux_clock_divider() DP vfunc Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-17  1:16   ` Rodrigo Vivi
  2014-09-04 11:26 ` [PATCH 23/89] drm/i915/skl: Initialize PPGTT like gen8 Damien Lespiau
                   ` (67 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

Skylake doesn't use the pre-charge field now, but, instead, we need to
specify the total number of SYNC pulses for the SYNC phase (pre-charge +
SYNC pattern pules). Let's use the default value (32) for that.

v3: increase DP AUX TX timeout as 400us is not to be used on SKL
    apparently (Jesse).

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h |  1 +
 drivers/gpu/drm/i915/intel_dp.c | 20 +++++++++++++++++++-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 087085c..acd0a7b 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3630,6 +3630,7 @@ enum punit_power_well {
 #define   DP_AUX_CH_CTL_PRECHARGE_TEST	    (1 << 11)
 #define   DP_AUX_CH_CTL_BIT_CLOCK_2X_MASK    (0x7ff)
 #define   DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT   0
+#define   DP_AUX_CH_CTL_SYNC_PULSE_SKL(c)   ((c) - 1)
 
 /*
  * Computing GMCH M and N values for the Display Port link
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 4560ced..5755f59 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -529,6 +529,21 @@ static uint32_t i9xx_get_aux_send_ctl(struct intel_dp *intel_dp,
 	       (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT);
 }
 
+static uint32_t skl_get_aux_send_ctl(struct intel_dp *intel_dp,
+				      bool has_aux_irq,
+				      int send_bytes,
+				      uint32_t unused)
+{
+	return DP_AUX_CH_CTL_SEND_BUSY |
+	       DP_AUX_CH_CTL_DONE |
+	       (has_aux_irq ? DP_AUX_CH_CTL_INTERRUPT : 0) |
+	       DP_AUX_CH_CTL_TIME_OUT_ERROR |
+	       DP_AUX_CH_CTL_TIME_OUT_1600us |
+	       DP_AUX_CH_CTL_RECEIVE_ERROR |
+	       (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
+	       DP_AUX_CH_CTL_SYNC_PULSE_SKL(32);
+}
+
 static int
 intel_dp_aux_ch(struct intel_dp *intel_dp,
 		uint8_t *send, int send_bytes,
@@ -4747,7 +4762,10 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	else
 		intel_dp->get_aux_clock_divider = i9xx_get_aux_clock_divider;
 
-	intel_dp->get_aux_send_ctl = i9xx_get_aux_send_ctl;
+	if (INTEL_INFO(dev)->gen >= 9)
+		intel_dp->get_aux_send_ctl = skl_get_aux_send_ctl;
+	else
+		intel_dp->get_aux_send_ctl = i9xx_get_aux_send_ctl;
 
 	/* Preserve the current hw state. */
 	intel_dp->DP = I915_READ(intel_dp->output_reg);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 23/89] drm/i915/skl: Initialize PPGTT like gen8
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (21 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 22/89] drm/i915/skl: Provide a get_aux_send_ctl() vfunc for skylake Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-17  1:17   ` Rodrigo Vivi
  2014-09-04 11:26 ` [PATCH 24/89] drm/i915/skl: Allow the reg_read ioctl to return RCS_TIMESTAMP Damien Lespiau
                   ` (66 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

gen9 uses very similar memory management to what gen8 has. Just follow
the flow.

v2: Fix trivial conflict (Damien)

Reviewed-by: Ben Widawsky <ben@bwidawsk.net>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 688dd00..66e4b2b 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1092,7 +1092,7 @@ static int __hw_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
 
 	if (INTEL_INFO(dev)->gen < 8)
 		return gen6_ppgtt_init(ppgtt);
-	else if (IS_GEN8(dev))
+	else if (IS_GEN8(dev) || IS_GEN9(dev))
 		return gen8_ppgtt_init(ppgtt, dev_priv->gtt.base.total);
 	else
 		BUG();
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 24/89] drm/i915/skl: Allow the reg_read ioctl to return RCS_TIMESTAMP
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (22 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 23/89] drm/i915/skl: Initialize PPGTT like gen8 Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-17  1:27   ` Rodrigo Vivi
  2014-09-04 11:26 ` [PATCH 25/89] drm/i915/skl: report the same INSTDONE registers as gen8 Damien Lespiau
                   ` (65 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_uncore.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 918b761..3b27fb0 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -968,7 +968,7 @@ static const struct register_whitelist {
 	/* supported gens, 0x10 for 4, 0x30 for 4 and 5, etc. */
 	uint32_t gen_bitmask;
 } whitelist[] = {
-	{ RING_TIMESTAMP(RENDER_RING_BASE), 8, GEN_RANGE(4, 8) },
+	{ RING_TIMESTAMP(RENDER_RING_BASE), 8, GEN_RANGE(4, 9) },
 };
 
 int i915_reg_read_ioctl(struct drm_device *dev,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 25/89] drm/i915/skl: report the same INSTDONE registers as gen8
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (23 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 24/89] drm/i915/skl: Allow the reg_read ioctl to return RCS_TIMESTAMP Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-17  1:28   ` Rodrigo Vivi
  2014-09-04 11:26 ` [PATCH 26/89] drm/i915/skl: Report the PDP regs as in gen8 Damien Lespiau
                   ` (64 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_gpu_error.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 68fd767..1bf6e69 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1390,6 +1390,7 @@ void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone)
 		WARN_ONCE(1, "Unsupported platform\n");
 	case 7:
 	case 8:
+	case 9:
 		instdone[0] = I915_READ(GEN7_INSTDONE_1);
 		instdone[1] = I915_READ(GEN7_SC_INSTDONE);
 		instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 26/89] drm/i915/skl: Report the PDP regs as in gen8
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (24 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 25/89] drm/i915/skl: report the same INSTDONE registers as gen8 Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-17  1:33   ` Rodrigo Vivi
  2014-09-04 11:26 ` [PATCH 27/89] drm/i915/skl: SKL shares the same underrun interrupt as BDW Damien Lespiau
                   ` (63 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_gpu_error.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 1bf6e69..fe14980 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -924,6 +924,7 @@ static void i915_record_ring_state(struct drm_device *dev,
 		ering->vm_info.gfx_mode = I915_READ(RING_MODE_GEN7(ring));
 
 		switch (INTEL_INFO(dev)->gen) {
+		case 9:
 		case 8:
 			for (i = 0; i < 4; i++) {
 				ering->vm_info.pdp[i] =
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 27/89] drm/i915/skl: SKL shares the same underrun interrupt as BDW
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (25 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 26/89] drm/i915/skl: Report the PDP regs as in gen8 Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-17  1:39   ` Rodrigo Vivi
  2014-09-04 11:26 ` [PATCH 28/89] drm/i915/skl: SKL pipe misc programming Damien Lespiau
                   ` (62 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index e9979f5..c62a2e4 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -503,7 +503,7 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
 		ironlake_set_fifo_underrun_reporting(dev, pipe, enable);
 	else if (IS_GEN7(dev))
 		ivybridge_set_fifo_underrun_reporting(dev, pipe, enable, old);
-	else if (IS_GEN8(dev))
+	else if (IS_GEN8(dev) || IS_GEN9(dev))
 		broadwell_set_fifo_underrun_reporting(dev, pipe, enable);
 
 	return old;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 28/89] drm/i915/skl: SKL pipe misc programming
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (26 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 27/89] drm/i915/skl: SKL shares the same underrun interrupt as BDW Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-17  1:43   ` Rodrigo Vivi
  2014-09-04 11:26 ` [PATCH 29/89] drm/i915/skl: vfuncs for skl eld and global resource Damien Lespiau
                   ` (61 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

Pipe misc programming in gen9 is similar to BDW. Extending the BDW
implementation to gen 9.

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6ad8098..bffabfd 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7022,7 +7022,7 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
 	I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT);
 	POSTING_READ(GAMMA_MODE(intel_crtc->pipe));
 
-	if (IS_BROADWELL(dev)) {
+	if (IS_BROADWELL(dev) || INTEL_INFO(dev)->gen >= 9) {
 		val = 0;
 
 		switch (intel_crtc->config.pipe_bpp) {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 29/89] drm/i915/skl: vfuncs for skl eld and global resource
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (27 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 28/89] drm/i915/skl: SKL pipe misc programming Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-17  1:50   ` Rodrigo Vivi
  2014-09-04 11:26 ` [PATCH 30/89] drm/i915/skl: SKL backlight enabling Damien Lespiau
                   ` (60 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

Set gen 9 function pointers for eld write and global resource.
Implementation remains same as HSW.

v2: Rebase on top of Sonika's untangling of the if/else ladder (Damien)

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v1)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index bffabfd..48d2d0d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12654,6 +12654,10 @@ static void intel_init_display(struct drm_device *dev)
 		dev_priv->display.modeset_global_resources =
 			valleyview_modeset_global_resources;
 		dev_priv->display.write_eld = ironlake_write_eld;
+	} else if (INTEL_INFO(dev)->gen >= 9) {
+		dev_priv->display.write_eld = haswell_write_eld;
+		dev_priv->display.modeset_global_resources =
+			haswell_modeset_global_resources;
 	}
 
 	/* Default just returns -ENODEV to indicate unsupported */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 30/89] drm/i915/skl: SKL backlight enabling
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (28 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 29/89] drm/i915/skl: vfuncs for skl eld and global resource Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-17  1:56   ` Rodrigo Vivi
  2014-09-04 11:26 ` [PATCH 31/89] drm/i915/skl: Restore pipe B/C interrupts Damien Lespiau
                   ` (59 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

Extending the BDW backlight implementation to SKL.

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_panel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 1878447..d69a3cb6 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -1317,7 +1317,7 @@ void intel_panel_init_backlight_funcs(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (IS_BROADWELL(dev)) {
+	if (IS_BROADWELL(dev) || (INTEL_INFO(dev)->gen >= 9)) {
 		dev_priv->display.setup_backlight = bdw_setup_backlight;
 		dev_priv->display.enable_backlight = bdw_enable_backlight;
 		dev_priv->display.disable_backlight = pch_disable_backlight;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 31/89] drm/i915/skl: Restore pipe B/C interrupts
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (29 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 30/89] drm/i915/skl: SKL backlight enabling Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 11:26 ` [PATCH 32/89] drm/i915/skl: Adjust the display engine interrupts Damien Lespiau
                   ` (58 subsequent siblings)
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

Extending BDW implementation to gen9. Pipe B/C interrupt
restoration after exiting LPSP.

v2: Fix minor rebasing conflict.

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 23eea92..0265116 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6277,7 +6277,7 @@ static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
 	outb(inb(VGA_MSR_READ), VGA_MSR_WRITE);
 	vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
 
-	if (IS_BROADWELL(dev))
+	if (IS_BROADWELL(dev) || (INTEL_INFO(dev)->gen >= 9))
 		gen8_irq_power_well_post_enable(dev_priv);
 }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 32/89] drm/i915/skl: Adjust the display engine interrupts
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (30 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 31/89] drm/i915/skl: Restore pipe B/C interrupts Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-04 13:19   ` Daniel Vetter
  2014-09-04 11:26 ` [PATCH 33/89] drm/i915/skl: Sunrise Point PCH detection Damien Lespiau
                   ` (57 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

To accomodate the extra planes, the bit definitions were shuffled around
a bit.

v2: Rebase on top of the for_each_pipe() change adding dev_priv as first
    argument.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 37 ++++++++++++++++++++++++++++---------
 drivers/gpu/drm/i915/i915_reg.h | 13 +++++++++++++
 2 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index c62a2e4..734b73e 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2584,7 +2584,7 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
 	}
 
 	for_each_pipe(dev_priv, pipe) {
-		uint32_t pipe_iir;
+		uint32_t pipe_iir, flip_done = 0, fault_errors = 0;
 
 		if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe)))
 			continue;
@@ -2593,10 +2593,16 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
 		if (pipe_iir) {
 			ret = IRQ_HANDLED;
 			I915_WRITE(GEN8_DE_PIPE_IIR(pipe), pipe_iir);
+
 			if (pipe_iir & GEN8_PIPE_VBLANK)
 				intel_pipe_handle_vblank(dev, pipe);
 
-			if (pipe_iir & GEN8_PIPE_PRIMARY_FLIP_DONE) {
+			if (IS_GEN9(dev))
+				flip_done = pipe_iir & GEN9_PIPE_PLANE1_FLIP_DONE;
+			else
+				flip_done = pipe_iir & GEN8_PIPE_PRIMARY_FLIP_DONE;
+
+			if (flip_done) {
 				intel_prepare_page_flip(dev, pipe);
 				intel_finish_page_flip_plane(dev, pipe);
 			}
@@ -2611,11 +2617,16 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
 						  pipe_name(pipe));
 			}
 
-			if (pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS) {
+
+			if (IS_GEN9(dev))
+				fault_errors = pipe_iir & GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
+			else
+				fault_errors = pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
+
+			if (fault_errors)
 				DRM_ERROR("Fault errors on pipe %c\n: 0x%08x",
 					  pipe_name(pipe),
 					  pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS);
-			}
 		} else
 			DRM_ERROR("The master control interrupt lied (DE PIPE)!\n");
 	}
@@ -3845,12 +3856,20 @@ static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv)
 
 static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
 {
-	uint32_t de_pipe_masked = GEN8_PIPE_PRIMARY_FLIP_DONE |
-		GEN8_PIPE_CDCLK_CRC_DONE |
-		GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
-	uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
-		GEN8_PIPE_FIFO_UNDERRUN;
+	uint32_t de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE;
+	uint32_t de_pipe_enables;
 	int pipe;
+
+	if (IS_GEN9(dev_priv))
+		de_pipe_masked |= GEN9_PIPE_PLANE1_FLIP_DONE |
+				  GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
+	else
+		de_pipe_masked |= GEN8_PIPE_PRIMARY_FLIP_DONE |
+				  GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
+
+	de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
+					   GEN8_PIPE_FIFO_UNDERRUN;
+
 	dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked;
 	dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked;
 	dev_priv->de_irq_mask[PIPE_C] = ~de_pipe_masked;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index acd0a7b..5928a75 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4840,10 +4840,23 @@ enum punit_power_well {
 #define  GEN8_PIPE_SCAN_LINE_EVENT	(1 << 2)
 #define  GEN8_PIPE_VSYNC		(1 << 1)
 #define  GEN8_PIPE_VBLANK		(1 << 0)
+#define  GEN9_PIPE_CURSOR_FAULT		(1 << 11)
+#define  GEN9_PIPE_PLANE3_FAULT		(1 << 9)
+#define  GEN9_PIPE_PLANE2_FAULT		(1 << 8)
+#define  GEN9_PIPE_PLANE1_FAULT		(1 << 7)
+#define  GEN9_PIPE_PLANE3_FLIP_DONE	(1 << 5)
+#define  GEN9_PIPE_PLANE2_FLIP_DONE	(1 << 4)
+#define  GEN9_PIPE_PLANE1_FLIP_DONE	(1 << 3)
+#define  GEN9_PIPE_PLANE_FLIP_DONE(p)	(1 << (3 + p))
 #define GEN8_DE_PIPE_IRQ_FAULT_ERRORS \
 	(GEN8_PIPE_CURSOR_FAULT | \
 	 GEN8_PIPE_SPRITE_FAULT | \
 	 GEN8_PIPE_PRIMARY_FAULT)
+#define GEN9_DE_PIPE_IRQ_FAULT_ERRORS \
+	(GEN9_PIPE_CURSOR_FAULT | \
+	 GEN9_PIPE_PLANE3_FAULT | \
+	 GEN9_PIPE_PLANE2_FAULT | \
+	 GEN9_PIPE_PLANE1_FAULT)
 
 #define GEN8_DE_PORT_ISR 0x44440
 #define GEN8_DE_PORT_IMR 0x44444
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 33/89] drm/i915/skl: Sunrise Point PCH detection
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (31 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 32/89] drm/i915/skl: Adjust the display engine interrupts Damien Lespiau
@ 2014-09-04 11:26 ` Damien Lespiau
  2014-09-17 22:18   ` Rodrigo Vivi
  2014-09-04 11:27 ` [PATCH 34/89] drm/i915/skl: Implement WaDisableSDEUnitClockGating:skl Damien Lespiau
                   ` (56 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:26 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

This patch implements detection of SPT and SPT-LP PCH devices.

v2: Added HAS_PCH_SPT macro

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c | 10 ++++++++++
 drivers/gpu/drm/i915/i915_drv.h |  4 ++++
 2 files changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 3d7f823..c6a8a80 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -475,6 +475,16 @@ void intel_detect_pch(struct drm_device *dev)
 				DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
 				WARN_ON(!IS_HASWELL(dev));
 				WARN_ON(!IS_ULT(dev));
+			} else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) {
+				dev_priv->pch_type = PCH_SPT;
+				DRM_DEBUG_KMS("Found SunrisePoint PCH\n");
+				WARN_ON(!IS_SKYLAKE(dev));
+				WARN_ON(IS_ULT(dev));
+			} else if (id == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) {
+				dev_priv->pch_type = PCH_SPT;
+				DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n");
+				WARN_ON(!IS_SKYLAKE(dev));
+				WARN_ON(!IS_ULT(dev));
 			} else
 				continue;
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index cf4fc86..be82888 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -699,6 +699,7 @@ enum intel_pch {
 	PCH_IBX,	/* Ibexpeak PCH */
 	PCH_CPT,	/* Cougarpoint PCH */
 	PCH_LPT,	/* Lynxpoint PCH */
+	PCH_SPT,        /* Sunrisepoint PCH */
 	PCH_NOP,
 };
 
@@ -2184,8 +2185,11 @@ struct drm_i915_cmd_table {
 #define INTEL_PCH_PPT_DEVICE_ID_TYPE		0x1e00
 #define INTEL_PCH_LPT_DEVICE_ID_TYPE		0x8c00
 #define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE		0x9c00
+#define INTEL_PCH_SPT_DEVICE_ID_TYPE		0xA100
+#define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE		0x9D00
 
 #define INTEL_PCH_TYPE(dev) (to_i915(dev)->pch_type)
+#define HAS_PCH_SPT(dev) (INTEL_PCH_TYPE(dev) == PCH_SPT)
 #define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT)
 #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
 #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 34/89] drm/i915/skl: Implement WaDisableSDEUnitClockGating:skl
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (32 preceding siblings ...)
  2014-09-04 11:26 ` [PATCH 33/89] drm/i915/skl: Sunrise Point PCH detection Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-17 18:48   ` Rodrigo Vivi
  2014-09-04 11:27 ` [PATCH 35/89] drm/i915/skl: Implement Wa4x4STCOptimizationDisable:skl Damien Lespiau
                   ` (55 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 0265116..0dc148c 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -68,6 +68,14 @@
 
 static void gen9_init_clock_gating(struct drm_device *dev)
 {
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/*
+	 * WaDisableSDEUnitClockGating:skl
+	 * This seems to be a pre-production w/a.
+	 */
+	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
+		   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
 }
 
 static void i8xx_disable_fbc(struct drm_device *dev)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 35/89] drm/i915/skl: Implement Wa4x4STCOptimizationDisable:skl
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (33 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 34/89] drm/i915/skl: Implement WaDisableSDEUnitClockGating:skl Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-17 19:00   ` Rodrigo Vivi
  2014-09-04 11:27 ` [PATCH 36/89] drm/i915/skl: Implement WaDisableDgMirrorFixInHalfSliceChicken5:skl Damien Lespiau
                   ` (54 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 0dc148c..c38baea 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -76,6 +76,10 @@ static void gen9_init_clock_gating(struct drm_device *dev)
 	 */
 	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
 		   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
+
+	/* Wa4x4STCOptimizationDisable:skl */
+	I915_WRITE(CACHE_MODE_1,
+		   _MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE));
 }
 
 static void i8xx_disable_fbc(struct drm_device *dev)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 36/89] drm/i915/skl: Implement WaDisableDgMirrorFixInHalfSliceChicken5:skl
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (34 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 35/89] drm/i915/skl: Implement Wa4x4STCOptimizationDisable:skl Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-17 21:22   ` Rodrigo Vivi
  2014-09-04 11:27 ` [PATCH 37/89] drm/i915/skl: Skylake has 2 "sprite" planes per pipe Damien Lespiau
                   ` (53 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h | 3 +++
 drivers/gpu/drm/i915/intel_pm.c | 8 ++++++++
 2 files changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 5928a75..c293dab 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5862,6 +5862,9 @@ enum punit_power_well {
 #define   GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE	(1<<10)
 #define   GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE	(1<<3)
 
+#define GEN9_HALF_SLICE_CHICKEN5	0xe188
+#define   GEN9_DG_MIRROR_FIX_ENABLE	(1<<5)
+
 #define GEN8_ROW_CHICKEN		0xe4f0
 #define   PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE	(1<<8)
 #define   STALL_DOP_GATING_DISABLE		(1<<5)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index c38baea..faff54e 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -77,6 +77,14 @@ static void gen9_init_clock_gating(struct drm_device *dev)
 	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
 		   GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
 
+	/*
+	 * WaDisableDgMirrorFixInHalfSliceChicken5:skl
+	 * This is a pre-production w/a.
+	 */
+	I915_WRITE(GEN9_HALF_SLICE_CHICKEN5,
+		   I915_READ(GEN9_HALF_SLICE_CHICKEN5) &
+		   ~GEN9_DG_MIRROR_FIX_ENABLE);
+
 	/* Wa4x4STCOptimizationDisable:skl */
 	I915_WRITE(CACHE_MODE_1,
 		   _MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE));
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 37/89] drm/i915/skl: Skylake has 2 "sprite" planes per pipe
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (35 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 36/89] drm/i915/skl: Implement WaDisableDgMirrorFixInHalfSliceChicken5:skl Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-17 21:25   ` Rodrigo Vivi
  2014-09-04 11:27 ` [PATCH 38/89] drm/i915/skl: Implement drm_plane vfuncs Damien Lespiau
                   ` (52 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

On Skylake, we use plane1 as primary plane and plane2/3 as sprite
planes.

v2: Rebase on top of the for_each_pipe() change adding dev_priv as first
    argument.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_dma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index a58fed9..4573953 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1528,7 +1528,7 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
 
 	info = (struct intel_device_info *)&dev_priv->info;
 
-	if (IS_VALLEYVIEW(dev))
+	if (IS_VALLEYVIEW(dev) || INTEL_INFO(dev)->gen == 9)
 		for_each_pipe(dev_priv, pipe)
 			info->num_sprites[pipe] = 2;
 	else
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 38/89] drm/i915/skl: Implement drm_plane vfuncs
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (36 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 37/89] drm/i915/skl: Skylake has 2 "sprite" planes per pipe Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-04 13:21   ` Daniel Vetter
  2014-09-17 22:08   ` Rodrigo Vivi
  2014-09-04 11:27 ` [PATCH 39/89] drm/i915/skl: Adjust assert_sprites_disabled() Damien Lespiau
                   ` (51 subsequent siblings)
  89 siblings, 2 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

SKL Uses the same hardware for all planes now, so called "universal"
planes. Ie both the primary planes and sprite planes share the same
logic. This patch implements the drm_plane vfuncs for "sprites" ie
planes that aren't the primary plane.

v2: Couple of fixes:
  - Actually enabled the planes and fix the plane number

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h     |  31 +++++-
 drivers/gpu/drm/i915/intel_sprite.c | 206 +++++++++++++++++++++++++++++++++++-
 2 files changed, 235 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index c293dab..0159f2d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4513,7 +4513,9 @@ enum punit_power_well {
 #define   PLANE_CTL_FORMAT_INDEXED		( 12 << 24)
 #define   PLANE_CTL_FORMAT_RGB_565		( 14 << 24)
 #define   PLANE_CTL_PIPE_CSC_ENABLE		(1 << 23)
-#define   PLANE_CTL_KEY_ENABLE			(1 << 22)
+#define   PLANE_CTL_KEY_ENABLE_MASK		(0x3 << 21)
+#define   PLANE_CTL_KEY_ENABLE_SOURCE		(  1 << 21)
+#define   PLANE_CTL_KEY_ENABLE_DESTINATION	(  2 << 21)
 #define   PLANE_CTL_ORDER_BGRX			(0 << 20)
 #define   PLANE_CTL_ORDER_RGBX			(1 << 20)
 #define   PLANE_CTL_YUV422_ORDER_MASK		(0x3 << 16)
@@ -4548,6 +4550,12 @@ enum punit_power_well {
 #define _PLANE_OFFSET_1_A			0x701a4
 #define _PLANE_OFFSET_2_A			0x702a4
 #define _PLANE_OFFSET_3_A			0x703a4
+#define _PLANE_KEYVAL_1_A			0x70194
+#define _PLANE_KEYVAL_2_A			0x70294
+#define _PLANE_KEYMSK_1_A			0x70198
+#define _PLANE_KEYMSK_2_A			0x70298
+#define _PLANE_KEYMAX_1_A			0x701a0
+#define _PLANE_KEYMAX_2_A			0x702a0
 
 #define _PLANE_CTL_1_B				0x71180
 #define _PLANE_CTL_2_B				0x71280
@@ -4604,6 +4612,27 @@ enum punit_power_well {
 #define PLANE_OFFSET(pipe, plane)	\
 	_PLANE(plane, _PLANE_OFFSET_1(pipe), _PLANE_OFFSET_2(pipe))
 
+#define _PLANE_KEYVAL_1_B			0x71194
+#define _PLANE_KEYVAL_2_B			0x71294
+#define _PLANE_KEYVAL_1(pipe) _PIPE(pipe, _PLANE_KEYVAL_1_A, _PLANE_KEYVAL_1_B)
+#define _PLANE_KEYVAL_2(pipe) _PIPE(pipe, _PLANE_KEYVAL_2_A, _PLANE_KEYVAL_2_B)
+#define PLANE_KEYVAL(pipe, plane)	\
+	_PLANE(plane, _PLANE_KEYVAL_1(pipe), _PLANE_KEYVAL_2(pipe))
+
+#define _PLANE_KEYMSK_1_B			0x71198
+#define _PLANE_KEYMSK_2_B			0x71298
+#define _PLANE_KEYMSK_1(pipe) _PIPE(pipe, _PLANE_KEYMSK_1_A, _PLANE_KEYMSK_1_B)
+#define _PLANE_KEYMSK_2(pipe) _PIPE(pipe, _PLANE_KEYMSK_2_A, _PLANE_KEYMSK_2_B)
+#define PLANE_KEYMSK(pipe, plane)	\
+	_PLANE(plane, _PLANE_KEYMSK_1(pipe), _PLANE_KEYMSK_2(pipe))
+
+#define _PLANE_KEYMAX_1_B			0x711a0
+#define _PLANE_KEYMAX_2_B			0x712a0
+#define _PLANE_KEYMAX_1(pipe) _PIPE(pipe, _PLANE_KEYMAX_1_A, _PLANE_KEYMAX_1_B)
+#define _PLANE_KEYMAX_2(pipe) _PIPE(pipe, _PLANE_KEYMAX_2_A, _PLANE_KEYMAX_2_B)
+#define PLANE_KEYMAX(pipe, plane)	\
+	_PLANE(plane, _PLANE_KEYMAX_1(pipe), _PLANE_KEYMAX_2(pipe))
+
 /* VBIOS regs */
 #define VGACNTRL		0x71400
 # define VGA_DISP_DISABLE			(1 << 31)
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 07a74ef..57e7190 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -139,6 +139,184 @@ static void intel_update_primary_plane(struct intel_crtc *crtc)
 }
 
 static void
+skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
+		 struct drm_framebuffer *fb,
+		 struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
+		 unsigned int crtc_w, unsigned int crtc_h,
+		 uint32_t x, uint32_t y,
+		 uint32_t src_w, uint32_t src_h)
+{
+	struct drm_device *dev = drm_plane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(drm_plane);
+	const int pipe = intel_plane->pipe;
+	const int plane = intel_plane->plane + 1;
+	u32 plane_ctl, stride;
+	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
+
+	plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
+
+	/* Mask out pixel format bits in case we change it */
+	plane_ctl &= ~PLANE_CTL_FORMAT_MASK;
+	plane_ctl &= ~PLANE_CTL_ORDER_RGBX;
+	plane_ctl &= ~PLANE_CTL_YUV422_ORDER_MASK;
+	plane_ctl &= ~PLANE_CTL_TILED_MASK;
+	plane_ctl &= ~PLANE_CTL_ALPHA_MASK;
+
+	/* Trickle feed has to be enabled */
+	plane_ctl &= ~PLANE_CTL_TRICKLE_FEED_DISABLE;
+
+	switch (fb->pixel_format) {
+	case DRM_FORMAT_RGB565:
+		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
+		break;
+	case DRM_FORMAT_XBGR8888:
+		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
+		break;
+	case DRM_FORMAT_XRGB8888:
+		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
+		break;
+	/*
+	 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
+	 * to be already pre-multiplied. We need to add a knob (or a different
+	 * DRM_FORMAT) for user-space to configure that.
+	 */
+	case DRM_FORMAT_ABGR8888:
+		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
+			     PLANE_CTL_ORDER_RGBX |
+			     PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+		break;
+	case DRM_FORMAT_ARGB8888:
+		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
+			     PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+		break;
+	case DRM_FORMAT_YUYV:
+		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
+		break;
+	case DRM_FORMAT_YVYU:
+		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
+		break;
+	case DRM_FORMAT_UYVY:
+		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
+		break;
+	case DRM_FORMAT_VYUY:
+		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
+		break;
+	default:
+		BUG();
+	}
+
+	switch (obj->tiling_mode) {
+	case I915_TILING_NONE:
+		stride = fb->pitches[0] >> 6;
+		break;
+	case I915_TILING_X:
+		plane_ctl |= PLANE_CTL_TILED_X;
+		stride = fb->pitches[0] >> 9;
+		break;
+	default:
+		BUG();
+	}
+
+	plane_ctl |= PLANE_CTL_ENABLE;
+	plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE;
+
+	intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h,
+				       pixel_size, true,
+				       src_w != crtc_w || src_h != crtc_h);
+
+	/* Sizes are 0 based */
+	src_w--;
+	src_h--;
+	crtc_w--;
+	crtc_h--;
+
+	I915_WRITE(PLANE_OFFSET(pipe, plane), (y << 16) | x);
+	I915_WRITE(PLANE_STRIDE(pipe, plane), stride);
+	I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
+	I915_WRITE(PLANE_SIZE(pipe, plane), (crtc_h << 16) | crtc_w);
+	I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
+	I915_WRITE(PLANE_SURF(pipe, plane), i915_gem_obj_ggtt_offset(obj));
+	POSTING_READ(PLANE_SURF(pipe, plane));
+}
+
+static void
+skl_disable_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc)
+{
+	struct drm_device *dev = drm_plane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(drm_plane);
+	const int pipe = intel_plane->pipe;
+	const int plane = intel_plane->plane + 1;
+
+	I915_WRITE(PLANE_CTL(pipe, plane),
+		   I915_READ(PLANE_CTL(pipe, plane)) & ~PLANE_CTL_ENABLE);
+
+	/* Activate double buffered register update */
+	I915_WRITE(PLANE_CTL(pipe, plane), 0);
+	POSTING_READ(PLANE_CTL(pipe, plane));
+
+	intel_update_sprite_watermarks(drm_plane, crtc, 0, 0, 0, false, false);
+}
+
+static int
+skl_update_colorkey(struct drm_plane *drm_plane,
+		    struct drm_intel_sprite_colorkey *key)
+{
+	struct drm_device *dev = drm_plane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(drm_plane);
+	const int pipe = intel_plane->pipe;
+	const int plane = intel_plane->plane;
+	u32 plane_ctl;
+
+	I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value);
+	I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value);
+	I915_WRITE(PLANE_KEYMSK(pipe, plane), key->channel_mask);
+
+	plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
+	plane_ctl &= ~PLANE_CTL_KEY_ENABLE_MASK;
+	if (key->flags & I915_SET_COLORKEY_DESTINATION)
+		plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION;
+	else if (key->flags & I915_SET_COLORKEY_SOURCE)
+		plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE;
+	I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
+
+	POSTING_READ(PLANE_CTL(pipe, plane));
+
+	return 0;
+}
+
+static void
+skl_get_colorkey(struct drm_plane *drm_plane,
+		 struct drm_intel_sprite_colorkey *key)
+{
+	struct drm_device *dev = drm_plane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(drm_plane);
+	const int pipe = intel_plane->pipe;
+	const int plane = intel_plane->plane;
+	u32 plane_ctl;
+
+	key->min_value = I915_READ(PLANE_KEYVAL(pipe, plane));
+	key->max_value = I915_READ(PLANE_KEYMAX(pipe, plane));
+	key->channel_mask = I915_READ(PLANE_KEYMSK(pipe, plane));
+
+	plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
+
+	switch (plane_ctl & PLANE_CTL_KEY_ENABLE_MASK) {
+	case PLANE_CTL_KEY_ENABLE_DESTINATION:
+		key->flags = I915_SET_COLORKEY_DESTINATION;
+		break;
+	case PLANE_CTL_KEY_ENABLE_SOURCE:
+		key->flags = I915_SET_COLORKEY_SOURCE;
+		break;
+	default:
+		key->flags = I915_SET_COLORKEY_NONE;
+	}
+}
+
+static void
 vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
 		 struct drm_framebuffer *fb,
 		 struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
@@ -1305,6 +1483,18 @@ static uint32_t vlv_plane_formats[] = {
 	DRM_FORMAT_VYUY,
 };
 
+static uint32_t skl_plane_formats[] = {
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_YUYV,
+	DRM_FORMAT_YVYU,
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_VYUY,
+};
+
 int
 intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
 {
@@ -1368,7 +1558,21 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
 			num_plane_formats = ARRAY_SIZE(snb_plane_formats);
 		}
 		break;
-
+	case 9:
+		/*
+		 * FIXME: Skylake planes can be scaled (with some restrictions),
+		 * but this is for another time.
+		 */
+		intel_plane->can_scale = false;
+		intel_plane->max_downscale = 1;
+		intel_plane->update_plane = skl_update_plane;
+		intel_plane->disable_plane = skl_disable_plane;
+		intel_plane->update_colorkey = skl_update_colorkey;
+		intel_plane->get_colorkey = skl_get_colorkey;
+
+		plane_formats = skl_plane_formats;
+		num_plane_formats = ARRAY_SIZE(skl_plane_formats);
+		break;
 	default:
 		kfree(intel_plane);
 		return -ENODEV;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 39/89] drm/i915/skl: Adjust assert_sprites_disabled()
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (37 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 38/89] drm/i915/skl: Implement drm_plane vfuncs Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-17 22:10   ` Rodrigo Vivi
  2014-09-04 11:27 ` [PATCH 40/89] drm/i915/skl: Introduce a I915_MAX_PLANES macro Damien Lespiau
                   ` (50 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

Let's put to good use the new PLANE_CTL macros.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 48d2d0d..3d9f447 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1335,7 +1335,14 @@ static void assert_sprites_disabled(struct drm_i915_private *dev_priv,
 	int reg, sprite;
 	u32 val;
 
-	if (IS_VALLEYVIEW(dev)) {
+	if (INTEL_INFO(dev)->gen >= 9) {
+		for_each_sprite(pipe, sprite) {
+			val = I915_READ(PLANE_CTL(pipe, sprite));
+			WARN(val & PLANE_CTL_ENABLE,
+			     "plane %d assertion failure, should be off on pipe %c but is still active\n",
+			     sprite, pipe_name(pipe));
+		}
+	} else if (IS_VALLEYVIEW(dev)) {
 		for_each_sprite(pipe, sprite) {
 			reg = SPCNTR(pipe, sprite);
 			val = I915_READ(reg);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 40/89] drm/i915/skl: Introduce a I915_MAX_PLANES macro
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (38 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 39/89] drm/i915/skl: Adjust assert_sprites_disabled() Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-17 22:12   ` Rodrigo Vivi
  2014-09-04 11:27 ` [PATCH 41/89] drm/i915/skl: Introduce intel_num_planes() Damien Lespiau
                   ` (49 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

This can be useful to declare structures around pipes and planes and
don't have to go back auditing the code if the next platorm bump that
number.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index be82888..dcd1c72 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -74,6 +74,14 @@ enum transcoder {
 };
 #define transcoder_name(t) ((t) + 'A')
 
+/*
+ * This is the maximum (across all platforms) number of planes (primary +
+ * sprites) that can be active at the same time on one pipe.
+ *
+ * This value doesn't count the cursor plane.
+ */
+#define I915_MAX_PLANES	3
+
 enum plane {
 	PLANE_A = 0,
 	PLANE_B,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 41/89] drm/i915/skl: Introduce intel_num_planes()
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (39 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 40/89] drm/i915/skl: Introduce a I915_MAX_PLANES macro Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-17 22:13   ` Rodrigo Vivi
  2014-09-04 11:27 ` [PATCH 42/89] drm/i915/skl: Move gen9 pm initialization into its own branch Damien Lespiau
                   ` (48 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

It can be handy to get the number of planes for this pipe, ie including
the primary plane to loop over them. Introduce a little function to do
so.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d727d20..3239e58 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -721,6 +721,14 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
 	return container_of(intel_hdmi, struct intel_digital_port, hdmi);
 }
 
+/*
+ * Returns the number of planes for this pipe, ie the number of sprites + 1
+ * (primary plane). This doesn't count the cursor plane then.
+ */
+static inline unsigned int intel_num_planes(struct intel_crtc *crtc)
+{
+	return INTEL_INFO(crtc->base.dev)->num_sprites[crtc->pipe] + 1;
+}
 
 /* i915_irq.c */
 bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 42/89] drm/i915/skl: Move gen9 pm initialization into its own branch
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (40 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 41/89] drm/i915/skl: Introduce intel_num_planes() Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-17 22:16   ` Rodrigo Vivi
  2014-09-04 11:27 ` [PATCH 43/89] drm/i915/skl: Read the Memory Latency Values for WM computation Damien Lespiau
                   ` (47 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

Gen9 is different enough (for instance, fetching the memory latency
values is different from ILK+) to not take the HAS_PCH_SPLIT() branch,
so let's prefer a clean separation.

v2: Rebase on top of the broadwell_init_clock_gating() name change

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index faff54e..a236e77 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7395,7 +7395,9 @@ void intel_init_pm(struct drm_device *dev)
 		i915_ironlake_get_mem_freq(dev);
 
 	/* For FIFO watermark updates */
-	if (HAS_PCH_SPLIT(dev)) {
+	if (IS_GEN9(dev)) {
+		dev_priv->display.init_clock_gating = gen9_init_clock_gating;
+	} else if (HAS_PCH_SPLIT(dev)) {
 		ilk_setup_wm_latency(dev);
 
 		if ((IS_GEN5(dev) && dev_priv->wm.pri_latency[1] &&
@@ -7419,8 +7421,6 @@ void intel_init_pm(struct drm_device *dev)
 			dev_priv->display.init_clock_gating = haswell_init_clock_gating;
 		else if (INTEL_INFO(dev)->gen == 8)
 			dev_priv->display.init_clock_gating = broadwell_init_clock_gating;
-		else if (INTEL_INFO(dev)->gen == 9)
-			dev_priv->display.init_clock_gating = gen9_init_clock_gating;
 	} else if (IS_CHERRYVIEW(dev)) {
 		dev_priv->display.update_wm = cherryview_update_wm;
 		dev_priv->display.update_sprite_wm = valleyview_update_sprite_wm;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 43/89] drm/i915/skl: Read the Memory Latency Values for WM computation
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (41 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 42/89] drm/i915/skl: Move gen9 pm initialization into its own branch Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-04 18:49   ` [PATCH 43/89 v6] " Damien Lespiau
  2014-09-05  8:25   ` [PATCH 43/89] " Ville Syrjälä
  2014-09-04 11:27 ` [PATCH 44/89] drm/i915/skl: Register definitions and macros for SKL Watermark regs Damien Lespiau
                   ` (46 subsequent siblings)
  89 siblings, 2 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx; +Cc: Pradeep Bhat

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch reads the memory latency values for all the 8 levels for
SKL. These values are needed for the Watermark computation.

v2: Incorporated the review comments from Damien on register
    indentation.

v3: Updated the code to use the sandybridge_pcode_read for reading
    memory latencies for GEN9.

v4: Don't put gen 9 in the middle of an ordered list of ifs
    (Damien)

v5 take the rps.hw_lock around sandybridge_pcode_read() (Damien)

Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h |  6 ++++
 drivers/gpu/drm/i915/i915_reg.h |  9 +++++
 drivers/gpu/drm/i915/intel_pm.c | 73 +++++++++++++++++++++++++++++++++++++----
 3 files changed, 82 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index dcd1c72..32be299 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1665,6 +1665,12 @@ struct drm_i915_private {
 		uint16_t spr_latency[5];
 		/* cursor */
 		uint16_t cur_latency[5];
+		/*
+		 * Raw watermark memory latency values
+		 * for SKL for all 8 levels
+		 * in 1us units.
+		 */
+		uint16_t skl_latency[8];
 
 		/* current hardware state */
 		struct ilk_wm_values hw;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 0159f2d..bc55990 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2018,6 +2018,15 @@ enum punit_power_well {
 #define   MAD_DIMM_A_SIZE_SHIFT		0
 #define   MAD_DIMM_A_SIZE_MASK		(0xff << MAD_DIMM_A_SIZE_SHIFT)
 
+/* SKL GT Driver Mailbox registers for reading memory latencies */
+#define GEN9_MAILBOX_DATA1		0x13812C
+#define   GEN9_MAILBOX_READ_MEM_LAT	(0x6)
+#define   GEN9_MAILBOX_READ_TIMEOUT	150
+#define   GEN9_MEM_LAT_LEVEL_MASK	0xFF
+#define   GEN9_MEM_LAT_LEVEL_1_5_SHIFT	8
+#define   GEN9_MEM_LAT_LEVEL_2_6_SHIFT	16
+#define   GEN9_MEM_LAT_LEVEL_3_7_SHIFT	24
+
 /* snb MCH registers for priority tuning */
 #define MCH_SSKPD			(MCHBAR_MIRROR_BASE_SNB + 0x5d10)
 #define   MCH_SSKPD_WM0_MASK		0x3f
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a236e77..d8c8531 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2239,11 +2239,53 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)
 	       PIPE_WM_LINETIME_TIME(linetime);
 }
 
-static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[5])
+static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+	if (IS_GEN9(dev)) {
+		uint32_t val;
+		int ret;
+
+		/* read the first set of memory latencies[0:3] */
+		val = 0; /* data0 to be programmed to 0 for first set */
+		mutex_lock(&dev_priv->rps.hw_lock);
+		ret = sandybridge_pcode_read(dev_priv,
+					     GEN9_MAILBOX_READ_MEM_LAT,
+					     &val);
+		mutex_unlock(&dev_priv->rps.hw_lock);
+
+		if (ret) {
+			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
+			return;
+		}
+		wm[0] = val & GEN9_MEM_LAT_LEVEL_MASK;
+		wm[1] = (val >> GEN9_MEM_LAT_LEVEL_1_5_SHIFT) &
+				GEN9_MEM_LAT_LEVEL_MASK;
+		wm[2] = (val >> GEN9_MEM_LAT_LEVEL_2_6_SHIFT) &
+				GEN9_MEM_LAT_LEVEL_MASK;
+		wm[3] = (val >> GEN9_MEM_LAT_LEVEL_3_7_SHIFT) &
+				GEN9_MEM_LAT_LEVEL_MASK;
+
+		/* read the second set of memory latencies[4:7] */
+		val = 1; /* data0 to be programmed to 1 for second set */
+		mutex_lock(&dev_priv->rps.hw_lock);
+		ret = sandybridge_pcode_read(dev_priv,
+					     GEN9_MAILBOX_READ_MEM_LAT,
+					     &val);
+		mutex_unlock(&dev_priv->rps.hw_lock);
+		if (ret) {
+			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
+			return;
+		}
+		wm[4] = val & GEN9_MEM_LAT_LEVEL_MASK;
+		wm[5] = (val >> GEN9_MEM_LAT_LEVEL_1_5_SHIFT) &
+				GEN9_MEM_LAT_LEVEL_MASK;
+		wm[6] = (val >> GEN9_MEM_LAT_LEVEL_2_6_SHIFT) &
+				GEN9_MEM_LAT_LEVEL_MASK;
+		wm[7] = (val >> GEN9_MEM_LAT_LEVEL_3_7_SHIFT) &
+				GEN9_MEM_LAT_LEVEL_MASK;
+	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
 		uint64_t sskpd = I915_READ64(MCH_SSKPD);
 
 		wm[0] = (sskpd >> 56) & 0xFF;
@@ -2291,7 +2333,9 @@ static void intel_fixup_cur_wm_latency(struct drm_device *dev, uint16_t wm[5])
 int ilk_wm_max_level(const struct drm_device *dev)
 {
 	/* how many WM levels are we expecting */
-	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+	if (IS_GEN9(dev))
+		return 7;
+	else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
 		return 4;
 	else if (INTEL_INFO(dev)->gen >= 6)
 		return 3;
@@ -2300,7 +2344,7 @@ int ilk_wm_max_level(const struct drm_device *dev)
 }
 static void intel_print_wm_latency(struct drm_device *dev,
 				   const char *name,
-				   const uint16_t wm[5])
+				   const uint16_t wm[8])
 {
 	int level, max_level = ilk_wm_max_level(dev);
 
@@ -2313,8 +2357,13 @@ static void intel_print_wm_latency(struct drm_device *dev,
 			continue;
 		}
 
-		/* WM1+ latency values in 0.5us units */
-		if (level > 0)
+		/*
+		 * - latencies are in us on gen9.
+		 * - before then, WM1+ latency values are in 0.5us units
+		 */
+		if (IS_GEN9(dev))
+			latency *= 10;
+		else if (level > 0)
 			latency *= 5;
 
 		DRM_DEBUG_KMS("%s WM%d latency %u (%u.%u usec)\n",
@@ -2382,6 +2431,14 @@ static void ilk_setup_wm_latency(struct drm_device *dev)
 		snb_wm_latency_quirk(dev);
 }
 
+static void skl_setup_wm_latency(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	intel_read_wm_latency(dev, dev_priv->wm.skl_latency);
+	intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
+}
+
 static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
 				      struct ilk_pipe_wm_parameters *p)
 {
@@ -7396,6 +7453,8 @@ void intel_init_pm(struct drm_device *dev)
 
 	/* For FIFO watermark updates */
 	if (IS_GEN9(dev)) {
+		skl_setup_wm_latency(dev);
+
 		dev_priv->display.init_clock_gating = gen9_init_clock_gating;
 	} else if (HAS_PCH_SPLIT(dev)) {
 		ilk_setup_wm_latency(dev);
@@ -7488,6 +7547,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val)
 	}
 
 	I915_WRITE(GEN6_PCODE_DATA, *val);
+	if (IS_GEN9(dev_priv->dev))
+		I915_WRITE(GEN9_MAILBOX_DATA1, 0);
 	I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox);
 
 	if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 44/89] drm/i915/skl: Register definitions and macros for SKL Watermark regs
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (42 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 43/89] drm/i915/skl: Read the Memory Latency Values for WM computation Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-10 18:04   ` Ville Syrjälä
  2014-09-23 11:17   ` [PATCH 44/89 v5] " Damien Lespiau
  2014-09-04 11:27 ` [PATCH 45/89] drm/i915/skl: Definition of SKL WM param structs for pipe/plane Damien Lespiau
                   ` (45 subsequent siblings)
  89 siblings, 2 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx; +Cc: Pradeep Bhat

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch defines SKL specific PLANE_WM Watermark registers. It also
defines macros to get the addresses of different LP levels within a pipe.

v2: Reworked the register definitions and associated macros to make it more
    generic and be able to use for_each_pipe in values computation.
    Incorporated Damien's review comments and indentation.

v3: Added default values for lines and blocks. Provided mask for blocks.

Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index bc55990..9fbce2c 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4066,6 +4066,43 @@ enum punit_power_well {
 #define I965_CURSOR_MAX_WM	32
 #define I965_CURSOR_DFT_WM	8
 
+/* Watermark register definitions for SKL */
+#define CUR_WM_A_0		0x70140
+#define CUR_WM_B_0		0x71140
+#define PLANE_WM_1_A_0		0x70240
+#define PLANE_WM_1_B_0		0x71240
+#define PLANE_WM_2_A_0		0x70340
+#define PLANE_WM_2_B_0		0x71340
+#define PLANE_WM_TRANS_1_A_0	0x70268
+#define PLANE_WM_TRANS_1_B_0	0x71268
+#define PLANE_WM_TRANS_2_A_0	0x70368
+#define PLANE_WM_TRANS_2_B_0	0x71368
+#define CUR_WM_TRANS_A_0	0x70168
+#define CUR_WM_TRANS_B_0	0x71168
+#define   PLANE_WM_EN		(1 << 31)
+#define   PLANE_WM_LINES_SHIFT	14
+#define   PLANE_WM_LINES_MASK	0x1f
+#define   PLANE_WM_BLOCKS_MASK	0x3ff
+#define   PLANE_WM_LINES_DEFAULT	0x1
+#define   PLANE_WM_BLOCKS_DEFAULT	0x7
+
+#define CUR_WM_0(pipe) _PIPE(pipe, CUR_WM_A_0, CUR_WM_B_0)
+#define CUR_WM(pipe, level) (CUR_WM_0(pipe) + ((4) * (level)))
+#define CUR_WM_TRANS(pipe) _PIPE(pipe, CUR_WM_TRANS_A_0, CUR_WM_TRANS_B_0)
+
+#define PLANE_WM_1(pipe) _PIPE(pipe, PLANE_WM_1_A_0, PLANE_WM_1_B_0)
+#define PLANE_WM_2(pipe) _PIPE(pipe, PLANE_WM_2_A_0, PLANE_WM_2_B_0)
+#define PLANE_WM_BASE(pipe, plane)	\
+			_PLANE(plane, PLANE_WM_1(pipe), PLANE_WM_2(pipe))
+#define PLANE_WM(pipe, plane, level)	\
+			(PLANE_WM_BASE(pipe, plane) + ((4) * (level)))
+#define PLANE_WM_TRANS_1(pipe)		\
+			_PIPE(pipe, PLANE_WM_TRANS_1_A_0, PLANE_WM_TRANS_1_B_0)
+#define PLANE_WM_TRANS_2(pipe)		\
+			_PIPE(pipe, PLANE_WM_TRANS_2_A_0, PLANE_WM_TRANS_2_B_0)
+#define PLANE_WM_TRANS(pipe, plane)	\
+		_PLANE(plane, PLANE_WM_TRANS_1(pipe), PLANE_WM_TRANS_2(pipe))
+
 /* define the Watermark register on Ironlake */
 #define WM0_PIPEA_ILK		0x45100
 #define  WM0_PIPE_PLANE_MASK	(0xffff<<16)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 45/89] drm/i915/skl: Definition of SKL WM param structs for pipe/plane
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (43 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 44/89] drm/i915/skl: Register definitions and macros for SKL Watermark regs Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-10 18:39   ` Ville Syrjälä
  2014-09-22 14:06   ` Ville Syrjälä
  2014-09-04 11:27 ` [PATCH 46/89] drm/i915/skl: Add DDB allocation management structures Damien Lespiau
                   ` (44 subsequent siblings)
  89 siblings, 2 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx; +Cc: Pradeep Bhat

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch defines the structures needed for computation of
watermarks of pipes and planes for SKL.

v2: Incorporated Damien's review comments and removed unused fields
    in structs for future features like rotation, drrs and scaling.
    The skl_wm_values struct is now made more generic across planes
    and cursor planes for all pipes.

v3: implemented the plane/cursor split.

Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h  | 18 ++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h | 10 +++++++++-
 drivers/gpu/drm/i915/intel_pm.c  |  8 ++++++++
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 32be299..3764ad5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1381,6 +1381,24 @@ struct ilk_wm_values {
 	enum intel_ddb_partitioning partitioning;
 };
 
+struct skl_wm_values {
+	bool dirty[I915_MAX_PIPES];
+	uint32_t wm_linetime[I915_MAX_PIPES];
+	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
+	uint32_t cursor[I915_MAX_PIPES][8];
+	uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
+	uint32_t cursor_trans[I915_MAX_PIPES];
+};
+
+struct skl_wm_level {
+	bool plane_en[I915_MAX_PLANES];
+	uint16_t plane_res_b[I915_MAX_PLANES];
+	uint8_t plane_res_l[I915_MAX_PLANES];
+	bool cursor_en;
+	uint16_t cursor_res_b;
+	uint8_t cursor_res_l;
+};
+
 /*
  * This struct helps tracking the state needed for runtime PM, which puts the
  * device in PCI D3 state. Notice that when this happens, nothing on the
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3239e58..268087f 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -387,6 +387,12 @@ struct intel_mmio_flip {
 	u32 ring_id;
 };
 
+struct skl_pipe_wm {
+	struct skl_wm_level wm[8];
+	struct skl_wm_level trans_wm;
+	uint32_t linetime;
+};
+
 struct intel_crtc {
 	struct drm_crtc base;
 	enum pipe pipe;
@@ -431,9 +437,11 @@ struct intel_crtc {
 	bool pch_fifo_underrun_disabled;
 
 	/* per-pipe watermark state */
-	struct {
+	union {
 		/* watermarks currently being used  */
 		struct intel_pipe_wm active;
+		/* SKL wm values currently in use */
+		struct skl_pipe_wm skl_active;
 	} wm;
 
 	int scanline_offset;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d8c8531..2503ab9 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1928,6 +1928,14 @@ static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels,
 	return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2;
 }
 
+struct skl_pipe_wm_parameters {
+	bool active;
+	uint32_t pipe_htotal;
+	uint32_t pixel_rate; /* in KHz */
+	struct intel_plane_wm_parameters plane[I915_MAX_PLANES];
+	struct intel_plane_wm_parameters cursor;
+};
+
 struct ilk_pipe_wm_parameters {
 	bool active;
 	uint32_t pipe_htotal;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 46/89] drm/i915/skl: Add DDB allocation management structures
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (44 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 45/89] drm/i915/skl: Definition of SKL WM param structs for pipe/plane Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-17 10:47   ` Ville Syrjälä
  2014-10-29 15:32   ` Ville Syrjälä
  2014-09-04 11:27 ` [PATCH 47/89] drm/i915/skl: SKL Watermark Computation Damien Lespiau
                   ` (43 subsequent siblings)
  89 siblings, 2 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

We now need to allocate space in the DDB for planes being scanned out
ourselves. The data structure to represent an allocation mirrors what
we'll need to write in the registers later on: (start, end).

We add that allocation datat to the skl_wm_values structure as part of
the values to program the hardware with.

v2: Split planes and cursor for consistency.

v3: Make the skl_ddb_entry_size() parameter const

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 3764ad5..de278a5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1381,8 +1381,27 @@ struct ilk_wm_values {
 	enum intel_ddb_partitioning partitioning;
 };
 
+struct skl_ddb_entry {
+	uint16_t start, end;	/* in number of blocks */
+};
+
+static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry)
+{
+	/* end not set, clearly no allocation here. start can be 0 though */
+	if (entry->end == 0)
+		return 0;
+
+	return entry->end - entry->start + 1;
+}
+
+struct skl_ddb_allocation {
+	struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
+	struct skl_ddb_entry cursor[I915_MAX_PIPES];
+};
+
 struct skl_wm_values {
 	bool dirty[I915_MAX_PIPES];
+	struct skl_ddb_allocation ddb;
 	uint32_t wm_linetime[I915_MAX_PIPES];
 	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
 	uint32_t cursor[I915_MAX_PIPES][8];
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 47/89] drm/i915/skl: SKL Watermark Computation
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (45 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 46/89] drm/i915/skl: Add DDB allocation management structures Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-17 12:07   ` Ville Syrjälä
  2014-09-04 11:27 ` [PATCH 48/89] drm/i915/skl: Allocate DDB portions for display planes Damien Lespiau
                   ` (42 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx; +Cc: Pradeep Bhat

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch implements the watermark algorithm and its necessary
functions. Two function pointers skl_update_wm and
skl_update_sprite_wm are provided. The skl_update_wm will update
the watermarks for the crtc provided as an argument and then
checks for change in DDB allocation for other active pipes and
recomputes the watermarks for those Pipes and planes as well.
Finally it does the register programming for all dirty pipes.
The trigger of the Watermark double buffer registers will have
to be once the plane configurations are done by the caller.

v2: fixed the divide-by-0 error in the results computation func.
    Also reworked the PLANE_WM register values computation func to
    make it more compact. Incorporated all other review comments
    from Damien.

v3: Changed the skl_compute_plane_wm function to now return success
    or failure. Also the result blocks and lines are computed here
    instead of in skl_compute_wm_results function.

v4: Adjust skl_ddb_alloc_changed() to the new planes/cursor split
    (Damien)

v5: Reworked the affected functions to implement new plane/cursor
    split.

v6: Rework the logic that triggers the DDB allocation and WM computation
    of skl_update_other_pipe_wm() to not depend on non-computed DDB
    values.
    Always give a valid cursor_width (at boot it's 0) to keep the
    invariant that we consider the cursor plane always enabled.
    Otherwise we end up dividing by 0 in skl_compute_plane_wm()
    (Damien Lespiau)

v7: Spell out allocation
    skl_ddb_ functions should have the ddb as first argument
    Make the skl_ddb_alloc_changed() parameters const
    (Damien)

v8: Rebase on top of the crtc->primary changes

v9: Split the staging results structure to not exceed the 1Kb stack
    allocation in skl_update_wm()

Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

drm/i915/skl: Don't allocate as much on the stack in skl_update_wm()

Stack space can be scarce and a compiler check has been added to warn if the
per-function stack allocation is above 1KB.

We we were hitting that warning in skl_update_wm(), so move the big
results array in dev_priv instead.

For reference, here's the compiler warning before this patch:

  drivers/gpu/drm/i915/intel_pm.c: In function ‘skl_update_wm’:
  drivers/gpu/drm/i915/intel_pm.c:3618:1: warning: the frame size of 1296 bytes
    is larger than 1024 bytes [-Wframe-larger-than=]

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h |  12 +-
 drivers/gpu/drm/i915/intel_pm.c | 423 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 434 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index de278a5..9b0e398 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1709,8 +1709,18 @@ struct drm_i915_private {
 		 */
 		uint16_t skl_latency[8];
 
+		/*
+		 * The skl_wm_values structure is a bit too big for stack
+		 * allocation, so we keep the staging struct where we store
+		 * intermediate results here instead.
+		 */
+		struct skl_wm_values skl_results;
+
 		/* current hardware state */
-		struct ilk_wm_values hw;
+		union {
+			struct ilk_wm_values hw;
+			struct skl_wm_values skl_hw;
+		};
 	} wm;
 
 	struct i915_runtime_pm pm;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 2503ab9..4ee90b6 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2937,6 +2937,427 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
 	return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
 }
 
+static uint32_t skl_pipe_pixel_rate(struct drm_device *dev,
+				    struct drm_crtc *crtc)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	uint32_t pixel_rate;
+
+	pixel_rate = intel_crtc->config.adjusted_mode.crtc_clock;
+
+	return pixel_rate;
+}
+
+static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel,
+			       uint32_t latency)
+{
+	uint32_t wm_intermediate_val, ret;
+
+	if (latency == 0)
+		return UINT_MAX;
+
+	wm_intermediate_val = latency * pixel_rate * bytes_per_pixel;
+	ret = DIV_ROUND_UP(wm_intermediate_val, 1000);
+
+	return ret;
+}
+
+static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
+			       uint32_t horiz_pixels, uint8_t bytes_per_pixel,
+			       uint32_t latency)
+{
+	uint32_t ret, plane_bytes_per_line, wm_intermediate_val;
+
+	if (latency == 0)
+		return UINT_MAX;
+
+	plane_bytes_per_line = horiz_pixels * bytes_per_pixel;
+	wm_intermediate_val = latency * pixel_rate;
+	ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) *
+				plane_bytes_per_line;
+
+	return ret;
+}
+
+static void skl_compute_transition_wm(struct drm_crtc *crtc,
+				  struct skl_pipe_wm_parameters *params,
+				  struct skl_pipe_wm *pipe_wm)
+{
+	/*
+	 * For now it is suggested to use the LP0 wm val of corresponding
+	 * plane as transition wm val. This is done while computing results.
+	 */
+	if (!params->active)
+		return;
+}
+
+static uint32_t
+skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p)
+{
+	if (!intel_crtc_active(crtc))
+		return 0;
+
+	return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate);
+
+}
+
+static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
+				       const struct intel_crtc *intel_crtc)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
+	enum pipe pipe = intel_crtc->pipe;
+	size_t size;
+
+	size = ARRAY_SIZE(new_ddb->plane[pipe]) * sizeof(struct skl_ddb_entry);
+	if (memcmp(new_ddb->plane[pipe], cur_ddb->plane[pipe], size))
+		return true;
+
+	if (memcmp(&new_ddb->cursor[pipe], &cur_ddb->cursor[pipe],
+		    sizeof(struct skl_ddb_entry)))
+		return true;
+
+	return false;
+}
+
+static void skl_compute_wm_global_parameters(struct drm_device *dev,
+					     struct intel_wm_config *config)
+{
+	struct drm_crtc *crtc;
+	struct drm_plane *plane;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+		config->num_pipes_active += intel_crtc_active(crtc);
+
+	/* FIXME: I don't think we need those two global parameters on SKL */
+	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+		struct intel_plane *intel_plane = to_intel_plane(plane);
+
+		config->sprites_enabled |= intel_plane->wm.enabled;
+		config->sprites_scaled |= intel_plane->wm.scaled;
+	}
+}
+
+static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
+					   struct skl_pipe_wm_parameters *p)
+{
+	struct drm_device *dev = crtc->dev;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	enum pipe pipe = intel_crtc->pipe;
+	struct drm_plane *plane;
+	int i = 1; /* Index for sprite planes start */
+
+	p->active = intel_crtc_active(crtc);
+	if (p->active) {
+		p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal;
+		p->pixel_rate = skl_pipe_pixel_rate(dev, crtc);
+
+		/*
+		 * For now, assume primary and cursor planes are always enabled.
+		 */
+		p->plane[0].enabled = true;
+		p->plane[0].bytes_per_pixel =
+			crtc->primary->fb->bits_per_pixel / 8;
+		p->plane[0].horiz_pixels = intel_crtc->config.pipe_src_w;
+		p->plane[0].vert_pixels = intel_crtc->config.pipe_src_h;
+
+		p->cursor.enabled = true;
+		p->cursor.bytes_per_pixel = 4;
+		p->cursor.horiz_pixels = intel_crtc->cursor_width ?
+					 intel_crtc->cursor_width : 64;
+	}
+
+	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+		struct intel_plane *intel_plane = to_intel_plane(plane);
+
+		if (intel_plane->pipe == pipe)
+			p->plane[i++] = intel_plane->wm;
+	}
+}
+
+static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
+				   struct intel_plane_wm_parameters *p_params,
+				   uint16_t max_page_buff_alloc,
+				   uint32_t mem_value,
+				   uint16_t *res_blocks, /* out */
+				   uint8_t *res_lines /* out */)
+{
+	uint32_t method1, method2, plane_bytes_per_line;
+	uint32_t result_bytes;
+
+	if (!p->active || !p_params->enabled) {
+		*res_blocks = PLANE_WM_BLOCKS_DEFAULT;
+		*res_lines = PLANE_WM_LINES_DEFAULT;
+		return false;
+	}
+
+	method1 = skl_wm_method1(p->pixel_rate,
+				 p_params->bytes_per_pixel,
+				 mem_value);
+	method2 = skl_wm_method2(p->pixel_rate,
+				 p->pipe_htotal,
+				 p_params->horiz_pixels,
+				 p_params->bytes_per_pixel,
+				 mem_value);
+
+	plane_bytes_per_line = p_params->horiz_pixels *
+					p_params->bytes_per_pixel;
+
+	/* For now xtile and linear */
+	if (((max_page_buff_alloc * 512) / plane_bytes_per_line) >= 1)
+		result_bytes = min(method1, method2);
+	else
+		result_bytes = method1;
+
+	*res_blocks = DIV_ROUND_UP(result_bytes, 512) + 1;
+	*res_lines = DIV_ROUND_UP(result_bytes, plane_bytes_per_line);
+
+	return true;
+}
+
+static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
+				 struct skl_ddb_allocation *ddb,
+				 struct skl_pipe_wm_parameters *p,
+				 enum pipe pipe,
+				 int level,
+				 int num_planes,
+				 struct skl_wm_level *result)
+{
+	uint16_t latency = dev_priv->wm.skl_latency[level];
+	uint16_t ddb_blocks;
+	int i;
+
+	for (i = 0; i < num_planes; i++) {
+		ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
+
+		result->plane_en[i] = skl_compute_plane_wm(p, &p->plane[i],
+						ddb_blocks,
+						latency,
+						&result->plane_res_b[i],
+						&result->plane_res_l[i]);
+	}
+
+	ddb_blocks = skl_ddb_entry_size(&ddb->cursor[pipe]);
+	result->cursor_en = skl_compute_plane_wm(p, &p->cursor, ddb_blocks,
+						 latency, &result->cursor_res_b,
+						 &result->cursor_res_l);
+}
+
+static void skl_compute_pipe_wm(struct drm_crtc *crtc,
+				struct skl_ddb_allocation *ddb,
+				struct skl_pipe_wm_parameters *params,
+				struct skl_pipe_wm *pipe_wm)
+{
+	struct drm_device *dev = crtc->dev;
+	const struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int level, max_level = ilk_wm_max_level(dev);
+
+	for (level = 0; level <= max_level; level++) {
+		skl_compute_wm_level(dev_priv, ddb, params, intel_crtc->pipe,
+				     level, intel_num_planes(intel_crtc),
+				     &pipe_wm->wm[level]);
+	}
+	pipe_wm->linetime = skl_compute_linetime_wm(crtc, params);
+
+	skl_compute_transition_wm(crtc, params, pipe_wm);
+}
+
+static void skl_compute_wm_results(struct drm_device *dev,
+				   struct skl_pipe_wm_parameters *p,
+				   struct skl_pipe_wm *p_wm,
+				   struct skl_wm_values *r,
+				   struct intel_crtc *intel_crtc)
+{
+	int i, level, max_level = ilk_wm_max_level(dev);
+	uint32_t temp;
+	enum pipe pipe = intel_crtc->pipe;
+	uint16_t ddb_blocks;
+
+	for (level = 0; level <= max_level; level++) {
+		for (i = 0; i < intel_num_planes(intel_crtc); i++) {
+			temp = 0;
+			ddb_blocks = skl_ddb_entry_size(&r->ddb.plane[pipe][i]);
+
+			if ((p_wm->wm[level].plane_res_b[i] > ddb_blocks) ||
+				(p_wm->wm[level].plane_res_l[i] > 31))
+				p_wm->wm[level].plane_en[i] = false;
+
+			temp |= p_wm->wm[level].plane_res_l[i] <<
+					PLANE_WM_LINES_SHIFT;
+			temp |= p_wm->wm[level].plane_res_b[i];
+			if (p_wm->wm[level].plane_en[i])
+				temp |= PLANE_WM_EN;
+
+			r->plane[pipe][i][level] = temp;
+			/* Use the LP0 WM value for transition WM for now. */
+			if (level == 0)
+				r->plane_trans[pipe][i] = temp;
+		}
+
+		temp = 0;
+		ddb_blocks = skl_ddb_entry_size(&r->ddb.cursor[pipe]);
+
+		if ((p_wm->wm[level].cursor_res_b > ddb_blocks) ||
+			(p_wm->wm[level].cursor_res_l > 31))
+			p_wm->wm[level].cursor_en = false;
+
+		temp |= p_wm->wm[level].cursor_res_l << PLANE_WM_LINES_SHIFT;
+		temp |= p_wm->wm[level].cursor_res_b;
+
+		if (p_wm->wm[level].cursor_en)
+			temp |= PLANE_WM_EN;
+
+		r->cursor[pipe][level] = temp;
+		/* Use the LP0 WM value for transition WM for now. */
+		if (level == 0)
+			r->cursor_trans[pipe] = temp;
+
+	}
+
+	r->wm_linetime[pipe] = p_wm->linetime;
+}
+
+static void skl_write_wm_values(struct drm_i915_private *dev_priv,
+				struct skl_wm_values *new)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct intel_crtc *crtc;
+	int i, level, max_level = ilk_wm_max_level(dev);
+	enum pipe pipe;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
+		pipe = crtc->pipe;
+		if (new->dirty[pipe]) {
+			I915_WRITE(PIPE_WM_LINETIME(pipe),
+					new->wm_linetime[pipe]);
+
+			for (level = 0; level <= max_level; level++) {
+				for (i = 0; i < intel_num_planes(crtc); i++)
+					I915_WRITE(PLANE_WM(pipe, i, level),
+						new->plane[pipe][i][level]);
+				I915_WRITE(CUR_WM(pipe, level),
+					new->cursor[pipe][level]);
+			}
+			for (i = 0; i < intel_num_planes(crtc); i++)
+				I915_WRITE(PLANE_WM_TRANS(pipe, i),
+						new->plane_trans[pipe][i]);
+			I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
+		}
+	}
+
+	dev_priv->wm.skl_hw = *new;
+}
+
+static bool skl_update_pipe_wm(struct drm_crtc *crtc,
+			       struct skl_pipe_wm_parameters *params,
+			       struct intel_wm_config *config,
+			       struct skl_ddb_allocation *ddb, /* out */
+			       struct skl_pipe_wm *pipe_wm /* out */)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	skl_compute_wm_pipe_parameters(crtc, params);
+	skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
+
+	if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
+		return false;
+
+	intel_crtc->wm.skl_active = *pipe_wm;
+	return true;
+}
+
+static void skl_update_other_pipe_wm(struct drm_device *dev,
+				     struct drm_crtc *crtc,
+				     struct intel_wm_config *config,
+				     struct skl_wm_values *r)
+{
+	struct intel_crtc *intel_crtc;
+	struct intel_crtc *this_crtc = to_intel_crtc(crtc);
+	struct skl_pipe_wm_parameters params;
+	struct skl_pipe_wm pipe_wm;
+
+	/*
+	 * If the WM update hasn't changed the allocation for this_crtc (the
+	 * crtc we are currently computing the new WM values for), other
+	 * enabled crtcs will keep the same allocation and we don't need to
+	 * recompute anything for them.
+	 */
+	if (!skl_ddb_allocation_changed(&r->ddb, this_crtc))
+		return;
+
+	/*
+	 * Otherwise, because of this_crtc being freshly enabled/disabled, the
+	 * other active pipes need new DDB allocation and WM values.
+	 */
+	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
+				base.head) {
+		bool wm_changed;
+
+		if (this_crtc->pipe == intel_crtc->pipe)
+			continue;
+
+		if (!intel_crtc->active)
+			continue;
+
+		wm_changed = skl_update_pipe_wm(&intel_crtc->base,
+						&params, config,
+						&r->ddb, &pipe_wm);
+
+		/*
+		 * If we end up re-computing the other pipe WM values, it's
+		 * because it was really needed, so we expect the WM values to
+		 * be different.
+		 */
+		WARN_ON(!wm_changed);
+
+		skl_compute_wm_results(dev, &params, &pipe_wm, r, intel_crtc);
+		r->dirty[intel_crtc->pipe] = true;
+	}
+}
+
+static void skl_update_wm(struct drm_crtc *crtc)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct skl_pipe_wm_parameters params = {};
+	struct skl_wm_values *results = &dev_priv->wm.skl_results;
+	struct skl_pipe_wm pipe_wm = {};
+	struct intel_wm_config config = {};
+
+	memset(results, 0, sizeof(*results));
+
+	skl_compute_wm_global_parameters(dev, &config);
+
+	if (!skl_update_pipe_wm(crtc, &params, &config,
+				&results->ddb, &pipe_wm))
+		return;
+
+	skl_compute_wm_results(dev, &params, &pipe_wm, results, intel_crtc);
+	results->dirty[intel_crtc->pipe] = true;
+
+	skl_update_other_pipe_wm(dev, crtc, &config, results);
+	skl_write_wm_values(dev_priv, results);
+}
+
+static void
+skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc,
+		     uint32_t sprite_width, uint32_t sprite_height,
+		     int pixel_size, bool enabled, bool scaled)
+{
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+
+	intel_plane->wm.enabled = enabled;
+	intel_plane->wm.scaled = scaled;
+	intel_plane->wm.horiz_pixels = sprite_width;
+	intel_plane->wm.vert_pixels = sprite_height;
+	intel_plane->wm.bytes_per_pixel = pixel_size;
+
+	skl_update_wm(crtc);
+}
+
 static void ilk_update_wm(struct drm_crtc *crtc)
 {
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -7464,6 +7885,8 @@ void intel_init_pm(struct drm_device *dev)
 		skl_setup_wm_latency(dev);
 
 		dev_priv->display.init_clock_gating = gen9_init_clock_gating;
+		dev_priv->display.update_wm = skl_update_wm;
+		dev_priv->display.update_sprite_wm = skl_update_sprite_wm;
 	} else if (HAS_PCH_SPLIT(dev)) {
 		ilk_setup_wm_latency(dev);
 
-- 
1.8.3.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 48/89] drm/i915/skl: Allocate DDB portions for display planes
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (46 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 47/89] drm/i915/skl: SKL Watermark Computation Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-19  9:58   ` Ville Syrjälä
  2014-09-23 11:19   ` [PATCH 48/89 v4] " Damien Lespiau
  2014-09-04 11:27 ` [PATCH 49/89] drm/i915/skl: Program the DDB allocation Damien Lespiau
                   ` (41 subsequent siblings)
  89 siblings, 2 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

v2: Fix the 3rd plane/cursor logic (Pradeep Bhat)
v3: Fix one-by-one error in the DDB allocation code

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 150 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 150 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 4ee90b6..0ddcbad 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2937,6 +2937,155 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
 	return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
 }
 
+/*
+ * On gen9, we need to allocate Display Data Buffer (DDB) portions to the
+ * different active planes.
+ */
+
+#define SKL_DDB_SIZE		896	/* in blocks */
+
+static void
+skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
+				   struct drm_crtc *for_crtc,
+				   struct intel_wm_config *config,
+				   struct skl_pipe_wm_parameters *params,
+				   uint16_t *available,
+				   uint16_t *start,
+				   uint16_t *end)
+{
+	struct drm_crtc *crtc;
+	unsigned int ddb_size;
+	int nth_active_pipe;
+
+	if (!params->active) {
+		*available = 0;
+		*start = 0;
+		*end = 0;
+		return;
+	}
+
+	ddb_size = SKL_DDB_SIZE;
+
+	ddb_size -= 4; /* 4 blocks for bypass path allocation */
+
+	nth_active_pipe = 1;
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		if (!intel_crtc_active(crtc))
+			continue;
+
+		if (crtc == for_crtc)
+			break;
+
+		nth_active_pipe++;
+	}
+
+	*available = ddb_size / config->num_pipes_active;
+	*start = (nth_active_pipe - 1) * ddb_size / config->num_pipes_active;
+	*end = *start + *available - 1;
+}
+
+static unsigned int skl_cursor_allocation(struct intel_wm_config *config)
+{
+	if (config->num_pipes_active == 1)
+		return 32;
+
+	return 8;
+}
+
+static unsigned int
+skl_plane_relative_data_rate(struct intel_plane_wm_parameters *p)
+{
+	return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel;
+}
+
+/*
+ * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching
+ * a 8192x4096@32bpp framebuffer:
+ *   3 * 4096 * 8192  * 4 < 2^32
+ */
+static unsigned int
+skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc,
+				 struct skl_pipe_wm_parameters *params)
+{
+	unsigned int total_data_rate = 0;
+	int plane;
+
+	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
+		struct intel_plane_wm_parameters *p = &params->plane[plane];
+
+		if (!p->enabled)
+			continue;
+
+		total_data_rate += skl_plane_relative_data_rate(p);
+	}
+
+	return total_data_rate;
+}
+
+static void
+skl_allocate_pipe_ddb(struct drm_crtc *crtc,
+		      struct intel_wm_config *config,
+		      struct skl_pipe_wm_parameters *params,
+		      struct skl_ddb_allocation *ddb /* out */)
+{
+	struct drm_device *dev = crtc->dev;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	enum pipe pipe = intel_crtc->pipe;
+	uint16_t available, start, end, cursor_blocks;
+	unsigned int total_data_rate;
+	int plane;
+
+	skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params,
+					   &available, &start, &end);
+	if (available == 0) {
+		const size_t size = ARRAY_SIZE(ddb->plane[pipe]) *
+				    sizeof(struct skl_ddb_entry);
+
+		memset(ddb->plane[pipe], 0, size);
+		memset(&ddb->cursor[pipe], 0, sizeof(struct skl_ddb_entry));
+		return;
+	}
+
+	cursor_blocks = skl_cursor_allocation(config);
+	ddb->cursor[pipe].start = end - cursor_blocks + 1;
+	ddb->cursor[pipe].end = end;
+
+	available -= cursor_blocks;
+	end -= cursor_blocks;
+
+	/*
+	 * Each active plane get a portion of the remaining space, in
+	 * proportion to the amount of data they need to fetch from memory.
+	 *
+	 * FIXME: we don't always allocate every single block here.
+	 */
+	total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params);
+
+	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
+		struct intel_plane_wm_parameters *p = &params->plane[plane];
+		unsigned int data_rate;
+		uint16_t plane_blocks;
+
+		if (!p->enabled)
+			continue;
+
+		data_rate = skl_plane_relative_data_rate(p);
+
+		/*
+		 * promote the expression to 64 bits to avoid overflowing, the
+		 * result is < available as data_rate / total_data_rate < 1
+		 */
+		plane_blocks = div_u64((uint64_t)available * data_rate,
+				       total_data_rate);
+
+		ddb->plane[pipe][plane].start = start;
+		ddb->plane[pipe][plane].end = start + plane_blocks - 1;
+
+		start += plane_blocks;
+	}
+
+}
+
 static uint32_t skl_pipe_pixel_rate(struct drm_device *dev,
 				    struct drm_crtc *crtc)
 {
@@ -3259,6 +3408,7 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
 	skl_compute_wm_pipe_parameters(crtc, params);
+	skl_allocate_pipe_ddb(crtc, config, params, ddb);
 	skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
 
 	if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 49/89] drm/i915/skl: Program the DDB allocation
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (47 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 48/89] drm/i915/skl: Allocate DDB portions for display planes Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-19 10:03   ` Ville Syrjälä
  2014-09-04 11:27 ` [PATCH 50/89] drm/i915/skl: Read the pipe WM HW state Damien Lespiau
                   ` (40 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

v2: Adapt to the planes/cursor split

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h | 16 ++++++++++++++++
 drivers/gpu/drm/i915/intel_pm.c |  9 +++++++++
 2 files changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 9fbce2c..414c2a5 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4602,6 +4602,8 @@ enum punit_power_well {
 #define _PLANE_KEYMSK_2_A			0x70298
 #define _PLANE_KEYMAX_1_A			0x701a0
 #define _PLANE_KEYMAX_2_A			0x702a0
+#define _PLANE_BUF_CFG_1_A			0x7027c
+#define _PLANE_BUF_CFG_2_A			0x7037c
 
 #define _PLANE_CTL_1_B				0x71180
 #define _PLANE_CTL_2_B				0x71280
@@ -4679,6 +4681,20 @@ enum punit_power_well {
 #define PLANE_KEYMAX(pipe, plane)	\
 	_PLANE(plane, _PLANE_KEYMAX_1(pipe), _PLANE_KEYMAX_2(pipe))
 
+#define _PLANE_BUF_CFG_1_B			0x7127c
+#define _PLANE_BUF_CFG_2_B			0x7137c
+#define _PLANE_BUF_CFG_1(pipe)	\
+	_PIPE(pipe, _PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B)
+#define _PLANE_BUF_CFG_2(pipe)	\
+	_PIPE(pipe, _PLANE_BUF_CFG_2_A, _PLANE_BUF_CFG_2_B)
+#define PLANE_BUF_CFG(pipe, plane)	\
+	_PLANE(plane, _PLANE_BUF_CFG_1(pipe), _PLANE_BUF_CFG_2(pipe))
+
+/* SKL new cursor registers */
+#define _CUR_BUF_CFG_A				0x7017c
+#define _CUR_BUF_CFG_B				0x7117c
+#define CUR_BUF_CFG(pipe)	_PIPE(pipe, _CUR_BUF_CFG_A, _CUR_BUF_CFG_B)
+
 /* VBIOS regs */
 #define VGACNTRL		0x71400
 # define VGA_DISP_DISABLE			(1 << 31)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 0ddcbad..756ff16 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3393,6 +3393,15 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
 				I915_WRITE(PLANE_WM_TRANS(pipe, i),
 						new->plane_trans[pipe][i]);
 			I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
+
+			for (i = 0; i < intel_num_planes(crtc); i++)
+				I915_WRITE(PLANE_BUF_CFG(pipe, i),
+					   new->ddb.plane[pipe][i].end << 16 |
+					   new->ddb.plane[pipe][i].start);
+
+			I915_WRITE(CUR_BUF_CFG(pipe),
+				   new->ddb.cursor[pipe].end << 16 |
+				   new->ddb.cursor[pipe].start);
 		}
 	}
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 50/89] drm/i915/skl: Read the pipe WM HW state
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (48 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 49/89] drm/i915/skl: Program the DDB allocation Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-10-29 19:02   ` Ville Syrjälä
  2014-09-04 11:27 ` [PATCH 51/89] drm/i915/gen9: Add 2us read latency to WM level Damien Lespiau
                   ` (39 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx; +Cc: Pradeep Bhat

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch provides the implementation for reading the pipe wm HW
state.

v2: Incorporated Damien's review comments and also made modifications
    to incorporate the plane/cursor split.

v3: No need to ident a line that was fitting 80 chars
    Return early instead of indenting the remaining of a function
    (Damien)

v4: Rebase on top of nightly (minor conflect in intel_drv.h)

Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |   4 +-
 drivers/gpu/drm/i915/intel_drv.h     |   1 +
 drivers/gpu/drm/i915/intel_pm.c      | 104 +++++++++++++++++++++++++++++++++++
 3 files changed, 108 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3d9f447..69e023a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13375,7 +13375,9 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
 		pll->on = false;
 	}
 
-	if (HAS_PCH_SPLIT(dev))
+	if (IS_GEN9(dev))
+		skl_wm_get_hw_state(dev);
+	else if (HAS_PCH_SPLIT(dev))
 		ilk_wm_get_hw_state(dev);
 
 	if (force_restore) {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 268087f..559b747 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1102,6 +1102,7 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv);
 void intel_init_runtime_pm(struct drm_i915_private *dev_priv);
 void intel_fini_runtime_pm(struct drm_i915_private *dev_priv);
 void ilk_wm_get_hw_state(struct drm_device *dev);
+void skl_wm_get_hw_state(struct drm_device *dev);
 
 
 /* intel_sdvo.c */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 756ff16..1e56067 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3591,6 +3591,110 @@ ilk_update_sprite_wm(struct drm_plane *plane,
 	ilk_update_wm(crtc);
 }
 
+static void skl_pipe_wm_active_state(uint32_t val,
+				     struct skl_pipe_wm *active,
+				     bool is_transwm,
+				     bool is_cursor,
+				     int i,
+				     int level)
+{
+	bool is_enabled = (val & PLANE_WM_EN) != 0;
+
+	if (!is_transwm) {
+		if (!is_cursor) {
+			active->wm[level].plane_en[i] = is_enabled;
+			active->wm[level].plane_res_b[i] =
+					val & PLANE_WM_BLOCKS_MASK;
+			active->wm[level].plane_res_l[i] =
+					(val >> PLANE_WM_LINES_SHIFT) &
+						PLANE_WM_LINES_MASK;
+		} else {
+			active->wm[level].cursor_en = is_enabled;
+			active->wm[level].cursor_res_b =
+					val & PLANE_WM_BLOCKS_MASK;
+			active->wm[level].cursor_res_l =
+					(val >> PLANE_WM_LINES_SHIFT) &
+						PLANE_WM_LINES_MASK;
+		}
+	} else {
+		if (!is_cursor) {
+			active->trans_wm.plane_en[i] = is_enabled;
+			active->trans_wm.plane_res_b[i] =
+					val & PLANE_WM_BLOCKS_MASK;
+			active->trans_wm.plane_res_l[i] =
+					(val >> PLANE_WM_LINES_SHIFT) &
+						PLANE_WM_LINES_MASK;
+		} else {
+			active->trans_wm.cursor_en = is_enabled;
+			active->trans_wm.cursor_res_b =
+					val & PLANE_WM_BLOCKS_MASK;
+			active->trans_wm.cursor_res_l =
+					(val >> PLANE_WM_LINES_SHIFT) &
+						PLANE_WM_LINES_MASK;
+		}
+	}
+}
+
+static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct skl_pipe_wm *active = &intel_crtc->wm.skl_active;
+	enum pipe pipe = intel_crtc->pipe;
+	int level, i, max_level;
+	uint32_t temp;
+
+	max_level = ilk_wm_max_level(dev);
+
+	hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe));
+
+	for (level = 0; level <= max_level; level++) {
+		for (i = 0; i < intel_num_planes(intel_crtc); i++)
+			hw->plane[pipe][i][level] =
+					I915_READ(PLANE_WM(pipe, i, level));
+		hw->cursor[pipe][level] = I915_READ(CUR_WM(pipe, level));
+	}
+
+	for (i = 0; i < intel_num_planes(intel_crtc); i++)
+		hw->plane_trans[pipe][i] = I915_READ(PLANE_WM_TRANS(pipe, i));
+	hw->cursor_trans[pipe] = I915_READ(CUR_WM_TRANS(pipe));
+
+	if (!intel_crtc_active(crtc))
+		return;
+
+	hw->dirty[pipe] = true;
+
+	active->linetime = hw->wm_linetime[pipe];
+
+	for (level = 0; level <= max_level; level++) {
+		for (i = 0; i < intel_num_planes(intel_crtc); i++) {
+			temp = hw->plane[pipe][i][level];
+			skl_pipe_wm_active_state(temp, active, false,
+						false, i, level);
+		}
+		temp = hw->cursor[pipe][level];
+		skl_pipe_wm_active_state(temp, active, false, true, i, level);
+	}
+
+	for (i = 0; i < intel_num_planes(intel_crtc); i++) {
+		temp = hw->plane_trans[pipe][i];
+		skl_pipe_wm_active_state(temp, active, true, false, i, 0);
+	}
+
+	temp = hw->cursor_trans[pipe];
+	skl_pipe_wm_active_state(temp, active, true, true, i, 0);
+}
+
+void skl_wm_get_hw_state(struct drm_device *dev)
+{
+	struct drm_crtc *crtc;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+		skl_pipe_wm_get_hw_state(crtc);
+}
+
 static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 51/89] drm/i915/gen9: Add 2us read latency to WM level
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (49 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 50/89] drm/i915/skl: Read the pipe WM HW state Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-19 10:04   ` Ville Syrjälä
  2014-09-04 11:27 ` [PATCH 52/89] drm/i915/gen9: Disable WM if corresponding latency is 0 Damien Lespiau
                   ` (38 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Vandana Kannan <vandana.kannan@intel.com>

According to the updated Bspec, The mailbox response data is not currently
accounting for memory read latency. Add 2 microseconds to the result for
each level.
This patch adds 2us to latency of level 0 for all cases and
for all other levels (1-7) only if latency[level] > 0.

v2: Slightly rework the patch and add a big comment (Damien)

Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v1)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Reviewed-by: M, Satheeshakrishna <satheeshakrishna.m@intel.com> (v1)
Cc: Lespiau, Damien <damien.lespiau@intel.com>
Cc: M, Satheeshakrishna <satheeshakrishna.m@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 1e56067..16ad008 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2254,6 +2254,7 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
 	if (IS_GEN9(dev)) {
 		uint32_t val;
 		int ret;
+		int level, max_level = ilk_wm_max_level(dev);
 
 		/* read the first set of memory latencies[0:3] */
 		val = 0; /* data0 to be programmed to 0 for first set */
@@ -2267,6 +2268,7 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
 			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
 			return;
 		}
+
 		wm[0] = val & GEN9_MEM_LAT_LEVEL_MASK;
 		wm[1] = (val >> GEN9_MEM_LAT_LEVEL_1_5_SHIFT) &
 				GEN9_MEM_LAT_LEVEL_MASK;
@@ -2293,6 +2295,22 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
 				GEN9_MEM_LAT_LEVEL_MASK;
 		wm[7] = (val >> GEN9_MEM_LAT_LEVEL_3_7_SHIFT) &
 				GEN9_MEM_LAT_LEVEL_MASK;
+
+		/*
+		 * punit doesn't take into account the read latency so we need
+		 * to add 2us to the various latency levels we retrieve from
+		 * the punit.
+		 *   - W0 is a bit special in that it's the only level that
+		 *   can't be disabled if we want to have display working, so
+		 *   we always add 2us there.
+		 *   - For levels >=1, punit returns 0us latency when they are
+		 *   disabled, so we respect that and don't add 2us then
+		 */
+		wm[0] += 2;
+		for (level = 1; level <= max_level; level++)
+			if (wm[level] != 0)
+				wm[level] += 2;
+
 	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
 		uint64_t sskpd = I915_READ64(MCH_SSKPD);
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 52/89] drm/i915/gen9: Disable WM if corresponding latency is 0
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (50 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 51/89] drm/i915/gen9: Add 2us read latency to WM level Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-19 10:05   ` Ville Syrjälä
  2014-09-04 11:27 ` [PATCH 53/89] drm/i915/skl: Gen9 Forcewake Damien Lespiau
                   ` (37 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Vandana Kannan <vandana.kannan@intel.com>

According to updated BSpec, If level 1 or any higher level has a value of 0x00,
that level and any higher levels are unused and the associated watermark
registers must not be enabled.

This patch checks for latency 0 for level >=1 and does not enable WM
corresponding to level m | m>=n, if level n (n != 0) has a 0us latency.

v2: Satheesh's review comments
	- zero-out latency values (for all higher levels if latency of given
	level is zero ) in read_wm_latency() function itself

v3: removed redundant check as per Satheesh's observation.
v4: rebase on top before merging (Damien)

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
Reviewed-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v3)
Cc: Satheeshakrishna M <satheeshakrishna.m@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 16ad008..fdf297f 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2253,7 +2253,7 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
 
 	if (IS_GEN9(dev)) {
 		uint32_t val;
-		int ret;
+		int ret, i;
 		int level, max_level = ilk_wm_max_level(dev);
 
 		/* read the first set of memory latencies[0:3] */
@@ -2305,12 +2305,22 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
 		 *   we always add 2us there.
 		 *   - For levels >=1, punit returns 0us latency when they are
 		 *   disabled, so we respect that and don't add 2us then
+		 *
+		 * Additionally, if a level n (n > 1) has a 0us latency, all
+		 * levels m (m >= n) need to be disabled. We make sure to
+		 * sanitize the values out of the punit to satisfy this
+		 * requirement.
 		 */
 		wm[0] += 2;
 		for (level = 1; level <= max_level; level++)
 			if (wm[level] != 0)
 				wm[level] += 2;
+			else {
+				for (i = level + 1; i <= max_level; i++)
+					wm[i] = 0;
 
+				break;
+			}
 	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
 		uint64_t sskpd = I915_READ64(MCH_SSKPD);
 
@@ -3253,7 +3263,7 @@ static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
 	uint32_t method1, method2, plane_bytes_per_line;
 	uint32_t result_bytes;
 
-	if (!p->active || !p_params->enabled) {
+	if (mem_value == 0 || !p->active || !p_params->enabled) {
 		*res_blocks = PLANE_WM_BLOCKS_DEFAULT;
 		*res_lines = PLANE_WM_LINES_DEFAULT;
 		return false;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 53/89] drm/i915/skl: Gen9 Forcewake
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (51 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 52/89] drm/i915/gen9: Disable WM if corresponding latency is 0 Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-10 13:44   ` Mika Kuoppala
  2014-09-04 11:27 ` [PATCH 54/89] drm/i915/skl: Enable Gen9 RC6 Damien Lespiau
                   ` (36 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Zhe Wang <zhe1.wang@intel.com>

Implement common forcewake functions shared by Gen9 features.

Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h     |   5 +-
 drivers/gpu/drm/i915/i915_reg.h     |   6 ++
 drivers/gpu/drm/i915/intel_uncore.c | 175 +++++++++++++++++++++++++++++++++++-
 3 files changed, 184 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9b0e398..84defa4 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -535,6 +535,7 @@ struct intel_uncore {
 
 	unsigned fw_rendercount;
 	unsigned fw_mediacount;
+	unsigned fw_blittercount;
 
 	struct timer_list force_wake_timer;
 };
@@ -2950,7 +2951,9 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val);
 
 #define FORCEWAKE_RENDER	(1 << 0)
 #define FORCEWAKE_MEDIA		(1 << 1)
-#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | FORCEWAKE_MEDIA)
+#define FORCEWAKE_BLITTER	(1 << 2)
+#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | FORCEWAKE_MEDIA | \
+					FORCEWAKE_BLITTER)
 
 
 #define I915_READ8(reg)		dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 414c2a5..417075d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5738,6 +5738,12 @@ enum punit_power_well {
 #define   VLV_GTLC_PW_MEDIA_STATUS_MASK		(1 << 5)
 #define   VLV_GTLC_PW_RENDER_STATUS_MASK	(1 << 7)
 #define  FORCEWAKE_MT				0xa188 /* multi-threaded */
+#define  FORCEWAKE_MEDIA_GEN9			0xa270
+#define  FORCEWAKE_RENDER_GEN9			0xa278
+#define  FORCEWAKE_BLITTER_GEN9			0xa188
+#define  FORCEWAKE_ACK_MEDIA_GEN9		0x0D88
+#define  FORCEWAKE_ACK_RENDER_GEN9		0x0D84
+#define  FORCEWAKE_ACK_BLITTER_GEN9		0x130044
 #define   FORCEWAKE_KERNEL			0x1
 #define   FORCEWAKE_USER			0x2
 #define  FORCEWAKE_MT_ACK			0x130040
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 3b27fb0..7b7fc9e 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -299,6 +299,154 @@ static void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
+static void __gen9_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
+{
+	__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
+			_MASKED_BIT_DISABLE(0xffff));
+
+	__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
+			_MASKED_BIT_DISABLE(0xffff));
+
+	__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
+			_MASKED_BIT_DISABLE(0xffff));
+}
+
+static void __gen9_force_wake_get(struct drm_i915_private *dev_priv,
+						int fw_engine)
+{
+	/* Check for Render Engine */
+	if (FORCEWAKE_RENDER & fw_engine) {
+		if (wait_for_atomic((__raw_i915_read32(dev_priv,
+						FORCEWAKE_ACK_RENDER_GEN9) &
+						FORCEWAKE_KERNEL) == 0,
+					FORCEWAKE_ACK_TIMEOUT_MS))
+			DRM_ERROR("Timed out: Render forcewake old ack to clear.\n");
+
+		__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
+				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
+
+		if (wait_for_atomic((__raw_i915_read32(dev_priv,
+						FORCEWAKE_ACK_RENDER_GEN9) &
+						FORCEWAKE_KERNEL),
+					FORCEWAKE_ACK_TIMEOUT_MS))
+			DRM_ERROR("Timed out: waiting for Render to ack.\n");
+	}
+
+	/* Check for Media Engine */
+	if (FORCEWAKE_MEDIA & fw_engine) {
+		if (wait_for_atomic((__raw_i915_read32(dev_priv,
+						FORCEWAKE_ACK_MEDIA_GEN9) &
+						FORCEWAKE_KERNEL) == 0,
+					FORCEWAKE_ACK_TIMEOUT_MS))
+			DRM_ERROR("Timed out: Media forcewake old ack to clear.\n");
+
+		__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
+				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
+
+		if (wait_for_atomic((__raw_i915_read32(dev_priv,
+						FORCEWAKE_ACK_MEDIA_GEN9) &
+						FORCEWAKE_KERNEL),
+					FORCEWAKE_ACK_TIMEOUT_MS))
+			DRM_ERROR("Timed out: waiting for Media to ack.\n");
+	}
+
+	/* Check for Blitter Engine */
+	if (FORCEWAKE_BLITTER & fw_engine) {
+		if (wait_for_atomic((__raw_i915_read32(dev_priv,
+						FORCEWAKE_ACK_BLITTER_GEN9) &
+						FORCEWAKE_KERNEL) == 0,
+					FORCEWAKE_ACK_TIMEOUT_MS))
+			DRM_ERROR("Timed out: Blitter forcewake old ack to clear.\n");
+
+		__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
+				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
+
+		if (wait_for_atomic((__raw_i915_read32(dev_priv,
+						FORCEWAKE_ACK_BLITTER_GEN9) &
+						FORCEWAKE_KERNEL),
+					FORCEWAKE_ACK_TIMEOUT_MS))
+			DRM_ERROR("Timed out: waiting for Blitter to ack.\n");
+	}
+}
+
+static void __gen9_force_wake_put(struct drm_i915_private *dev_priv,
+					int fw_engine)
+{
+	/* Check for Render Engine */
+	if (FORCEWAKE_RENDER & fw_engine)
+		__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
+				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
+
+	/* Check for Media Engine */
+	if (FORCEWAKE_MEDIA & fw_engine)
+		__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
+				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
+
+	/* Check for Blitter Engine */
+	if (FORCEWAKE_BLITTER & fw_engine)
+		__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
+				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
+}
+
+void gen9_force_wake_get(struct drm_i915_private *dev_priv,
+						int fw_engine)
+{
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+
+	if (FORCEWAKE_RENDER & fw_engine) {
+		if (dev_priv->uncore.fw_rendercount++ == 0)
+			dev_priv->uncore.funcs.force_wake_get(dev_priv,
+							FORCEWAKE_RENDER);
+	}
+
+	if (FORCEWAKE_MEDIA & fw_engine) {
+		if (dev_priv->uncore.fw_mediacount++ == 0)
+			dev_priv->uncore.funcs.force_wake_get(dev_priv,
+							FORCEWAKE_MEDIA);
+	}
+
+	if (FORCEWAKE_BLITTER & fw_engine) {
+		if (dev_priv->uncore.fw_blittercount++ == 0)
+			dev_priv->uncore.funcs.force_wake_get(dev_priv,
+							FORCEWAKE_BLITTER);
+	}
+
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+}
+
+void gen9_force_wake_put(struct drm_i915_private *dev_priv,
+						int fw_engine)
+{
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+
+	if (FORCEWAKE_RENDER & fw_engine) {
+		WARN_ON(dev_priv->uncore.fw_rendercount == 0);
+		if (--dev_priv->uncore.fw_rendercount == 0)
+			dev_priv->uncore.funcs.force_wake_put(dev_priv,
+							FORCEWAKE_RENDER);
+	}
+
+	if (FORCEWAKE_MEDIA & fw_engine) {
+		WARN_ON(dev_priv->uncore.fw_mediacount == 0);
+		if (--dev_priv->uncore.fw_mediacount == 0)
+			dev_priv->uncore.funcs.force_wake_put(dev_priv,
+							FORCEWAKE_MEDIA);
+	}
+
+	if (FORCEWAKE_BLITTER & fw_engine) {
+		WARN_ON(dev_priv->uncore.fw_blittercount == 0);
+		if (--dev_priv->uncore.fw_blittercount == 0)
+			dev_priv->uncore.funcs.force_wake_put(dev_priv,
+							FORCEWAKE_BLITTER);
+	}
+
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+}
+
 static void gen6_force_wake_timer(unsigned long arg)
 {
 	struct drm_i915_private *dev_priv = (void *)arg;
@@ -337,6 +485,9 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
 	if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev))
 		__gen7_gt_force_wake_mt_reset(dev_priv);
 
+	if (IS_GEN9(dev))
+		__gen9_gt_force_wake_mt_reset(dev_priv);
+
 	if (restore) { /* If reset with a user forcewake, try to restore */
 		unsigned fw = 0;
 
@@ -346,6 +497,15 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
 
 			if (dev_priv->uncore.fw_mediacount)
 				fw |= FORCEWAKE_MEDIA;
+		} else if (IS_GEN9(dev)) {
+			if (dev_priv->uncore.fw_rendercount)
+				fw |= FORCEWAKE_RENDER;
+
+			if (dev_priv->uncore.fw_mediacount)
+				fw |= FORCEWAKE_MEDIA;
+
+			if (dev_priv->uncore.fw_blittercount)
+				fw |= FORCEWAKE_BLITTER;
 		} else {
 			if (dev_priv->uncore.forcewake_count)
 				fw = FORCEWAKE_ALL;
@@ -410,6 +570,10 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
 
 	intel_runtime_pm_get(dev_priv);
 
+	/* Redirect to Gen9 specific routine */
+	if (IS_GEN9(dev_priv->dev))
+		return gen9_force_wake_get(dev_priv, fw_engine);
+
 	/* Redirect to VLV specific routine */
 	if (IS_VALLEYVIEW(dev_priv->dev))
 		return vlv_force_wake_get(dev_priv, fw_engine);
@@ -431,6 +595,12 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
 	if (!dev_priv->uncore.funcs.force_wake_put)
 		return;
 
+	/* Redirect to Gen9 specific routine */
+	if (IS_GEN9(dev_priv->dev)) {
+		gen9_force_wake_put(dev_priv, fw_engine);
+		goto out;
+	}
+
 	/* Redirect to VLV specific routine */
 	if (IS_VALLEYVIEW(dev_priv->dev)) {
 		vlv_force_wake_put(dev_priv, fw_engine);
@@ -835,7 +1005,10 @@ void intel_uncore_init(struct drm_device *dev)
 
 	intel_uncore_early_sanitize(dev, false);
 
-	if (IS_VALLEYVIEW(dev)) {
+	if (IS_GEN9(dev)) {
+		dev_priv->uncore.funcs.force_wake_get = __gen9_force_wake_get;
+		dev_priv->uncore.funcs.force_wake_put = __gen9_force_wake_put;
+	} else if (IS_VALLEYVIEW(dev)) {
 		dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get;
 		dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put;
 	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 54/89] drm/i915/skl: Enable Gen9 RC6
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (52 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 53/89] drm/i915/skl: Gen9 Forcewake Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-22 13:15   ` Mika Kuoppala
  2014-09-04 11:27 ` [PATCH 55/89] drm/i915/skl: Gen9 multi-engine forcewake Damien Lespiau
                   ` (35 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Zhe Wang <zhe1.wang@intel.com>

Configure and enable RC6 for Gen9.

v2: Rebase on top of BDW rc6 support (Damien)

Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 52 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 51 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index fdf297f..74a8519 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4332,6 +4332,13 @@ static void gen8_disable_rps_interrupts(struct drm_device *dev)
 	}
 }
 
+static void gen9_disable_rps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(GEN6_RC_CONTROL, 0);
+}
+
 static void gen6_disable_rps_interrupts(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -4579,6 +4586,45 @@ void bdw_software_turbo(struct drm_device *dev)
 			&current_time, &current_c0);
 }
 
+static void gen9_enable_rps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *ring;
+	uint32_t rc6_mask = 0;
+	int unused;
+
+	/* 1a: Software RC state - RC0 */
+	I915_WRITE(GEN6_RC_STATE, 0);
+
+	/* 1b: Get forcewake during program sequence. Although the driver
+	 * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
+	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+
+	/* 2a: Disable RC states. */
+	I915_WRITE(GEN6_RC_CONTROL, 0);
+
+	/* 2b: Program RC6 thresholds.*/
+	I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
+	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
+	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
+	for_each_ring(ring, dev_priv, unused)
+		I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
+	I915_WRITE(GEN6_RC_SLEEP, 0);
+	I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */
+
+	/* 3a: Enable RC6 */
+	if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
+		rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
+	DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
+			"on" : "off");
+	I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
+				   GEN6_RC_CTL_EI_MODE(1) |
+				   rc6_mask);
+
+	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+
+}
+
 static void gen8_enable_rps(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -6158,7 +6204,9 @@ void intel_disable_gt_powersave(struct drm_device *dev)
 		intel_suspend_gt_powersave(dev);
 
 		mutex_lock(&dev_priv->rps.hw_lock);
-		if (IS_CHERRYVIEW(dev))
+		if (INTEL_INFO(dev)->gen >= 9)
+			gen9_disable_rps(dev);
+		else if (IS_CHERRYVIEW(dev))
 			cherryview_disable_rps(dev);
 		else if (IS_VALLEYVIEW(dev))
 			valleyview_disable_rps(dev);
@@ -6184,6 +6232,8 @@ static void intel_gen6_powersave_work(struct work_struct *work)
 		cherryview_enable_rps(dev);
 	} else if (IS_VALLEYVIEW(dev)) {
 		valleyview_enable_rps(dev);
+	} else if (INTEL_INFO(dev)->gen >= 9) {
+		gen9_enable_rps(dev);
 	} else if (IS_BROADWELL(dev)) {
 		gen8_enable_rps(dev);
 		__gen6_update_ring_freq(dev);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 55/89] drm/i915/skl: Gen9 multi-engine forcewake
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (53 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 54/89] drm/i915/skl: Enable Gen9 RC6 Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-22 15:11   ` Mika Kuoppala
  2014-09-04 11:27 ` [PATCH 56/89] drm/i915: Gen9 shadowed registers Damien Lespiau
                   ` (34 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Zhe Wang <zhe1.wang@intel.com>

Enable multi-engine forcewake for Gen9.

v2: Rebase on top of nightly
    Move the register range definitions to intel_uncore.c
    Whitespace fixes
    (Damien)

Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_uncore.c | 120 ++++++++++++++++++++++++++++++++++++
 1 file changed, 120 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 7b7fc9e..f289f4f 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -674,6 +674,34 @@ void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
 	 REG_RANGE((reg), 0x14000, 0x14400) || \
 	 REG_RANGE((reg), 0x22000, 0x24000))
 
+#define FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) \
+	((reg) >= 0xC00 && (reg) < 0x2000)
+
+#define FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) \
+	(((reg) >= 0x2000 && (reg) < 0x4000) || \
+	((reg) >= 0x5200 && (reg) < 0x8000) || \
+	((reg) >= 0x8300 && (reg) < 0x8500) || \
+	((reg) >= 0x8C00 && (reg) < 0x8D00) || \
+	((reg) >= 0xB000 && (reg) < 0xB480) || \
+	((reg) >= 0xE000 && (reg) < 0xE800))
+
+#define FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) \
+	(((reg) >= 0x8800 && (reg) < 0x8A00) || \
+	((reg) >= 0xD000 && (reg) < 0xD800) || \
+	((reg) >= 0x12000 && (reg) < 0x14000) || \
+	((reg) >= 0x1A000 && (reg) < 0x1EA00) || \
+	((reg) >= 0x30000 && (reg) < 0x40000))
+
+#define FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg) \
+	((reg) >= 0x9400 && (reg) < 0x9800)
+
+#define FORCEWAKE_GEN9_BLITTER_RANGE_OFFSET(reg) \
+	((reg) < 0x40000 &&\
+	!FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) && \
+	!FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) && \
+	!FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) && \
+	!FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg))
+
 static void
 ilk_dummy_write(struct drm_i915_private *dev_priv)
 {
@@ -804,6 +832,43 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
 	REG_READ_FOOTER; \
 }
 
+#define __gen9_read(x) \
+static u##x \
+gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
+	REG_READ_HEADER(x); \
+	if (!NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
+			FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg)) { \
+		val = __raw_i915_read##x(dev_priv, reg); \
+	} else { \
+		unsigned fwengine = 0; \
+		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
+			if (dev_priv->uncore.fw_rendercount == 0) \
+				fwengine = FORCEWAKE_RENDER; \
+		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
+			if (dev_priv->uncore.fw_mediacount == 0) \
+				fwengine = FORCEWAKE_MEDIA; \
+		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
+			if (dev_priv->uncore.fw_rendercount == 0) \
+				fwengine |= FORCEWAKE_RENDER; \
+			if (dev_priv->uncore.fw_mediacount == 0) \
+				fwengine |= FORCEWAKE_MEDIA; \
+		} else { \
+			if (dev_priv->uncore.fw_blittercount == 0) \
+				fwengine = FORCEWAKE_BLITTER; \
+		} \
+		if (fwengine) \
+			dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
+		val = __raw_i915_read##x(dev_priv, reg); \
+		if (fwengine) \
+			dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
+	} \
+	REG_READ_FOOTER; \
+}
+
+__gen9_read(8)
+__gen9_read(16)
+__gen9_read(32)
+__gen9_read(64)
 __chv_read(8)
 __chv_read(16)
 __chv_read(32)
@@ -825,6 +890,7 @@ __gen4_read(16)
 __gen4_read(32)
 __gen4_read(64)
 
+#undef __gen9_read
 #undef __chv_read
 #undef __vlv_read
 #undef __gen6_read
@@ -962,6 +1028,46 @@ chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
 	REG_WRITE_FOOTER; \
 }
 
+#define __gen9_write(x) \
+static void \
+gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
+		bool trace) { \
+	REG_WRITE_HEADER; \
+	if (!NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
+			FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg)) { \
+		__raw_i915_write##x(dev_priv, reg, val); \
+	} else { \
+		unsigned fwengine = 0; \
+		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
+			if (dev_priv->uncore.fw_rendercount == 0) \
+				fwengine = FORCEWAKE_RENDER; \
+		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
+			if (dev_priv->uncore.fw_mediacount == 0) \
+				fwengine = FORCEWAKE_MEDIA; \
+		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
+			if (dev_priv->uncore.fw_rendercount == 0) \
+				fwengine |= FORCEWAKE_RENDER; \
+			if (dev_priv->uncore.fw_mediacount == 0) \
+				fwengine |= FORCEWAKE_MEDIA; \
+		} else { \
+			if (dev_priv->uncore.fw_blittercount == 0) \
+				fwengine = FORCEWAKE_BLITTER; \
+		} \
+		if (fwengine) \
+			dev_priv->uncore.funcs.force_wake_get(dev_priv, \
+					fwengine); \
+		__raw_i915_write##x(dev_priv, reg, val); \
+		if (fwengine) \
+			dev_priv->uncore.funcs.force_wake_put(dev_priv, \
+					fwengine); \
+	} \
+	REG_WRITE_FOOTER; \
+}
+
+__gen9_write(8)
+__gen9_write(16)
+__gen9_write(32)
+__gen9_write(64)
 __chv_write(8)
 __chv_write(16)
 __chv_write(32)
@@ -987,6 +1093,7 @@ __gen4_write(16)
 __gen4_write(32)
 __gen4_write(64)
 
+#undef __gen9_write
 #undef __chv_write
 #undef __gen8_write
 #undef __hsw_write
@@ -1054,6 +1161,19 @@ void intel_uncore_init(struct drm_device *dev)
 
 	switch (INTEL_INFO(dev)->gen) {
 	default:
+		WARN_ON(1);
+		return;
+	case 9:
+		dev_priv->uncore.funcs.mmio_writeb  = gen9_write8;
+		dev_priv->uncore.funcs.mmio_writew  = gen9_write16;
+		dev_priv->uncore.funcs.mmio_writel  = gen9_write32;
+		dev_priv->uncore.funcs.mmio_writeq  = gen9_write64;
+		dev_priv->uncore.funcs.mmio_readb  = gen9_read8;
+		dev_priv->uncore.funcs.mmio_readw  = gen9_read16;
+		dev_priv->uncore.funcs.mmio_readl  = gen9_read32;
+		dev_priv->uncore.funcs.mmio_readq  = gen9_read64;
+		break;
+	case 8:
 		if (IS_CHERRYVIEW(dev)) {
 			dev_priv->uncore.funcs.mmio_writeb  = chv_write8;
 			dev_priv->uncore.funcs.mmio_writew  = chv_write16;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 56/89] drm/i915: Gen9 shadowed registers
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (54 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 55/89] drm/i915/skl: Gen9 multi-engine forcewake Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-24 13:36   ` Mika Kuoppala
  2014-09-04 11:27 ` [PATCH 57/89] drm/i915: Rewrite ABS_DIFF() in a safer manner Damien Lespiau
                   ` (33 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Zhe Wang <zhe1.wang@intel.com>

For MMIO registers which are shadowed, force wake is not needed to
write to these registers.

v2: Rebase on top of nightly (Damien)

Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_uncore.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index f289f4f..ce1214b 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -1028,13 +1028,37 @@ chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
 	REG_WRITE_FOOTER; \
 }
 
+static const u32 gen9_shadowed_regs[] = {
+	FORCEWAKE_MEDIA_GEN9,
+	FORCEWAKE_RENDER_GEN9,
+	FORCEWAKE_BLITTER_GEN9,
+	GEN6_RPNSWREQ,
+	GEN6_RC_VIDEO_FREQ,
+	RING_TAIL(RENDER_RING_BASE),
+	RING_TAIL(GEN6_BSD_RING_BASE),
+	RING_TAIL(VEBOX_RING_BASE),
+	RING_TAIL(BLT_RING_BASE),
+	/* TODO: Other registers are not yet used */
+};
+
+static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(gen9_shadowed_regs); i++)
+		if (reg == gen9_shadowed_regs[i])
+			return true;
+
+	return false;
+}
+
 #define __gen9_write(x) \
 static void \
 gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
 		bool trace) { \
 	REG_WRITE_HEADER; \
 	if (!NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
-			FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg)) { \
+			FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) || \
+			is_gen9_shadowed(dev_priv, reg)) { \
 		__raw_i915_write##x(dev_priv, reg, val); \
 	} else { \
 		unsigned fwengine = 0; \
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 57/89] drm/i915: Rewrite ABS_DIFF() in a safer manner
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (55 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 56/89] drm/i915: Gen9 shadowed registers Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-04 12:11   ` Jani Nikula
  2014-09-04 11:27 ` [PATCH 58/89] drm/i915/skl: Register definitions for SKL Clocks Damien Lespiau
                   ` (32 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

The new version of the macro does a few things better:
  - protect the arguments,
  - only evaluate the arguments once,
  - check that the arguments are of the same type,

Change LC_FREQ_2K to be a unsigned 64bit constant and removed the '()'
from the caller as a result.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 64eda53..ba1103f 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -460,7 +460,7 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
 }
 
 #define LC_FREQ 2700
-#define LC_FREQ_2K (LC_FREQ * 2000)
+#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
 
 #define P_MIN 2
 #define P_MAX 64
@@ -472,7 +472,11 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
 #define VCO_MIN 2400
 #define VCO_MAX 4800
 
-#define ABS_DIFF(a, b) ((a > b) ? (a - b) : (b - a))
+#define abs_diff(a, b) ({			\
+	typeof(a) __a = (a);			\
+	typeof(b) __b = (b);			\
+	(void) (&__a == &__b);			\
+	__a > __b ? (__a - __b) : (__b - __a); })
 
 struct wrpll_rnp {
 	unsigned p, n2, r2;
@@ -582,9 +586,9 @@ static void wrpll_update_rnp(uint64_t freq2k, unsigned budget,
 	 */
 	a = freq2k * budget * p * r2;
 	b = freq2k * budget * best->p * best->r2;
-	diff = ABS_DIFF((freq2k * p * r2), (LC_FREQ_2K * n2));
-	diff_best = ABS_DIFF((freq2k * best->p * best->r2),
-			     (LC_FREQ_2K * best->n2));
+	diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
+	diff_best = abs_diff(freq2k * best->p * best->r2,
+			     LC_FREQ_2K * best->n2);
 	c = 1000000 * diff;
 	d = 1000000 * diff_best;
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 58/89] drm/i915/skl: Register definitions for SKL Clocks
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (56 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 57/89] drm/i915: Rewrite ABS_DIFF() in a safer manner Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-22 18:17   ` Paulo Zanoni
  2014-09-04 11:27 ` [PATCH 59/89] drm/i915/skl: Structure/enum definitions for SKL clocks Damien Lespiau
                   ` (31 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

This patch defines the necessary SKL registers for implementing the
new clocking mechanism.

v2: Addressed review comments by Damien
	- Added code comment
	- Introduced enum for WRPLL values

v3: Rebase on top of nightly (minor conflict in i915_reg.h)

v4: Use 0x, not 0X (Ville)

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v2)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v3,v4)
---
 drivers/gpu/drm/i915/i915_reg.h | 84 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 417075d..2364ece 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6336,6 +6336,90 @@ enum punit_power_well {
 #define  LCPLL_CD_SOURCE_FCLK		(1<<21)
 #define  LCPLL_CD_SOURCE_FCLK_DONE	(1<<19)
 
+/*
+ * SKL Clocks
+ */
+
+/* CDCLK_CTL */
+#define CDCLK_CTL			0x46000
+#define  CDCLK_FREQ_SEL_MASK		(3<<26)
+#define  CDCLK_FREQ_450_432		(0<<26)
+#define  CDCLK_FREQ_540			(1<<26)
+#define  CDCLK_FREQ_337_308		(2<<26)
+#define  CDCLK_FREQ_675_617		(3<<26)
+#define	 CDCLK_FREQ_DECIMAL_MASK	(0x7ff)
+
+/* LCPLL_CTL */
+#define LCPLL1_CTL		0x46010
+#define LCPLL2_CTL		0x46014
+#define  LCPLL_PLL_ENABLE	(1<<31)
+
+/* DPLL control1 */
+#define DPLL_CTRL1		0x6C058
+#define  DPLL_CTRL1_HDMI_MODE(id)		(1<<((id)*6+5))
+#define  DPLL_CTRL1_SSC(id)			(1<<((id)*6+4))
+#define  DPLL_CRTL1_LINK_RATE_MASK(id)		(7<<((id)*6+1))
+#define  DPLL_CRTL1_LINK_RATE(linkrate, id)	((linkrate)<<((id)*6+1))
+#define  DPLL_CTRL1_OVERRIDE(id)		(1<<((id)*6))
+#define  DPLL_CRTL1_LINK_RATE_2700		0
+#define  DPLL_CRTL1_LINK_RATE_1350		1
+#define  DPLL_CRTL1_LINK_RATE_810		2
+#define  DPLL_CRTL1_LINK_RATE_1620		3
+#define  DPLL_CRTL1_LINK_RATE_1080		4
+#define  DPLL_CRTL1_LINK_RATE_2160		5
+
+/* DPLL control2 */
+#define DPLL_CTRL2				0x6C05C
+#define  DPLL_CTRL2_DDI_CLK_OFF(port)		(1<<(port+15))
+#define  DPLL_CTRL2_DDI_CLK_SEL_MASK(port)	(3<<((port)*3+1))
+#define  DPLL_CTRL2_DDI_CLK_SEL(clk, port)	(clk<<((port)*3+1))
+#define  DPLL_CTRL2_DDI_SEL_OVERRIDE(port)	(1<<(port*3))
+
+/* DPLL Status */
+#define DPLL_STATUS	0x6C060
+#define	 DPLL_LOCK(id)	(1<<((id)*8))
+
+/* DPLL cfg */
+#define DPLL1_CFGCR1	0x6C040
+#define DPLL2_CFGCR1	0x6C048
+#define DPLL3_CFGCR1	0x6C050
+#define  DPLL_CFGCR1_FREQ_ENABLE	(1<<31)
+#define  DPLL_CFGCR1_DCO_FRACTION_MASK	(0x7fff<<9)
+#define  DPLL_CFGCR1_DCO_FRACTION(x)	(x<<9)
+#define  DPLL_CFGCR1_DCO_INTEGER_MASK	(0x1ff)
+
+#define DPLL1_CFGCR2	0x6C044
+#define DPLL2_CFGCR2	0x6C04C
+#define DPLL3_CFGCR2	0x6C054
+#define  DPLL_CFGCR2_QDIV_RATIO_MASK	(0xff<<8)
+#define  DPLL_CFGCR2_QDIV_RATIO(x)	(x<<8)
+#define  DPLL_CFGCR2_QDIV_MODE(x)	(x<<7)
+#define  DPLL_CFGCR2_KDIV_MASK		(3<<5)
+#define  DPLL_CFGCR2_KDIV(x)		(x<<5)
+#define  DPLL_CFGCR2_PDIV_MASK		(7<<2)
+#define  DPLL_CFGCR2_PDIV(x)		(x<<2)
+#define  DPLL_CFGCR2_CENTRAL_FREQ_MASK	(3)
+
+enum central_freq {
+	freq_9600 = 0,
+	freq_9000 = 1,
+	freq_8400 = 3,
+};
+
+enum pdiv {
+	pdiv_1 = 0,
+	pdiv_2 = 1,
+	pdiv_3 = 2,
+	pdiv_7 = 4,
+};
+
+enum kdiv {
+	kdiv_5 = 0,
+	kdiv_2 = 1,
+	kdiv_3 = 2,
+	kdiv_1 = 3,
+};
+
 /* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register,
  * since on HSW we can't write to it using I915_WRITE. */
 #define D_COMP_HSW			(MCHBAR_MIRROR_BASE_SNB + 0x5F0C)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 59/89] drm/i915/skl: Structure/enum definitions for SKL clocks
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (57 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 58/89] drm/i915/skl: Register definitions for SKL Clocks Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-22 18:25   ` Paulo Zanoni
  2014-09-04 11:27 ` [PATCH 60/89] drm/i915/skl: CD clock back calculation for SKL Damien Lespiau
                   ` (30 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

Adding structure/enum for SKL clocking implementation.

v2: Addressed Damien's comment
	- Removed internal structure from this header file

v3: Stove this into the generic intel_dpll_id enum and give them the established
DPLL_ID_ prefixes. (Daniel)

v4: - We'll only try to share DPLL1/2/3, leaving DPLL0 to eDP
    - Use SKL in the skylake shared DPLL names
    - Re-add the skl_dpll enum
    (Damien)

v5: Remove SKL_DPLL_NONE (Daniel)

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v2)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v4,v5)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v3)
---
 drivers/gpu/drm/i915/i915_drv.h | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 84defa4..65e5ffb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -206,10 +206,15 @@ enum intel_dpll_id {
 	/* real shared dpll ids must be >= 0 */
 	DPLL_ID_PCH_PLL_A = 0,
 	DPLL_ID_PCH_PLL_B = 1,
+	/* hsw/bdw */
 	DPLL_ID_WRPLL1 = 0,
 	DPLL_ID_WRPLL2 = 1,
+	/* skl */
+	DPLL_ID_SKL_DPLL1 = 0,
+	DPLL_ID_SKL_DPLL2 = 1,
+	DPLL_ID_SKL_DPLL3 = 2,
 };
-#define I915_NUM_PLLS 2
+#define I915_NUM_PLLS 3
 
 struct intel_dpll_hw_state {
 	/* i9xx, pch plls */
@@ -243,6 +248,13 @@ struct intel_shared_dpll {
 			     struct intel_dpll_hw_state *hw_state);
 };
 
+enum skl_dpll {
+	SKL_DPLL0,
+	SKL_DPLL1,
+	SKL_DPLL2,
+	SKL_DPLL3,
+};
+
 /* Used by dp and fdi links */
 struct intel_link_m_n {
 	uint32_t	tu;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 60/89] drm/i915/skl: CD clock back calculation for SKL
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (58 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 59/89] drm/i915/skl: Structure/enum definitions for SKL clocks Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-22 19:19   ` Paulo Zanoni
  2014-09-04 11:27 ` [PATCH 61/89] drm/i915/skl: Determine enabled PLL and its linkrate/pixel clock Damien Lespiau
                   ` (29 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

Determine programmed cd clock for SKL.

v2: Fix the LCPLL1 enable warning logic

v3: Rebase over the hsw pll rework.

v4: Rebase on top of the per-platform split (Damien)

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 76 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 67 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index ba1103f..e7a5428 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1260,6 +1260,55 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
 	}
 }
 
+static int skl_get_cdclk_freq(struct drm_i915_private *dev_priv)
+{
+	uint32_t lcpll1 = I915_READ(LCPLL1_CTL);
+	uint32_t cdctl = I915_READ(CDCLK_CTL);
+	uint32_t linkrate;
+
+	if (!(lcpll1 & LCPLL_PLL_ENABLE)) {
+		WARN(1, "LCPLL1 not enabled\n");
+		return 24000; /* 24MHz is the cd freq with NSSC ref */
+	}
+
+	if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540)
+		return 540000;
+
+	linkrate = (I915_READ(DPLL_CTRL1) &
+		    DPLL_CRTL1_LINK_RATE_MASK(SKL_DPLL0)) >> 1;
+
+	if (linkrate == DPLL_CRTL1_LINK_RATE_2160 ||
+	    linkrate == DPLL_CRTL1_LINK_RATE_1080) {
+		/* vco 8640 */
+		switch (cdctl & CDCLK_FREQ_SEL_MASK) {
+		case CDCLK_FREQ_450_432:
+			return 432000;
+		case CDCLK_FREQ_337_308:
+			return 308570;
+		case CDCLK_FREQ_675_617:
+			return 617140;
+			break;
+		default:
+			WARN(1, "Unknown cd freq selection\n");
+		}
+	} else {
+		/* vco 8100 */
+		switch (cdctl & CDCLK_FREQ_SEL_MASK) {
+		case CDCLK_FREQ_450_432:
+			return 450000;
+		case CDCLK_FREQ_337_308:
+			return 337500;
+		case CDCLK_FREQ_675_617:
+			return 675000;
+		default:
+			WARN(1, "Unknown cd freq selection\n");
+		}
+	}
+
+	/* error case, do as if DPLL0 isn't enabled */
+	return 24000;
+}
+
 static int bdw_get_cdclk_freq(struct drm_i915_private *dev_priv)
 {
 	uint32_t lcpll = I915_READ(LCPLL_CTL);
@@ -1301,6 +1350,9 @@ int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
 {
 	struct drm_device *dev = dev_priv->dev;
 
+	if (IS_SKYLAKE(dev))
+		return skl_get_cdclk_freq(dev_priv);
+
 	if (IS_BROADWELL(dev))
 		return bdw_get_cdclk_freq(dev_priv);
 
@@ -1369,19 +1421,25 @@ void intel_ddi_pll_init(struct drm_device *dev)
 
 	hsw_shared_dplls_init(dev_priv);
 
-	/* The LCPLL register should be turned on by the BIOS. For now let's
-	 * just check its state and print errors in case something is wrong.
-	 * Don't even try to turn it on.
-	 */
-
 	DRM_DEBUG_KMS("CDCLK running at %dKHz\n",
 		      intel_ddi_get_cdclk_freq(dev_priv));
 
-	if (val & LCPLL_CD_SOURCE_FCLK)
-		DRM_ERROR("CDCLK source is not LCPLL\n");
+	if (IS_SKYLAKE(dev)) {
+		if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
+			DRM_ERROR("LCPLL1 is disabled\n");
+	} else {
+		/*
+		 * The LCPLL register should be turned on by the BIOS. For now
+		 * let's just check its state and print errors in case
+		 * something is wrong.  Don't even try to turn it on.
+		 */
+
+		if (val & LCPLL_CD_SOURCE_FCLK)
+			DRM_ERROR("CDCLK source is not LCPLL\n");
 
-	if (val & LCPLL_PLL_DISABLE)
-		DRM_ERROR("LCPLL is disabled\n");
+		if (val & LCPLL_PLL_DISABLE)
+			DRM_ERROR("LCPLL is disabled\n");
+	}
 }
 
 void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 61/89] drm/i915/skl: Determine enabled PLL and its linkrate/pixel clock
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (59 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 60/89] drm/i915/skl: CD clock back calculation for SKL Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-22 20:12   ` Paulo Zanoni
  2014-09-04 11:27 ` [PATCH 62/89] drm/i915/skl: Query DPLL attached to port on SKL Damien Lespiau
                   ` (28 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

v2: Fixup compilation due to the removal of the intel_ddi_dpll_id enum.
And add a fixme about the abuse of pipe_config here.

v3: Rebase on top of the hsw_ddi_clock_get() rename (Damien)

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v1)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v3)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v2)
---
 drivers/gpu/drm/i915/i915_reg.h  |   5 ++
 drivers/gpu/drm/i915/intel_ddi.c | 114 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 118 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2364ece..794d0ba 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6367,6 +6367,7 @@ enum punit_power_well {
 #define  DPLL_CRTL1_LINK_RATE_1620		3
 #define  DPLL_CRTL1_LINK_RATE_1080		4
 #define  DPLL_CRTL1_LINK_RATE_2160		5
+#define  DPLL_CRTL1_LINK_RATE_SHIFT(id)		((id)*6+1)
 
 /* DPLL control2 */
 #define DPLL_CTRL2				0x6C05C
@@ -6374,6 +6375,7 @@ enum punit_power_well {
 #define  DPLL_CTRL2_DDI_CLK_SEL_MASK(port)	(3<<((port)*3+1))
 #define  DPLL_CTRL2_DDI_CLK_SEL(clk, port)	(clk<<((port)*3+1))
 #define  DPLL_CTRL2_DDI_SEL_OVERRIDE(port)	(1<<(port*3))
+#define  DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port)	(port*3+1)
 
 /* DPLL Status */
 #define DPLL_STATUS	0x6C060
@@ -6400,6 +6402,9 @@ enum punit_power_well {
 #define  DPLL_CFGCR2_PDIV(x)		(x<<2)
 #define  DPLL_CFGCR2_CENTRAL_FREQ_MASK	(3)
 
+#define GET_CFG_CR1_REG(id) (DPLL1_CFGCR1 + (id - 1) * 8)
+#define GET_CFG_CR2_REG(id) (DPLL1_CFGCR2 + (id - 1) * 8)
+
 enum central_freq {
 	freq_9600 = 0,
 	freq_9000 = 1,
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index e7a5428..b5cfb07 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -649,6 +649,114 @@ static int intel_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
 	return (refclk * n * 100) / (p * r);
 }
 
+static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
+			       enum intel_dpll_id dpll)
+{
+	uint32_t cfgcr1_reg, cfgcr2_reg;
+	uint32_t cfgcr1, cfgcr2;
+	uint32_t p0, p1, p2, dco_freq;
+
+	cfgcr1_reg = GET_CFG_CR1_REG(dpll);
+	cfgcr2_reg = GET_CFG_CR2_REG(dpll);
+
+	cfgcr1 = I915_READ(cfgcr1_reg);
+	cfgcr2 = I915_READ(cfgcr2_reg);
+
+	p0 = (cfgcr2 & DPLL_CFGCR2_PDIV_MASK) >> 2;
+	p2 = (cfgcr2 & DPLL_CFGCR2_KDIV_MASK) >> 5;
+
+	if (cfgcr2 &  DPLL_CFGCR2_QDIV_MODE(1))
+		p1 = (cfgcr2 & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
+	else
+		p1 = 1;
+
+
+	switch (p0) {
+	case pdiv_1:
+		p0 = 1;
+		break;
+	case pdiv_2:
+		p0 = 2;
+		break;
+	case pdiv_3:
+		p0 = 3;
+		break;
+	case pdiv_7:
+		p0 = 7;
+		break;
+	}
+
+	switch (p2) {
+	case kdiv_5:
+		p2 = 5;
+		break;
+	case kdiv_2:
+		p2 = 2;
+		break;
+	case kdiv_3:
+		p2 = 3;
+		break;
+	case kdiv_1:
+		p2 = 1;
+		break;
+	}
+
+	dco_freq = (cfgcr1 & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
+
+	dco_freq += (((cfgcr1 & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
+		1000) / 0x8000;
+
+	return dco_freq / (p0 * p1 * p2 * 5);
+}
+
+
+static void skl_ddi_clock_get(struct intel_encoder *encoder,
+				struct intel_crtc_config *pipe_config)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	enum port port = intel_ddi_get_encoder_port(encoder);
+	int link_clock = 0;
+	uint32_t dpll_ctl1, dpll;
+
+	/* FIXME: This should be tracked in the pipe config. */
+	dpll = I915_READ(DPLL_CTRL2);
+	dpll &= DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
+	dpll >>= DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port);
+
+	dpll_ctl1 = I915_READ(DPLL_CTRL1);
+
+	if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
+		link_clock = skl_calc_wrpll_link(dev_priv, dpll);
+	} else {
+		link_clock = dpll_ctl1 & DPLL_CRTL1_LINK_RATE_MASK(dpll);
+		link_clock >>= DPLL_CRTL1_LINK_RATE_SHIFT(dpll);
+
+		switch (link_clock) {
+		case DPLL_CRTL1_LINK_RATE_810:
+			link_clock = 81000;
+			break;
+		case DPLL_CRTL1_LINK_RATE_1350:
+			link_clock = 135000;
+			break;
+		case DPLL_CRTL1_LINK_RATE_2700:
+			link_clock = 270000;
+			break;
+		default:
+			break;
+		}
+		link_clock *= 2;
+	}
+
+	pipe_config->port_clock = link_clock;
+
+	if (pipe_config->has_dp_encoder)
+		pipe_config->adjusted_mode.crtc_clock =
+			intel_dotclock_calculate(pipe_config->port_clock,
+						 &pipe_config->dp_m_n);
+	else
+		pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock;
+}
+
 static void hsw_ddi_clock_get(struct intel_encoder *encoder,
 			      struct intel_crtc_config *pipe_config)
 {
@@ -1535,6 +1643,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
 	enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
 	u32 temp, flags = 0;
+	struct drm_device *dev = dev_priv->dev;
 
 	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
 	if (temp & TRANS_DDI_PHSYNC)
@@ -1606,7 +1715,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 		dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
 	}
 
-	hsw_ddi_clock_get(encoder, pipe_config);
+	if (INTEL_INFO(dev)->gen < 9)
+		hsw_ddi_clock_get(encoder, pipe_config);
+	else
+		skl_ddi_clock_get(encoder, pipe_config);
 }
 
 static void intel_ddi_destroy(struct drm_encoder *encoder)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 62/89] drm/i915/skl: Query DPLL attached to port on SKL
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (60 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 61/89] drm/i915/skl: Determine enabled PLL and its linkrate/pixel clock Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-22 20:24   ` Paulo Zanoni
  2014-09-04 11:27 ` [PATCH 63/89] drm/i915/skl: Define shared DPLLs for Skylake Damien Lespiau
                   ` (27 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

Modify the implementation to query DPLL attached to a SKL port.

v2: Rebase on top of the run-time PM on DPMS series (Damien)

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 27 ++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_drv.h     |  5 ++++-
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 69e023a..6e71250 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7789,6 +7789,28 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
 	return 0;
 }
 
+static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv,
+				enum port port,
+				struct intel_crtc_config *pipe_config)
+{
+	u32 temp;
+
+	temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
+	pipe_config->ddi_pll_sel = temp >> (port * 3 + 1);
+
+	switch (pipe_config->ddi_pll_sel) {
+	case SKL_DPLL1:
+		pipe_config->shared_dpll = DPLL_ID_SKL_DPLL1;
+		break;
+	case SKL_DPLL2:
+		pipe_config->shared_dpll = DPLL_ID_SKL_DPLL2;
+		break;
+	case SKL_DPLL3:
+		pipe_config->shared_dpll = DPLL_ID_SKL_DPLL3;
+		break;
+	}
+}
+
 static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
 				enum port port,
 				struct intel_crtc_config *pipe_config)
@@ -7818,7 +7840,10 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
 
 	port = (tmp & TRANS_DDI_PORT_MASK) >> TRANS_DDI_PORT_SHIFT;
 
-	haswell_get_ddi_pll(dev_priv, port, pipe_config);
+	if (IS_SKYLAKE(dev))
+		skylake_get_ddi_pll(dev_priv, port, pipe_config);
+	else
+		haswell_get_ddi_pll(dev_priv, port, pipe_config);
 
 	if (pipe_config->shared_dpll >= 0) {
 		pll = &dev_priv->shared_dplls[pipe_config->shared_dpll];
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 559b747..9558f07 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -323,7 +323,10 @@ struct intel_crtc_config {
 	/* Selected dpll when shared or DPLL_ID_PRIVATE. */
 	enum intel_dpll_id shared_dpll;
 
-	/* PORT_CLK_SEL for DDI ports. */
+	/*
+	 * - PORT_CLK_SEL for DDI ports on HSW/BDW.
+	 * - enum skl_dpll on SKL
+	 */
 	uint32_t ddi_pll_sel;
 
 	/* Actual register state of the dpll, for shared dpll cross-checking. */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 63/89] drm/i915/skl: Define shared DPLLs for Skylake
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (61 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 62/89] drm/i915/skl: Query DPLL attached to port on SKL Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-23 14:28   ` Paulo Zanoni
  2014-09-04 11:27 ` [PATCH 64/89] drm/i915/skl: Adjust the port PLL selection code Damien Lespiau
                   ` (26 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

On skylake, DPLL 1, 2 and 3 can be used for DP and HDMI. The shared dpll
framework allows us to share those DPLLs among DDIs when possible.

The most tricky part is to provide a DPLL state that can be easily
compared. DPLL_CRTL1 is shared by all the DPLLs, 6 bits each. The
per-dpll crtl1 field of the hw state is then normalized to be the same
value if 2 DPLLs do indeed have identical values for those 6 bits.

v2: Port the code to the shared DPLL infrastructure (Damien)

XXX: This patch would benefit from a bunchf of macros for handling ctrl1
to encapsulate the masking and shifting (Daniel)

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v1)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h  |  11 ++++
 drivers/gpu/drm/i915/intel_ddi.c | 126 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 136 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 65e5ffb..a6e14db 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -225,6 +225,17 @@ struct intel_dpll_hw_state {
 
 	/* hsw, bdw */
 	uint32_t wrpll;
+
+	/* skl */
+	/*
+	 * DPLL_CTRL1 has 6 bits for each each this DPLL. We store those in
+	 * lower part of crtl1 and they get shifted into position when writing
+	 * the register.  This allows us to easily compare the state to share
+	 * the DPLL.
+	 */
+	uint32_t ctrl1;
+	/* HDMI only, 0 when used for DP */
+	uint32_t cfgcr1, cfgcr2;
 };
 
 struct intel_shared_dpll {
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index b5cfb07..53ac23d 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1522,12 +1522,136 @@ static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
 	}
 }
 
+static const char * const skl_ddi_pll_names[] = {
+	"DPLL 1",
+	"DPLL 2",
+	"DPLL 3",
+};
+
+struct skl_dpll_regs {
+	u32 ctl, cfgcr1, cfgcr2;
+};
+
+/* this array is indexed by the *shared* pll id */
+static const struct skl_dpll_regs skl_dpll_regs[3] = {
+	{
+		/* DPLL 1 */
+		.ctl = LCPLL2_CTL,
+		.cfgcr1 = DPLL1_CFGCR1,
+		.cfgcr2 = DPLL1_CFGCR2,
+	},
+	{
+		/* DPLL 2 */
+		.ctl = WRPLL_CTL1,
+		.cfgcr1 = DPLL2_CFGCR1,
+		.cfgcr2 = DPLL2_CFGCR2,
+	},
+	{
+		/* DPLL 3 */
+		.ctl = WRPLL_CTL2,
+		.cfgcr1 = DPLL3_CFGCR1,
+		.cfgcr2 = DPLL3_CFGCR2,
+	},
+};
+
+static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
+			       struct intel_shared_dpll *pll)
+{
+	uint32_t val;
+	unsigned int dpll;
+	const struct skl_dpll_regs *regs = skl_dpll_regs;
+
+	/* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
+	dpll = pll->id + 1;
+
+	val = I915_READ(DPLL_CTRL1);
+
+	val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
+		 DPLL_CRTL1_LINK_RATE_MASK(dpll));
+	val |= pll->hw_state.ctrl1 << (dpll * 6);
+
+	I915_WRITE(DPLL_CTRL1, val);
+	POSTING_READ(DPLL_CTRL1);
+
+	I915_WRITE(regs[pll->id].cfgcr1, pll->hw_state.cfgcr1);
+	I915_WRITE(regs[pll->id].cfgcr2, pll->hw_state.cfgcr2);
+	POSTING_READ(regs[pll->id].cfgcr1);
+	POSTING_READ(regs[pll->id].cfgcr2);
+
+	/* the enable bit is always bit 31 */
+	I915_WRITE(regs[pll->id].ctl,
+		   I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
+
+	if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
+		DRM_ERROR("DPLL %d not locked\n", dpll);
+}
+
+static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
+				struct intel_shared_dpll *pll)
+{
+	const struct skl_dpll_regs *regs = skl_dpll_regs;
+
+	/* the enable bit is always bit 31 */
+	I915_WRITE(regs[pll->id].ctl,
+		   I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
+	POSTING_READ(regs[pll->id].ctl);
+}
+
+static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
+				     struct intel_shared_dpll *pll,
+				     struct intel_dpll_hw_state *hw_state)
+{
+	uint32_t val;
+	unsigned int dpll;
+	const struct skl_dpll_regs *regs = skl_dpll_regs;
+
+	if (!intel_display_power_enabled(dev_priv, POWER_DOMAIN_PLLS))
+		return false;
+
+	/* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
+	dpll = pll->id + 1;
+
+	val = I915_READ(regs[pll->id].ctl);
+	if (!(val & LCPLL_PLL_ENABLE))
+		return false;
+
+	val = I915_READ(DPLL_CTRL1);
+	hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
+
+	/* avoid reading back stale values if HDMI mode is not enabled */
+	if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
+		hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
+		hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
+	}
+
+	return true;
+}
+
+static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
+{
+	int i;
+
+	dev_priv->num_shared_dpll = 3;
+
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		dev_priv->shared_dplls[i].id = i;
+		dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
+		dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
+		dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
+		dev_priv->shared_dplls[i].get_hw_state =
+			skl_ddi_pll_get_hw_state;
+	}
+}
+
 void intel_ddi_pll_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t val = I915_READ(LCPLL_CTL);
 
-	hsw_shared_dplls_init(dev_priv);
+	if (IS_SKYLAKE(dev))
+		skl_shared_dplls_init(dev_priv);
+	else
+		hsw_shared_dplls_init(dev_priv);
 
 	DRM_DEBUG_KMS("CDCLK running at %dKHz\n",
 		      intel_ddi_get_cdclk_freq(dev_priv));
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 64/89] drm/i915/skl: Adjust the port PLL selection code
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (62 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 63/89] drm/i915/skl: Define shared DPLLs for Skylake Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-23 14:39   ` Paulo Zanoni
  2014-09-04 11:27 ` [PATCH 65/89] drm/i915/skl: Always use DPLL0 for eDP Damien Lespiau
                   ` (25 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

Skylake deprecates the usage of PORT_CLK_SEL and we are advised to use
the new DPLL_CRTL2 for the DDI->PLL mapping.

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 30 +++++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 53ac23d..439cd50 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1223,7 +1223,8 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
 static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
-	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
 	enum port port = intel_ddi_get_encoder_port(intel_encoder);
 	int type = intel_encoder->type;
@@ -1242,8 +1243,22 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 		intel_edp_panel_on(intel_dp);
 	}
 
-	WARN_ON(crtc->config.ddi_pll_sel == PORT_CLK_SEL_NONE);
-	I915_WRITE(PORT_CLK_SEL(port), crtc->config.ddi_pll_sel);
+	if (IS_SKYLAKE(dev)) {
+		enum skl_dpll dpll = crtc->config.ddi_pll_sel;
+		uint32_t val;
+
+		val = I915_READ(DPLL_CTRL2);
+
+		val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
+			DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
+		val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
+			DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
+
+		I915_WRITE(DPLL_CTRL2, val);
+	} else {
+		WARN_ON(crtc->config.ddi_pll_sel == PORT_CLK_SEL_NONE);
+		I915_WRITE(PORT_CLK_SEL(port), crtc->config.ddi_pll_sel);
+	}
 
 	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
 		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
@@ -1267,7 +1282,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
-	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	enum port port = intel_ddi_get_encoder_port(intel_encoder);
 	int type = intel_encoder->type;
 	uint32_t val;
@@ -1295,7 +1311,11 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
 		intel_edp_panel_off(intel_dp);
 	}
 
-	I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
+	if (IS_SKYLAKE(dev))
+		I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
+					DPLL_CTRL2_DDI_CLK_OFF(port)));
+	else
+		I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
 }
 
 static void intel_enable_ddi(struct intel_encoder *intel_encoder)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 65/89] drm/i915/skl: Always use DPLL0 for eDP
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (63 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 64/89] drm/i915/skl: Adjust the port PLL selection code Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-23 15:07   ` Paulo Zanoni
  2014-09-04 11:27 ` [PATCH 66/89] drm/i915/skl: Implementation of SKL DPLL programming Damien Lespiau
                   ` (24 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

DPLL0 is not part of the shared PLL infrastructure. We'll use on for
eDP and rely on what the BIOS does for now.

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5755f59..93bd9bf 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1005,7 +1005,10 @@ found:
 				&pipe_config->dp_m2_n2);
 	}
 
-	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+	if (IS_SKYLAKE(dev)) {
+		if (is_edp(intel_dp))
+			pipe_config->ddi_pll_sel = SKL_DPLL0;
+	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
 		hsw_dp_set_ddi_pll_sel(pipe_config, intel_dp->link_bw);
 	else
 		intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 66/89] drm/i915/skl: Implementation of SKL DPLL programming
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (64 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 65/89] drm/i915/skl: Always use DPLL0 for eDP Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-23 18:05   ` Paulo Zanoni
  2015-05-13 14:54   ` [PATCH 66/89] " Tvrtko Ursulin
  2014-09-04 11:27 ` [PATCH 67/89] drm/i915/skl: Provide skl-specific pll hw state cross-checking Damien Lespiau
                   ` (23 subsequent siblings)
  89 siblings, 2 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

This patch implements SKL DPLL programming that includes:
        - DPLL allocation
        - wide range PLL calculation and programming
        - DP link rate programming
        - DDI to DPLL mapping

v2: Incorporated following changes
        - Added vfunc for function required outside
        - Fixed multiple comments in WRPLL calculation

v3: - Fix the DCO computation
    - Move the initialization up to not clobber the computed values
    - Use the correct macro for DP link rate programming.
    - Use wait_for() to wait for the PLL locked bit

v4: Rebase on top of nigthly (Damien)

v5: A few code cleanups in the WRPLL computation (Damien)
    - Use uint32_t when possible
    - Use abs_diff() in the WRPLL computation
    - Make the 64bits divisions use div64_u64()
    - Fix typo in dco_central_feq_deviation (freq)
    - Replace the chain of breaks with a goto

v6: Port of the patch to work on top of the shared DPLLs (Damien)
v7: Don't try to handle eDP in ddi_pll_select() (Damien)

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v3)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 225 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 224 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 439cd50..f68e04c 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -915,6 +915,225 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
 	return true;
 }
 
+struct skl_wrpll_params {
+	uint32_t        dco_fraction;
+	uint32_t        dco_integer;
+	uint32_t        qdiv_ratio;
+	uint32_t        qdiv_mode;
+	uint32_t        kdiv;
+	uint32_t        pdiv;
+	uint32_t        central_freq;
+};
+
+static void
+skl_ddi_calculate_wrpll(int clock /* in Hz */,
+			struct skl_wrpll_params *wrpll_params)
+{
+	uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
+	uint64_t dco_central_freq[3] = {8400000000, 9000000000, 9600000000};
+	uint32_t min_dco_deviation = 400;
+	uint32_t min_dco_index = 3;
+	uint32_t P0[4] = {1, 2, 3, 7};
+	uint32_t P2[4] = {1, 2, 3, 5};
+	bool found = false;
+	uint32_t candidate_p = 0;
+	uint32_t candidate_p0[3] = {0}, candidate_p1[3] = {0};
+	uint32_t candidate_p2[3] = {0};
+	uint32_t dco_central_freq_deviation[3];
+	uint32_t i, P1, k, dco_count;
+	bool retry_with_odd = false;
+	uint64_t dco_freq;
+
+	/* Determine P0, P1 or P2 */
+	for (dco_count = 0; dco_count < 3; dco_count++) {
+		found = false;
+		candidate_p =
+			div64_u64(dco_central_freq[dco_count], afe_clock);
+		if (retry_with_odd == false)
+			candidate_p = (candidate_p % 2 == 0 ?
+				candidate_p : candidate_p + 1);
+
+		for (P1 = 1; P1 < candidate_p; P1++) {
+			for (i = 0; i < 4; i++) {
+				if (!(P0[i] != 1 || P1 == 1))
+					continue;
+
+				for (k = 0; k < 4; k++) {
+					if (!((P2[k] != 2 && P1 == 1) ||
+						(P2[k] == 2)))
+						continue;
+
+					if (candidate_p == P0[i] * P1 * P2[k]) {
+						/* Found possible P0, P1, P2 */
+						found = true;
+						candidate_p0[dco_count] = P0[i];
+						candidate_p1[dco_count] = P1;
+						candidate_p2[dco_count] = P2[k];
+						goto found;
+					}
+
+				}
+			}
+		}
+
+found:
+		if (found) {
+			dco_central_freq_deviation[dco_count] =
+				div64_u64(10000 *
+					  abs_diff((candidate_p * afe_clock),
+						   dco_central_freq[dco_count]),
+					  dco_central_freq[dco_count]);
+
+			if (dco_central_freq_deviation[dco_count] <
+				min_dco_deviation) {
+				min_dco_deviation =
+					dco_central_freq_deviation[dco_count];
+				min_dco_index = dco_count;
+			}
+		}
+
+		if (min_dco_index > 2 && dco_count == 2) {
+			retry_with_odd = true;
+			dco_count = 0;
+		}
+	}
+
+	if (min_dco_index > 2) {
+		WARN(1, "No valid values found for the given pixel clock\n");
+	} else {
+		 wrpll_params->central_freq = dco_central_freq[min_dco_index];
+
+		 switch (dco_central_freq[min_dco_index]) {
+		 case 9600000000:
+			wrpll_params->central_freq = 0;
+			break;
+		 case 9000000000:
+			wrpll_params->central_freq = 1;
+			break;
+		 case 8400000000:
+			wrpll_params->central_freq = 3;
+		 }
+
+		 switch (candidate_p0[min_dco_index]) {
+		 case 1:
+			wrpll_params->pdiv = 0;
+			break;
+		 case 2:
+			wrpll_params->pdiv = 1;
+			break;
+		 case 3:
+			wrpll_params->pdiv = 2;
+			break;
+		 case 7:
+			wrpll_params->pdiv = 4;
+			break;
+		 default:
+			WARN(1, "Incorrect PDiv\n");
+		 }
+
+		 switch (candidate_p2[min_dco_index]) {
+		 case 5:
+			wrpll_params->kdiv = 0;
+			break;
+		 case 2:
+			wrpll_params->kdiv = 1;
+			break;
+		 case 3:
+			wrpll_params->kdiv = 2;
+			break;
+		 case 1:
+			wrpll_params->kdiv = 3;
+			break;
+		 default:
+			WARN(1, "Incorrect KDiv\n");
+		 }
+
+		 wrpll_params->qdiv_ratio = candidate_p1[min_dco_index];
+		 wrpll_params->qdiv_mode =
+			(wrpll_params->qdiv_ratio == 1) ? 0 : 1;
+
+		 dco_freq = candidate_p0[min_dco_index] *
+			 candidate_p1[min_dco_index] *
+			 candidate_p2[min_dco_index] * afe_clock;
+
+		 /* Intermediate values are in Hz.
+		    Divide by MHz to match bsepc */
+		 wrpll_params->dco_integer = div_u64(dco_freq, (24 * MHz(1)));
+		 wrpll_params->dco_fraction =
+			 div_u64(((div_u64(dco_freq, 24) -
+				   wrpll_params->dco_integer * MHz(1)) * 0x8000), MHz(1));
+
+	}
+}
+
+
+static bool
+skl_ddi_pll_select(struct intel_crtc *intel_crtc,
+		   struct intel_encoder *intel_encoder,
+		   int clock)
+{
+	struct intel_shared_dpll *pll;
+	uint32_t ctrl1, cfgcr1, cfgcr2;
+
+	/*
+	 * See comment in intel_dpll_hw_state to understand why we always use 0
+	 * as the DPLL id in this function.
+	 */
+
+	ctrl1 = DPLL_CTRL1_OVERRIDE(0);
+
+	if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
+		struct skl_wrpll_params wrpll_params = { 0, };
+
+		ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
+
+		skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params);
+
+		cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
+			 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
+			 wrpll_params.dco_integer;
+
+		cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
+			 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
+			 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
+			 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
+			 wrpll_params.central_freq;
+	} else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
+		struct drm_encoder *encoder = &intel_encoder->base;
+		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+		switch (intel_dp->link_bw) {
+		case DP_LINK_BW_1_62:
+			ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_810, 0);
+			break;
+		case DP_LINK_BW_2_7:
+			ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_1350, 0);
+			break;
+		case DP_LINK_BW_5_4:
+			ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_2700, 0);
+			break;
+		}
+
+		cfgcr1 = cfgcr2 = 0;
+	} else /* eDP */
+		return true;
+
+	intel_crtc->config.dpll_hw_state.ctrl1 = ctrl1;
+	intel_crtc->config.dpll_hw_state.cfgcr1 = cfgcr1;
+	intel_crtc->config.dpll_hw_state.cfgcr2 = cfgcr2;
+
+	pll = intel_get_shared_dpll(intel_crtc);
+	if (pll == NULL) {
+		DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
+				 pipe_name(intel_crtc->pipe));
+		return false;
+	}
+
+	/* shared DPLL id 0 is DPLL 1 */
+	intel_crtc->config.ddi_pll_sel = pll->id + 1;
+
+	return true;
+}
 
 /*
  * Tries to find a *shared* PLL for the CRTC and store it in
@@ -926,12 +1145,16 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
 bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
 {
 	struct drm_crtc *crtc = &intel_crtc->base;
+	struct drm_device *dev = crtc->dev;
 	struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
 	int clock = intel_crtc->config.port_clock;
 
 	intel_put_shared_dpll(intel_crtc);
 
-	return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock);
+	if (IS_SKYLAKE(dev))
+		return skl_ddi_pll_select(intel_crtc, intel_encoder, clock);
+	else
+		return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock);
 }
 
 void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 67/89] drm/i915/skl: Provide skl-specific pll hw state cross-checking
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (65 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 66/89] drm/i915/skl: Implementation of SKL DPLL programming Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-23 18:07   ` Paulo Zanoni
  2014-09-04 11:27 ` [PATCH 68/89] drm/i915/skl: Apply eDP WA only for gen < 9 Damien Lespiau
                   ` (22 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

v2: rebase on top of the hw state flattening.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6e71250..0a4dd00 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10775,6 +10775,9 @@ intel_pipe_config_compare(struct drm_device *dev,
 	PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
 	PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
 	PIPE_CONF_CHECK_X(dpll_hw_state.wrpll);
+	PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1);
+	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
+	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
 
 	if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5)
 		PIPE_CONF_CHECK_I(pipe_bpp);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 68/89] drm/i915/skl: Apply eDP WA only for gen < 9
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (66 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 67/89] drm/i915/skl: Provide skl-specific pll hw state cross-checking Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-23 18:11   ` Paulo Zanoni
  2014-09-04 11:27 ` [PATCH 69/89] drm/i915/skl: Adding power domains for AUX controllers Damien Lespiau
                   ` (21 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Vandana Kannan <vandana.kannan@intel.com>

The eDP WA to stop link train based on port type is for HSW/BDW, not
required for SKL+.
Suggested by Satheesh

v2: Simplified the check befoe stop_link_train. Suggested by Satheesh.

v3: stop_link_train need not be called from intel_enable_ddi for gen >= 9

Suggested-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Reviewed-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
Cc: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index f68e04c..2561b40 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1491,7 +1491,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
 		intel_dp_start_link_train(intel_dp);
 		intel_dp_complete_link_train(intel_dp);
-		if (port != PORT_A)
+		if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
 			intel_dp_stop_link_train(intel_dp);
 	} else if (type == INTEL_OUTPUT_HDMI) {
 		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
@@ -1567,7 +1567,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
 	} else if (type == INTEL_OUTPUT_EDP) {
 		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
-		if (port == PORT_A)
+		if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
 			intel_dp_stop_link_train(intel_dp);
 
 		intel_edp_backlight_on(intel_dp);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 69/89] drm/i915/skl: Adding power domains for AUX controllers
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (67 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 68/89] drm/i915/skl: Apply eDP WA only for gen < 9 Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-16 12:35   ` Imre Deak
  2014-09-04 11:27 ` [PATCH 70/89] drm/i915/skl: Register definition for SKL power well Damien Lespiau
                   ` (20 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

Adding new power doamins for AUX controllers

v2: Added new power domains in power_domain_str per Imre's comment

v3: Added AUX power domains to older platforms

v4: Rebase on top of POWER_DOMAIN_PLLS.

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v3)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/i915_debugfs.c |  8 ++++++++
 drivers/gpu/drm/i915/i915_drv.h     |  4 ++++
 drivers/gpu/drm/i915/intel_pm.c     | 12 ++++++++++++
 3 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 88a4643..02cb310 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2273,6 +2273,14 @@ static const char *power_domain_str(enum intel_display_power_domain domain)
 		return "AUDIO";
 	case POWER_DOMAIN_PLLS:
 		return "PLLS";
+	case POWER_DOMAIN_AUX_A:
+		return "AUX_A";
+	case POWER_DOMAIN_AUX_B:
+		return "AUX_B";
+	case POWER_DOMAIN_AUX_C:
+		return "AUX_C";
+	case POWER_DOMAIN_AUX_D:
+		return "AUX_D";
 	case POWER_DOMAIN_INIT:
 		return "INIT";
 	default:
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a6e14db..91ea2b7 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -138,6 +138,10 @@ enum intel_display_power_domain {
 	POWER_DOMAIN_VGA,
 	POWER_DOMAIN_AUDIO,
 	POWER_DOMAIN_PLLS,
+	POWER_DOMAIN_AUX_A,
+	POWER_DOMAIN_AUX_B,
+	POWER_DOMAIN_AUX_C,
+	POWER_DOMAIN_AUX_D,
 	POWER_DOMAIN_INIT,
 
 	POWER_DOMAIN_NUM,
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 74a8519..ec849db 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7664,6 +7664,10 @@ EXPORT_SYMBOL_GPL(i915_get_cdclk_freq);
 	BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |		\
 	BIT(POWER_DOMAIN_PORT_CRT) |			\
 	BIT(POWER_DOMAIN_PLLS) |			\
+	BIT(POWER_DOMAIN_AUX_A) |			\
+	BIT(POWER_DOMAIN_AUX_B) |			\
+	BIT(POWER_DOMAIN_AUX_C) |			\
+	BIT(POWER_DOMAIN_AUX_D) |			\
 	BIT(POWER_DOMAIN_INIT))
 #define HSW_DISPLAY_POWER_DOMAINS (				\
 	(POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) |	\
@@ -7685,24 +7689,32 @@ EXPORT_SYMBOL_GPL(i915_get_cdclk_freq);
 	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |	\
 	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |	\
 	BIT(POWER_DOMAIN_PORT_CRT) |		\
+	BIT(POWER_DOMAIN_AUX_A) |		\
+	BIT(POWER_DOMAIN_AUX_B) |		\
+	BIT(POWER_DOMAIN_AUX_C) |		\
+	BIT(POWER_DOMAIN_AUX_D) |		\
 	BIT(POWER_DOMAIN_INIT))
 
 #define VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS (	\
 	BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |	\
 	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_B) |		\
 	BIT(POWER_DOMAIN_INIT))
 
 #define VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS (	\
 	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_B) |		\
 	BIT(POWER_DOMAIN_INIT))
 
 #define VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS (	\
 	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |	\
 	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_C) |		\
 	BIT(POWER_DOMAIN_INIT))
 
 #define VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS (	\
 	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_C) |		\
 	BIT(POWER_DOMAIN_INIT))
 
 #define CHV_PIPE_A_POWER_DOMAINS (	\
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 70/89] drm/i915/skl: Register definition for SKL power well
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (68 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 69/89] drm/i915/skl: Adding power domains for AUX controllers Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-16 12:43   ` Imre Deak
  2014-09-04 11:27 ` [PATCH 71/89] drm/i915/skl: Implementation of SKL display power well support Damien Lespiau
                   ` (19 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

Defining new bit fields for SKL display power wells.

v2: Clean up unused macros

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 794d0ba..4d072a8 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6133,6 +6133,13 @@ enum punit_power_well {
 #define   HSW_PWR_WELL_FORCE_ON			(1<<19)
 #define HSW_PWR_WELL_CTL6			0x45414
 
+/* SKL Fuse Status */
+#define SKL_FUSE_STATUS				0x42000
+#define  SKL_FUSE_DOWNLOAD_STATUS              (1<<31)
+#define  SKL_FUSE_PG0_DIST_STATUS              (1<<27)
+#define  SKL_FUSE_PG1_DIST_STATUS              (1<<26)
+#define  SKL_FUSE_PG2_DIST_STATUS              (1<<25)
+
 /* Per-pipe DDI Function Control */
 #define TRANS_DDI_FUNC_CTL_A		0x60400
 #define TRANS_DDI_FUNC_CTL_B		0x61400
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 71/89] drm/i915/skl: Implementation of SKL display power well support
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (69 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 70/89] drm/i915/skl: Register definition for SKL power well Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-16 13:56   ` Imre Deak
  2014-09-04 11:27 ` [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction Damien Lespiau
                   ` (18 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

This patch implements core logic of SKL display power well.

FIXME: hsw_pwr needs to go. The audio guys promised us that they'll do a proper
implementation for skl+.

v2: Addressed Imre's comments
	- Added respective DDIs under power well #1 and #2
	- Simplified repetitive code in power well programming

v3: Implemented Imre's comments
	- Further simplified power well programming
	- Made sure that PW 1 is enabled prior to PW 2

v4: Fix minor conflict with the the cherryview support (Damien)

v5: Add the PLL power domain to the always on power well (Damien)

v6: Disable BIOS power well (Imre)
    Use power well data for comparison (Imre)
    Put the PLL power domain into PW1 as its needed for CDCLK (Satheesh,
    Damien)

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v3,v6)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h |  13 +++
 drivers/gpu/drm/i915/intel_pm.c | 207 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 220 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 4d072a8..84a0de6 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -541,6 +541,19 @@ enum punit_power_well {
 	PUNIT_POWER_WELL_NUM,
 };
 
+enum skl_disp_power_wells {
+	SKL_DISP_PW_MISC_IO,
+	SKL_DISP_PW_DDI_A_E,
+	SKL_DISP_PW_DDI_B,
+	SKL_DISP_PW_DDI_C,
+	SKL_DISP_PW_DDI_D,
+	SKL_DISP_PW_1 = 14,
+	SKL_DISP_PW_2,
+};
+
+#define SKL_POWER_WELL_STATE(pw) (1 << (pw * 2))
+#define SKL_POWER_WELL_REQ(pw) (1 << ((pw * 2) + 1))
+
 #define PUNIT_REG_PWRGT_CTRL			0x60
 #define PUNIT_REG_PWRGT_STATUS			0x61
 #define   PUNIT_PWRGT_MASK(power_well)		(3 << ((power_well) * 2))
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index ec849db..853b596 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7160,6 +7160,128 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
 	}
 }
 
+#define SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS (                 \
+	BIT(POWER_DOMAIN_PIPE_B) |                      \
+	BIT(POWER_DOMAIN_TRANSCODER_B) |                \
+	BIT(POWER_DOMAIN_PIPE_C) |                      \
+	BIT(POWER_DOMAIN_TRANSCODER_C) |                \
+	BIT(POWER_DOMAIN_PIPE_B_PANEL_FITTER) |         \
+	BIT(POWER_DOMAIN_PIPE_C_PANEL_FITTER) |         \
+	BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |          \
+	BIT(POWER_DOMAIN_AUX_B) |                       \
+	BIT(POWER_DOMAIN_AUX_C) |                       \
+	BIT(POWER_DOMAIN_AUX_D) |                       \
+	BIT(POWER_DOMAIN_AUDIO) |                       \
+	BIT(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS (         \
+	SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS |         \
+	BIT(POWER_DOMAIN_PLLS) |			\
+	BIT(POWER_DOMAIN_PIPE_A) |                      \
+	BIT(POWER_DOMAIN_TRANSCODER_EDP) |              \
+	BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \
+	BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) |          \
+	BIT(POWER_DOMAIN_AUX_A) |                       \
+	BIT(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DDI_A_E_POWER_DOMAINS (                     \
+	BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) |          \
+	BIT(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DDI_B_POWER_DOMAINS (                       \
+	BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |          \
+	BIT(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DDI_C_POWER_DOMAINS (                       \
+	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |          \
+	BIT(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DDI_D_POWER_DOMAINS (                       \
+	BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |          \
+	BIT(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_ALWAYS_ON_POWER_DOMAINS (           \
+	(POWER_DOMAIN_MASK & ~(SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS |  \
+	SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS |         \
+	SKL_DISPLAY_DDI_A_E_POWER_DOMAINS |             \
+	SKL_DISPLAY_DDI_B_POWER_DOMAINS |               \
+	SKL_DISPLAY_DDI_C_POWER_DOMAINS |               \
+	SKL_DISPLAY_DDI_D_POWER_DOMAINS)) |             \
+	BIT(POWER_DOMAIN_INIT))
+
+static void skl_set_power_well(struct drm_i915_private *dev_priv,
+			struct i915_power_well *power_well, bool enable)
+{
+	uint32_t tmp, fuse_status;
+	uint32_t req_mask, state_mask;
+	bool check_fuse_status = false;
+
+	tmp = I915_READ(HSW_PWR_WELL_DRIVER);
+	fuse_status = I915_READ(SKL_FUSE_STATUS);
+
+	switch (power_well->data) {
+	case SKL_DISP_PW_1:
+		if (wait_for((I915_READ(SKL_FUSE_STATUS) &
+			SKL_FUSE_PG0_DIST_STATUS), 5)) {
+			DRM_ERROR("PG0 not enabled\n");
+			return;
+		}
+		break;
+	case SKL_DISP_PW_2:
+		if (!(fuse_status & SKL_FUSE_PG1_DIST_STATUS)) {
+			DRM_ERROR("PG1 in disabled state\n");
+			return;
+		}
+		break;
+	case SKL_DISP_PW_DDI_A_E:
+	case SKL_DISP_PW_DDI_B:
+	case SKL_DISP_PW_DDI_C:
+	case SKL_DISP_PW_DDI_D:
+		break;
+	default:
+		return;
+	}
+
+	req_mask = SKL_POWER_WELL_REQ(power_well->data);
+	state_mask = SKL_POWER_WELL_STATE(power_well->data);
+
+	if (enable) {
+		if (!(tmp & req_mask))
+			I915_WRITE(HSW_PWR_WELL_DRIVER, tmp | req_mask);
+
+		if (!(tmp & state_mask)) {
+			DRM_DEBUG_KMS("Enabling DDI power well\n");
+			if (wait_for((I915_READ(HSW_PWR_WELL_DRIVER) &
+				state_mask), 20))
+				DRM_ERROR("%s enable timeout\n",
+					power_well->name);
+			check_fuse_status = true;
+		}
+	} else {
+		if (tmp & req_mask) {
+			I915_WRITE(HSW_PWR_WELL_DRIVER,	tmp & ~req_mask);
+			POSTING_READ(HSW_PWR_WELL_DRIVER);
+			DRM_DEBUG_KMS("Disabling %s\n", power_well->name);
+		}
+	}
+
+	if (check_fuse_status) {
+		if (power_well->data == SKL_DISP_PW_1) {
+			if (wait_for((I915_READ(SKL_FUSE_STATUS) &
+				SKL_FUSE_PG1_DIST_STATUS), 5))
+				DRM_ERROR("PG1 distributing status timeout\n");
+		} else if (power_well->data == SKL_DISP_PW_2) {
+			if (wait_for((I915_READ(SKL_FUSE_STATUS) &
+				SKL_FUSE_PG2_DIST_STATUS), 1))
+				DRM_ERROR("PG2 distributing status timeout\n");
+		}
+	}
+}
+
 static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv,
 				   struct i915_power_well *power_well)
 {
@@ -7185,6 +7307,36 @@ static void hsw_power_well_disable(struct drm_i915_private *dev_priv,
 	hsw_set_power_well(dev_priv, power_well, false);
 }
 
+static bool skl_power_well_enabled(struct drm_i915_private *dev_priv,
+					struct i915_power_well *power_well)
+{
+	uint32_t mask = SKL_POWER_WELL_REQ(power_well->data) |
+		SKL_POWER_WELL_STATE(power_well->data);
+
+	return (I915_READ(HSW_PWR_WELL_DRIVER) & mask) == mask;
+}
+
+static void skl_power_well_sync_hw(struct drm_i915_private *dev_priv,
+				struct i915_power_well *power_well)
+{
+	skl_set_power_well(dev_priv, power_well, power_well->count > 0);
+
+	/* Clear any request made by BIOS as driver is taking over */
+	I915_WRITE(HSW_PWR_WELL_BIOS, 0);
+}
+
+static void skl_power_well_enable(struct drm_i915_private *dev_priv,
+				struct i915_power_well *power_well)
+{
+	skl_set_power_well(dev_priv, power_well, true);
+}
+
+static void skl_power_well_disable(struct drm_i915_private *dev_priv,
+				struct i915_power_well *power_well)
+{
+	skl_set_power_well(dev_priv, power_well, false);
+}
+
 static void i9xx_always_on_power_well_noop(struct drm_i915_private *dev_priv,
 					   struct i915_power_well *power_well)
 {
@@ -7787,6 +7939,13 @@ static const struct i915_power_well_ops hsw_power_well_ops = {
 	.is_enabled = hsw_power_well_enabled,
 };
 
+static const struct i915_power_well_ops skl_power_well_ops = {
+	.sync_hw = skl_power_well_sync_hw,
+	.enable = skl_power_well_enable,
+	.disable = skl_power_well_disable,
+	.is_enabled = skl_power_well_enabled,
+};
+
 static struct i915_power_well hsw_power_wells[] = {
 	{
 		.name = "always-on",
@@ -8009,6 +8168,51 @@ static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_pr
 	return NULL;
 }
 
+static struct i915_power_well skl_power_wells[] = {
+	{
+		.name = "always-on",
+		.always_on = 1,
+		.domains = SKL_DISPLAY_ALWAYS_ON_POWER_DOMAINS,
+		.ops = &i9xx_always_on_power_well_ops,
+	},
+	{
+		.name = "power well 1",
+		.domains = SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS,
+		.ops = &skl_power_well_ops,
+		.data = SKL_DISP_PW_1,
+	},
+	{
+		.name = "power well 2",
+		.domains = SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS,
+		.ops = &skl_power_well_ops,
+		.data = SKL_DISP_PW_2,
+	},
+	{
+		.name = "DDI A/E power well",
+		.domains = SKL_DISPLAY_DDI_A_E_POWER_DOMAINS,
+		.ops = &skl_power_well_ops,
+		.data = SKL_DISP_PW_DDI_A_E,
+	},
+	{
+		.name = "DDI B power well",
+		.domains = SKL_DISPLAY_DDI_B_POWER_DOMAINS,
+		.ops = &skl_power_well_ops,
+		.data = SKL_DISP_PW_DDI_B,
+	},
+	{
+		.name = "DDI C power well",
+		.domains = SKL_DISPLAY_DDI_C_POWER_DOMAINS,
+		.ops = &skl_power_well_ops,
+		.data = SKL_DISP_PW_DDI_C,
+	},
+	{
+		.name = "DDI D power well",
+		.domains = SKL_DISPLAY_DDI_D_POWER_DOMAINS,
+		.ops = &skl_power_well_ops,
+		.data = SKL_DISP_PW_DDI_D,
+	},
+};
+
 #define set_power_wells(power_domains, __power_wells) ({		\
 	(power_domains)->power_wells = (__power_wells);			\
 	(power_domains)->power_well_count = ARRAY_SIZE(__power_wells);	\
@@ -8030,6 +8234,9 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
 	} else if (IS_BROADWELL(dev_priv->dev)) {
 		set_power_wells(power_domains, bdw_power_wells);
 		hsw_pwr = power_domains;
+	} else if (IS_SKYLAKE(dev_priv->dev)) {
+		set_power_wells(power_domains, skl_power_wells);
+		hsw_pwr = power_domains;
 	} else if (IS_CHERRYVIEW(dev_priv->dev)) {
 		set_power_wells(power_domains, chv_power_wells);
 	} else if (IS_VALLEYVIEW(dev_priv->dev)) {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (70 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 71/89] drm/i915/skl: Implementation of SKL display power well support Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-16 13:19   ` Imre Deak
  2014-09-04 11:27 ` [PATCH 73/89] drm/i915/skl: Enabling MISC IO power well Damien Lespiau
                   ` (17 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

This patch enables power well 2 required for any aux transaction.

v2: Implemented Imre's comments
	- In EDID/DPCD related routines, request AUX power well in SKL

v3: Implemented Imre's comments
	- Call AUX power well domain unconditionally for all platforms

v4: Remove the check on the output type for the AUX power domain

v5: Rebase on top of drm-intel-nightly (Damien)

v6: Rebase on top of -nightly (minor conflict in intel_drv.h) (Damien)

v7: Remove platform check while getting power well for port (Imre)

v8: Fix aux power handling around Vdd on/off (Damien)

v9: Acquire aux power domain on enabling vdd in
    intel_edp_panel_vdd_sanitize() (Satheesh)

v10: Rebase on top of Ville's patch to return early in this function intead of
     having a big indented block. (Damien)

v12: Rebase on top of Chris EDID caching work (Damien)

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v4, v9)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 21 ++++++++++++
 drivers/gpu/drm/i915/intel_dp.c      | 62 ++++++++++++++++++++++++++----------
 drivers/gpu/drm/i915/intel_drv.h     |  2 ++
 3 files changed, 68 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0a4dd00..abd4201 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4503,6 +4503,27 @@ intel_display_port_power_domain(struct intel_encoder *intel_encoder)
 	}
 }
 
+enum intel_display_power_domain
+intel_display_aux_power_domain(struct intel_encoder *intel_encoder)
+{
+	struct intel_digital_port *intel_dig_port;
+
+	intel_dig_port = enc_to_dig_port(&intel_encoder->base);
+	switch (intel_dig_port->port) {
+	case PORT_A:
+		return POWER_DOMAIN_AUX_A;
+	case PORT_B:
+		return POWER_DOMAIN_AUX_B;
+	case PORT_C:
+		return POWER_DOMAIN_AUX_C;
+	case PORT_D:
+		return POWER_DOMAIN_AUX_D;
+	default:
+		WARN_ON_ONCE(1);
+		return 0;
+	}
+}
+
 static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 93bd9bf..a983b40 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1233,6 +1233,9 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp)
 	power_domain = intel_display_port_power_domain(intel_encoder);
 	intel_display_power_get(dev_priv, power_domain);
 
+	power_domain = intel_display_aux_power_domain(intel_encoder);
+	intel_display_power_get(dev_priv, power_domain);
+
 	DRM_DEBUG_KMS("Turning eDP VDD on\n");
 
 	if (!edp_have_panel_power(intel_dp))
@@ -1309,8 +1312,12 @@ static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp)
 
 	power_domain = intel_display_port_power_domain(intel_encoder);
 	intel_display_power_put(dev_priv, power_domain);
+
+	power_domain = intel_display_aux_power_domain(intel_encoder);
+	intel_display_power_put(dev_priv, power_domain);
 }
 
+
 static void edp_panel_vdd_work(struct work_struct *__work)
 {
 	struct intel_dp *intel_dp = container_of(to_delayed_work(__work),
@@ -3836,7 +3843,13 @@ g4x_dp_detect(struct intel_dp *intel_dp)
 static struct edid *
 intel_dp_get_edid(struct intel_dp *intel_dp)
 {
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	struct drm_device *dev = intel_encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
+	enum intel_display_power_domain power_domain;
+	struct edid *edid;
 
 	/* use cached edid if we have one */
 	if (intel_connector->edid) {
@@ -3845,9 +3858,16 @@ intel_dp_get_edid(struct intel_dp *intel_dp)
 			return NULL;
 
 		return drm_edid_duplicate(intel_connector->edid);
-	} else
-		return drm_get_edid(&intel_connector->base,
-				    &intel_dp->aux.ddc);
+	} else {
+		power_domain = intel_display_aux_power_domain(intel_encoder);
+		intel_display_power_get(dev_priv, power_domain);
+
+		edid = drm_get_edid(&intel_connector->base, &intel_dp->aux.ddc);
+
+		intel_display_power_put(dev_priv, power_domain);
+
+		return edid;
+	}
 }
 
 static void
@@ -3876,24 +3896,30 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
 	intel_dp->has_audio = false;
 }
 
-static enum intel_display_power_domain
-intel_dp_power_get(struct intel_dp *dp)
+static void intel_dp_power_get(struct intel_dp *dp)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(dp)->base;
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum intel_display_power_domain power_domain;
 
 	power_domain = intel_display_port_power_domain(encoder);
 	intel_display_power_get(to_i915(encoder->base.dev), power_domain);
 
-	return power_domain;
+	power_domain = intel_display_aux_power_domain(encoder);
+	intel_display_power_get(dev_priv, power_domain);
 }
 
-static void
-intel_dp_power_put(struct intel_dp *dp,
-		   enum intel_display_power_domain power_domain)
+static void intel_dp_power_put(struct intel_dp *dp)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(dp)->base;
-	intel_display_power_put(to_i915(encoder->base.dev), power_domain);
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum intel_display_power_domain power_domain;
+
+	power_domain = intel_display_port_power_domain(encoder);
+	intel_display_power_put(dev_priv, power_domain);
+
+	power_domain = intel_display_aux_power_domain(encoder);
+	intel_display_power_put(dev_priv, power_domain);
 }
 
 static enum drm_connector_status
@@ -3904,7 +3930,6 @@ intel_dp_detect(struct drm_connector *connector, bool force)
 	struct intel_encoder *intel_encoder = &intel_dig_port->base;
 	struct drm_device *dev = connector->dev;
 	enum drm_connector_status status;
-	enum intel_display_power_domain power_domain;
 	bool ret;
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
@@ -3918,7 +3943,7 @@ intel_dp_detect(struct drm_connector *connector, bool force)
 		return connector_status_disconnected;
 	}
 
-	power_domain = intel_dp_power_get(intel_dp);
+	intel_dp_power_get(intel_dp);
 
 	/* Can't disconnect eDP, but you can close the lid... */
 	if (is_edp(intel_dp))
@@ -3949,7 +3974,7 @@ intel_dp_detect(struct drm_connector *connector, bool force)
 	status = connector_status_connected;
 
 out:
-	intel_dp_power_put(intel_dp, power_domain);
+	intel_dp_power_put(intel_dp);
 	return status;
 }
 
@@ -3958,7 +3983,6 @@ intel_dp_force(struct drm_connector *connector)
 {
 	struct intel_dp *intel_dp = intel_attached_dp(connector);
 	struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
-	enum intel_display_power_domain power_domain;
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
 		      connector->base.id, connector->name);
@@ -3967,11 +3991,11 @@ intel_dp_force(struct drm_connector *connector)
 	if (connector->status != connector_status_connected)
 		return;
 
-	power_domain = intel_dp_power_get(intel_dp);
+	intel_dp_power_get(intel_dp);
 
 	intel_dp_set_edid(intel_dp);
 
-	intel_dp_power_put(intel_dp, power_domain);
+	intel_dp_power_put(intel_dp);
 
 	if (intel_encoder->type != INTEL_OUTPUT_EDP)
 		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
@@ -4205,7 +4229,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
 		      port_name(intel_dig_port->port),
 		      long_hpd ? "long" : "short");
 
-	power_domain = intel_display_port_power_domain(intel_encoder);
+	power_domain = intel_display_aux_power_domain(intel_encoder);
+
 	intel_display_power_get(dev_priv, power_domain);
 
 	if (long_hpd) {
@@ -4648,6 +4673,9 @@ void intel_edp_panel_vdd_sanitize(struct intel_encoder *intel_encoder)
 	power_domain = intel_display_port_power_domain(intel_encoder);
 	intel_display_power_get(dev_priv, power_domain);
 
+	power_domain = intel_display_aux_power_domain(intel_encoder);
+	intel_display_power_get(dev_priv, power_domain);
+
 	edp_panel_vdd_schedule_off(intel_dp);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 9558f07..a407d04 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -916,6 +916,8 @@ void hsw_disable_ips(struct intel_crtc *crtc);
 void intel_display_set_init_power(struct drm_i915_private *dev, bool enable);
 enum intel_display_power_domain
 intel_display_port_power_domain(struct intel_encoder *intel_encoder);
+enum intel_display_power_domain
+intel_display_aux_power_domain(struct intel_encoder *intel_encoder);
 void intel_mode_from_pipe_config(struct drm_display_mode *mode,
 				 struct intel_crtc_config *pipe_config);
 int intel_format_to_fourcc(int format);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 73/89] drm/i915/skl: Enabling MISC IO power well
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (71 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-16 14:12   ` Imre Deak
  2014-09-04 11:27 ` [PATCH 74/89] drm/i915/skl: Implement queue_flip Damien Lespiau
                   ` (16 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

Earlier it was thought that MISC IO is always ON power well.
But it doesn't looks like the case as confirmed by the HW team.
Adding code to enable/disable MISC IO power well.

v2: Use power well data for comparison (Imre)

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 853b596..5425d85 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7204,6 +7204,21 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
 	BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) |          \
 	BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |          \
 	BIT(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_MISC_IO_POWER_DOMAINS (                       \
+	BIT(POWER_DOMAIN_AUX_A) |                       \
+	BIT(POWER_DOMAIN_AUX_B) |                       \
+	BIT(POWER_DOMAIN_AUX_C) |                       \
+	BIT(POWER_DOMAIN_AUX_D) |                       \
+	BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) |          \
+	BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |          \
+	BIT(POWER_DOMAIN_AUDIO) |                       \
+	BIT(POWER_DOMAIN_INIT))
 #define SKL_DISPLAY_ALWAYS_ON_POWER_DOMAINS (           \
 	(POWER_DOMAIN_MASK & ~(SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS |  \
 	SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS |         \
@@ -7241,6 +7256,7 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv,
 	case SKL_DISP_PW_DDI_B:
 	case SKL_DISP_PW_DDI_C:
 	case SKL_DISP_PW_DDI_D:
+	case SKL_DISP_PW_MISC_IO:
 		break;
 	default:
 		return;
@@ -8211,6 +8227,12 @@ static struct i915_power_well skl_power_wells[] = {
 		.ops = &skl_power_well_ops,
 		.data = SKL_DISP_PW_DDI_D,
 	},
+	{
+		.name = "MISC IO power well",
+		.domains = SKL_DISPLAY_MISC_IO_POWER_DOMAINS,
+		.ops = &skl_power_well_ops,
+		.data = SKL_DISP_PW_MISC_IO,
+	}
 };
 
 #define set_power_wells(power_domains, __power_wells) ({		\
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 74/89] drm/i915/skl: Implement queue_flip
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (72 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 73/89] drm/i915/skl: Enabling MISC IO power well Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-23 20:06   ` Paulo Zanoni
  2014-09-04 11:27 ` [PATCH 75/89] drm/i915/skl: fetch, enable/disable pfit as needed Damien Lespiau
                   ` (15 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

A few bits have changed in MI_DISPLAY_FLIP to accomodate the new planes.
DE_RRMR seems to have kept its plane flip bits backward compatible.

v2: Rebase on top of nightly
v2: Rebase on top of nightly (minor conflict in i915_reg.h)

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h      | 10 +++++
 drivers/gpu/drm/i915/intel_display.c | 78 ++++++++++++++++++++++++++++++++++++
 2 files changed, 88 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 84a0de6..176e84e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -240,6 +240,16 @@
 #define   MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19)
 #define   MI_DISPLAY_FLIP_IVB_PLANE_C  (4 << 19)
 #define   MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19)
+/* SKL ones */
+#define   MI_DISPLAY_FLIP_SKL_PLANE_1_A	(0 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_1_B	(1 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_1_C	(2 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_2_A	(4 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_2_B	(5 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_2_C	(6 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_3_A	(7 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_3_B	(8 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_3_C	(9 << 8)
 #define MI_SEMAPHORE_MBOX	MI_INSTR(0x16, 1) /* gen6, gen7 */
 #define   MI_SEMAPHORE_GLOBAL_GTT    (1<<22)
 #define   MI_SEMAPHORE_UPDATE	    (1<<21)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index abd4201..393bd19 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9913,6 +9913,81 @@ static int intel_queue_mmio_flip(struct drm_device *dev,
 	return 0;
 }
 
+static int intel_gen9_queue_flip(struct drm_device *dev,
+				 struct drm_crtc *crtc,
+				 struct drm_framebuffer *fb,
+				 struct drm_i915_gem_object *obj,
+				 struct intel_engine_cs *ring,
+				 uint32_t flags)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	uint32_t plane = 0, stride;
+	int ret;
+
+	ring = obj->ring;
+	if (ring == NULL || ring->id != BCS)
+		ring = &dev_priv->ring[RCS];
+
+	ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
+	if (ret)
+		goto err;
+
+	switch(intel_crtc->pipe) {
+	case PIPE_A:
+		plane = MI_DISPLAY_FLIP_SKL_PLANE_1_A;
+		break;
+	case PIPE_B:
+		plane = MI_DISPLAY_FLIP_SKL_PLANE_1_B;
+		break;
+	case PIPE_C:
+		plane = MI_DISPLAY_FLIP_SKL_PLANE_1_C;
+		break;
+	default:
+		BUG();
+	}
+
+	switch (obj->tiling_mode) {
+	case I915_TILING_NONE:
+		stride = fb->pitches[0] >> 6;
+		break;
+	case I915_TILING_X:
+		stride = fb->pitches[0] >> 9;
+		break;
+	default:
+		BUG();
+	}
+
+	ret = intel_ring_begin(ring, 10);
+	if (ret)
+		goto err_unpin;
+
+	intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
+	intel_ring_emit(ring, DERRMR);
+	intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE |
+				DERRMR_PIPEB_PRI_FLIP_DONE |
+				DERRMR_PIPEC_PRI_FLIP_DONE));
+	intel_ring_emit(ring, MI_STORE_REGISTER_MEM_GEN8(1) |
+			      MI_SRM_LRM_GLOBAL_GTT);
+	intel_ring_emit(ring, DERRMR);
+	intel_ring_emit(ring, ring->scratch.gtt_offset + 256);
+	intel_ring_emit(ring, 0);
+
+	intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane);
+	intel_ring_emit(ring, stride << 6 | obj->tiling_mode);
+	intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj));
+
+	intel_mark_page_flip_active(intel_crtc);
+	__intel_ring_advance(ring);
+
+	return 0;
+
+err_unpin:
+	intel_unpin_fb_obj(obj);
+err:
+	return ret;
+}
+
 static int intel_default_queue_flip(struct drm_device *dev,
 				    struct drm_crtc *crtc,
 				    struct drm_framebuffer *fb,
@@ -12740,6 +12815,9 @@ static void intel_init_display(struct drm_device *dev)
 	case 8: /* FIXME(BDW): Check that the gen8 RCS flip works. */
 		dev_priv->display.queue_flip = intel_gen7_queue_flip;
 		break;
+	case 9:
+		dev_priv->display.queue_flip = intel_gen9_queue_flip;
+		break;
 	}
 
 	intel_panel_init_backlight_funcs(dev);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 75/89] drm/i915/skl: fetch, enable/disable pfit as needed
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (73 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 74/89] drm/i915/skl: Implement queue_flip Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-23 20:50   ` Paulo Zanoni
  2014-09-25 17:58   ` [PATCH] drm/i915/skl: fetch, enable/disable pfit as needed v2 Jesse Barnes
  2014-09-04 11:27 ` [PATCH 76/89] drm/i915/skl: Store the new WM state at the very end of the update Damien Lespiau
                   ` (14 subsequent siblings)
  89 siblings, 2 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Jesse Barnes <jbarnes@virtuousgeek.org>

This moved around on SKL, so we need to make sure we read/write the
correct regs.

Signed-off-by: Jesse Barnes <jbarnes@virtuougseek.org>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h      | 13 ++++++++
 drivers/gpu/drm/i915/intel_display.c | 61 +++++++++++++++++++++++++++++++++---
 2 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 176e84e..35c0759 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4833,6 +4833,19 @@ enum skl_disp_power_wells {
 #define PF_VSCALE(pipe)		_PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE)
 #define PF_HSCALE(pipe)		_PIPE(pipe, _PFA_HSCALE, _PFB_HSCALE)
 
+#define _PSA_CTL		0x68180
+#define _PSB_CTL		0x68980
+#define PS_ENABLE		(1<<31)
+#define PS_PIPE_SEL(pipe)	((pipe)<<27)
+#define _PSA_WIN_SZ		0x68174
+#define _PSB_WIN_SZ		0x68974
+#define _PSA_WIN_POS		0x68178
+#define _PSB_WIN_POS		0x68978
+
+#define PS_CTL(pipe)		_PIPE(pipe, _PSA_CTL, _PSB_CTL)
+#define PS_WIN_SZ(pipe)		_PIPE(pipe, _PSA_WIN_SZ, _PSB_WIN_SZ)
+#define PS_WIN_POS(pipe)	_PIPE(pipe, _PSA_WIN_POS, _PSB_WIN_POS)
+
 /* legacy palette */
 #define _LGC_PALETTE_A           0x4a000
 #define _LGC_PALETTE_B           0x4a800
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 393bd19..9b31342 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3882,6 +3882,19 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe)
 	}
 }
 
+static void skylake_pfit_enable(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = crtc->pipe;
+
+	if (crtc->config.pch_pfit.enabled) {
+		I915_WRITE(PS_CTL(pipe), PS_ENABLE);
+		I915_WRITE(PS_WIN_POS(pipe), crtc->config.pch_pfit.pos);
+		I915_WRITE(PS_WIN_SZ(pipe), crtc->config.pch_pfit.size);
+	}
+}
+
 static void ironlake_pfit_enable(struct intel_crtc *crtc)
 {
 	struct drm_device *dev = crtc->base.dev;
@@ -4264,7 +4277,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 
 	intel_ddi_enable_pipe_clock(intel_crtc);
 
-	ironlake_pfit_enable(intel_crtc);
+	if (IS_SKYLAKE(dev))
+		skylake_pfit_enable(intel_crtc);
+	else
+		ironlake_pfit_enable(intel_crtc);
 
 	/*
 	 * On ILK+ LUT must be loaded before the pipe is running but with
@@ -4295,6 +4311,20 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	intel_crtc_enable_planes(crtc);
 }
 
+static void skylake_pfit_disable(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = crtc->pipe;
+
+	/* To avoid upsetting the power well on haswell only disable the pfit if
+	 * it's in use. The hw state code will make sure we get this right. */
+	if (crtc->config.pch_pfit.enabled) {
+		I915_WRITE(PS_CTL(pipe), 0);
+		I915_WRITE(PS_WIN_SZ(pipe), 0);
+	}
+}
+
 static void ironlake_pfit_disable(struct intel_crtc *crtc)
 {
 	struct drm_device *dev = crtc->base.dev;
@@ -4399,7 +4429,10 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
 
 	intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
 
-	ironlake_pfit_disable(intel_crtc);
+	if (IS_SKYLAKE(dev))
+		skylake_pfit_disable(intel_crtc);
+	else
+		ironlake_pfit_disable(intel_crtc);
 
 	intel_ddi_disable_pipe_clock(intel_crtc);
 
@@ -7382,6 +7415,22 @@ static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
 				     &pipe_config->fdi_m_n, NULL);
 }
 
+static void skylake_get_pfit_config(struct intel_crtc *crtc,
+				    struct intel_crtc_config *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t tmp;
+
+	tmp = I915_READ(PS_CTL(crtc->pipe));
+
+	if (tmp & PS_ENABLE) {
+		pipe_config->pch_pfit.enabled = true;
+		pipe_config->pch_pfit.pos = I915_READ(PS_WIN_POS(crtc->pipe));
+		pipe_config->pch_pfit.size = I915_READ(PS_WIN_SZ(crtc->pipe));
+	}
+}
+
 static void ironlake_get_pfit_config(struct intel_crtc *crtc,
 				     struct intel_crtc_config *pipe_config)
 {
@@ -7940,8 +7989,12 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 	intel_get_pipe_timings(crtc, pipe_config);
 
 	pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
-	if (intel_display_power_enabled(dev_priv, pfit_domain))
-		ironlake_get_pfit_config(crtc, pipe_config);
+	if (intel_display_power_enabled(dev_priv, pfit_domain)) {
+		if (IS_SKYLAKE(dev))
+			skylake_get_pfit_config(crtc, pipe_config);
+		else
+			ironlake_get_pfit_config(crtc, pipe_config);
+	}
 
 	if (IS_HASWELL(dev))
 		pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) &&
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 76/89] drm/i915/skl: Store the new WM state at the very end of the update
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (74 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 75/89] drm/i915/skl: fetch, enable/disable pfit as needed Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-10-29 19:19   ` Ville Syrjälä
  2014-09-04 11:27 ` [PATCH 77/89] drm/i915: Introduce a for_each_plane() macro Damien Lespiau
                   ` (13 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

We're going to add a new step, let's not hide the copy of the new WM
state inside one inner function, but as a 1st level operation in the WM
update.

v2: Split the staging results structure to not exceed the 1Kb stack
    allocation in skl_update_wm()

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 5425d85..7f7a2e2 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3432,8 +3432,6 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
 				   new->ddb.cursor[pipe].start);
 		}
 	}
-
-	dev_priv->wm.skl_hw = *new;
 }
 
 static bool skl_update_pipe_wm(struct drm_crtc *crtc,
@@ -3527,6 +3525,9 @@ static void skl_update_wm(struct drm_crtc *crtc)
 
 	skl_update_other_pipe_wm(dev, crtc, &config, results);
 	skl_write_wm_values(dev_priv, results);
+
+	/* store the new configuration */
+	dev_priv->wm.skl_hw = *results;
 }
 
 static void
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 77/89] drm/i915: Introduce a for_each_plane() macro
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (75 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 76/89] drm/i915/skl: Store the new WM state at the very end of the update Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-04 13:26   ` Daniel Vetter
  2014-09-04 13:32   ` Chris Wilson
  2014-09-04 11:27 ` [PATCH 78/89] drm/i915/skl: Flush the WM configuration Damien Lespiau
                   ` (12 subsequent siblings)
  89 siblings, 2 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

Tired of copy/pasting things around.

v2: Rebase on top of the for_each_pipe() change adding dev_priv as first
    argument.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 91ea2b7..95e57dc 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -176,6 +176,8 @@ enum hpd_pin {
 
 #define for_each_pipe(__dev_priv, __p) \
 	for ((__p) = 0; (__p) < INTEL_INFO(__dev_priv)->num_pipes; (__p)++)
+#define for_each_plane(pipe, p) \
+	for ((p) = 0; (p) < INTEL_INFO(dev)->num_sprites[(pipe)] + 1; (p)++)
 #define for_each_sprite(p, s) for ((s) = 0; (s) < INTEL_INFO(dev)->num_sprites[(p)]; (s)++)
 
 #define for_each_crtc(dev, crtc) \
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 78/89] drm/i915/skl: Flush the WM configuration
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (76 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 77/89] drm/i915: Introduce a for_each_plane() macro Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-19 10:46   ` Ville Syrjälä
  2014-09-04 11:27 ` [PATCH 79/89] drm/i915/skl: Read back the DDB allocation hw state Damien Lespiau
                   ` (11 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

When we write new values for the DDB allocation and WM parameters, we now
need to trigger the double buffer update for the pipe to take the new
configuration into account.

As the DDB is a global resource shared between planes, enabling or
disabling one plane will result in changes for all planes that are
currently in use, thus the need write PLANE_SURF/CUR_BASE for more than
the plane we're touching.

v2: Don't wait for pipes that are off

v3: Split the staging results structure to not exceed the 1Kb stack
    allocation in skl_update_wm()

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 92 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 7f7a2e2..d378879 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3198,6 +3198,22 @@ static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
 	return false;
 }
 
+static unsigned int
+skl_ddb_pipe_allocation_size(const struct skl_ddb_allocation *ddb,
+			     const struct intel_crtc *intel_crtc)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	unsigned int size = 0;
+	enum pipe pipe = intel_crtc->pipe;
+	int plane;
+
+	for_each_plane(pipe, plane)
+		size += skl_ddb_entry_size(&ddb->plane[pipe][plane]);
+	size += skl_ddb_entry_size(&ddb->cursor[pipe]);
+
+	return size;
+}
+
 static void skl_compute_wm_global_parameters(struct drm_device *dev,
 					     struct intel_wm_config *config)
 {
@@ -3434,6 +3450,81 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
 	}
 }
 
+static void skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
+{
+	struct drm_device *dev = dev_priv->dev;
+	int plane;
+
+	for_each_plane(pipe, plane) {
+		I915_WRITE(PLANE_SURF(pipe, plane),
+			   I915_READ(PLANE_SURF(pipe, plane)));
+	}
+	I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe)));
+}
+
+static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
+				struct skl_wm_values *new_values)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct skl_ddb_allocation *cur_ddb, *new_ddb;
+	unsigned int cur_size[I915_MAX_PIPES], new_size[I915_MAX_PIPES];
+	struct intel_crtc *crtc;
+	enum pipe pipe;
+
+	new_ddb = &new_values->ddb;
+	cur_ddb = &dev_priv->wm.skl_hw.ddb;
+
+	/*
+	 * Start by computing the total allocated space for each pipe as we
+	 * need that values for the two passes.
+	 */
+	for_each_intel_crtc(dev, crtc) {
+		pipe = crtc->pipe;
+		new_size[pipe] = skl_ddb_pipe_allocation_size(new_ddb, crtc);
+		cur_size[pipe] = skl_ddb_pipe_allocation_size(cur_ddb, crtc);
+	}
+
+	/*
+	 * First pass: we flush the pipes that had their allocation reduced.
+	 *
+	 * We then have to wait until the pipe stops fetching pixels from the
+	 * previous allocation. This way, pipes that have just been allocated
+	 * more space won't try to fetch pixels belonging to a different pipe.
+	 */
+	for_each_intel_crtc(dev, crtc) {
+		if (!crtc->active)
+			continue;
+
+		pipe = crtc->pipe;
+
+		if (new_size[pipe] < cur_size[pipe]) {
+			skl_wm_flush_pipe(dev_priv, pipe);
+			intel_wait_for_vblank(dev, pipe);
+		}
+	}
+
+	/*
+	 * Second pass: flush the pipes that got more allocated space.
+	 *
+	 * We don't need to actively wait for the update here, next vblank
+	 * will just get more DDB space with the correct WM values.
+	 */
+	for_each_intel_crtc(dev, crtc) {
+		if (!crtc->active)
+			continue;
+
+		pipe = crtc->pipe;
+
+		if (new_size[pipe] < cur_size[pipe])
+			continue;
+
+		if (!skl_ddb_allocation_changed(new_ddb, crtc))
+			continue;
+
+		skl_wm_flush_pipe(dev_priv, pipe);
+	}
+}
+
 static bool skl_update_pipe_wm(struct drm_crtc *crtc,
 			       struct skl_pipe_wm_parameters *params,
 			       struct intel_wm_config *config,
@@ -3525,6 +3616,7 @@ static void skl_update_wm(struct drm_crtc *crtc)
 
 	skl_update_other_pipe_wm(dev, crtc, &config, results);
 	skl_write_wm_values(dev_priv, results);
+	skl_flush_wm_values(dev_priv, results);
 
 	/* store the new configuration */
 	dev_priv->wm.skl_hw = *results;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 79/89] drm/i915/skl: Read back the DDB allocation hw state
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (77 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 78/89] drm/i915/skl: Flush the WM configuration Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-19 10:54   ` Ville Syrjälä
  2014-09-04 11:27 ` [PATCH 80/89] drm/i915/skl: Augment the latency debugfs files for SKL Damien Lespiau
                   ` (10 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

This logically belongs to the WM state, so do it there.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d378879..8d24a4d 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3020,6 +3020,32 @@ static unsigned int skl_cursor_allocation(struct intel_wm_config *config)
 	return 8;
 }
 
+static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg)
+{
+	entry->start = reg & 0x3ff;
+	entry->end = (reg >> 16) & 0x3ff;
+}
+
+static void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
+				 struct skl_ddb_allocation *ddb /* out */)
+{
+	struct drm_device *dev = dev_priv->dev;
+	enum pipe pipe;
+	int plane;
+	u32 val;
+
+	for_each_pipe(dev_priv, pipe) {
+		for_each_plane(pipe, plane) {
+			val = I915_READ(PLANE_BUF_CFG(pipe, plane));
+			skl_ddb_entry_init_from_hw(&ddb->plane[pipe][plane],
+						   val);
+		}
+
+		val = I915_READ(CUR_BUF_CFG(pipe));
+		skl_ddb_entry_init_from_hw(&ddb->cursor[pipe], val);
+	}
+}
+
 static unsigned int
 skl_plane_relative_data_rate(struct intel_plane_wm_parameters *p)
 {
@@ -3810,8 +3836,11 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 
 void skl_wm_get_hw_state(struct drm_device *dev)
 {
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct skl_ddb_allocation *ddb = &dev_priv->wm.skl_hw.ddb;
 	struct drm_crtc *crtc;
 
+	skl_ddb_get_hw_state(dev_priv, ddb);
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
 		skl_pipe_wm_get_hw_state(crtc);
 }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 80/89] drm/i915/skl: Augment the latency debugfs files for SKL
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (78 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 79/89] drm/i915/skl: Read back the DDB allocation hw state Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-19 10:53   ` Ville Syrjälä
  2014-09-04 11:27 ` [PATCH 81/89] drm/i915/skl: Expose skl_ddb_get_hw_state() Damien Lespiau
                   ` (9 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 76 ++++++++++++++++++++++++++++++-------
 1 file changed, 62 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 02cb310..1520d1f 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3499,7 +3499,7 @@ static const struct file_operations i915_display_crc_ctl_fops = {
 	.write = display_crc_ctl_write
 };
 
-static void wm_latency_show(struct seq_file *m, const uint16_t wm[5])
+static void wm_latency_show(struct seq_file *m, const uint16_t wm[8])
 {
 	struct drm_device *dev = m->private;
 	int num_levels = ilk_wm_max_level(dev) + 1;
@@ -3510,13 +3510,17 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[5])
 	for (level = 0; level < num_levels; level++) {
 		unsigned int latency = wm[level];
 
-		/* WM1+ latency values in 0.5us units */
-		if (level > 0)
+		/*
+		 * - WM1+ latency values in 0.5us units
+		 * - latencies are in us on gen9
+		 */
+		if (IS_GEN9(dev))
+			latency *= 10;
+		else if (level > 0)
 			latency *= 5;
 
 		seq_printf(m, "WM%d %u (%u.%u usec)\n",
-			   level, wm[level],
-			   latency / 10, latency % 10);
+			   level, wm[level], latency / 10, latency % 10);
 	}
 
 	drm_modeset_unlock_all(dev);
@@ -3525,8 +3529,15 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[5])
 static int pri_wm_latency_show(struct seq_file *m, void *data)
 {
 	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const uint16_t *latencies;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.pri_latency;
 
-	wm_latency_show(m, to_i915(dev)->wm.pri_latency);
+	wm_latency_show(m, latencies);
 
 	return 0;
 }
@@ -3534,8 +3545,15 @@ static int pri_wm_latency_show(struct seq_file *m, void *data)
 static int spr_wm_latency_show(struct seq_file *m, void *data)
 {
 	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const uint16_t *latencies;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.spr_latency;
 
-	wm_latency_show(m, to_i915(dev)->wm.spr_latency);
+	wm_latency_show(m, latencies);
 
 	return 0;
 }
@@ -3543,8 +3561,15 @@ static int spr_wm_latency_show(struct seq_file *m, void *data)
 static int cur_wm_latency_show(struct seq_file *m, void *data)
 {
 	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const uint16_t *latencies;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.cur_latency;
 
-	wm_latency_show(m, to_i915(dev)->wm.cur_latency);
+	wm_latency_show(m, latencies);
 
 	return 0;
 }
@@ -3580,11 +3605,11 @@ static int cur_wm_latency_open(struct inode *inode, struct file *file)
 }
 
 static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
-				size_t len, loff_t *offp, uint16_t wm[5])
+				size_t len, loff_t *offp, uint16_t wm[8])
 {
 	struct seq_file *m = file->private_data;
 	struct drm_device *dev = m->private;
-	uint16_t new[5] = { 0 };
+	uint16_t new[8] = { 0 };
 	int num_levels = ilk_wm_max_level(dev) + 1;
 	int level;
 	int ret;
@@ -3598,7 +3623,9 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
 
 	tmp[len] = '\0';
 
-	ret = sscanf(tmp, "%hu %hu %hu %hu %hu", &new[0], &new[1], &new[2], &new[3], &new[4]);
+	ret = sscanf(tmp, "%hu %hu %hu %hu %hu %hu %hu %hu",
+		     &new[0], &new[1], &new[2], &new[3],
+		     &new[4], &new[5], &new[6], &new[7]);
 	if (ret != num_levels)
 		return -EINVAL;
 
@@ -3618,8 +3645,15 @@ static ssize_t pri_wm_latency_write(struct file *file, const char __user *ubuf,
 {
 	struct seq_file *m = file->private_data;
 	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint16_t *latencies;
 
-	return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.pri_latency);
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.pri_latency;
+
+	return wm_latency_write(file, ubuf, len, offp, latencies);
 }
 
 static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf,
@@ -3627,8 +3661,15 @@ static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf,
 {
 	struct seq_file *m = file->private_data;
 	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint16_t *latencies;
 
-	return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.spr_latency);
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.spr_latency;
+
+	return wm_latency_write(file, ubuf, len, offp, latencies);
 }
 
 static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
@@ -3636,8 +3677,15 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
 {
 	struct seq_file *m = file->private_data;
 	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint16_t *latencies;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.cur_latency;
 
-	return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.cur_latency);
+	return wm_latency_write(file, ubuf, len, offp, latencies);
 }
 
 static const struct file_operations i915_pri_wm_latency_fops = {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 81/89] drm/i915/skl: Expose skl_ddb_get_hw_state()
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (79 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 80/89] drm/i915/skl: Augment the latency debugfs files for SKL Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-10-29 19:21   ` Ville Syrjälä
  2014-09-04 11:27 ` [PATCH 82/89] drm/i915/skl: Add a debugfs file to dump the DDB allocation Damien Lespiau
                   ` (8 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

So we can use it in the modeset checker.

v2: Rebase on top of nigthly

v3: Rebase on top of -nigthly (minor conflict in intel_drv.h)

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h | 2 ++
 drivers/gpu/drm/i915/intel_pm.c  | 4 ++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a407d04..782dfbc 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1108,6 +1108,8 @@ void intel_init_runtime_pm(struct drm_i915_private *dev_priv);
 void intel_fini_runtime_pm(struct drm_i915_private *dev_priv);
 void ilk_wm_get_hw_state(struct drm_device *dev);
 void skl_wm_get_hw_state(struct drm_device *dev);
+void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
+			  struct skl_ddb_allocation *ddb /* out */);
 
 
 /* intel_sdvo.c */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 8d24a4d..ff0d8cb 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3026,8 +3026,8 @@ static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg)
 	entry->end = (reg >> 16) & 0x3ff;
 }
 
-static void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
-				 struct skl_ddb_allocation *ddb /* out */)
+void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
+			  struct skl_ddb_allocation *ddb /* out */)
 {
 	struct drm_device *dev = dev_priv->dev;
 	enum pipe pipe;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 82/89] drm/i915/skl: Add a debugfs file to dump the DDB allocation
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (80 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 81/89] drm/i915/skl: Expose skl_ddb_get_hw_state() Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-10-29 19:23   ` Ville Syrjälä
  2014-09-04 11:27 ` [PATCH 83/89] drm/i915/skl: Check the DDB state at modeset Damien Lespiau
                   ` (7 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

v2: minor conflict in i915_debugfs.c
v3: Rebase on top of the for_each_pipe() change adding dev_priv as first
    argument.
v4: minor conflict in the i915_debugfs_files array
v5: minor conflict in the i915_debugfs_files array

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 1520d1f..0468ec9 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2669,6 +2669,42 @@ static int i915_wa_registers(struct seq_file *m, void *unused)
 	return 0;
 }
 
+static int i915_ddb_info(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct skl_ddb_allocation *ddb;
+	struct skl_ddb_entry *entry;
+	enum pipe pipe;
+	int plane;
+
+	drm_modeset_lock_all(dev);
+
+	ddb = &dev_priv->wm.skl_hw.ddb;
+
+	seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
+
+	for_each_pipe(dev_priv, pipe) {
+		seq_printf(m, "Pipe %c\n", pipe_name(pipe));
+
+		for_each_plane(pipe, plane) {
+			entry = &ddb->plane[pipe][plane];
+			seq_printf(m, "  Plane%-8d%8u%8u%8u\n", plane + 1,
+				   entry->start, entry->end,
+				   skl_ddb_entry_size(entry));
+		}
+
+		entry = &ddb->cursor[pipe];
+		seq_printf(m, "  %-13s%8u%8u%8u\n", "Cursor", entry->start,
+			   entry->end, skl_ddb_entry_size(entry));
+	}
+
+	drm_modeset_unlock_all(dev);
+
+	return 0;
+}
+
 struct pipe_crc_info {
 	const char *name;
 	struct drm_device *dev;
@@ -4249,6 +4285,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
 	{"i915_shared_dplls_info", i915_shared_dplls_info, 0},
 	{"i915_dp_mst_info", i915_dp_mst_info, 0},
 	{"i915_wa_registers", i915_wa_registers, 0},
+	{"i915_ddb_info", i915_ddb_info, 0},
 };
 #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 83/89] drm/i915/skl: Check the DDB state at modeset
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (81 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 82/89] drm/i915/skl: Add a debugfs file to dump the DDB allocation Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-04 13:27   ` Daniel Vetter
  2014-09-04 11:27 ` [PATCH 84/89] drm/i915/skl: add turbo support Damien Lespiau
                   ` (6 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

v2: Don't check DDB on pre-SKL platforms
    Don't check DDB state on disabled pipes

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  9 +++++++
 drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 95e57dc..0baf7f3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1424,6 +1424,15 @@ static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry)
 	return entry->end - entry->start + 1;
 }
 
+static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
+				       const struct skl_ddb_entry *e2)
+{
+	if (e1->start == e2->start && e1->end == e2->end)
+		return true;
+
+	return false;
+}
+
 struct skl_ddb_allocation {
 	struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
 	struct skl_ddb_entry cursor[I915_MAX_PIPES];
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9b31342..35d3389 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10944,6 +10944,56 @@ intel_pipe_config_compare(struct drm_device *dev,
 	return true;
 }
 
+static void check_wm_state(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct skl_ddb_allocation hw_ddb, *sw_ddb;
+	struct intel_crtc *intel_crtc;
+	int plane;
+
+	if (INTEL_INFO(dev)->gen < 9)
+		return;
+
+	skl_ddb_get_hw_state(dev_priv, &hw_ddb);
+	sw_ddb = &dev_priv->wm.skl_hw.ddb;
+
+	for_each_intel_crtc(dev, intel_crtc) {
+		struct skl_ddb_entry *hw_entry, *sw_entry;
+		const enum pipe pipe = intel_crtc->pipe;
+
+		if (!intel_crtc->active)
+			continue;
+
+		/* planes */
+		for_each_plane(pipe, plane) {
+			hw_entry = &hw_ddb.plane[pipe][plane];
+			sw_entry = &sw_ddb->plane[pipe][plane];
+
+			if (skl_ddb_entry_equal(hw_entry, sw_entry))
+				continue;
+
+			DRM_ERROR("mismatch in DDB state pipe %c plane %d "
+				  "(expected (%u,%u), found (%u,%u))\n",
+				  pipe_name(pipe), plane + 1,
+				  sw_entry->start, sw_entry->end,
+				  hw_entry->start, hw_entry->end);
+		}
+
+		/* cursor */
+		hw_entry = &hw_ddb.cursor[pipe];
+		sw_entry = &sw_ddb->cursor[pipe];
+
+		if (skl_ddb_entry_equal(hw_entry, sw_entry))
+			continue;
+
+		DRM_ERROR("mismatch in DDB state pipe %c cursor "
+			  "(expected (%u,%u), found (%u,%u))\n",
+			  pipe_name(pipe),
+			  sw_entry->start, sw_entry->end,
+			  hw_entry->start, hw_entry->end);
+	}
+}
+
 static void
 check_connector_state(struct drm_device *dev)
 {
@@ -11143,6 +11193,7 @@ check_shared_dpll_state(struct drm_device *dev)
 void
 intel_modeset_check_state(struct drm_device *dev)
 {
+	check_wm_state(dev);
 	check_connector_state(dev);
 	check_encoder_state(dev);
 	check_crtc_state(dev);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 84/89] drm/i915/skl: add turbo support
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (82 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 83/89] drm/i915/skl: Check the DDB state at modeset Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-26 14:55   ` Mika Kuoppala
  2014-09-04 11:27 ` [PATCH 85/89] drm/i915/skl: Retrieve the frequency limits Damien Lespiau
                   ` (5 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Jesse Barnes <jbarnes@virtuousgeek.org>

Per latest PM programming guide.

v2: the wrong flavour of the function updating the ring frequency was
    called, leading to dead locks (Tvrtko)

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index ff0d8cb..9e9377a 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4708,9 +4708,36 @@ void bdw_software_turbo(struct drm_device *dev)
 			&current_time, &current_c0);
 }
 
+/* See the Gen9_GT_PM_Programming_Guide doc for the below */
 static void gen9_enable_rps(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+
+	I915_WRITE(GEN6_RPNSWREQ, 0xc800000);
+	I915_WRITE(GEN6_RC_VIDEO_FREQ, 0xc800000);
+
+	I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 0xf4240);
+	I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, 0x12060000);
+	I915_WRITE(GEN6_RP_UP_THRESHOLD, 0xe808);
+	I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 0x3bd08);
+	I915_WRITE(GEN6_RP_UP_EI, 0x101d0);
+	I915_WRITE(GEN6_RP_DOWN_EI, 0x55730);
+	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 0xa);
+	I915_WRITE(GEN6_PMINTRMSK, 0x6);
+	I915_WRITE(GEN6_RP_CONTROL, GEN6_RP_MEDIA_TURBO |
+		   GEN6_RP_MEDIA_HW_MODE | GEN6_RP_ENABLE |
+		   GEN6_RP_UP_BUSY_AVG | GEN6_RP_DOWN_IDLE_AVG);
+
+	gen8_enable_rps_interrupts(dev);
+
+	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+}
+
+static void gen9_enable_rc6(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_engine_cs *ring;
 	uint32_t rc6_mask = 0;
 	int unused;
@@ -6355,7 +6382,9 @@ static void intel_gen6_powersave_work(struct work_struct *work)
 	} else if (IS_VALLEYVIEW(dev)) {
 		valleyview_enable_rps(dev);
 	} else if (INTEL_INFO(dev)->gen >= 9) {
+		gen9_enable_rc6(dev);
 		gen9_enable_rps(dev);
+		__gen6_update_ring_freq(dev);
 	} else if (IS_BROADWELL(dev)) {
 		gen8_enable_rps(dev);
 		__gen6_update_ring_freq(dev);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 85/89] drm/i915/skl: Retrieve the frequency limits
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (83 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 84/89] drm/i915/skl: add turbo support Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-26 15:09   ` Mika Kuoppala
  2014-09-04 11:27 ` [PATCH 86/89] drm/i915: only reset media, blt, and render engines on GPU hangs Damien Lespiau
                   ` (4 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 9e9377a..77e1d52 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4712,9 +4712,13 @@ void bdw_software_turbo(struct drm_device *dev)
 static void gen9_enable_rps(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 rp_state_cap;
 
 	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
 
+	rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
+	parse_rp_state_cap(dev_priv, rp_state_cap);
+
 	I915_WRITE(GEN6_RPNSWREQ, 0xc800000);
 	I915_WRITE(GEN6_RC_VIDEO_FREQ, 0xc800000);
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 86/89] drm/i915: only reset media, blt, and render engines on GPU hangs
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (84 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 85/89] drm/i915/skl: Retrieve the frequency limits Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-04 12:03   ` Jani Nikula
  2014-09-04 12:36   ` Mika Kuoppala
  2014-09-04 11:27 ` [PATCH 87/89] drm/i915/skl: AUX irqs have moved Damien Lespiau
                   ` (3 subsequent siblings)
  89 siblings, 2 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Jesse Barnes <jbarnes@virtuousgeek.org>

No need to mess with display.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_uncore.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index ce1214b..29aa63e 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -1472,7 +1472,8 @@ static int gen6_do_reset(struct drm_device *dev)
 	 * for fifo space for the write or forcewake the chip for
 	 * the read
 	 */
-	__raw_i915_write32(dev_priv, GEN6_GDRST, GEN6_GRDOM_FULL);
+	__raw_i915_write32(dev_priv, GEN6_GDRST, GEN6_GRDOM_MEDIA |
+			   GEN6_GRDOM_BLT | GEN6_GRDOM_RENDER);
 
 	/* Spin waiting for the device to ack the reset request */
 	ret = wait_for((__raw_i915_read32(dev_priv, GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 87/89] drm/i915/skl: AUX irqs have moved
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (85 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 86/89] drm/i915: only reset media, blt, and render engines on GPU hangs Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-26 15:21   ` Mika Kuoppala
  2014-09-04 11:27 ` [PATCH 88/89] drm/i915/skl: Add Gen9 LRC size Damien Lespiau
                   ` (2 subsequent siblings)
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: Jesse Barnes <jbarnes@virtuousgeek.org>

Use the new AUX port irq bits where needed.

v2: Rebase on top of upstream changes
v3: Rebase on top of Oscar change to write IIR as soon as possible (Damien)
v4: Rebase on top of the for_each_pipe() change adding dev_priv as first
    argument (Damien)

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 17 +++++++++++++----
 drivers/gpu/drm/i915/i915_reg.h |  3 +++
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 734b73e..8c7fbfb 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2542,6 +2542,11 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
 	irqreturn_t ret = IRQ_NONE;
 	uint32_t tmp = 0;
 	enum pipe pipe;
+	u32 aux_mask = GEN8_AUX_CHANNEL_A;
+
+	if (IS_GEN9(dev))
+		aux_mask |=  GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
+			GEN9_AUX_CHANNEL_D;
 
 	master_ctl = I915_READ(GEN8_MASTER_IRQ);
 	master_ctl &= ~GEN8_MASTER_IRQ_CONTROL;
@@ -2574,7 +2579,8 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
 		if (tmp) {
 			I915_WRITE(GEN8_DE_PORT_IIR, tmp);
 			ret = IRQ_HANDLED;
-			if (tmp & GEN8_AUX_CHANNEL_A)
+
+			if (tmp & aux_mask)
 				dp_aux_irq_handler(dev);
 			else
 				DRM_ERROR("Unexpected DE Port interrupt\n");
@@ -3859,11 +3865,14 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
 	uint32_t de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE;
 	uint32_t de_pipe_enables;
 	int pipe;
+	u32 aux_en = GEN8_AUX_CHANNEL_A;
 
-	if (IS_GEN9(dev_priv))
+	if (IS_GEN9(dev_priv)) {
 		de_pipe_masked |= GEN9_PIPE_PLANE1_FLIP_DONE |
 				  GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
-	else
+		aux_en |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
+			GEN9_AUX_CHANNEL_D;
+	} else
 		de_pipe_masked |= GEN8_PIPE_PRIMARY_FLIP_DONE |
 				  GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
 
@@ -3881,7 +3890,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
 					  dev_priv->de_irq_mask[pipe],
 					  de_pipe_enables);
 
-	GEN5_IRQ_INIT(GEN8_DE_PORT_, ~GEN8_AUX_CHANNEL_A, GEN8_AUX_CHANNEL_A);
+	GEN5_IRQ_INIT(GEN8_DE_PORT_, ~aux_en, aux_en);
 }
 
 static int gen8_irq_postinstall(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 35c0759..217001d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4990,6 +4990,9 @@ enum skl_disp_power_wells {
 #define GEN8_DE_PORT_IIR 0x44448
 #define GEN8_DE_PORT_IER 0x4444c
 #define  GEN8_PORT_DP_A_HOTPLUG		(1 << 3)
+#define  GEN9_AUX_CHANNEL_D		(1 << 27)
+#define  GEN9_AUX_CHANNEL_C		(1 << 26)
+#define  GEN9_AUX_CHANNEL_B		(1 << 25)
 #define  GEN8_AUX_CHANNEL_A		(1 << 0)
 
 #define GEN8_DE_MISC_ISR 0x44460
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 88/89] drm/i915/skl: Add Gen9 LRC size
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (86 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 87/89] drm/i915/skl: AUX irqs have moved Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-04 11:27 ` [PATCH 89/89] drm/i915/skl: Disable contexts if execlists aren't enabled Damien Lespiau
  2014-09-04 14:16 ` [PATCH 00/89] Basic Skylake enabling (reviewers) Damien Lespiau
  89 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

From: "Michael H. Nguyen" <michael.h.nguyen@intel.com>

The LRC increased in size on gen9. Make sure we return the right
size in get_lr_context_size()

v2. Corrected the size, should be 22 pages. I unintentionally mailed out
a test patch w/ size equaling 23 pages.

Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Michael H. Nguyen <michael.h.nguyen@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_lrc.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index bd1b28d..fcfe3a6 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -136,6 +136,7 @@
 #include <drm/i915_drm.h>
 #include "i915_drv.h"
 
+#define GEN9_LR_CONTEXT_RENDER_SIZE (22 * PAGE_SIZE)
 #define GEN8_LR_CONTEXT_RENDER_SIZE (20 * PAGE_SIZE)
 #define GEN8_LR_CONTEXT_OTHER_SIZE (2 * PAGE_SIZE)
 
@@ -1611,11 +1612,14 @@ static uint32_t get_lr_context_size(struct intel_engine_cs *ring)
 {
 	int ret = 0;
 
-	WARN_ON(INTEL_INFO(ring->dev)->gen != 8);
+	WARN_ON(INTEL_INFO(ring->dev)->gen < 8);
 
 	switch (ring->id) {
 	case RCS:
-		ret = GEN8_LR_CONTEXT_RENDER_SIZE;
+		if (INTEL_INFO(ring->dev)->gen >= 9)
+			ret = GEN9_LR_CONTEXT_RENDER_SIZE;
+		else
+			ret = GEN8_LR_CONTEXT_RENDER_SIZE;
 		break;
 	case VCS:
 	case BCS:
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 89/89] drm/i915/skl: Disable contexts if execlists aren't enabled
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (87 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 88/89] drm/i915/skl: Add Gen9 LRC size Damien Lespiau
@ 2014-09-04 11:27 ` Damien Lespiau
  2014-09-26 15:28   ` Mika Kuoppala
  2014-09-04 14:16 ` [PATCH 00/89] Basic Skylake enabling (reviewers) Damien Lespiau
  89 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 11:27 UTC (permalink / raw)
  To: intel-gfx

We were hiting a BUG() in get_context_size() with execlist disabled.

"legacy" contexts are not supported on gen9 so we don't have a gen9
specific size to add in there. Instead, let's disable legacy contexts
altogether on gen9, whether we're booting with execlist enabled or not.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_context.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index a5221d8..ec81d8a 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -320,7 +320,7 @@ int i915_gem_context_init(struct drm_device *dev)
 	if (WARN_ON(dev_priv->ring[RCS].default_context))
 		return 0;
 
-	if (i915.enable_execlists) {
+	if (INTEL_INFO(dev)->gen >= 9 || i915.enable_execlists) {
 		/* NB: intentionally left blank. We will allocate our own
 		 * backing objects as we need them, thank you very much */
 		dev_priv->hw_context_size = 0;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* Re: [PATCH 86/89] drm/i915: only reset media, blt, and render engines on GPU hangs
  2014-09-04 11:27 ` [PATCH 86/89] drm/i915: only reset media, blt, and render engines on GPU hangs Damien Lespiau
@ 2014-09-04 12:03   ` Jani Nikula
  2014-09-04 12:29     ` Damien Lespiau
  2014-09-04 12:36   ` Mika Kuoppala
  1 sibling, 1 reply; 286+ messages in thread
From: Jani Nikula @ 2014-09-04 12:03 UTC (permalink / raw)
  To: Damien Lespiau, intel-gfx

On Thu, 04 Sep 2014, Damien Lespiau <damien.lespiau@intel.com> wrote:
> From: Jesse Barnes <jbarnes@virtuousgeek.org>
>
> No need to mess with display.

Why is this patch part of the skl enabling series? The commit message is
a bit thin on the details too...

BR,
Jani.

>
> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_uncore.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index ce1214b..29aa63e 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -1472,7 +1472,8 @@ static int gen6_do_reset(struct drm_device *dev)
>  	 * for fifo space for the write or forcewake the chip for
>  	 * the read
>  	 */
> -	__raw_i915_write32(dev_priv, GEN6_GDRST, GEN6_GRDOM_FULL);
> +	__raw_i915_write32(dev_priv, GEN6_GDRST, GEN6_GRDOM_MEDIA |
> +			   GEN6_GRDOM_BLT | GEN6_GRDOM_RENDER);
>  
>  	/* Spin waiting for the device to ack the reset request */
>  	ret = wait_for((__raw_i915_read32(dev_priv, GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500);
> -- 
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 57/89] drm/i915: Rewrite ABS_DIFF() in a safer manner
  2014-09-04 11:27 ` [PATCH 57/89] drm/i915: Rewrite ABS_DIFF() in a safer manner Damien Lespiau
@ 2014-09-04 12:11   ` Jani Nikula
  2014-09-04 12:32     ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Jani Nikula @ 2014-09-04 12:11 UTC (permalink / raw)
  To: Damien Lespiau, intel-gfx

On Thu, 04 Sep 2014, Damien Lespiau <damien.lespiau@intel.com> wrote:
> The new version of the macro does a few things better:
>   - protect the arguments,
>   - only evaluate the arguments once,
>   - check that the arguments are of the same type,
>
> Change LC_FREQ_2K to be a unsigned 64bit constant and removed the '()'
> from the caller as a result.
>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

Reviewed-by: Jani Nikula <jani.nikula@intel.com>

Can be picked up for dinq separate from this series, right?


> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 14 +++++++++-----
>  1 file changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 64eda53..ba1103f 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -460,7 +460,7 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
>  }
>  
>  #define LC_FREQ 2700
> -#define LC_FREQ_2K (LC_FREQ * 2000)
> +#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
>  
>  #define P_MIN 2
>  #define P_MAX 64
> @@ -472,7 +472,11 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
>  #define VCO_MIN 2400
>  #define VCO_MAX 4800
>  
> -#define ABS_DIFF(a, b) ((a > b) ? (a - b) : (b - a))
> +#define abs_diff(a, b) ({			\
> +	typeof(a) __a = (a);			\
> +	typeof(b) __b = (b);			\
> +	(void) (&__a == &__b);			\
> +	__a > __b ? (__a - __b) : (__b - __a); })
>  
>  struct wrpll_rnp {
>  	unsigned p, n2, r2;
> @@ -582,9 +586,9 @@ static void wrpll_update_rnp(uint64_t freq2k, unsigned budget,
>  	 */
>  	a = freq2k * budget * p * r2;
>  	b = freq2k * budget * best->p * best->r2;
> -	diff = ABS_DIFF((freq2k * p * r2), (LC_FREQ_2K * n2));
> -	diff_best = ABS_DIFF((freq2k * best->p * best->r2),
> -			     (LC_FREQ_2K * best->n2));
> +	diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
> +	diff_best = abs_diff(freq2k * best->p * best->r2,
> +			     LC_FREQ_2K * best->n2);
>  	c = 1000000 * diff;
>  	d = 1000000 * diff_best;
>  
> -- 
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 86/89] drm/i915: only reset media, blt, and render engines on GPU hangs
  2014-09-04 12:03   ` Jani Nikula
@ 2014-09-04 12:29     ` Damien Lespiau
  2014-09-04 13:13       ` Daniel Vetter
  2014-09-04 15:46       ` Jesse Barnes
  0 siblings, 2 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 12:29 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 03:03:27PM +0300, Jani Nikula wrote:
> On Thu, 04 Sep 2014, Damien Lespiau <damien.lespiau@intel.com> wrote:
> > From: Jesse Barnes <jbarnes@virtuousgeek.org>
> >
> > No need to mess with display.
> 
> Why is this patch part of the skl enabling series? The commit message is
> a bit thin on the details too...

I did hesitate with this one, this is indeed orthogonal to SKL enabling
and was just a shot in the dark.

Jesse, do you mind if we just drop this one?

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 57/89] drm/i915: Rewrite ABS_DIFF() in a safer manner
  2014-09-04 12:11   ` Jani Nikula
@ 2014-09-04 12:32     ` Damien Lespiau
  2014-09-04 13:11       ` Daniel Vetter
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 12:32 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 03:11:24PM +0300, Jani Nikula wrote:
> On Thu, 04 Sep 2014, Damien Lespiau <damien.lespiau@intel.com> wrote:
> > The new version of the macro does a few things better:
> >   - protect the arguments,
> >   - only evaluate the arguments once,
> >   - check that the arguments are of the same type,
> >
> > Change LC_FREQ_2K to be a unsigned 64bit constant and removed the '()'
> > from the caller as a result.
> >
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> 
> Reviewed-by: Jani Nikula <jani.nikula@intel.com>
> 
> Can be picked up for dinq separate from this series, right?

Yes, it can indeed.

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 86/89] drm/i915: only reset media, blt, and render engines on GPU hangs
  2014-09-04 11:27 ` [PATCH 86/89] drm/i915: only reset media, blt, and render engines on GPU hangs Damien Lespiau
  2014-09-04 12:03   ` Jani Nikula
@ 2014-09-04 12:36   ` Mika Kuoppala
  1 sibling, 0 replies; 286+ messages in thread
From: Mika Kuoppala @ 2014-09-04 12:36 UTC (permalink / raw)
  To: Damien Lespiau, intel-gfx

Damien Lespiau <damien.lespiau@intel.com> writes:

> From: Jesse Barnes <jbarnes@virtuousgeek.org>
>
> No need to mess with display.
>
> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_uncore.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index ce1214b..29aa63e 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -1472,7 +1472,8 @@ static int gen6_do_reset(struct drm_device *dev)
>  	 * for fifo space for the write or forcewake the chip for
>  	 * the read
>  	 */
> -	__raw_i915_write32(dev_priv, GEN6_GDRST, GEN6_GRDOM_FULL);
> +	__raw_i915_write32(dev_priv, GEN6_GDRST, GEN6_GRDOM_MEDIA |
> +			   GEN6_GRDOM_BLT | GEN6_GRDOM_RENDER);

You need to reset more engines even if you don't do full reset. Vebox is
missing atleast.

-Mika

>  	/* Spin waiting for the device to ack the reset request */
>  	ret = wait_for((__raw_i915_read32(dev_priv, GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500);
> -- 
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 57/89] drm/i915: Rewrite ABS_DIFF() in a safer manner
  2014-09-04 12:32     ` Damien Lespiau
@ 2014-09-04 13:11       ` Daniel Vetter
  0 siblings, 0 replies; 286+ messages in thread
From: Daniel Vetter @ 2014-09-04 13:11 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 01:32:24PM +0100, Damien Lespiau wrote:
> On Thu, Sep 04, 2014 at 03:11:24PM +0300, Jani Nikula wrote:
> > On Thu, 04 Sep 2014, Damien Lespiau <damien.lespiau@intel.com> wrote:
> > > The new version of the macro does a few things better:
> > >   - protect the arguments,
> > >   - only evaluate the arguments once,
> > >   - check that the arguments are of the same type,
> > >
> > > Change LC_FREQ_2K to be a unsigned 64bit constant and removed the '()'
> > > from the caller as a result.
> > >
> > > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> > 
> > Reviewed-by: Jani Nikula <jani.nikula@intel.com>
> > 
> > Can be picked up for dinq separate from this series, right?
> 
> Yes, it can indeed.

s/can/must/ If the platform enabling changes shared code, that part must
go in through the normal merge process and has the same merge window
cutoff deadlines like everything else.

Queued for -next, thanks for the patch.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 86/89] drm/i915: only reset media, blt, and render engines on GPU hangs
  2014-09-04 12:29     ` Damien Lespiau
@ 2014-09-04 13:13       ` Daniel Vetter
  2014-09-04 15:46       ` Jesse Barnes
  1 sibling, 0 replies; 286+ messages in thread
From: Daniel Vetter @ 2014-09-04 13:13 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 01:29:06PM +0100, Damien Lespiau wrote:
> On Thu, Sep 04, 2014 at 03:03:27PM +0300, Jani Nikula wrote:
> > On Thu, 04 Sep 2014, Damien Lespiau <damien.lespiau@intel.com> wrote:
> > > From: Jesse Barnes <jbarnes@virtuousgeek.org>
> > >
> > > No need to mess with display.
> > 
> > Why is this patch part of the skl enabling series? The commit message is
> > a bit thin on the details too...
> 
> I did hesitate with this one, this is indeed orthogonal to SKL enabling
> and was just a shot in the dark.
> 
> Jesse, do you mind if we just drop this one?

Afaik we only reset GT (i.e. media/blit) and not display on gen6+, at
least all the display stuff survives. This has been the case since roughly
g4x+, and we actually have a bunch of testcases now to verify that.
Specifically the crc vs reset tests will start to fail if anything in the
display block goes south.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 05/89] drm/i915/skl: i915_swizzle_info gen9 fix
  2014-09-04 11:26 ` [PATCH 05/89] drm/i915/skl: i915_swizzle_info gen9 fix Damien Lespiau
@ 2014-09-04 13:14   ` Daniel Vetter
  2014-09-04 15:26     ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Daniel Vetter @ 2014-09-04 13:14 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:26:31PM +0100, Damien Lespiau wrote:
> From: Robert Beckett <robert.beckett@intel.com>
> 
> Fix ARB_MODE register read for gen >= 8 in i915_swizzle_info
> 
> Signed-off-by: Robert Beckett <robert.beckett@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

given that the swizzle stuff is gone, shouldn't we just have a gen9+
check to do nothing?
-Daniel

> ---
>  drivers/gpu/drm/i915/i915_debugfs.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index d8389b2..88a4643 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -1971,7 +1971,7 @@ static int i915_swizzle_info(struct seq_file *m, void *data)
>  			   I915_READ(MAD_DIMM_C2));
>  		seq_printf(m, "TILECTL = 0x%08x\n",
>  			   I915_READ(TILECTL));
> -		if (IS_GEN8(dev))
> +		if (INTEL_INFO(dev)->gen >= 8)
>  			seq_printf(m, "GAMTARBMODE = 0x%08x\n",
>  				   I915_READ(GAMTARBMODE));
>  		else
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 32/89] drm/i915/skl: Adjust the display engine interrupts
  2014-09-04 11:26 ` [PATCH 32/89] drm/i915/skl: Adjust the display engine interrupts Damien Lespiau
@ 2014-09-04 13:19   ` Daniel Vetter
  2014-09-17 18:41     ` Rodrigo Vivi
  0 siblings, 1 reply; 286+ messages in thread
From: Daniel Vetter @ 2014-09-04 13:19 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:26:58PM +0100, Damien Lespiau wrote:
> To accomodate the extra planes, the bit definitions were shuffled around
> a bit.
> 
> v2: Rebase on top of the for_each_pipe() change adding dev_priv as first
>     argument.
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_irq.c | 37 ++++++++++++++++++++++++++++---------
>  drivers/gpu/drm/i915/i915_reg.h | 13 +++++++++++++
>  2 files changed, 41 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index c62a2e4..734b73e 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -2584,7 +2584,7 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
>  	}
>  
>  	for_each_pipe(dev_priv, pipe) {
> -		uint32_t pipe_iir;
> +		uint32_t pipe_iir, flip_done = 0, fault_errors = 0;
>  
>  		if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe)))
>  			continue;
> @@ -2593,10 +2593,16 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
>  		if (pipe_iir) {
>  			ret = IRQ_HANDLED;
>  			I915_WRITE(GEN8_DE_PIPE_IIR(pipe), pipe_iir);
> +
>  			if (pipe_iir & GEN8_PIPE_VBLANK)
>  				intel_pipe_handle_vblank(dev, pipe);
>  
> -			if (pipe_iir & GEN8_PIPE_PRIMARY_FLIP_DONE) {
> +			if (IS_GEN9(dev))
> +				flip_done = pipe_iir & GEN9_PIPE_PLANE1_FLIP_DONE;
> +			else
> +				flip_done = pipe_iir & GEN8_PIPE_PRIMARY_FLIP_DONE;
> +
> +			if (flip_done) {
>  				intel_prepare_page_flip(dev, pipe);
>  				intel_finish_page_flip_plane(dev, pipe);
>  			}
> @@ -2611,11 +2617,16 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
>  						  pipe_name(pipe));
>  			}
>  
> -			if (pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS) {
> +
> +			if (IS_GEN9(dev))
> +				fault_errors = pipe_iir & GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
> +			else
> +				fault_errors = pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
> +
> +			if (fault_errors)
>  				DRM_ERROR("Fault errors on pipe %c\n: 0x%08x",
>  					  pipe_name(pipe),
>  					  pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS);
> -			}
>  		} else
>  			DRM_ERROR("The master control interrupt lied (DE PIPE)!\n");

gen8+ irq handling functions would _really_ benefit from a bit of function
extraction to prevent them from falling off the right edge of my screen
all the time ...

Just in case you have no idea what to do on a rainy day ;-)
-Daniel

>  	}
> @@ -3845,12 +3856,20 @@ static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv)
>  
>  static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
>  {
> -	uint32_t de_pipe_masked = GEN8_PIPE_PRIMARY_FLIP_DONE |
> -		GEN8_PIPE_CDCLK_CRC_DONE |
> -		GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
> -	uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
> -		GEN8_PIPE_FIFO_UNDERRUN;
> +	uint32_t de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE;
> +	uint32_t de_pipe_enables;
>  	int pipe;
> +
> +	if (IS_GEN9(dev_priv))
> +		de_pipe_masked |= GEN9_PIPE_PLANE1_FLIP_DONE |
> +				  GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
> +	else
> +		de_pipe_masked |= GEN8_PIPE_PRIMARY_FLIP_DONE |
> +				  GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
> +
> +	de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
> +					   GEN8_PIPE_FIFO_UNDERRUN;
> +
>  	dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked;
>  	dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked;
>  	dev_priv->de_irq_mask[PIPE_C] = ~de_pipe_masked;
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index acd0a7b..5928a75 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4840,10 +4840,23 @@ enum punit_power_well {
>  #define  GEN8_PIPE_SCAN_LINE_EVENT	(1 << 2)
>  #define  GEN8_PIPE_VSYNC		(1 << 1)
>  #define  GEN8_PIPE_VBLANK		(1 << 0)
> +#define  GEN9_PIPE_CURSOR_FAULT		(1 << 11)
> +#define  GEN9_PIPE_PLANE3_FAULT		(1 << 9)
> +#define  GEN9_PIPE_PLANE2_FAULT		(1 << 8)
> +#define  GEN9_PIPE_PLANE1_FAULT		(1 << 7)
> +#define  GEN9_PIPE_PLANE3_FLIP_DONE	(1 << 5)
> +#define  GEN9_PIPE_PLANE2_FLIP_DONE	(1 << 4)
> +#define  GEN9_PIPE_PLANE1_FLIP_DONE	(1 << 3)
> +#define  GEN9_PIPE_PLANE_FLIP_DONE(p)	(1 << (3 + p))
>  #define GEN8_DE_PIPE_IRQ_FAULT_ERRORS \
>  	(GEN8_PIPE_CURSOR_FAULT | \
>  	 GEN8_PIPE_SPRITE_FAULT | \
>  	 GEN8_PIPE_PRIMARY_FAULT)
> +#define GEN9_DE_PIPE_IRQ_FAULT_ERRORS \
> +	(GEN9_PIPE_CURSOR_FAULT | \
> +	 GEN9_PIPE_PLANE3_FAULT | \
> +	 GEN9_PIPE_PLANE2_FAULT | \
> +	 GEN9_PIPE_PLANE1_FAULT)
>  
>  #define GEN8_DE_PORT_ISR 0x44440
>  #define GEN8_DE_PORT_IMR 0x44444
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 38/89] drm/i915/skl: Implement drm_plane vfuncs
  2014-09-04 11:27 ` [PATCH 38/89] drm/i915/skl: Implement drm_plane vfuncs Damien Lespiau
@ 2014-09-04 13:21   ` Daniel Vetter
  2014-09-16 13:20     ` Damien Lespiau
  2014-09-17 22:08   ` Rodrigo Vivi
  1 sibling, 1 reply; 286+ messages in thread
From: Daniel Vetter @ 2014-09-04 13:21 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:27:04PM +0100, Damien Lespiau wrote:
> SKL Uses the same hardware for all planes now, so called "universal"
> planes. Ie both the primary planes and sprite planes share the same
> logic. This patch implements the drm_plane vfuncs for "sprites" ie
> planes that aren't the primary plane.
> 
> v2: Couple of fixes:
>   - Actually enabled the planes and fix the plane number
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

This needs to be de-duped I think ... especially since it will conflict
quite badly with Padovan's ongoing work to introduce a struct
intel_plane_config.

Not sure yet how we can shuffle the merge here, I guess it'll be a case of
who's first wins ;-)
-Daniel

> ---
>  drivers/gpu/drm/i915/i915_reg.h     |  31 +++++-
>  drivers/gpu/drm/i915/intel_sprite.c | 206 +++++++++++++++++++++++++++++++++++-
>  2 files changed, 235 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index c293dab..0159f2d 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4513,7 +4513,9 @@ enum punit_power_well {
>  #define   PLANE_CTL_FORMAT_INDEXED		( 12 << 24)
>  #define   PLANE_CTL_FORMAT_RGB_565		( 14 << 24)
>  #define   PLANE_CTL_PIPE_CSC_ENABLE		(1 << 23)
> -#define   PLANE_CTL_KEY_ENABLE			(1 << 22)
> +#define   PLANE_CTL_KEY_ENABLE_MASK		(0x3 << 21)
> +#define   PLANE_CTL_KEY_ENABLE_SOURCE		(  1 << 21)
> +#define   PLANE_CTL_KEY_ENABLE_DESTINATION	(  2 << 21)
>  #define   PLANE_CTL_ORDER_BGRX			(0 << 20)
>  #define   PLANE_CTL_ORDER_RGBX			(1 << 20)
>  #define   PLANE_CTL_YUV422_ORDER_MASK		(0x3 << 16)
> @@ -4548,6 +4550,12 @@ enum punit_power_well {
>  #define _PLANE_OFFSET_1_A			0x701a4
>  #define _PLANE_OFFSET_2_A			0x702a4
>  #define _PLANE_OFFSET_3_A			0x703a4
> +#define _PLANE_KEYVAL_1_A			0x70194
> +#define _PLANE_KEYVAL_2_A			0x70294
> +#define _PLANE_KEYMSK_1_A			0x70198
> +#define _PLANE_KEYMSK_2_A			0x70298
> +#define _PLANE_KEYMAX_1_A			0x701a0
> +#define _PLANE_KEYMAX_2_A			0x702a0
>  
>  #define _PLANE_CTL_1_B				0x71180
>  #define _PLANE_CTL_2_B				0x71280
> @@ -4604,6 +4612,27 @@ enum punit_power_well {
>  #define PLANE_OFFSET(pipe, plane)	\
>  	_PLANE(plane, _PLANE_OFFSET_1(pipe), _PLANE_OFFSET_2(pipe))
>  
> +#define _PLANE_KEYVAL_1_B			0x71194
> +#define _PLANE_KEYVAL_2_B			0x71294
> +#define _PLANE_KEYVAL_1(pipe) _PIPE(pipe, _PLANE_KEYVAL_1_A, _PLANE_KEYVAL_1_B)
> +#define _PLANE_KEYVAL_2(pipe) _PIPE(pipe, _PLANE_KEYVAL_2_A, _PLANE_KEYVAL_2_B)
> +#define PLANE_KEYVAL(pipe, plane)	\
> +	_PLANE(plane, _PLANE_KEYVAL_1(pipe), _PLANE_KEYVAL_2(pipe))
> +
> +#define _PLANE_KEYMSK_1_B			0x71198
> +#define _PLANE_KEYMSK_2_B			0x71298
> +#define _PLANE_KEYMSK_1(pipe) _PIPE(pipe, _PLANE_KEYMSK_1_A, _PLANE_KEYMSK_1_B)
> +#define _PLANE_KEYMSK_2(pipe) _PIPE(pipe, _PLANE_KEYMSK_2_A, _PLANE_KEYMSK_2_B)
> +#define PLANE_KEYMSK(pipe, plane)	\
> +	_PLANE(plane, _PLANE_KEYMSK_1(pipe), _PLANE_KEYMSK_2(pipe))
> +
> +#define _PLANE_KEYMAX_1_B			0x711a0
> +#define _PLANE_KEYMAX_2_B			0x712a0
> +#define _PLANE_KEYMAX_1(pipe) _PIPE(pipe, _PLANE_KEYMAX_1_A, _PLANE_KEYMAX_1_B)
> +#define _PLANE_KEYMAX_2(pipe) _PIPE(pipe, _PLANE_KEYMAX_2_A, _PLANE_KEYMAX_2_B)
> +#define PLANE_KEYMAX(pipe, plane)	\
> +	_PLANE(plane, _PLANE_KEYMAX_1(pipe), _PLANE_KEYMAX_2(pipe))
> +
>  /* VBIOS regs */
>  #define VGACNTRL		0x71400
>  # define VGA_DISP_DISABLE			(1 << 31)
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 07a74ef..57e7190 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -139,6 +139,184 @@ static void intel_update_primary_plane(struct intel_crtc *crtc)
>  }
>  
>  static void
> +skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
> +		 struct drm_framebuffer *fb,
> +		 struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
> +		 unsigned int crtc_w, unsigned int crtc_h,
> +		 uint32_t x, uint32_t y,
> +		 uint32_t src_w, uint32_t src_h)
> +{
> +	struct drm_device *dev = drm_plane->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_plane *intel_plane = to_intel_plane(drm_plane);
> +	const int pipe = intel_plane->pipe;
> +	const int plane = intel_plane->plane + 1;
> +	u32 plane_ctl, stride;
> +	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
> +
> +	plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
> +
> +	/* Mask out pixel format bits in case we change it */
> +	plane_ctl &= ~PLANE_CTL_FORMAT_MASK;
> +	plane_ctl &= ~PLANE_CTL_ORDER_RGBX;
> +	plane_ctl &= ~PLANE_CTL_YUV422_ORDER_MASK;
> +	plane_ctl &= ~PLANE_CTL_TILED_MASK;
> +	plane_ctl &= ~PLANE_CTL_ALPHA_MASK;
> +
> +	/* Trickle feed has to be enabled */
> +	plane_ctl &= ~PLANE_CTL_TRICKLE_FEED_DISABLE;
> +
> +	switch (fb->pixel_format) {
> +	case DRM_FORMAT_RGB565:
> +		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
> +		break;
> +	case DRM_FORMAT_XBGR8888:
> +		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
> +		break;
> +	case DRM_FORMAT_XRGB8888:
> +		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> +		break;
> +	/*
> +	 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
> +	 * to be already pre-multiplied. We need to add a knob (or a different
> +	 * DRM_FORMAT) for user-space to configure that.
> +	 */
> +	case DRM_FORMAT_ABGR8888:
> +		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
> +			     PLANE_CTL_ORDER_RGBX |
> +			     PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		break;
> +	case DRM_FORMAT_ARGB8888:
> +		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
> +			     PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +		break;
> +	case DRM_FORMAT_YUYV:
> +		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
> +		break;
> +	case DRM_FORMAT_YVYU:
> +		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
> +		break;
> +	case DRM_FORMAT_UYVY:
> +		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
> +		break;
> +	case DRM_FORMAT_VYUY:
> +		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
> +		break;
> +	default:
> +		BUG();
> +	}
> +
> +	switch (obj->tiling_mode) {
> +	case I915_TILING_NONE:
> +		stride = fb->pitches[0] >> 6;
> +		break;
> +	case I915_TILING_X:
> +		plane_ctl |= PLANE_CTL_TILED_X;
> +		stride = fb->pitches[0] >> 9;
> +		break;
> +	default:
> +		BUG();
> +	}
> +
> +	plane_ctl |= PLANE_CTL_ENABLE;
> +	plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE;
> +
> +	intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h,
> +				       pixel_size, true,
> +				       src_w != crtc_w || src_h != crtc_h);
> +
> +	/* Sizes are 0 based */
> +	src_w--;
> +	src_h--;
> +	crtc_w--;
> +	crtc_h--;
> +
> +	I915_WRITE(PLANE_OFFSET(pipe, plane), (y << 16) | x);
> +	I915_WRITE(PLANE_STRIDE(pipe, plane), stride);
> +	I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
> +	I915_WRITE(PLANE_SIZE(pipe, plane), (crtc_h << 16) | crtc_w);
> +	I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
> +	I915_WRITE(PLANE_SURF(pipe, plane), i915_gem_obj_ggtt_offset(obj));
> +	POSTING_READ(PLANE_SURF(pipe, plane));
> +}
> +
> +static void
> +skl_disable_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc)
> +{
> +	struct drm_device *dev = drm_plane->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_plane *intel_plane = to_intel_plane(drm_plane);
> +	const int pipe = intel_plane->pipe;
> +	const int plane = intel_plane->plane + 1;
> +
> +	I915_WRITE(PLANE_CTL(pipe, plane),
> +		   I915_READ(PLANE_CTL(pipe, plane)) & ~PLANE_CTL_ENABLE);
> +
> +	/* Activate double buffered register update */
> +	I915_WRITE(PLANE_CTL(pipe, plane), 0);
> +	POSTING_READ(PLANE_CTL(pipe, plane));
> +
> +	intel_update_sprite_watermarks(drm_plane, crtc, 0, 0, 0, false, false);
> +}
> +
> +static int
> +skl_update_colorkey(struct drm_plane *drm_plane,
> +		    struct drm_intel_sprite_colorkey *key)
> +{
> +	struct drm_device *dev = drm_plane->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_plane *intel_plane = to_intel_plane(drm_plane);
> +	const int pipe = intel_plane->pipe;
> +	const int plane = intel_plane->plane;
> +	u32 plane_ctl;
> +
> +	I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value);
> +	I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value);
> +	I915_WRITE(PLANE_KEYMSK(pipe, plane), key->channel_mask);
> +
> +	plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
> +	plane_ctl &= ~PLANE_CTL_KEY_ENABLE_MASK;
> +	if (key->flags & I915_SET_COLORKEY_DESTINATION)
> +		plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION;
> +	else if (key->flags & I915_SET_COLORKEY_SOURCE)
> +		plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE;
> +	I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
> +
> +	POSTING_READ(PLANE_CTL(pipe, plane));
> +
> +	return 0;
> +}
> +
> +static void
> +skl_get_colorkey(struct drm_plane *drm_plane,
> +		 struct drm_intel_sprite_colorkey *key)
> +{
> +	struct drm_device *dev = drm_plane->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_plane *intel_plane = to_intel_plane(drm_plane);
> +	const int pipe = intel_plane->pipe;
> +	const int plane = intel_plane->plane;
> +	u32 plane_ctl;
> +
> +	key->min_value = I915_READ(PLANE_KEYVAL(pipe, plane));
> +	key->max_value = I915_READ(PLANE_KEYMAX(pipe, plane));
> +	key->channel_mask = I915_READ(PLANE_KEYMSK(pipe, plane));
> +
> +	plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
> +
> +	switch (plane_ctl & PLANE_CTL_KEY_ENABLE_MASK) {
> +	case PLANE_CTL_KEY_ENABLE_DESTINATION:
> +		key->flags = I915_SET_COLORKEY_DESTINATION;
> +		break;
> +	case PLANE_CTL_KEY_ENABLE_SOURCE:
> +		key->flags = I915_SET_COLORKEY_SOURCE;
> +		break;
> +	default:
> +		key->flags = I915_SET_COLORKEY_NONE;
> +	}
> +}
> +
> +static void
>  vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
>  		 struct drm_framebuffer *fb,
>  		 struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
> @@ -1305,6 +1483,18 @@ static uint32_t vlv_plane_formats[] = {
>  	DRM_FORMAT_VYUY,
>  };
>  
> +static uint32_t skl_plane_formats[] = {
> +	DRM_FORMAT_RGB565,
> +	DRM_FORMAT_ABGR8888,
> +	DRM_FORMAT_ARGB8888,
> +	DRM_FORMAT_XBGR8888,
> +	DRM_FORMAT_XRGB8888,
> +	DRM_FORMAT_YUYV,
> +	DRM_FORMAT_YVYU,
> +	DRM_FORMAT_UYVY,
> +	DRM_FORMAT_VYUY,
> +};
> +
>  int
>  intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
>  {
> @@ -1368,7 +1558,21 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
>  			num_plane_formats = ARRAY_SIZE(snb_plane_formats);
>  		}
>  		break;
> -
> +	case 9:
> +		/*
> +		 * FIXME: Skylake planes can be scaled (with some restrictions),
> +		 * but this is for another time.
> +		 */
> +		intel_plane->can_scale = false;
> +		intel_plane->max_downscale = 1;
> +		intel_plane->update_plane = skl_update_plane;
> +		intel_plane->disable_plane = skl_disable_plane;
> +		intel_plane->update_colorkey = skl_update_colorkey;
> +		intel_plane->get_colorkey = skl_get_colorkey;
> +
> +		plane_formats = skl_plane_formats;
> +		num_plane_formats = ARRAY_SIZE(skl_plane_formats);
> +		break;
>  	default:
>  		kfree(intel_plane);
>  		return -ENODEV;
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 77/89] drm/i915: Introduce a for_each_plane() macro
  2014-09-04 11:27 ` [PATCH 77/89] drm/i915: Introduce a for_each_plane() macro Damien Lespiau
@ 2014-09-04 13:26   ` Daniel Vetter
  2014-09-04 13:32   ` Chris Wilson
  1 sibling, 0 replies; 286+ messages in thread
From: Daniel Vetter @ 2014-09-04 13:26 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:27:43PM +0100, Damien Lespiau wrote:
> Tired of copy/pasting things around.
> 
> v2: Rebase on top of the for_each_pipe() change adding dev_priv as first
>     argument.
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

Queued for -next, thanks for the patch.
-Daniel
> ---
>  drivers/gpu/drm/i915/i915_drv.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 91ea2b7..95e57dc 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -176,6 +176,8 @@ enum hpd_pin {
>  
>  #define for_each_pipe(__dev_priv, __p) \
>  	for ((__p) = 0; (__p) < INTEL_INFO(__dev_priv)->num_pipes; (__p)++)
> +#define for_each_plane(pipe, p) \
> +	for ((p) = 0; (p) < INTEL_INFO(dev)->num_sprites[(pipe)] + 1; (p)++)
>  #define for_each_sprite(p, s) for ((s) = 0; (s) < INTEL_INFO(dev)->num_sprites[(p)]; (s)++)
>  
>  #define for_each_crtc(dev, crtc) \
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 83/89] drm/i915/skl: Check the DDB state at modeset
  2014-09-04 11:27 ` [PATCH 83/89] drm/i915/skl: Check the DDB state at modeset Damien Lespiau
@ 2014-09-04 13:27   ` Daniel Vetter
  2014-10-29 19:16     ` Ville Syrjälä
  0 siblings, 1 reply; 286+ messages in thread
From: Daniel Vetter @ 2014-09-04 13:27 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:27:49PM +0100, Damien Lespiau wrote:
> v2: Don't check DDB on pre-SKL platforms
>     Don't check DDB state on disabled pipes
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

We probably want to do this with a vfunc eventually ... but reall
deferring to Ville here, he'll know best what might be useful to make sure
that the wm readout/takeover is accurate enough. So lgtm for now.
-Daniel

> ---
>  drivers/gpu/drm/i915/i915_drv.h      |  9 +++++++
>  drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 60 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 95e57dc..0baf7f3 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1424,6 +1424,15 @@ static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry)
>  	return entry->end - entry->start + 1;
>  }
>  
> +static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
> +				       const struct skl_ddb_entry *e2)
> +{
> +	if (e1->start == e2->start && e1->end == e2->end)
> +		return true;
> +
> +	return false;
> +}
> +
>  struct skl_ddb_allocation {
>  	struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
>  	struct skl_ddb_entry cursor[I915_MAX_PIPES];
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 9b31342..35d3389 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -10944,6 +10944,56 @@ intel_pipe_config_compare(struct drm_device *dev,
>  	return true;
>  }
>  
> +static void check_wm_state(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct skl_ddb_allocation hw_ddb, *sw_ddb;
> +	struct intel_crtc *intel_crtc;
> +	int plane;
> +
> +	if (INTEL_INFO(dev)->gen < 9)
> +		return;
> +
> +	skl_ddb_get_hw_state(dev_priv, &hw_ddb);
> +	sw_ddb = &dev_priv->wm.skl_hw.ddb;
> +
> +	for_each_intel_crtc(dev, intel_crtc) {
> +		struct skl_ddb_entry *hw_entry, *sw_entry;
> +		const enum pipe pipe = intel_crtc->pipe;
> +
> +		if (!intel_crtc->active)
> +			continue;
> +
> +		/* planes */
> +		for_each_plane(pipe, plane) {
> +			hw_entry = &hw_ddb.plane[pipe][plane];
> +			sw_entry = &sw_ddb->plane[pipe][plane];
> +
> +			if (skl_ddb_entry_equal(hw_entry, sw_entry))
> +				continue;
> +
> +			DRM_ERROR("mismatch in DDB state pipe %c plane %d "
> +				  "(expected (%u,%u), found (%u,%u))\n",
> +				  pipe_name(pipe), plane + 1,
> +				  sw_entry->start, sw_entry->end,
> +				  hw_entry->start, hw_entry->end);
> +		}
> +
> +		/* cursor */
> +		hw_entry = &hw_ddb.cursor[pipe];
> +		sw_entry = &sw_ddb->cursor[pipe];
> +
> +		if (skl_ddb_entry_equal(hw_entry, sw_entry))
> +			continue;
> +
> +		DRM_ERROR("mismatch in DDB state pipe %c cursor "
> +			  "(expected (%u,%u), found (%u,%u))\n",
> +			  pipe_name(pipe),
> +			  sw_entry->start, sw_entry->end,
> +			  hw_entry->start, hw_entry->end);
> +	}
> +}
> +
>  static void
>  check_connector_state(struct drm_device *dev)
>  {
> @@ -11143,6 +11193,7 @@ check_shared_dpll_state(struct drm_device *dev)
>  void
>  intel_modeset_check_state(struct drm_device *dev)
>  {
> +	check_wm_state(dev);
>  	check_connector_state(dev);
>  	check_encoder_state(dev);
>  	check_crtc_state(dev);
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 77/89] drm/i915: Introduce a for_each_plane() macro
  2014-09-04 11:27 ` [PATCH 77/89] drm/i915: Introduce a for_each_plane() macro Damien Lespiau
  2014-09-04 13:26   ` Daniel Vetter
@ 2014-09-04 13:32   ` Chris Wilson
  2014-09-04 14:00     ` Daniel Vetter
  2014-09-04 14:02     ` Damien Lespiau
  1 sibling, 2 replies; 286+ messages in thread
From: Chris Wilson @ 2014-09-04 13:32 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:27:43PM +0100, Damien Lespiau wrote:
> Tired of copy/pasting things around.
> 
> v2: Rebase on top of the for_each_pipe() change adding dev_priv as first
>     argument.
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 91ea2b7..95e57dc 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -176,6 +176,8 @@ enum hpd_pin {
>  
>  #define for_each_pipe(__dev_priv, __p) \
>  	for ((__p) = 0; (__p) < INTEL_INFO(__dev_priv)->num_pipes; (__p)++)
> +#define for_each_plane(pipe, p) \
> +	for ((p) = 0; (p) < INTEL_INFO(dev)->num_sprites[(pipe)] + 1; (p)++)

We are adding new magic macros taking dev...

>  #define for_each_sprite(p, s) for ((s) = 0; (s) < INTEL_INFO(dev)->num_sprites[(p)]; (s)++)
I haven't asked you to fix this one yet either.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 77/89] drm/i915: Introduce a for_each_plane() macro
  2014-09-04 13:32   ` Chris Wilson
@ 2014-09-04 14:00     ` Daniel Vetter
  2014-09-04 14:05       ` Damien Lespiau
  2014-09-04 14:02     ` Damien Lespiau
  1 sibling, 1 reply; 286+ messages in thread
From: Daniel Vetter @ 2014-09-04 14:00 UTC (permalink / raw)
  To: Chris Wilson, Damien Lespiau, intel-gfx

On Thu, Sep 04, 2014 at 02:32:47PM +0100, Chris Wilson wrote:
> On Thu, Sep 04, 2014 at 12:27:43PM +0100, Damien Lespiau wrote:
> > Tired of copy/pasting things around.
> > 
> > v2: Rebase on top of the for_each_pipe() change adding dev_priv as first
> >     argument.
> > 
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 91ea2b7..95e57dc 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -176,6 +176,8 @@ enum hpd_pin {
> >  
> >  #define for_each_pipe(__dev_priv, __p) \
> >  	for ((__p) = 0; (__p) < INTEL_INFO(__dev_priv)->num_pipes; (__p)++)
> > +#define for_each_plane(pipe, p) \
> > +	for ((p) = 0; (p) < INTEL_INFO(dev)->num_sprites[(pipe)] + 1; (p)++)
> 
> We are adding new magic macros taking dev...
> 
> >  #define for_each_sprite(p, s) for ((s) = 0; (s) < INTEL_INFO(dev)->num_sprites[(p)]; (s)++)
> I haven't asked you to fix this one yet either.

Ok, dropping again for now ...
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 77/89] drm/i915: Introduce a for_each_plane() macro
  2014-09-04 13:32   ` Chris Wilson
  2014-09-04 14:00     ` Daniel Vetter
@ 2014-09-04 14:02     ` Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 14:02 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

On Thu, Sep 04, 2014 at 02:32:47PM +0100, Chris Wilson wrote:
> > +#define for_each_plane(pipe, p) \
> > +	for ((p) = 0; (p) < INTEL_INFO(dev)->num_sprites[(pipe)] + 1; (p)++)
> 
> We are adding new magic macros taking dev...
> 
> >  #define for_each_sprite(p, s) for ((s) = 0; (s) < INTEL_INFO(dev)->num_sprites[(p)]; (s)++)
> I haven't asked you to fix this one yet either.

I hereby promise I'll add those dev_priv arguments as followup up
patches.

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 77/89] drm/i915: Introduce a for_each_plane() macro
  2014-09-04 14:00     ` Daniel Vetter
@ 2014-09-04 14:05       ` Damien Lespiau
  2014-09-04 14:16         ` Daniel Vetter
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 14:05 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 04:00:32PM +0200, Daniel Vetter wrote:
> On Thu, Sep 04, 2014 at 02:32:47PM +0100, Chris Wilson wrote:
> > On Thu, Sep 04, 2014 at 12:27:43PM +0100, Damien Lespiau wrote:
> > > Tired of copy/pasting things around.
> > > 
> > > v2: Rebase on top of the for_each_pipe() change adding dev_priv as first
> > >     argument.
> > > 
> > > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/i915_drv.h | 2 ++
> > >  1 file changed, 2 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > > index 91ea2b7..95e57dc 100644
> > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > @@ -176,6 +176,8 @@ enum hpd_pin {
> > >  
> > >  #define for_each_pipe(__dev_priv, __p) \
> > >  	for ((__p) = 0; (__p) < INTEL_INFO(__dev_priv)->num_pipes; (__p)++)
> > > +#define for_each_plane(pipe, p) \
> > > +	for ((p) = 0; (p) < INTEL_INFO(dev)->num_sprites[(pipe)] + 1; (p)++)
> > 
> > We are adding new magic macros taking dev...
> > 
> > >  #define for_each_sprite(p, s) for ((s) = 0; (s) < INTEL_INFO(dev)->num_sprites[(p)]; (s)++)
> > I haven't asked you to fix this one yet either.
> 
> Ok, dropping again for now ...

The problem is that I then need to touch the patches that depend on it,
some not very interesting manipulations. Can't we have this as is and
I'll fix later?

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 00/89] Basic Skylake enabling (reviewers)
  2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
                   ` (88 preceding siblings ...)
  2014-09-04 11:27 ` [PATCH 89/89] drm/i915/skl: Disable contexts if execlists aren't enabled Damien Lespiau
@ 2014-09-04 14:16 ` Damien Lespiau
  2014-09-16 14:51   ` Thomas Wood
  2014-10-17 14:29   ` Damien Lespiau
  89 siblings, 2 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 14:16 UTC (permalink / raw)
  To: intel-gfx; +Cc: paulo.r.zanoni, thomas.wood, rodrigo.vivi

Of course, the series now needs reviewers. There's a list of known
problems that I'm planning to address, a few of those problems are easy
to solve and ca be addressed as a new revision of those pathes. However
I'm hoping other ones can be follup up patches instead.


Known issues:

  - There a known limitation in the DDB allocation code. It doesn't
    respect the minimal allocation of 8 blocks. When we're trying to
    scannout two planes (not counting the cursor) that have widely
    different data rates (1080p and 64x64), we'll under-allocate the
    small plane and hit underuns.

    (follow up series)

  - There are a fair number of patches that are just "|| IS_GEN9(dev)".
    I'd do a "let's by optimistic" pass on the driver to turn those into
    "gen >= 9" to try to limit the number of small patches in the
    future.

    (follow up series)

  - I haven't done a pass of the W/A just yet, waiting for things to
    settle a bit. In particular I haven't checked that the few W/A
    implemented can be done in init_clock_gating() or needs to be LRIs.
    (the patch predates all of that).

    (follow up series)

  - While looking at the patches before sending, I've noticed some
    extraneous defines in "Fix the extra defines in "drm/i915/skl: Read
    the Memory Latency Values for WM computation".

    Will send a new version of this patch rigth away

  - There's potential to unify the primary and sprite planes functions
    now that the primary plane is just another plane. This needs a bit
    of work to unify those paths.

    My current plan is to address this as a follow up series, not high
    priority.

  - Daniel had a few comments piped up already, the bigger ones have been
    addressed. I, however didn't look at this one

    < danvet> edp unconditionally uses cdclk/dpll0
    < danvet> but we don't track the port clock for that anywhere in the pipe
              config


Reviewers

some of the patches already have a r-b tag, having another look has some
value as patches get rebased and churned a bit. Some people have 2 lines
below.  

I've left some people out of the list as they're just jumping on the
list and give feedback already. If you expect some big delays in the
review, please do speak up so I can try to find somebody else.

Patches  1 to 20, excluding 12: Thomas Wood

Patches 12 + 21 to 42: Rodrigo

Patches 43 to 52: Ville (WM)

Patches 53 to 56: Mika (forcewake engine + a bit of rc6)

Patch 57 is already merged

Patches 58 to 68: Paulo (DPLL + removal of the eDP training W/A)

Patches 69 to 73: Imre (Power wells)

Patches 74 to 75: Paulo (queue_flip, pfit)

Patches 76 to 83: Ville (WM part2)

Patch 84 to 89: Mika (turbo and various small patches, some of them already
                dropped and/or reviewed)

Thanks,

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 77/89] drm/i915: Introduce a for_each_plane() macro
  2014-09-04 14:05       ` Damien Lespiau
@ 2014-09-04 14:16         ` Daniel Vetter
  0 siblings, 0 replies; 286+ messages in thread
From: Daniel Vetter @ 2014-09-04 14:16 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 03:05:11PM +0100, Damien Lespiau wrote:
> On Thu, Sep 04, 2014 at 04:00:32PM +0200, Daniel Vetter wrote:
> > On Thu, Sep 04, 2014 at 02:32:47PM +0100, Chris Wilson wrote:
> > > On Thu, Sep 04, 2014 at 12:27:43PM +0100, Damien Lespiau wrote:
> > > > Tired of copy/pasting things around.
> > > > 
> > > > v2: Rebase on top of the for_each_pipe() change adding dev_priv as first
> > > >     argument.
> > > > 
> > > > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/i915_drv.h | 2 ++
> > > >  1 file changed, 2 insertions(+)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > > > index 91ea2b7..95e57dc 100644
> > > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > > @@ -176,6 +176,8 @@ enum hpd_pin {
> > > >  
> > > >  #define for_each_pipe(__dev_priv, __p) \
> > > >  	for ((__p) = 0; (__p) < INTEL_INFO(__dev_priv)->num_pipes; (__p)++)
> > > > +#define for_each_plane(pipe, p) \
> > > > +	for ((p) = 0; (p) < INTEL_INFO(dev)->num_sprites[(pipe)] + 1; (p)++)
> > > 
> > > We are adding new magic macros taking dev...
> > > 
> > > >  #define for_each_sprite(p, s) for ((s) = 0; (s) < INTEL_INFO(dev)->num_sprites[(p)]; (s)++)
> > > I haven't asked you to fix this one yet either.
> > 
> > Ok, dropping again for now ...
> 
> The problem is that I then need to touch the patches that depend on it,
> some not very interesting manipulations. Can't we have this as is and
> I'll fix later?

Ok.

Queued for -next again, thanks for the patch.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 05/89] drm/i915/skl: i915_swizzle_info gen9 fix
  2014-09-04 13:14   ` Daniel Vetter
@ 2014-09-04 15:26     ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 15:26 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 03:14:45PM +0200, Daniel Vetter wrote:
> On Thu, Sep 04, 2014 at 12:26:31PM +0100, Damien Lespiau wrote:
> > From: Robert Beckett <robert.beckett@intel.com>
> > 
> > Fix ARB_MODE register read for gen >= 8 in i915_swizzle_info
> > 
> > Signed-off-by: Robert Beckett <robert.beckett@intel.com>
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> 
> given that the swizzle stuff is gone, shouldn't we just have a gen9+
> check to do nothing?

Well, the swizzled bits are still in the SKL docs, they are really not
expected to be used though. We can either still dump them in that
debugfs file, or nothing at all. I vote for keeping the dump "just in
case", but I can see the alternative working as well. No strong opinion
either way.

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 86/89] drm/i915: only reset media, blt, and render engines on GPU hangs
  2014-09-04 12:29     ` Damien Lespiau
  2014-09-04 13:13       ` Daniel Vetter
@ 2014-09-04 15:46       ` Jesse Barnes
  1 sibling, 0 replies; 286+ messages in thread
From: Jesse Barnes @ 2014-09-04 15:46 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, 4 Sep 2014 13:29:06 +0100
Damien Lespiau <damien.lespiau@intel.com> wrote:

> On Thu, Sep 04, 2014 at 03:03:27PM +0300, Jani Nikula wrote:
> > On Thu, 04 Sep 2014, Damien Lespiau <damien.lespiau@intel.com> wrote:
> > > From: Jesse Barnes <jbarnes@virtuousgeek.org>
> > >
> > > No need to mess with display.
> > 
> > Why is this patch part of the skl enabling series? The commit message is
> > a bit thin on the details too...
> 
> I did hesitate with this one, this is indeed orthogonal to SKL enabling
> and was just a shot in the dark.
> 
> Jesse, do you mind if we just drop this one?

Yeah it doesn't belong in the SKL series.  But iirc it's been
outstanding for awhile from different authors.  Does anyone remember
why we haven't merged something like this yet?

-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 286+ messages in thread

* [PATCH 43/89 v6] drm/i915/skl: Read the Memory Latency Values for WM computation
  2014-09-04 11:27 ` [PATCH 43/89] drm/i915/skl: Read the Memory Latency Values for WM computation Damien Lespiau
@ 2014-09-04 18:49   ` Damien Lespiau
  2014-09-10 17:37     ` Ville Syrjälä
  2014-09-05  8:25   ` [PATCH 43/89] " Ville Syrjälä
  1 sibling, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 18:49 UTC (permalink / raw)
  To: intel-gfx; +Cc: Pradeep Bhat

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch reads the memory latency values for all the 8 levels for
SKL. These values are needed for the Watermark computation.

v2: Incorporated the review comments from Damien on register
    indentation.

v3: Updated the code to use the sandybridge_pcode_read for reading
    memory latencies for GEN9.

v4: Don't put gen 9 in the middle of an ordered list of ifs
    (Damien)

v5: take the rps.hw_lock around sandybridge_pcode_read() (Damien)

v6: Use gen >= 9 in the pcode_read() function for data1.
    Move the defines near the gen6 ones and prefix them with PCODE.
    Remove unused timeout define (the pcode_read() code has a larger
    timeout already).

Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h |  6 ++++
 drivers/gpu/drm/i915/i915_reg.h |  7 ++++
 drivers/gpu/drm/i915/intel_pm.c | 76 +++++++++++++++++++++++++++++++++++++----
 3 files changed, 83 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index dcd1c72..32be299 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1665,6 +1665,12 @@ struct drm_i915_private {
 		uint16_t spr_latency[5];
 		/* cursor */
 		uint16_t cur_latency[5];
+		/*
+		 * Raw watermark memory latency values
+		 * for SKL for all 8 levels
+		 * in 1us units.
+		 */
+		uint16_t skl_latency[8];
 
 		/* current hardware state */
 		struct ilk_wm_values hw;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 0159f2d..6785d51 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5855,6 +5855,13 @@ enum punit_power_well {
 #define   GEN6_PCODE_FREQ_IA_RATIO_SHIFT	8
 #define   GEN6_PCODE_FREQ_RING_RATIO_SHIFT	16
 
+#define GEN9_PCODE_DATA1			0x13812C
+#define   GEN9_PCODE_READ_MEM_LATENCY		0x6
+#define   GEN9_MEM_LATENCY_LEVEL_MASK		0xFF
+#define   GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT	8
+#define   GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT	16
+#define   GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT	24
+
 #define GEN6_GT_CORE_STATUS		0x138060
 #define   GEN6_CORE_CPD_STATE_MASK	(7<<4)
 #define   GEN6_RCn_MASK			7
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a236e77..2774db1 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2239,11 +2239,56 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)
 	       PIPE_WM_LINETIME_TIME(linetime);
 }
 
-static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[5])
+static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+	if (IS_GEN9(dev)) {
+		uint32_t val;
+		int ret;
+
+		/* read the first set of memory latencies[0:3] */
+		val = 0; /* data0 to be programmed to 0 for first set */
+		mutex_lock(&dev_priv->rps.hw_lock);
+		ret = sandybridge_pcode_read(dev_priv,
+					     GEN9_PCODE_READ_MEM_LATENCY,
+					     &val);
+		mutex_unlock(&dev_priv->rps.hw_lock);
+
+		if (ret) {
+			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
+			return;
+		}
+
+		wm[0] = val & GEN9_MEM_LATENCY_LEVEL_MASK;
+		wm[1] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) &
+				GEN9_MEM_LATENCY_LEVEL_MASK;
+		wm[2] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) &
+				GEN9_MEM_LATENCY_LEVEL_MASK;
+		wm[3] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) &
+				GEN9_MEM_LATENCY_LEVEL_MASK;
+
+		/* read the second set of memory latencies[4:7] */
+		val = 1; /* data0 to be programmed to 1 for second set */
+		mutex_lock(&dev_priv->rps.hw_lock);
+		ret = sandybridge_pcode_read(dev_priv,
+					     GEN9_PCODE_READ_MEM_LATENCY,
+					     &val);
+		mutex_unlock(&dev_priv->rps.hw_lock);
+		if (ret) {
+			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
+			return;
+		}
+
+		wm[4] = val & GEN9_MEM_LATENCY_LEVEL_MASK;
+		wm[5] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) &
+				GEN9_MEM_LATENCY_LEVEL_MASK;
+		wm[6] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) &
+				GEN9_MEM_LATENCY_LEVEL_MASK;
+		wm[7] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) &
+				GEN9_MEM_LATENCY_LEVEL_MASK;
+
+	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
 		uint64_t sskpd = I915_READ64(MCH_SSKPD);
 
 		wm[0] = (sskpd >> 56) & 0xFF;
@@ -2291,7 +2336,9 @@ static void intel_fixup_cur_wm_latency(struct drm_device *dev, uint16_t wm[5])
 int ilk_wm_max_level(const struct drm_device *dev)
 {
 	/* how many WM levels are we expecting */
-	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+	if (IS_GEN9(dev))
+		return 7;
+	else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
 		return 4;
 	else if (INTEL_INFO(dev)->gen >= 6)
 		return 3;
@@ -2300,7 +2347,7 @@ int ilk_wm_max_level(const struct drm_device *dev)
 }
 static void intel_print_wm_latency(struct drm_device *dev,
 				   const char *name,
-				   const uint16_t wm[5])
+				   const uint16_t wm[8])
 {
 	int level, max_level = ilk_wm_max_level(dev);
 
@@ -2313,8 +2360,13 @@ static void intel_print_wm_latency(struct drm_device *dev,
 			continue;
 		}
 
-		/* WM1+ latency values in 0.5us units */
-		if (level > 0)
+		/*
+		 * - latencies are in us on gen9.
+		 * - before then, WM1+ latency values are in 0.5us units
+		 */
+		if (IS_GEN9(dev))
+			latency *= 10;
+		else if (level > 0)
 			latency *= 5;
 
 		DRM_DEBUG_KMS("%s WM%d latency %u (%u.%u usec)\n",
@@ -2382,6 +2434,14 @@ static void ilk_setup_wm_latency(struct drm_device *dev)
 		snb_wm_latency_quirk(dev);
 }
 
+static void skl_setup_wm_latency(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	intel_read_wm_latency(dev, dev_priv->wm.skl_latency);
+	intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
+}
+
 static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
 				      struct ilk_pipe_wm_parameters *p)
 {
@@ -7396,6 +7456,8 @@ void intel_init_pm(struct drm_device *dev)
 
 	/* For FIFO watermark updates */
 	if (IS_GEN9(dev)) {
+		skl_setup_wm_latency(dev);
+
 		dev_priv->display.init_clock_gating = gen9_init_clock_gating;
 	} else if (HAS_PCH_SPLIT(dev)) {
 		ilk_setup_wm_latency(dev);
@@ -7488,6 +7550,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val)
 	}
 
 	I915_WRITE(GEN6_PCODE_DATA, *val);
+	if (INTEL_INFO(dev_priv)->gen >= 9)
+		I915_WRITE(GEN9_PCODE_DATA1, 0);
 	I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox);
 
 	if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 15/89 v7] drm/i915/skl: Program the DDI buffer translation tables
  2014-09-04 11:26 ` [PATCH 15/89] drm/i915/skl: Program the DDI buffer translation tables Damien Lespiau
@ 2014-09-04 18:58   ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-04 18:58 UTC (permalink / raw)
  To: intel-gfx

A couple of things have changed compared to Broadwell:
  - Entry 9 is used for eDP
  - No more FDI

v2: Update the translation values to latest specs.
v3: Rebase on top of the BDW HDMI translation patch
v4: Remove the low voltage edp tables,
    Rebase on top of the patch not writing the HDMI entry on eDP/FDI
    DDIs (Satheesh, Paulo).
v5: Apply the / 2 fix for the number of HDMI entries (Satheesh)
v6: Rebase on top of Jani's clean up for the DDI_BUF_TRANS tables
v7: Restore the commit message that was mangled by error

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 40 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index eed9a2a..64eda53 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -127,6 +127,32 @@ static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
 	{ 0x80FFFFFF, 0x001B0002 },	/* 9:	1000	1000	0	*/
 };
 
+static const struct ddi_buf_trans skl_ddi_translations_dp[] = {
+	{ 0x00000018, 0x000000a0 },
+	{ 0x00004014, 0x00000098 },
+	{ 0x00006012, 0x00000088 },
+	{ 0x00008010, 0x00000080 },
+	{ 0x00000018, 0x00000098 },
+	{ 0x00004014, 0x00000088 },
+	{ 0x00006012, 0x00000080 },
+	{ 0x00000018, 0x00000088 },
+	{ 0x00004014, 0x00000080 },
+};
+
+static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = {
+					/* Idx	NT mV   T mV    db  */
+	{ 0x00000018, 0x000000a0 },	/* 0:	400	400	0   */
+	{ 0x00004014, 0x00000098 },	/* 1:	400	600	3.5 */
+	{ 0x00006012, 0x00000088 },	/* 2:	400	800	6   */
+	{ 0x00000018, 0x0000003c },	/* 3:	450	450	0   */
+	{ 0x00000018, 0x00000098 },	/* 4:	600	600	0   */
+	{ 0x00003015, 0x00000088 },	/* 5:	600	800	2.5 */
+	{ 0x00005013, 0x00000080 },	/* 6:	600	1000	4.5 */
+	{ 0x00000018, 0x00000088 },	/* 7:	800	800	0   */
+	{ 0x00000096, 0x00000080 },	/* 8:	800	1000	2   */
+	{ 0x00000018, 0x00000080 },	/* 9:	1200	1200	0   */
+};
+
 enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
@@ -169,7 +195,14 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port)
 	const struct ddi_buf_trans *ddi_translations_hdmi;
 	const struct ddi_buf_trans *ddi_translations;
 
-	if (IS_BROADWELL(dev)) {
+	if (IS_SKYLAKE(dev)) {
+		ddi_translations_fdi = NULL;
+		ddi_translations_dp = skl_ddi_translations_dp;
+		ddi_translations_edp = skl_ddi_translations_dp;
+		ddi_translations_hdmi = skl_ddi_translations_hdmi;
+		n_hdmi_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
+		hdmi_800mV_0dB = 7;
+	} else if (IS_BROADWELL(dev)) {
 		ddi_translations_fdi = bdw_ddi_translations_fdi;
 		ddi_translations_dp = bdw_ddi_translations_dp;
 		ddi_translations_edp = bdw_ddi_translations_edp;
@@ -208,7 +241,10 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port)
 			ddi_translations = ddi_translations_dp;
 		break;
 	case PORT_E:
-		ddi_translations = ddi_translations_fdi;
+		if (ddi_translations_fdi)
+			ddi_translations = ddi_translations_fdi;
+		else
+			ddi_translations = ddi_translations_dp;
 		break;
 	default:
 		BUG();
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* Re: [PATCH 43/89] drm/i915/skl: Read the Memory Latency Values for WM computation
  2014-09-04 11:27 ` [PATCH 43/89] drm/i915/skl: Read the Memory Latency Values for WM computation Damien Lespiau
  2014-09-04 18:49   ` [PATCH 43/89 v6] " Damien Lespiau
@ 2014-09-05  8:25   ` Ville Syrjälä
  2014-09-05  8:29     ` Damien Lespiau
  1 sibling, 1 reply; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-05  8:25 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx, Pradeep Bhat

On Thu, Sep 04, 2014 at 12:27:09PM +0100, Damien Lespiau wrote:
> From: Pradeep Bhat <pradeep.bhat@intel.com>
> 
> This patch reads the memory latency values for all the 8 levels for
> SKL. These values are needed for the Watermark computation.
> 
> v2: Incorporated the review comments from Damien on register
>     indentation.
> 
> v3: Updated the code to use the sandybridge_pcode_read for reading
>     memory latencies for GEN9.
> 
> v4: Don't put gen 9 in the middle of an ordered list of ifs
>     (Damien)
> 
> v5 take the rps.hw_lock around sandybridge_pcode_read() (Damien)
> 
> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h |  6 ++++
>  drivers/gpu/drm/i915/i915_reg.h |  9 +++++
>  drivers/gpu/drm/i915/intel_pm.c | 73 +++++++++++++++++++++++++++++++++++++----
>  3 files changed, 82 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index dcd1c72..32be299 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1665,6 +1665,12 @@ struct drm_i915_private {
>  		uint16_t spr_latency[5];
>  		/* cursor */
>  		uint16_t cur_latency[5];
> +		/*
> +		 * Raw watermark memory latency values
> +		 * for SKL for all 8 levels
> +		 * in 1us units.
> +		 */
> +		uint16_t skl_latency[8];

Not sure if we could unify these somehow to avoid wasted space. But that
can be left as a future exercise.

>  
>  		/* current hardware state */
>  		struct ilk_wm_values hw;
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 0159f2d..bc55990 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -2018,6 +2018,15 @@ enum punit_power_well {
>  #define   MAD_DIMM_A_SIZE_SHIFT		0
>  #define   MAD_DIMM_A_SIZE_MASK		(0xff << MAD_DIMM_A_SIZE_SHIFT)
>  
> +/* SKL GT Driver Mailbox registers for reading memory latencies */
> +#define GEN9_MAILBOX_DATA1		0x13812C
> +#define   GEN9_MAILBOX_READ_MEM_LAT	(0x6)
> +#define   GEN9_MAILBOX_READ_TIMEOUT	150

Timeout not used anywhere. Also spec says 100us.

> +#define   GEN9_MEM_LAT_LEVEL_MASK	0xFF
> +#define   GEN9_MEM_LAT_LEVEL_1_5_SHIFT	8
> +#define   GEN9_MEM_LAT_LEVEL_2_6_SHIFT	16
> +#define   GEN9_MEM_LAT_LEVEL_3_7_SHIFT	24

This stuff should be grouped along the other pcode register defines.

Also according to Bspec the mailbox data1 register already existed since
snb. The hsw cdclk change sequence also mentions that it should be set
to 0, but eg. the bdw IPS sequence doesn't mention it. I guess in theory
some pcode command might cause it to be clobbered, so I'm thinking we
should just explicitly set it to 0 for all platforms in the pcode
read/write functions. That should be a separate patch though.

> +
>  /* snb MCH registers for priority tuning */
>  #define MCH_SSKPD			(MCHBAR_MIRROR_BASE_SNB + 0x5d10)
>  #define   MCH_SSKPD_WM0_MASK		0x3f
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index a236e77..d8c8531 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2239,11 +2239,53 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)
>  	       PIPE_WM_LINETIME_TIME(linetime);
>  }
>  
> -static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[5])
> +static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  
> -	if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
> +	if (IS_GEN9(dev)) {
> +		uint32_t val;
> +		int ret;
> +
> +		/* read the first set of memory latencies[0:3] */
> +		val = 0; /* data0 to be programmed to 0 for first set */
> +		mutex_lock(&dev_priv->rps.hw_lock);
> +		ret = sandybridge_pcode_read(dev_priv,
> +					     GEN9_MAILBOX_READ_MEM_LAT,
> +					     &val);
> +		mutex_unlock(&dev_priv->rps.hw_lock);
> +
> +		if (ret) {
> +			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
> +			return;
> +		}
> +		wm[0] = val & GEN9_MEM_LAT_LEVEL_MASK;
> +		wm[1] = (val >> GEN9_MEM_LAT_LEVEL_1_5_SHIFT) &
> +				GEN9_MEM_LAT_LEVEL_MASK;
> +		wm[2] = (val >> GEN9_MEM_LAT_LEVEL_2_6_SHIFT) &
> +				GEN9_MEM_LAT_LEVEL_MASK;
> +		wm[3] = (val >> GEN9_MEM_LAT_LEVEL_3_7_SHIFT) &
> +				GEN9_MEM_LAT_LEVEL_MASK;
> +
> +		/* read the second set of memory latencies[4:7] */
> +		val = 1; /* data0 to be programmed to 1 for second set */
> +		mutex_lock(&dev_priv->rps.hw_lock);
> +		ret = sandybridge_pcode_read(dev_priv,
> +					     GEN9_MAILBOX_READ_MEM_LAT,
> +					     &val);
> +		mutex_unlock(&dev_priv->rps.hw_lock);
> +		if (ret) {
> +			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
> +			return;
> +		}
> +		wm[4] = val & GEN9_MEM_LAT_LEVEL_MASK;
> +		wm[5] = (val >> GEN9_MEM_LAT_LEVEL_1_5_SHIFT) &
> +				GEN9_MEM_LAT_LEVEL_MASK;
> +		wm[6] = (val >> GEN9_MEM_LAT_LEVEL_2_6_SHIFT) &
> +				GEN9_MEM_LAT_LEVEL_MASK;
> +		wm[7] = (val >> GEN9_MEM_LAT_LEVEL_3_7_SHIFT) &
> +				GEN9_MEM_LAT_LEVEL_MASK;
> +	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
>  		uint64_t sskpd = I915_READ64(MCH_SSKPD);
>  
>  		wm[0] = (sskpd >> 56) & 0xFF;
> @@ -2291,7 +2333,9 @@ static void intel_fixup_cur_wm_latency(struct drm_device *dev, uint16_t wm[5])
>  int ilk_wm_max_level(const struct drm_device *dev)
>  {
>  	/* how many WM levels are we expecting */
> -	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
> +	if (IS_GEN9(dev))
> +		return 7;
> +	else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>  		return 4;
>  	else if (INTEL_INFO(dev)->gen >= 6)
>  		return 3;
> @@ -2300,7 +2344,7 @@ int ilk_wm_max_level(const struct drm_device *dev)
>  }
>  static void intel_print_wm_latency(struct drm_device *dev,
>  				   const char *name,
> -				   const uint16_t wm[5])
> +				   const uint16_t wm[8])
>  {
>  	int level, max_level = ilk_wm_max_level(dev);
>  
> @@ -2313,8 +2357,13 @@ static void intel_print_wm_latency(struct drm_device *dev,
>  			continue;
>  		}
>  
> -		/* WM1+ latency values in 0.5us units */
> -		if (level > 0)
> +		/*
> +		 * - latencies are in us on gen9.
> +		 * - before then, WM1+ latency values are in 0.5us units
> +		 */
> +		if (IS_GEN9(dev))
> +			latency *= 10;
> +		else if (level > 0)
>  			latency *= 5;
>  
>  		DRM_DEBUG_KMS("%s WM%d latency %u (%u.%u usec)\n",
> @@ -2382,6 +2431,14 @@ static void ilk_setup_wm_latency(struct drm_device *dev)
>  		snb_wm_latency_quirk(dev);
>  }
>  
> +static void skl_setup_wm_latency(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +
> +	intel_read_wm_latency(dev, dev_priv->wm.skl_latency);
> +	intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
> +}
> +
>  static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
>  				      struct ilk_pipe_wm_parameters *p)
>  {
> @@ -7396,6 +7453,8 @@ void intel_init_pm(struct drm_device *dev)
>  
>  	/* For FIFO watermark updates */
>  	if (IS_GEN9(dev)) {
> +		skl_setup_wm_latency(dev);
> +
>  		dev_priv->display.init_clock_gating = gen9_init_clock_gating;
>  	} else if (HAS_PCH_SPLIT(dev)) {
>  		ilk_setup_wm_latency(dev);
> @@ -7488,6 +7547,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val)
>  	}
>  
>  	I915_WRITE(GEN6_PCODE_DATA, *val);
> +	if (IS_GEN9(dev_priv->dev))
> +		I915_WRITE(GEN9_MAILBOX_DATA1, 0);
>  	I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox);
>  
>  	if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 43/89] drm/i915/skl: Read the Memory Latency Values for WM computation
  2014-09-05  8:25   ` [PATCH 43/89] " Ville Syrjälä
@ 2014-09-05  8:29     ` Damien Lespiau
  2014-09-05  8:42       ` Ville Syrjälä
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-05  8:29 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, Pradeep Bhat

On Fri, Sep 05, 2014 at 11:25:30AM +0300, Ville Syrjälä wrote:
> > +/* SKL GT Driver Mailbox registers for reading memory latencies */
> > +#define GEN9_MAILBOX_DATA1		0x13812C
> > +#define   GEN9_MAILBOX_READ_MEM_LAT	(0x6)
> > +#define   GEN9_MAILBOX_READ_TIMEOUT	150
> 
> Timeout not used anywhere. Also spec says 100us.
> 
> > +#define   GEN9_MEM_LAT_LEVEL_MASK	0xFF
> > +#define   GEN9_MEM_LAT_LEVEL_1_5_SHIFT	8
> > +#define   GEN9_MEM_LAT_LEVEL_2_6_SHIFT	16
> > +#define   GEN9_MEM_LAT_LEVEL_3_7_SHIFT	24
> 
> This stuff should be grouped along the other pcode register defines.

Funny you mention this, I fixed those two in the v6 sent as reply
yesterday.

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 43/89] drm/i915/skl: Read the Memory Latency Values for WM computation
  2014-09-05  8:29     ` Damien Lespiau
@ 2014-09-05  8:42       ` Ville Syrjälä
  2014-09-05 12:56         ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-05  8:42 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx, Pradeep Bhat

On Fri, Sep 05, 2014 at 09:29:33AM +0100, Damien Lespiau wrote:
> On Fri, Sep 05, 2014 at 11:25:30AM +0300, Ville Syrjälä wrote:
> > > +/* SKL GT Driver Mailbox registers for reading memory latencies */
> > > +#define GEN9_MAILBOX_DATA1		0x13812C
> > > +#define   GEN9_MAILBOX_READ_MEM_LAT	(0x6)
> > > +#define   GEN9_MAILBOX_READ_TIMEOUT	150
> > 
> > Timeout not used anywhere. Also spec says 100us.
> > 
> > > +#define   GEN9_MEM_LAT_LEVEL_MASK	0xFF
> > > +#define   GEN9_MEM_LAT_LEVEL_1_5_SHIFT	8
> > > +#define   GEN9_MEM_LAT_LEVEL_2_6_SHIFT	16
> > > +#define   GEN9_MEM_LAT_LEVEL_3_7_SHIFT	24
> > 
> > This stuff should be grouped along the other pcode register defines.
> 
> Funny you mention this, I fixed those two in the v6 sent as reply
> yesterday.

Well that's two down then. I should stop composing mails the previous
day and then forgetting to send them and firing them off the next day
without checking if they still make sense :)

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 43/89] drm/i915/skl: Read the Memory Latency Values for WM computation
  2014-09-05  8:42       ` Ville Syrjälä
@ 2014-09-05 12:56         ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-05 12:56 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, Pradeep Bhat

On Fri, Sep 05, 2014 at 11:42:32AM +0300, Ville Syrjälä wrote:
> On Fri, Sep 05, 2014 at 09:29:33AM +0100, Damien Lespiau wrote:
> > On Fri, Sep 05, 2014 at 11:25:30AM +0300, Ville Syrjälä wrote:
> > > > +/* SKL GT Driver Mailbox registers for reading memory latencies */
> > > > +#define GEN9_MAILBOX_DATA1		0x13812C
> > > > +#define   GEN9_MAILBOX_READ_MEM_LAT	(0x6)
> > > > +#define   GEN9_MAILBOX_READ_TIMEOUT	150
> > > 
> > > Timeout not used anywhere. Also spec says 100us.
> > > 
> > > > +#define   GEN9_MEM_LAT_LEVEL_MASK	0xFF
> > > > +#define   GEN9_MEM_LAT_LEVEL_1_5_SHIFT	8
> > > > +#define   GEN9_MEM_LAT_LEVEL_2_6_SHIFT	16
> > > > +#define   GEN9_MEM_LAT_LEVEL_3_7_SHIFT	24
> > > 
> > > This stuff should be grouped along the other pcode register defines.
> > 
> > Funny you mention this, I fixed those two in the v6 sent as reply
> > yesterday.
> 
> Well that's two down then.

The other 2 items were marked as "patch on top is fine/better", so I
guess it's now r-b material?

In any case, addressed the 2 points you raised separately.

  http://lists.freedesktop.org/archives/intel-gfx/2014-September/052008.html

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 53/89] drm/i915/skl: Gen9 Forcewake
  2014-09-04 11:27 ` [PATCH 53/89] drm/i915/skl: Gen9 Forcewake Damien Lespiau
@ 2014-09-10 13:44   ` Mika Kuoppala
  2014-09-16 13:49     ` [PATCH 53/89 v2] " Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Mika Kuoppala @ 2014-09-10 13:44 UTC (permalink / raw)
  To: Damien Lespiau, intel-gfx

Damien Lespiau <damien.lespiau@intel.com> writes:

> From: Zhe Wang <zhe1.wang@intel.com>
>
> Implement common forcewake functions shared by Gen9 features.
>
> Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h     |   5 +-
>  drivers/gpu/drm/i915/i915_reg.h     |   6 ++
>  drivers/gpu/drm/i915/intel_uncore.c | 175 +++++++++++++++++++++++++++++++++++-
>  3 files changed, 184 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 9b0e398..84defa4 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -535,6 +535,7 @@ struct intel_uncore {
>  
>  	unsigned fw_rendercount;
>  	unsigned fw_mediacount;
> +	unsigned fw_blittercount;
>  
>  	struct timer_list force_wake_timer;
>  };
> @@ -2950,7 +2951,9 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val);
>  
>  #define FORCEWAKE_RENDER	(1 << 0)
>  #define FORCEWAKE_MEDIA		(1 << 1)
> -#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | FORCEWAKE_MEDIA)
> +#define FORCEWAKE_BLITTER	(1 << 2)
> +#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | FORCEWAKE_MEDIA | \
> +					FORCEWAKE_BLITTER)
>  
>  
>  #define I915_READ8(reg)		dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true)
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 414c2a5..417075d 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -5738,6 +5738,12 @@ enum punit_power_well {
>  #define   VLV_GTLC_PW_MEDIA_STATUS_MASK		(1 << 5)
>  #define   VLV_GTLC_PW_RENDER_STATUS_MASK	(1 << 7)
>  #define  FORCEWAKE_MT				0xa188 /* multi-threaded */
> +#define  FORCEWAKE_MEDIA_GEN9			0xa270
> +#define  FORCEWAKE_RENDER_GEN9			0xa278
> +#define  FORCEWAKE_BLITTER_GEN9			0xa188
> +#define  FORCEWAKE_ACK_MEDIA_GEN9		0x0D88
> +#define  FORCEWAKE_ACK_RENDER_GEN9		0x0D84
> +#define  FORCEWAKE_ACK_BLITTER_GEN9		0x130044
>  #define   FORCEWAKE_KERNEL			0x1
>  #define   FORCEWAKE_USER			0x2
>  #define  FORCEWAKE_MT_ACK			0x130040
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 3b27fb0..7b7fc9e 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -299,6 +299,154 @@ static void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
>  
> +static void __gen9_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
> +{
> +	__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
> +			_MASKED_BIT_DISABLE(0xffff));
> +
> +	__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
> +			_MASKED_BIT_DISABLE(0xffff));
> +
> +	__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
> +			_MASKED_BIT_DISABLE(0xffff));
> +}
> +
> +static void __gen9_force_wake_get(struct drm_i915_private *dev_priv,
> +						int fw_engine)
> +{
> +	/* Check for Render Engine */
> +	if (FORCEWAKE_RENDER & fw_engine) {
> +		if (wait_for_atomic((__raw_i915_read32(dev_priv,
> +						FORCEWAKE_ACK_RENDER_GEN9) &
> +						FORCEWAKE_KERNEL) == 0,
> +					FORCEWAKE_ACK_TIMEOUT_MS))
> +			DRM_ERROR("Timed out: Render forcewake old ack to clear.\n");
> +
> +		__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
> +				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
> +
> +		if (wait_for_atomic((__raw_i915_read32(dev_priv,
> +						FORCEWAKE_ACK_RENDER_GEN9) &
> +						FORCEWAKE_KERNEL),
> +					FORCEWAKE_ACK_TIMEOUT_MS))
> +			DRM_ERROR("Timed out: waiting for Render to ack.\n");
> +	}
> +
> +	/* Check for Media Engine */
> +	if (FORCEWAKE_MEDIA & fw_engine) {
> +		if (wait_for_atomic((__raw_i915_read32(dev_priv,
> +						FORCEWAKE_ACK_MEDIA_GEN9) &
> +						FORCEWAKE_KERNEL) == 0,
> +					FORCEWAKE_ACK_TIMEOUT_MS))
> +			DRM_ERROR("Timed out: Media forcewake old ack to clear.\n");
> +
> +		__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
> +				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
> +
> +		if (wait_for_atomic((__raw_i915_read32(dev_priv,
> +						FORCEWAKE_ACK_MEDIA_GEN9) &
> +						FORCEWAKE_KERNEL),
> +					FORCEWAKE_ACK_TIMEOUT_MS))
> +			DRM_ERROR("Timed out: waiting for Media to ack.\n");
> +	}
> +
> +	/* Check for Blitter Engine */
> +	if (FORCEWAKE_BLITTER & fw_engine) {
> +		if (wait_for_atomic((__raw_i915_read32(dev_priv,
> +						FORCEWAKE_ACK_BLITTER_GEN9) &
> +						FORCEWAKE_KERNEL) == 0,
> +					FORCEWAKE_ACK_TIMEOUT_MS))
> +			DRM_ERROR("Timed out: Blitter forcewake old ack to clear.\n");
> +
> +		__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
> +				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
> +
> +		if (wait_for_atomic((__raw_i915_read32(dev_priv,
> +						FORCEWAKE_ACK_BLITTER_GEN9) &
> +						FORCEWAKE_KERNEL),
> +					FORCEWAKE_ACK_TIMEOUT_MS))
> +			DRM_ERROR("Timed out: waiting for Blitter to ack.\n");
> +	}
> +}
> +
> +static void __gen9_force_wake_put(struct drm_i915_private *dev_priv,
> +					int fw_engine)
> +{
> +	/* Check for Render Engine */
> +	if (FORCEWAKE_RENDER & fw_engine)
> +		__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
> +				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
> +
> +	/* Check for Media Engine */
> +	if (FORCEWAKE_MEDIA & fw_engine)
> +		__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
> +				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
> +
> +	/* Check for Blitter Engine */
> +	if (FORCEWAKE_BLITTER & fw_engine)
> +		__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
> +				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
> +}
> +
> +void gen9_force_wake_get(struct drm_i915_private *dev_priv,
> +						int fw_engine)

static missing

> +{
> +	unsigned long irqflags;
> +
> +	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> +
> +	if (FORCEWAKE_RENDER & fw_engine) {
> +		if (dev_priv->uncore.fw_rendercount++ == 0)
> +			dev_priv->uncore.funcs.force_wake_get(dev_priv,
> +							FORCEWAKE_RENDER);
> +	}
> +
> +	if (FORCEWAKE_MEDIA & fw_engine) {
> +		if (dev_priv->uncore.fw_mediacount++ == 0)
> +			dev_priv->uncore.funcs.force_wake_get(dev_priv,
> +							FORCEWAKE_MEDIA);
> +	}
> +
> +	if (FORCEWAKE_BLITTER & fw_engine) {
> +		if (dev_priv->uncore.fw_blittercount++ == 0)
> +			dev_priv->uncore.funcs.force_wake_get(dev_priv,
> +							FORCEWAKE_BLITTER);
> +	}
> +
> +	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> +}
> +
> +void gen9_force_wake_put(struct drm_i915_private *dev_priv,
> +						int fw_engine)

static missing

above statics added it is:

Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>

> +{
> +	unsigned long irqflags;
> +
> +	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> +
> +	if (FORCEWAKE_RENDER & fw_engine) {
> +		WARN_ON(dev_priv->uncore.fw_rendercount == 0);
> +		if (--dev_priv->uncore.fw_rendercount == 0)
> +			dev_priv->uncore.funcs.force_wake_put(dev_priv,
> +							FORCEWAKE_RENDER);
> +	}
> +
> +	if (FORCEWAKE_MEDIA & fw_engine) {
> +		WARN_ON(dev_priv->uncore.fw_mediacount == 0);
> +		if (--dev_priv->uncore.fw_mediacount == 0)
> +			dev_priv->uncore.funcs.force_wake_put(dev_priv,
> +							FORCEWAKE_MEDIA);
> +	}
> +
> +	if (FORCEWAKE_BLITTER & fw_engine) {
> +		WARN_ON(dev_priv->uncore.fw_blittercount == 0);
> +		if (--dev_priv->uncore.fw_blittercount == 0)
> +			dev_priv->uncore.funcs.force_wake_put(dev_priv,
> +							FORCEWAKE_BLITTER);
> +	}
> +
> +	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> +}
> +
>  static void gen6_force_wake_timer(unsigned long arg)
>  {
>  	struct drm_i915_private *dev_priv = (void *)arg;
> @@ -337,6 +485,9 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
>  	if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev))
>  		__gen7_gt_force_wake_mt_reset(dev_priv);
>  
> +	if (IS_GEN9(dev))
> +		__gen9_gt_force_wake_mt_reset(dev_priv);
> +
>  	if (restore) { /* If reset with a user forcewake, try to restore */
>  		unsigned fw = 0;
>  
> @@ -346,6 +497,15 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
>  
>  			if (dev_priv->uncore.fw_mediacount)
>  				fw |= FORCEWAKE_MEDIA;
> +		} else if (IS_GEN9(dev)) {
> +			if (dev_priv->uncore.fw_rendercount)
> +				fw |= FORCEWAKE_RENDER;
> +
> +			if (dev_priv->uncore.fw_mediacount)
> +				fw |= FORCEWAKE_MEDIA;
> +
> +			if (dev_priv->uncore.fw_blittercount)
> +				fw |= FORCEWAKE_BLITTER;
>  		} else {
>  			if (dev_priv->uncore.forcewake_count)
>  				fw = FORCEWAKE_ALL;
> @@ -410,6 +570,10 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
>  
>  	intel_runtime_pm_get(dev_priv);
>  
> +	/* Redirect to Gen9 specific routine */
> +	if (IS_GEN9(dev_priv->dev))
> +		return gen9_force_wake_get(dev_priv, fw_engine);
> +
>  	/* Redirect to VLV specific routine */
>  	if (IS_VALLEYVIEW(dev_priv->dev))
>  		return vlv_force_wake_get(dev_priv, fw_engine);
> @@ -431,6 +595,12 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>  	if (!dev_priv->uncore.funcs.force_wake_put)
>  		return;
>  
> +	/* Redirect to Gen9 specific routine */
> +	if (IS_GEN9(dev_priv->dev)) {
> +		gen9_force_wake_put(dev_priv, fw_engine);
> +		goto out;
> +	}
> +
>  	/* Redirect to VLV specific routine */
>  	if (IS_VALLEYVIEW(dev_priv->dev)) {
>  		vlv_force_wake_put(dev_priv, fw_engine);
> @@ -835,7 +1005,10 @@ void intel_uncore_init(struct drm_device *dev)
>  
>  	intel_uncore_early_sanitize(dev, false);
>  
> -	if (IS_VALLEYVIEW(dev)) {
> +	if (IS_GEN9(dev)) {
> +		dev_priv->uncore.funcs.force_wake_get = __gen9_force_wake_get;
> +		dev_priv->uncore.funcs.force_wake_put = __gen9_force_wake_put;
> +	} else if (IS_VALLEYVIEW(dev)) {
>  		dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get;
>  		dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put;
>  	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
> -- 
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 43/89 v6] drm/i915/skl: Read the Memory Latency Values for WM computation
  2014-09-04 18:49   ` [PATCH 43/89 v6] " Damien Lespiau
@ 2014-09-10 17:37     ` Ville Syrjälä
  0 siblings, 0 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-10 17:37 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx, Pradeep Bhat

On Thu, Sep 04, 2014 at 07:49:43PM +0100, Damien Lespiau wrote:
> From: Pradeep Bhat <pradeep.bhat@intel.com>
> 
> This patch reads the memory latency values for all the 8 levels for
> SKL. These values are needed for the Watermark computation.
> 
> v2: Incorporated the review comments from Damien on register
>     indentation.
> 
> v3: Updated the code to use the sandybridge_pcode_read for reading
>     memory latencies for GEN9.
> 
> v4: Don't put gen 9 in the middle of an ordered list of ifs
>     (Damien)
> 
> v5: take the rps.hw_lock around sandybridge_pcode_read() (Damien)
> 
> v6: Use gen >= 9 in the pcode_read() function for data1.
>     Move the defines near the gen6 ones and prefix them with PCODE.
>     Remove unused timeout define (the pcode_read() code has a larger
>     timeout already).
> 
> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

With the pcode gen6 stuff handled by the followup patch this is:
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/i915/i915_drv.h |  6 ++++
>  drivers/gpu/drm/i915/i915_reg.h |  7 ++++
>  drivers/gpu/drm/i915/intel_pm.c | 76 +++++++++++++++++++++++++++++++++++++----
>  3 files changed, 83 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index dcd1c72..32be299 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1665,6 +1665,12 @@ struct drm_i915_private {
>  		uint16_t spr_latency[5];
>  		/* cursor */
>  		uint16_t cur_latency[5];
> +		/*
> +		 * Raw watermark memory latency values
> +		 * for SKL for all 8 levels
> +		 * in 1us units.
> +		 */
> +		uint16_t skl_latency[8];
>  
>  		/* current hardware state */
>  		struct ilk_wm_values hw;
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 0159f2d..6785d51 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -5855,6 +5855,13 @@ enum punit_power_well {
>  #define   GEN6_PCODE_FREQ_IA_RATIO_SHIFT	8
>  #define   GEN6_PCODE_FREQ_RING_RATIO_SHIFT	16
>  
> +#define GEN9_PCODE_DATA1			0x13812C
> +#define   GEN9_PCODE_READ_MEM_LATENCY		0x6
> +#define   GEN9_MEM_LATENCY_LEVEL_MASK		0xFF
> +#define   GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT	8
> +#define   GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT	16
> +#define   GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT	24
> +
>  #define GEN6_GT_CORE_STATUS		0x138060
>  #define   GEN6_CORE_CPD_STATE_MASK	(7<<4)
>  #define   GEN6_RCn_MASK			7
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index a236e77..2774db1 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2239,11 +2239,56 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)
>  	       PIPE_WM_LINETIME_TIME(linetime);
>  }
>  
> -static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[5])
> +static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  
> -	if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
> +	if (IS_GEN9(dev)) {
> +		uint32_t val;
> +		int ret;
> +
> +		/* read the first set of memory latencies[0:3] */
> +		val = 0; /* data0 to be programmed to 0 for first set */
> +		mutex_lock(&dev_priv->rps.hw_lock);
> +		ret = sandybridge_pcode_read(dev_priv,
> +					     GEN9_PCODE_READ_MEM_LATENCY,
> +					     &val);
> +		mutex_unlock(&dev_priv->rps.hw_lock);
> +
> +		if (ret) {
> +			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
> +			return;
> +		}
> +
> +		wm[0] = val & GEN9_MEM_LATENCY_LEVEL_MASK;
> +		wm[1] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) &
> +				GEN9_MEM_LATENCY_LEVEL_MASK;
> +		wm[2] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) &
> +				GEN9_MEM_LATENCY_LEVEL_MASK;
> +		wm[3] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) &
> +				GEN9_MEM_LATENCY_LEVEL_MASK;
> +
> +		/* read the second set of memory latencies[4:7] */
> +		val = 1; /* data0 to be programmed to 1 for second set */
> +		mutex_lock(&dev_priv->rps.hw_lock);
> +		ret = sandybridge_pcode_read(dev_priv,
> +					     GEN9_PCODE_READ_MEM_LATENCY,
> +					     &val);
> +		mutex_unlock(&dev_priv->rps.hw_lock);
> +		if (ret) {
> +			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
> +			return;
> +		}
> +
> +		wm[4] = val & GEN9_MEM_LATENCY_LEVEL_MASK;
> +		wm[5] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) &
> +				GEN9_MEM_LATENCY_LEVEL_MASK;
> +		wm[6] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) &
> +				GEN9_MEM_LATENCY_LEVEL_MASK;
> +		wm[7] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) &
> +				GEN9_MEM_LATENCY_LEVEL_MASK;
> +
> +	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
>  		uint64_t sskpd = I915_READ64(MCH_SSKPD);
>  
>  		wm[0] = (sskpd >> 56) & 0xFF;
> @@ -2291,7 +2336,9 @@ static void intel_fixup_cur_wm_latency(struct drm_device *dev, uint16_t wm[5])
>  int ilk_wm_max_level(const struct drm_device *dev)
>  {
>  	/* how many WM levels are we expecting */
> -	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
> +	if (IS_GEN9(dev))
> +		return 7;
> +	else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>  		return 4;
>  	else if (INTEL_INFO(dev)->gen >= 6)
>  		return 3;
> @@ -2300,7 +2347,7 @@ int ilk_wm_max_level(const struct drm_device *dev)
>  }
>  static void intel_print_wm_latency(struct drm_device *dev,
>  				   const char *name,
> -				   const uint16_t wm[5])
> +				   const uint16_t wm[8])
>  {
>  	int level, max_level = ilk_wm_max_level(dev);
>  
> @@ -2313,8 +2360,13 @@ static void intel_print_wm_latency(struct drm_device *dev,
>  			continue;
>  		}
>  
> -		/* WM1+ latency values in 0.5us units */
> -		if (level > 0)
> +		/*
> +		 * - latencies are in us on gen9.
> +		 * - before then, WM1+ latency values are in 0.5us units
> +		 */
> +		if (IS_GEN9(dev))
> +			latency *= 10;
> +		else if (level > 0)
>  			latency *= 5;
>  
>  		DRM_DEBUG_KMS("%s WM%d latency %u (%u.%u usec)\n",
> @@ -2382,6 +2434,14 @@ static void ilk_setup_wm_latency(struct drm_device *dev)
>  		snb_wm_latency_quirk(dev);
>  }
>  
> +static void skl_setup_wm_latency(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +
> +	intel_read_wm_latency(dev, dev_priv->wm.skl_latency);
> +	intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
> +}
> +
>  static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
>  				      struct ilk_pipe_wm_parameters *p)
>  {
> @@ -7396,6 +7456,8 @@ void intel_init_pm(struct drm_device *dev)
>  
>  	/* For FIFO watermark updates */
>  	if (IS_GEN9(dev)) {
> +		skl_setup_wm_latency(dev);
> +
>  		dev_priv->display.init_clock_gating = gen9_init_clock_gating;
>  	} else if (HAS_PCH_SPLIT(dev)) {
>  		ilk_setup_wm_latency(dev);
> @@ -7488,6 +7550,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val)
>  	}
>  
>  	I915_WRITE(GEN6_PCODE_DATA, *val);
> +	if (INTEL_INFO(dev_priv)->gen >= 9)
> +		I915_WRITE(GEN9_PCODE_DATA1, 0);
>  	I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox);
>  
>  	if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 44/89] drm/i915/skl: Register definitions and macros for SKL Watermark regs
  2014-09-04 11:27 ` [PATCH 44/89] drm/i915/skl: Register definitions and macros for SKL Watermark regs Damien Lespiau
@ 2014-09-10 18:04   ` Ville Syrjälä
  2014-09-16 14:11     ` Damien Lespiau
  2014-09-17 13:40     ` [PATCH 44/89 v4] " Damien Lespiau
  2014-09-23 11:17   ` [PATCH 44/89 v5] " Damien Lespiau
  1 sibling, 2 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-10 18:04 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx, Pradeep Bhat

On Thu, Sep 04, 2014 at 12:27:10PM +0100, Damien Lespiau wrote:
> From: Pradeep Bhat <pradeep.bhat@intel.com>
> 
> This patch defines SKL specific PLANE_WM Watermark registers. It also
> defines macros to get the addresses of different LP levels within a pipe.
> 
> v2: Reworked the register definitions and associated macros to make it more
>     generic and be able to use for_each_pipe in values computation.
>     Incorporated Damien's review comments and indentation.
> 
> v3: Added default values for lines and blocks. Provided mask for blocks.
> 
> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h | 37 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 37 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index bc55990..9fbce2c 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4066,6 +4066,43 @@ enum punit_power_well {
>  #define I965_CURSOR_MAX_WM	32
>  #define I965_CURSOR_DFT_WM	8
>  
> +/* Watermark register definitions for SKL */
> +#define CUR_WM_A_0		0x70140
> +#define CUR_WM_B_0		0x71140
> +#define PLANE_WM_1_A_0		0x70240
> +#define PLANE_WM_1_B_0		0x71240
> +#define PLANE_WM_2_A_0		0x70340
> +#define PLANE_WM_2_B_0		0x71340
> +#define PLANE_WM_TRANS_1_A_0	0x70268
> +#define PLANE_WM_TRANS_1_B_0	0x71268
> +#define PLANE_WM_TRANS_2_A_0	0x70368
> +#define PLANE_WM_TRANS_2_B_0	0x71368
> +#define CUR_WM_TRANS_A_0	0x70168
> +#define CUR_WM_TRANS_B_0	0x71168
> +#define   PLANE_WM_EN		(1 << 31)
> +#define   PLANE_WM_LINES_SHIFT	14
> +#define   PLANE_WM_LINES_MASK	0x1f
> +#define   PLANE_WM_BLOCKS_MASK	0x3ff
> +#define   PLANE_WM_LINES_DEFAULT	0x1
> +#define   PLANE_WM_BLOCKS_DEFAULT	0x7
> +

These numbers seemed to make sense when I tried to compare with the
spec.

> +#define CUR_WM_0(pipe) _PIPE(pipe, CUR_WM_A_0, CUR_WM_B_0)
> +#define CUR_WM(pipe, level) (CUR_WM_0(pipe) + ((4) * (level)))
> +#define CUR_WM_TRANS(pipe) _PIPE(pipe, CUR_WM_TRANS_A_0, CUR_WM_TRANS_B_0)
> +
> +#define PLANE_WM_1(pipe) _PIPE(pipe, PLANE_WM_1_A_0, PLANE_WM_1_B_0)
> +#define PLANE_WM_2(pipe) _PIPE(pipe, PLANE_WM_2_A_0, PLANE_WM_2_B_0)
> +#define PLANE_WM_BASE(pipe, plane)	\
> +			_PLANE(plane, PLANE_WM_1(pipe), PLANE_WM_2(pipe))
> +#define PLANE_WM(pipe, plane, level)	\
> +			(PLANE_WM_BASE(pipe, plane) + ((4) * (level)))
> +#define PLANE_WM_TRANS_1(pipe)		\
> +			_PIPE(pipe, PLANE_WM_TRANS_1_A_0, PLANE_WM_TRANS_1_B_0)
> +#define PLANE_WM_TRANS_2(pipe)		\
> +			_PIPE(pipe, PLANE_WM_TRANS_2_A_0, PLANE_WM_TRANS_2_B_0)
> +#define PLANE_WM_TRANS(pipe, plane)	\
> +		_PLANE(plane, PLANE_WM_TRANS_1(pipe), PLANE_WM_TRANS_2(pipe))

I must admit to my eyes glazing over when trying to parse these macros.
Not sure if a bit less redirection might help here. Anyway I plugged them
into a small test program and the resulting register offsets were all good.

Just one small nit: if the intermediate macros aren't supposed to be used
by anywhere outside this file then they might be prefixed with _ to make
it clear they're internal.

Either way:
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> +
>  /* define the Watermark register on Ironlake */
>  #define WM0_PIPEA_ILK		0x45100
>  #define  WM0_PIPE_PLANE_MASK	(0xffff<<16)
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 45/89] drm/i915/skl: Definition of SKL WM param structs for pipe/plane
  2014-09-04 11:27 ` [PATCH 45/89] drm/i915/skl: Definition of SKL WM param structs for pipe/plane Damien Lespiau
@ 2014-09-10 18:39   ` Ville Syrjälä
  2014-09-17 13:59     ` Damien Lespiau
  2014-09-22 14:06   ` Ville Syrjälä
  1 sibling, 1 reply; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-10 18:39 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx, Pradeep Bhat

On Thu, Sep 04, 2014 at 12:27:11PM +0100, Damien Lespiau wrote:
> From: Pradeep Bhat <pradeep.bhat@intel.com>
> 
> This patch defines the structures needed for computation of
> watermarks of pipes and planes for SKL.
> 
> v2: Incorporated Damien's review comments and removed unused fields
>     in structs for future features like rotation, drrs and scaling.
>     The skl_wm_values struct is now made more generic across planes
>     and cursor planes for all pipes.
> 
> v3: implemented the plane/cursor split.
> 
> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h  | 18 ++++++++++++++++++
>  drivers/gpu/drm/i915/intel_drv.h | 10 +++++++++-
>  drivers/gpu/drm/i915/intel_pm.c  |  8 ++++++++
>  3 files changed, 35 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 32be299..3764ad5 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1381,6 +1381,24 @@ struct ilk_wm_values {
>  	enum intel_ddb_partitioning partitioning;
>  };
>  
> +struct skl_wm_values {
> +	bool dirty[I915_MAX_PIPES];
> +	uint32_t wm_linetime[I915_MAX_PIPES];
> +	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
> +	uint32_t cursor[I915_MAX_PIPES][8];
> +	uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
> +	uint32_t cursor_trans[I915_MAX_PIPES];
> +};

These multi dimensional arrays hurt my eyes. Maybe we should restructure
this a bit to eg:

struct skl_wm_values {
	struct {
		wm_linetime;
		plane[MAX_PLANES][8];
		...
	} pipe[MAX_PIPES];
};

The two dimensional plane[][] array is still a bit nasty, but maybe we
can live with it.

We could also do the same operatiob for the ilk version to keep stuff
similar.

> +
> +struct skl_wm_level {
> +	bool plane_en[I915_MAX_PLANES];
> +	uint16_t plane_res_b[I915_MAX_PLANES];
> +	uint8_t plane_res_l[I915_MAX_PLANES];

This stuff could also look better as an array of struct of some sort.
Also should probably put the bool and uint8_t next to each other in case
gcc is smart enough to pack things more tightly.

> +	bool cursor_en;
> +	uint16_t cursor_res_b;
> +	uint8_t cursor_res_l;

And this could also be an instance of the same struct use for the proper
planes.

I'm actually wondering if we want this cursor stuff around at all.
I was under the impression using the cursor eats one of the planes,
so we could just as well use the plane always. But if the current
code actually implements stuff using the legacy cursor thing I guess we
need it for now at least.

> +};
> +
>  /*
>   * This struct helps tracking the state needed for runtime PM, which puts the
>   * device in PCI D3 state. Notice that when this happens, nothing on the
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 3239e58..268087f 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -387,6 +387,12 @@ struct intel_mmio_flip {
>  	u32 ring_id;
>  };
>  
> +struct skl_pipe_wm {
> +	struct skl_wm_level wm[8];
> +	struct skl_wm_level trans_wm;
> +	uint32_t linetime;
> +};
> +
>  struct intel_crtc {
>  	struct drm_crtc base;
>  	enum pipe pipe;
> @@ -431,9 +437,11 @@ struct intel_crtc {
>  	bool pch_fifo_underrun_disabled;
>  
>  	/* per-pipe watermark state */
> -	struct {
> +	union {
>  		/* watermarks currently being used  */
>  		struct intel_pipe_wm active;
> +		/* SKL wm values currently in use */
> +		struct skl_pipe_wm skl_active;
>  	} wm;
>  
>  	int scanline_offset;
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index d8c8531..2503ab9 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -1928,6 +1928,14 @@ static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels,
>  	return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2;
>  }
>  
> +struct skl_pipe_wm_parameters {
> +	bool active;
> +	uint32_t pipe_htotal;
> +	uint32_t pixel_rate; /* in KHz */
> +	struct intel_plane_wm_parameters plane[I915_MAX_PLANES];
> +	struct intel_plane_wm_parameters cursor;
> +};

I suppose we just need to start using some kind of named indexes for the
planes on all platforms so we can unify all this stuff. But that can be
done when we have all the code merged so we can better see how to unify
things.

> +
>  struct ilk_pipe_wm_parameters {
>  	bool active;
>  	uint32_t pipe_htotal;
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 69/89] drm/i915/skl: Adding power domains for AUX controllers
  2014-09-04 11:27 ` [PATCH 69/89] drm/i915/skl: Adding power domains for AUX controllers Damien Lespiau
@ 2014-09-16 12:35   ` Imre Deak
  2014-09-18 13:56     ` Damien Lespiau
  2014-11-05 14:23     ` [PATCH 69/89 v5] " Damien Lespiau
  0 siblings, 2 replies; 286+ messages in thread
From: Imre Deak @ 2014-09-16 12:35 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 3920 bytes --]

On Thu, 2014-09-04 at 12:27 +0100, Damien Lespiau wrote:
> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> 
> Adding new power doamins for AUX controllers
> 
> v2: Added new power domains in power_domain_str per Imre's comment
> 
> v3: Added AUX power domains to older platforms
> 
> v4: Rebase on top of POWER_DOMAIN_PLLS.
> 
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v3)
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---

This needs to be rebased on the recent CHV changes, adding the AUX
domains to the CMN and TX wells similarly to the VLV mappings. With that
this looks ok:
Reviewed-by: Imre Deak <imre.deak@intel.com>

>  drivers/gpu/drm/i915/i915_debugfs.c |  8 ++++++++
>  drivers/gpu/drm/i915/i915_drv.h     |  4 ++++
>  drivers/gpu/drm/i915/intel_pm.c     | 12 ++++++++++++
>  3 files changed, 24 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 88a4643..02cb310 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -2273,6 +2273,14 @@ static const char *power_domain_str(enum intel_display_power_domain domain)
>  		return "AUDIO";
>  	case POWER_DOMAIN_PLLS:
>  		return "PLLS";
> +	case POWER_DOMAIN_AUX_A:
> +		return "AUX_A";
> +	case POWER_DOMAIN_AUX_B:
> +		return "AUX_B";
> +	case POWER_DOMAIN_AUX_C:
> +		return "AUX_C";
> +	case POWER_DOMAIN_AUX_D:
> +		return "AUX_D";
>  	case POWER_DOMAIN_INIT:
>  		return "INIT";
>  	default:
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index a6e14db..91ea2b7 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -138,6 +138,10 @@ enum intel_display_power_domain {
>  	POWER_DOMAIN_VGA,
>  	POWER_DOMAIN_AUDIO,
>  	POWER_DOMAIN_PLLS,
> +	POWER_DOMAIN_AUX_A,
> +	POWER_DOMAIN_AUX_B,
> +	POWER_DOMAIN_AUX_C,
> +	POWER_DOMAIN_AUX_D,
>  	POWER_DOMAIN_INIT,
>  
>  	POWER_DOMAIN_NUM,
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 74a8519..ec849db 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -7664,6 +7664,10 @@ EXPORT_SYMBOL_GPL(i915_get_cdclk_freq);
>  	BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |		\
>  	BIT(POWER_DOMAIN_PORT_CRT) |			\
>  	BIT(POWER_DOMAIN_PLLS) |			\
> +	BIT(POWER_DOMAIN_AUX_A) |			\
> +	BIT(POWER_DOMAIN_AUX_B) |			\
> +	BIT(POWER_DOMAIN_AUX_C) |			\
> +	BIT(POWER_DOMAIN_AUX_D) |			\
>  	BIT(POWER_DOMAIN_INIT))
>  #define HSW_DISPLAY_POWER_DOMAINS (				\
>  	(POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) |	\
> @@ -7685,24 +7689,32 @@ EXPORT_SYMBOL_GPL(i915_get_cdclk_freq);
>  	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |	\
>  	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |	\
>  	BIT(POWER_DOMAIN_PORT_CRT) |		\
> +	BIT(POWER_DOMAIN_AUX_A) |		\
> +	BIT(POWER_DOMAIN_AUX_B) |		\
> +	BIT(POWER_DOMAIN_AUX_C) |		\
> +	BIT(POWER_DOMAIN_AUX_D) |		\
>  	BIT(POWER_DOMAIN_INIT))
>  
>  #define VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS (	\
>  	BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |	\
>  	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |	\
> +	BIT(POWER_DOMAIN_AUX_B) |		\
>  	BIT(POWER_DOMAIN_INIT))
>  
>  #define VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS (	\
>  	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |	\
> +	BIT(POWER_DOMAIN_AUX_B) |		\
>  	BIT(POWER_DOMAIN_INIT))
>  
>  #define VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS (	\
>  	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |	\
>  	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |	\
> +	BIT(POWER_DOMAIN_AUX_C) |		\
>  	BIT(POWER_DOMAIN_INIT))
>  
>  #define VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS (	\
>  	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |	\
> +	BIT(POWER_DOMAIN_AUX_C) |		\
>  	BIT(POWER_DOMAIN_INIT))
>  
>  #define CHV_PIPE_A_POWER_DOMAINS (	\


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 70/89] drm/i915/skl: Register definition for SKL power well
  2014-09-04 11:27 ` [PATCH 70/89] drm/i915/skl: Register definition for SKL power well Damien Lespiau
@ 2014-09-16 12:43   ` Imre Deak
  0 siblings, 0 replies; 286+ messages in thread
From: Imre Deak @ 2014-09-16 12:43 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1348 bytes --]

On Thu, 2014-09-04 at 12:27 +0100, Damien Lespiau wrote:
> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> 
> Defining new bit fields for SKL display power wells.
> 
> v2: Clean up unused macros
> 
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

This looks ok, but it should be squashed into 71/89, where it's first
used. Either way:
Reviewed-by: Imre Deak <imre.deak@intel.com>

> ---
>  drivers/gpu/drm/i915/i915_reg.h | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 794d0ba..4d072a8 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -6133,6 +6133,13 @@ enum punit_power_well {
>  #define   HSW_PWR_WELL_FORCE_ON			(1<<19)
>  #define HSW_PWR_WELL_CTL6			0x45414
>  
> +/* SKL Fuse Status */
> +#define SKL_FUSE_STATUS				0x42000
> +#define  SKL_FUSE_DOWNLOAD_STATUS              (1<<31)
> +#define  SKL_FUSE_PG0_DIST_STATUS              (1<<27)
> +#define  SKL_FUSE_PG1_DIST_STATUS              (1<<26)
> +#define  SKL_FUSE_PG2_DIST_STATUS              (1<<25)
> +
>  /* Per-pipe DDI Function Control */
>  #define TRANS_DDI_FUNC_CTL_A		0x60400
>  #define TRANS_DDI_FUNC_CTL_B		0x61400


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction
  2014-09-04 11:27 ` [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction Damien Lespiau
@ 2014-09-16 13:19   ` Imre Deak
  2014-09-16 16:13     ` Daniel Vetter
                       ` (2 more replies)
  0 siblings, 3 replies; 286+ messages in thread
From: Imre Deak @ 2014-09-16 13:19 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 10667 bytes --]

On Thu, 2014-09-04 at 12:27 +0100, Damien Lespiau wrote:
> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> 
> This patch enables power well 2 required for any aux transaction.
> 
> v2: Implemented Imre's comments
> 	- In EDID/DPCD related routines, request AUX power well in SKL
> 
> v3: Implemented Imre's comments
> 	- Call AUX power well domain unconditionally for all platforms
> 
> v4: Remove the check on the output type for the AUX power domain
> 
> v5: Rebase on top of drm-intel-nightly (Damien)
> 
> v6: Rebase on top of -nightly (minor conflict in intel_drv.h) (Damien)
> 
> v7: Remove platform check while getting power well for port (Imre)
> 
> v8: Fix aux power handling around Vdd on/off (Damien)
> 
> v9: Acquire aux power domain on enabling vdd in
>     intel_edp_panel_vdd_sanitize() (Satheesh)
> 
> v10: Rebase on top of Ville's patch to return early in this function intead of
>      having a big indented block. (Damien)
> 
> v12: Rebase on top of Chris EDID caching work (Damien)
> 
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v4, v9)
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

This patch needs to be rebased on the recent PPS changes at least
getting/putting the AUX power domain in pps_lock()/pps_unlock() too.
Also it should be squashed into 69/89. Some more comments below.

> ---
>  drivers/gpu/drm/i915/intel_display.c | 21 ++++++++++++
>  drivers/gpu/drm/i915/intel_dp.c      | 62 ++++++++++++++++++++++++++----------
>  drivers/gpu/drm/i915/intel_drv.h     |  2 ++
>  3 files changed, 68 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 0a4dd00..abd4201 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4503,6 +4503,27 @@ intel_display_port_power_domain(struct intel_encoder *intel_encoder)
>  	}
>  }
>  
> +enum intel_display_power_domain
> +intel_display_aux_power_domain(struct intel_encoder *intel_encoder)
> +{
> +	struct intel_digital_port *intel_dig_port;
> +
> +	intel_dig_port = enc_to_dig_port(&intel_encoder->base);
> +	switch (intel_dig_port->port) {
> +	case PORT_A:
> +		return POWER_DOMAIN_AUX_A;
> +	case PORT_B:
> +		return POWER_DOMAIN_AUX_B;
> +	case PORT_C:
> +		return POWER_DOMAIN_AUX_C;
> +	case PORT_D:
> +		return POWER_DOMAIN_AUX_D;
> +	default:
> +		WARN_ON_ONCE(1);
> +		return 0;
> +	}
> +}
> +
>  static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
>  {
>  	struct drm_device *dev = crtc->dev;
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 93bd9bf..a983b40 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1233,6 +1233,9 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp)
>  	power_domain = intel_display_port_power_domain(intel_encoder);
>  	intel_display_power_get(dev_priv, power_domain);
>  
> +	power_domain = intel_display_aux_power_domain(intel_encoder);
> +	intel_display_power_get(dev_priv, power_domain);
> +

The AUX power domains were added to save power when only AUX
functionality is needed, since then we don't need to power on the power
domain needed for full port functionality. With the above change and
everywhere else below we'll end up enabling both power domains, though
we only need AUX functionality.

The power wells needed for AUX are a subset of those needed for full
port functionality on all platforms (at least atm), so this patch won't
change anything. The patch would make sense, if you requested only the
AUX domains.

>  	DRM_DEBUG_KMS("Turning eDP VDD on\n");
>  
>  	if (!edp_have_panel_power(intel_dp))
> @@ -1309,8 +1312,12 @@ static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp)
>  
>  	power_domain = intel_display_port_power_domain(intel_encoder);
>  	intel_display_power_put(dev_priv, power_domain);
> +
> +	power_domain = intel_display_aux_power_domain(intel_encoder);
> +	intel_display_power_put(dev_priv, power_domain);
>  }

intel_edp_panel_off() needs to be changed too accordingly.

>  
> +

Extra w/s.

>  static void edp_panel_vdd_work(struct work_struct *__work)
>  {
>  	struct intel_dp *intel_dp = container_of(to_delayed_work(__work),
> @@ -3836,7 +3843,13 @@ g4x_dp_detect(struct intel_dp *intel_dp)
>  static struct edid *
>  intel_dp_get_edid(struct intel_dp *intel_dp)
>  {
> +	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> +	struct intel_encoder *intel_encoder = &intel_dig_port->base;
> +	struct drm_device *dev = intel_encoder->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_connector *intel_connector = intel_dp->attached_connector;
> +	enum intel_display_power_domain power_domain;
> +	struct edid *edid;
>  
>  	/* use cached edid if we have one */
>  	if (intel_connector->edid) {
> @@ -3845,9 +3858,16 @@ intel_dp_get_edid(struct intel_dp *intel_dp)
>  			return NULL;
>  
>  		return drm_edid_duplicate(intel_connector->edid);
> -	} else
> -		return drm_get_edid(&intel_connector->base,
> -				    &intel_dp->aux.ddc);
> +	} else {
> +		power_domain = intel_display_aux_power_domain(intel_encoder);
> +		intel_display_power_get(dev_priv, power_domain);

This is redundant, the higher level intel_dp_detect(), intel_dp_force()
already get/put the needed power domains.

> +
> +		edid = drm_get_edid(&intel_connector->base, &intel_dp->aux.ddc);
> +
> +		intel_display_power_put(dev_priv, power_domain);
> +
> +		return edid;
> +	}
>  }
>  
>  static void
> @@ -3876,24 +3896,30 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
>  	intel_dp->has_audio = false;
>  }
>  
> -static enum intel_display_power_domain
> -intel_dp_power_get(struct intel_dp *dp)
> +static void intel_dp_power_get(struct intel_dp *dp)
>  {
>  	struct intel_encoder *encoder = &dp_to_dig_port(dp)->base;
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	enum intel_display_power_domain power_domain;
>  
>  	power_domain = intel_display_port_power_domain(encoder);
>  	intel_display_power_get(to_i915(encoder->base.dev), power_domain);
>  
> -	return power_domain;
> +	power_domain = intel_display_aux_power_domain(encoder);
> +	intel_display_power_get(dev_priv, power_domain);
>  }
>  
> -static void
> -intel_dp_power_put(struct intel_dp *dp,
> -		   enum intel_display_power_domain power_domain)
> +static void intel_dp_power_put(struct intel_dp *dp)
>  {
>  	struct intel_encoder *encoder = &dp_to_dig_port(dp)->base;
> -	intel_display_power_put(to_i915(encoder->base.dev), power_domain);
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	enum intel_display_power_domain power_domain;
> +
> +	power_domain = intel_display_port_power_domain(encoder);
> +	intel_display_power_put(dev_priv, power_domain);
> +
> +	power_domain = intel_display_aux_power_domain(encoder);
> +	intel_display_power_put(dev_priv, power_domain);
>  }
>  
>  static enum drm_connector_status
> @@ -3904,7 +3930,6 @@ intel_dp_detect(struct drm_connector *connector, bool force)
>  	struct intel_encoder *intel_encoder = &intel_dig_port->base;
>  	struct drm_device *dev = connector->dev;
>  	enum drm_connector_status status;
> -	enum intel_display_power_domain power_domain;
>  	bool ret;
>  
>  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> @@ -3918,7 +3943,7 @@ intel_dp_detect(struct drm_connector *connector, bool force)
>  		return connector_status_disconnected;
>  	}
>  
> -	power_domain = intel_dp_power_get(intel_dp);
> +	intel_dp_power_get(intel_dp);

Based on the above intel_dp_power_get() would only enable the AUX power
domain, which means we could keep the current prototype for
intel_dp_power_get()/put().

>  
>  	/* Can't disconnect eDP, but you can close the lid... */
>  	if (is_edp(intel_dp))
> @@ -3949,7 +3974,7 @@ intel_dp_detect(struct drm_connector *connector, bool force)
>  	status = connector_status_connected;
>  
>  out:
> -	intel_dp_power_put(intel_dp, power_domain);
> +	intel_dp_power_put(intel_dp);
>  	return status;
>  }
>  
> @@ -3958,7 +3983,6 @@ intel_dp_force(struct drm_connector *connector)
>  {
>  	struct intel_dp *intel_dp = intel_attached_dp(connector);
>  	struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
> -	enum intel_display_power_domain power_domain;
>  
>  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
>  		      connector->base.id, connector->name);
> @@ -3967,11 +3991,11 @@ intel_dp_force(struct drm_connector *connector)
>  	if (connector->status != connector_status_connected)
>  		return;
>  
> -	power_domain = intel_dp_power_get(intel_dp);
> +	intel_dp_power_get(intel_dp);
>  
>  	intel_dp_set_edid(intel_dp);
>  
> -	intel_dp_power_put(intel_dp, power_domain);
> +	intel_dp_power_put(intel_dp);
>  
>  	if (intel_encoder->type != INTEL_OUTPUT_EDP)
>  		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
> @@ -4205,7 +4229,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
>  		      port_name(intel_dig_port->port),
>  		      long_hpd ? "long" : "short");
>  
> -	power_domain = intel_display_port_power_domain(intel_encoder);
> +	power_domain = intel_display_aux_power_domain(intel_encoder);
> +
>  	intel_display_power_get(dev_priv, power_domain);
>  
>  	if (long_hpd) {
> @@ -4648,6 +4673,9 @@ void intel_edp_panel_vdd_sanitize(struct intel_encoder *intel_encoder)
>  	power_domain = intel_display_port_power_domain(intel_encoder);
>  	intel_display_power_get(dev_priv, power_domain);
>  
> +	power_domain = intel_display_aux_power_domain(intel_encoder);
> +	intel_display_power_get(dev_priv, power_domain);
> +
>  	edp_panel_vdd_schedule_off(intel_dp);
>  }
>  
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 9558f07..a407d04 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -916,6 +916,8 @@ void hsw_disable_ips(struct intel_crtc *crtc);
>  void intel_display_set_init_power(struct drm_i915_private *dev, bool enable);
>  enum intel_display_power_domain
>  intel_display_port_power_domain(struct intel_encoder *intel_encoder);
> +enum intel_display_power_domain
> +intel_display_aux_power_domain(struct intel_encoder *intel_encoder);
>  void intel_mode_from_pipe_config(struct drm_display_mode *mode,
>  				 struct intel_crtc_config *pipe_config);
>  int intel_format_to_fourcc(int format);


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 38/89] drm/i915/skl: Implement drm_plane vfuncs
  2014-09-04 13:21   ` Daniel Vetter
@ 2014-09-16 13:20     ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-16 13:20 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 03:21:16PM +0200, Daniel Vetter wrote:
> On Thu, Sep 04, 2014 at 12:27:04PM +0100, Damien Lespiau wrote:
> > SKL Uses the same hardware for all planes now, so called "universal"
> > planes. Ie both the primary planes and sprite planes share the same
> > logic. This patch implements the drm_plane vfuncs for "sprites" ie
> > planes that aren't the primary plane.
> > 
> > v2: Couple of fixes:
> >   - Actually enabled the planes and fix the plane number
> > 
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> 
> This needs to be de-duped I think ...

I was hoping to do that in a separate task on top. Right now the two
code paths are not quite ready to be merged together, close though.

> especially since it will conflict quite badly with Padovan's ongoing
> work to introduce a struct intel_plane_config.
> 
> Not sure yet how we can shuffle the merge here, I guess it'll be a
> case of who's first wins ;-)

mine mine mine :) well, we shall see, so far, so good.

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* [PATCH 53/89 v2] drm/i915/skl: Gen9 Forcewake
  2014-09-10 13:44   ` Mika Kuoppala
@ 2014-09-16 13:49     ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-16 13:49 UTC (permalink / raw)
  To: intel-gfx

From: Zhe Wang <zhe1.wang@intel.com>

Implement common forcewake functions shared by Gen9 features.

v2: Make the focewake_{get,put} functions static (Mika)
    Small coding style fix in the function definition (Damien)

Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
Signed-off-by: Zhe Wang <zhe1.wang@intel.com> (v1)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v2)
---
 drivers/gpu/drm/i915/i915_drv.h     |   5 +-
 drivers/gpu/drm/i915/i915_reg.h     |   6 ++
 drivers/gpu/drm/i915/intel_uncore.c | 175 +++++++++++++++++++++++++++++++++++-
 3 files changed, 184 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4712a32..91f4506 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -545,6 +545,7 @@ struct intel_uncore {
 
 	unsigned fw_rendercount;
 	unsigned fw_mediacount;
+	unsigned fw_blittercount;
 
 	struct timer_list force_wake_timer;
 };
@@ -2969,7 +2970,9 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val);
 
 #define FORCEWAKE_RENDER	(1 << 0)
 #define FORCEWAKE_MEDIA		(1 << 1)
-#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | FORCEWAKE_MEDIA)
+#define FORCEWAKE_BLITTER	(1 << 2)
+#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | FORCEWAKE_MEDIA | \
+					FORCEWAKE_BLITTER)
 
 
 #define I915_READ8(reg)		dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index d9adf44..07f74b4 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5750,6 +5750,12 @@ enum punit_power_well {
 #define   VLV_GTLC_PW_MEDIA_STATUS_MASK		(1 << 5)
 #define   VLV_GTLC_PW_RENDER_STATUS_MASK	(1 << 7)
 #define  FORCEWAKE_MT				0xa188 /* multi-threaded */
+#define  FORCEWAKE_MEDIA_GEN9			0xa270
+#define  FORCEWAKE_RENDER_GEN9			0xa278
+#define  FORCEWAKE_BLITTER_GEN9			0xa188
+#define  FORCEWAKE_ACK_MEDIA_GEN9		0x0D88
+#define  FORCEWAKE_ACK_RENDER_GEN9		0x0D84
+#define  FORCEWAKE_ACK_BLITTER_GEN9		0x130044
 #define   FORCEWAKE_KERNEL			0x1
 #define   FORCEWAKE_USER			0x2
 #define  FORCEWAKE_MT_ACK			0x130040
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 3b27fb0..cbf7420 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -299,6 +299,154 @@ static void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
+static void __gen9_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
+{
+	__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
+			_MASKED_BIT_DISABLE(0xffff));
+
+	__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
+			_MASKED_BIT_DISABLE(0xffff));
+
+	__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
+			_MASKED_BIT_DISABLE(0xffff));
+}
+
+static void
+__gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
+{
+	/* Check for Render Engine */
+	if (FORCEWAKE_RENDER & fw_engine) {
+		if (wait_for_atomic((__raw_i915_read32(dev_priv,
+						FORCEWAKE_ACK_RENDER_GEN9) &
+						FORCEWAKE_KERNEL) == 0,
+					FORCEWAKE_ACK_TIMEOUT_MS))
+			DRM_ERROR("Timed out: Render forcewake old ack to clear.\n");
+
+		__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
+				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
+
+		if (wait_for_atomic((__raw_i915_read32(dev_priv,
+						FORCEWAKE_ACK_RENDER_GEN9) &
+						FORCEWAKE_KERNEL),
+					FORCEWAKE_ACK_TIMEOUT_MS))
+			DRM_ERROR("Timed out: waiting for Render to ack.\n");
+	}
+
+	/* Check for Media Engine */
+	if (FORCEWAKE_MEDIA & fw_engine) {
+		if (wait_for_atomic((__raw_i915_read32(dev_priv,
+						FORCEWAKE_ACK_MEDIA_GEN9) &
+						FORCEWAKE_KERNEL) == 0,
+					FORCEWAKE_ACK_TIMEOUT_MS))
+			DRM_ERROR("Timed out: Media forcewake old ack to clear.\n");
+
+		__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
+				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
+
+		if (wait_for_atomic((__raw_i915_read32(dev_priv,
+						FORCEWAKE_ACK_MEDIA_GEN9) &
+						FORCEWAKE_KERNEL),
+					FORCEWAKE_ACK_TIMEOUT_MS))
+			DRM_ERROR("Timed out: waiting for Media to ack.\n");
+	}
+
+	/* Check for Blitter Engine */
+	if (FORCEWAKE_BLITTER & fw_engine) {
+		if (wait_for_atomic((__raw_i915_read32(dev_priv,
+						FORCEWAKE_ACK_BLITTER_GEN9) &
+						FORCEWAKE_KERNEL) == 0,
+					FORCEWAKE_ACK_TIMEOUT_MS))
+			DRM_ERROR("Timed out: Blitter forcewake old ack to clear.\n");
+
+		__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
+				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
+
+		if (wait_for_atomic((__raw_i915_read32(dev_priv,
+						FORCEWAKE_ACK_BLITTER_GEN9) &
+						FORCEWAKE_KERNEL),
+					FORCEWAKE_ACK_TIMEOUT_MS))
+			DRM_ERROR("Timed out: waiting for Blitter to ack.\n");
+	}
+}
+
+static void
+__gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
+{
+	/* Check for Render Engine */
+	if (FORCEWAKE_RENDER & fw_engine)
+		__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
+				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
+
+	/* Check for Media Engine */
+	if (FORCEWAKE_MEDIA & fw_engine)
+		__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
+				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
+
+	/* Check for Blitter Engine */
+	if (FORCEWAKE_BLITTER & fw_engine)
+		__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
+				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
+}
+
+static void
+gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
+{
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+
+	if (FORCEWAKE_RENDER & fw_engine) {
+		if (dev_priv->uncore.fw_rendercount++ == 0)
+			dev_priv->uncore.funcs.force_wake_get(dev_priv,
+							FORCEWAKE_RENDER);
+	}
+
+	if (FORCEWAKE_MEDIA & fw_engine) {
+		if (dev_priv->uncore.fw_mediacount++ == 0)
+			dev_priv->uncore.funcs.force_wake_get(dev_priv,
+							FORCEWAKE_MEDIA);
+	}
+
+	if (FORCEWAKE_BLITTER & fw_engine) {
+		if (dev_priv->uncore.fw_blittercount++ == 0)
+			dev_priv->uncore.funcs.force_wake_get(dev_priv,
+							FORCEWAKE_BLITTER);
+	}
+
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+}
+
+static void
+gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
+{
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+
+	if (FORCEWAKE_RENDER & fw_engine) {
+		WARN_ON(dev_priv->uncore.fw_rendercount == 0);
+		if (--dev_priv->uncore.fw_rendercount == 0)
+			dev_priv->uncore.funcs.force_wake_put(dev_priv,
+							FORCEWAKE_RENDER);
+	}
+
+	if (FORCEWAKE_MEDIA & fw_engine) {
+		WARN_ON(dev_priv->uncore.fw_mediacount == 0);
+		if (--dev_priv->uncore.fw_mediacount == 0)
+			dev_priv->uncore.funcs.force_wake_put(dev_priv,
+							FORCEWAKE_MEDIA);
+	}
+
+	if (FORCEWAKE_BLITTER & fw_engine) {
+		WARN_ON(dev_priv->uncore.fw_blittercount == 0);
+		if (--dev_priv->uncore.fw_blittercount == 0)
+			dev_priv->uncore.funcs.force_wake_put(dev_priv,
+							FORCEWAKE_BLITTER);
+	}
+
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+}
+
 static void gen6_force_wake_timer(unsigned long arg)
 {
 	struct drm_i915_private *dev_priv = (void *)arg;
@@ -337,6 +485,9 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
 	if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev))
 		__gen7_gt_force_wake_mt_reset(dev_priv);
 
+	if (IS_GEN9(dev))
+		__gen9_gt_force_wake_mt_reset(dev_priv);
+
 	if (restore) { /* If reset with a user forcewake, try to restore */
 		unsigned fw = 0;
 
@@ -346,6 +497,15 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
 
 			if (dev_priv->uncore.fw_mediacount)
 				fw |= FORCEWAKE_MEDIA;
+		} else if (IS_GEN9(dev)) {
+			if (dev_priv->uncore.fw_rendercount)
+				fw |= FORCEWAKE_RENDER;
+
+			if (dev_priv->uncore.fw_mediacount)
+				fw |= FORCEWAKE_MEDIA;
+
+			if (dev_priv->uncore.fw_blittercount)
+				fw |= FORCEWAKE_BLITTER;
 		} else {
 			if (dev_priv->uncore.forcewake_count)
 				fw = FORCEWAKE_ALL;
@@ -410,6 +570,10 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
 
 	intel_runtime_pm_get(dev_priv);
 
+	/* Redirect to Gen9 specific routine */
+	if (IS_GEN9(dev_priv->dev))
+		return gen9_force_wake_get(dev_priv, fw_engine);
+
 	/* Redirect to VLV specific routine */
 	if (IS_VALLEYVIEW(dev_priv->dev))
 		return vlv_force_wake_get(dev_priv, fw_engine);
@@ -431,6 +595,12 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
 	if (!dev_priv->uncore.funcs.force_wake_put)
 		return;
 
+	/* Redirect to Gen9 specific routine */
+	if (IS_GEN9(dev_priv->dev)) {
+		gen9_force_wake_put(dev_priv, fw_engine);
+		goto out;
+	}
+
 	/* Redirect to VLV specific routine */
 	if (IS_VALLEYVIEW(dev_priv->dev)) {
 		vlv_force_wake_put(dev_priv, fw_engine);
@@ -835,7 +1005,10 @@ void intel_uncore_init(struct drm_device *dev)
 
 	intel_uncore_early_sanitize(dev, false);
 
-	if (IS_VALLEYVIEW(dev)) {
+	if (IS_GEN9(dev)) {
+		dev_priv->uncore.funcs.force_wake_get = __gen9_force_wake_get;
+		dev_priv->uncore.funcs.force_wake_put = __gen9_force_wake_put;
+	} else if (IS_VALLEYVIEW(dev)) {
 		dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get;
 		dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put;
 	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* Re: [PATCH 71/89] drm/i915/skl: Implementation of SKL display power well support
  2014-09-04 11:27 ` [PATCH 71/89] drm/i915/skl: Implementation of SKL display power well support Damien Lespiau
@ 2014-09-16 13:56   ` Imre Deak
  2014-09-16 14:19     ` Imre Deak
  0 siblings, 1 reply; 286+ messages in thread
From: Imre Deak @ 2014-09-16 13:56 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 11493 bytes --]

On Thu, 2014-09-04 at 12:27 +0100, Damien Lespiau wrote:
> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> 
> This patch implements core logic of SKL display power well.
> 
> FIXME: hsw_pwr needs to go. The audio guys promised us that they'll do a proper
> implementation for skl+.
> 
> v2: Addressed Imre's comments
> 	- Added respective DDIs under power well #1 and #2
> 	- Simplified repetitive code in power well programming
> 
> v3: Implemented Imre's comments
> 	- Further simplified power well programming
> 	- Made sure that PW 1 is enabled prior to PW 2
> 
> v4: Fix minor conflict with the the cherryview support (Damien)
> 
> v5: Add the PLL power domain to the always on power well (Damien)
> 
> v6: Disable BIOS power well (Imre)
>     Use power well data for comparison (Imre)
>     Put the PLL power domain into PW1 as its needed for CDCLK (Satheesh,
>     Damien)
> 
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v3,v6)
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h |  13 +++
>  drivers/gpu/drm/i915/intel_pm.c | 207 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 220 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 4d072a8..84a0de6 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -541,6 +541,19 @@ enum punit_power_well {
>  	PUNIT_POWER_WELL_NUM,
>  };
>  
> +enum skl_disp_power_wells {
> +	SKL_DISP_PW_MISC_IO,
> +	SKL_DISP_PW_DDI_A_E,
> +	SKL_DISP_PW_DDI_B,
> +	SKL_DISP_PW_DDI_C,
> +	SKL_DISP_PW_DDI_D,
> +	SKL_DISP_PW_1 = 14,
> +	SKL_DISP_PW_2,
> +};
> +
> +#define SKL_POWER_WELL_STATE(pw) (1 << (pw * 2))
> +#define SKL_POWER_WELL_REQ(pw) (1 << ((pw * 2) + 1))
> +
>  #define PUNIT_REG_PWRGT_CTRL			0x60
>  #define PUNIT_REG_PWRGT_STATUS			0x61
>  #define   PUNIT_PWRGT_MASK(power_well)		(3 << ((power_well) * 2))
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index ec849db..853b596 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -7160,6 +7160,128 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
>  	}
>  }
>  
> +#define SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS (                 \
> +	BIT(POWER_DOMAIN_PIPE_B) |                      \
> +	BIT(POWER_DOMAIN_TRANSCODER_B) |                \
> +	BIT(POWER_DOMAIN_PIPE_C) |                      \
> +	BIT(POWER_DOMAIN_TRANSCODER_C) |                \
> +	BIT(POWER_DOMAIN_PIPE_B_PANEL_FITTER) |         \
> +	BIT(POWER_DOMAIN_PIPE_C_PANEL_FITTER) |         \
> +	BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |          \
> +	BIT(POWER_DOMAIN_AUX_B) |                       \
> +	BIT(POWER_DOMAIN_AUX_C) |                       \
> +	BIT(POWER_DOMAIN_AUX_D) |                       \
> +	BIT(POWER_DOMAIN_AUDIO) |                       \
> +	BIT(POWER_DOMAIN_INIT))
> +#define SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS (         \
> +	SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS |         \
> +	BIT(POWER_DOMAIN_PLLS) |			\
> +	BIT(POWER_DOMAIN_PIPE_A) |                      \
> +	BIT(POWER_DOMAIN_TRANSCODER_EDP) |              \
> +	BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \
> +	BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) |          \
> +	BIT(POWER_DOMAIN_AUX_A) |                       \
> +	BIT(POWER_DOMAIN_INIT))
> +#define SKL_DISPLAY_DDI_A_E_POWER_DOMAINS (                     \
> +	BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) |          \
> +	BIT(POWER_DOMAIN_INIT))
> +#define SKL_DISPLAY_DDI_B_POWER_DOMAINS (                       \
> +	BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |          \
> +	BIT(POWER_DOMAIN_INIT))
> +#define SKL_DISPLAY_DDI_C_POWER_DOMAINS (                       \
> +	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |          \
> +	BIT(POWER_DOMAIN_INIT))
> +#define SKL_DISPLAY_DDI_D_POWER_DOMAINS (                       \
> +	BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |          \
> +	BIT(POWER_DOMAIN_INIT))
> +#define SKL_DISPLAY_ALWAYS_ON_POWER_DOMAINS (           \
> +	(POWER_DOMAIN_MASK & ~(SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS |  \
> +	SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS |         \
> +	SKL_DISPLAY_DDI_A_E_POWER_DOMAINS |             \
> +	SKL_DISPLAY_DDI_B_POWER_DOMAINS |               \
> +	SKL_DISPLAY_DDI_C_POWER_DOMAINS |               \
> +	SKL_DISPLAY_DDI_D_POWER_DOMAINS)) |             \
> +	BIT(POWER_DOMAIN_INIT))
> +
> +static void skl_set_power_well(struct drm_i915_private *dev_priv,
> +			struct i915_power_well *power_well, bool enable)
> +{
> +	uint32_t tmp, fuse_status;
> +	uint32_t req_mask, state_mask;
> +	bool check_fuse_status = false;
> +
> +	tmp = I915_READ(HSW_PWR_WELL_DRIVER);
> +	fuse_status = I915_READ(SKL_FUSE_STATUS);
> +
> +	switch (power_well->data) {
> +	case SKL_DISP_PW_1:
> +		if (wait_for((I915_READ(SKL_FUSE_STATUS) &
> +			SKL_FUSE_PG0_DIST_STATUS), 5)) {

The spec says 5 us not 5 ms, so we could just wait for 1 ms. The same
applies to similar places below.

> +			DRM_ERROR("PG0 not enabled\n");
> +			return;
> +		}
> +		break;
> +	case SKL_DISP_PW_2:
> +		if (!(fuse_status & SKL_FUSE_PG1_DIST_STATUS)) {
> +			DRM_ERROR("PG1 in disabled state\n");
> +			return;
> +		}
> +		break;
> +	case SKL_DISP_PW_DDI_A_E:
> +	case SKL_DISP_PW_DDI_B:
> +	case SKL_DISP_PW_DDI_C:
> +	case SKL_DISP_PW_DDI_D:
> +		break;
> +	default:

This would be a driver bug, so it needs a WARN().

> +		return;
> +	}
> +
> +	req_mask = SKL_POWER_WELL_REQ(power_well->data);
> +	state_mask = SKL_POWER_WELL_STATE(power_well->data);
> +
> +	if (enable) {
> +		if (!(tmp & req_mask))
> +			I915_WRITE(HSW_PWR_WELL_DRIVER, tmp | req_mask);
> +
> +		if (!(tmp & state_mask)) {
> +			DRM_DEBUG_KMS("Enabling DDI power well\n");

Could be just "Enabling %s", power_well->name. Also we could miss the
message depending on timing, so it needs to go above where the request
bit is set.

With the above changes, this looks ok:
Reviewed-by: Imre Deak <imre.deak@intel.com>

> +			if (wait_for((I915_READ(HSW_PWR_WELL_DRIVER) &
> +				state_mask), 20))
> +				DRM_ERROR("%s enable timeout\n",
> +					power_well->name);
> +			check_fuse_status = true;
> +		}
> +	} else {
> +		if (tmp & req_mask) {
> +			I915_WRITE(HSW_PWR_WELL_DRIVER,	tmp & ~req_mask);
> +			POSTING_READ(HSW_PWR_WELL_DRIVER);
> +			DRM_DEBUG_KMS("Disabling %s\n", power_well->name);
> +		}
> +	}
> +
> +	if (check_fuse_status) {
> +		if (power_well->data == SKL_DISP_PW_1) {
> +			if (wait_for((I915_READ(SKL_FUSE_STATUS) &
> +				SKL_FUSE_PG1_DIST_STATUS), 5))
> +				DRM_ERROR("PG1 distributing status timeout\n");
> +		} else if (power_well->data == SKL_DISP_PW_2) {
> +			if (wait_for((I915_READ(SKL_FUSE_STATUS) &
> +				SKL_FUSE_PG2_DIST_STATUS), 1))
> +				DRM_ERROR("PG2 distributing status timeout\n");
> +		}
> +	}
> +}
> +
>  static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv,
>  				   struct i915_power_well *power_well)
>  {
> @@ -7185,6 +7307,36 @@ static void hsw_power_well_disable(struct drm_i915_private *dev_priv,
>  	hsw_set_power_well(dev_priv, power_well, false);
>  }
>  
> +static bool skl_power_well_enabled(struct drm_i915_private *dev_priv,
> +					struct i915_power_well *power_well)
> +{
> +	uint32_t mask = SKL_POWER_WELL_REQ(power_well->data) |
> +		SKL_POWER_WELL_STATE(power_well->data);
> +
> +	return (I915_READ(HSW_PWR_WELL_DRIVER) & mask) == mask;
> +}
> +
> +static void skl_power_well_sync_hw(struct drm_i915_private *dev_priv,
> +				struct i915_power_well *power_well)
> +{
> +	skl_set_power_well(dev_priv, power_well, power_well->count > 0);
> +
> +	/* Clear any request made by BIOS as driver is taking over */
> +	I915_WRITE(HSW_PWR_WELL_BIOS, 0);
> +}
> +
> +static void skl_power_well_enable(struct drm_i915_private *dev_priv,
> +				struct i915_power_well *power_well)
> +{
> +	skl_set_power_well(dev_priv, power_well, true);
> +}
> +
> +static void skl_power_well_disable(struct drm_i915_private *dev_priv,
> +				struct i915_power_well *power_well)
> +{
> +	skl_set_power_well(dev_priv, power_well, false);
> +}
> +
>  static void i9xx_always_on_power_well_noop(struct drm_i915_private *dev_priv,
>  					   struct i915_power_well *power_well)
>  {
> @@ -7787,6 +7939,13 @@ static const struct i915_power_well_ops hsw_power_well_ops = {
>  	.is_enabled = hsw_power_well_enabled,
>  };
>  
> +static const struct i915_power_well_ops skl_power_well_ops = {
> +	.sync_hw = skl_power_well_sync_hw,
> +	.enable = skl_power_well_enable,
> +	.disable = skl_power_well_disable,
> +	.is_enabled = skl_power_well_enabled,
> +};
> +
>  static struct i915_power_well hsw_power_wells[] = {
>  	{
>  		.name = "always-on",
> @@ -8009,6 +8168,51 @@ static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_pr
>  	return NULL;
>  }
>  
> +static struct i915_power_well skl_power_wells[] = {
> +	{
> +		.name = "always-on",
> +		.always_on = 1,
> +		.domains = SKL_DISPLAY_ALWAYS_ON_POWER_DOMAINS,
> +		.ops = &i9xx_always_on_power_well_ops,
> +	},
> +	{
> +		.name = "power well 1",
> +		.domains = SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS,
> +		.ops = &skl_power_well_ops,
> +		.data = SKL_DISP_PW_1,
> +	},
> +	{
> +		.name = "power well 2",
> +		.domains = SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS,
> +		.ops = &skl_power_well_ops,
> +		.data = SKL_DISP_PW_2,
> +	},
> +	{
> +		.name = "DDI A/E power well",
> +		.domains = SKL_DISPLAY_DDI_A_E_POWER_DOMAINS,
> +		.ops = &skl_power_well_ops,
> +		.data = SKL_DISP_PW_DDI_A_E,
> +	},
> +	{
> +		.name = "DDI B power well",
> +		.domains = SKL_DISPLAY_DDI_B_POWER_DOMAINS,
> +		.ops = &skl_power_well_ops,
> +		.data = SKL_DISP_PW_DDI_B,
> +	},
> +	{
> +		.name = "DDI C power well",
> +		.domains = SKL_DISPLAY_DDI_C_POWER_DOMAINS,
> +		.ops = &skl_power_well_ops,
> +		.data = SKL_DISP_PW_DDI_C,
> +	},
> +	{
> +		.name = "DDI D power well",
> +		.domains = SKL_DISPLAY_DDI_D_POWER_DOMAINS,
> +		.ops = &skl_power_well_ops,
> +		.data = SKL_DISP_PW_DDI_D,
> +	},
> +};
> +
>  #define set_power_wells(power_domains, __power_wells) ({		\
>  	(power_domains)->power_wells = (__power_wells);			\
>  	(power_domains)->power_well_count = ARRAY_SIZE(__power_wells);	\
> @@ -8030,6 +8234,9 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
>  	} else if (IS_BROADWELL(dev_priv->dev)) {
>  		set_power_wells(power_domains, bdw_power_wells);
>  		hsw_pwr = power_domains;
> +	} else if (IS_SKYLAKE(dev_priv->dev)) {
> +		set_power_wells(power_domains, skl_power_wells);
> +		hsw_pwr = power_domains;
>  	} else if (IS_CHERRYVIEW(dev_priv->dev)) {
>  		set_power_wells(power_domains, chv_power_wells);
>  	} else if (IS_VALLEYVIEW(dev_priv->dev)) {


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 44/89] drm/i915/skl: Register definitions and macros for SKL Watermark regs
  2014-09-10 18:04   ` Ville Syrjälä
@ 2014-09-16 14:11     ` Damien Lespiau
  2014-09-17 13:40     ` [PATCH 44/89 v4] " Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-16 14:11 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, Pradeep Bhat

On Wed, Sep 10, 2014 at 09:04:04PM +0300, Ville Syrjälä wrote:
> > +#define PLANE_WM_TRANS_1(pipe)		\
> > +			_PIPE(pipe, PLANE_WM_TRANS_1_A_0, PLANE_WM_TRANS_1_B_0)
> > +#define PLANE_WM_TRANS_2(pipe)		\
> > +			_PIPE(pipe, PLANE_WM_TRANS_2_A_0, PLANE_WM_TRANS_2_B_0)
> > +#define PLANE_WM_TRANS(pipe, plane)	\
> > +		_PLANE(plane, PLANE_WM_TRANS_1(pipe), PLANE_WM_TRANS_2(pipe))
> 
> I must admit to my eyes glazing over when trying to parse these macros.
> Not sure if a bit less redirection might help here. Anyway I plugged them
> into a small test program and the resulting register offsets were all good.

While I'm generally for simple things, there's some pleasure to be had
in abusing the preprocessor a bit. Sometimes it has to be about fun to
keep us interested :)

> Just one small nit: if the intermediate macros aren't supposed to be used
> by anywhere outside this file then they might be prefixed with _ to make
> it clear they're internal.

Fair enough, will spin a new version for this one.

> Either way:
> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 73/89] drm/i915/skl: Enabling MISC IO power well
  2014-09-04 11:27 ` [PATCH 73/89] drm/i915/skl: Enabling MISC IO power well Damien Lespiau
@ 2014-09-16 14:12   ` Imre Deak
  0 siblings, 0 replies; 286+ messages in thread
From: Imre Deak @ 2014-09-16 14:12 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 3467 bytes --]

On Thu, 2014-09-04 at 12:27 +0100, Damien Lespiau wrote:
> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> 
> Earlier it was thought that MISC IO is always ON power well.
> But it doesn't looks like the case as confirmed by the HW team.
> Adding code to enable/disable MISC IO power well.
> 
> v2: Use power well data for comparison (Imre)
> 
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 853b596..5425d85 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -7204,6 +7204,21 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
>  	BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) |          \
>  	BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |          \
>  	BIT(POWER_DOMAIN_INIT))
> +#define SKL_DISPLAY_MISC_IO_POWER_DOMAINS (                       \
> +	BIT(POWER_DOMAIN_AUX_A) |                       \
> +	BIT(POWER_DOMAIN_AUX_B) |                       \
> +	BIT(POWER_DOMAIN_AUX_C) |                       \
> +	BIT(POWER_DOMAIN_AUX_D) |                       \
> +	BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) |          \
> +	BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |          \
> +	BIT(POWER_DOMAIN_AUDIO) |                       \
> +	BIT(POWER_DOMAIN_INIT))

From the bspec page "Skylake Sequences to Initialize Display":
"""
Most display engine functions will not operate while display is not
initialized. Only basic PCI, I/O, and MMIO register read/write
operations are supported when display is not initialized.
"""

And for the display to be initialized we need power well#1 and the misc
power well. Based on this we need the misc power well (and power well#1)
for all domains, so simply:
#define SKL_DISPLAY_MISC_IO_POWER_DOMAINS POWER_DOMAIN_MASK


>  #define SKL_DISPLAY_ALWAYS_ON_POWER_DOMAINS (           \
>  	(POWER_DOMAIN_MASK & ~(SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS |  \
>  	SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS |         \
> @@ -7241,6 +7256,7 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv,
>  	case SKL_DISP_PW_DDI_B:
>  	case SKL_DISP_PW_DDI_C:
>  	case SKL_DISP_PW_DDI_D:
> +	case SKL_DISP_PW_MISC_IO:
>  		break;
>  	default:
>  		return;
> @@ -8211,6 +8227,12 @@ static struct i915_power_well skl_power_wells[] = {
>  		.ops = &skl_power_well_ops,
>  		.data = SKL_DISP_PW_DDI_D,
>  	},
> +	{
> +		.name = "MISC IO power well",
> +		.domains = SKL_DISPLAY_MISC_IO_POWER_DOMAINS,
> +		.ops = &skl_power_well_ops,
> +		.data = SKL_DISP_PW_MISC_IO,
> +	}

Based on the above bspec page, the misc power well needs to be enabled
before any other power wells, so it needs to be the first entry.

Optionally this patch could be squashed into 71/89.

With the above changes:
Reviewed-by: Imre Deak <imre.deak@intel.com>

>  };
>  
>  #define set_power_wells(power_domains, __power_wells) ({		\


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 71/89] drm/i915/skl: Implementation of SKL display power well support
  2014-09-16 13:56   ` Imre Deak
@ 2014-09-16 14:19     ` Imre Deak
  0 siblings, 0 replies; 286+ messages in thread
From: Imre Deak @ 2014-09-16 14:19 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 12405 bytes --]

On Tue, 2014-09-16 at 16:56 +0300, Imre Deak wrote:
> On Thu, 2014-09-04 at 12:27 +0100, Damien Lespiau wrote:
> > From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> > 
> > This patch implements core logic of SKL display power well.
> > 
> > FIXME: hsw_pwr needs to go. The audio guys promised us that they'll do a proper
> > implementation for skl+.
> > 
> > v2: Addressed Imre's comments
> > 	- Added respective DDIs under power well #1 and #2
> > 	- Simplified repetitive code in power well programming
> > 
> > v3: Implemented Imre's comments
> > 	- Further simplified power well programming
> > 	- Made sure that PW 1 is enabled prior to PW 2
> > 
> > v4: Fix minor conflict with the the cherryview support (Damien)
> > 
> > v5: Add the PLL power domain to the always on power well (Damien)
> > 
> > v6: Disable BIOS power well (Imre)
> >     Use power well data for comparison (Imre)
> >     Put the PLL power domain into PW1 as its needed for CDCLK (Satheesh,
> >     Damien)
> > 
> > Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v3,v6)
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_reg.h |  13 +++
> >  drivers/gpu/drm/i915/intel_pm.c | 207 ++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 220 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> > index 4d072a8..84a0de6 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -541,6 +541,19 @@ enum punit_power_well {
> >  	PUNIT_POWER_WELL_NUM,
> >  };
> >  
> > +enum skl_disp_power_wells {
> > +	SKL_DISP_PW_MISC_IO,
> > +	SKL_DISP_PW_DDI_A_E,
> > +	SKL_DISP_PW_DDI_B,
> > +	SKL_DISP_PW_DDI_C,
> > +	SKL_DISP_PW_DDI_D,
> > +	SKL_DISP_PW_1 = 14,
> > +	SKL_DISP_PW_2,
> > +};
> > +
> > +#define SKL_POWER_WELL_STATE(pw) (1 << (pw * 2))
> > +#define SKL_POWER_WELL_REQ(pw) (1 << ((pw * 2) + 1))

Missed this one: missing parentheses for pw.

> > +
> >  #define PUNIT_REG_PWRGT_CTRL			0x60
> >  #define PUNIT_REG_PWRGT_STATUS			0x61
> >  #define   PUNIT_PWRGT_MASK(power_well)		(3 << ((power_well) * 2))
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index ec849db..853b596 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -7160,6 +7160,128 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
> >  	}
> >  }
> >  
> > +#define SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS (                 \
> > +	BIT(POWER_DOMAIN_PIPE_B) |                      \
> > +	BIT(POWER_DOMAIN_TRANSCODER_B) |                \
> > +	BIT(POWER_DOMAIN_PIPE_C) |                      \
> > +	BIT(POWER_DOMAIN_TRANSCODER_C) |                \
> > +	BIT(POWER_DOMAIN_PIPE_B_PANEL_FITTER) |         \
> > +	BIT(POWER_DOMAIN_PIPE_C_PANEL_FITTER) |         \
> > +	BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |          \
> > +	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |          \
> > +	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |          \
> > +	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |          \
> > +	BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) |          \
> > +	BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |          \
> > +	BIT(POWER_DOMAIN_AUX_B) |                       \
> > +	BIT(POWER_DOMAIN_AUX_C) |                       \
> > +	BIT(POWER_DOMAIN_AUX_D) |                       \
> > +	BIT(POWER_DOMAIN_AUDIO) |                       \
> > +	BIT(POWER_DOMAIN_INIT))
> > +#define SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS (         \
> > +	SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS |         \
> > +	BIT(POWER_DOMAIN_PLLS) |			\
> > +	BIT(POWER_DOMAIN_PIPE_A) |                      \
> > +	BIT(POWER_DOMAIN_TRANSCODER_EDP) |              \
> > +	BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \
> > +	BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) |          \
> > +	BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) |          \
> > +	BIT(POWER_DOMAIN_AUX_A) |                       \
> > +	BIT(POWER_DOMAIN_INIT))
> > +#define SKL_DISPLAY_DDI_A_E_POWER_DOMAINS (                     \
> > +	BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) |          \
> > +	BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) |          \
> > +	BIT(POWER_DOMAIN_INIT))
> > +#define SKL_DISPLAY_DDI_B_POWER_DOMAINS (                       \
> > +	BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |          \
> > +	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |          \
> > +	BIT(POWER_DOMAIN_INIT))
> > +#define SKL_DISPLAY_DDI_C_POWER_DOMAINS (                       \
> > +	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |          \
> > +	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |          \
> > +	BIT(POWER_DOMAIN_INIT))
> > +#define SKL_DISPLAY_DDI_D_POWER_DOMAINS (                       \
> > +	BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) |          \
> > +	BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |          \
> > +	BIT(POWER_DOMAIN_INIT))
> > +#define SKL_DISPLAY_ALWAYS_ON_POWER_DOMAINS (           \
> > +	(POWER_DOMAIN_MASK & ~(SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS |  \
> > +	SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS |         \
> > +	SKL_DISPLAY_DDI_A_E_POWER_DOMAINS |             \
> > +	SKL_DISPLAY_DDI_B_POWER_DOMAINS |               \
> > +	SKL_DISPLAY_DDI_C_POWER_DOMAINS |               \
> > +	SKL_DISPLAY_DDI_D_POWER_DOMAINS)) |             \
> > +	BIT(POWER_DOMAIN_INIT))
> > +
> > +static void skl_set_power_well(struct drm_i915_private *dev_priv,
> > +			struct i915_power_well *power_well, bool enable)
> > +{
> > +	uint32_t tmp, fuse_status;
> > +	uint32_t req_mask, state_mask;
> > +	bool check_fuse_status = false;
> > +
> > +	tmp = I915_READ(HSW_PWR_WELL_DRIVER);
> > +	fuse_status = I915_READ(SKL_FUSE_STATUS);
> > +
> > +	switch (power_well->data) {
> > +	case SKL_DISP_PW_1:
> > +		if (wait_for((I915_READ(SKL_FUSE_STATUS) &
> > +			SKL_FUSE_PG0_DIST_STATUS), 5)) {
> 
> The spec says 5 us not 5 ms, so we could just wait for 1 ms. The same
> applies to similar places below.
> 
> > +			DRM_ERROR("PG0 not enabled\n");
> > +			return;
> > +		}
> > +		break;
> > +	case SKL_DISP_PW_2:
> > +		if (!(fuse_status & SKL_FUSE_PG1_DIST_STATUS)) {
> > +			DRM_ERROR("PG1 in disabled state\n");
> > +			return;
> > +		}
> > +		break;
> > +	case SKL_DISP_PW_DDI_A_E:
> > +	case SKL_DISP_PW_DDI_B:
> > +	case SKL_DISP_PW_DDI_C:
> > +	case SKL_DISP_PW_DDI_D:
> > +		break;
> > +	default:
> 
> This would be a driver bug, so it needs a WARN().
> 
> > +		return;
> > +	}
> > +
> > +	req_mask = SKL_POWER_WELL_REQ(power_well->data);
> > +	state_mask = SKL_POWER_WELL_STATE(power_well->data);
> > +
> > +	if (enable) {
> > +		if (!(tmp & req_mask))
> > +			I915_WRITE(HSW_PWR_WELL_DRIVER, tmp | req_mask);
> > +
> > +		if (!(tmp & state_mask)) {
> > +			DRM_DEBUG_KMS("Enabling DDI power well\n");
> 
> Could be just "Enabling %s", power_well->name. Also we could miss the
> message depending on timing, so it needs to go above where the request
> bit is set.
> 
> With the above changes, this looks ok:
> Reviewed-by: Imre Deak <imre.deak@intel.com>
> 
> > +			if (wait_for((I915_READ(HSW_PWR_WELL_DRIVER) &
> > +				state_mask), 20))
> > +				DRM_ERROR("%s enable timeout\n",
> > +					power_well->name);
> > +			check_fuse_status = true;
> > +		}
> > +	} else {
> > +		if (tmp & req_mask) {
> > +			I915_WRITE(HSW_PWR_WELL_DRIVER,	tmp & ~req_mask);
> > +			POSTING_READ(HSW_PWR_WELL_DRIVER);
> > +			DRM_DEBUG_KMS("Disabling %s\n", power_well->name);
> > +		}
> > +	}
> > +
> > +	if (check_fuse_status) {
> > +		if (power_well->data == SKL_DISP_PW_1) {
> > +			if (wait_for((I915_READ(SKL_FUSE_STATUS) &
> > +				SKL_FUSE_PG1_DIST_STATUS), 5))
> > +				DRM_ERROR("PG1 distributing status timeout\n");
> > +		} else if (power_well->data == SKL_DISP_PW_2) {
> > +			if (wait_for((I915_READ(SKL_FUSE_STATUS) &
> > +				SKL_FUSE_PG2_DIST_STATUS), 1))
> > +				DRM_ERROR("PG2 distributing status timeout\n");
> > +		}
> > +	}
> > +}
> > +
> >  static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv,
> >  				   struct i915_power_well *power_well)
> >  {
> > @@ -7185,6 +7307,36 @@ static void hsw_power_well_disable(struct drm_i915_private *dev_priv,
> >  	hsw_set_power_well(dev_priv, power_well, false);
> >  }
> >  
> > +static bool skl_power_well_enabled(struct drm_i915_private *dev_priv,
> > +					struct i915_power_well *power_well)
> > +{
> > +	uint32_t mask = SKL_POWER_WELL_REQ(power_well->data) |
> > +		SKL_POWER_WELL_STATE(power_well->data);
> > +
> > +	return (I915_READ(HSW_PWR_WELL_DRIVER) & mask) == mask;
> > +}
> > +
> > +static void skl_power_well_sync_hw(struct drm_i915_private *dev_priv,
> > +				struct i915_power_well *power_well)
> > +{
> > +	skl_set_power_well(dev_priv, power_well, power_well->count > 0);
> > +
> > +	/* Clear any request made by BIOS as driver is taking over */
> > +	I915_WRITE(HSW_PWR_WELL_BIOS, 0);
> > +}
> > +
> > +static void skl_power_well_enable(struct drm_i915_private *dev_priv,
> > +				struct i915_power_well *power_well)
> > +{
> > +	skl_set_power_well(dev_priv, power_well, true);
> > +}
> > +
> > +static void skl_power_well_disable(struct drm_i915_private *dev_priv,
> > +				struct i915_power_well *power_well)
> > +{
> > +	skl_set_power_well(dev_priv, power_well, false);
> > +}
> > +
> >  static void i9xx_always_on_power_well_noop(struct drm_i915_private *dev_priv,
> >  					   struct i915_power_well *power_well)
> >  {
> > @@ -7787,6 +7939,13 @@ static const struct i915_power_well_ops hsw_power_well_ops = {
> >  	.is_enabled = hsw_power_well_enabled,
> >  };
> >  
> > +static const struct i915_power_well_ops skl_power_well_ops = {
> > +	.sync_hw = skl_power_well_sync_hw,
> > +	.enable = skl_power_well_enable,
> > +	.disable = skl_power_well_disable,
> > +	.is_enabled = skl_power_well_enabled,
> > +};
> > +
> >  static struct i915_power_well hsw_power_wells[] = {
> >  	{
> >  		.name = "always-on",
> > @@ -8009,6 +8168,51 @@ static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_pr
> >  	return NULL;
> >  }
> >  
> > +static struct i915_power_well skl_power_wells[] = {
> > +	{
> > +		.name = "always-on",
> > +		.always_on = 1,
> > +		.domains = SKL_DISPLAY_ALWAYS_ON_POWER_DOMAINS,
> > +		.ops = &i9xx_always_on_power_well_ops,
> > +	},
> > +	{
> > +		.name = "power well 1",
> > +		.domains = SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS,
> > +		.ops = &skl_power_well_ops,
> > +		.data = SKL_DISP_PW_1,
> > +	},
> > +	{
> > +		.name = "power well 2",
> > +		.domains = SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS,
> > +		.ops = &skl_power_well_ops,
> > +		.data = SKL_DISP_PW_2,
> > +	},
> > +	{
> > +		.name = "DDI A/E power well",
> > +		.domains = SKL_DISPLAY_DDI_A_E_POWER_DOMAINS,
> > +		.ops = &skl_power_well_ops,
> > +		.data = SKL_DISP_PW_DDI_A_E,
> > +	},
> > +	{
> > +		.name = "DDI B power well",
> > +		.domains = SKL_DISPLAY_DDI_B_POWER_DOMAINS,
> > +		.ops = &skl_power_well_ops,
> > +		.data = SKL_DISP_PW_DDI_B,
> > +	},
> > +	{
> > +		.name = "DDI C power well",
> > +		.domains = SKL_DISPLAY_DDI_C_POWER_DOMAINS,
> > +		.ops = &skl_power_well_ops,
> > +		.data = SKL_DISP_PW_DDI_C,
> > +	},
> > +	{
> > +		.name = "DDI D power well",
> > +		.domains = SKL_DISPLAY_DDI_D_POWER_DOMAINS,
> > +		.ops = &skl_power_well_ops,
> > +		.data = SKL_DISP_PW_DDI_D,
> > +	},
> > +};
> > +
> >  #define set_power_wells(power_domains, __power_wells) ({		\
> >  	(power_domains)->power_wells = (__power_wells);			\
> >  	(power_domains)->power_well_count = ARRAY_SIZE(__power_wells);	\
> > @@ -8030,6 +8234,9 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
> >  	} else if (IS_BROADWELL(dev_priv->dev)) {
> >  		set_power_wells(power_domains, bdw_power_wells);
> >  		hsw_pwr = power_domains;
> > +	} else if (IS_SKYLAKE(dev_priv->dev)) {
> > +		set_power_wells(power_domains, skl_power_wells);
> > +		hsw_pwr = power_domains;
> >  	} else if (IS_CHERRYVIEW(dev_priv->dev)) {
> >  		set_power_wells(power_domains, chv_power_wells);
> >  	} else if (IS_VALLEYVIEW(dev_priv->dev)) {
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 00/89] Basic Skylake enabling (reviewers)
  2014-09-04 14:16 ` [PATCH 00/89] Basic Skylake enabling (reviewers) Damien Lespiau
@ 2014-09-16 14:51   ` Thomas Wood
  2014-10-17 14:29   ` Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: Thomas Wood @ 2014-09-16 14:51 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Paulo R Zanoni, Intel Graphics Development, Rodrigo Vivi

On 4 September 2014 15:16, Damien Lespiau <damien.lespiau@intel.com> wrote:
> Of course, the series now needs reviewers. There's a list of known
> problems that I'm planning to address, a few of those problems are easy
> to solve and ca be addressed as a new revision of those pathes. However
> I'm hoping other ones can be follup up patches instead.
>
>
> Known issues:
>
>   - There a known limitation in the DDB allocation code. It doesn't
>     respect the minimal allocation of 8 blocks. When we're trying to
>     scannout two planes (not counting the cursor) that have widely
>     different data rates (1080p and 64x64), we'll under-allocate the
>     small plane and hit underuns.
>
>     (follow up series)
>
>   - There are a fair number of patches that are just "|| IS_GEN9(dev)".
>     I'd do a "let's by optimistic" pass on the driver to turn those into
>     "gen >= 9" to try to limit the number of small patches in the
>     future.
>
>     (follow up series)
>
>   - I haven't done a pass of the W/A just yet, waiting for things to
>     settle a bit. In particular I haven't checked that the few W/A
>     implemented can be done in init_clock_gating() or needs to be LRIs.
>     (the patch predates all of that).
>
>     (follow up series)
>
>   - While looking at the patches before sending, I've noticed some
>     extraneous defines in "Fix the extra defines in "drm/i915/skl: Read
>     the Memory Latency Values for WM computation".
>
>     Will send a new version of this patch rigth away
>
>   - There's potential to unify the primary and sprite planes functions
>     now that the primary plane is just another plane. This needs a bit
>     of work to unify those paths.
>
>     My current plan is to address this as a follow up series, not high
>     priority.
>
>   - Daniel had a few comments piped up already, the bigger ones have been
>     addressed. I, however didn't look at this one
>
>     < danvet> edp unconditionally uses cdclk/dpll0
>     < danvet> but we don't track the port clock for that anywhere in the pipe
>               config
>
>
> Reviewers
>
> some of the patches already have a r-b tag, having another look has some
> value as patches get rebased and churned a bit. Some people have 2 lines
> below.
>
> I've left some people out of the list as they're just jumping on the
> list and give feedback already. If you expect some big delays in the
> review, please do speak up so I can try to find somebody else.
>
> Patches  1 to 20, excluding 12: Thomas Wood


Patches 1 to 5, 7, 9, 13 to 16, 18 and 19 are:

Reviewed-by: Thomas Wood <thomas.wood@intel.com>


There are a few minor issues with patches 6 and 10:

  Patch 6 has a "v1" in the commit message, rather than "v2".
  Patch 10 seems to reference a non-existent commit id in the commit message.

Otherwise, these are also:

Reviewed-by: Thomas Wood <thomas.wood@intel.com>


Patches 8 and 11 have further comments, and patch 17 can be dropped as
it is superseded by patch 21.

Patch 20 is already reviewed and I am unsure if there was a conclusion
from the previous discussion about this change.


>
> Patches 12 + 21 to 42: Rodrigo
>
> Patches 43 to 52: Ville (WM)
>
> Patches 53 to 56: Mika (forcewake engine + a bit of rc6)
>
> Patch 57 is already merged
>
> Patches 58 to 68: Paulo (DPLL + removal of the eDP training W/A)
>
> Patches 69 to 73: Imre (Power wells)
>
> Patches 74 to 75: Paulo (queue_flip, pfit)
>
> Patches 76 to 83: Ville (WM part2)
>
> Patch 84 to 89: Mika (turbo and various small patches, some of them already
>                 dropped and/or reviewed)
>
> Thanks,
>
> --
> Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 08/89] drm/i915/skl: Use gen8_ring_dispatch_execbuffer() on GEN9
  2014-09-04 11:26 ` [PATCH 08/89] drm/i915/skl: Use gen8_ring_dispatch_execbuffer() on GEN9 Damien Lespiau
@ 2014-09-16 14:53   ` Thomas Wood
  2014-09-19 11:09     ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Thomas Wood @ 2014-09-16 14:53 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

On 4 September 2014 12:26, Damien Lespiau <damien.lespiau@intel.com> wrote:
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

While discussing this with Damien, he mentioned that legacy ring
buffer submission is not supported on gen 9 and perhaps
dispatch_execbuffer should be set to null instead.


> ---
>  drivers/gpu/drm/i915/intel_ringbuffer.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index f8aadc3..7b3d0ca 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -2361,7 +2361,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
>
>         if (IS_HASWELL(dev))
>                 ring->dispatch_execbuffer = hsw_ring_dispatch_execbuffer;
> -       else if (IS_GEN8(dev))
> +       else if (INTEL_INFO(dev)->gen >= 8)
>                 ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
>         else if (INTEL_INFO(dev)->gen >= 6)
>                 ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 11/89] drm/i915/skl: Framebuffers need to be aligned to 256Kb on Skylake
  2014-09-04 11:26 ` [PATCH 11/89] drm/i915/skl: Framebuffers need to be aligned to 256Kb on Skylake Damien Lespiau
@ 2014-09-16 14:54   ` Thomas Wood
  2014-09-19 11:26     ` [PATCH 11/89 v2] drm/i915/skl: Framebuffers need to be aligned to 256KB " Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Thomas Wood @ 2014-09-16 14:54 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

On 4 September 2014 12:26, Damien Lespiau <damien.lespiau@intel.com> wrote:
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

Does the X tiling alignment value need to be set too?

A minor point, but perhaps use KB in the subject rather than Kb?


> ---
>  drivers/gpu/drm/i915/intel_display.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 22d3902..02236f9 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2199,7 +2199,9 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
>
>         switch (obj->tiling_mode) {
>         case I915_TILING_NONE:
> -               if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
> +               if (INTEL_INFO(dev)->gen >= 9)
> +                       alignment = 256 * 1024;
> +               else if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
>                         alignment = 128 * 1024;
>                 else if (INTEL_INFO(dev)->gen >= 4)
>                         alignment = 4 * 1024;
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction
  2014-09-16 13:19   ` Imre Deak
@ 2014-09-16 16:13     ` Daniel Vetter
  2014-11-07 12:08     ` Damien Lespiau
  2014-11-07 13:11     ` Damien Lespiau
  2 siblings, 0 replies; 286+ messages in thread
From: Daniel Vetter @ 2014-09-16 16:13 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

On Tue, Sep 16, 2014 at 04:19:07PM +0300, Imre Deak wrote:
> On Thu, 2014-09-04 at 12:27 +0100, Damien Lespiau wrote:
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index 93bd9bf..a983b40 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -1233,6 +1233,9 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp)
> >  	power_domain = intel_display_port_power_domain(intel_encoder);
> >  	intel_display_power_get(dev_priv, power_domain);
> >  
> > +	power_domain = intel_display_aux_power_domain(intel_encoder);
> > +	intel_display_power_get(dev_priv, power_domain);
> > +
> 
> The AUX power domains were added to save power when only AUX
> functionality is needed, since then we don't need to power on the power
> domain needed for full port functionality. With the above change and
> everywhere else below we'll end up enabling both power domains, though
> we only need AUX functionality.
> 
> The power wells needed for AUX are a subset of those needed for full
> port functionality on all platforms (at least atm), so this patch won't
> change anything. The patch would make sense, if you requested only the
> AUX domains.

Also this changes shared code so should be split out from the stage 1
enabling. At least if we want to push it to 3.18 since drm-next already
closed feature-wise for that kernel.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 12/89] drm/i915/skl: Implement thew new update_plane() for primary planes
  2014-09-04 11:26 ` [PATCH 12/89] drm/i915/skl: Implement thew new update_plane() for primary planes Damien Lespiau
@ 2014-09-17  0:49   ` Rodrigo Vivi
  2014-09-22 11:18     ` [PATCH 12/89 v8] drm/i915/skl: Implement the " Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17  0:49 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 14306 bytes --]

On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> Skylake makes primary planes the same as sprite planes and call the
> result "universal planes".
>
> This commit emulates a primary plane with plane 0, taking the
> opportunity to redefine primary and sprite registers to be identical now
> that the underlying hardware is. It also makes sense as plenty of fields
> have changed.
>
> v2: Rebase on top of the vma code.
>
> v3: Follow upstream evolution:
> - Drop return values.
> - Remove pipe checks since redudant and BUG instead.
> - Remove tiling checks and BUG instead.
> - Drop commented out DISP_MODIFY usage.
>
> v4: s/plane/primary_plane/
>
> v5: Misc fixes:
> - Fix the fields we need to clear up
> - Disable trickle feed
> - Correctly use PLANE_OFFSET for the panning
>
> v6: (Jesse)
> Use pipe src size when programming plane size. This makes cloned configs
> work correctly w/o the use of a panel fitter.
>
> v7: Rebase on top of Ville's rmw elimination series
>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v1,5,6,7)
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v2,3)
> ---
>  drivers/gpu/drm/i915/i915_reg.h      | 110
> ++++++++++++++++++++++++++++++++++-
>  drivers/gpu/drm/i915/intel_display.c |  88 +++++++++++++++++++++++++++-
>  2 files changed, 195 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h
> index 15c0eaa..087085c 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -26,8 +26,8 @@
>  #define _I915_REG_H_
>
>  #define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a)))
> +#define _PLANE(plane, a, b) _PIPE(plane, a, b)
>  #define _TRANSCODER(tran, a, b) ((a) + (tran)*((b)-(a)))
> -
>  #define _PORT(port, a, b) ((a) + (port)*((b)-(a)))
>  #define _PIPE3(pipe, a, b, c) ((pipe) == PIPE_A ? (a) : \
>                                (pipe) == PIPE_B ? (b) : (c))
> @@ -4495,6 +4495,114 @@ enum punit_power_well {
>  #define SPCONSTALPHA(pipe, plane) _PIPE(pipe * 2 + plane, _SPACONSTALPHA,
> _SPBCONSTALPHA)
>  #define SPGAMC(pipe, plane) _PIPE(pipe * 2 + plane, _SPAGAMC, _SPBGAMC)
>
> +/* Skylake plane registers */
> +
> +#define _PLANE_CTL_1_A                         0x70180
> +#define _PLANE_CTL_2_A                         0x70280
> +#define _PLANE_CTL_3_A                         0x70380

#first-bickesheding ;)
 Since the definitions os 4_A, {1,2,3,4}_B and {1,2,3,4}_C are all in the
same spec with same bits below I'd prefer to define them here.

>

+#define   PLANE_CTL_ENABLE                     (1 << 31)
> +#define   PLANE_CTL_PIPE_GAMMA_ENABLE          (1 << 30)
> +#define   PLANE_CTL_FORMAT_MASK                        (0xf << 24)
> +#define   PLANE_CTL_FORMAT_YUV422              (  0 << 24)
> +#define   PLANE_CTL_FORMAT_NV12                        (  1 << 24)
> +#define   PLANE_CTL_FORMAT_XRGB_2101010                (  2 << 24)
> +#define   PLANE_CTL_FORMAT_XRGB_8888           (  4 << 24)
> +#define   PLANE_CTL_FORMAT_XRGB_16161616F      (  6 << 24)
> +#define   PLANE_CTL_FORMAT_AYUV                        (  8 << 24)
>

1010 missed or useless to add here?


> +#define   PLANE_CTL_FORMAT_INDEXED             ( 12 << 24)
> +#define   PLANE_CTL_FORMAT_RGB_565             ( 14 << 24)
> +#define   PLANE_CTL_PIPE_CSC_ENABLE            (1 << 23)
> +#define   PLANE_CTL_KEY_ENABLE                 (1 << 22)
>

Key is [22:21] and 01, i.e 22=0 also is a kind of Key enabled.
Or just the source matters?
In this case second bikesheding would be change for SOURCE_KEY_ENABLE


> +#define   PLANE_CTL_ORDER_BGRX                 (0 << 20)
> +#define   PLANE_CTL_ORDER_RGBX                 (1 << 20)
> +#define   PLANE_CTL_YUV422_ORDER_MASK          (0x3 << 16)
> +#define   PLANE_CTL_YUV422_YUYV                        (  0 << 16)
> +#define   PLANE_CTL_YUV422_UYVY                        (  1 << 16)
> +#define   PLANE_CTL_YUV422_YVYU                        (  2 << 16)
> +#define   PLANE_CTL_YUV422_VYUY                        (  3 << 16)
> +#define   PLANE_CTL_DECOMPRESSION_ENABLE       (1 << 15)

+#define   PLANE_CTL_TRICKLE_FEED_DISABLE       (1 << 14)
>

On Spec there is a restrictions: "Do not program this field to 1b." So I'd
prefer to declare FEED_ENABLE (0 << 14). Just to avoid have to always ~ it.


> +#define   PLANE_CTL_PLANE_GAMMA_DISABLE                (1 << 13)
> +#define   PLANE_CTL_TILED_MASK                 (0x7 << 10)
> +#define   PLANE_CTL_TILED_LINEAR               (  0 << 10)
> +#define   PLANE_CTL_TILED_X                    (  1 << 10)
> +#define   PLANE_CTL_TILED_Y                    (  4 << 10)
> +#define   PLANE_CTL_TILED_YF                   (  5 << 10)
> +#define   PLANE_CTL_ALPHA_MASK                 (0x3 << 4)
> +#define   PLANE_CTL_ALPHA_DISABLE              (  0 << 4)
> +#define   PLANE_CTL_ALPHA_SW_PREMULTIPLY       (  2 << 4)
> +#define   PLANE_CTL_ALPHA_HW_PREMULTIPLY       (  3 << 4)
> +#define _PLANE_STRIDE_1_A                      0x70188
> +#define _PLANE_STRIDE_2_A                      0x70288
> +#define _PLANE_STRIDE_3_A                      0x70388
> +#define _PLANE_POS_1_A                         0x7018c
> +#define _PLANE_POS_2_A                         0x7028c
> +#define _PLANE_POS_3_A                         0x7038c
> +#define _PLANE_SIZE_1_A                                0x70190
> +#define _PLANE_SIZE_2_A                                0x70290
> +#define _PLANE_SIZE_3_A                                0x70390
> +#define _PLANE_SURF_1_A                                0x7019c
> +#define _PLANE_SURF_2_A                                0x7029c
> +#define _PLANE_SURF_3_A                                0x7039c
> +#define _PLANE_OFFSET_1_A                      0x701a4
> +#define _PLANE_OFFSET_2_A                      0x702a4
> +#define _PLANE_OFFSET_3_A                      0x703a4
> +
> +#define _PLANE_CTL_1_B                         0x71180
> +#define _PLANE_CTL_2_B                         0x71280
> +#define _PLANE_CTL_3_B                         0x71380
> +#define _PLANE_CTL_1(pipe)     _PIPE(pipe, _PLANE_CTL_1_A, _PLANE_CTL_1_B)
> +#define _PLANE_CTL_2(pipe)     _PIPE(pipe, _PLANE_CTL_2_A, _PLANE_CTL_2_B)
> +#define _PLANE_CTL_3(pipe)     _PIPE(pipe, _PLANE_CTL_3_A, _PLANE_CTL_3_B)
> +#define PLANE_CTL(pipe, plane) \
> +       _PLANE(plane, _PLANE_CTL_1(pipe), _PLANE_CTL_2(pipe))
> +
> +#define _PLANE_STRIDE_1_B                      0x71188
> +#define _PLANE_STRIDE_2_B                      0x71288
> +#define _PLANE_STRIDE_3_B                      0x71388
> +#define _PLANE_STRIDE_1(pipe)  \
> +       _PIPE(pipe, _PLANE_STRIDE_1_A, _PLANE_STRIDE_1_B)
> +#define _PLANE_STRIDE_2(pipe)  \
> +       _PIPE(pipe, _PLANE_STRIDE_2_A, _PLANE_STRIDE_2_B)
> +#define _PLANE_STRIDE_3(pipe)  \
> +       _PIPE(pipe, _PLANE_STRIDE_3_A, _PLANE_STRIDE_3_B)
> +#define PLANE_STRIDE(pipe, plane)      \
> +       _PLANE(plane, _PLANE_STRIDE_1(pipe), _PLANE_STRIDE_2(pipe))
> +
> +#define _PLANE_POS_1_B                         0x7118c
> +#define _PLANE_POS_2_B                         0x7128c
> +#define _PLANE_POS_3_B                         0x7138c
> +#define _PLANE_POS_1(pipe)     _PIPE(pipe, _PLANE_POS_1_A, _PLANE_POS_1_B)
> +#define _PLANE_POS_2(pipe)     _PIPE(pipe, _PLANE_POS_2_A, _PLANE_POS_2_B)
> +#define _PLANE_POS_3(pipe)     _PIPE(pipe, _PLANE_POS_3_A, _PLANE_POS_3_B)
> +#define PLANE_POS(pipe, plane) \
> +       _PLANE(plane, _PLANE_POS_1(pipe), _PLANE_POS_2(pipe))
> +
> +#define _PLANE_SIZE_1_B                                0x71190
> +#define _PLANE_SIZE_2_B                                0x71290
> +#define _PLANE_SIZE_3_B                                0x71390
> +#define _PLANE_SIZE_1(pipe)    _PIPE(pipe, _PLANE_SIZE_1_A,
> _PLANE_SIZE_1_B)
> +#define _PLANE_SIZE_2(pipe)    _PIPE(pipe, _PLANE_SIZE_2_A,
> _PLANE_SIZE_2_B)
> +#define _PLANE_SIZE_3(pipe)    _PIPE(pipe, _PLANE_SIZE_3_A,
> _PLANE_SIZE_3_B)
> +#define PLANE_SIZE(pipe, plane)        \
> +       _PLANE(plane, _PLANE_SIZE_1(pipe), _PLANE_SIZE_2(pipe))
> +
> +#define _PLANE_SURF_1_B                                0x7119c
> +#define _PLANE_SURF_2_B                                0x7129c
> +#define _PLANE_SURF_3_B                                0x7139c
> +#define _PLANE_SURF_1(pipe)    _PIPE(pipe, _PLANE_SURF_1_A,
> _PLANE_SURF_1_B)
> +#define _PLANE_SURF_2(pipe)    _PIPE(pipe, _PLANE_SURF_2_A,
> _PLANE_SURF_2_B)
> +#define _PLANE_SURF_3(pipe)    _PIPE(pipe, _PLANE_SURF_3_A,
> _PLANE_SURF_3_B)
> +#define PLANE_SURF(pipe, plane)        \
> +       _PLANE(plane, _PLANE_SURF_1(pipe), _PLANE_SURF_2(pipe))
> +
> +#define _PLANE_OFFSET_1_B                      0x711a4
> +#define _PLANE_OFFSET_2_B                      0x712a4
> +#define _PLANE_OFFSET_1(pipe) _PIPE(pipe, _PLANE_OFFSET_1_A,
> _PLANE_OFFSET_1_B)
> +#define _PLANE_OFFSET_2(pipe) _PIPE(pipe, _PLANE_OFFSET_2_A,
> _PLANE_OFFSET_2_B)
> +#define PLANE_OFFSET(pipe, plane)      \
> +       _PLANE(plane, _PLANE_OFFSET_1(pipe), _PLANE_OFFSET_2(pipe))
> +
>  /* VBIOS regs */
>  #define VGACNTRL               0x71400
>  # define VGA_DISP_DISABLE                      (1 << 31)
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 02236f9..f98d1c4 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2640,6 +2640,86 @@ static void ironlake_update_primary_plane(struct
> drm_crtc *crtc,
>         POSTING_READ(reg);
>  }
>
> +static void skylake_update_primary_plane(struct drm_crtc *crtc,
> +                                        struct drm_framebuffer *fb,
> +                                        int x, int y)
> +{
> +       struct drm_device *dev = crtc->dev;
> +       struct drm_i915_private *dev_priv = dev->dev_private;
> +       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +       struct intel_framebuffer *intel_fb;
> +       struct drm_i915_gem_object *obj;
> +       int pipe = intel_crtc->pipe;
> +       u32 plane_ctl, stride;
> +
> +       if (!intel_crtc->primary_enabled) {
> +               I915_WRITE(PLANE_CTL(pipe, 0), 0);
> +               I915_WRITE(PLANE_SURF(pipe, 0), 0);
> +               POSTING_READ(PLANE_CTL(pipe, 0));
> +               return;
> +       }
> +
> +       plane_ctl = PLANE_CTL_ENABLE |
> +                   PLANE_CTL_PIPE_GAMMA_ENABLE |
> +                   PLANE_CTL_PIPE_CSC_ENABLE;
> +
> +       switch (fb->pixel_format) {
> +       case DRM_FORMAT_RGB565:
> +               plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
> +               break;
> +       case DRM_FORMAT_XRGB8888:
> +               plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> +               break;
> +       case DRM_FORMAT_XBGR8888:
> +               plane_ctl |= PLANE_CTL_ORDER_RGBX;
> +               plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> +               break;
> +       case DRM_FORMAT_XRGB2101010:
> +               plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
> +               break;
> +       case DRM_FORMAT_XBGR2101010:
> +               plane_ctl |= PLANE_CTL_ORDER_RGBX;
> +               plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
> +               break;
> +       default:
> +               BUG();
> +       }
> +
> +       intel_fb = to_intel_framebuffer(fb);
> +       obj = intel_fb->obj;
> +       switch (obj->tiling_mode) {
> +       case I915_TILING_NONE:
> +               stride = fb->pitches[0] >> 6;
>
A comment here would be good to explain this:
"For Linear memory this field specifies the stride in chunks of 64 bytes"

> +               break;
> +       case I915_TILING_X:
> +               plane_ctl |= PLANE_CTL_TILED_X;
> +               stride = fb->pitches[0] >> 9;

and something like or better than the following here:
"Fox X-tiled this field specifies the stride in number of tiles" 1/512
bytes.


> +               break;
> +       default:
>

is I915_TILING_Y  impossible?

+               BUG();
> +       }
> +
> +       plane_ctl &= ~PLANE_CTL_TRICKLE_FEED_DISABLE;
> +       plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
> +
> +       I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
> +
> +       DRM_DEBUG_KMS("Writing base %08lX %d,%d,%d,%d pitch=%d\n",
> +                     i915_gem_obj_ggtt_offset(obj),
> +                     x, y, fb->width, fb->height,
> +                     fb->pitches[0]);
> +
> +       I915_WRITE(PLANE_POS(pipe, 0), 0);
> +       I915_WRITE(PLANE_OFFSET(pipe, 0), (y << 16) | x);
> +       I915_WRITE(PLANE_SIZE(pipe, 0),
> +                  (intel_crtc->config.pipe_src_h - 1) << 16 |
> +                  (intel_crtc->config.pipe_src_w - 1));
> +       I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
> +       I915_WRITE(PLANE_SURF(pipe, 0), i915_gem_obj_ggtt_offset(obj));
> +
> +       POSTING_READ(PLANE_SURF(pipe, 0));
> +}
> +
>  /* Assume fb object is pinned & idle & fenced and just update base
> pointers */
>  static int
>  intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer
> *fb,
> @@ -12481,8 +12561,12 @@ static void intel_init_display(struct drm_device
> *dev)
>                 dev_priv->display.crtc_enable = haswell_crtc_enable;
>                 dev_priv->display.crtc_disable = haswell_crtc_disable;
>                 dev_priv->display.off = ironlake_crtc_off;
> -               dev_priv->display.update_primary_plane =
> -                       ironlake_update_primary_plane;
> +               if (INTEL_INFO(dev)->gen >= 9)
> +                       dev_priv->display.update_primary_plane =
> +                               skylake_update_primary_plane;
> +               else
> +                       dev_priv->display.update_primary_plane =
> +                               ironlake_update_primary_plane;
>         } else if (HAS_PCH_SPLIT(dev)) {
>                 dev_priv->display.get_pipe_config =
> ironlake_get_pipe_config;
>                 dev_priv->display.get_plane_config =
> ironlake_get_plane_config;
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>


Regardless the bikeshedings, and if all answers to the questions above
result in no change to the code, consider this
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>


-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 19707 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 21/89] drm/i915/skl: Implement the get_aux_clock_divider() DP vfunc
  2014-09-04 11:26 ` [PATCH 21/89] drm/i915/skl: Implement the get_aux_clock_divider() DP vfunc Damien Lespiau
@ 2014-09-17  1:12   ` Rodrigo Vivi
  2014-09-22 13:21     ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17  1:12 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 2378 bytes --]

I believe this patch should remove the gen9 part of
ilk_get_aux_clock_divider.

Also there it just returns 0, but here it returns 0 or 1 depending on the
index.
This also is incoherent with the commit description.

On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> We need to provide a vfunc that will make the code in intel_dp_aux_ch()
> loop once to start the AUX transaction. The return value (clock divider)
> is unused on SKL, so just return 1.
>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dp.c | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c
> b/drivers/gpu/drm/i915/intel_dp.c
> index a95fb47..4560ced 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -489,6 +489,16 @@ static uint32_t vlv_get_aux_clock_divider(struct
> intel_dp *intel_dp, int index)
>         return index ? 0 : 100;
>  }
>
> +static uint32_t skl_get_aux_clock_divider(struct intel_dp *intel_dp, int
> index)
> +{
> +       /*
> +        * SKL doesn't need us to program the AUX clock divider (Hardware
> will
> +        * derive the clock from CDCLK automatically). We still implement
> the
> +        * get_aux_clock_divider vfunc to plug-in into the existing code.
> +        */
> +       return index ? 0 : 1;
> +}
> +
>  static uint32_t i9xx_get_aux_send_ctl(struct intel_dp *intel_dp,
>                                       bool has_aux_irq,
>                                       int send_bytes,
> @@ -4726,7 +4736,9 @@ intel_dp_init_connector(struct intel_digital_port
> *intel_dig_port,
>         int type;
>
>         /* intel_dp vfuncs */
> -       if (IS_VALLEYVIEW(dev))
> +       if (INTEL_INFO(dev)->gen >= 9)
> +               intel_dp->get_aux_clock_divider =
> skl_get_aux_clock_divider;
> +       else if (IS_VALLEYVIEW(dev))
>                 intel_dp->get_aux_clock_divider =
> vlv_get_aux_clock_divider;
>         else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>                 intel_dp->get_aux_clock_divider =
> hsw_get_aux_clock_divider;
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 3345 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 22/89] drm/i915/skl: Provide a get_aux_send_ctl() vfunc for skylake
  2014-09-04 11:26 ` [PATCH 22/89] drm/i915/skl: Provide a get_aux_send_ctl() vfunc for skylake Damien Lespiau
@ 2014-09-17  1:16   ` Rodrigo Vivi
  0 siblings, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17  1:16 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 3126 bytes --]

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> Skylake doesn't use the pre-charge field now, but, instead, we need to
> specify the total number of SYNC pulses for the SYNC phase (pre-charge +
> SYNC pattern pules). Let's use the default value (32) for that.
>
> v3: increase DP AUX TX timeout as 400us is not to be used on SKL
>     apparently (Jesse).
>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h |  1 +
>  drivers/gpu/drm/i915/intel_dp.c | 20 +++++++++++++++++++-
>  2 files changed, 20 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h
> index 087085c..acd0a7b 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -3630,6 +3630,7 @@ enum punit_power_well {
>  #define   DP_AUX_CH_CTL_PRECHARGE_TEST     (1 << 11)
>  #define   DP_AUX_CH_CTL_BIT_CLOCK_2X_MASK    (0x7ff)
>  #define   DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT   0
> +#define   DP_AUX_CH_CTL_SYNC_PULSE_SKL(c)   ((c) - 1)
>
>  /*
>   * Computing GMCH M and N values for the Display Port link
> diff --git a/drivers/gpu/drm/i915/intel_dp.c
> b/drivers/gpu/drm/i915/intel_dp.c
> index 4560ced..5755f59 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -529,6 +529,21 @@ static uint32_t i9xx_get_aux_send_ctl(struct intel_dp
> *intel_dp,
>                (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT);
>  }
>
> +static uint32_t skl_get_aux_send_ctl(struct intel_dp *intel_dp,
> +                                     bool has_aux_irq,
> +                                     int send_bytes,
> +                                     uint32_t unused)
> +{
> +       return DP_AUX_CH_CTL_SEND_BUSY |
> +              DP_AUX_CH_CTL_DONE |
> +              (has_aux_irq ? DP_AUX_CH_CTL_INTERRUPT : 0) |
> +              DP_AUX_CH_CTL_TIME_OUT_ERROR |
> +              DP_AUX_CH_CTL_TIME_OUT_1600us |
> +              DP_AUX_CH_CTL_RECEIVE_ERROR |
> +              (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
> +              DP_AUX_CH_CTL_SYNC_PULSE_SKL(32);
> +}
> +
>  static int
>  intel_dp_aux_ch(struct intel_dp *intel_dp,
>                 uint8_t *send, int send_bytes,
> @@ -4747,7 +4762,10 @@ intel_dp_init_connector(struct intel_digital_port
> *intel_dig_port,
>         else
>                 intel_dp->get_aux_clock_divider =
> i9xx_get_aux_clock_divider;
>
> -       intel_dp->get_aux_send_ctl = i9xx_get_aux_send_ctl;
> +       if (INTEL_INFO(dev)->gen >= 9)
> +               intel_dp->get_aux_send_ctl = skl_get_aux_send_ctl;
> +       else
> +               intel_dp->get_aux_send_ctl = i9xx_get_aux_send_ctl;
>
>         /* Preserve the current hw state. */
>         intel_dp->DP = I915_READ(intel_dp->output_reg);
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 4304 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 23/89] drm/i915/skl: Initialize PPGTT like gen8
  2014-09-04 11:26 ` [PATCH 23/89] drm/i915/skl: Initialize PPGTT like gen8 Damien Lespiau
@ 2014-09-17  1:17   ` Rodrigo Vivi
  0 siblings, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17  1:17 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1371 bytes --]

This already has the ideal rv-b ;)
But feel free to also use:
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> gen9 uses very similar memory management to what gen8 has. Just follow
> the flow.
>
> v2: Fix trivial conflict (Damien)
>
> Reviewed-by: Ben Widawsky <ben@bwidawsk.net>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c
> b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 688dd00..66e4b2b 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -1092,7 +1092,7 @@ static int __hw_ppgtt_init(struct drm_device *dev,
> struct i915_hw_ppgtt *ppgtt)
>
>         if (INTEL_INFO(dev)->gen < 8)
>                 return gen6_ppgtt_init(ppgtt);
> -       else if (IS_GEN8(dev))
> +       else if (IS_GEN8(dev) || IS_GEN9(dev))
>                 return gen8_ppgtt_init(ppgtt, dev_priv->gtt.base.total);
>         else
>                 BUG();
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 2295 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 24/89] drm/i915/skl: Allow the reg_read ioctl to return RCS_TIMESTAMP
  2014-09-04 11:26 ` [PATCH 24/89] drm/i915/skl: Allow the reg_read ioctl to return RCS_TIMESTAMP Damien Lespiau
@ 2014-09-17  1:27   ` Rodrigo Vivi
  2014-09-22 13:27     ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17  1:27 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1233 bytes --]

This seems to allow more than just the RCS timestamp, but also allow
the I915_REG_READ ioctl for gen9.

Anyway:
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_uncore.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c
> b/drivers/gpu/drm/i915/intel_uncore.c
> index 918b761..3b27fb0 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -968,7 +968,7 @@ static const struct register_whitelist {
>         /* supported gens, 0x10 for 4, 0x30 for 4 and 5, etc. */
>         uint32_t gen_bitmask;
>  } whitelist[] = {
> -       { RING_TIMESTAMP(RENDER_RING_BASE), 8, GEN_RANGE(4, 8) },
> +       { RING_TIMESTAMP(RENDER_RING_BASE), 8, GEN_RANGE(4, 9) },
>  };
>
>  int i915_reg_read_ioctl(struct drm_device *dev,
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 2080 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 25/89] drm/i915/skl: report the same INSTDONE registers as gen8
  2014-09-04 11:26 ` [PATCH 25/89] drm/i915/skl: report the same INSTDONE registers as gen8 Damien Lespiau
@ 2014-09-17  1:28   ` Rodrigo Vivi
  0 siblings, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17  1:28 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1135 bytes --]

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_gpu_error.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c
> b/drivers/gpu/drm/i915/i915_gpu_error.c
> index 68fd767..1bf6e69 100644
> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> @@ -1390,6 +1390,7 @@ void i915_get_extra_instdone(struct drm_device *dev,
> uint32_t *instdone)
>                 WARN_ONCE(1, "Unsupported platform\n");
>         case 7:
>         case 8:
> +       case 9:
>                 instdone[0] = I915_READ(GEN7_INSTDONE_1);
>                 instdone[1] = I915_READ(GEN7_SC_INSTDONE);
>                 instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE);
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 1976 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 26/89] drm/i915/skl: Report the PDP regs as in gen8
  2014-09-04 11:26 ` [PATCH 26/89] drm/i915/skl: Report the PDP regs as in gen8 Damien Lespiau
@ 2014-09-17  1:33   ` Rodrigo Vivi
  0 siblings, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17  1:33 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1250 bytes --]

I just noticed this is a "legacy" mode 48b and standard for skl would be a
64b aligned..

But anyway this seems to be the right for now so
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_gpu_error.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c
> b/drivers/gpu/drm/i915/i915_gpu_error.c
> index 1bf6e69..fe14980 100644
> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> @@ -924,6 +924,7 @@ static void i915_record_ring_state(struct drm_device
> *dev,
>                 ering->vm_info.gfx_mode = I915_READ(RING_MODE_GEN7(ring));
>
>                 switch (INTEL_INFO(dev)->gen) {
> +               case 9:
>                 case 8:
>                         for (i = 0; i < 4; i++) {
>                                 ering->vm_info.pdp[i] =
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 2154 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 27/89] drm/i915/skl: SKL shares the same underrun interrupt as BDW
  2014-09-04 11:26 ` [PATCH 27/89] drm/i915/skl: SKL shares the same underrun interrupt as BDW Damien Lespiau
@ 2014-09-17  1:39   ` Rodrigo Vivi
  0 siblings, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17  1:39 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1304 bytes --]

the rest of DE_PIPE_INTERRUPT definition is different from BDW to SKL but
the underrun is indeed the same!

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_irq.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c
> b/drivers/gpu/drm/i915/i915_irq.c
> index e9979f5..c62a2e4 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -503,7 +503,7 @@ static bool
> __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
>                 ironlake_set_fifo_underrun_reporting(dev, pipe, enable);
>         else if (IS_GEN7(dev))
>                 ivybridge_set_fifo_underrun_reporting(dev, pipe, enable,
> old);
> -       else if (IS_GEN8(dev))
> +       else if (IS_GEN8(dev) || IS_GEN9(dev))
>                 broadwell_set_fifo_underrun_reporting(dev, pipe, enable);
>
>         return old;
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 2157 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 28/89] drm/i915/skl: SKL pipe misc programming
  2014-09-04 11:26 ` [PATCH 28/89] drm/i915/skl: SKL pipe misc programming Damien Lespiau
@ 2014-09-17  1:43   ` Rodrigo Vivi
  0 siblings, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17  1:43 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1448 bytes --]

Again, PIPE_MISC has differences, but this dither set part is identical!

So:
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>
> Pipe misc programming in gen9 is similar to BDW. Extending the BDW
> implementation to gen 9.
>
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 6ad8098..bffabfd 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -7022,7 +7022,7 @@ static void haswell_set_pipeconf(struct drm_crtc
> *crtc)
>         I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT);
>         POSTING_READ(GAMMA_MODE(intel_crtc->pipe));
>
> -       if (IS_BROADWELL(dev)) {
> +       if (IS_BROADWELL(dev) || INTEL_INFO(dev)->gen >= 9) {
>                 val = 0;
>
>                 switch (intel_crtc->config.pipe_bpp) {
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 2455 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 29/89] drm/i915/skl: vfuncs for skl eld and global resource
  2014-09-04 11:26 ` [PATCH 29/89] drm/i915/skl: vfuncs for skl eld and global resource Damien Lespiau
@ 2014-09-17  1:50   ` Rodrigo Vivi
  2014-09-22 13:32     ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17  1:50 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1691 bytes --]

isn't fdi_link_training needed?

if not: Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>
> Set gen 9 function pointers for eld write and global resource.
> Implementation remains same as HSW.
>
> v2: Rebase on top of Sonika's untangling of the if/else ladder (Damien)
>
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v1)
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index bffabfd..48d2d0d 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -12654,6 +12654,10 @@ static void intel_init_display(struct drm_device
> *dev)
>                 dev_priv->display.modeset_global_resources =
>                         valleyview_modeset_global_resources;
>                 dev_priv->display.write_eld = ironlake_write_eld;
> +       } else if (INTEL_INFO(dev)->gen >= 9) {
> +               dev_priv->display.write_eld = haswell_write_eld;
> +               dev_priv->display.modeset_global_resources =
> +                       haswell_modeset_global_resources;
>         }
>
>         /* Default just returns -ENODEV to indicate unsupported */
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 2745 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 30/89] drm/i915/skl: SKL backlight enabling
  2014-09-04 11:26 ` [PATCH 30/89] drm/i915/skl: SKL backlight enabling Damien Lespiau
@ 2014-09-17  1:56   ` Rodrigo Vivi
  2014-09-17  9:09     ` Jani Nikula
  0 siblings, 1 reply; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17  1:56 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1492 bytes --]

This is wrong.

A skl_enable_backlight must be created setting c8254 propperly without the
shift 16. Also maybe setting c8354h.


On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>
> Extending the BDW backlight implementation to SKL.
>
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_panel.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_panel.c
> b/drivers/gpu/drm/i915/intel_panel.c
> index 1878447..d69a3cb6 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -1317,7 +1317,7 @@ void intel_panel_init_backlight_funcs(struct
> drm_device *dev)
>  {
>         struct drm_i915_private *dev_priv = dev->dev_private;
>
> -       if (IS_BROADWELL(dev)) {
> +       if (IS_BROADWELL(dev) || (INTEL_INFO(dev)->gen >= 9)) {
>                 dev_priv->display.setup_backlight = bdw_setup_backlight;
>                 dev_priv->display.enable_backlight = bdw_enable_backlight;
>                 dev_priv->display.disable_backlight =
> pch_disable_backlight;
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 2453 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 30/89] drm/i915/skl: SKL backlight enabling
  2014-09-17  1:56   ` Rodrigo Vivi
@ 2014-09-17  9:09     ` Jani Nikula
  2014-09-17 13:46       ` Rodrigo Vivi
  0 siblings, 1 reply; 286+ messages in thread
From: Jani Nikula @ 2014-09-17  9:09 UTC (permalink / raw)
  To: Rodrigo Vivi, Damien Lespiau; +Cc: intel-gfx

On Wed, 17 Sep 2014, Rodrigo Vivi <rodrigo.vivi@gmail.com> wrote:
> This is wrong.
>
> A skl_enable_backlight must be created setting c8254 propperly without the
> shift 16. Also maybe setting c8354h.

Nope, this is all right for skl/spt, with the small exception that it'll
need the equivalent of [1]. I'll post another version addressing Ville's
comments.

BR,
Jani.


[1] http://mid.gmane.org/87y4tzefmz.fsf@intel.com


>
>
> On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
> wrote:
>
>> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>>
>> Extending the BDW backlight implementation to SKL.
>>
>> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_panel.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_panel.c
>> b/drivers/gpu/drm/i915/intel_panel.c
>> index 1878447..d69a3cb6 100644
>> --- a/drivers/gpu/drm/i915/intel_panel.c
>> +++ b/drivers/gpu/drm/i915/intel_panel.c
>> @@ -1317,7 +1317,7 @@ void intel_panel_init_backlight_funcs(struct
>> drm_device *dev)
>>  {
>>         struct drm_i915_private *dev_priv = dev->dev_private;
>>
>> -       if (IS_BROADWELL(dev)) {
>> +       if (IS_BROADWELL(dev) || (INTEL_INFO(dev)->gen >= 9)) {
>>                 dev_priv->display.setup_backlight = bdw_setup_backlight;
>>                 dev_priv->display.enable_backlight = bdw_enable_backlight;
>>                 dev_priv->display.disable_backlight =
>> pch_disable_backlight;
>> --
>> 1.8.3.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>
>
>
>
> -- 
> Rodrigo Vivi
> Blog: http://blog.vivi.eng.br
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 46/89] drm/i915/skl: Add DDB allocation management structures
  2014-09-04 11:27 ` [PATCH 46/89] drm/i915/skl: Add DDB allocation management structures Damien Lespiau
@ 2014-09-17 10:47   ` Ville Syrjälä
  2014-09-22 14:08     ` Damien Lespiau
  2014-10-29 15:32   ` Ville Syrjälä
  1 sibling, 1 reply; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-17 10:47 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:27:12PM +0100, Damien Lespiau wrote:
> We now need to allocate space in the DDB for planes being scanned out
> ourselves. The data structure to represent an allocation mirrors what
> we'll need to write in the registers later on: (start, end).
> 
> We add that allocation datat to the skl_wm_values structure as part of
> the values to program the hardware with.
> 
> v2: Split planes and cursor for consistency.
> 
> v3: Make the skl_ddb_entry_size() parameter const
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 3764ad5..de278a5 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1381,8 +1381,27 @@ struct ilk_wm_values {
>  	enum intel_ddb_partitioning partitioning;
>  };
>  
> +struct skl_ddb_entry {
> +	uint16_t start, end;	/* in number of blocks */
> +};
> +
> +static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry)
> +{
> +	/* end not set, clearly no allocation here. start can be 0 though */
> +	if (entry->end == 0)
> +		return 0;
> +
> +	return entry->end - entry->start + 1;

I would make 'end' exclusive as that allows you to represent an empty
block more naturally, and you don't have to worry about the +/-1 adjustments
when going between start/end and start/size representation.

> +}
> +
> +struct skl_ddb_allocation {
> +	struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
> +	struct skl_ddb_entry cursor[I915_MAX_PIPES];
> +};
> +
>  struct skl_wm_values {
>  	bool dirty[I915_MAX_PIPES];
> +	struct skl_ddb_allocation ddb;
>  	uint32_t wm_linetime[I915_MAX_PIPES];
>  	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
>  	uint32_t cursor[I915_MAX_PIPES][8];
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 47/89] drm/i915/skl: SKL Watermark Computation
  2014-09-04 11:27 ` [PATCH 47/89] drm/i915/skl: SKL Watermark Computation Damien Lespiau
@ 2014-09-17 12:07   ` Ville Syrjälä
  2014-09-22 22:36     ` Damien Lespiau
                       ` (2 more replies)
  0 siblings, 3 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-17 12:07 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx, Pradeep Bhat

On Thu, Sep 04, 2014 at 12:27:13PM +0100, Damien Lespiau wrote:
> From: Pradeep Bhat <pradeep.bhat@intel.com>
> 
> This patch implements the watermark algorithm and its necessary
> functions. Two function pointers skl_update_wm and
> skl_update_sprite_wm are provided. The skl_update_wm will update
> the watermarks for the crtc provided as an argument and then
> checks for change in DDB allocation for other active pipes and
> recomputes the watermarks for those Pipes and planes as well.
> Finally it does the register programming for all dirty pipes.
> The trigger of the Watermark double buffer registers will have
> to be once the plane configurations are done by the caller.
> 
> v2: fixed the divide-by-0 error in the results computation func.
>     Also reworked the PLANE_WM register values computation func to
>     make it more compact. Incorporated all other review comments
>     from Damien.
> 
> v3: Changed the skl_compute_plane_wm function to now return success
>     or failure. Also the result blocks and lines are computed here
>     instead of in skl_compute_wm_results function.
> 
> v4: Adjust skl_ddb_alloc_changed() to the new planes/cursor split
>     (Damien)
> 
> v5: Reworked the affected functions to implement new plane/cursor
>     split.
> 
> v6: Rework the logic that triggers the DDB allocation and WM computation
>     of skl_update_other_pipe_wm() to not depend on non-computed DDB
>     values.
>     Always give a valid cursor_width (at boot it's 0) to keep the
>     invariant that we consider the cursor plane always enabled.
>     Otherwise we end up dividing by 0 in skl_compute_plane_wm()
>     (Damien Lespiau)
> 
> v7: Spell out allocation
>     skl_ddb_ functions should have the ddb as first argument
>     Make the skl_ddb_alloc_changed() parameters const
>     (Damien)
> 
> v8: Rebase on top of the crtc->primary changes
> 
> v9: Split the staging results structure to not exceed the 1Kb stack
>     allocation in skl_update_wm()
> 
> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> 
> drm/i915/skl: Don't allocate as much on the stack in skl_update_wm()
> 
> Stack space can be scarce and a compiler check has been added to warn if the
> per-function stack allocation is above 1KB.
> 
> We we were hitting that warning in skl_update_wm(), so move the big
> results array in dev_priv instead.
> 
> For reference, here's the compiler warning before this patch:
> 
>   drivers/gpu/drm/i915/intel_pm.c: In function ‘skl_update_wm’:
>   drivers/gpu/drm/i915/intel_pm.c:3618:1: warning: the frame size of 1296 bytes
>     is larger than 1024 bytes [-Wframe-larger-than=]
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h |  12 +-
>  drivers/gpu/drm/i915/intel_pm.c | 423 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 434 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index de278a5..9b0e398 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1709,8 +1709,18 @@ struct drm_i915_private {
>  		 */
>  		uint16_t skl_latency[8];
>  
> +		/*
> +		 * The skl_wm_values structure is a bit too big for stack
> +		 * allocation, so we keep the staging struct where we store
> +		 * intermediate results here instead.
> +		 */
> +		struct skl_wm_values skl_results;
> +
>  		/* current hardware state */
> -		struct ilk_wm_values hw;
> +		union {
> +			struct ilk_wm_values hw;
> +			struct skl_wm_values skl_hw;
> +		};
>  	} wm;
>  
>  	struct i915_runtime_pm pm;
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 2503ab9..4ee90b6 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2937,6 +2937,427 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
>  	return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
>  }
>  
> +static uint32_t skl_pipe_pixel_rate(struct drm_device *dev,
> +				    struct drm_crtc *crtc)
> +{
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	uint32_t pixel_rate;
> +
> +	pixel_rate = intel_crtc->config.adjusted_mode.crtc_clock;
> +
> +	return pixel_rate;
> +}

I changed the ilk version to take just the pipe config as a parameter.
This should be changed to do the same. I'm not entirely sure it makes
sense to have this function around until pipe scaling is implemented,
but I guess it serves as a decent reminder that something needs to be
done here.

> +
> +static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel,
> +			       uint32_t latency)
> +{
> +	uint32_t wm_intermediate_val, ret;
> +
> +	if (latency == 0)
> +		return UINT_MAX;
> +
> +	wm_intermediate_val = latency * pixel_rate * bytes_per_pixel;

I was a bit worried if we have enough bits here, but max latency should
be 0xff and bytes_per_pixel should always be <=8, so that should allow
pixel_rate up to ~2 GHz which seems sufficient since max 2xcdclk is
1350 MHz and the pixel rate should never exceed that. Not that we have
such checks anywhere at the moment, but we should eventually add them.

> +	ret = DIV_ROUND_UP(wm_intermediate_val, 1000);
> +
> +	return ret;
> +}
> +
> +static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
> +			       uint32_t horiz_pixels, uint8_t bytes_per_pixel,
> +			       uint32_t latency)
> +{
> +	uint32_t ret, plane_bytes_per_line, wm_intermediate_val;
> +
> +	if (latency == 0)
> +		return UINT_MAX;
> +
> +	plane_bytes_per_line = horiz_pixels * bytes_per_pixel;
> +	wm_intermediate_val = latency * pixel_rate;
> +	ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) *
> +				plane_bytes_per_line;
> +
> +	return ret;
> +}
> +
> +static void skl_compute_transition_wm(struct drm_crtc *crtc,
> +				  struct skl_pipe_wm_parameters *params,
> +				  struct skl_pipe_wm *pipe_wm)
> +{
> +	/*
> +	 * For now it is suggested to use the LP0 wm val of corresponding
> +	 * plane as transition wm val. This is done while computing results.
> +	 */
> +	if (!params->active)
> +		return;
> +}

Seems like a rather pointless function.

> +
> +static uint32_t
> +skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p)
> +{
> +	if (!intel_crtc_active(crtc))
> +		return 0;
> +
> +	return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate);
> +
> +}
> +
> +static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
> +				       const struct intel_crtc *intel_crtc)
> +{
> +	struct drm_device *dev = intel_crtc->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;

const

> +	enum pipe pipe = intel_crtc->pipe;
> +	size_t size;
> +
> +	size = ARRAY_SIZE(new_ddb->plane[pipe]) * sizeof(struct skl_ddb_entry);

sizeof(new_ddb->plane[pipe])

> +	if (memcmp(new_ddb->plane[pipe], cur_ddb->plane[pipe], size))
> +		return true;
> +
> +	if (memcmp(&new_ddb->cursor[pipe], &cur_ddb->cursor[pipe],
> +		    sizeof(struct skl_ddb_entry)))

sizeof(new_ddb->cursor[pipe])

> +		return true;
> +
> +	return false;
> +}
> +
> +static void skl_compute_wm_global_parameters(struct drm_device *dev,
> +					     struct intel_wm_config *config)
> +{
> +	struct drm_crtc *crtc;
> +	struct drm_plane *plane;
> +
> +	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
> +		config->num_pipes_active += intel_crtc_active(crtc);
> +
> +	/* FIXME: I don't think we need those two global parameters on SKL */
> +	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> +		struct intel_plane *intel_plane = to_intel_plane(plane);
> +
> +		config->sprites_enabled |= intel_plane->wm.enabled;
> +		config->sprites_scaled |= intel_plane->wm.scaled;
> +	}
> +}
> +
> +static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
> +					   struct skl_pipe_wm_parameters *p)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	enum pipe pipe = intel_crtc->pipe;
> +	struct drm_plane *plane;
> +	int i = 1; /* Index for sprite planes start */
> +
> +	p->active = intel_crtc_active(crtc);
> +	if (p->active) {
> +		p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal;
> +		p->pixel_rate = skl_pipe_pixel_rate(dev, crtc);
> +
> +		/*
> +		 * For now, assume primary and cursor planes are always enabled.
> +		 */
> +		p->plane[0].enabled = true;
> +		p->plane[0].bytes_per_pixel =
> +			crtc->primary->fb->bits_per_pixel / 8;
> +		p->plane[0].horiz_pixels = intel_crtc->config.pipe_src_w;
> +		p->plane[0].vert_pixels = intel_crtc->config.pipe_src_h;
> +
> +		p->cursor.enabled = true;
> +		p->cursor.bytes_per_pixel = 4;
> +		p->cursor.horiz_pixels = intel_crtc->cursor_width ?
> +					 intel_crtc->cursor_width : 64;
> +	}
> +
> +	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> +		struct intel_plane *intel_plane = to_intel_plane(plane);
> +
> +		if (intel_plane->pipe == pipe)
> +			p->plane[i++] = intel_plane->wm;
> +	}
> +}
> +
> +static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
> +				   struct intel_plane_wm_parameters *p_params,
> +				   uint16_t max_page_buff_alloc,
> +				   uint32_t mem_value,
> +				   uint16_t *res_blocks, /* out */
> +				   uint8_t *res_lines /* out */)
> +{
> +	uint32_t method1, method2, plane_bytes_per_line;
> +	uint32_t result_bytes;
> +
> +	if (!p->active || !p_params->enabled) {
> +		*res_blocks = PLANE_WM_BLOCKS_DEFAULT;
> +		*res_lines = PLANE_WM_LINES_DEFAULT;

Why do we need to set !=0 values for disabled planes?

> +		return false;
> +	}
> +
> +	method1 = skl_wm_method1(p->pixel_rate,
> +				 p_params->bytes_per_pixel,
> +				 mem_value);
> +	method2 = skl_wm_method2(p->pixel_rate,
> +				 p->pipe_htotal,
> +				 p_params->horiz_pixels,
> +				 p_params->bytes_per_pixel,
> +				 mem_value);
> +
> +	plane_bytes_per_line = p_params->horiz_pixels *
> +					p_params->bytes_per_pixel;
> +
> +	/* For now xtile and linear */
> +	if (((max_page_buff_alloc * 512) / plane_bytes_per_line) >= 1)
> +		result_bytes = min(method1, method2);
> +	else
> +		result_bytes = method1;
> +
> +	*res_blocks = DIV_ROUND_UP(result_bytes, 512) + 1;
> +	*res_lines = DIV_ROUND_UP(result_bytes, plane_bytes_per_line);
> +

Seems we're missing the final validity checks here.

> +	return true;
> +}
> +
> +static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
> +				 struct skl_ddb_allocation *ddb,
> +				 struct skl_pipe_wm_parameters *p,
> +				 enum pipe pipe,
> +				 int level,
> +				 int num_planes,
> +				 struct skl_wm_level *result)
> +{
> +	uint16_t latency = dev_priv->wm.skl_latency[level];
> +	uint16_t ddb_blocks;
> +	int i;
> +
> +	for (i = 0; i < num_planes; i++) {
> +		ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
> +
> +		result->plane_en[i] = skl_compute_plane_wm(p, &p->plane[i],
> +						ddb_blocks,
> +						latency,
> +						&result->plane_res_b[i],
> +						&result->plane_res_l[i]);
> +	}
> +
> +	ddb_blocks = skl_ddb_entry_size(&ddb->cursor[pipe]);
> +	result->cursor_en = skl_compute_plane_wm(p, &p->cursor, ddb_blocks,
> +						 latency, &result->cursor_res_b,
> +						 &result->cursor_res_l);
> +}
> +
> +static void skl_compute_pipe_wm(struct drm_crtc *crtc,
> +				struct skl_ddb_allocation *ddb,
> +				struct skl_pipe_wm_parameters *params,
> +				struct skl_pipe_wm *pipe_wm)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	const struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	int level, max_level = ilk_wm_max_level(dev);
> +
> +	for (level = 0; level <= max_level; level++) {
> +		skl_compute_wm_level(dev_priv, ddb, params, intel_crtc->pipe,
> +				     level, intel_num_planes(intel_crtc),
> +				     &pipe_wm->wm[level]);
> +	}
> +	pipe_wm->linetime = skl_compute_linetime_wm(crtc, params);
> +
> +	skl_compute_transition_wm(crtc, params, pipe_wm);
> +}
> +
> +static void skl_compute_wm_results(struct drm_device *dev,
> +				   struct skl_pipe_wm_parameters *p,
> +				   struct skl_pipe_wm *p_wm,
> +				   struct skl_wm_values *r,
> +				   struct intel_crtc *intel_crtc)
> +{
> +	int i, level, max_level = ilk_wm_max_level(dev);
> +	uint32_t temp;
> +	enum pipe pipe = intel_crtc->pipe;
> +	uint16_t ddb_blocks;

Could move a bunch of that to a narrower scope.

> +
> +	for (level = 0; level <= max_level; level++) {
> +		for (i = 0; i < intel_num_planes(intel_crtc); i++) {
> +			temp = 0;
> +			ddb_blocks = skl_ddb_entry_size(&r->ddb.plane[pipe][i]);
> +
> +			if ((p_wm->wm[level].plane_res_b[i] > ddb_blocks) ||
> +				(p_wm->wm[level].plane_res_l[i] > 31))
> +				p_wm->wm[level].plane_en[i] = false;

So the validity check is here that I was expecting in skl_compute_plane_wm().
The way this is done makes me think we might overflow the register
bitfields if invalid values are propagated this far.

The way the ilk code works is that it won't ever keep around intermediate
values that would exceed the register maximum values (such values are
already dropped in intel_compute_pipe_wm()), and then it will filter out
the otherwise invalid values in ilk_wm_merge() before ilk_compute_wm_results()
gets called. Would seem less surprising if we could follow a similar
pattern in the skl code.

> +
> +			temp |= p_wm->wm[level].plane_res_l[i] <<
> +					PLANE_WM_LINES_SHIFT;
> +			temp |= p_wm->wm[level].plane_res_b[i];
> +			if (p_wm->wm[level].plane_en[i])
> +				temp |= PLANE_WM_EN;
> +
> +			r->plane[pipe][i][level] = temp;
> +			/* Use the LP0 WM value for transition WM for now. */
> +			if (level == 0)
> +				r->plane_trans[pipe][i] = temp;

I'd stick this special case into the compute function rather than here.

> +		}
> +
> +		temp = 0;
> +		ddb_blocks = skl_ddb_entry_size(&r->ddb.cursor[pipe]);
> +
> +		if ((p_wm->wm[level].cursor_res_b > ddb_blocks) ||
> +			(p_wm->wm[level].cursor_res_l > 31))
> +			p_wm->wm[level].cursor_en = false;
> +
> +		temp |= p_wm->wm[level].cursor_res_l << PLANE_WM_LINES_SHIFT;
> +		temp |= p_wm->wm[level].cursor_res_b;
> +
> +		if (p_wm->wm[level].cursor_en)
> +			temp |= PLANE_WM_EN;
> +
> +		r->cursor[pipe][level] = temp;
> +		/* Use the LP0 WM value for transition WM for now. */
> +		if (level == 0)
> +			r->cursor_trans[pipe] = temp;
> +
> +	}
> +
> +	r->wm_linetime[pipe] = p_wm->linetime;
> +}
> +
> +static void skl_write_wm_values(struct drm_i915_private *dev_priv,
> +				struct skl_wm_values *new)

const

> +{
> +	struct drm_device *dev = dev_priv->dev;
> +	struct intel_crtc *crtc;
> +	int i, level, max_level = ilk_wm_max_level(dev);
> +	enum pipe pipe;

More stuff that could live in a narrower scope.

> +
> +	list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
> +		pipe = crtc->pipe;
> +		if (new->dirty[pipe]) {
> +			I915_WRITE(PIPE_WM_LINETIME(pipe),
> +					new->wm_linetime[pipe]);
> +
> +			for (level = 0; level <= max_level; level++) {
> +				for (i = 0; i < intel_num_planes(crtc); i++)
> +					I915_WRITE(PLANE_WM(pipe, i, level),
> +						new->plane[pipe][i][level]);
> +				I915_WRITE(CUR_WM(pipe, level),
> +					new->cursor[pipe][level]);
> +			}
> +			for (i = 0; i < intel_num_planes(crtc); i++)
> +				I915_WRITE(PLANE_WM_TRANS(pipe, i),
> +						new->plane_trans[pipe][i]);
> +			I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
> +		}
> +	}
> +
> +	dev_priv->wm.skl_hw = *new;
> +}
> +
> +static bool skl_update_pipe_wm(struct drm_crtc *crtc,
> +			       struct skl_pipe_wm_parameters *params,
> +			       struct intel_wm_config *config,
> +			       struct skl_ddb_allocation *ddb, /* out */
> +			       struct skl_pipe_wm *pipe_wm /* out */)
> +{
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +
> +	skl_compute_wm_pipe_parameters(crtc, params);
> +	skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
> +
> +	if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
> +		return false;
> +
> +	intel_crtc->wm.skl_active = *pipe_wm;
> +	return true;
> +}
> +
> +static void skl_update_other_pipe_wm(struct drm_device *dev,
> +				     struct drm_crtc *crtc,
> +				     struct intel_wm_config *config,
> +				     struct skl_wm_values *r)
> +{
> +	struct intel_crtc *intel_crtc;
> +	struct intel_crtc *this_crtc = to_intel_crtc(crtc);
> +	struct skl_pipe_wm_parameters params;
> +	struct skl_pipe_wm pipe_wm;

More stuff that can be moved to a narrower scope.

Should these be zero initializd? At least the way the ilk code works
is that most structures need zero initialization to avoid consulting
stack garbage somewhere down the line.

> +
> +	/*
> +	 * If the WM update hasn't changed the allocation for this_crtc (the
> +	 * crtc we are currently computing the new WM values for), other
> +	 * enabled crtcs will keep the same allocation and we don't need to
> +	 * recompute anything for them.
> +	 */
> +	if (!skl_ddb_allocation_changed(&r->ddb, this_crtc))
> +		return;
> +
> +	/*
> +	 * Otherwise, because of this_crtc being freshly enabled/disabled, the
> +	 * other active pipes need new DDB allocation and WM values.
> +	 */
> +	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
> +				base.head) {

Not sure how the locking is planned here. In the ilk wm patches that are
still pending I'm adding a wm.mutex which might fit the bill. Otherwise
we're going to need to make sure we have all the crtc locks held here.

Also if multiple pipes are active we surely can't just go changing the
DDB allocation without considering the fact that vblanks for all pipes
don't occur at the same time. So some kind of heavy handed
synchronization is needed to make sure none of the DDB allocations
overlap even for a short period of time.

> +		bool wm_changed;
> +
> +		if (this_crtc->pipe == intel_crtc->pipe)
> +			continue;
> +
> +		if (!intel_crtc->active)
> +			continue;
> +
> +		wm_changed = skl_update_pipe_wm(&intel_crtc->base,
> +						&params, config,
> +						&r->ddb, &pipe_wm);
> +
> +		/*
> +		 * If we end up re-computing the other pipe WM values, it's
> +		 * because it was really needed, so we expect the WM values to
> +		 * be different.
> +		 */
> +		WARN_ON(!wm_changed);
> +
> +		skl_compute_wm_results(dev, &params, &pipe_wm, r, intel_crtc);
> +		r->dirty[intel_crtc->pipe] = true;
> +	}
> +}
> +
> +static void skl_update_wm(struct drm_crtc *crtc)
> +{
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct drm_device *dev = crtc->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct skl_pipe_wm_parameters params = {};
> +	struct skl_wm_values *results = &dev_priv->wm.skl_results;
> +	struct skl_pipe_wm pipe_wm = {};
> +	struct intel_wm_config config = {};
> +
> +	memset(results, 0, sizeof(*results));
> +
> +	skl_compute_wm_global_parameters(dev, &config);
> +
> +	if (!skl_update_pipe_wm(crtc, &params, &config,
> +				&results->ddb, &pipe_wm))
> +		return;
> +
> +	skl_compute_wm_results(dev, &params, &pipe_wm, results, intel_crtc);
> +	results->dirty[intel_crtc->pipe] = true;
> +
> +	skl_update_other_pipe_wm(dev, crtc, &config, results);
> +	skl_write_wm_values(dev_priv, results);
> +}
> +
> +static void
> +skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc,
> +		     uint32_t sprite_width, uint32_t sprite_height,
> +		     int pixel_size, bool enabled, bool scaled)
> +{
> +	struct intel_plane *intel_plane = to_intel_plane(plane);
> +
> +	intel_plane->wm.enabled = enabled;
> +	intel_plane->wm.scaled = scaled;
> +	intel_plane->wm.horiz_pixels = sprite_width;
> +	intel_plane->wm.vert_pixels = sprite_height;
> +	intel_plane->wm.bytes_per_pixel = pixel_size;
> +
> +	skl_update_wm(crtc);
> +}
> +
>  static void ilk_update_wm(struct drm_crtc *crtc)
>  {
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> @@ -7464,6 +7885,8 @@ void intel_init_pm(struct drm_device *dev)
>  		skl_setup_wm_latency(dev);
>  
>  		dev_priv->display.init_clock_gating = gen9_init_clock_gating;
> +		dev_priv->display.update_wm = skl_update_wm;
> +		dev_priv->display.update_sprite_wm = skl_update_sprite_wm;
>  	} else if (HAS_PCH_SPLIT(dev)) {
>  		ilk_setup_wm_latency(dev);
>  
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* [PATCH 44/89 v4] drm/i915/skl: Register definitions and macros for SKL Watermark regs
  2014-09-10 18:04   ` Ville Syrjälä
  2014-09-16 14:11     ` Damien Lespiau
@ 2014-09-17 13:40     ` Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-17 13:40 UTC (permalink / raw)
  To: intel-gfx; +Cc: Pradeep Bhat

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch defines SKL specific PLANE_WM Watermark registers. It also
defines macros to get the addresses of different LP levels within a pipe.

v2: Reworked the register definitions and associated macros to make it more
    generic and be able to use for_each_pipe in values computation.
    Incorporated Damien's review comments and indentation.

v3: Added default values for lines and blocks. Provided mask for blocks.

v4: Prefix intermedidate (internal-only) macros with _ (Ville)

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index e5e45a6..c5663c6 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4078,6 +4078,43 @@ enum punit_power_well {
 #define I965_CURSOR_MAX_WM	32
 #define I965_CURSOR_DFT_WM	8
 
+/* Watermark register definitions for SKL */
+#define CUR_WM_A_0		0x70140
+#define CUR_WM_B_0		0x71140
+#define PLANE_WM_1_A_0		0x70240
+#define PLANE_WM_1_B_0		0x71240
+#define PLANE_WM_2_A_0		0x70340
+#define PLANE_WM_2_B_0		0x71340
+#define PLANE_WM_TRANS_1_A_0	0x70268
+#define PLANE_WM_TRANS_1_B_0	0x71268
+#define PLANE_WM_TRANS_2_A_0	0x70368
+#define PLANE_WM_TRANS_2_B_0	0x71368
+#define CUR_WM_TRANS_A_0	0x70168
+#define CUR_WM_TRANS_B_0	0x71168
+#define   PLANE_WM_EN		(1 << 31)
+#define   PLANE_WM_LINES_SHIFT	14
+#define   PLANE_WM_LINES_MASK	0x1f
+#define   PLANE_WM_BLOCKS_MASK	0x3ff
+#define   PLANE_WM_LINES_DEFAULT	0x1
+#define   PLANE_WM_BLOCKS_DEFAULT	0x7
+
+#define CUR_WM_0(pipe) _PIPE(pipe, CUR_WM_A_0, CUR_WM_B_0)
+#define CUR_WM(pipe, level) (CUR_WM_0(pipe) + ((4) * (level)))
+#define CUR_WM_TRANS(pipe) _PIPE(pipe, CUR_WM_TRANS_A_0, CUR_WM_TRANS_B_0)
+
+#define _PLANE_WM_1(pipe) _PIPE(pipe, PLANE_WM_1_A_0, PLANE_WM_1_B_0)
+#define _PLANE_WM_2(pipe) _PIPE(pipe, PLANE_WM_2_A_0, PLANE_WM_2_B_0)
+#define _PLANE_WM_BASE(pipe, plane)	\
+			_PLANE(plane, _PLANE_WM_1(pipe), _PLANE_WM_2(pipe))
+#define PLANE_WM(pipe, plane, level)	\
+			(_PLANE_WM_BASE(pipe, plane) + ((4) * (level)))
+#define _PLANE_WM_TRANS_1(pipe)	\
+			_PIPE(pipe, PLANE_WM_TRANS_1_A_0, PLANE_WM_TRANS_1_B_0)
+#define _PLANE_WM_TRANS_2(pipe)	\
+			_PIPE(pipe, PLANE_WM_TRANS_2_A_0, PLANE_WM_TRANS_2_B_0)
+#define PLANE_WM_TRANS(pipe, plane)	\
+		_PLANE(plane, _PLANE_WM_TRANS_1(pipe), _PLANE_WM_TRANS_2(pipe))
+
 /* define the Watermark register on Ironlake */
 #define WM0_PIPEA_ILK		0x45100
 #define  WM0_PIPE_PLANE_MASK	(0xffff<<16)
-- 
1.8.3.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* Re: [PATCH 30/89] drm/i915/skl: SKL backlight enabling
  2014-09-17  9:09     ` Jani Nikula
@ 2014-09-17 13:46       ` Rodrigo Vivi
  2014-09-17 14:56         ` Rodrigo Vivi
  0 siblings, 1 reply; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17 13:46 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 2615 bytes --]

besides the override bit,
c8254h for bdw has the pwm frequency on 31:16 and on skl the frequency on
same register address is from 31:0 and also a pwm 2 register on c8354h.
So I think this patch can be right if there is an if IS_SKL without the >>
16 part inside bdw_enable_backlight.


On Wed, Sep 17, 2014 at 5:09 AM, Jani Nikula <jani.nikula@linux.intel.com>
wrote:

> On Wed, 17 Sep 2014, Rodrigo Vivi <rodrigo.vivi@gmail.com> wrote:
> > This is wrong.
> >
> > A skl_enable_backlight must be created setting c8254 propperly without
> the
> > shift 16. Also maybe setting c8354h.
>
> Nope, this is all right for skl/spt, with the small exception that it'll
> need the equivalent of [1]. I'll post another version addressing Ville's
> comments.
>
> BR,
> Jani.
>
>
> [1] http://mid.gmane.org/87y4tzefmz.fsf@intel.com
>
>
> >
> >
> > On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com
> >
> > wrote:
> >
> >> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> >>
> >> Extending the BDW backlight implementation to SKL.
> >>
> >> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> >> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_panel.c | 2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/intel_panel.c
> >> b/drivers/gpu/drm/i915/intel_panel.c
> >> index 1878447..d69a3cb6 100644
> >> --- a/drivers/gpu/drm/i915/intel_panel.c
> >> +++ b/drivers/gpu/drm/i915/intel_panel.c
> >> @@ -1317,7 +1317,7 @@ void intel_panel_init_backlight_funcs(struct
> >> drm_device *dev)
> >>  {
> >>         struct drm_i915_private *dev_priv = dev->dev_private;
> >>
> >> -       if (IS_BROADWELL(dev)) {
> >> +       if (IS_BROADWELL(dev) || (INTEL_INFO(dev)->gen >= 9)) {
> >>                 dev_priv->display.setup_backlight = bdw_setup_backlight;
> >>                 dev_priv->display.enable_backlight =
> bdw_enable_backlight;
> >>                 dev_priv->display.disable_backlight =
> >> pch_disable_backlight;
> >> --
> >> 1.8.3.1
> >>
> >> _______________________________________________
> >> Intel-gfx mailing list
> >> Intel-gfx@lists.freedesktop.org
> >> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> >>
> >
> >
> >
> > --
> > Rodrigo Vivi
> > Blog: http://blog.vivi.eng.br
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> --
> Jani Nikula, Intel Open Source Technology Center
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 4347 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 45/89] drm/i915/skl: Definition of SKL WM param structs for pipe/plane
  2014-09-10 18:39   ` Ville Syrjälä
@ 2014-09-17 13:59     ` Damien Lespiau
  2014-09-17 15:59       ` Daniel Vetter
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-17 13:59 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Wed, Sep 10, 2014 at 09:39:53PM +0300, Ville Syrjälä wrote:
> > +struct skl_wm_values {
> > +	bool dirty[I915_MAX_PIPES];
> > +	uint32_t wm_linetime[I915_MAX_PIPES];
> > +	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
> > +	uint32_t cursor[I915_MAX_PIPES][8];
> > +	uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
> > +	uint32_t cursor_trans[I915_MAX_PIPES];
> > +};
> 
> These multi dimensional arrays hurt my eyes. Maybe we should restructure
> this a bit to eg:
> 
> struct skl_wm_values {
> 	struct {
> 		wm_linetime;
> 		plane[MAX_PLANES][8];
> 		...
> 	} pipe[MAX_PIPES];
> };
> 
> The two dimensional plane[][] array is still a bit nasty, but maybe we
> can live with it.
> 
> We could also do the same operatiob for the ilk version to keep stuff
> similar.
> 
> > +
> > +struct skl_wm_level {
> > +	bool plane_en[I915_MAX_PLANES];
> > +	uint16_t plane_res_b[I915_MAX_PLANES];
> > +	uint8_t plane_res_l[I915_MAX_PLANES];
> 
> This stuff could also look better as an array of struct of some sort.
> Also should probably put the bool and uint8_t next to each other in case
> gcc is smart enough to pack things more tightly.
> 
> > +	bool cursor_en;
> > +	uint16_t cursor_res_b;
> > +	uint8_t cursor_res_l;
> 
> And this could also be an instance of the same struct use for the proper
> planes.
> 
> > +struct skl_pipe_wm_parameters {
> > +	bool active;
> > +	uint32_t pipe_htotal;
> > +	uint32_t pixel_rate; /* in KHz */
> > +	struct intel_plane_wm_parameters plane[I915_MAX_PLANES];
> > +	struct intel_plane_wm_parameters cursor;
> > +};
> 
> I suppose we just need to start using some kind of named indexes for the
> planes on all platforms so we can unify all this stuff. But that can be
> done when we have all the code merged so we can better see how to unify
> things.

For all those comments, the issue here is that changing something in
those definitions has consequences in 10/15 patches that will need to be
changed. Rather painful. It'd be much easier to do those change once we
have that code upstream, on top. As far as I can see there are minor-ish
improvements over what's here.

I've added an item in my post-merge plan. Sounds like an acceptable
plan?

Thanks,

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 30/89] drm/i915/skl: SKL backlight enabling
  2014-09-17 13:46       ` Rodrigo Vivi
@ 2014-09-17 14:56         ` Rodrigo Vivi
  0 siblings, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17 14:56 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 3003 bytes --]

Oh Jani showed me that I was looking to the wrong spec.

So just ignore my previous comments and use:
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Wed, Sep 17, 2014 at 6:46 AM, Rodrigo Vivi <rodrigo.vivi@gmail.com>
wrote:

> besides the override bit,
> c8254h for bdw has the pwm frequency on 31:16 and on skl the frequency on
> same register address is from 31:0 and also a pwm 2 register on c8354h.
> So I think this patch can be right if there is an if IS_SKL without the >>
> 16 part inside bdw_enable_backlight.
>
>
> On Wed, Sep 17, 2014 at 5:09 AM, Jani Nikula <jani.nikula@linux.intel.com>
> wrote:
>
>> On Wed, 17 Sep 2014, Rodrigo Vivi <rodrigo.vivi@gmail.com> wrote:
>> > This is wrong.
>> >
>> > A skl_enable_backlight must be created setting c8254 propperly without
>> the
>> > shift 16. Also maybe setting c8354h.
>>
>> Nope, this is all right for skl/spt, with the small exception that it'll
>> need the equivalent of [1]. I'll post another version addressing Ville's
>> comments.
>>
>> BR,
>> Jani.
>>
>>
>> [1] http://mid.gmane.org/87y4tzefmz.fsf@intel.com
>>
>>
>> >
>> >
>> > On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <
>> damien.lespiau@intel.com>
>> > wrote:
>> >
>> >> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>> >>
>> >> Extending the BDW backlight implementation to SKL.
>> >>
>> >> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>> >> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
>> >> ---
>> >>  drivers/gpu/drm/i915/intel_panel.c | 2 +-
>> >>  1 file changed, 1 insertion(+), 1 deletion(-)
>> >>
>> >> diff --git a/drivers/gpu/drm/i915/intel_panel.c
>> >> b/drivers/gpu/drm/i915/intel_panel.c
>> >> index 1878447..d69a3cb6 100644
>> >> --- a/drivers/gpu/drm/i915/intel_panel.c
>> >> +++ b/drivers/gpu/drm/i915/intel_panel.c
>> >> @@ -1317,7 +1317,7 @@ void intel_panel_init_backlight_funcs(struct
>> >> drm_device *dev)
>> >>  {
>> >>         struct drm_i915_private *dev_priv = dev->dev_private;
>> >>
>> >> -       if (IS_BROADWELL(dev)) {
>> >> +       if (IS_BROADWELL(dev) || (INTEL_INFO(dev)->gen >= 9)) {
>> >>                 dev_priv->display.setup_backlight =
>> bdw_setup_backlight;
>> >>                 dev_priv->display.enable_backlight =
>> bdw_enable_backlight;
>> >>                 dev_priv->display.disable_backlight =
>> >> pch_disable_backlight;
>> >> --
>> >> 1.8.3.1
>> >>
>> >> _______________________________________________
>> >> Intel-gfx mailing list
>> >> Intel-gfx@lists.freedesktop.org
>> >> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>> >>
>> >
>> >
>> >
>> > --
>> > Rodrigo Vivi
>> > Blog: http://blog.vivi.eng.br
>> > _______________________________________________
>> > Intel-gfx mailing list
>> > Intel-gfx@lists.freedesktop.org
>> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>
>> --
>> Jani Nikula, Intel Open Source Technology Center
>>
>
>
>
> --
> Rodrigo Vivi
> Blog: http://blog.vivi.eng.br
>
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 5271 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 45/89] drm/i915/skl: Definition of SKL WM param structs for pipe/plane
  2014-09-17 13:59     ` Damien Lespiau
@ 2014-09-17 15:59       ` Daniel Vetter
  2014-09-22 14:00         ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Daniel Vetter @ 2014-09-17 15:59 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Wed, Sep 17, 2014 at 02:59:00PM +0100, Damien Lespiau wrote:
> On Wed, Sep 10, 2014 at 09:39:53PM +0300, Ville Syrjälä wrote:
> > > +struct skl_wm_values {
> > > +	bool dirty[I915_MAX_PIPES];
> > > +	uint32_t wm_linetime[I915_MAX_PIPES];
> > > +	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
> > > +	uint32_t cursor[I915_MAX_PIPES][8];
> > > +	uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
> > > +	uint32_t cursor_trans[I915_MAX_PIPES];
> > > +};
> > 
> > These multi dimensional arrays hurt my eyes. Maybe we should restructure
> > this a bit to eg:
> > 
> > struct skl_wm_values {
> > 	struct {
> > 		wm_linetime;
> > 		plane[MAX_PLANES][8];
> > 		...
> > 	} pipe[MAX_PIPES];
> > };
> > 
> > The two dimensional plane[][] array is still a bit nasty, but maybe we
> > can live with it.
> > 
> > We could also do the same operatiob for the ilk version to keep stuff
> > similar.
> > 
> > > +
> > > +struct skl_wm_level {
> > > +	bool plane_en[I915_MAX_PLANES];
> > > +	uint16_t plane_res_b[I915_MAX_PLANES];
> > > +	uint8_t plane_res_l[I915_MAX_PLANES];
> > 
> > This stuff could also look better as an array of struct of some sort.
> > Also should probably put the bool and uint8_t next to each other in case
> > gcc is smart enough to pack things more tightly.
> > 
> > > +	bool cursor_en;
> > > +	uint16_t cursor_res_b;
> > > +	uint8_t cursor_res_l;
> > 
> > And this could also be an instance of the same struct use for the proper
> > planes.
> > 
> > > +struct skl_pipe_wm_parameters {
> > > +	bool active;
> > > +	uint32_t pipe_htotal;
> > > +	uint32_t pixel_rate; /* in KHz */
> > > +	struct intel_plane_wm_parameters plane[I915_MAX_PLANES];
> > > +	struct intel_plane_wm_parameters cursor;
> > > +};
> > 
> > I suppose we just need to start using some kind of named indexes for the
> > planes on all platforms so we can unify all this stuff. But that can be
> > done when we have all the code merged so we can better see how to unify
> > things.
> 
> For all those comments, the issue here is that changing something in
> those definitions has consequences in 10/15 patches that will need to be
> changed. Rather painful. It'd be much easier to do those change once we
> have that code upstream, on top. As far as I can see there are minor-ish
> improvements over what's here.
> 
> I've added an item in my post-merge plan. Sounds like an acceptable
> plan?

Sounds good to me, atm all the plane config tracking is seriously all
in-flight anyway ...
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 32/89] drm/i915/skl: Adjust the display engine interrupts
  2014-09-04 13:19   ` Daniel Vetter
@ 2014-09-17 18:41     ` Rodrigo Vivi
  2014-09-22 13:38       ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17 18:41 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 6534 bytes --]

Oh cool here are the actual fixes on de_pipe int bits!

I agree with Daniel that a separated function would be better, but what is
here is right anyway so
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Thu, Sep 4, 2014 at 6:19 AM, Daniel Vetter <daniel@ffwll.ch> wrote:

> On Thu, Sep 04, 2014 at 12:26:58PM +0100, Damien Lespiau wrote:
> > To accomodate the extra planes, the bit definitions were shuffled around
> > a bit.
> >
> > v2: Rebase on top of the for_each_pipe() change adding dev_priv as first
> >     argument.
> >
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_irq.c | 37
> ++++++++++++++++++++++++++++---------
> >  drivers/gpu/drm/i915/i915_reg.h | 13 +++++++++++++
> >  2 files changed, 41 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_irq.c
> b/drivers/gpu/drm/i915/i915_irq.c
> > index c62a2e4..734b73e 100644
> > --- a/drivers/gpu/drm/i915/i915_irq.c
> > +++ b/drivers/gpu/drm/i915/i915_irq.c
> > @@ -2584,7 +2584,7 @@ static irqreturn_t gen8_irq_handler(int irq, void
> *arg)
> >       }
> >
> >       for_each_pipe(dev_priv, pipe) {
> > -             uint32_t pipe_iir;
> > +             uint32_t pipe_iir, flip_done = 0, fault_errors = 0;
> >
> >               if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe)))
> >                       continue;
> > @@ -2593,10 +2593,16 @@ static irqreturn_t gen8_irq_handler(int irq,
> void *arg)
> >               if (pipe_iir) {
> >                       ret = IRQ_HANDLED;
> >                       I915_WRITE(GEN8_DE_PIPE_IIR(pipe), pipe_iir);
> > +
> >                       if (pipe_iir & GEN8_PIPE_VBLANK)
> >                               intel_pipe_handle_vblank(dev, pipe);
> >
> > -                     if (pipe_iir & GEN8_PIPE_PRIMARY_FLIP_DONE) {
> > +                     if (IS_GEN9(dev))
> > +                             flip_done = pipe_iir &
> GEN9_PIPE_PLANE1_FLIP_DONE;
> > +                     else
> > +                             flip_done = pipe_iir &
> GEN8_PIPE_PRIMARY_FLIP_DONE;
> > +
> > +                     if (flip_done) {
> >                               intel_prepare_page_flip(dev, pipe);
> >                               intel_finish_page_flip_plane(dev, pipe);
> >                       }
> > @@ -2611,11 +2617,16 @@ static irqreturn_t gen8_irq_handler(int irq,
> void *arg)
> >                                                 pipe_name(pipe));
> >                       }
> >
> > -                     if (pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS) {
> > +
> > +                     if (IS_GEN9(dev))
> > +                             fault_errors = pipe_iir &
> GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
> > +                     else
> > +                             fault_errors = pipe_iir &
> GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
> > +
> > +                     if (fault_errors)
> >                               DRM_ERROR("Fault errors on pipe %c\n:
> 0x%08x",
> >                                         pipe_name(pipe),
> >                                         pipe_iir &
> GEN8_DE_PIPE_IRQ_FAULT_ERRORS);
> > -                     }
> >               } else
> >                       DRM_ERROR("The master control interrupt lied (DE
> PIPE)!\n");
>
> gen8+ irq handling functions would _really_ benefit from a bit of function
> extraction to prevent them from falling off the right edge of my screen
> all the time ...
>
> Just in case you have no idea what to do on a rainy day ;-)
> -Daniel
>
> >       }
> > @@ -3845,12 +3856,20 @@ static void gen8_gt_irq_postinstall(struct
> drm_i915_private *dev_priv)
> >
> >  static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
> >  {
> > -     uint32_t de_pipe_masked = GEN8_PIPE_PRIMARY_FLIP_DONE |
> > -             GEN8_PIPE_CDCLK_CRC_DONE |
> > -             GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
> > -     uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
> > -             GEN8_PIPE_FIFO_UNDERRUN;
> > +     uint32_t de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE;
> > +     uint32_t de_pipe_enables;
> >       int pipe;
> > +
> > +     if (IS_GEN9(dev_priv))
> > +             de_pipe_masked |= GEN9_PIPE_PLANE1_FLIP_DONE |
> > +                               GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
> > +     else
> > +             de_pipe_masked |= GEN8_PIPE_PRIMARY_FLIP_DONE |
> > +                               GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
> > +
> > +     de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
> > +                                        GEN8_PIPE_FIFO_UNDERRUN;
> > +
> >       dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked;
> >       dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked;
> >       dev_priv->de_irq_mask[PIPE_C] = ~de_pipe_masked;
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h
> > index acd0a7b..5928a75 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -4840,10 +4840,23 @@ enum punit_power_well {
> >  #define  GEN8_PIPE_SCAN_LINE_EVENT   (1 << 2)
> >  #define  GEN8_PIPE_VSYNC             (1 << 1)
> >  #define  GEN8_PIPE_VBLANK            (1 << 0)
> > +#define  GEN9_PIPE_CURSOR_FAULT              (1 << 11)
> > +#define  GEN9_PIPE_PLANE3_FAULT              (1 << 9)
> > +#define  GEN9_PIPE_PLANE2_FAULT              (1 << 8)
> > +#define  GEN9_PIPE_PLANE1_FAULT              (1 << 7)
> > +#define  GEN9_PIPE_PLANE3_FLIP_DONE  (1 << 5)
> > +#define  GEN9_PIPE_PLANE2_FLIP_DONE  (1 << 4)
> > +#define  GEN9_PIPE_PLANE1_FLIP_DONE  (1 << 3)
> > +#define  GEN9_PIPE_PLANE_FLIP_DONE(p)        (1 << (3 + p))
> >  #define GEN8_DE_PIPE_IRQ_FAULT_ERRORS \
> >       (GEN8_PIPE_CURSOR_FAULT | \
> >        GEN8_PIPE_SPRITE_FAULT | \
> >        GEN8_PIPE_PRIMARY_FAULT)
> > +#define GEN9_DE_PIPE_IRQ_FAULT_ERRORS \
> > +     (GEN9_PIPE_CURSOR_FAULT | \
> > +      GEN9_PIPE_PLANE3_FAULT | \
> > +      GEN9_PIPE_PLANE2_FAULT | \
> > +      GEN9_PIPE_PLANE1_FAULT)
> >
> >  #define GEN8_DE_PORT_ISR 0x44440
> >  #define GEN8_DE_PORT_IMR 0x44444
> > --
> > 1.8.3.1
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 9233 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 34/89] drm/i915/skl: Implement WaDisableSDEUnitClockGating:skl
  2014-09-04 11:27 ` [PATCH 34/89] drm/i915/skl: Implement WaDisableSDEUnitClockGating:skl Damien Lespiau
@ 2014-09-17 18:48   ` Rodrigo Vivi
  0 siblings, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17 18:48 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1256 bytes --]

Yeah, this might be only until B0 but useful for now anyway so feel free to
use
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Thu, Sep 4, 2014 at 4:27 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index 0265116..0dc148c 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -68,6 +68,14 @@
>
>  static void gen9_init_clock_gating(struct drm_device *dev)
>  {
> +       struct drm_i915_private *dev_priv = dev->dev_private;
> +
> +       /*
> +        * WaDisableSDEUnitClockGating:skl
> +        * This seems to be a pre-production w/a.
> +        */
> +       I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
> +                  GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
>  }
>
>  static void i8xx_disable_fbc(struct drm_device *dev)
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 2118 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 35/89] drm/i915/skl: Implement Wa4x4STCOptimizationDisable:skl
  2014-09-04 11:27 ` [PATCH 35/89] drm/i915/skl: Implement Wa4x4STCOptimizationDisable:skl Damien Lespiau
@ 2014-09-17 19:00   ` Rodrigo Vivi
  2014-09-17 19:00     ` Rodrigo Vivi
  0 siblings, 1 reply; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17 19:00 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1150 bytes --]

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Thu, Sep 4, 2014 at 4:27 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index 0dc148c..c38baea 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -76,6 +76,10 @@ static void gen9_init_clock_gating(struct drm_device
> *dev)
>          */
>         I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
>                    GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
> +
> +       /* Wa4x4STCOptimizationDisable:skl */
> +       I915_WRITE(CACHE_MODE_1,
> +                  _MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE));
>  }
>
>  static void i8xx_disable_fbc(struct drm_device *dev)
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 1985 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 35/89] drm/i915/skl: Implement Wa4x4STCOptimizationDisable:skl
  2014-09-17 19:00   ` Rodrigo Vivi
@ 2014-09-17 19:00     ` Rodrigo Vivi
  2014-09-22 13:49       ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17 19:00 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1431 bytes --]

Although I believe that we could have a init_workaround function for skl as
we have for bdw and chv

On Wed, Sep 17, 2014 at 12:00 PM, Rodrigo Vivi <rodrigo.vivi@gmail.com>
wrote:

> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
>
> On Thu, Sep 4, 2014 at 4:27 AM, Damien Lespiau <damien.lespiau@intel.com>
> wrote:
>
>> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_pm.c | 4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_pm.c
>> b/drivers/gpu/drm/i915/intel_pm.c
>> index 0dc148c..c38baea 100644
>> --- a/drivers/gpu/drm/i915/intel_pm.c
>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>> @@ -76,6 +76,10 @@ static void gen9_init_clock_gating(struct drm_device
>> *dev)
>>          */
>>         I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
>>                    GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
>> +
>> +       /* Wa4x4STCOptimizationDisable:skl */
>> +       I915_WRITE(CACHE_MODE_1,
>> +                  _MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE));
>>  }
>>
>>  static void i8xx_disable_fbc(struct drm_device *dev)
>> --
>> 1.8.3.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>
>
>
>
> --
> Rodrigo Vivi
> Blog: http://blog.vivi.eng.br
>
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 2756 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 36/89] drm/i915/skl: Implement WaDisableDgMirrorFixInHalfSliceChicken5:skl
  2014-09-04 11:27 ` [PATCH 36/89] drm/i915/skl: Implement WaDisableDgMirrorFixInHalfSliceChicken5:skl Damien Lespiau
@ 2014-09-17 21:22   ` Rodrigo Vivi
  0 siblings, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17 21:22 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 2040 bytes --]

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Thu, Sep 4, 2014 at 4:27 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h | 3 +++
>  drivers/gpu/drm/i915/intel_pm.c | 8 ++++++++
>  2 files changed, 11 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h
> index 5928a75..c293dab 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -5862,6 +5862,9 @@ enum punit_power_well {
>  #define   GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE  (1<<10)
>  #define   GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE (1<<3)
>
> +#define GEN9_HALF_SLICE_CHICKEN5       0xe188
> +#define   GEN9_DG_MIRROR_FIX_ENABLE    (1<<5)
> +
>  #define GEN8_ROW_CHICKEN               0xe4f0
>  #define   PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE        (1<<8)
>  #define   STALL_DOP_GATING_DISABLE             (1<<5)
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index c38baea..faff54e 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -77,6 +77,14 @@ static void gen9_init_clock_gating(struct drm_device
> *dev)
>         I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
>                    GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
>
> +       /*
> +        * WaDisableDgMirrorFixInHalfSliceChicken5:skl
> +        * This is a pre-production w/a.
> +        */
> +       I915_WRITE(GEN9_HALF_SLICE_CHICKEN5,
> +                  I915_READ(GEN9_HALF_SLICE_CHICKEN5) &
> +                  ~GEN9_DG_MIRROR_FIX_ENABLE);
> +
>         /* Wa4x4STCOptimizationDisable:skl */
>         I915_WRITE(CACHE_MODE_1,
>                    _MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE));
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 3039 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 37/89] drm/i915/skl: Skylake has 2 "sprite" planes per pipe
  2014-09-04 11:27 ` [PATCH 37/89] drm/i915/skl: Skylake has 2 "sprite" planes per pipe Damien Lespiau
@ 2014-09-17 21:25   ` Rodrigo Vivi
  0 siblings, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17 21:25 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1270 bytes --]

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Thu, Sep 4, 2014 at 4:27 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> On Skylake, we use plane1 as primary plane and plane2/3 as sprite
> planes.
>
> v2: Rebase on top of the for_each_pipe() change adding dev_priv as first
>     argument.
>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_dma.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_dma.c
> b/drivers/gpu/drm/i915/i915_dma.c
> index a58fed9..4573953 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -1528,7 +1528,7 @@ static void intel_device_info_runtime_init(struct
> drm_device *dev)
>
>         info = (struct intel_device_info *)&dev_priv->info;
>
> -       if (IS_VALLEYVIEW(dev))
> +       if (IS_VALLEYVIEW(dev) || INTEL_INFO(dev)->gen == 9)
>                 for_each_pipe(dev_priv, pipe)
>                         info->num_sprites[pipe] = 2;
>         else
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 2133 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 38/89] drm/i915/skl: Implement drm_plane vfuncs
  2014-09-04 11:27 ` [PATCH 38/89] drm/i915/skl: Implement drm_plane vfuncs Damien Lespiau
  2014-09-04 13:21   ` Daniel Vetter
@ 2014-09-17 22:08   ` Rodrigo Vivi
  1 sibling, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17 22:08 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 13370 bytes --]

On Thu, Sep 4, 2014 at 4:27 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> SKL Uses the same hardware for all planes now, so called "universal"
> planes. Ie both the primary planes and sprite planes share the same
> logic. This patch implements the drm_plane vfuncs for "sprites" ie
> planes that aren't the primary plane.
>
> v2: Couple of fixes:
>   - Actually enabled the planes and fix the plane number
>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h     |  31 +++++-
>  drivers/gpu/drm/i915/intel_sprite.c | 206
> +++++++++++++++++++++++++++++++++++-
>  2 files changed, 235 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h
> index c293dab..0159f2d 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4513,7 +4513,9 @@ enum punit_power_well {
>  #define   PLANE_CTL_FORMAT_INDEXED             ( 12 << 24)
>  #define   PLANE_CTL_FORMAT_RGB_565             ( 14 << 24)
>  #define   PLANE_CTL_PIPE_CSC_ENABLE            (1 << 23)
> -#define   PLANE_CTL_KEY_ENABLE                 (1 << 22)
> +#define   PLANE_CTL_KEY_ENABLE_MASK            (0x3 << 21)
> +#define   PLANE_CTL_KEY_ENABLE_SOURCE          (  1 << 21)
> +#define   PLANE_CTL_KEY_ENABLE_DESTINATION     (  2 << 21)
>

Oh ignore my comments on patch 12/89 regarding these bits! ;)


>  #define   PLANE_CTL_ORDER_BGRX                 (0 << 20)
>  #define   PLANE_CTL_ORDER_RGBX                 (1 << 20)
>  #define   PLANE_CTL_YUV422_ORDER_MASK          (0x3 << 16)
> @@ -4548,6 +4550,12 @@ enum punit_power_well {
>  #define _PLANE_OFFSET_1_A                      0x701a4
>  #define _PLANE_OFFSET_2_A                      0x702a4
>  #define _PLANE_OFFSET_3_A                      0x703a4
> +#define _PLANE_KEYVAL_1_A                      0x70194
> +#define _PLANE_KEYVAL_2_A                      0x70294
> +#define _PLANE_KEYMSK_1_A                      0x70198
> +#define _PLANE_KEYMSK_2_A                      0x70298
> +#define _PLANE_KEYMAX_1_A                      0x701a0
> +#define _PLANE_KEYMAX_2_A                      0x702a0
>
>  #define _PLANE_CTL_1_B                         0x71180
>  #define _PLANE_CTL_2_B                         0x71280
> @@ -4604,6 +4612,27 @@ enum punit_power_well {
>  #define PLANE_OFFSET(pipe, plane)      \
>         _PLANE(plane, _PLANE_OFFSET_1(pipe), _PLANE_OFFSET_2(pipe))
>
> +#define _PLANE_KEYVAL_1_B                      0x71194
> +#define _PLANE_KEYVAL_2_B                      0x71294
> +#define _PLANE_KEYVAL_1(pipe) _PIPE(pipe, _PLANE_KEYVAL_1_A,
> _PLANE_KEYVAL_1_B)
> +#define _PLANE_KEYVAL_2(pipe) _PIPE(pipe, _PLANE_KEYVAL_2_A,
> _PLANE_KEYVAL_2_B)
> +#define PLANE_KEYVAL(pipe, plane)      \
> +       _PLANE(plane, _PLANE_KEYVAL_1(pipe), _PLANE_KEYVAL_2(pipe))
> +
> +#define _PLANE_KEYMSK_1_B                      0x71198
> +#define _PLANE_KEYMSK_2_B                      0x71298
> +#define _PLANE_KEYMSK_1(pipe) _PIPE(pipe, _PLANE_KEYMSK_1_A,
> _PLANE_KEYMSK_1_B)
> +#define _PLANE_KEYMSK_2(pipe) _PIPE(pipe, _PLANE_KEYMSK_2_A,
> _PLANE_KEYMSK_2_B)
> +#define PLANE_KEYMSK(pipe, plane)      \
> +       _PLANE(plane, _PLANE_KEYMSK_1(pipe), _PLANE_KEYMSK_2(pipe))
> +
> +#define _PLANE_KEYMAX_1_B                      0x711a0
> +#define _PLANE_KEYMAX_2_B                      0x712a0
> +#define _PLANE_KEYMAX_1(pipe) _PIPE(pipe, _PLANE_KEYMAX_1_A,
> _PLANE_KEYMAX_1_B)
> +#define _PLANE_KEYMAX_2(pipe) _PIPE(pipe, _PLANE_KEYMAX_2_A,
> _PLANE_KEYMAX_2_B)
> +#define PLANE_KEYMAX(pipe, plane)      \
> +       _PLANE(plane, _PLANE_KEYMAX_1(pipe), _PLANE_KEYMAX_2(pipe))
> +
>  /* VBIOS regs */
>  #define VGACNTRL               0x71400
>  # define VGA_DISP_DISABLE                      (1 << 31)
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c
> b/drivers/gpu/drm/i915/intel_sprite.c
> index 07a74ef..57e7190 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -139,6 +139,184 @@ static void intel_update_primary_plane(struct
> intel_crtc *crtc)
>  }
>
>  static void
> +skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
> +                struct drm_framebuffer *fb,
> +                struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
> +                unsigned int crtc_w, unsigned int crtc_h,
> +                uint32_t x, uint32_t y,
> +                uint32_t src_w, uint32_t src_h)
> +{
> +       struct drm_device *dev = drm_plane->dev;
> +       struct drm_i915_private *dev_priv = dev->dev_private;
> +       struct intel_plane *intel_plane = to_intel_plane(drm_plane);
> +       const int pipe = intel_plane->pipe;
> +       const int plane = intel_plane->plane + 1;


A comment above to remind skl doesn't have the primary would be good.


> +       u32 plane_ctl, stride;
> +       int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
> +
> +       plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
> +
> +       /* Mask out pixel format bits in case we change it */
> +       plane_ctl &= ~PLANE_CTL_FORMAT_MASK;
> +       plane_ctl &= ~PLANE_CTL_ORDER_RGBX;
> +       plane_ctl &= ~PLANE_CTL_YUV422_ORDER_MASK;
> +       plane_ctl &= ~PLANE_CTL_TILED_MASK;
> +       plane_ctl &= ~PLANE_CTL_ALPHA_MASK;
> +
> +       /* Trickle feed has to be enabled */
> +       plane_ctl &= ~PLANE_CTL_TRICKLE_FEED_DISABLE;
> +
> +       switch (fb->pixel_format) {
> +       case DRM_FORMAT_RGB565:
> +               plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
> +               break;
> +       case DRM_FORMAT_XBGR8888:
> +               plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
> PLANE_CTL_ORDER_RGBX;
> +               break;
> +       case DRM_FORMAT_XRGB8888:
> +               plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
> +               break;
> +       /*
> +        * XXX: For ARBG/ABGR formats we default to expecting scanout
> buffers
> +        * to be already pre-multiplied. We need to add a knob (or a
> different
> +        * DRM_FORMAT) for user-space to configure that.
> +        */
> +       case DRM_FORMAT_ABGR8888:
> +               plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
> +                            PLANE_CTL_ORDER_RGBX |
> +                            PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +               break;
> +       case DRM_FORMAT_ARGB8888:
> +               plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
> +                            PLANE_CTL_ALPHA_SW_PREMULTIPLY;
> +               break;
> +       case DRM_FORMAT_YUYV:
> +               plane_ctl |= PLANE_CTL_FORMAT_YUV422 |
> PLANE_CTL_YUV422_YUYV;
> +               break;
> +       case DRM_FORMAT_YVYU:
> +               plane_ctl |= PLANE_CTL_FORMAT_YUV422 |
> PLANE_CTL_YUV422_YVYU;
> +               break;
> +       case DRM_FORMAT_UYVY:
> +               plane_ctl |= PLANE_CTL_FORMAT_YUV422 |
> PLANE_CTL_YUV422_UYVY;
> +               break;
> +       case DRM_FORMAT_VYUY:
> +               plane_ctl |= PLANE_CTL_FORMAT_YUV422 |
> PLANE_CTL_YUV422_VYUY;
> +               break;
> +       default:
> +               BUG();
> +       }
> +
> +       switch (obj->tiling_mode) {
> +       case I915_TILING_NONE:
> +               stride = fb->pitches[0] >> 6;
> +               break;
> +       case I915_TILING_X:
> +               plane_ctl |= PLANE_CTL_TILED_X;
> +               stride = fb->pitches[0] >> 9;
> +               break;
> +       default:
> +               BUG();
> +       }
> +
> +       plane_ctl |= PLANE_CTL_ENABLE;
> +       plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE;
> +
> +       intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h,
> +                                      pixel_size, true,
> +                                      src_w != crtc_w || src_h != crtc_h);
> +
> +       /* Sizes are 0 based */
> +       src_w--;
> +       src_h--;
> +       crtc_w--;
> +       crtc_h--;
> +
> +       I915_WRITE(PLANE_OFFSET(pipe, plane), (y << 16) | x);
> +       I915_WRITE(PLANE_STRIDE(pipe, plane), stride);
> +       I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
> +       I915_WRITE(PLANE_SIZE(pipe, plane), (crtc_h << 16) | crtc_w);
> +       I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
> +       I915_WRITE(PLANE_SURF(pipe, plane), i915_gem_obj_ggtt_offset(obj));
> +       POSTING_READ(PLANE_SURF(pipe, plane));
> +}
> +
> +static void
> +skl_disable_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc)
> +{
> +       struct drm_device *dev = drm_plane->dev;
> +       struct drm_i915_private *dev_priv = dev->dev_private;
> +       struct intel_plane *intel_plane = to_intel_plane(drm_plane);
> +       const int pipe = intel_plane->pipe;
> +       const int plane = intel_plane->plane + 1;
> +
> +       I915_WRITE(PLANE_CTL(pipe, plane),
> +                  I915_READ(PLANE_CTL(pipe, plane)) & ~PLANE_CTL_ENABLE);
> +
> +       /* Activate double buffered register update */
> +       I915_WRITE(PLANE_CTL(pipe, plane), 0);
> +       POSTING_READ(PLANE_CTL(pipe, plane));
> +
> +       intel_update_sprite_watermarks(drm_plane, crtc, 0, 0, 0, false,
> false);
> +}
> +
> +static int
> +skl_update_colorkey(struct drm_plane *drm_plane,
> +                   struct drm_intel_sprite_colorkey *key)
> +{
> +       struct drm_device *dev = drm_plane->dev;
> +       struct drm_i915_private *dev_priv = dev->dev_private;
> +       struct intel_plane *intel_plane = to_intel_plane(drm_plane);
> +       const int pipe = intel_plane->pipe;
> +       const int plane = intel_plane->plane;
> +       u32 plane_ctl;
> +
> +       I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value);
> +       I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value);
> +       I915_WRITE(PLANE_KEYMSK(pipe, plane), key->channel_mask);
> +
> +       plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
> +       plane_ctl &= ~PLANE_CTL_KEY_ENABLE_MASK;
> +       if (key->flags & I915_SET_COLORKEY_DESTINATION)
> +               plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION;
> +       else if (key->flags & I915_SET_COLORKEY_SOURCE)
> +               plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE;
> +       I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
> +
> +       POSTING_READ(PLANE_CTL(pipe, plane));
> +
> +       return 0;
> +}
> +
> +static void
> +skl_get_colorkey(struct drm_plane *drm_plane,
> +                struct drm_intel_sprite_colorkey *key)
> +{
> +       struct drm_device *dev = drm_plane->dev;
> +       struct drm_i915_private *dev_priv = dev->dev_private;
> +       struct intel_plane *intel_plane = to_intel_plane(drm_plane);
> +       const int pipe = intel_plane->pipe;
> +       const int plane = intel_plane->plane;
> +       u32 plane_ctl;
> +
> +       key->min_value = I915_READ(PLANE_KEYVAL(pipe, plane));
> +       key->max_value = I915_READ(PLANE_KEYMAX(pipe, plane));
> +       key->channel_mask = I915_READ(PLANE_KEYMSK(pipe, plane));
> +
> +       plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
> +
> +       switch (plane_ctl & PLANE_CTL_KEY_ENABLE_MASK) {
> +       case PLANE_CTL_KEY_ENABLE_DESTINATION:
> +               key->flags = I915_SET_COLORKEY_DESTINATION;
> +               break;
> +       case PLANE_CTL_KEY_ENABLE_SOURCE:
> +               key->flags = I915_SET_COLORKEY_SOURCE;
> +               break;
> +       default:
> +               key->flags = I915_SET_COLORKEY_NONE;
> +       }
> +}
> +
> +static void
>  vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
>                  struct drm_framebuffer *fb,
>                  struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
> @@ -1305,6 +1483,18 @@ static uint32_t vlv_plane_formats[] = {
>         DRM_FORMAT_VYUY,
>  };
>
> +static uint32_t skl_plane_formats[] = {
> +       DRM_FORMAT_RGB565,
> +       DRM_FORMAT_ABGR8888,
> +       DRM_FORMAT_ARGB8888,
> +       DRM_FORMAT_XBGR8888,
> +       DRM_FORMAT_XRGB8888,
> +       DRM_FORMAT_YUYV,
> +       DRM_FORMAT_YVYU,
> +       DRM_FORMAT_UYVY,
> +       DRM_FORMAT_VYUY,
> +};
> +
>  int
>  intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
>  {
> @@ -1368,7 +1558,21 @@ intel_plane_init(struct drm_device *dev, enum pipe
> pipe, int plane)
>                         num_plane_formats = ARRAY_SIZE(snb_plane_formats);
>                 }
>                 break;
> -
> +       case 9:
> +               /*
> +                * FIXME: Skylake planes can be scaled (with some
> restrictions),
> +                * but this is for another time.
> +                */
> +               intel_plane->can_scale = false;
> +               intel_plane->max_downscale = 1;
> +               intel_plane->update_plane = skl_update_plane;
> +               intel_plane->disable_plane = skl_disable_plane;
> +               intel_plane->update_colorkey = skl_update_colorkey;
> +               intel_plane->get_colorkey = skl_get_colorkey;
> +
> +               plane_formats = skl_plane_formats;
> +               num_plane_formats = ARRAY_SIZE(skl_plane_formats);
> +               break;
>         default:
>                 kfree(intel_plane);
>                 return -ENODEV;
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>


Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 16912 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 39/89] drm/i915/skl: Adjust assert_sprites_disabled()
  2014-09-04 11:27 ` [PATCH 39/89] drm/i915/skl: Adjust assert_sprites_disabled() Damien Lespiau
@ 2014-09-17 22:10   ` Rodrigo Vivi
  0 siblings, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17 22:10 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1589 bytes --]

Reviewed-by: Rodrigo VIvi <rodrigo.vivi@intel.com>

On Thu, Sep 4, 2014 at 4:27 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> Let's put to good use the new PLANE_CTL macros.
>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 48d2d0d..3d9f447 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -1335,7 +1335,14 @@ static void assert_sprites_disabled(struct
> drm_i915_private *dev_priv,
>         int reg, sprite;
>         u32 val;
>
> -       if (IS_VALLEYVIEW(dev)) {
> +       if (INTEL_INFO(dev)->gen >= 9) {
> +               for_each_sprite(pipe, sprite) {
> +                       val = I915_READ(PLANE_CTL(pipe, sprite));
> +                       WARN(val & PLANE_CTL_ENABLE,
> +                            "plane %d assertion failure, should be off on
> pipe %c but is still active\n",
> +                            sprite, pipe_name(pipe));
> +               }
> +       } else if (IS_VALLEYVIEW(dev)) {
>                 for_each_sprite(pipe, sprite) {
>                         reg = SPCNTR(pipe, sprite);
>                         val = I915_READ(reg);
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 2550 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 40/89] drm/i915/skl: Introduce a I915_MAX_PLANES macro
  2014-09-04 11:27 ` [PATCH 40/89] drm/i915/skl: Introduce a I915_MAX_PLANES macro Damien Lespiau
@ 2014-09-17 22:12   ` Rodrigo Vivi
  0 siblings, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17 22:12 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1313 bytes --]

On Thu, Sep 4, 2014 at 4:27 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> This can be useful to declare structures around pipes and planes and
> don't have to go back auditing the code if the next platorm bump that
> number.
>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index be82888..dcd1c72 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -74,6 +74,14 @@ enum transcoder {
>  };
>  #define transcoder_name(t) ((t) + 'A')
>
> +/*
> + * This is the maximum (across all platforms) number of planes (primary +
> + * sprites) that can be active at the same time on one pipe.
> + *
> + * This value doesn't count the cursor plane.
> + */
> +#define I915_MAX_PLANES        3
>

Any plan to allow 4 planes on pipes A and B?

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

+
>  enum plane {
>         PLANE_A = 0,
>         PLANE_B,
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 2345 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 41/89] drm/i915/skl: Introduce intel_num_planes()
  2014-09-04 11:27 ` [PATCH 41/89] drm/i915/skl: Introduce intel_num_planes() Damien Lespiau
@ 2014-09-17 22:13   ` Rodrigo Vivi
  0 siblings, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17 22:13 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1436 bytes --]

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Thu, Sep 4, 2014 at 4:27 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> It can be handy to get the number of planes for this pipe, ie including
> the primary plane to loop over them. Introduce a little function to do
> so.
>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_drv.h | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index d727d20..3239e58 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -721,6 +721,14 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
>         return container_of(intel_hdmi, struct intel_digital_port, hdmi);
>  }
>
> +/*
> + * Returns the number of planes for this pipe, ie the number of sprites +
> 1
> + * (primary plane). This doesn't count the cursor plane then.
> + */
> +static inline unsigned int intel_num_planes(struct intel_crtc *crtc)
> +{
> +       return INTEL_INFO(crtc->base.dev)->num_sprites[crtc->pipe] + 1;
> +}
>
>  /* i915_irq.c */
>  bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 2283 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 42/89] drm/i915/skl: Move gen9 pm initialization into its own branch
  2014-09-04 11:27 ` [PATCH 42/89] drm/i915/skl: Move gen9 pm initialization into its own branch Damien Lespiau
@ 2014-09-17 22:16   ` Rodrigo Vivi
  0 siblings, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17 22:16 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 2243 bytes --]

Oh I think we should reorganize everything here now...

It got messy... Well it was messy anyway already...

not this patch's fault so:

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Thu, Sep 4, 2014 at 4:27 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> Gen9 is different enough (for instance, fetching the memory latency
> values is different from ILK+) to not take the HAS_PCH_SPLIT() branch,
> so let's prefer a clean separation.
>
> v2: Rebase on top of the broadwell_init_clock_gating() name change
>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index faff54e..a236e77 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -7395,7 +7395,9 @@ void intel_init_pm(struct drm_device *dev)
>                 i915_ironlake_get_mem_freq(dev);
>
>         /* For FIFO watermark updates */
> -       if (HAS_PCH_SPLIT(dev)) {
> +       if (IS_GEN9(dev)) {
> +               dev_priv->display.init_clock_gating =
> gen9_init_clock_gating;
> +       } else if (HAS_PCH_SPLIT(dev)) {
>                 ilk_setup_wm_latency(dev);
>
>                 if ((IS_GEN5(dev) && dev_priv->wm.pri_latency[1] &&
> @@ -7419,8 +7421,6 @@ void intel_init_pm(struct drm_device *dev)
>                         dev_priv->display.init_clock_gating =
> haswell_init_clock_gating;
>                 else if (INTEL_INFO(dev)->gen == 8)
>                         dev_priv->display.init_clock_gating =
> broadwell_init_clock_gating;
> -               else if (INTEL_INFO(dev)->gen == 9)
> -                       dev_priv->display.init_clock_gating =
> gen9_init_clock_gating;
>         } else if (IS_CHERRYVIEW(dev)) {
>                 dev_priv->display.update_wm = cherryview_update_wm;
>                 dev_priv->display.update_sprite_wm =
> valleyview_update_sprite_wm;
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 3325 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 33/89] drm/i915/skl: Sunrise Point PCH detection
  2014-09-04 11:26 ` [PATCH 33/89] drm/i915/skl: Sunrise Point PCH detection Damien Lespiau
@ 2014-09-17 22:18   ` Rodrigo Vivi
  2014-09-22 13:42     ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-17 22:18 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 3113 bytes --]

Where can I find these pch device id definitions?

On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>
> This patch implements detection of SPT and SPT-LP PCH devices.
>
> v2: Added HAS_PCH_SPT macro
>
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.c | 10 ++++++++++
>  drivers/gpu/drm/i915/i915_drv.h |  4 ++++
>  2 files changed, 14 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.c
> b/drivers/gpu/drm/i915/i915_drv.c
> index 3d7f823..c6a8a80 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -475,6 +475,16 @@ void intel_detect_pch(struct drm_device *dev)
>                                 DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
>                                 WARN_ON(!IS_HASWELL(dev));
>                                 WARN_ON(!IS_ULT(dev));
> +                       } else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) {
> +                               dev_priv->pch_type = PCH_SPT;
> +                               DRM_DEBUG_KMS("Found SunrisePoint PCH\n");
> +                               WARN_ON(!IS_SKYLAKE(dev));
> +                               WARN_ON(IS_ULT(dev));
> +                       } else if (id == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) {
> +                               dev_priv->pch_type = PCH_SPT;
> +                               DRM_DEBUG_KMS("Found SunrisePoint LP
> PCH\n");
> +                               WARN_ON(!IS_SKYLAKE(dev));
> +                               WARN_ON(!IS_ULT(dev));
>                         } else
>                                 continue;
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index cf4fc86..be82888 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -699,6 +699,7 @@ enum intel_pch {
>         PCH_IBX,        /* Ibexpeak PCH */
>         PCH_CPT,        /* Cougarpoint PCH */
>         PCH_LPT,        /* Lynxpoint PCH */
> +       PCH_SPT,        /* Sunrisepoint PCH */
>         PCH_NOP,
>  };
>
> @@ -2184,8 +2185,11 @@ struct drm_i915_cmd_table {
>  #define INTEL_PCH_PPT_DEVICE_ID_TYPE           0x1e00
>  #define INTEL_PCH_LPT_DEVICE_ID_TYPE           0x8c00
>  #define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE                0x9c00
> +#define INTEL_PCH_SPT_DEVICE_ID_TYPE           0xA100
> +#define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE                0x9D00
>
>  #define INTEL_PCH_TYPE(dev) (to_i915(dev)->pch_type)
> +#define HAS_PCH_SPT(dev) (INTEL_PCH_TYPE(dev) == PCH_SPT)
>  #define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT)
>  #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
>  #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX)
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 4436 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 69/89] drm/i915/skl: Adding power domains for AUX controllers
  2014-09-16 12:35   ` Imre Deak
@ 2014-09-18 13:56     ` Damien Lespiau
  2014-09-18 14:23       ` Imre Deak
  2014-11-05 14:23     ` [PATCH 69/89 v5] " Damien Lespiau
  1 sibling, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-18 13:56 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

Hi Imre,

I actually had some question there as well:

On Tue, Sep 16, 2014 at 03:35:15PM +0300, Imre Deak wrote:
> > @@ -7685,24 +7689,32 @@ EXPORT_SYMBOL_GPL(i915_get_cdclk_freq);
> >  	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |	\
> >  	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |	\
> >  	BIT(POWER_DOMAIN_PORT_CRT) |		\
> > +	BIT(POWER_DOMAIN_AUX_A) |		\
> > +	BIT(POWER_DOMAIN_AUX_B) |		\
> > +	BIT(POWER_DOMAIN_AUX_C) |		\
> > +	BIT(POWER_DOMAIN_AUX_D) |		\
> >  	BIT(POWER_DOMAIN_INIT))

That's the VLV_DPIO_CMN_BC_POWER_DOMAINS, shouldn't we move AUX_A out of
this define?

Where does the port A lanes/aux should be on VLV and CHV, I don't see a
good fit nor where the POWER_DOMAIN_PORT_DDI_A_X_LANES is today

> >  #define VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS (	\
> >  	BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |	\
> >  	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |	\
> > +	BIT(POWER_DOMAIN_AUX_B) |		\
> >  	BIT(POWER_DOMAIN_INIT))
> >  
> >  #define VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS (	\
> >  	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |	\
> > +	BIT(POWER_DOMAIN_AUX_B) |		\
> >  	BIT(POWER_DOMAIN_INIT))

Wouldn't it better to leave the AUX domain in the LANES_01 power domain,
otherwise we'll power up the full 4 lanes for aux transactions?

Thanks,

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 69/89] drm/i915/skl: Adding power domains for AUX controllers
  2014-09-18 13:56     ` Damien Lespiau
@ 2014-09-18 14:23       ` Imre Deak
  2014-09-18 14:29         ` Ville Syrjälä
  0 siblings, 1 reply; 286+ messages in thread
From: Imre Deak @ 2014-09-18 14:23 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 2414 bytes --]

On Thu, 2014-09-18 at 14:56 +0100, Damien Lespiau wrote:
> Hi Imre,
> 
> I actually had some question there as well:
> 
> On Tue, Sep 16, 2014 at 03:35:15PM +0300, Imre Deak wrote:
> > > @@ -7685,24 +7689,32 @@ EXPORT_SYMBOL_GPL(i915_get_cdclk_freq);
> > >  	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |	\
> > >  	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |	\
> > >  	BIT(POWER_DOMAIN_PORT_CRT) |		\
> > > +	BIT(POWER_DOMAIN_AUX_A) |		\
> > > +	BIT(POWER_DOMAIN_AUX_B) |		\
> > > +	BIT(POWER_DOMAIN_AUX_C) |		\
> > > +	BIT(POWER_DOMAIN_AUX_D) |		\
> > >  	BIT(POWER_DOMAIN_INIT))
> 
> That's the VLV_DPIO_CMN_BC_POWER_DOMAINS, shouldn't we move AUX_A out of
> this define?

Yes I haven't noticed this. Port A and D don't exist on VLV so we don't
need to add them here. It wouldn't be a problem to add them, since we
never ask for these domains on VLV, but I agree that it's confusing to
add them here.

> Where does the port A lanes/aux should be on VLV and CHV, I don't see a
> good fit nor where the POWER_DOMAIN_PORT_DDI_A_X_LANES is today

POWER_DOMAIN_PORT_DDI_A_X_LANES and POWER_DOMAIN_PORT_DDI_D_X_LANES is
part of VLV_DISPLAY_POWER_DOMAINS, but again they are only a place
holder there. The display power well is needed for all domains, so I
defined the mapping simply accordingly.

> > >  #define VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS (	\
> > >  	BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |	\
> > >  	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |	\
> > > +	BIT(POWER_DOMAIN_AUX_B) |		\
> > >  	BIT(POWER_DOMAIN_INIT))
> > >  
> > >  #define VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS (	\
> > >  	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |	\
> > > +	BIT(POWER_DOMAIN_AUX_B) |		\
> > >  	BIT(POWER_DOMAIN_INIT))
> 
> Wouldn't it better to leave the AUX domain in the LANES_01 power domain,
> otherwise we'll power up the full 4 lanes for aux transactions?

With this patch I thought that we'd keep things as-is for all platforms
except SKL. I imagined that we'd get only the AUX power domains for AUX
functionality (in patch 72/89) and not take the port power domains for
full port functionality. That would provide the extra power saving on
SKL and would keep the other platforms unchanged.

You are right that we probably don't need the TX power wells for AUX
functionality on VLV, but I haven't checked this yet, so this would need
to be done separately as a follow-up.

--Imre


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 69/89] drm/i915/skl: Adding power domains for AUX controllers
  2014-09-18 14:23       ` Imre Deak
@ 2014-09-18 14:29         ` Ville Syrjälä
  0 siblings, 0 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-18 14:29 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

On Thu, Sep 18, 2014 at 05:23:14PM +0300, Imre Deak wrote:
> On Thu, 2014-09-18 at 14:56 +0100, Damien Lespiau wrote:
 
> > > >  #define VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS (	\
> > > >  	BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |	\
> > > >  	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |	\
> > > > +	BIT(POWER_DOMAIN_AUX_B) |		\
> > > >  	BIT(POWER_DOMAIN_INIT))
> > > >  
> > > >  #define VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS (	\
> > > >  	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |	\
> > > > +	BIT(POWER_DOMAIN_AUX_B) |		\
> > > >  	BIT(POWER_DOMAIN_INIT))
> > 
> > Wouldn't it better to leave the AUX domain in the LANES_01 power domain,
> > otherwise we'll power up the full 4 lanes for aux transactions?
> 
> With this patch I thought that we'd keep things as-is for all platforms
> except SKL. I imagined that we'd get only the AUX power domains for AUX
> functionality (in patch 72/89) and not take the port power domains for
> full port functionality. That would provide the extra power saving on
> SKL and would keep the other platforms unchanged.
> 
> You are right that we probably don't need the TX power wells for AUX
> functionality on VLV, but I haven't checked this yet, so this would need
> to be done separately as a follow-up.

And we always have the nasty CMN vs. TX ordering issue on VLV. So unless
someone adds the logic to bring the wells down and back up again when
we need to power up TX wells when CMN is already up, we just have to
keep TX wells powered whenever CMN is powered.

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 48/89] drm/i915/skl: Allocate DDB portions for display planes
  2014-09-04 11:27 ` [PATCH 48/89] drm/i915/skl: Allocate DDB portions for display planes Damien Lespiau
@ 2014-09-19  9:58   ` Ville Syrjälä
  2014-09-27 14:15     ` [PATCH 48/89 v6] " Damien Lespiau
  2014-09-23 11:19   ` [PATCH 48/89 v4] " Damien Lespiau
  1 sibling, 1 reply; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-19  9:58 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:27:14PM +0100, Damien Lespiau wrote:
> v2: Fix the 3rd plane/cursor logic (Pradeep Bhat)
> v3: Fix one-by-one error in the DDB allocation code
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 150 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 150 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 4ee90b6..0ddcbad 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2937,6 +2937,155 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
>  	return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
>  }
>  
> +/*
> + * On gen9, we need to allocate Display Data Buffer (DDB) portions to the
> + * different active planes.
> + */
> +
> +#define SKL_DDB_SIZE		896	/* in blocks */
> +
> +static void
> +skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
> +				   struct drm_crtc *for_crtc,
> +				   struct intel_wm_config *config,
> +				   struct skl_pipe_wm_parameters *params,

const

> +				   uint16_t *available,
> +				   uint16_t *start,
> +				   uint16_t *end)
> +{
> +	struct drm_crtc *crtc;
> +	unsigned int ddb_size;
> +	int nth_active_pipe;
> +
> +	if (!params->active) {
> +		*available = 0;
> +		*start = 0;
> +		*end = 0;
> +		return;
> +	}
> +
> +	ddb_size = SKL_DDB_SIZE;
> +
> +	ddb_size -= 4; /* 4 blocks for bypass path allocation */
> +
> +	nth_active_pipe = 1;

Why does this start from 1 and not 0? Are we pascal coders now? :P

> +	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
> +		if (!intel_crtc_active(crtc))
> +			continue;
> +
> +		if (crtc == for_crtc)
> +			break;
> +
> +		nth_active_pipe++;
> +	}

One thing that has been bugging me for a long time is this kind of
loops for just counting stuff. I think we want to start using bitmasks
to track active pipes/planes/etc. But that's not really related to this
patch itself, just a more generic remark. And in this case it wouldn't
even help :)

> +
> +	*available = ddb_size / config->num_pipes_active;

This seems like a pointless thing to return separately. end-start is
the same thing (apart from the +/-1 stuff which should be killed again
by making end exclusive).

> +	*start = (nth_active_pipe - 1) * ddb_size / config->num_pipes_active;
> +	*end = *start + *available - 1;

Didn't we have that new struct with start+end in it? Perhaps it should
be used here?

As stated before this is going to complicate the application of the DDB
registers since we now have to consider the vblanks of potentially
multiple active pipes. But it should provide more optiomal DDB usage
than the max/num_pipes that the automagic maxfifo mode on most other
platforms provides, so I guess we really do want to do it this way. And
it seems to me that having two pipes enabled woud more much more common
than three pipes.

> +}
> +
> +static unsigned int skl_cursor_allocation(struct intel_wm_config *config)

const

> +{
> +	if (config->num_pipes_active == 1)
> +		return 32;
> +
> +	return 8;
> +}
> +
> +static unsigned int
> +skl_plane_relative_data_rate(struct intel_plane_wm_parameters *p)

const

> +{
> +	return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel;
> +}
> +
> +/*
> + * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching
> + * a 8192x4096@32bpp framebuffer:
> + *   3 * 4096 * 8192  * 4 < 2^32
> + */
> +static unsigned int
> +skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc,
> +				 struct skl_pipe_wm_parameters *params)

const

> +{
> +	unsigned int total_data_rate = 0;
> +	int plane;
> +
> +	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
> +		struct intel_plane_wm_parameters *p = &params->plane[plane];
> +
> +		if (!p->enabled)
> +			continue;
> +
> +		total_data_rate += skl_plane_relative_data_rate(p);
> +	}
> +
> +	return total_data_rate;
> +}
> +
> +static void
> +skl_allocate_pipe_ddb(struct drm_crtc *crtc,
> +		      struct intel_wm_config *config,
> +		      struct skl_pipe_wm_parameters *params,

const

> +		      struct skl_ddb_allocation *ddb /* out */)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	enum pipe pipe = intel_crtc->pipe;
> +	uint16_t available, start, end, cursor_blocks;
> +	unsigned int total_data_rate;
> +	int plane;
> +
> +	skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params,
> +					   &available, &start, &end);
> +	if (available == 0) {
> +		const size_t size = ARRAY_SIZE(ddb->plane[pipe]) *
> +				    sizeof(struct skl_ddb_entry);
> +
> +		memset(ddb->plane[pipe], 0, size);

sizeof(ddb->plane[pipe]) 

> +		memset(&ddb->cursor[pipe], 0, sizeof(struct skl_ddb_entry));

sizeof(ddb->cursor[pipe]) 

> +		return;
> +	}
> +
> +	cursor_blocks = skl_cursor_allocation(config);
> +	ddb->cursor[pipe].start = end - cursor_blocks + 1;
> +	ddb->cursor[pipe].end = end;
> +
> +	available -= cursor_blocks;
> +	end -= cursor_blocks;

I got the impression bspec recommened putting all the cursor allocations
into one lump. But I can't really think of any good reason for doing
that so this seems fine to me.

> +
> +	/*
> +	 * Each active plane get a portion of the remaining space, in
> +	 * proportion to the amount of data they need to fetch from memory.
> +	 *
> +	 * FIXME: we don't always allocate every single block here.
> +	 */
> +	total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params);
> +
> +	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
> +		struct intel_plane_wm_parameters *p = &params->plane[plane];
> +		unsigned int data_rate;
> +		uint16_t plane_blocks;
> +
> +		if (!p->enabled)
> +			continue;
> +
> +		data_rate = skl_plane_relative_data_rate(p);
> +
> +		/*
> +		 * promote the expression to 64 bits to avoid overflowing, the
> +		 * result is < available as data_rate / total_data_rate < 1
> +		 */
> +		plane_blocks = div_u64((uint64_t)available * data_rate,
> +				       total_data_rate);
> +
> +		ddb->plane[pipe][plane].start = start;
> +		ddb->plane[pipe][plane].end = start + plane_blocks - 1;
> +
> +		start += plane_blocks;
> +	}
> +
> +}
> +
>  static uint32_t skl_pipe_pixel_rate(struct drm_device *dev,
>  				    struct drm_crtc *crtc)
>  {
> @@ -3259,6 +3408,7 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  
>  	skl_compute_wm_pipe_parameters(crtc, params);
> +	skl_allocate_pipe_ddb(crtc, config, params, ddb);
>  	skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
>  
>  	if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 49/89] drm/i915/skl: Program the DDB allocation
  2014-09-04 11:27 ` [PATCH 49/89] drm/i915/skl: Program the DDB allocation Damien Lespiau
@ 2014-09-19 10:03   ` Ville Syrjälä
  2014-09-27 14:17     ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-19 10:03 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:27:15PM +0100, Damien Lespiau wrote:
> v2: Adapt to the planes/cursor split
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h | 16 ++++++++++++++++
>  drivers/gpu/drm/i915/intel_pm.c |  9 +++++++++
>  2 files changed, 25 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 9fbce2c..414c2a5 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4602,6 +4602,8 @@ enum punit_power_well {
>  #define _PLANE_KEYMSK_2_A			0x70298
>  #define _PLANE_KEYMAX_1_A			0x701a0
>  #define _PLANE_KEYMAX_2_A			0x702a0
> +#define _PLANE_BUF_CFG_1_A			0x7027c
> +#define _PLANE_BUF_CFG_2_A			0x7037c
>  
>  #define _PLANE_CTL_1_B				0x71180
>  #define _PLANE_CTL_2_B				0x71280
> @@ -4679,6 +4681,20 @@ enum punit_power_well {
>  #define PLANE_KEYMAX(pipe, plane)	\
>  	_PLANE(plane, _PLANE_KEYMAX_1(pipe), _PLANE_KEYMAX_2(pipe))
>  
> +#define _PLANE_BUF_CFG_1_B			0x7127c
> +#define _PLANE_BUF_CFG_2_B			0x7137c
> +#define _PLANE_BUF_CFG_1(pipe)	\
> +	_PIPE(pipe, _PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B)
> +#define _PLANE_BUF_CFG_2(pipe)	\
> +	_PIPE(pipe, _PLANE_BUF_CFG_2_A, _PLANE_BUF_CFG_2_B)
> +#define PLANE_BUF_CFG(pipe, plane)	\
> +	_PLANE(plane, _PLANE_BUF_CFG_1(pipe), _PLANE_BUF_CFG_2(pipe))
> +
> +/* SKL new cursor registers */
> +#define _CUR_BUF_CFG_A				0x7017c
> +#define _CUR_BUF_CFG_B				0x7117c
> +#define CUR_BUF_CFG(pipe)	_PIPE(pipe, _CUR_BUF_CFG_A, _CUR_BUF_CFG_B)
> +

More macros to confuse me :P

The magic numbers look correct again though.

>  /* VBIOS regs */
>  #define VGACNTRL		0x71400
>  # define VGA_DISP_DISABLE			(1 << 31)
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 0ddcbad..756ff16 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3393,6 +3393,15 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
>  				I915_WRITE(PLANE_WM_TRANS(pipe, i),
>  						new->plane_trans[pipe][i]);
>  			I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
> +
> +			for (i = 0; i < intel_num_planes(crtc); i++)
> +				I915_WRITE(PLANE_BUF_CFG(pipe, i),
> +					   new->ddb.plane[pipe][i].end << 16 |

The spec doesn't say if end is inclusive or exclusive. Someone actually
confirmed that from someone or tested it?

> +					   new->ddb.plane[pipe][i].start);
> +
> +			I915_WRITE(CUR_BUF_CFG(pipe),
> +				   new->ddb.cursor[pipe].end << 16 |
> +				   new->ddb.cursor[pipe].start);
>  		}
>  	}

And here we land in deep doodoo wrt. changing the DDB allocation
for active pipes. Someone needs to implement the correct logic to
sequence the DDB allocation changes so that the allocations don't
overlap at any point in time.

So this needs a big FIXME at the very least.

>  
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 51/89] drm/i915/gen9: Add 2us read latency to WM level
  2014-09-04 11:27 ` [PATCH 51/89] drm/i915/gen9: Add 2us read latency to WM level Damien Lespiau
@ 2014-09-19 10:04   ` Ville Syrjälä
  0 siblings, 0 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-19 10:04 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:27:17PM +0100, Damien Lespiau wrote:
> From: Vandana Kannan <vandana.kannan@intel.com>
> 
> According to the updated Bspec, The mailbox response data is not currently
> accounting for memory read latency. Add 2 microseconds to the result for
> each level.
> This patch adds 2us to latency of level 0 for all cases and
> for all other levels (1-7) only if latency[level] > 0.
> 
> v2: Slightly rework the patch and add a big comment (Damien)
> 
> Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v1)
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> Reviewed-by: M, Satheeshakrishna <satheeshakrishna.m@intel.com> (v1)
> Cc: Lespiau, Damien <damien.lespiau@intel.com>
> Cc: M, Satheeshakrishna <satheeshakrishna.m@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/i915/intel_pm.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 1e56067..16ad008 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2254,6 +2254,7 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
>  	if (IS_GEN9(dev)) {
>  		uint32_t val;
>  		int ret;
> +		int level, max_level = ilk_wm_max_level(dev);
>  
>  		/* read the first set of memory latencies[0:3] */
>  		val = 0; /* data0 to be programmed to 0 for first set */
> @@ -2267,6 +2268,7 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
>  			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
>  			return;
>  		}
> +
>  		wm[0] = val & GEN9_MEM_LAT_LEVEL_MASK;
>  		wm[1] = (val >> GEN9_MEM_LAT_LEVEL_1_5_SHIFT) &
>  				GEN9_MEM_LAT_LEVEL_MASK;
> @@ -2293,6 +2295,22 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
>  				GEN9_MEM_LAT_LEVEL_MASK;
>  		wm[7] = (val >> GEN9_MEM_LAT_LEVEL_3_7_SHIFT) &
>  				GEN9_MEM_LAT_LEVEL_MASK;
> +
> +		/*
> +		 * punit doesn't take into account the read latency so we need
> +		 * to add 2us to the various latency levels we retrieve from
> +		 * the punit.
> +		 *   - W0 is a bit special in that it's the only level that
> +		 *   can't be disabled if we want to have display working, so
> +		 *   we always add 2us there.
> +		 *   - For levels >=1, punit returns 0us latency when they are
> +		 *   disabled, so we respect that and don't add 2us then
> +		 */
> +		wm[0] += 2;
> +		for (level = 1; level <= max_level; level++)
> +			if (wm[level] != 0)
> +				wm[level] += 2;
> +
>  	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
>  		uint64_t sskpd = I915_READ64(MCH_SSKPD);
>  
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 52/89] drm/i915/gen9: Disable WM if corresponding latency is 0
  2014-09-04 11:27 ` [PATCH 52/89] drm/i915/gen9: Disable WM if corresponding latency is 0 Damien Lespiau
@ 2014-09-19 10:05   ` Ville Syrjälä
  2014-09-24 14:06     ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-19 10:05 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:27:18PM +0100, Damien Lespiau wrote:
> From: Vandana Kannan <vandana.kannan@intel.com>
> 
> According to updated BSpec, If level 1 or any higher level has a value of 0x00,
> that level and any higher levels are unused and the associated watermark
> registers must not be enabled.
> 
> This patch checks for latency 0 for level >=1 and does not enable WM
> corresponding to level m | m>=n, if level n (n != 0) has a 0us latency.
> 
> v2: Satheesh's review comments
> 	- zero-out latency values (for all higher levels if latency of given
> 	level is zero ) in read_wm_latency() function itself
> 
> v3: removed redundant check as per Satheesh's observation.
> v4: rebase on top before merging (Damien)
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
> Reviewed-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v3)
> Cc: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 14 ++++++++++++--
>  1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 16ad008..fdf297f 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2253,7 +2253,7 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
>  
>  	if (IS_GEN9(dev)) {
>  		uint32_t val;
> -		int ret;
> +		int ret, i;
>  		int level, max_level = ilk_wm_max_level(dev);
>  
>  		/* read the first set of memory latencies[0:3] */
> @@ -2305,12 +2305,22 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
>  		 *   we always add 2us there.
>  		 *   - For levels >=1, punit returns 0us latency when they are
>  		 *   disabled, so we respect that and don't add 2us then
> +		 *
> +		 * Additionally, if a level n (n > 1) has a 0us latency, all
> +		 * levels m (m >= n) need to be disabled. We make sure to
> +		 * sanitize the values out of the punit to satisfy this
> +		 * requirement.
>  		 */
>  		wm[0] += 2;
>  		for (level = 1; level <= max_level; level++)
>  			if (wm[level] != 0)
>  				wm[level] += 2;
> +			else {
> +				for (i = level + 1; i <= max_level; i++)
> +					wm[i] = 0;
>  
> +				break;
> +			}

If we're going to be paranoid I think we should disable all higher WM
levels whose latency is lower than any of the lower levels. And I
think we'll want something like dev_priv->wm.max_wm_level instead of
relying on the zero latency tricks. That thing has been on my TODO
list since forever.

>  	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
>  		uint64_t sskpd = I915_READ64(MCH_SSKPD);
>  
> @@ -3253,7 +3263,7 @@ static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
>  	uint32_t method1, method2, plane_bytes_per_line;
>  	uint32_t result_bytes;
>  
> -	if (!p->active || !p_params->enabled) {
> +	if (mem_value == 0 || !p->active || !p_params->enabled) {
>  		*res_blocks = PLANE_WM_BLOCKS_DEFAULT;
>  		*res_lines = PLANE_WM_LINES_DEFAULT;
>  		return false;
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 78/89] drm/i915/skl: Flush the WM configuration
  2014-09-04 11:27 ` [PATCH 78/89] drm/i915/skl: Flush the WM configuration Damien Lespiau
@ 2014-09-19 10:46   ` Ville Syrjälä
  0 siblings, 0 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-19 10:46 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:27:44PM +0100, Damien Lespiau wrote:
> When we write new values for the DDB allocation and WM parameters, we now
> need to trigger the double buffer update for the pipe to take the new
> configuration into account.
> 
> As the DDB is a global resource shared between planes, enabling or
> disabling one plane will result in changes for all planes that are
> currently in use, thus the need write PLANE_SURF/CUR_BASE for more than
> the plane we're touching.

Ah, so here's the sequenced DDB update logic I was looking for.

> 
> v2: Don't wait for pipes that are off
> 
> v3: Split the staging results structure to not exceed the 1Kb stack
>     allocation in skl_update_wm()
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 92 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 92 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 7f7a2e2..d378879 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3198,6 +3198,22 @@ static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
>  	return false;
>  }
>  
> +static unsigned int
> +skl_ddb_pipe_allocation_size(const struct skl_ddb_allocation *ddb,
> +			     const struct intel_crtc *intel_crtc)
> +{
> +	struct drm_device *dev = intel_crtc->base.dev;
> +	unsigned int size = 0;
> +	enum pipe pipe = intel_crtc->pipe;
> +	int plane;
> +
> +	for_each_plane(pipe, plane)
> +		size += skl_ddb_entry_size(&ddb->plane[pipe][plane]);
> +	size += skl_ddb_entry_size(&ddb->cursor[pipe]);
> +
> +	return size;
> +}
> +
>  static void skl_compute_wm_global_parameters(struct drm_device *dev,
>  					     struct intel_wm_config *config)
>  {
> @@ -3434,6 +3450,81 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
>  	}
>  }
>  
> +static void skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
> +{
> +	struct drm_device *dev = dev_priv->dev;
> +	int plane;
> +
> +	for_each_plane(pipe, plane) {
> +		I915_WRITE(PLANE_SURF(pipe, plane),
> +			   I915_READ(PLANE_SURF(pipe, plane)));
> +	}
> +	I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe)));
> +}

I'm not sure I really like this thing. The DDB/wm update should be part
of the atomic pipe update. But since we're not really there yet I guess
we need to start with something. And dealing with multiple pipes is
a definite complication here.

> +
> +static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
> +				struct skl_wm_values *new_values)
> +{
> +	struct drm_device *dev = dev_priv->dev;
> +	struct skl_ddb_allocation *cur_ddb, *new_ddb;
> +	unsigned int cur_size[I915_MAX_PIPES], new_size[I915_MAX_PIPES];
> +	struct intel_crtc *crtc;
> +	enum pipe pipe;
> +
> +	new_ddb = &new_values->ddb;
> +	cur_ddb = &dev_priv->wm.skl_hw.ddb;
> +
> +	/*
> +	 * Start by computing the total allocated space for each pipe as we
> +	 * need that values for the two passes.
> +	 */
> +	for_each_intel_crtc(dev, crtc) {
> +		pipe = crtc->pipe;
> +		new_size[pipe] = skl_ddb_pipe_allocation_size(new_ddb, crtc);
> +		cur_size[pipe] = skl_ddb_pipe_allocation_size(cur_ddb, crtc);
> +	}
> +
> +	/*
> +	 * First pass: we flush the pipes that had their allocation reduced.
> +	 *
> +	 * We then have to wait until the pipe stops fetching pixels from the
> +	 * previous allocation. This way, pipes that have just been allocated
> +	 * more space won't try to fetch pixels belonging to a different pipe.
> +	 */
> +	for_each_intel_crtc(dev, crtc) {
> +		if (!crtc->active)
> +			continue;
> +
> +		pipe = crtc->pipe;
> +
> +		if (new_size[pipe] < cur_size[pipe]) {
> +			skl_wm_flush_pipe(dev_priv, pipe);
> +			intel_wait_for_vblank(dev, pipe);
> +		}
> +	}
> +
> +	/*
> +	 * Second pass: flush the pipes that got more allocated space.
> +	 *
> +	 * We don't need to actively wait for the update here, next vblank
> +	 * will just get more DDB space with the correct WM values.
> +	 */
> +	for_each_intel_crtc(dev, crtc) {
> +		if (!crtc->active)
> +			continue;
> +
> +		pipe = crtc->pipe;
> +
> +		if (new_size[pipe] < cur_size[pipe])
> +			continue;
> +
> +		if (!skl_ddb_allocation_changed(new_ddb, crtc))
> +			continue;
> +
> +		skl_wm_flush_pipe(dev_priv, pipe);
> +	}
> +}

I don't think this logic will do the right thing. Consider for example
when going from two pipes to three:

1. initially DDB looks like this
   |   B    |   C    |
2. enable pipe A
3. reduce pipe B DDB allocation
   |     |  B..|     |
   |        |   C    |

Notice the part marked with .. is now used by both pipes B and C until
the allocation for C also gets reduced. It would work correctly in case
we would go AB->ABC or AC->ABC. Similar problem would be
encountered when going ABC->AB. So we need more care in which order
we update the DDB allocation for each pipe to avoid such overlaps.

> +
>  static bool skl_update_pipe_wm(struct drm_crtc *crtc,
>  			       struct skl_pipe_wm_parameters *params,
>  			       struct intel_wm_config *config,
> @@ -3525,6 +3616,7 @@ static void skl_update_wm(struct drm_crtc *crtc)
>  
>  	skl_update_other_pipe_wm(dev, crtc, &config, results);
>  	skl_write_wm_values(dev_priv, results);
> +	skl_flush_wm_values(dev_priv, results);
>  
>  	/* store the new configuration */
>  	dev_priv->wm.skl_hw = *results;
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 80/89] drm/i915/skl: Augment the latency debugfs files for SKL
  2014-09-04 11:27 ` [PATCH 80/89] drm/i915/skl: Augment the latency debugfs files for SKL Damien Lespiau
@ 2014-09-19 10:53   ` Ville Syrjälä
  2014-09-29 13:37     ` [PATCH 80/89 v2] " Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-19 10:53 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:27:46PM +0100, Damien Lespiau wrote:
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c | 76 ++++++++++++++++++++++++++++++-------
>  1 file changed, 62 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 02cb310..1520d1f 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -3499,7 +3499,7 @@ static const struct file_operations i915_display_crc_ctl_fops = {
>  	.write = display_crc_ctl_write
>  };
>  
> -static void wm_latency_show(struct seq_file *m, const uint16_t wm[5])
> +static void wm_latency_show(struct seq_file *m, const uint16_t wm[8])
>  {
>  	struct drm_device *dev = m->private;
>  	int num_levels = ilk_wm_max_level(dev) + 1;
> @@ -3510,13 +3510,17 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[5])
>  	for (level = 0; level < num_levels; level++) {
>  		unsigned int latency = wm[level];
>  
> -		/* WM1+ latency values in 0.5us units */
> -		if (level > 0)
> +		/*
> +		 * - WM1+ latency values in 0.5us units
> +		 * - latencies are in us on gen9
> +		 */
> +		if (IS_GEN9(dev))

gen >= 9 here to perhaps?

Apart from that it looks ok to me.
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> +			latency *= 10;
> +		else if (level > 0)
>  			latency *= 5;
>  
>  		seq_printf(m, "WM%d %u (%u.%u usec)\n",
> -			   level, wm[level],
> -			   latency / 10, latency % 10);
> +			   level, wm[level], latency / 10, latency % 10);
>  	}
>  
>  	drm_modeset_unlock_all(dev);
> @@ -3525,8 +3529,15 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[5])
>  static int pri_wm_latency_show(struct seq_file *m, void *data)
>  {
>  	struct drm_device *dev = m->private;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	const uint16_t *latencies;
> +
> +	if (INTEL_INFO(dev)->gen >= 9)
> +		latencies = dev_priv->wm.skl_latency;
> +	else
> +		latencies = to_i915(dev)->wm.pri_latency;
>  
> -	wm_latency_show(m, to_i915(dev)->wm.pri_latency);
> +	wm_latency_show(m, latencies);
>  
>  	return 0;
>  }
> @@ -3534,8 +3545,15 @@ static int pri_wm_latency_show(struct seq_file *m, void *data)
>  static int spr_wm_latency_show(struct seq_file *m, void *data)
>  {
>  	struct drm_device *dev = m->private;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	const uint16_t *latencies;
> +
> +	if (INTEL_INFO(dev)->gen >= 9)
> +		latencies = dev_priv->wm.skl_latency;
> +	else
> +		latencies = to_i915(dev)->wm.spr_latency;
>  
> -	wm_latency_show(m, to_i915(dev)->wm.spr_latency);
> +	wm_latency_show(m, latencies);
>  
>  	return 0;
>  }
> @@ -3543,8 +3561,15 @@ static int spr_wm_latency_show(struct seq_file *m, void *data)
>  static int cur_wm_latency_show(struct seq_file *m, void *data)
>  {
>  	struct drm_device *dev = m->private;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	const uint16_t *latencies;
> +
> +	if (INTEL_INFO(dev)->gen >= 9)
> +		latencies = dev_priv->wm.skl_latency;
> +	else
> +		latencies = to_i915(dev)->wm.cur_latency;
>  
> -	wm_latency_show(m, to_i915(dev)->wm.cur_latency);
> +	wm_latency_show(m, latencies);
>  
>  	return 0;
>  }
> @@ -3580,11 +3605,11 @@ static int cur_wm_latency_open(struct inode *inode, struct file *file)
>  }
>  
>  static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
> -				size_t len, loff_t *offp, uint16_t wm[5])
> +				size_t len, loff_t *offp, uint16_t wm[8])
>  {
>  	struct seq_file *m = file->private_data;
>  	struct drm_device *dev = m->private;
> -	uint16_t new[5] = { 0 };
> +	uint16_t new[8] = { 0 };
>  	int num_levels = ilk_wm_max_level(dev) + 1;
>  	int level;
>  	int ret;
> @@ -3598,7 +3623,9 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
>  
>  	tmp[len] = '\0';
>  
> -	ret = sscanf(tmp, "%hu %hu %hu %hu %hu", &new[0], &new[1], &new[2], &new[3], &new[4]);
> +	ret = sscanf(tmp, "%hu %hu %hu %hu %hu %hu %hu %hu",
> +		     &new[0], &new[1], &new[2], &new[3],
> +		     &new[4], &new[5], &new[6], &new[7]);
>  	if (ret != num_levels)
>  		return -EINVAL;
>  
> @@ -3618,8 +3645,15 @@ static ssize_t pri_wm_latency_write(struct file *file, const char __user *ubuf,
>  {
>  	struct seq_file *m = file->private_data;
>  	struct drm_device *dev = m->private;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	uint16_t *latencies;
>  
> -	return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.pri_latency);
> +	if (INTEL_INFO(dev)->gen >= 9)
> +		latencies = dev_priv->wm.skl_latency;
> +	else
> +		latencies = to_i915(dev)->wm.pri_latency;
> +
> +	return wm_latency_write(file, ubuf, len, offp, latencies);
>  }
>  
>  static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf,
> @@ -3627,8 +3661,15 @@ static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf,
>  {
>  	struct seq_file *m = file->private_data;
>  	struct drm_device *dev = m->private;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	uint16_t *latencies;
>  
> -	return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.spr_latency);
> +	if (INTEL_INFO(dev)->gen >= 9)
> +		latencies = dev_priv->wm.skl_latency;
> +	else
> +		latencies = to_i915(dev)->wm.spr_latency;
> +
> +	return wm_latency_write(file, ubuf, len, offp, latencies);
>  }
>  
>  static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
> @@ -3636,8 +3677,15 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
>  {
>  	struct seq_file *m = file->private_data;
>  	struct drm_device *dev = m->private;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	uint16_t *latencies;
> +
> +	if (INTEL_INFO(dev)->gen >= 9)
> +		latencies = dev_priv->wm.skl_latency;
> +	else
> +		latencies = to_i915(dev)->wm.cur_latency;
>  
> -	return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.cur_latency);
> +	return wm_latency_write(file, ubuf, len, offp, latencies);
>  }
>  
>  static const struct file_operations i915_pri_wm_latency_fops = {
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 79/89] drm/i915/skl: Read back the DDB allocation hw state
  2014-09-04 11:27 ` [PATCH 79/89] drm/i915/skl: Read back the DDB allocation hw state Damien Lespiau
@ 2014-09-19 10:54   ` Ville Syrjälä
  0 siblings, 0 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-19 10:54 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:27:45PM +0100, Damien Lespiau wrote:
> This logically belongs to the WM state, so do it there.
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index d378879..8d24a4d 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3020,6 +3020,32 @@ static unsigned int skl_cursor_allocation(struct intel_wm_config *config)
>  	return 8;
>  }
>  
> +static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg)
> +{
> +	entry->start = reg & 0x3ff;
> +	entry->end = (reg >> 16) & 0x3ff;

Would need a rebase in case the HW register is really inclusive and we
make skl_ddb_entry.end exclusive.

Apart from that 
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> +}
> +
> +static void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
> +				 struct skl_ddb_allocation *ddb /* out */)
> +{
> +	struct drm_device *dev = dev_priv->dev;
> +	enum pipe pipe;
> +	int plane;
> +	u32 val;
> +
> +	for_each_pipe(dev_priv, pipe) {
> +		for_each_plane(pipe, plane) {
> +			val = I915_READ(PLANE_BUF_CFG(pipe, plane));
> +			skl_ddb_entry_init_from_hw(&ddb->plane[pipe][plane],
> +						   val);
> +		}
> +
> +		val = I915_READ(CUR_BUF_CFG(pipe));
> +		skl_ddb_entry_init_from_hw(&ddb->cursor[pipe], val);
> +	}
> +}
> +
>  static unsigned int
>  skl_plane_relative_data_rate(struct intel_plane_wm_parameters *p)
>  {
> @@ -3810,8 +3836,11 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
>  
>  void skl_wm_get_hw_state(struct drm_device *dev)
>  {
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct skl_ddb_allocation *ddb = &dev_priv->wm.skl_hw.ddb;
>  	struct drm_crtc *crtc;
>  
> +	skl_ddb_get_hw_state(dev_priv, ddb);
>  	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
>  		skl_pipe_wm_get_hw_state(crtc);
>  }
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 08/89] drm/i915/skl: Use gen8_ring_dispatch_execbuffer() on GEN9
  2014-09-16 14:53   ` Thomas Wood
@ 2014-09-19 11:09     ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-19 11:09 UTC (permalink / raw)
  To: Thomas Wood; +Cc: Intel Graphics Development

On Tue, Sep 16, 2014 at 03:53:12PM +0100, Thomas Wood wrote:
> On 4 September 2014 12:26, Damien Lespiau <damien.lespiau@intel.com> wrote:
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_ringbuffer.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> > index f8aadc3..7b3d0ca 100644
> > --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> > +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> > @@ -2361,7 +2361,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
> >
> >         if (IS_HASWELL(dev))
> >                 ring->dispatch_execbuffer = hsw_ring_dispatch_execbuffer;
> > -       else if (IS_GEN8(dev))
> > +       else if (INTEL_INFO(dev)->gen >= 8)
> >                 ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
> >         else if (INTEL_INFO(dev)->gen >= 6)
> >                 ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
> 
> While discussing this with Damien, he mentioned that legacy ring
> buffer submission is not supported on gen 9 and perhaps
> dispatch_execbuffer should be set to null instead.

We can just drop the whole patch I guess, not expecting to run that code
on gen >= 9.

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* [PATCH 11/89 v2] drm/i915/skl: Framebuffers need to be aligned to 256KB on Skylake
  2014-09-16 14:54   ` Thomas Wood
@ 2014-09-19 11:26     ` Damien Lespiau
  2014-09-19 13:46       ` Thomas Wood
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-19 11:26 UTC (permalink / raw)
  To: intel-gfx; +Cc: thomas.wood

v2: Also align X tiled fbs to 256KB (Thomas)

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index cf51704..a48a2f3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2182,7 +2182,9 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
 
 	switch (obj->tiling_mode) {
 	case I915_TILING_NONE:
-		if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
+		if (INTEL_INFO(dev)->gen >= 9)
+			alignment = 256 * 1024;
+		else if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
 			alignment = 128 * 1024;
 		else if (INTEL_INFO(dev)->gen >= 4)
 			alignment = 4 * 1024;
@@ -2190,8 +2192,12 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
 			alignment = 64 * 1024;
 		break;
 	case I915_TILING_X:
-		/* pin() will align the object as required by fence */
-		alignment = 0;
+		if (INTEL_INFO(dev)->gen >= 9)
+			alignment = 256 * 1024;
+		else {
+			/* pin() will align the object as required by fence */
+			alignment = 0;
+		}
 		break;
 	case I915_TILING_Y:
 		WARN(1, "Y tiled bo slipped through, driver bug!\n");
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* Re: [PATCH 11/89 v2] drm/i915/skl: Framebuffers need to be aligned to 256KB on Skylake
  2014-09-19 11:26     ` [PATCH 11/89 v2] drm/i915/skl: Framebuffers need to be aligned to 256KB " Damien Lespiau
@ 2014-09-19 13:46       ` Thomas Wood
  0 siblings, 0 replies; 286+ messages in thread
From: Thomas Wood @ 2014-09-19 13:46 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

On 19 September 2014 12:26, Damien Lespiau <damien.lespiau@intel.com> wrote:
> v2: Also align X tiled fbs to 256KB (Thomas)
>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

Reviewed-by: Thomas Wood <thomas.wood@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_display.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index cf51704..a48a2f3 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2182,7 +2182,9 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
>
>         switch (obj->tiling_mode) {
>         case I915_TILING_NONE:
> -               if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
> +               if (INTEL_INFO(dev)->gen >= 9)
> +                       alignment = 256 * 1024;
> +               else if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
>                         alignment = 128 * 1024;
>                 else if (INTEL_INFO(dev)->gen >= 4)
>                         alignment = 4 * 1024;
> @@ -2190,8 +2192,12 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
>                         alignment = 64 * 1024;
>                 break;
>         case I915_TILING_X:
> -               /* pin() will align the object as required by fence */
> -               alignment = 0;
> +               if (INTEL_INFO(dev)->gen >= 9)
> +                       alignment = 256 * 1024;
> +               else {
> +                       /* pin() will align the object as required by fence */
> +                       alignment = 0;
> +               }
>                 break;
>         case I915_TILING_Y:
>                 WARN(1, "Y tiled bo slipped through, driver bug!\n");
> --
> 1.8.3.1
>

^ permalink raw reply	[flat|nested] 286+ messages in thread

* [PATCH 12/89 v8] drm/i915/skl: Implement the new update_plane() for primary planes
  2014-09-17  0:49   ` Rodrigo Vivi
@ 2014-09-22 11:18     ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-22 11:18 UTC (permalink / raw)
  To: intel-gfx; +Cc: rodrigo.vivi

Skylake makes primary planes the same as sprite planes and call the
result "universal planes".

This commit emulates a primary plane with plane 0, taking the
opportunity to redefine primary and sprite registers to be identical now
that the underlying hardware is. It also makes sense as plenty of fields
have changed.

v2: Rebase on top of the vma code.

v3: Follow upstream evolution:
- Drop return values.
- Remove pipe checks since redudant and BUG instead.
- Remove tiling checks and BUG instead.
- Drop commented out DISP_MODIFY usage.

v4: s/plane/primary_plane/

v5: Misc fixes:
- Fix the fields we need to clear up
- Disable trickle feed
- Correctly use PLANE_OFFSET for the panning

v6: (Jesse)
Use pipe src size when programming plane size. This makes cloned configs
work correctly w/o the use of a panel fitter.

v7: Rebase on top of Ville's rmw elimination series

v8: Remove clearing the trickle feed bit now that we don't do a RMW (Rodrigo,
    Damien)
    Add a comment about the stride unit (Rodrigo)

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v1,5,6,7)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v2,3)
---
 drivers/gpu/drm/i915/i915_reg.h      | 110 ++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_display.c |  92 ++++++++++++++++++++++++++++-
 2 files changed, 199 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index ad8179b..6c593d1 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -26,8 +26,8 @@
 #define _I915_REG_H_
 
 #define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a)))
+#define _PLANE(plane, a, b) _PIPE(plane, a, b)
 #define _TRANSCODER(tran, a, b) ((a) + (tran)*((b)-(a)))
-
 #define _PORT(port, a, b) ((a) + (port)*((b)-(a)))
 #define _PIPE3(pipe, a, b, c) ((pipe) == PIPE_A ? (a) : \
 			       (pipe) == PIPE_B ? (b) : (c))
@@ -4507,6 +4507,114 @@ enum punit_power_well {
 #define SPCONSTALPHA(pipe, plane) _PIPE(pipe * 2 + plane, _SPACONSTALPHA, _SPBCONSTALPHA)
 #define SPGAMC(pipe, plane) _PIPE(pipe * 2 + plane, _SPAGAMC, _SPBGAMC)
 
+/* Skylake plane registers */
+
+#define _PLANE_CTL_1_A				0x70180
+#define _PLANE_CTL_2_A				0x70280
+#define _PLANE_CTL_3_A				0x70380
+#define   PLANE_CTL_ENABLE			(1 << 31)
+#define   PLANE_CTL_PIPE_GAMMA_ENABLE		(1 << 30)
+#define   PLANE_CTL_FORMAT_MASK			(0xf << 24)
+#define   PLANE_CTL_FORMAT_YUV422		(  0 << 24)
+#define   PLANE_CTL_FORMAT_NV12			(  1 << 24)
+#define   PLANE_CTL_FORMAT_XRGB_2101010		(  2 << 24)
+#define   PLANE_CTL_FORMAT_XRGB_8888		(  4 << 24)
+#define   PLANE_CTL_FORMAT_XRGB_16161616F	(  6 << 24)
+#define   PLANE_CTL_FORMAT_AYUV			(  8 << 24)
+#define   PLANE_CTL_FORMAT_INDEXED		( 12 << 24)
+#define   PLANE_CTL_FORMAT_RGB_565		( 14 << 24)
+#define   PLANE_CTL_PIPE_CSC_ENABLE		(1 << 23)
+#define   PLANE_CTL_KEY_ENABLE			(1 << 22)
+#define   PLANE_CTL_ORDER_BGRX			(0 << 20)
+#define   PLANE_CTL_ORDER_RGBX			(1 << 20)
+#define   PLANE_CTL_YUV422_ORDER_MASK		(0x3 << 16)
+#define   PLANE_CTL_YUV422_YUYV			(  0 << 16)
+#define   PLANE_CTL_YUV422_UYVY			(  1 << 16)
+#define   PLANE_CTL_YUV422_YVYU			(  2 << 16)
+#define   PLANE_CTL_YUV422_VYUY			(  3 << 16)
+#define   PLANE_CTL_DECOMPRESSION_ENABLE	(1 << 15)
+#define   PLANE_CTL_TRICKLE_FEED_DISABLE	(1 << 14)
+#define   PLANE_CTL_PLANE_GAMMA_DISABLE		(1 << 13)
+#define   PLANE_CTL_TILED_MASK			(0x7 << 10)
+#define   PLANE_CTL_TILED_LINEAR		(  0 << 10)
+#define   PLANE_CTL_TILED_X			(  1 << 10)
+#define   PLANE_CTL_TILED_Y			(  4 << 10)
+#define   PLANE_CTL_TILED_YF			(  5 << 10)
+#define   PLANE_CTL_ALPHA_MASK			(0x3 << 4)
+#define   PLANE_CTL_ALPHA_DISABLE		(  0 << 4)
+#define   PLANE_CTL_ALPHA_SW_PREMULTIPLY	(  2 << 4)
+#define   PLANE_CTL_ALPHA_HW_PREMULTIPLY	(  3 << 4)
+#define _PLANE_STRIDE_1_A			0x70188
+#define _PLANE_STRIDE_2_A			0x70288
+#define _PLANE_STRIDE_3_A			0x70388
+#define _PLANE_POS_1_A				0x7018c
+#define _PLANE_POS_2_A				0x7028c
+#define _PLANE_POS_3_A				0x7038c
+#define _PLANE_SIZE_1_A				0x70190
+#define _PLANE_SIZE_2_A				0x70290
+#define _PLANE_SIZE_3_A				0x70390
+#define _PLANE_SURF_1_A				0x7019c
+#define _PLANE_SURF_2_A				0x7029c
+#define _PLANE_SURF_3_A				0x7039c
+#define _PLANE_OFFSET_1_A			0x701a4
+#define _PLANE_OFFSET_2_A			0x702a4
+#define _PLANE_OFFSET_3_A			0x703a4
+
+#define _PLANE_CTL_1_B				0x71180
+#define _PLANE_CTL_2_B				0x71280
+#define _PLANE_CTL_3_B				0x71380
+#define _PLANE_CTL_1(pipe)	_PIPE(pipe, _PLANE_CTL_1_A, _PLANE_CTL_1_B)
+#define _PLANE_CTL_2(pipe)	_PIPE(pipe, _PLANE_CTL_2_A, _PLANE_CTL_2_B)
+#define _PLANE_CTL_3(pipe)	_PIPE(pipe, _PLANE_CTL_3_A, _PLANE_CTL_3_B)
+#define PLANE_CTL(pipe, plane)	\
+	_PLANE(plane, _PLANE_CTL_1(pipe), _PLANE_CTL_2(pipe))
+
+#define _PLANE_STRIDE_1_B			0x71188
+#define _PLANE_STRIDE_2_B			0x71288
+#define _PLANE_STRIDE_3_B			0x71388
+#define _PLANE_STRIDE_1(pipe)	\
+	_PIPE(pipe, _PLANE_STRIDE_1_A, _PLANE_STRIDE_1_B)
+#define _PLANE_STRIDE_2(pipe)	\
+	_PIPE(pipe, _PLANE_STRIDE_2_A, _PLANE_STRIDE_2_B)
+#define _PLANE_STRIDE_3(pipe)	\
+	_PIPE(pipe, _PLANE_STRIDE_3_A, _PLANE_STRIDE_3_B)
+#define PLANE_STRIDE(pipe, plane)	\
+	_PLANE(plane, _PLANE_STRIDE_1(pipe), _PLANE_STRIDE_2(pipe))
+
+#define _PLANE_POS_1_B				0x7118c
+#define _PLANE_POS_2_B				0x7128c
+#define _PLANE_POS_3_B				0x7138c
+#define _PLANE_POS_1(pipe)	_PIPE(pipe, _PLANE_POS_1_A, _PLANE_POS_1_B)
+#define _PLANE_POS_2(pipe)	_PIPE(pipe, _PLANE_POS_2_A, _PLANE_POS_2_B)
+#define _PLANE_POS_3(pipe)	_PIPE(pipe, _PLANE_POS_3_A, _PLANE_POS_3_B)
+#define PLANE_POS(pipe, plane)	\
+	_PLANE(plane, _PLANE_POS_1(pipe), _PLANE_POS_2(pipe))
+
+#define _PLANE_SIZE_1_B				0x71190
+#define _PLANE_SIZE_2_B				0x71290
+#define _PLANE_SIZE_3_B				0x71390
+#define _PLANE_SIZE_1(pipe)	_PIPE(pipe, _PLANE_SIZE_1_A, _PLANE_SIZE_1_B)
+#define _PLANE_SIZE_2(pipe)	_PIPE(pipe, _PLANE_SIZE_2_A, _PLANE_SIZE_2_B)
+#define _PLANE_SIZE_3(pipe)	_PIPE(pipe, _PLANE_SIZE_3_A, _PLANE_SIZE_3_B)
+#define PLANE_SIZE(pipe, plane)	\
+	_PLANE(plane, _PLANE_SIZE_1(pipe), _PLANE_SIZE_2(pipe))
+
+#define _PLANE_SURF_1_B				0x7119c
+#define _PLANE_SURF_2_B				0x7129c
+#define _PLANE_SURF_3_B				0x7139c
+#define _PLANE_SURF_1(pipe)	_PIPE(pipe, _PLANE_SURF_1_A, _PLANE_SURF_1_B)
+#define _PLANE_SURF_2(pipe)	_PIPE(pipe, _PLANE_SURF_2_A, _PLANE_SURF_2_B)
+#define _PLANE_SURF_3(pipe)	_PIPE(pipe, _PLANE_SURF_3_A, _PLANE_SURF_3_B)
+#define PLANE_SURF(pipe, plane)	\
+	_PLANE(plane, _PLANE_SURF_1(pipe), _PLANE_SURF_2(pipe))
+
+#define _PLANE_OFFSET_1_B			0x711a4
+#define _PLANE_OFFSET_2_B			0x712a4
+#define _PLANE_OFFSET_1(pipe) _PIPE(pipe, _PLANE_OFFSET_1_A, _PLANE_OFFSET_1_B)
+#define _PLANE_OFFSET_2(pipe) _PIPE(pipe, _PLANE_OFFSET_2_A, _PLANE_OFFSET_2_B)
+#define PLANE_OFFSET(pipe, plane)	\
+	_PLANE(plane, _PLANE_OFFSET_1(pipe), _PLANE_OFFSET_2(pipe))
+
 /* VBIOS regs */
 #define VGACNTRL		0x71400
 # define VGA_DISP_DISABLE			(1 << 31)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a48a2f3..d5ee56d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2627,6 +2627,90 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
 	POSTING_READ(reg);
 }
 
+static void skylake_update_primary_plane(struct drm_crtc *crtc,
+					 struct drm_framebuffer *fb,
+					 int x, int y)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_framebuffer *intel_fb;
+	struct drm_i915_gem_object *obj;
+	int pipe = intel_crtc->pipe;
+	u32 plane_ctl, stride;
+
+	if (!intel_crtc->primary_enabled) {
+		I915_WRITE(PLANE_CTL(pipe, 0), 0);
+		I915_WRITE(PLANE_SURF(pipe, 0), 0);
+		POSTING_READ(PLANE_CTL(pipe, 0));
+		return;
+	}
+
+	plane_ctl = PLANE_CTL_ENABLE |
+		    PLANE_CTL_PIPE_GAMMA_ENABLE |
+		    PLANE_CTL_PIPE_CSC_ENABLE;
+
+	switch (fb->pixel_format) {
+	case DRM_FORMAT_RGB565:
+		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
+		break;
+	case DRM_FORMAT_XRGB8888:
+		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
+		break;
+	case DRM_FORMAT_XBGR8888:
+		plane_ctl |= PLANE_CTL_ORDER_RGBX;
+		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
+		break;
+	case DRM_FORMAT_XRGB2101010:
+		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
+		break;
+	case DRM_FORMAT_XBGR2101010:
+		plane_ctl |= PLANE_CTL_ORDER_RGBX;
+		plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010;
+		break;
+	default:
+		BUG();
+	}
+
+	intel_fb = to_intel_framebuffer(fb);
+	obj = intel_fb->obj;
+
+	/*
+	 * The stride is either expressed as a multiple of 64 bytes chunks for
+	 * linear buffers or in number of tiles for tiled buffers.
+	 */
+	switch (obj->tiling_mode) {
+	case I915_TILING_NONE:
+		stride = fb->pitches[0] >> 6;
+		break;
+	case I915_TILING_X:
+		plane_ctl |= PLANE_CTL_TILED_X;
+		stride = fb->pitches[0] >> 9;
+		break;
+	default:
+		BUG();
+	}
+
+	plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
+
+	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
+
+	DRM_DEBUG_KMS("Writing base %08lX %d,%d,%d,%d pitch=%d\n",
+		      i915_gem_obj_ggtt_offset(obj),
+		      x, y, fb->width, fb->height,
+		      fb->pitches[0]);
+
+	I915_WRITE(PLANE_POS(pipe, 0), 0);
+	I915_WRITE(PLANE_OFFSET(pipe, 0), (y << 16) | x);
+	I915_WRITE(PLANE_SIZE(pipe, 0),
+		   (intel_crtc->config.pipe_src_h - 1) << 16 |
+		   (intel_crtc->config.pipe_src_w - 1));
+	I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
+	I915_WRITE(PLANE_SURF(pipe, 0), i915_gem_obj_ggtt_offset(obj));
+
+	POSTING_READ(PLANE_SURF(pipe, 0));
+}
+
 /* Assume fb object is pinned & idle & fenced and just update base pointers */
 static int
 intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
@@ -12642,8 +12726,12 @@ static void intel_init_display(struct drm_device *dev)
 		dev_priv->display.crtc_enable = haswell_crtc_enable;
 		dev_priv->display.crtc_disable = haswell_crtc_disable;
 		dev_priv->display.off = ironlake_crtc_off;
-		dev_priv->display.update_primary_plane =
-			ironlake_update_primary_plane;
+		if (INTEL_INFO(dev)->gen >= 9)
+			dev_priv->display.update_primary_plane =
+				skylake_update_primary_plane;
+		else
+			dev_priv->display.update_primary_plane =
+				ironlake_update_primary_plane;
 	} else if (HAS_PCH_SPLIT(dev)) {
 		dev_priv->display.get_pipe_config = ironlake_get_pipe_config;
 		dev_priv->display.get_plane_config = ironlake_get_plane_config;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* Re: [PATCH 54/89] drm/i915/skl: Enable Gen9 RC6
  2014-09-04 11:27 ` [PATCH 54/89] drm/i915/skl: Enable Gen9 RC6 Damien Lespiau
@ 2014-09-22 13:15   ` Mika Kuoppala
  2014-09-24 17:58     ` Bob Wang
  0 siblings, 1 reply; 286+ messages in thread
From: Mika Kuoppala @ 2014-09-22 13:15 UTC (permalink / raw)
  To: Damien Lespiau, intel-gfx

Damien Lespiau <damien.lespiau@intel.com> writes:

> From: Zhe Wang <zhe1.wang@intel.com>
>
> Configure and enable RC6 for Gen9.
>
> v2: Rebase on top of BDW rc6 support (Damien)
>
> Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 52 ++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index fdf297f..74a8519 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4332,6 +4332,13 @@ static void gen8_disable_rps_interrupts(struct drm_device *dev)
>  	}
>  }
>  
> +static void gen9_disable_rps(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +
> +	I915_WRITE(GEN6_RC_CONTROL, 0);
> +}
> +
>  static void gen6_disable_rps_interrupts(struct drm_device *dev)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -4579,6 +4586,45 @@ void bdw_software_turbo(struct drm_device *dev)
>  			&current_time, &current_c0);
>  }
>  
> +static void gen9_enable_rps(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_engine_cs *ring;
> +	uint32_t rc6_mask = 0;
> +	int unused;
> +
> +	/* 1a: Software RC state - RC0 */
> +	I915_WRITE(GEN6_RC_STATE, 0);
> +
> +	/* 1b: Get forcewake during program sequence. Although the driver
> +	 * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
> +	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
> +
> +	/* 2a: Disable RC states. */
> +	I915_WRITE(GEN6_RC_CONTROL, 0);
> +
> +	/* 2b: Program RC6 thresholds.*/
> +	I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);

40 << 16

> +	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
> +	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
> +	for_each_ring(ring, dev_priv, unused)
> +		I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
> +	I915_WRITE(GEN6_RC_SLEEP, 0);
> +	I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */

50000 50ms/125ms per EI

> +
> +	/* 3a: Enable RC6 */
> +	if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
> +		rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
> +	DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
> +			"on" : "off");
> +	I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
> +				   GEN6_RC_CTL_EI_MODE(1) |
> +				   rc6_mask);
> +
> +	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
> +
> +}
> +
>  static void gen8_enable_rps(struct drm_device *dev)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -6158,7 +6204,9 @@ void intel_disable_gt_powersave(struct drm_device *dev)
>  		intel_suspend_gt_powersave(dev);
>  
>  		mutex_lock(&dev_priv->rps.hw_lock);
> -		if (IS_CHERRYVIEW(dev))
> +		if (INTEL_INFO(dev)->gen >= 9)
> +			gen9_disable_rps(dev);
> +		else if (IS_CHERRYVIEW(dev))
>  			cherryview_disable_rps(dev);
>  		else if (IS_VALLEYVIEW(dev))
>  			valleyview_disable_rps(dev);
> @@ -6184,6 +6232,8 @@ static void intel_gen6_powersave_work(struct work_struct *work)
>  		cherryview_enable_rps(dev);
>  	} else if (IS_VALLEYVIEW(dev)) {
>  		valleyview_enable_rps(dev);
> +	} else if (INTEL_INFO(dev)->gen >= 9) {
> +		gen9_enable_rps(dev);
>  	} else if (IS_BROADWELL(dev)) {
>  		gen8_enable_rps(dev);
>  		__gen6_update_ring_freq(dev);
> -- 
> 1.8.3.1

I couldn't find out if those values suggested are newer than the values
in this patch. We need to visit this are when we are wiser.

Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>

> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 21/89] drm/i915/skl: Implement the get_aux_clock_divider() DP vfunc
  2014-09-17  1:12   ` Rodrigo Vivi
@ 2014-09-22 13:21     ` Damien Lespiau
  2014-09-22 19:33       ` Rodrigo Vivi
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-22 13:21 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Tue, Sep 16, 2014 at 06:12:04PM -0700, Rodrigo Vivi wrote:
>    I believe this patch should remove the gen9 part of
>    ilk_get_aux_clock_divider.

The previous patch changing ilk_get_aux_clock_divider() got removed
entirely.

>    Also there it just returns 0, but here it returns 0 or 1 depending on the
>    index.
>    This also is incoherent with the commit description.

Yes, when the index is 0, we need to return a non 0 value (chose 1) to
have the code using this vfunc loop once. Then, when the index is
incremented, we return 0 to stop the loop.

-- 
Damien

>    On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
>    wrote:
> 
>      We need to provide a vfunc that will make the code in intel_dp_aux_ch()
>      loop once to start the AUX transaction. The return value (clock divider)
>      is unused on SKL, so just return 1.
> 
>      Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
>      ---
>       drivers/gpu/drm/i915/intel_dp.c | 14 +++++++++++++-
>       1 file changed, 13 insertions(+), 1 deletion(-)
> 
>      diff --git a/drivers/gpu/drm/i915/intel_dp.c
>      b/drivers/gpu/drm/i915/intel_dp.c
>      index a95fb47..4560ced 100644
>      --- a/drivers/gpu/drm/i915/intel_dp.c
>      +++ b/drivers/gpu/drm/i915/intel_dp.c
>      @@ -489,6 +489,16 @@ static uint32_t vlv_get_aux_clock_divider(struct
>      intel_dp *intel_dp, int index)
>              return index ? 0 : 100;
>       }
> 
>      +static uint32_t skl_get_aux_clock_divider(struct intel_dp *intel_dp,
>      int index)
>      +{
>      +       /*
>      +        * SKL doesn't need us to program the AUX clock divider
>      (Hardware will
>      +        * derive the clock from CDCLK automatically). We still
>      implement the
>      +        * get_aux_clock_divider vfunc to plug-in into the existing
>      code.
>      +        */
>      +       return index ? 0 : 1;
>      +}
>      +
>       static uint32_t i9xx_get_aux_send_ctl(struct intel_dp *intel_dp,
>                                            bool has_aux_irq,
>                                            int send_bytes,
>      @@ -4726,7 +4736,9 @@ intel_dp_init_connector(struct intel_digital_port
>      *intel_dig_port,
>              int type;
> 
>              /* intel_dp vfuncs */
>      -       if (IS_VALLEYVIEW(dev))
>      +       if (INTEL_INFO(dev)->gen >= 9)
>      +               intel_dp->get_aux_clock_divider =
>      skl_get_aux_clock_divider;
>      +       else if (IS_VALLEYVIEW(dev))
>                      intel_dp->get_aux_clock_divider =
>      vlv_get_aux_clock_divider;
>              else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>                      intel_dp->get_aux_clock_divider =
>      hsw_get_aux_clock_divider;
>      --
>      1.8.3.1
> 
>      _______________________________________________
>      Intel-gfx mailing list
>      Intel-gfx@lists.freedesktop.org
>      http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
>    --
>    Rodrigo Vivi
>    Blog: http://blog.vivi.eng.br
>     

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 24/89] drm/i915/skl: Allow the reg_read ioctl to return RCS_TIMESTAMP
  2014-09-17  1:27   ` Rodrigo Vivi
@ 2014-09-22 13:27     ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-22 13:27 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Tue, Sep 16, 2014 at 06:27:04PM -0700, Rodrigo Vivi wrote:
>    This seems to allow more than just the RCS timestamp, but also allow
>    the I915_REG_READ ioctl for gen9.

Well, yes, this array is the white list for the reg_read ioctl, so
that's expected.

>    Anyway:
>    Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
>    On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
>    wrote:
> 
>      Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
>      ---
>       drivers/gpu/drm/i915/intel_uncore.c | 2 +-
>       1 file changed, 1 insertion(+), 1 deletion(-)
> 
>      diff --git a/drivers/gpu/drm/i915/intel_uncore.c
>      b/drivers/gpu/drm/i915/intel_uncore.c
>      index 918b761..3b27fb0 100644
>      --- a/drivers/gpu/drm/i915/intel_uncore.c
>      +++ b/drivers/gpu/drm/i915/intel_uncore.c
>      @@ -968,7 +968,7 @@ static const struct register_whitelist {
>              /* supported gens, 0x10 for 4, 0x30 for 4 and 5, etc. */
>              uint32_t gen_bitmask;
>       } whitelist[] = {
>      -       { RING_TIMESTAMP(RENDER_RING_BASE), 8, GEN_RANGE(4, 8) },
>      +       { RING_TIMESTAMP(RENDER_RING_BASE), 8, GEN_RANGE(4, 9) },
>       };
> 
>       int i915_reg_read_ioctl(struct drm_device *dev,
>      --
>      1.8.3.1
> 
>      _______________________________________________
>      Intel-gfx mailing list
>      Intel-gfx@lists.freedesktop.org
>      http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
>    --
>    Rodrigo Vivi
>    Blog: http://blog.vivi.eng.br
>     

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 29/89] drm/i915/skl: vfuncs for skl eld and global resource
  2014-09-17  1:50   ` Rodrigo Vivi
@ 2014-09-22 13:32     ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-22 13:32 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Tue, Sep 16, 2014 at 06:50:47PM -0700, Rodrigo Vivi wrote:
>    isn't fdi_link_training needed?

No, it's not. SKL doesn't have FDI.

-- 
Damien

>    if not: Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
>    On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
>    wrote:
> 
>      From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> 
>      Set gen 9 function pointers for eld write and global resource.
>      Implementation remains same as HSW.
> 
>      v2: Rebase on top of Sonika's untangling of the if/else ladder (Damien)
> 
>      Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v1)
>      Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
>      ---
>       drivers/gpu/drm/i915/intel_display.c | 4 ++++
>       1 file changed, 4 insertions(+)
> 
>      diff --git a/drivers/gpu/drm/i915/intel_display.c
>      b/drivers/gpu/drm/i915/intel_display.c
>      index bffabfd..48d2d0d 100644
>      --- a/drivers/gpu/drm/i915/intel_display.c
>      +++ b/drivers/gpu/drm/i915/intel_display.c
>      @@ -12654,6 +12654,10 @@ static void intel_init_display(struct
>      drm_device *dev)
>                      dev_priv->display.modeset_global_resources =
>                              valleyview_modeset_global_resources;
>                      dev_priv->display.write_eld = ironlake_write_eld;
>      +       } else if (INTEL_INFO(dev)->gen >= 9) {
>      +               dev_priv->display.write_eld = haswell_write_eld;
>      +               dev_priv->display.modeset_global_resources =
>      +                       haswell_modeset_global_resources;
>              }
> 
>              /* Default just returns -ENODEV to indicate unsupported */
>      --
>      1.8.3.1
> 
>      _______________________________________________
>      Intel-gfx mailing list
>      Intel-gfx@lists.freedesktop.org
>      http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
>    --
>    Rodrigo Vivi
>    Blog: http://blog.vivi.eng.br
>     

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 32/89] drm/i915/skl: Adjust the display engine interrupts
  2014-09-17 18:41     ` Rodrigo Vivi
@ 2014-09-22 13:38       ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-22 13:38 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Wed, Sep 17, 2014 at 11:41:54AM -0700, Rodrigo Vivi wrote:
>    Oh cool here are the actual fixes on de_pipe int bits! 
>    I agree with Daniel that a separated function would be better, but what is
>    here is right anyway so

Took a note about that. Will have to wait for when the situation has
settled down a bit.

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 33/89] drm/i915/skl: Sunrise Point PCH detection
  2014-09-17 22:18   ` Rodrigo Vivi
@ 2014-09-22 13:42     ` Damien Lespiau
  2014-09-22 19:34       ` Rodrigo Vivi
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-22 13:42 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Wed, Sep 17, 2014 at 03:18:21PM -0700, Rodrigo Vivi wrote:
>    Where can I find these pch device id definitions?

You'll have to trust Satheesh on that, it's not something we have
documented in the GPU specs.

-- 
Damien

>    On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <damien.lespiau@intel.com>
>    wrote:
> 
>      From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> 
>      This patch implements detection of SPT and SPT-LP PCH devices.
> 
>      v2: Added HAS_PCH_SPT macro
> 
>      Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>      Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
>      ---
>       drivers/gpu/drm/i915/i915_drv.c | 10 ++++++++++
>       drivers/gpu/drm/i915/i915_drv.h |  4 ++++
>       2 files changed, 14 insertions(+)
> 
>      diff --git a/drivers/gpu/drm/i915/i915_drv.c
>      b/drivers/gpu/drm/i915/i915_drv.c
>      index 3d7f823..c6a8a80 100644
>      --- a/drivers/gpu/drm/i915/i915_drv.c
>      +++ b/drivers/gpu/drm/i915/i915_drv.c
>      @@ -475,6 +475,16 @@ void intel_detect_pch(struct drm_device *dev)
>                                      DRM_DEBUG_KMS("Found LynxPoint LP
>      PCH\n");
>                                      WARN_ON(!IS_HASWELL(dev));
>                                      WARN_ON(!IS_ULT(dev));
>      +                       } else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) {
>      +                               dev_priv->pch_type = PCH_SPT;
>      +                               DRM_DEBUG_KMS("Found SunrisePoint
>      PCH\n");
>      +                               WARN_ON(!IS_SKYLAKE(dev));
>      +                               WARN_ON(IS_ULT(dev));
>      +                       } else if (id ==
>      INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) {
>      +                               dev_priv->pch_type = PCH_SPT;
>      +                               DRM_DEBUG_KMS("Found SunrisePoint LP
>      PCH\n");
>      +                               WARN_ON(!IS_SKYLAKE(dev));
>      +                               WARN_ON(!IS_ULT(dev));
>                              } else
>                                      continue;
> 
>      diff --git a/drivers/gpu/drm/i915/i915_drv.h
>      b/drivers/gpu/drm/i915/i915_drv.h
>      index cf4fc86..be82888 100644
>      --- a/drivers/gpu/drm/i915/i915_drv.h
>      +++ b/drivers/gpu/drm/i915/i915_drv.h
>      @@ -699,6 +699,7 @@ enum intel_pch {
>              PCH_IBX,        /* Ibexpeak PCH */
>              PCH_CPT,        /* Cougarpoint PCH */
>              PCH_LPT,        /* Lynxpoint PCH */
>      +       PCH_SPT,        /* Sunrisepoint PCH */
>              PCH_NOP,
>       };
> 
>      @@ -2184,8 +2185,11 @@ struct drm_i915_cmd_table {
>       #define INTEL_PCH_PPT_DEVICE_ID_TYPE           0x1e00
>       #define INTEL_PCH_LPT_DEVICE_ID_TYPE           0x8c00
>       #define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE                0x9c00
>      +#define INTEL_PCH_SPT_DEVICE_ID_TYPE           0xA100
>      +#define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE                0x9D00
> 
>       #define INTEL_PCH_TYPE(dev) (to_i915(dev)->pch_type)
>      +#define HAS_PCH_SPT(dev) (INTEL_PCH_TYPE(dev) == PCH_SPT)
>       #define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT)
>       #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
>       #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX)
>      --
>      1.8.3.1
> 
>      _______________________________________________
>      Intel-gfx mailing list
>      Intel-gfx@lists.freedesktop.org
>      http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
>    --
>    Rodrigo Vivi
>    Blog: http://blog.vivi.eng.br
>     

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 35/89] drm/i915/skl: Implement Wa4x4STCOptimizationDisable:skl
  2014-09-17 19:00     ` Rodrigo Vivi
@ 2014-09-22 13:49       ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-22 13:49 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Wed, Sep 17, 2014 at 12:00:39PM -0700, Rodrigo Vivi wrote:
>    Although I believe that we could have a init_workaround function for skl
>    as we have for bdw and chv

FWIW, the W/A code is in a confusing state right now, with at least two
people working on it. I'd like to wait a bit before things settle and
have a full W/A pass at that point.

-- 
Damien

>    On Wed, Sep 17, 2014 at 12:00 PM, Rodrigo Vivi <rodrigo.vivi@gmail.com>
>    wrote:
> 
>      Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
>      On Thu, Sep 4, 2014 at 4:27 AM, Damien Lespiau
>      <damien.lespiau@intel.com> wrote:
> 
>        Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
>        ---
>         drivers/gpu/drm/i915/intel_pm.c | 4 ++++
>         1 file changed, 4 insertions(+)
> 
>        diff --git a/drivers/gpu/drm/i915/intel_pm.c
>        b/drivers/gpu/drm/i915/intel_pm.c
>        index 0dc148c..c38baea 100644
>        --- a/drivers/gpu/drm/i915/intel_pm.c
>        +++ b/drivers/gpu/drm/i915/intel_pm.c
>        @@ -76,6 +76,10 @@ static void gen9_init_clock_gating(struct
>        drm_device *dev)
>                 */
>                I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
>                           GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
>        +
>        +       /* Wa4x4STCOptimizationDisable:skl */
>        +       I915_WRITE(CACHE_MODE_1,
>        +                 
>        _MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE));
>         }
> 
>         static void i8xx_disable_fbc(struct drm_device *dev)
>        --
>        1.8.3.1
> 
>        _______________________________________________
>        Intel-gfx mailing list
>        Intel-gfx@lists.freedesktop.org
>        http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
>      --
>      Rodrigo Vivi
>      Blog: http://blog.vivi.eng.br
>       
> 
>    --
>    Rodrigo Vivi
>    Blog: http://blog.vivi.eng.br
>     

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 45/89] drm/i915/skl: Definition of SKL WM param structs for pipe/plane
  2014-09-17 15:59       ` Daniel Vetter
@ 2014-09-22 14:00         ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-22 14:00 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Wed, Sep 17, 2014 at 05:59:24PM +0200, Daniel Vetter wrote:
> On Wed, Sep 17, 2014 at 02:59:00PM +0100, Damien Lespiau wrote:
> > On Wed, Sep 10, 2014 at 09:39:53PM +0300, Ville Syrjälä wrote:
> > > > +struct skl_wm_values {
> > > > +	bool dirty[I915_MAX_PIPES];
> > > > +	uint32_t wm_linetime[I915_MAX_PIPES];
> > > > +	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
> > > > +	uint32_t cursor[I915_MAX_PIPES][8];
> > > > +	uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
> > > > +	uint32_t cursor_trans[I915_MAX_PIPES];
> > > > +};
> > > 
> > > These multi dimensional arrays hurt my eyes. Maybe we should restructure
> > > this a bit to eg:
> > > 
> > > struct skl_wm_values {
> > > 	struct {
> > > 		wm_linetime;
> > > 		plane[MAX_PLANES][8];
> > > 		...
> > > 	} pipe[MAX_PIPES];
> > > };
> > > 
> > > The two dimensional plane[][] array is still a bit nasty, but maybe we
> > > can live with it.
> > > 
> > > We could also do the same operatiob for the ilk version to keep stuff
> > > similar.
> > > 
> > > > +
> > > > +struct skl_wm_level {
> > > > +	bool plane_en[I915_MAX_PLANES];
> > > > +	uint16_t plane_res_b[I915_MAX_PLANES];
> > > > +	uint8_t plane_res_l[I915_MAX_PLANES];
> > > 
> > > This stuff could also look better as an array of struct of some sort.
> > > Also should probably put the bool and uint8_t next to each other in case
> > > gcc is smart enough to pack things more tightly.
> > > 
> > > > +	bool cursor_en;
> > > > +	uint16_t cursor_res_b;
> > > > +	uint8_t cursor_res_l;
> > > 
> > > And this could also be an instance of the same struct use for the proper
> > > planes.
> > > 
> > > > +struct skl_pipe_wm_parameters {
> > > > +	bool active;
> > > > +	uint32_t pipe_htotal;
> > > > +	uint32_t pixel_rate; /* in KHz */
> > > > +	struct intel_plane_wm_parameters plane[I915_MAX_PLANES];
> > > > +	struct intel_plane_wm_parameters cursor;
> > > > +};
> > > 
> > > I suppose we just need to start using some kind of named indexes for the
> > > planes on all platforms so we can unify all this stuff. But that can be
> > > done when we have all the code merged so we can better see how to unify
> > > things.
> > 
> > For all those comments, the issue here is that changing something in
> > those definitions has consequences in 10/15 patches that will need to be
> > changed. Rather painful. It'd be much easier to do those change once we
> > have that code upstream, on top. As far as I can see there are minor-ish
> > improvements over what's here.
> > 
> > I've added an item in my post-merge plan. Sounds like an acceptable
> > plan?
> 
> Sounds good to me, atm all the plane config tracking is seriously all
> in-flight anyway ...

Is this patch worthy of your r-b tag then Ville?

Thanks,

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 45/89] drm/i915/skl: Definition of SKL WM param structs for pipe/plane
  2014-09-04 11:27 ` [PATCH 45/89] drm/i915/skl: Definition of SKL WM param structs for pipe/plane Damien Lespiau
  2014-09-10 18:39   ` Ville Syrjälä
@ 2014-09-22 14:06   ` Ville Syrjälä
  2014-09-22 14:21     ` Damien Lespiau
  1 sibling, 1 reply; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-22 14:06 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx, Pradeep Bhat

On Thu, Sep 04, 2014 at 12:27:11PM +0100, Damien Lespiau wrote:
> From: Pradeep Bhat <pradeep.bhat@intel.com>
> 
> This patch defines the structures needed for computation of
> watermarks of pipes and planes for SKL.
> 
> v2: Incorporated Damien's review comments and removed unused fields
>     in structs for future features like rotation, drrs and scaling.
>     The skl_wm_values struct is now made more generic across planes
>     and cursor planes for all pipes.
> 
> v3: implemented the plane/cursor split.
> 
> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h  | 18 ++++++++++++++++++
>  drivers/gpu/drm/i915/intel_drv.h | 10 +++++++++-
>  drivers/gpu/drm/i915/intel_pm.c  |  8 ++++++++
>  3 files changed, 35 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 32be299..3764ad5 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1381,6 +1381,24 @@ struct ilk_wm_values {
>  	enum intel_ddb_partitioning partitioning;
>  };
>  
> +struct skl_wm_values {
> +	bool dirty[I915_MAX_PIPES];
> +	uint32_t wm_linetime[I915_MAX_PIPES];
> +	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
> +	uint32_t cursor[I915_MAX_PIPES][8];
> +	uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
> +	uint32_t cursor_trans[I915_MAX_PIPES];
> +};
> +
> +struct skl_wm_level {
> +	bool plane_en[I915_MAX_PLANES];
> +	uint16_t plane_res_b[I915_MAX_PLANES];
> +	uint8_t plane_res_l[I915_MAX_PLANES];
> +	bool cursor_en;
> +	uint16_t cursor_res_b;
> +	uint8_t cursor_res_l;
> +};
> +
>  /*
>   * This struct helps tracking the state needed for runtime PM, which puts the
>   * device in PCI D3 state. Notice that when this happens, nothing on the
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 3239e58..268087f 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -387,6 +387,12 @@ struct intel_mmio_flip {
>  	u32 ring_id;
>  };
>  
> +struct skl_pipe_wm {
> +	struct skl_wm_level wm[8];
> +	struct skl_wm_level trans_wm;
> +	uint32_t linetime;
> +};
> +
>  struct intel_crtc {
>  	struct drm_crtc base;
>  	enum pipe pipe;
> @@ -431,9 +437,11 @@ struct intel_crtc {
>  	bool pch_fifo_underrun_disabled;
>  
>  	/* per-pipe watermark state */
> -	struct {
> +	union {

I almost gave my r-b, but then I noticed this. It's going to mess up my
pending watermark series. I'm going to add tons of junk here, so union
is not really acceptable for me. Needs some other solution.


>  		/* watermarks currently being used  */
>  		struct intel_pipe_wm active;
> +		/* SKL wm values currently in use */
> +		struct skl_pipe_wm skl_active;
>  	} wm;
>  
>  	int scanline_offset;
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index d8c8531..2503ab9 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -1928,6 +1928,14 @@ static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels,
>  	return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2;
>  }
>  
> +struct skl_pipe_wm_parameters {
> +	bool active;
> +	uint32_t pipe_htotal;
> +	uint32_t pixel_rate; /* in KHz */
> +	struct intel_plane_wm_parameters plane[I915_MAX_PLANES];
> +	struct intel_plane_wm_parameters cursor;
> +};
> +
>  struct ilk_pipe_wm_parameters {
>  	bool active;
>  	uint32_t pipe_htotal;
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 46/89] drm/i915/skl: Add DDB allocation management structures
  2014-09-17 10:47   ` Ville Syrjälä
@ 2014-09-22 14:08     ` Damien Lespiau
  2014-09-22 18:26       ` Ville Syrjälä
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-22 14:08 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Wed, Sep 17, 2014 at 01:47:54PM +0300, Ville Syrjälä wrote:
> On Thu, Sep 04, 2014 at 12:27:12PM +0100, Damien Lespiau wrote:
> > We now need to allocate space in the DDB for planes being scanned out
> > ourselves. The data structure to represent an allocation mirrors what
> > we'll need to write in the registers later on: (start, end).
> > 
> > We add that allocation datat to the skl_wm_values structure as part of
> > the values to program the hardware with.
> > 
> > v2: Split planes and cursor for consistency.
> > 
> > v3: Make the skl_ddb_entry_size() parameter const
> > 
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h | 19 +++++++++++++++++++
> >  1 file changed, 19 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 3764ad5..de278a5 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -1381,8 +1381,27 @@ struct ilk_wm_values {
> >  	enum intel_ddb_partitioning partitioning;
> >  };
> >  
> > +struct skl_ddb_entry {
> > +	uint16_t start, end;	/* in number of blocks */
> > +};
> > +
> > +static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry)
> > +{
> > +	/* end not set, clearly no allocation here. start can be 0 though */
> > +	if (entry->end == 0)
> > +		return 0;
> > +
> > +	return entry->end - entry->start + 1;
> 
> I would make 'end' exclusive as that allows you to represent an empty
> block more naturally, and you don't have to worry about the +/-1 adjustments
> when going between start/end and start/size representation.

The values we program in the registers are inclusive (I had a bug where
the end of one plane and the start of another plane had the same value
and artefacts could be seen, due to the pipes fetching from overlapping
DDB space). I took the option of having those values mirror what we need
to program. Hopefully the small functions around the skl_ddb_entry
structure doesn't make it too bad?

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 45/89] drm/i915/skl: Definition of SKL WM param structs for pipe/plane
  2014-09-22 14:06   ` Ville Syrjälä
@ 2014-09-22 14:21     ` Damien Lespiau
  2014-09-23  8:16       ` Daniel Vetter
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-22 14:21 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, Pradeep Bhat

On Mon, Sep 22, 2014 at 05:06:11PM +0300, Ville Syrjälä wrote:
> > +struct skl_pipe_wm {
> > +	struct skl_wm_level wm[8];
> > +	struct skl_wm_level trans_wm;
> > +	uint32_t linetime;
> > +};
> > +
> >  struct intel_crtc {
> >  	struct drm_crtc base;
> >  	enum pipe pipe;
> > @@ -431,9 +437,11 @@ struct intel_crtc {
> >  	bool pch_fifo_underrun_disabled;
> >  
> >  	/* per-pipe watermark state */
> > -	struct {
> > +	union {
> 
> I almost gave my r-b, but then I noticed this. It's going to mess up my
> pending watermark series. I'm going to add tons of junk here, so union
> is not really acceptable for me. Needs some other solution.

Well, you could use an anonymous structure in that union? We could also
try to merge skl_pipe_wm and intel_pipe_wm at a later point? or just
leaving this a struct, wasting a tiny bit of memory be good enough for
now?

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 55/89] drm/i915/skl: Gen9 multi-engine forcewake
  2014-09-04 11:27 ` [PATCH 55/89] drm/i915/skl: Gen9 multi-engine forcewake Damien Lespiau
@ 2014-09-22 15:11   ` Mika Kuoppala
  2014-09-24 18:08     ` Bob Wang
  0 siblings, 1 reply; 286+ messages in thread
From: Mika Kuoppala @ 2014-09-22 15:11 UTC (permalink / raw)
  To: Damien Lespiau, intel-gfx

Damien Lespiau <damien.lespiau@intel.com> writes:

> From: Zhe Wang <zhe1.wang@intel.com>
>
> Enable multi-engine forcewake for Gen9.
>
> v2: Rebase on top of nightly
>     Move the register range definitions to intel_uncore.c
>     Whitespace fixes
>     (Damien)
>
> Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_uncore.c | 120 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 120 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 7b7fc9e..f289f4f 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -674,6 +674,34 @@ void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
>  	 REG_RANGE((reg), 0x14000, 0x14400) || \
>  	 REG_RANGE((reg), 0x22000, 0x24000))
>  
> +#define FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) \
> +	((reg) >= 0xC00 && (reg) < 0x2000)
> +
> +#define FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) \
> +	(((reg) >= 0x2000 && (reg) < 0x4000) || \
> +	((reg) >= 0x5200 && (reg) < 0x8000) || \
> +	((reg) >= 0x8300 && (reg) < 0x8500) || \
> +	((reg) >= 0x8C00 && (reg) < 0x8D00) || \
> +	((reg) >= 0xB000 && (reg) < 0xB480) || \
> +	((reg) >= 0xE000 && (reg) < 0xE800))
> +
> +#define FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) \
> +	(((reg) >= 0x8800 && (reg) < 0x8A00) || \
> +	((reg) >= 0xD000 && (reg) < 0xD800) || \
> +	((reg) >= 0x12000 && (reg) < 0x14000) || \
> +	((reg) >= 0x1A000 && (reg) < 0x1EA00) || \
> +	((reg) >= 0x30000 && (reg) < 0x40000))
> +
> +#define FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg) \
> +	((reg) >= 0x9400 && (reg) < 0x9800)

Please use REG_RANGE for all above.

> +#define FORCEWAKE_GEN9_BLITTER_RANGE_OFFSET(reg) \
> +	((reg) < 0x40000 &&\
> +	!FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) && \
> +	!FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) && \
> +	!FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) && \
> +	!FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg))
> +
>  static void
>  ilk_dummy_write(struct drm_i915_private *dev_priv)
>  {
> @@ -804,6 +832,43 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>  	REG_READ_FOOTER; \
>  }
>  
> +#define __gen9_read(x) \
> +static u##x \
> +gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
> +	REG_READ_HEADER(x); \
> +	if (!NEEDS_FORCE_WAKE((dev_priv), (reg)) || \

As gen9 doesn't have FORCEWAKE register, you can save one
comparison here if you discard the macro and opencode.

> +			FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg)) { \
> +		val = __raw_i915_read##x(dev_priv, reg); \
> +	} else { \
> +		unsigned fwengine = 0; \
> +		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
> +			if (dev_priv->uncore.fw_rendercount == 0) \
> +				fwengine = FORCEWAKE_RENDER; \
> +		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
> +			if (dev_priv->uncore.fw_mediacount == 0) \
> +				fwengine = FORCEWAKE_MEDIA; \
> +		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
> +			if (dev_priv->uncore.fw_rendercount == 0) \
> +				fwengine |= FORCEWAKE_RENDER; \
> +			if (dev_priv->uncore.fw_mediacount == 0) \
> +				fwengine |= FORCEWAKE_MEDIA; \
> +		} else { \
> +			if (dev_priv->uncore.fw_blittercount == 0) \
> +				fwengine = FORCEWAKE_BLITTER; \
> +		} \
> +		if (fwengine) \
> +			dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
> +		val = __raw_i915_read##x(dev_priv, reg); \
> +		if (fwengine) \
> +			dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
> +	} \
> +	REG_READ_FOOTER; \
> +}
> +
> +__gen9_read(8)
> +__gen9_read(16)
> +__gen9_read(32)
> +__gen9_read(64)
>  __chv_read(8)
>  __chv_read(16)
>  __chv_read(32)
> @@ -825,6 +890,7 @@ __gen4_read(16)
>  __gen4_read(32)
>  __gen4_read(64)
>  
> +#undef __gen9_read
>  #undef __chv_read
>  #undef __vlv_read
>  #undef __gen6_read
> @@ -962,6 +1028,46 @@ chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
>  	REG_WRITE_FOOTER; \
>  }
>  
> +#define __gen9_write(x) \
> +static void \
> +gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
> +		bool trace) { \
> +	REG_WRITE_HEADER; \
> +	if (!NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
ditto

-Mika

> +			FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg)) { \
> +		__raw_i915_write##x(dev_priv, reg, val); \
> +	} else { \
> +		unsigned fwengine = 0; \
> +		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
> +			if (dev_priv->uncore.fw_rendercount == 0) \
> +				fwengine = FORCEWAKE_RENDER; \
> +		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
> +			if (dev_priv->uncore.fw_mediacount == 0) \
> +				fwengine = FORCEWAKE_MEDIA; \
> +		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
> +			if (dev_priv->uncore.fw_rendercount == 0) \
> +				fwengine |= FORCEWAKE_RENDER; \
> +			if (dev_priv->uncore.fw_mediacount == 0) \
> +				fwengine |= FORCEWAKE_MEDIA; \
> +		} else { \
> +			if (dev_priv->uncore.fw_blittercount == 0) \
> +				fwengine = FORCEWAKE_BLITTER; \
> +		} \
> +		if (fwengine) \
> +			dev_priv->uncore.funcs.force_wake_get(dev_priv, \
> +					fwengine); \
> +		__raw_i915_write##x(dev_priv, reg, val); \
> +		if (fwengine) \
> +			dev_priv->uncore.funcs.force_wake_put(dev_priv, \
> +					fwengine); \
> +	} \
> +	REG_WRITE_FOOTER; \
> +}
> +
> +__gen9_write(8)
> +__gen9_write(16)
> +__gen9_write(32)
> +__gen9_write(64)
>  __chv_write(8)
>  __chv_write(16)
>  __chv_write(32)
> @@ -987,6 +1093,7 @@ __gen4_write(16)
>  __gen4_write(32)
>  __gen4_write(64)
>  
> +#undef __gen9_write
>  #undef __chv_write
>  #undef __gen8_write
>  #undef __hsw_write
> @@ -1054,6 +1161,19 @@ void intel_uncore_init(struct drm_device *dev)
>  
>  	switch (INTEL_INFO(dev)->gen) {
>  	default:
> +		WARN_ON(1);
> +		return;
> +	case 9:
> +		dev_priv->uncore.funcs.mmio_writeb  = gen9_write8;
> +		dev_priv->uncore.funcs.mmio_writew  = gen9_write16;
> +		dev_priv->uncore.funcs.mmio_writel  = gen9_write32;
> +		dev_priv->uncore.funcs.mmio_writeq  = gen9_write64;
> +		dev_priv->uncore.funcs.mmio_readb  = gen9_read8;
> +		dev_priv->uncore.funcs.mmio_readw  = gen9_read16;
> +		dev_priv->uncore.funcs.mmio_readl  = gen9_read32;
> +		dev_priv->uncore.funcs.mmio_readq  = gen9_read64;
> +		break;
> +	case 8:
>  		if (IS_CHERRYVIEW(dev)) {
>  			dev_priv->uncore.funcs.mmio_writeb  = chv_write8;
>  			dev_priv->uncore.funcs.mmio_writew  = chv_write16;
> -- 
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 58/89] drm/i915/skl: Register definitions for SKL Clocks
  2014-09-04 11:27 ` [PATCH 58/89] drm/i915/skl: Register definitions for SKL Clocks Damien Lespiau
@ 2014-09-22 18:17   ` Paulo Zanoni
  2014-10-01 10:51     ` M, Satheeshakrishna
  2014-11-04 16:11     ` [PATCH 58/89 v5] " Damien Lespiau
  0 siblings, 2 replies; 286+ messages in thread
From: Paulo Zanoni @ 2014-09-22 18:17 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>
> This patch defines the necessary SKL registers for implementing the
> new clocking mechanism.
>
> v2: Addressed review comments by Damien
>         - Added code comment
>         - Introduced enum for WRPLL values
>
> v3: Rebase on top of nightly (minor conflict in i915_reg.h)
>
> v4: Use 0x, not 0X (Ville)

Bikeshed: One of my worries with this patch is that names like
CDCLK_CTL and DPLL_CTRL1 are too generic. Basically every platform has
a CDCLK and DPLLs... Maybe adding _SKL in their names would help a
little. Or maybe we don't need it, since the functions using these
defines will already be surrounded by IS_SKL+ checks...

>
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v2)
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v3,v4)
> ---
>  drivers/gpu/drm/i915/i915_reg.h | 84 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 84 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 417075d..2364ece 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -6336,6 +6336,90 @@ enum punit_power_well {
>  #define  LCPLL_CD_SOURCE_FCLK          (1<<21)
>  #define  LCPLL_CD_SOURCE_FCLK_DONE     (1<<19)
>
> +/*
> + * SKL Clocks
> + */
> +
> +/* CDCLK_CTL */
> +#define CDCLK_CTL                      0x46000
> +#define  CDCLK_FREQ_SEL_MASK           (3<<26)
> +#define  CDCLK_FREQ_450_432            (0<<26)
> +#define  CDCLK_FREQ_540                        (1<<26)
> +#define  CDCLK_FREQ_337_308            (2<<26)
> +#define  CDCLK_FREQ_675_617            (3<<26)
> +#define         CDCLK_FREQ_DECIMAL_MASK        (0x7ff)

<ocd> Please replace the tab for a space on the line above. </ocd>

> +
> +/* LCPLL_CTL */
> +#define LCPLL1_CTL             0x46010
> +#define LCPLL2_CTL             0x46014
> +#define  LCPLL_PLL_ENABLE      (1<<31)
> +
> +/* DPLL control1 */
> +#define DPLL_CTRL1             0x6C058
> +#define  DPLL_CTRL1_HDMI_MODE(id)              (1<<((id)*6+5))
> +#define  DPLL_CTRL1_SSC(id)                    (1<<((id)*6+4))
> +#define  DPLL_CRTL1_LINK_RATE_MASK(id)         (7<<((id)*6+1))
> +#define  DPLL_CRTL1_LINK_RATE(linkrate, id)    ((linkrate)<<((id)*6+1))
> +#define  DPLL_CTRL1_OVERRIDE(id)               (1<<((id)*6))
> +#define  DPLL_CRTL1_LINK_RATE_2700             0
> +#define  DPLL_CRTL1_LINK_RATE_1350             1
> +#define  DPLL_CRTL1_LINK_RATE_810              2
> +#define  DPLL_CRTL1_LINK_RATE_1620             3
> +#define  DPLL_CRTL1_LINK_RATE_1080             4
> +#define  DPLL_CRTL1_LINK_RATE_2160             5
> +
> +/* DPLL control2 */
> +#define DPLL_CTRL2                             0x6C05C
> +#define  DPLL_CTRL2_DDI_CLK_OFF(port)          (1<<(port+15))
> +#define  DPLL_CTRL2_DDI_CLK_SEL_MASK(port)     (3<<((port)*3+1))
> +#define  DPLL_CTRL2_DDI_CLK_SEL(clk, port)     (clk<<((port)*3+1))
> +#define  DPLL_CTRL2_DDI_SEL_OVERRIDE(port)     (1<<(port*3))
> +
> +/* DPLL Status */
> +#define DPLL_STATUS    0x6C060
> +#define         DPLL_LOCK(id)  (1<<((id)*8))

Bad tab here too.


> +
> +/* DPLL cfg */
> +#define DPLL1_CFGCR1   0x6C040
> +#define DPLL2_CFGCR1   0x6C048
> +#define DPLL3_CFGCR1   0x6C050
> +#define  DPLL_CFGCR1_FREQ_ENABLE       (1<<31)
> +#define  DPLL_CFGCR1_DCO_FRACTION_MASK (0x7fff<<9)
> +#define  DPLL_CFGCR1_DCO_FRACTION(x)   (x<<9)
> +#define  DPLL_CFGCR1_DCO_INTEGER_MASK  (0x1ff)
> +
> +#define DPLL1_CFGCR2   0x6C044
> +#define DPLL2_CFGCR2   0x6C04C
> +#define DPLL3_CFGCR2   0x6C054
> +#define  DPLL_CFGCR2_QDIV_RATIO_MASK   (0xff<<8)
> +#define  DPLL_CFGCR2_QDIV_RATIO(x)     (x<<8)
> +#define  DPLL_CFGCR2_QDIV_MODE(x)      (x<<7)
> +#define  DPLL_CFGCR2_KDIV_MASK         (3<<5)
> +#define  DPLL_CFGCR2_KDIV(x)           (x<<5)
> +#define  DPLL_CFGCR2_PDIV_MASK         (7<<2)
> +#define  DPLL_CFGCR2_PDIV(x)           (x<<2)
> +#define  DPLL_CFGCR2_CENTRAL_FREQ_MASK (3)
> +
> +enum central_freq {
> +       freq_9600 = 0,
> +       freq_9000 = 1,
> +       freq_8400 = 3,
> +};
> +
> +enum pdiv {
> +       pdiv_1 = 0,
> +       pdiv_2 = 1,
> +       pdiv_3 = 2,
> +       pdiv_7 = 4,
> +};
> +
> +enum kdiv {
> +       kdiv_5 = 0,
> +       kdiv_2 = 1,
> +       kdiv_3 = 2,
> +       kdiv_1 = 3,
> +};
> +

I find it weird that we're using enums here. We don't have the
tradition to do this, so it's a deviation from the usual coding style.

With or without changes:
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

>  /* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register,
>   * since on HSW we can't write to it using I915_WRITE. */
>  #define D_COMP_HSW                     (MCHBAR_MIRROR_BASE_SNB + 0x5F0C)
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 59/89] drm/i915/skl: Structure/enum definitions for SKL clocks
  2014-09-04 11:27 ` [PATCH 59/89] drm/i915/skl: Structure/enum definitions for SKL clocks Damien Lespiau
@ 2014-09-22 18:25   ` Paulo Zanoni
  2014-11-04 16:12     ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Paulo Zanoni @ 2014-09-22 18:25 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>
> Adding structure/enum for SKL clocking implementation.
>
> v2: Addressed Damien's comment
>         - Removed internal structure from this header file
>
> v3: Stove this into the generic intel_dpll_id enum and give them the established
> DPLL_ID_ prefixes. (Daniel)
>
> v4: - We'll only try to share DPLL1/2/3, leaving DPLL0 to eDP
>     - Use SKL in the skylake shared DPLL names
>     - Re-add the skl_dpll enum
>     (Damien)
>
> v5: Remove SKL_DPLL_NONE (Daniel)
>
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v2)
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v4,v5)
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v3)

The changes contained on this patch should be part of another patch. I
can't really review this if I don't know how those things, especially
enum skl_dpll are going to be used. And it also makes the lives of
backporters harder.

Also, I guess that a patch with 3 signed-off-by stamps shouldn't
really need an additional reviewed-by stamp, right? So maybe this
should just be merged.

> ---
>  drivers/gpu/drm/i915/i915_drv.h | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 84defa4..65e5ffb 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -206,10 +206,15 @@ enum intel_dpll_id {
>         /* real shared dpll ids must be >= 0 */
>         DPLL_ID_PCH_PLL_A = 0,
>         DPLL_ID_PCH_PLL_B = 1,
> +       /* hsw/bdw */
>         DPLL_ID_WRPLL1 = 0,
>         DPLL_ID_WRPLL2 = 1,
> +       /* skl */
> +       DPLL_ID_SKL_DPLL1 = 0,
> +       DPLL_ID_SKL_DPLL2 = 1,
> +       DPLL_ID_SKL_DPLL3 = 2,
>  };
> -#define I915_NUM_PLLS 2
> +#define I915_NUM_PLLS 3
>
>  struct intel_dpll_hw_state {
>         /* i9xx, pch plls */
> @@ -243,6 +248,13 @@ struct intel_shared_dpll {
>                              struct intel_dpll_hw_state *hw_state);
>  };
>
> +enum skl_dpll {
> +       SKL_DPLL0,
> +       SKL_DPLL1,
> +       SKL_DPLL2,
> +       SKL_DPLL3,
> +};
> +
>  /* Used by dp and fdi links */
>  struct intel_link_m_n {
>         uint32_t        tu;
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 46/89] drm/i915/skl: Add DDB allocation management structures
  2014-09-22 14:08     ` Damien Lespiau
@ 2014-09-22 18:26       ` Ville Syrjälä
  0 siblings, 0 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-09-22 18:26 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Mon, Sep 22, 2014 at 03:08:27PM +0100, Damien Lespiau wrote:
> On Wed, Sep 17, 2014 at 01:47:54PM +0300, Ville Syrjälä wrote:
> > On Thu, Sep 04, 2014 at 12:27:12PM +0100, Damien Lespiau wrote:
> > > We now need to allocate space in the DDB for planes being scanned out
> > > ourselves. The data structure to represent an allocation mirrors what
> > > we'll need to write in the registers later on: (start, end).
> > > 
> > > We add that allocation datat to the skl_wm_values structure as part of
> > > the values to program the hardware with.
> > > 
> > > v2: Split planes and cursor for consistency.
> > > 
> > > v3: Make the skl_ddb_entry_size() parameter const
> > > 
> > > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/i915_drv.h | 19 +++++++++++++++++++
> > >  1 file changed, 19 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > > index 3764ad5..de278a5 100644
> > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > @@ -1381,8 +1381,27 @@ struct ilk_wm_values {
> > >  	enum intel_ddb_partitioning partitioning;
> > >  };
> > >  
> > > +struct skl_ddb_entry {
> > > +	uint16_t start, end;	/* in number of blocks */
> > > +};
> > > +
> > > +static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry)
> > > +{
> > > +	/* end not set, clearly no allocation here. start can be 0 though */
> > > +	if (entry->end == 0)
> > > +		return 0;
> > > +
> > > +	return entry->end - entry->start + 1;
> > 
> > I would make 'end' exclusive as that allows you to represent an empty
> > block more naturally, and you don't have to worry about the +/-1 adjustments
> > when going between start/end and start/size representation.
> 
> The values we program in the registers are inclusive (I had a bug where
> the end of one plane and the start of another plane had the same value
> and artefacts could be seen, due to the pipes fetching from overlapping
> DDB space). I took the option of having those values mirror what we need
> to program. Hopefully the small functions around the skl_ddb_entry
> structure doesn't make it too bad?

I'd still change to exclusive. Inclusive is just too troublesome to use IMO,
you're bound to forget the magic +/-1 somewhere eventually.

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 60/89] drm/i915/skl: CD clock back calculation for SKL
  2014-09-04 11:27 ` [PATCH 60/89] drm/i915/skl: CD clock back calculation for SKL Damien Lespiau
@ 2014-09-22 19:19   ` Paulo Zanoni
  2014-10-01 10:51     ` M, Satheeshakrishna
  2014-11-04 16:15     ` [PATCH 60/89 v5] " Damien Lespiau
  0 siblings, 2 replies; 286+ messages in thread
From: Paulo Zanoni @ 2014-09-22 19:19 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>
> Determine programmed cd clock for SKL.
>
> v2: Fix the LCPLL1 enable warning logic
>
> v3: Rebase over the hsw pll rework.
>
> v4: Rebase on top of the per-platform split (Damien)
>
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 76 +++++++++++++++++++++++++++++++++++-----
>  1 file changed, 67 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index ba1103f..e7a5428 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1260,6 +1260,55 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
>         }
>  }
>
> +static int skl_get_cdclk_freq(struct drm_i915_private *dev_priv)
> +{
> +       uint32_t lcpll1 = I915_READ(LCPLL1_CTL);
> +       uint32_t cdctl = I915_READ(CDCLK_CTL);
> +       uint32_t linkrate;
> +
> +       if (!(lcpll1 & LCPLL_PLL_ENABLE)) {
> +               WARN(1, "LCPLL1 not enabled\n");
> +               return 24000; /* 24MHz is the cd freq with NSSC ref */
> +       }
> +
> +       if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540)
> +               return 540000;
> +
> +       linkrate = (I915_READ(DPLL_CTRL1) &
> +                   DPLL_CRTL1_LINK_RATE_MASK(SKL_DPLL0)) >> 1;
> +
> +       if (linkrate == DPLL_CRTL1_LINK_RATE_2160 ||
> +           linkrate == DPLL_CRTL1_LINK_RATE_1080) {
> +               /* vco 8640 */
> +               switch (cdctl & CDCLK_FREQ_SEL_MASK) {
> +               case CDCLK_FREQ_450_432:
> +                       return 432000;
> +               case CDCLK_FREQ_337_308:
> +                       return 308570;
> +               case CDCLK_FREQ_675_617:
> +                       return 617140;
> +                       break;

This is the only line with a "break" after a return :)


> +               default:
> +                       WARN(1, "Unknown cd freq selection\n");
> +               }
> +       } else {
> +               /* vco 8100 */
> +               switch (cdctl & CDCLK_FREQ_SEL_MASK) {
> +               case CDCLK_FREQ_450_432:
> +                       return 450000;
> +               case CDCLK_FREQ_337_308:
> +                       return 337500;
> +               case CDCLK_FREQ_675_617:
> +                       return 675000;
> +               default:
> +                       WARN(1, "Unknown cd freq selection\n");
> +               }
> +       }
> +
> +       /* error case, do as if DPLL0 isn't enabled */
> +       return 24000;
> +}
> +
>  static int bdw_get_cdclk_freq(struct drm_i915_private *dev_priv)
>  {
>         uint32_t lcpll = I915_READ(LCPLL_CTL);
> @@ -1301,6 +1350,9 @@ int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
>  {
>         struct drm_device *dev = dev_priv->dev;
>
> +       if (IS_SKYLAKE(dev))
> +               return skl_get_cdclk_freq(dev_priv);
> +

I hope someone will replace this with a "switch (INTEL_INFO(gen))"
before Gen 15 :)

With or without changes: Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>


>         if (IS_BROADWELL(dev))
>                 return bdw_get_cdclk_freq(dev_priv);
>
> @@ -1369,19 +1421,25 @@ void intel_ddi_pll_init(struct drm_device *dev)
>
>         hsw_shared_dplls_init(dev_priv);
>
> -       /* The LCPLL register should be turned on by the BIOS. For now let's
> -        * just check its state and print errors in case something is wrong.
> -        * Don't even try to turn it on.
> -        */
> -
>         DRM_DEBUG_KMS("CDCLK running at %dKHz\n",
>                       intel_ddi_get_cdclk_freq(dev_priv));
>
> -       if (val & LCPLL_CD_SOURCE_FCLK)
> -               DRM_ERROR("CDCLK source is not LCPLL\n");
> +       if (IS_SKYLAKE(dev)) {
> +               if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
> +                       DRM_ERROR("LCPLL1 is disabled\n");
> +       } else {
> +               /*
> +                * The LCPLL register should be turned on by the BIOS. For now
> +                * let's just check its state and print errors in case
> +                * something is wrong.  Don't even try to turn it on.
> +                */
> +
> +               if (val & LCPLL_CD_SOURCE_FCLK)
> +                       DRM_ERROR("CDCLK source is not LCPLL\n");
>
> -       if (val & LCPLL_PLL_DISABLE)
> -               DRM_ERROR("LCPLL is disabled\n");
> +               if (val & LCPLL_PLL_DISABLE)
> +                       DRM_ERROR("LCPLL is disabled\n");
> +       }
>  }
>
>  void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 21/89] drm/i915/skl: Implement the get_aux_clock_divider() DP vfunc
  2014-09-22 13:21     ` Damien Lespiau
@ 2014-09-22 19:33       ` Rodrigo Vivi
  0 siblings, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-22 19:33 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 3422 bytes --]

Thanks, so feel free to use:

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Mon, Sep 22, 2014 at 6:21 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> On Tue, Sep 16, 2014 at 06:12:04PM -0700, Rodrigo Vivi wrote:
> >    I believe this patch should remove the gen9 part of
> >    ilk_get_aux_clock_divider.
>
> The previous patch changing ilk_get_aux_clock_divider() got removed
> entirely.
>
> >    Also there it just returns 0, but here it returns 0 or 1 depending on
> the
> >    index.
> >    This also is incoherent with the commit description.
>
> Yes, when the index is 0, we need to return a non 0 value (chose 1) to
> have the code using this vfunc loop once. Then, when the index is
> incremented, we return 0 to stop the loop.
>
> --
> Damien
>
> >    On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <
> damien.lespiau@intel.com>
> >    wrote:
> >
> >      We need to provide a vfunc that will make the code in
> intel_dp_aux_ch()
> >      loop once to start the AUX transaction. The return value (clock
> divider)
> >      is unused on SKL, so just return 1.
> >
> >      Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> >      ---
> >       drivers/gpu/drm/i915/intel_dp.c | 14 +++++++++++++-
> >       1 file changed, 13 insertions(+), 1 deletion(-)
> >
> >      diff --git a/drivers/gpu/drm/i915/intel_dp.c
> >      b/drivers/gpu/drm/i915/intel_dp.c
> >      index a95fb47..4560ced 100644
> >      --- a/drivers/gpu/drm/i915/intel_dp.c
> >      +++ b/drivers/gpu/drm/i915/intel_dp.c
> >      @@ -489,6 +489,16 @@ static uint32_t
> vlv_get_aux_clock_divider(struct
> >      intel_dp *intel_dp, int index)
> >              return index ? 0 : 100;
> >       }
> >
> >      +static uint32_t skl_get_aux_clock_divider(struct intel_dp
> *intel_dp,
> >      int index)
> >      +{
> >      +       /*
> >      +        * SKL doesn't need us to program the AUX clock divider
> >      (Hardware will
> >      +        * derive the clock from CDCLK automatically). We still
> >      implement the
> >      +        * get_aux_clock_divider vfunc to plug-in into the existing
> >      code.
> >      +        */
> >      +       return index ? 0 : 1;
> >      +}
> >      +
> >       static uint32_t i9xx_get_aux_send_ctl(struct intel_dp *intel_dp,
> >                                            bool has_aux_irq,
> >                                            int send_bytes,
> >      @@ -4726,7 +4736,9 @@ intel_dp_init_connector(struct
> intel_digital_port
> >      *intel_dig_port,
> >              int type;
> >
> >              /* intel_dp vfuncs */
> >      -       if (IS_VALLEYVIEW(dev))
> >      +       if (INTEL_INFO(dev)->gen >= 9)
> >      +               intel_dp->get_aux_clock_divider =
> >      skl_get_aux_clock_divider;
> >      +       else if (IS_VALLEYVIEW(dev))
> >                      intel_dp->get_aux_clock_divider =
> >      vlv_get_aux_clock_divider;
> >              else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
> >                      intel_dp->get_aux_clock_divider =
> >      hsw_get_aux_clock_divider;
> >      --
> >      1.8.3.1
> >
> >      _______________________________________________
> >      Intel-gfx mailing list
> >      Intel-gfx@lists.freedesktop.org
> >      http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> >
> >    --
> >    Rodrigo Vivi
> >    Blog: http://blog.vivi.eng.br
> >
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 5130 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 33/89] drm/i915/skl: Sunrise Point PCH detection
  2014-09-22 13:42     ` Damien Lespiau
@ 2014-09-22 19:34       ` Rodrigo Vivi
  0 siblings, 0 replies; 286+ messages in thread
From: Rodrigo Vivi @ 2014-09-22 19:34 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 4068 bytes --]

Oh! ok, so let's not block the progress

Thanks, so feel free to use:

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Mon, Sep 22, 2014 at 6:42 AM, Damien Lespiau <damien.lespiau@intel.com>
wrote:

> On Wed, Sep 17, 2014 at 03:18:21PM -0700, Rodrigo Vivi wrote:
> >    Where can I find these pch device id definitions?
>
> You'll have to trust Satheesh on that, it's not something we have
> documented in the GPU specs.
>
> --
> Damien
>
> >    On Thu, Sep 4, 2014 at 4:26 AM, Damien Lespiau <
> damien.lespiau@intel.com>
> >    wrote:
> >
> >      From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> >
> >      This patch implements detection of SPT and SPT-LP PCH devices.
> >
> >      v2: Added HAS_PCH_SPT macro
> >
> >      Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> >      Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> >      ---
> >       drivers/gpu/drm/i915/i915_drv.c | 10 ++++++++++
> >       drivers/gpu/drm/i915/i915_drv.h |  4 ++++
> >       2 files changed, 14 insertions(+)
> >
> >      diff --git a/drivers/gpu/drm/i915/i915_drv.c
> >      b/drivers/gpu/drm/i915/i915_drv.c
> >      index 3d7f823..c6a8a80 100644
> >      --- a/drivers/gpu/drm/i915/i915_drv.c
> >      +++ b/drivers/gpu/drm/i915/i915_drv.c
> >      @@ -475,6 +475,16 @@ void intel_detect_pch(struct drm_device *dev)
> >                                      DRM_DEBUG_KMS("Found LynxPoint LP
> >      PCH\n");
> >                                      WARN_ON(!IS_HASWELL(dev));
> >                                      WARN_ON(!IS_ULT(dev));
> >      +                       } else if (id ==
> INTEL_PCH_SPT_DEVICE_ID_TYPE) {
> >      +                               dev_priv->pch_type = PCH_SPT;
> >      +                               DRM_DEBUG_KMS("Found SunrisePoint
> >      PCH\n");
> >      +                               WARN_ON(!IS_SKYLAKE(dev));
> >      +                               WARN_ON(IS_ULT(dev));
> >      +                       } else if (id ==
> >      INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) {
> >      +                               dev_priv->pch_type = PCH_SPT;
> >      +                               DRM_DEBUG_KMS("Found SunrisePoint LP
> >      PCH\n");
> >      +                               WARN_ON(!IS_SKYLAKE(dev));
> >      +                               WARN_ON(!IS_ULT(dev));
> >                              } else
> >                                      continue;
> >
> >      diff --git a/drivers/gpu/drm/i915/i915_drv.h
> >      b/drivers/gpu/drm/i915/i915_drv.h
> >      index cf4fc86..be82888 100644
> >      --- a/drivers/gpu/drm/i915/i915_drv.h
> >      +++ b/drivers/gpu/drm/i915/i915_drv.h
> >      @@ -699,6 +699,7 @@ enum intel_pch {
> >              PCH_IBX,        /* Ibexpeak PCH */
> >              PCH_CPT,        /* Cougarpoint PCH */
> >              PCH_LPT,        /* Lynxpoint PCH */
> >      +       PCH_SPT,        /* Sunrisepoint PCH */
> >              PCH_NOP,
> >       };
> >
> >      @@ -2184,8 +2185,11 @@ struct drm_i915_cmd_table {
> >       #define INTEL_PCH_PPT_DEVICE_ID_TYPE           0x1e00
> >       #define INTEL_PCH_LPT_DEVICE_ID_TYPE           0x8c00
> >       #define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE                0x9c00
> >      +#define INTEL_PCH_SPT_DEVICE_ID_TYPE           0xA100
> >      +#define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE                0x9D00
> >
> >       #define INTEL_PCH_TYPE(dev) (to_i915(dev)->pch_type)
> >      +#define HAS_PCH_SPT(dev) (INTEL_PCH_TYPE(dev) == PCH_SPT)
> >       #define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT)
> >       #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
> >       #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX)
> >      --
> >      1.8.3.1
> >
> >      _______________________________________________
> >      Intel-gfx mailing list
> >      Intel-gfx@lists.freedesktop.org
> >      http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> >
> >    --
> >    Rodrigo Vivi
> >    Blog: http://blog.vivi.eng.br
> >
>



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br

[-- Attachment #1.2: Type: text/html, Size: 6183 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 61/89] drm/i915/skl: Determine enabled PLL and its linkrate/pixel clock
  2014-09-04 11:27 ` [PATCH 61/89] drm/i915/skl: Determine enabled PLL and its linkrate/pixel clock Damien Lespiau
@ 2014-09-22 20:12   ` Paulo Zanoni
  2014-10-01 10:51     ` M, Satheeshakrishna
  2014-11-04 16:17     ` [PATCH 61/89 v4] " Damien Lespiau
  0 siblings, 2 replies; 286+ messages in thread
From: Paulo Zanoni @ 2014-09-22 20:12 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>
> v2: Fixup compilation due to the removal of the intel_ddi_dpll_id enum.
> And add a fixme about the abuse of pipe_config here.
>
> v3: Rebase on top of the hsw_ddi_clock_get() rename (Damien)
>
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v1)
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v3)
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v2)
> ---
>  drivers/gpu/drm/i915/i915_reg.h  |   5 ++
>  drivers/gpu/drm/i915/intel_ddi.c | 114 ++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 118 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 2364ece..794d0ba 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -6367,6 +6367,7 @@ enum punit_power_well {
>  #define  DPLL_CRTL1_LINK_RATE_1620             3
>  #define  DPLL_CRTL1_LINK_RATE_1080             4
>  #define  DPLL_CRTL1_LINK_RATE_2160             5
> +#define  DPLL_CRTL1_LINK_RATE_SHIFT(id)                ((id)*6+1)

I'd move this to a few lines above, where the MASK and RATE
definitions are. Possibly reimplement the other macros using the new
one (if the lines don't look to big/ugly).

>
>  /* DPLL control2 */
>  #define DPLL_CTRL2                             0x6C05C
> @@ -6374,6 +6375,7 @@ enum punit_power_well {
>  #define  DPLL_CTRL2_DDI_CLK_SEL_MASK(port)     (3<<((port)*3+1))
>  #define  DPLL_CTRL2_DDI_CLK_SEL(clk, port)     (clk<<((port)*3+1))
>  #define  DPLL_CTRL2_DDI_SEL_OVERRIDE(port)     (1<<(port*3))
> +#define  DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port)    (port*3+1)

Same here: move a few lines above, and possibly reimplement the others
using the new one. Also, use "(port)" instead of "port", since we
don't want to risk really-hard-to-debug bugs due to operator
precedence on those "*" and "+" operations.

>
>  /* DPLL Status */
>  #define DPLL_STATUS    0x6C060
> @@ -6400,6 +6402,9 @@ enum punit_power_well {
>  #define  DPLL_CFGCR2_PDIV(x)           (x<<2)
>  #define  DPLL_CFGCR2_CENTRAL_FREQ_MASK (3)
>
> +#define GET_CFG_CR1_REG(id) (DPLL1_CFGCR1 + (id - 1) * 8)
> +#define GET_CFG_CR2_REG(id) (DPLL1_CFGCR2 + (id - 1) * 8)

The macros above are not really trivial due to the fact that the "id"
is undefined and confusing. Please convert this to an inline function,
since what we're actually expecting here is "enum intel_dpll_id",
which has ID 0 for DPLL 1, which can be super confusing (imagine
someone passing ID 1 for DPLL 1, not realizing it should be using the
correct enum...). If we use a function we can specify the correct
expected enum for the ID type, which helps the programmer find out
what is the expected thing to pass to the function.


> +
>  enum central_freq {
>         freq_9600 = 0,
>         freq_9000 = 1,
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index e7a5428..b5cfb07 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -649,6 +649,114 @@ static int intel_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
>         return (refclk * n * 100) / (p * r);
>  }
>
> +static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
> +                              enum intel_dpll_id dpll)
> +{
> +       uint32_t cfgcr1_reg, cfgcr2_reg;
> +       uint32_t cfgcr1, cfgcr2;
> +       uint32_t p0, p1, p2, dco_freq;
> +
> +       cfgcr1_reg = GET_CFG_CR1_REG(dpll);
> +       cfgcr2_reg = GET_CFG_CR2_REG(dpll);
> +
> +       cfgcr1 = I915_READ(cfgcr1_reg);
> +       cfgcr2 = I915_READ(cfgcr2_reg);

Bikeshed: I'd probably call these cfgcr{1,2}_val to avoid confusion.

> +
> +       p0 = (cfgcr2 & DPLL_CFGCR2_PDIV_MASK) >> 2;
> +       p2 = (cfgcr2 & DPLL_CFGCR2_KDIV_MASK) >> 5;
> +
> +       if (cfgcr2 &  DPLL_CFGCR2_QDIV_MODE(1))
> +               p1 = (cfgcr2 & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
> +       else
> +               p1 = 1;
> +
> +
> +       switch (p0) {
> +       case pdiv_1:
> +               p0 = 1;
> +               break;
> +       case pdiv_2:
> +               p0 = 2;
> +               break;
> +       case pdiv_3:
> +               p0 = 3;
> +               break;
> +       case pdiv_7:
> +               p0 = 7;
> +               break;
> +       }
> +
> +       switch (p2) {
> +       case kdiv_5:
> +               p2 = 5;
> +               break;
> +       case kdiv_2:
> +               p2 = 2;
> +               break;
> +       case kdiv_3:
> +               p2 = 3;
> +               break;
> +       case kdiv_1:
> +               p2 = 1;
> +               break;
> +       }

I really think that if we had something like:
#define DPLL_CFGCR2_PDIV_7 (4 << 2)
we'd be able to avoid this "convert to enum and then get the value"
part, making the function much simpler...


> +
> +       dco_freq = (cfgcr1 & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
> +
> +       dco_freq += (((cfgcr1 & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
> +               1000) / 0x8000;
> +
> +       return dco_freq / (p0 * p1 * p2 * 5);
> +}
> +
> +
> +static void skl_ddi_clock_get(struct intel_encoder *encoder,
> +                               struct intel_crtc_config *pipe_config)
> +{
> +       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> +       enum port port = intel_ddi_get_encoder_port(encoder);
> +       int link_clock = 0;
> +       uint32_t dpll_ctl1, dpll;
> +
> +       /* FIXME: This should be tracked in the pipe config. */
> +       dpll = I915_READ(DPLL_CTRL2);
> +       dpll &= DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
> +       dpll >>= DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port);
> +
> +       dpll_ctl1 = I915_READ(DPLL_CTRL1);
> +
> +       if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
> +               link_clock = skl_calc_wrpll_link(dev_priv, dpll);
> +       } else {
> +               link_clock = dpll_ctl1 & DPLL_CRTL1_LINK_RATE_MASK(dpll);
> +               link_clock >>= DPLL_CRTL1_LINK_RATE_SHIFT(dpll);
> +
> +               switch (link_clock) {
> +               case DPLL_CRTL1_LINK_RATE_810:
> +                       link_clock = 81000;
> +                       break;
> +               case DPLL_CRTL1_LINK_RATE_1350:
> +                       link_clock = 135000;
> +                       break;
> +               case DPLL_CRTL1_LINK_RATE_2700:
> +                       link_clock = 270000;
> +                       break;

What about 1620 and 1080?


> +               default:
> +                       break;

We're just silently failing here, which will probably result in later
WARNs on the HW state readout/check code. So we should probably give a
WARN() here to make debugging easier :)


> +               }
> +               link_clock *= 2;
> +       }
> +
> +       pipe_config->port_clock = link_clock;
> +
> +       if (pipe_config->has_dp_encoder)
> +               pipe_config->adjusted_mode.crtc_clock =
> +                       intel_dotclock_calculate(pipe_config->port_clock,
> +                                                &pipe_config->dp_m_n);
> +       else
> +               pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock;
> +}
> +
>  static void hsw_ddi_clock_get(struct intel_encoder *encoder,
>                               struct intel_crtc_config *pipe_config)
>  {
> @@ -1535,6 +1643,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>         struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
>         enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
>         u32 temp, flags = 0;
> +       struct drm_device *dev = dev_priv->dev;
>
>         temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
>         if (temp & TRANS_DDI_PHSYNC)
> @@ -1606,7 +1715,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>                 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
>         }
>
> -       hsw_ddi_clock_get(encoder, pipe_config);
> +       if (INTEL_INFO(dev)->gen < 9)

I'm sure Daniel would request a change to "<= 8" instead of "< 9" here :)

I should probably also complain about the fact that clock calculation
is a very confusing thing, and I never know which value should be
assigned where, and I also never know when to multiply by 2 or 5 or
divide by 10...

Note: not everything mentioned above is a hard requirement for a R-B
tag. Deciding what's a bikeshed and what's not is left as an exercise
to the reader.

> +               hsw_ddi_clock_get(encoder, pipe_config);
> +       else
> +               skl_ddi_clock_get(encoder, pipe_config);
>  }
>
>  static void intel_ddi_destroy(struct drm_encoder *encoder)
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 62/89] drm/i915/skl: Query DPLL attached to port on SKL
  2014-09-04 11:27 ` [PATCH 62/89] drm/i915/skl: Query DPLL attached to port on SKL Damien Lespiau
@ 2014-09-22 20:24   ` Paulo Zanoni
  2014-10-01 10:51     ` M, Satheeshakrishna
  2014-11-04 16:19     ` [PATCH 62/89 v3] " Damien Lespiau
  0 siblings, 2 replies; 286+ messages in thread
From: Paulo Zanoni @ 2014-09-22 20:24 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>
> Modify the implementation to query DPLL attached to a SKL port.
>
> v2: Rebase on top of the run-time PM on DPMS series (Damien)
>
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 27 ++++++++++++++++++++++++++-
>  drivers/gpu/drm/i915/intel_drv.h     |  5 ++++-
>  2 files changed, 30 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 69e023a..6e71250 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -7789,6 +7789,28 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
>         return 0;
>  }
>
> +static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv,
> +                               enum port port,
> +                               struct intel_crtc_config *pipe_config)
> +{
> +       u32 temp;
> +
> +       temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
> +       pipe_config->ddi_pll_sel = temp >> (port * 3 + 1);

Since we're relying on the fact that ddi_pll_sel is actually "enum
skl_dpll", I'd change the definition of the enum and explicitly
declare SKL_DPLL0 to be "0", and SKL_DPLL1 to be 1, and so on.

> +
> +       switch (pipe_config->ddi_pll_sel) {
> +       case SKL_DPLL1:
> +               pipe_config->shared_dpll = DPLL_ID_SKL_DPLL1;
> +               break;
> +       case SKL_DPLL2:
> +               pipe_config->shared_dpll = DPLL_ID_SKL_DPLL2;
> +               break;
> +       case SKL_DPLL3:
> +               pipe_config->shared_dpll = DPLL_ID_SKL_DPLL3;
> +               break;

Please also add a WARN() to the default case, especially since there
are 4 possible values and we're just checking 3.

> +       }
> +}
> +
>  static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
>                                 enum port port,
>                                 struct intel_crtc_config *pipe_config)
> @@ -7818,7 +7840,10 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
>
>         port = (tmp & TRANS_DDI_PORT_MASK) >> TRANS_DDI_PORT_SHIFT;
>
> -       haswell_get_ddi_pll(dev_priv, port, pipe_config);
> +       if (IS_SKYLAKE(dev))

If you invert the check so that SKL is on the "else" part (as you did
in your previous patch), you'll make sure we're ready for the next
Gens in case they happen to be same as SKL. It's more likely they will
be the same as SKL instead of being the same as HSW :)


With at least the WARN added on the switch statement: Reviewed-by:
Paulo Zanoni <paulo.r.zanoni@intel.com>

> +               skylake_get_ddi_pll(dev_priv, port, pipe_config);
> +       else
> +               haswell_get_ddi_pll(dev_priv, port, pipe_config);
>
>         if (pipe_config->shared_dpll >= 0) {
>                 pll = &dev_priv->shared_dplls[pipe_config->shared_dpll];
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 559b747..9558f07 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -323,7 +323,10 @@ struct intel_crtc_config {
>         /* Selected dpll when shared or DPLL_ID_PRIVATE. */
>         enum intel_dpll_id shared_dpll;
>
> -       /* PORT_CLK_SEL for DDI ports. */
> +       /*
> +        * - PORT_CLK_SEL for DDI ports on HSW/BDW.
> +        * - enum skl_dpll on SKL
> +        */
>         uint32_t ddi_pll_sel;
>
>         /* Actual register state of the dpll, for shared dpll cross-checking. */
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 47/89] drm/i915/skl: SKL Watermark Computation
  2014-09-17 12:07   ` Ville Syrjälä
@ 2014-09-22 22:36     ` Damien Lespiau
  2014-09-23  6:00       ` Satheeshakrishna M
  2014-09-23 11:13     ` [PATCH 47/89 v11] " Damien Lespiau
  2014-09-23 11:14     ` [PATCH 47/89] " Damien Lespiau
  2 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-22 22:36 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Hi Satheesh,

On Wed, Sep 17, 2014 at 03:07:51PM +0300, Ville Syrjälä wrote:
> > +static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
> > +				   struct intel_plane_wm_parameters *p_params,
> > +				   uint16_t max_page_buff_alloc,
> > +				   uint32_t mem_value,
> > +				   uint16_t *res_blocks, /* out */
> > +				   uint8_t *res_lines /* out */)
> > +{
> > +	uint32_t method1, method2, plane_bytes_per_line;
> > +	uint32_t result_bytes;
> > +
> > +	if (!p->active || !p_params->enabled) {
> > +		*res_blocks = PLANE_WM_BLOCKS_DEFAULT;
> > +		*res_lines = PLANE_WM_LINES_DEFAULT;
> 
> Why do we need to set !=0 values for disabled planes?
> 
> > +		return false;
> > +	}

Do you remember why we would program some default numbers of blocks/lines
for disabled planes? Can't find a reason to do so now.

Thanks,

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 47/89] drm/i915/skl: SKL Watermark Computation
  2014-09-22 22:36     ` Damien Lespiau
@ 2014-09-23  6:00       ` Satheeshakrishna M
  0 siblings, 0 replies; 286+ messages in thread
From: Satheeshakrishna M @ 2014-09-23  6:00 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx


On Tuesday 23 September 2014 04:06 AM, Damien Lespiau wrote:
> Hi Satheesh,
>
> On Wed, Sep 17, 2014 at 03:07:51PM +0300, Ville Syrjälä wrote:
>>> +static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
>>> +				   struct intel_plane_wm_parameters *p_params,
>>> +				   uint16_t max_page_buff_alloc,
>>> +				   uint32_t mem_value,
>>> +				   uint16_t *res_blocks, /* out */
>>> +				   uint8_t *res_lines /* out */)
>>> +{
>>> +	uint32_t method1, method2, plane_bytes_per_line;
>>> +	uint32_t result_bytes;
>>> +
>>> +	if (!p->active || !p_params->enabled) {
>>> +		*res_blocks = PLANE_WM_BLOCKS_DEFAULT;
>>> +		*res_lines = PLANE_WM_LINES_DEFAULT;
>> Why do we need to set !=0 values for disabled planes?
>>
>>> +		return false;
>>> +	}
> Do you remember why we would program some default numbers of blocks/lines
> for disabled planes? Can't find a reason to do so now.
Yes, that's not required as returning false here disables the WM itself.
>
> Thanks,
>

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 45/89] drm/i915/skl: Definition of SKL WM param structs for pipe/plane
  2014-09-22 14:21     ` Damien Lespiau
@ 2014-09-23  8:16       ` Daniel Vetter
  2014-09-23 15:10         ` [PATCH 45/89 v4] " Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Daniel Vetter @ 2014-09-23  8:16 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx, Pradeep Bhat

On Mon, Sep 22, 2014 at 03:21:22PM +0100, Damien Lespiau wrote:
> On Mon, Sep 22, 2014 at 05:06:11PM +0300, Ville Syrjälä wrote:
> > > +struct skl_pipe_wm {
> > > +	struct skl_wm_level wm[8];
> > > +	struct skl_wm_level trans_wm;
> > > +	uint32_t linetime;
> > > +};
> > > +
> > >  struct intel_crtc {
> > >  	struct drm_crtc base;
> > >  	enum pipe pipe;
> > > @@ -431,9 +437,11 @@ struct intel_crtc {
> > >  	bool pch_fifo_underrun_disabled;
> > >  
> > >  	/* per-pipe watermark state */
> > > -	struct {
> > > +	union {
> > 
> > I almost gave my r-b, but then I noticed this. It's going to mess up my
> > pending watermark series. I'm going to add tons of junk here, so union
> > is not really acceptable for me. Needs some other solution.
> 
> Well, you could use an anonymous structure in that union? We could also
> try to merge skl_pipe_wm and intel_pipe_wm at a later point? or just
> leaving this a struct, wasting a tiny bit of memory be good enough for
> now?

We only have 3 pipes ... you can waste a few kb and no one will notice at
all ;-)
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 286+ messages in thread

* [PATCH 47/89 v11] drm/i915/skl: SKL Watermark Computation
  2014-09-17 12:07   ` Ville Syrjälä
  2014-09-22 22:36     ` Damien Lespiau
@ 2014-09-23 11:13     ` Damien Lespiau
  2014-10-29 17:07       ` Ville Syrjälä
  2014-09-23 11:14     ` [PATCH 47/89] " Damien Lespiau
  2 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-23 11:13 UTC (permalink / raw)
  To: intel-gfx; +Cc: Pradeep Bhat

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch implements the watermark algorithm and its necessary
functions. Two function pointers skl_update_wm and
skl_update_sprite_wm are provided. The skl_update_wm will update
the watermarks for the crtc provided as an argument and then
checks for change in DDB allocation for other active pipes and
recomputes the watermarks for those Pipes and planes as well.
Finally it does the register programming for all dirty pipes.
The trigger of the Watermark double buffer registers will have
to be once the plane configurations are done by the caller.

v2: fixed the divide-by-0 error in the results computation func.
    Also reworked the PLANE_WM register values computation func to
    make it more compact. Incorporated all other review comments
    from Damien.

v3: Changed the skl_compute_plane_wm function to now return success
    or failure. Also the result blocks and lines are computed here
    instead of in skl_compute_wm_results function.

v4: Adjust skl_ddb_alloc_changed() to the new planes/cursor split
    (Damien)

v5: Reworked the affected functions to implement new plane/cursor
    split.

v6: Rework the logic that triggers the DDB allocation and WM computation
    of skl_update_other_pipe_wm() to not depend on non-computed DDB
    values.
    Always give a valid cursor_width (at boot it's 0) to keep the
    invariant that we consider the cursor plane always enabled.
    Otherwise we end up dividing by 0 in skl_compute_plane_wm()
    (Damien Lespiau)

v7: Spell out allocation
    skl_ddb_ functions should have the ddb as first argument
    Make the skl_ddb_alloc_changed() parameters const
    (Damien)

v8: Rebase on top of the crtc->primary changes

v9: Split the staging results structure to not exceed the 1Kb stack
    allocation in skl_update_wm()

v10: Make skl_pipe_pixel_rate() take a pointer to the pipe config
     Add a comment about overflow considerations for skl_wm_method1()
     Various additions of const
     Various use of sizeof(variable) instead of sizeof(type)
     Various move of variable definitons to a narrower scope
     Zero initialize some stack allocated structures to make sure we
     don't have garbage in case we don't write all the values
     (Ville)

v11: Remove non-necessary default number of blocks/lines when the plane
     is disabled (Ville)

Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h |  12 +-
 drivers/gpu/drm/i915/intel_pm.c | 422 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 433 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0301a91..cde5136 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1722,8 +1722,18 @@ struct drm_i915_private {
 		 */
 		uint16_t skl_latency[8];
 
+		/*
+		 * The skl_wm_values structure is a bit too big for stack
+		 * allocation, so we keep the staging struct where we store
+		 * intermediate results here instead.
+		 */
+		struct skl_wm_values skl_results;
+
 		/* current hardware state */
-		struct ilk_wm_values hw;
+		union {
+			struct ilk_wm_values hw;
+			struct skl_wm_values skl_hw;
+		};
 	} wm;
 
 	struct i915_runtime_pm pm;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 768890e..e69a833 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2957,6 +2957,426 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
 	return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
 }
 
+static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_config *config)
+{
+	/* TODO: Take into account the scalers once we support them */
+	return config->adjusted_mode.crtc_clock;
+}
+
+/*
+ * The max latency should be 257 (max the punit can code is 255 and we add 2us
+ * for the read latency) and bytes_per_pixel should always be <= 8, so that
+ * should allow pixel_rate up to ~2 GHz which seems sufficient since max
+ * 2xcdclk is 1350 MHz and the pixel rate should never exceed that.
+*/
+static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel,
+			       uint32_t latency)
+{
+	uint32_t wm_intermediate_val, ret;
+
+	if (latency == 0)
+		return UINT_MAX;
+
+	wm_intermediate_val = latency * pixel_rate * bytes_per_pixel;
+	ret = DIV_ROUND_UP(wm_intermediate_val, 1000);
+
+	return ret;
+}
+
+static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
+			       uint32_t horiz_pixels, uint8_t bytes_per_pixel,
+			       uint32_t latency)
+{
+	uint32_t ret, plane_bytes_per_line, wm_intermediate_val;
+
+	if (latency == 0)
+		return UINT_MAX;
+
+	plane_bytes_per_line = horiz_pixels * bytes_per_pixel;
+	wm_intermediate_val = latency * pixel_rate;
+	ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) *
+				plane_bytes_per_line;
+
+	return ret;
+}
+
+static void skl_compute_transition_wm(struct drm_crtc *crtc,
+				  struct skl_pipe_wm_parameters *params,
+				  struct skl_pipe_wm *pipe_wm)
+{
+	/*
+	 * For now it is suggested to use the LP0 wm val of corresponding
+	 * plane as transition wm val. This is done while computing results.
+	 */
+	if (!params->active)
+		return;
+}
+
+static uint32_t
+skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p)
+{
+	if (!intel_crtc_active(crtc))
+		return 0;
+
+	return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate);
+
+}
+
+static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
+				       const struct intel_crtc *intel_crtc)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
+	enum pipe pipe = intel_crtc->pipe;
+
+	if (memcmp(new_ddb->plane[pipe], cur_ddb->plane[pipe],
+		   sizeof(new_ddb->plane[pipe])))
+		return true;
+
+	if (memcmp(&new_ddb->cursor[pipe], &cur_ddb->cursor[pipe],
+		    sizeof(new_ddb->cursor[pipe])))
+		return true;
+
+	return false;
+}
+
+static void skl_compute_wm_global_parameters(struct drm_device *dev,
+					     struct intel_wm_config *config)
+{
+	struct drm_crtc *crtc;
+	struct drm_plane *plane;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+		config->num_pipes_active += intel_crtc_active(crtc);
+
+	/* FIXME: I don't think we need those two global parameters on SKL */
+	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+		struct intel_plane *intel_plane = to_intel_plane(plane);
+
+		config->sprites_enabled |= intel_plane->wm.enabled;
+		config->sprites_scaled |= intel_plane->wm.scaled;
+	}
+}
+
+static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
+					   struct skl_pipe_wm_parameters *p)
+{
+	struct drm_device *dev = crtc->dev;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	enum pipe pipe = intel_crtc->pipe;
+	struct drm_plane *plane;
+	int i = 1; /* Index for sprite planes start */
+
+	p->active = intel_crtc_active(crtc);
+	if (p->active) {
+		p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal;
+		p->pixel_rate = skl_pipe_pixel_rate(&intel_crtc->config);
+
+		/*
+		 * For now, assume primary and cursor planes are always enabled.
+		 */
+		p->plane[0].enabled = true;
+		p->plane[0].bytes_per_pixel =
+			crtc->primary->fb->bits_per_pixel / 8;
+		p->plane[0].horiz_pixels = intel_crtc->config.pipe_src_w;
+		p->plane[0].vert_pixels = intel_crtc->config.pipe_src_h;
+
+		p->cursor.enabled = true;
+		p->cursor.bytes_per_pixel = 4;
+		p->cursor.horiz_pixels = intel_crtc->cursor_width ?
+					 intel_crtc->cursor_width : 64;
+	}
+
+	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+		struct intel_plane *intel_plane = to_intel_plane(plane);
+
+		if (intel_plane->pipe == pipe)
+			p->plane[i++] = intel_plane->wm;
+	}
+}
+
+static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
+				   struct intel_plane_wm_parameters *p_params,
+				   uint16_t max_page_buff_alloc,
+				   uint32_t mem_value,
+				   uint16_t *res_blocks, /* out */
+				   uint8_t *res_lines /* out */)
+{
+	uint32_t method1, method2, plane_bytes_per_line;
+	uint32_t result_bytes;
+
+	if (!p->active || !p_params->enabled)
+		return false;
+
+	method1 = skl_wm_method1(p->pixel_rate,
+				 p_params->bytes_per_pixel,
+				 mem_value);
+	method2 = skl_wm_method2(p->pixel_rate,
+				 p->pipe_htotal,
+				 p_params->horiz_pixels,
+				 p_params->bytes_per_pixel,
+				 mem_value);
+
+	plane_bytes_per_line = p_params->horiz_pixels *
+					p_params->bytes_per_pixel;
+
+	/* For now xtile and linear */
+	if (((max_page_buff_alloc * 512) / plane_bytes_per_line) >= 1)
+		result_bytes = min(method1, method2);
+	else
+		result_bytes = method1;
+
+	*res_blocks = DIV_ROUND_UP(result_bytes, 512) + 1;
+	*res_lines = DIV_ROUND_UP(result_bytes, plane_bytes_per_line);
+
+	return true;
+}
+
+static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
+				 struct skl_ddb_allocation *ddb,
+				 struct skl_pipe_wm_parameters *p,
+				 enum pipe pipe,
+				 int level,
+				 int num_planes,
+				 struct skl_wm_level *result)
+{
+	uint16_t latency = dev_priv->wm.skl_latency[level];
+	uint16_t ddb_blocks;
+	int i;
+
+	for (i = 0; i < num_planes; i++) {
+		ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
+
+		result->plane_en[i] = skl_compute_plane_wm(p, &p->plane[i],
+						ddb_blocks,
+						latency,
+						&result->plane_res_b[i],
+						&result->plane_res_l[i]);
+	}
+
+	ddb_blocks = skl_ddb_entry_size(&ddb->cursor[pipe]);
+	result->cursor_en = skl_compute_plane_wm(p, &p->cursor, ddb_blocks,
+						 latency, &result->cursor_res_b,
+						 &result->cursor_res_l);
+}
+
+static void skl_compute_pipe_wm(struct drm_crtc *crtc,
+				struct skl_ddb_allocation *ddb,
+				struct skl_pipe_wm_parameters *params,
+				struct skl_pipe_wm *pipe_wm)
+{
+	struct drm_device *dev = crtc->dev;
+	const struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int level, max_level = ilk_wm_max_level(dev);
+
+	for (level = 0; level <= max_level; level++) {
+		skl_compute_wm_level(dev_priv, ddb, params, intel_crtc->pipe,
+				     level, intel_num_planes(intel_crtc),
+				     &pipe_wm->wm[level]);
+	}
+	pipe_wm->linetime = skl_compute_linetime_wm(crtc, params);
+
+	skl_compute_transition_wm(crtc, params, pipe_wm);
+}
+
+static void skl_compute_wm_results(struct drm_device *dev,
+				   struct skl_pipe_wm_parameters *p,
+				   struct skl_pipe_wm *p_wm,
+				   struct skl_wm_values *r,
+				   struct intel_crtc *intel_crtc)
+{
+	int level, max_level = ilk_wm_max_level(dev);
+	enum pipe pipe = intel_crtc->pipe;
+
+	for (level = 0; level <= max_level; level++) {
+		uint16_t ddb_blocks;
+		uint32_t temp;
+		int i;
+
+		for (i = 0; i < intel_num_planes(intel_crtc); i++) {
+			temp = 0;
+			ddb_blocks = skl_ddb_entry_size(&r->ddb.plane[pipe][i]);
+
+			if ((p_wm->wm[level].plane_res_b[i] > ddb_blocks) ||
+				(p_wm->wm[level].plane_res_l[i] > 31))
+				p_wm->wm[level].plane_en[i] = false;
+
+			temp |= p_wm->wm[level].plane_res_l[i] <<
+					PLANE_WM_LINES_SHIFT;
+			temp |= p_wm->wm[level].plane_res_b[i];
+			if (p_wm->wm[level].plane_en[i])
+				temp |= PLANE_WM_EN;
+
+			r->plane[pipe][i][level] = temp;
+			/* Use the LP0 WM value for transition WM for now. */
+			if (level == 0)
+				r->plane_trans[pipe][i] = temp;
+		}
+
+		temp = 0;
+		ddb_blocks = skl_ddb_entry_size(&r->ddb.cursor[pipe]);
+
+		if ((p_wm->wm[level].cursor_res_b > ddb_blocks) ||
+			(p_wm->wm[level].cursor_res_l > 31))
+			p_wm->wm[level].cursor_en = false;
+
+		temp |= p_wm->wm[level].cursor_res_l << PLANE_WM_LINES_SHIFT;
+		temp |= p_wm->wm[level].cursor_res_b;
+
+		if (p_wm->wm[level].cursor_en)
+			temp |= PLANE_WM_EN;
+
+		r->cursor[pipe][level] = temp;
+		/* Use the LP0 WM value for transition WM for now. */
+		if (level == 0)
+			r->cursor_trans[pipe] = temp;
+
+	}
+
+	r->wm_linetime[pipe] = p_wm->linetime;
+}
+
+static void skl_write_wm_values(struct drm_i915_private *dev_priv,
+				const struct skl_wm_values *new)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct intel_crtc *crtc;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
+		int i, level, max_level = ilk_wm_max_level(dev);
+		enum pipe pipe = crtc->pipe;
+
+		if (new->dirty[pipe]) {
+			I915_WRITE(PIPE_WM_LINETIME(pipe),
+					new->wm_linetime[pipe]);
+
+			for (level = 0; level <= max_level; level++) {
+				for (i = 0; i < intel_num_planes(crtc); i++)
+					I915_WRITE(PLANE_WM(pipe, i, level),
+						new->plane[pipe][i][level]);
+				I915_WRITE(CUR_WM(pipe, level),
+					new->cursor[pipe][level]);
+			}
+			for (i = 0; i < intel_num_planes(crtc); i++)
+				I915_WRITE(PLANE_WM_TRANS(pipe, i),
+						new->plane_trans[pipe][i]);
+			I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
+		}
+	}
+
+	dev_priv->wm.skl_hw = *new;
+}
+
+static bool skl_update_pipe_wm(struct drm_crtc *crtc,
+			       struct skl_pipe_wm_parameters *params,
+			       struct intel_wm_config *config,
+			       struct skl_ddb_allocation *ddb, /* out */
+			       struct skl_pipe_wm *pipe_wm /* out */)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	skl_compute_wm_pipe_parameters(crtc, params);
+	skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
+
+	if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
+		return false;
+
+	intel_crtc->wm.skl_active = *pipe_wm;
+	return true;
+}
+
+static void skl_update_other_pipe_wm(struct drm_device *dev,
+				     struct drm_crtc *crtc,
+				     struct intel_wm_config *config,
+				     struct skl_wm_values *r)
+{
+	struct intel_crtc *intel_crtc;
+	struct intel_crtc *this_crtc = to_intel_crtc(crtc);
+
+	/*
+	 * If the WM update hasn't changed the allocation for this_crtc (the
+	 * crtc we are currently computing the new WM values for), other
+	 * enabled crtcs will keep the same allocation and we don't need to
+	 * recompute anything for them.
+	 */
+	if (!skl_ddb_allocation_changed(&r->ddb, this_crtc))
+		return;
+
+	/*
+	 * Otherwise, because of this_crtc being freshly enabled/disabled, the
+	 * other active pipes need new DDB allocation and WM values.
+	 */
+	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
+				base.head) {
+		struct skl_pipe_wm_parameters params = {};
+		struct skl_pipe_wm pipe_wm = {};
+		bool wm_changed;
+
+		if (this_crtc->pipe == intel_crtc->pipe)
+			continue;
+
+		if (!intel_crtc->active)
+			continue;
+
+		wm_changed = skl_update_pipe_wm(&intel_crtc->base,
+						&params, config,
+						&r->ddb, &pipe_wm);
+
+		/*
+		 * If we end up re-computing the other pipe WM values, it's
+		 * because it was really needed, so we expect the WM values to
+		 * be different.
+		 */
+		WARN_ON(!wm_changed);
+
+		skl_compute_wm_results(dev, &params, &pipe_wm, r, intel_crtc);
+		r->dirty[intel_crtc->pipe] = true;
+	}
+}
+
+static void skl_update_wm(struct drm_crtc *crtc)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct skl_pipe_wm_parameters params = {};
+	struct skl_wm_values *results = &dev_priv->wm.skl_results;
+	struct skl_pipe_wm pipe_wm = {};
+	struct intel_wm_config config = {};
+
+	memset(results, 0, sizeof(*results));
+
+	skl_compute_wm_global_parameters(dev, &config);
+
+	if (!skl_update_pipe_wm(crtc, &params, &config,
+				&results->ddb, &pipe_wm))
+		return;
+
+	skl_compute_wm_results(dev, &params, &pipe_wm, results, intel_crtc);
+	results->dirty[intel_crtc->pipe] = true;
+
+	skl_update_other_pipe_wm(dev, crtc, &config, results);
+	skl_write_wm_values(dev_priv, results);
+}
+
+static void
+skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc,
+		     uint32_t sprite_width, uint32_t sprite_height,
+		     int pixel_size, bool enabled, bool scaled)
+{
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+
+	intel_plane->wm.enabled = enabled;
+	intel_plane->wm.scaled = scaled;
+	intel_plane->wm.horiz_pixels = sprite_width;
+	intel_plane->wm.vert_pixels = sprite_height;
+	intel_plane->wm.bytes_per_pixel = pixel_size;
+
+	skl_update_wm(crtc);
+}
+
 static void ilk_update_wm(struct drm_crtc *crtc)
 {
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -7486,6 +7906,8 @@ void intel_init_pm(struct drm_device *dev)
 		skl_setup_wm_latency(dev);
 
 		dev_priv->display.init_clock_gating = gen9_init_clock_gating;
+		dev_priv->display.update_wm = skl_update_wm;
+		dev_priv->display.update_sprite_wm = skl_update_sprite_wm;
 	} else if (HAS_PCH_SPLIT(dev)) {
 		ilk_setup_wm_latency(dev);
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* Re: [PATCH 47/89] drm/i915/skl: SKL Watermark Computation
  2014-09-17 12:07   ` Ville Syrjälä
  2014-09-22 22:36     ` Damien Lespiau
  2014-09-23 11:13     ` [PATCH 47/89 v11] " Damien Lespiau
@ 2014-09-23 11:14     ` Damien Lespiau
  2 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-23 11:14 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Wed, Sep 17, 2014 at 03:07:51PM +0300, Ville Syrjälä wrote:
> On Thu, Sep 04, 2014 at 12:27:13PM +0100, Damien Lespiau wrote:
> > From: Pradeep Bhat <pradeep.bhat@intel.com>
> > 
> > This patch implements the watermark algorithm and its necessary
> > functions. Two function pointers skl_update_wm and
> > skl_update_sprite_wm are provided. The skl_update_wm will update
> > the watermarks for the crtc provided as an argument and then
> > checks for change in DDB allocation for other active pipes and
> > recomputes the watermarks for those Pipes and planes as well.
> > Finally it does the register programming for all dirty pipes.
> > The trigger of the Watermark double buffer registers will have
> > to be once the plane configurations are done by the caller.
> > 
> > v2: fixed the divide-by-0 error in the results computation func.
> >     Also reworked the PLANE_WM register values computation func to
> >     make it more compact. Incorporated all other review comments
> >     from Damien.
> > 
> > v3: Changed the skl_compute_plane_wm function to now return success
> >     or failure. Also the result blocks and lines are computed here
> >     instead of in skl_compute_wm_results function.
> > 
> > v4: Adjust skl_ddb_alloc_changed() to the new planes/cursor split
> >     (Damien)
> > 
> > v5: Reworked the affected functions to implement new plane/cursor
> >     split.
> > 
> > v6: Rework the logic that triggers the DDB allocation and WM computation
> >     of skl_update_other_pipe_wm() to not depend on non-computed DDB
> >     values.
> >     Always give a valid cursor_width (at boot it's 0) to keep the
> >     invariant that we consider the cursor plane always enabled.
> >     Otherwise we end up dividing by 0 in skl_compute_plane_wm()
> >     (Damien Lespiau)
> > 
> > v7: Spell out allocation
> >     skl_ddb_ functions should have the ddb as first argument
> >     Make the skl_ddb_alloc_changed() parameters const
> >     (Damien)
> > 
> > v8: Rebase on top of the crtc->primary changes
> > 
> > v9: Split the staging results structure to not exceed the 1Kb stack
> >     allocation in skl_update_wm()
> > 
> > Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> > 
> > drm/i915/skl: Don't allocate as much on the stack in skl_update_wm()
> > 
> > Stack space can be scarce and a compiler check has been added to warn if the
> > per-function stack allocation is above 1KB.
> > 
> > We we were hitting that warning in skl_update_wm(), so move the big
> > results array in dev_priv instead.
> > 
> > For reference, here's the compiler warning before this patch:
> > 
> >   drivers/gpu/drm/i915/intel_pm.c: In function ‘skl_update_wm’:
> >   drivers/gpu/drm/i915/intel_pm.c:3618:1: warning: the frame size of 1296 bytes
> >     is larger than 1024 bytes [-Wframe-larger-than=]
> > 
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

So, v11 is answering all the review comments below  but two, which I
think need a proper diff to develop and review comfortably, so I'll send
them on their own (and then we could them as separate patches or
squashed into this one). The two changes in question are:
 
  1/ put the (temporary) transition WM computation in the eponymous
     function instead of resolving it at compute_results time

  2/ Move the validity checks inside the compute function

-- 
Damien

> > ---
> >  drivers/gpu/drm/i915/i915_drv.h |  12 +-
> >  drivers/gpu/drm/i915/intel_pm.c | 423 ++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 434 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index de278a5..9b0e398 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -1709,8 +1709,18 @@ struct drm_i915_private {
> >  		 */
> >  		uint16_t skl_latency[8];
> >  
> > +		/*
> > +		 * The skl_wm_values structure is a bit too big for stack
> > +		 * allocation, so we keep the staging struct where we store
> > +		 * intermediate results here instead.
> > +		 */
> > +		struct skl_wm_values skl_results;
> > +
> >  		/* current hardware state */
> > -		struct ilk_wm_values hw;
> > +		union {
> > +			struct ilk_wm_values hw;
> > +			struct skl_wm_values skl_hw;
> > +		};
> >  	} wm;
> >  
> >  	struct i915_runtime_pm pm;
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index 2503ab9..4ee90b6 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -2937,6 +2937,427 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
> >  	return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
> >  }
> >  
> > +static uint32_t skl_pipe_pixel_rate(struct drm_device *dev,
> > +				    struct drm_crtc *crtc)
> > +{
> > +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +	uint32_t pixel_rate;
> > +
> > +	pixel_rate = intel_crtc->config.adjusted_mode.crtc_clock;
> > +
> > +	return pixel_rate;
> > +}
> 
> I changed the ilk version to take just the pipe config as a parameter.
> This should be changed to do the same. I'm not entirely sure it makes
> sense to have this function around until pipe scaling is implemented,
> but I guess it serves as a decent reminder that something needs to be
> done here.
> 
> > +
> > +static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel,
> > +			       uint32_t latency)
> > +{
> > +	uint32_t wm_intermediate_val, ret;
> > +
> > +	if (latency == 0)
> > +		return UINT_MAX;
> > +
> > +	wm_intermediate_val = latency * pixel_rate * bytes_per_pixel;
> 
> I was a bit worried if we have enough bits here, but max latency should
> be 0xff and bytes_per_pixel should always be <=8, so that should allow
> pixel_rate up to ~2 GHz which seems sufficient since max 2xcdclk is
> 1350 MHz and the pixel rate should never exceed that. Not that we have
> such checks anywhere at the moment, but we should eventually add them.
> 
> > +	ret = DIV_ROUND_UP(wm_intermediate_val, 1000);
> > +
> > +	return ret;
> > +}
> > +
> > +static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
> > +			       uint32_t horiz_pixels, uint8_t bytes_per_pixel,
> > +			       uint32_t latency)
> > +{
> > +	uint32_t ret, plane_bytes_per_line, wm_intermediate_val;
> > +
> > +	if (latency == 0)
> > +		return UINT_MAX;
> > +
> > +	plane_bytes_per_line = horiz_pixels * bytes_per_pixel;
> > +	wm_intermediate_val = latency * pixel_rate;
> > +	ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) *
> > +				plane_bytes_per_line;
> > +
> > +	return ret;
> > +}
> > +
> > +static void skl_compute_transition_wm(struct drm_crtc *crtc,
> > +				  struct skl_pipe_wm_parameters *params,
> > +				  struct skl_pipe_wm *pipe_wm)
> > +{
> > +	/*
> > +	 * For now it is suggested to use the LP0 wm val of corresponding
> > +	 * plane as transition wm val. This is done while computing results.
> > +	 */
> > +	if (!params->active)
> > +		return;
> > +}
> 
> Seems like a rather pointless function.
> 
> > +
> > +static uint32_t
> > +skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p)
> > +{
> > +	if (!intel_crtc_active(crtc))
> > +		return 0;
> > +
> > +	return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate);
> > +
> > +}
> > +
> > +static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
> > +				       const struct intel_crtc *intel_crtc)
> > +{
> > +	struct drm_device *dev = intel_crtc->base.dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
> 
> const
> 
> > +	enum pipe pipe = intel_crtc->pipe;
> > +	size_t size;
> > +
> > +	size = ARRAY_SIZE(new_ddb->plane[pipe]) * sizeof(struct skl_ddb_entry);
> 
> sizeof(new_ddb->plane[pipe])
> 
> > +	if (memcmp(new_ddb->plane[pipe], cur_ddb->plane[pipe], size))
> > +		return true;
> > +
> > +	if (memcmp(&new_ddb->cursor[pipe], &cur_ddb->cursor[pipe],
> > +		    sizeof(struct skl_ddb_entry)))
> 
> sizeof(new_ddb->cursor[pipe])
> 
> > +		return true;
> > +
> > +	return false;
> > +}
> > +
> > +static void skl_compute_wm_global_parameters(struct drm_device *dev,
> > +					     struct intel_wm_config *config)
> > +{
> > +	struct drm_crtc *crtc;
> > +	struct drm_plane *plane;
> > +
> > +	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
> > +		config->num_pipes_active += intel_crtc_active(crtc);
> > +
> > +	/* FIXME: I don't think we need those two global parameters on SKL */
> > +	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> > +		struct intel_plane *intel_plane = to_intel_plane(plane);
> > +
> > +		config->sprites_enabled |= intel_plane->wm.enabled;
> > +		config->sprites_scaled |= intel_plane->wm.scaled;
> > +	}
> > +}
> > +
> > +static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
> > +					   struct skl_pipe_wm_parameters *p)
> > +{
> > +	struct drm_device *dev = crtc->dev;
> > +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +	enum pipe pipe = intel_crtc->pipe;
> > +	struct drm_plane *plane;
> > +	int i = 1; /* Index for sprite planes start */
> > +
> > +	p->active = intel_crtc_active(crtc);
> > +	if (p->active) {
> > +		p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal;
> > +		p->pixel_rate = skl_pipe_pixel_rate(dev, crtc);
> > +
> > +		/*
> > +		 * For now, assume primary and cursor planes are always enabled.
> > +		 */
> > +		p->plane[0].enabled = true;
> > +		p->plane[0].bytes_per_pixel =
> > +			crtc->primary->fb->bits_per_pixel / 8;
> > +		p->plane[0].horiz_pixels = intel_crtc->config.pipe_src_w;
> > +		p->plane[0].vert_pixels = intel_crtc->config.pipe_src_h;
> > +
> > +		p->cursor.enabled = true;
> > +		p->cursor.bytes_per_pixel = 4;
> > +		p->cursor.horiz_pixels = intel_crtc->cursor_width ?
> > +					 intel_crtc->cursor_width : 64;
> > +	}
> > +
> > +	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> > +		struct intel_plane *intel_plane = to_intel_plane(plane);
> > +
> > +		if (intel_plane->pipe == pipe)
> > +			p->plane[i++] = intel_plane->wm;
> > +	}
> > +}
> > +
> > +static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
> > +				   struct intel_plane_wm_parameters *p_params,
> > +				   uint16_t max_page_buff_alloc,
> > +				   uint32_t mem_value,
> > +				   uint16_t *res_blocks, /* out */
> > +				   uint8_t *res_lines /* out */)
> > +{
> > +	uint32_t method1, method2, plane_bytes_per_line;
> > +	uint32_t result_bytes;
> > +
> > +	if (!p->active || !p_params->enabled) {
> > +		*res_blocks = PLANE_WM_BLOCKS_DEFAULT;
> > +		*res_lines = PLANE_WM_LINES_DEFAULT;
> 
> Why do we need to set !=0 values for disabled planes?
> 
> > +		return false;
> > +	}
> > +
> > +	method1 = skl_wm_method1(p->pixel_rate,
> > +				 p_params->bytes_per_pixel,
> > +				 mem_value);
> > +	method2 = skl_wm_method2(p->pixel_rate,
> > +				 p->pipe_htotal,
> > +				 p_params->horiz_pixels,
> > +				 p_params->bytes_per_pixel,
> > +				 mem_value);
> > +
> > +	plane_bytes_per_line = p_params->horiz_pixels *
> > +					p_params->bytes_per_pixel;
> > +
> > +	/* For now xtile and linear */
> > +	if (((max_page_buff_alloc * 512) / plane_bytes_per_line) >= 1)
> > +		result_bytes = min(method1, method2);
> > +	else
> > +		result_bytes = method1;
> > +
> > +	*res_blocks = DIV_ROUND_UP(result_bytes, 512) + 1;
> > +	*res_lines = DIV_ROUND_UP(result_bytes, plane_bytes_per_line);
> > +
> 
> Seems we're missing the final validity checks here.
> 
> > +	return true;
> > +}
> > +
> > +static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
> > +				 struct skl_ddb_allocation *ddb,
> > +				 struct skl_pipe_wm_parameters *p,
> > +				 enum pipe pipe,
> > +				 int level,
> > +				 int num_planes,
> > +				 struct skl_wm_level *result)
> > +{
> > +	uint16_t latency = dev_priv->wm.skl_latency[level];
> > +	uint16_t ddb_blocks;
> > +	int i;
> > +
> > +	for (i = 0; i < num_planes; i++) {
> > +		ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
> > +
> > +		result->plane_en[i] = skl_compute_plane_wm(p, &p->plane[i],
> > +						ddb_blocks,
> > +						latency,
> > +						&result->plane_res_b[i],
> > +						&result->plane_res_l[i]);
> > +	}
> > +
> > +	ddb_blocks = skl_ddb_entry_size(&ddb->cursor[pipe]);
> > +	result->cursor_en = skl_compute_plane_wm(p, &p->cursor, ddb_blocks,
> > +						 latency, &result->cursor_res_b,
> > +						 &result->cursor_res_l);
> > +}
> > +
> > +static void skl_compute_pipe_wm(struct drm_crtc *crtc,
> > +				struct skl_ddb_allocation *ddb,
> > +				struct skl_pipe_wm_parameters *params,
> > +				struct skl_pipe_wm *pipe_wm)
> > +{
> > +	struct drm_device *dev = crtc->dev;
> > +	const struct drm_i915_private *dev_priv = dev->dev_private;
> > +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +	int level, max_level = ilk_wm_max_level(dev);
> > +
> > +	for (level = 0; level <= max_level; level++) {
> > +		skl_compute_wm_level(dev_priv, ddb, params, intel_crtc->pipe,
> > +				     level, intel_num_planes(intel_crtc),
> > +				     &pipe_wm->wm[level]);
> > +	}
> > +	pipe_wm->linetime = skl_compute_linetime_wm(crtc, params);
> > +
> > +	skl_compute_transition_wm(crtc, params, pipe_wm);
> > +}
> > +
> > +static void skl_compute_wm_results(struct drm_device *dev,
> > +				   struct skl_pipe_wm_parameters *p,
> > +				   struct skl_pipe_wm *p_wm,
> > +				   struct skl_wm_values *r,
> > +				   struct intel_crtc *intel_crtc)
> > +{
> > +	int i, level, max_level = ilk_wm_max_level(dev);
> > +	uint32_t temp;
> > +	enum pipe pipe = intel_crtc->pipe;
> > +	uint16_t ddb_blocks;
> 
> Could move a bunch of that to a narrower scope.
> 
> > +
> > +	for (level = 0; level <= max_level; level++) {
> > +		for (i = 0; i < intel_num_planes(intel_crtc); i++) {
> > +			temp = 0;
> > +			ddb_blocks = skl_ddb_entry_size(&r->ddb.plane[pipe][i]);
> > +
> > +			if ((p_wm->wm[level].plane_res_b[i] > ddb_blocks) ||
> > +				(p_wm->wm[level].plane_res_l[i] > 31))
> > +				p_wm->wm[level].plane_en[i] = false;
> 
> So the validity check is here that I was expecting in skl_compute_plane_wm().
> The way this is done makes me think we might overflow the register
> bitfields if invalid values are propagated this far.
> 
> The way the ilk code works is that it won't ever keep around intermediate
> values that would exceed the register maximum values (such values are
> already dropped in intel_compute_pipe_wm()), and then it will filter out
> the otherwise invalid values in ilk_wm_merge() before ilk_compute_wm_results()
> gets called. Would seem less surprising if we could follow a similar
> pattern in the skl code.
> 
> > +
> > +			temp |= p_wm->wm[level].plane_res_l[i] <<
> > +					PLANE_WM_LINES_SHIFT;
> > +			temp |= p_wm->wm[level].plane_res_b[i];
> > +			if (p_wm->wm[level].plane_en[i])
> > +				temp |= PLANE_WM_EN;
> > +
> > +			r->plane[pipe][i][level] = temp;
> > +			/* Use the LP0 WM value for transition WM for now. */
> > +			if (level == 0)
> > +				r->plane_trans[pipe][i] = temp;
> 
> I'd stick this special case into the compute function rather than here.
> 
> > +		}
> > +
> > +		temp = 0;
> > +		ddb_blocks = skl_ddb_entry_size(&r->ddb.cursor[pipe]);
> > +
> > +		if ((p_wm->wm[level].cursor_res_b > ddb_blocks) ||
> > +			(p_wm->wm[level].cursor_res_l > 31))
> > +			p_wm->wm[level].cursor_en = false;
> > +
> > +		temp |= p_wm->wm[level].cursor_res_l << PLANE_WM_LINES_SHIFT;
> > +		temp |= p_wm->wm[level].cursor_res_b;
> > +
> > +		if (p_wm->wm[level].cursor_en)
> > +			temp |= PLANE_WM_EN;
> > +
> > +		r->cursor[pipe][level] = temp;
> > +		/* Use the LP0 WM value for transition WM for now. */
> > +		if (level == 0)
> > +			r->cursor_trans[pipe] = temp;
> > +
> > +	}
> > +
> > +	r->wm_linetime[pipe] = p_wm->linetime;
> > +}
> > +
> > +static void skl_write_wm_values(struct drm_i915_private *dev_priv,
> > +				struct skl_wm_values *new)
> 
> const
> 
> > +{
> > +	struct drm_device *dev = dev_priv->dev;
> > +	struct intel_crtc *crtc;
> > +	int i, level, max_level = ilk_wm_max_level(dev);
> > +	enum pipe pipe;
> 
> More stuff that could live in a narrower scope.
> 
> > +
> > +	list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
> > +		pipe = crtc->pipe;
> > +		if (new->dirty[pipe]) {
> > +			I915_WRITE(PIPE_WM_LINETIME(pipe),
> > +					new->wm_linetime[pipe]);
> > +
> > +			for (level = 0; level <= max_level; level++) {
> > +				for (i = 0; i < intel_num_planes(crtc); i++)
> > +					I915_WRITE(PLANE_WM(pipe, i, level),
> > +						new->plane[pipe][i][level]);
> > +				I915_WRITE(CUR_WM(pipe, level),
> > +					new->cursor[pipe][level]);
> > +			}
> > +			for (i = 0; i < intel_num_planes(crtc); i++)
> > +				I915_WRITE(PLANE_WM_TRANS(pipe, i),
> > +						new->plane_trans[pipe][i]);
> > +			I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
> > +		}
> > +	}
> > +
> > +	dev_priv->wm.skl_hw = *new;
> > +}
> > +
> > +static bool skl_update_pipe_wm(struct drm_crtc *crtc,
> > +			       struct skl_pipe_wm_parameters *params,
> > +			       struct intel_wm_config *config,
> > +			       struct skl_ddb_allocation *ddb, /* out */
> > +			       struct skl_pipe_wm *pipe_wm /* out */)
> > +{
> > +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +
> > +	skl_compute_wm_pipe_parameters(crtc, params);
> > +	skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
> > +
> > +	if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
> > +		return false;
> > +
> > +	intel_crtc->wm.skl_active = *pipe_wm;
> > +	return true;
> > +}
> > +
> > +static void skl_update_other_pipe_wm(struct drm_device *dev,
> > +				     struct drm_crtc *crtc,
> > +				     struct intel_wm_config *config,
> > +				     struct skl_wm_values *r)
> > +{
> > +	struct intel_crtc *intel_crtc;
> > +	struct intel_crtc *this_crtc = to_intel_crtc(crtc);
> > +	struct skl_pipe_wm_parameters params;
> > +	struct skl_pipe_wm pipe_wm;
> 
> More stuff that can be moved to a narrower scope.
> 
> Should these be zero initializd? At least the way the ilk code works
> is that most structures need zero initialization to avoid consulting
> stack garbage somewhere down the line.
> 
> > +
> > +	/*
> > +	 * If the WM update hasn't changed the allocation for this_crtc (the
> > +	 * crtc we are currently computing the new WM values for), other
> > +	 * enabled crtcs will keep the same allocation and we don't need to
> > +	 * recompute anything for them.
> > +	 */
> > +	if (!skl_ddb_allocation_changed(&r->ddb, this_crtc))
> > +		return;
> > +
> > +	/*
> > +	 * Otherwise, because of this_crtc being freshly enabled/disabled, the
> > +	 * other active pipes need new DDB allocation and WM values.
> > +	 */
> > +	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
> > +				base.head) {
> 
> Not sure how the locking is planned here. In the ilk wm patches that are
> still pending I'm adding a wm.mutex which might fit the bill. Otherwise
> we're going to need to make sure we have all the crtc locks held here.
> 
> Also if multiple pipes are active we surely can't just go changing the
> DDB allocation without considering the fact that vblanks for all pipes
> don't occur at the same time. So some kind of heavy handed
> synchronization is needed to make sure none of the DDB allocations
> overlap even for a short period of time.
> 
> > +		bool wm_changed;
> > +
> > +		if (this_crtc->pipe == intel_crtc->pipe)
> > +			continue;
> > +
> > +		if (!intel_crtc->active)
> > +			continue;
> > +
> > +		wm_changed = skl_update_pipe_wm(&intel_crtc->base,
> > +						&params, config,
> > +						&r->ddb, &pipe_wm);
> > +
> > +		/*
> > +		 * If we end up re-computing the other pipe WM values, it's
> > +		 * because it was really needed, so we expect the WM values to
> > +		 * be different.
> > +		 */
> > +		WARN_ON(!wm_changed);
> > +
> > +		skl_compute_wm_results(dev, &params, &pipe_wm, r, intel_crtc);
> > +		r->dirty[intel_crtc->pipe] = true;
> > +	}
> > +}
> > +
> > +static void skl_update_wm(struct drm_crtc *crtc)
> > +{
> > +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +	struct drm_device *dev = crtc->dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	struct skl_pipe_wm_parameters params = {};
> > +	struct skl_wm_values *results = &dev_priv->wm.skl_results;
> > +	struct skl_pipe_wm pipe_wm = {};
> > +	struct intel_wm_config config = {};
> > +
> > +	memset(results, 0, sizeof(*results));
> > +
> > +	skl_compute_wm_global_parameters(dev, &config);
> > +
> > +	if (!skl_update_pipe_wm(crtc, &params, &config,
> > +				&results->ddb, &pipe_wm))
> > +		return;
> > +
> > +	skl_compute_wm_results(dev, &params, &pipe_wm, results, intel_crtc);
> > +	results->dirty[intel_crtc->pipe] = true;
> > +
> > +	skl_update_other_pipe_wm(dev, crtc, &config, results);
> > +	skl_write_wm_values(dev_priv, results);
> > +}
> > +
> > +static void
> > +skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc,
> > +		     uint32_t sprite_width, uint32_t sprite_height,
> > +		     int pixel_size, bool enabled, bool scaled)
> > +{
> > +	struct intel_plane *intel_plane = to_intel_plane(plane);
> > +
> > +	intel_plane->wm.enabled = enabled;
> > +	intel_plane->wm.scaled = scaled;
> > +	intel_plane->wm.horiz_pixels = sprite_width;
> > +	intel_plane->wm.vert_pixels = sprite_height;
> > +	intel_plane->wm.bytes_per_pixel = pixel_size;
> > +
> > +	skl_update_wm(crtc);
> > +}
> > +
> >  static void ilk_update_wm(struct drm_crtc *crtc)
> >  {
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > @@ -7464,6 +7885,8 @@ void intel_init_pm(struct drm_device *dev)
> >  		skl_setup_wm_latency(dev);
> >  
> >  		dev_priv->display.init_clock_gating = gen9_init_clock_gating;
> > +		dev_priv->display.update_wm = skl_update_wm;
> > +		dev_priv->display.update_sprite_wm = skl_update_sprite_wm;
> >  	} else if (HAS_PCH_SPLIT(dev)) {
> >  		ilk_setup_wm_latency(dev);
> >  
> > -- 
> > 1.8.3.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Ville Syrjälä
> Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* [PATCH 44/89 v5] drm/i915/skl: Register definitions and macros for SKL Watermark regs
  2014-09-04 11:27 ` [PATCH 44/89] drm/i915/skl: Register definitions and macros for SKL Watermark regs Damien Lespiau
  2014-09-10 18:04   ` Ville Syrjälä
@ 2014-09-23 11:17   ` Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-23 11:17 UTC (permalink / raw)
  To: intel-gfx; +Cc: Pradeep Bhat

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch defines SKL specific PLANE_WM Watermark registers. It also
defines macros to get the addresses of different LP levels within a pipe.

v2: Reworked the register definitions and associated macros to make it more
    generic and be able to use for_each_pipe in values computation.
    Incorporated Damien's review comments and indentation.

v3: Added default values for lines and blocks. Provided mask for blocks.

v4: Prefix intermedidate (internal-only) macros with _ (Ville)

v5: Remove the lines and block defaults value (Ville)

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> (v4)
Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index e5e45a6..e72e0e05 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4078,6 +4078,41 @@ enum punit_power_well {
 #define I965_CURSOR_MAX_WM	32
 #define I965_CURSOR_DFT_WM	8
 
+/* Watermark register definitions for SKL */
+#define CUR_WM_A_0		0x70140
+#define CUR_WM_B_0		0x71140
+#define PLANE_WM_1_A_0		0x70240
+#define PLANE_WM_1_B_0		0x71240
+#define PLANE_WM_2_A_0		0x70340
+#define PLANE_WM_2_B_0		0x71340
+#define PLANE_WM_TRANS_1_A_0	0x70268
+#define PLANE_WM_TRANS_1_B_0	0x71268
+#define PLANE_WM_TRANS_2_A_0	0x70368
+#define PLANE_WM_TRANS_2_B_0	0x71368
+#define CUR_WM_TRANS_A_0	0x70168
+#define CUR_WM_TRANS_B_0	0x71168
+#define   PLANE_WM_EN		(1 << 31)
+#define   PLANE_WM_LINES_SHIFT	14
+#define   PLANE_WM_LINES_MASK	0x1f
+#define   PLANE_WM_BLOCKS_MASK	0x3ff
+
+#define CUR_WM_0(pipe) _PIPE(pipe, CUR_WM_A_0, CUR_WM_B_0)
+#define CUR_WM(pipe, level) (CUR_WM_0(pipe) + ((4) * (level)))
+#define CUR_WM_TRANS(pipe) _PIPE(pipe, CUR_WM_TRANS_A_0, CUR_WM_TRANS_B_0)
+
+#define _PLANE_WM_1(pipe) _PIPE(pipe, PLANE_WM_1_A_0, PLANE_WM_1_B_0)
+#define _PLANE_WM_2(pipe) _PIPE(pipe, PLANE_WM_2_A_0, PLANE_WM_2_B_0)
+#define _PLANE_WM_BASE(pipe, plane)	\
+			_PLANE(plane, _PLANE_WM_1(pipe), _PLANE_WM_2(pipe))
+#define PLANE_WM(pipe, plane, level)	\
+			(_PLANE_WM_BASE(pipe, plane) + ((4) * (level)))
+#define _PLANE_WM_TRANS_1(pipe)	\
+			_PIPE(pipe, PLANE_WM_TRANS_1_A_0, PLANE_WM_TRANS_1_B_0)
+#define _PLANE_WM_TRANS_2(pipe)	\
+			_PIPE(pipe, PLANE_WM_TRANS_2_A_0, PLANE_WM_TRANS_2_B_0)
+#define PLANE_WM_TRANS(pipe, plane)	\
+		_PLANE(plane, _PLANE_WM_TRANS_1(pipe), _PLANE_WM_TRANS_2(pipe))
+
 /* define the Watermark register on Ironlake */
 #define WM0_PIPEA_ILK		0x45100
 #define  WM0_PIPE_PLANE_MASK	(0xffff<<16)
-- 
1.8.3.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 48/89 v4] drm/i915/skl: Allocate DDB portions for display planes
  2014-09-04 11:27 ` [PATCH 48/89] drm/i915/skl: Allocate DDB portions for display planes Damien Lespiau
  2014-09-19  9:58   ` Ville Syrjälä
@ 2014-09-23 11:19   ` Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-23 11:19 UTC (permalink / raw)
  To: intel-gfx

v2: Fix the 3rd plane/cursor logic (Pradeep Bhat)
v3: Fix one-by-one error in the DDB allocation code
v4: Rebase on top of the skl_pipe_pixel_rate() argument change

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 150 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 150 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index e69a833..716af24 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2957,6 +2957,155 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
 	return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
 }
 
+/*
+ * On gen9, we need to allocate Display Data Buffer (DDB) portions to the
+ * different active planes.
+ */
+
+#define SKL_DDB_SIZE		896	/* in blocks */
+
+static void
+skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
+				   struct drm_crtc *for_crtc,
+				   struct intel_wm_config *config,
+				   struct skl_pipe_wm_parameters *params,
+				   uint16_t *available,
+				   uint16_t *start,
+				   uint16_t *end)
+{
+	struct drm_crtc *crtc;
+	unsigned int ddb_size;
+	int nth_active_pipe;
+
+	if (!params->active) {
+		*available = 0;
+		*start = 0;
+		*end = 0;
+		return;
+	}
+
+	ddb_size = SKL_DDB_SIZE;
+
+	ddb_size -= 4; /* 4 blocks for bypass path allocation */
+
+	nth_active_pipe = 1;
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		if (!intel_crtc_active(crtc))
+			continue;
+
+		if (crtc == for_crtc)
+			break;
+
+		nth_active_pipe++;
+	}
+
+	*available = ddb_size / config->num_pipes_active;
+	*start = (nth_active_pipe - 1) * ddb_size / config->num_pipes_active;
+	*end = *start + *available - 1;
+}
+
+static unsigned int skl_cursor_allocation(struct intel_wm_config *config)
+{
+	if (config->num_pipes_active == 1)
+		return 32;
+
+	return 8;
+}
+
+static unsigned int
+skl_plane_relative_data_rate(struct intel_plane_wm_parameters *p)
+{
+	return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel;
+}
+
+/*
+ * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching
+ * a 8192x4096@32bpp framebuffer:
+ *   3 * 4096 * 8192  * 4 < 2^32
+ */
+static unsigned int
+skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc,
+				 struct skl_pipe_wm_parameters *params)
+{
+	unsigned int total_data_rate = 0;
+	int plane;
+
+	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
+		struct intel_plane_wm_parameters *p = &params->plane[plane];
+
+		if (!p->enabled)
+			continue;
+
+		total_data_rate += skl_plane_relative_data_rate(p);
+	}
+
+	return total_data_rate;
+}
+
+static void
+skl_allocate_pipe_ddb(struct drm_crtc *crtc,
+		      struct intel_wm_config *config,
+		      struct skl_pipe_wm_parameters *params,
+		      struct skl_ddb_allocation *ddb /* out */)
+{
+	struct drm_device *dev = crtc->dev;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	enum pipe pipe = intel_crtc->pipe;
+	uint16_t available, start, end, cursor_blocks;
+	unsigned int total_data_rate;
+	int plane;
+
+	skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params,
+					   &available, &start, &end);
+	if (available == 0) {
+		const size_t size = ARRAY_SIZE(ddb->plane[pipe]) *
+				    sizeof(struct skl_ddb_entry);
+
+		memset(ddb->plane[pipe], 0, size);
+		memset(&ddb->cursor[pipe], 0, sizeof(struct skl_ddb_entry));
+		return;
+	}
+
+	cursor_blocks = skl_cursor_allocation(config);
+	ddb->cursor[pipe].start = end - cursor_blocks + 1;
+	ddb->cursor[pipe].end = end;
+
+	available -= cursor_blocks;
+	end -= cursor_blocks;
+
+	/*
+	 * Each active plane get a portion of the remaining space, in
+	 * proportion to the amount of data they need to fetch from memory.
+	 *
+	 * FIXME: we don't always allocate every single block here.
+	 */
+	total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params);
+
+	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
+		struct intel_plane_wm_parameters *p = &params->plane[plane];
+		unsigned int data_rate;
+		uint16_t plane_blocks;
+
+		if (!p->enabled)
+			continue;
+
+		data_rate = skl_plane_relative_data_rate(p);
+
+		/*
+		 * promote the expression to 64 bits to avoid overflowing, the
+		 * result is < available as data_rate / total_data_rate < 1
+		 */
+		plane_blocks = div_u64((uint64_t)available * data_rate,
+				       total_data_rate);
+
+		ddb->plane[pipe][plane].start = start;
+		ddb->plane[pipe][plane].end = start + plane_blocks - 1;
+
+		start += plane_blocks;
+	}
+
+}
+
 static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_config *config)
 {
 	/* TODO: Take into account the scalers once we support them */
@@ -3278,6 +3427,7 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
 	skl_compute_wm_pipe_parameters(crtc, params);
+	skl_allocate_pipe_ddb(crtc, config, params, ddb);
 	skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
 
 	if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* Re: [PATCH 63/89] drm/i915/skl: Define shared DPLLs for Skylake
  2014-09-04 11:27 ` [PATCH 63/89] drm/i915/skl: Define shared DPLLs for Skylake Damien Lespiau
@ 2014-09-23 14:28   ` Paulo Zanoni
  2014-10-01 10:52     ` M, Satheeshakrishna
  0 siblings, 1 reply; 286+ messages in thread
From: Paulo Zanoni @ 2014-09-23 14:28 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>
> On skylake, DPLL 1, 2 and 3 can be used for DP and HDMI. The shared dpll
> framework allows us to share those DPLLs among DDIs when possible.
>
> The most tricky part is to provide a DPLL state that can be easily
> compared. DPLL_CRTL1 is shared by all the DPLLs, 6 bits each. The
> per-dpll crtl1 field of the hw state is then normalized to be the same
> value if 2 DPLLs do indeed have identical values for those 6 bits.
>
> v2: Port the code to the shared DPLL infrastructure (Damien)
>
> XXX: This patch would benefit from a bunchf of macros for handling ctrl1
> to encapsulate the masking and shifting (Daniel)

Are you planning to do the XXX above before merging?

The only suspect thing is that the spec doesn't mention
if/when/how-much we need to sleep after enabling the clocks... I hope
this won't be a problem later :)

Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

>
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v1)
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h  |  11 ++++
>  drivers/gpu/drm/i915/intel_ddi.c | 126 ++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 136 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 65e5ffb..a6e14db 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -225,6 +225,17 @@ struct intel_dpll_hw_state {
>
>         /* hsw, bdw */
>         uint32_t wrpll;
> +
> +       /* skl */
> +       /*
> +        * DPLL_CTRL1 has 6 bits for each each this DPLL. We store those in
> +        * lower part of crtl1 and they get shifted into position when writing
> +        * the register.  This allows us to easily compare the state to share
> +        * the DPLL.
> +        */
> +       uint32_t ctrl1;
> +       /* HDMI only, 0 when used for DP */
> +       uint32_t cfgcr1, cfgcr2;
>  };
>
>  struct intel_shared_dpll {
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index b5cfb07..53ac23d 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1522,12 +1522,136 @@ static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
>         }
>  }
>
> +static const char * const skl_ddi_pll_names[] = {
> +       "DPLL 1",
> +       "DPLL 2",
> +       "DPLL 3",
> +};
> +
> +struct skl_dpll_regs {
> +       u32 ctl, cfgcr1, cfgcr2;
> +};
> +
> +/* this array is indexed by the *shared* pll id */
> +static const struct skl_dpll_regs skl_dpll_regs[3] = {
> +       {
> +               /* DPLL 1 */
> +               .ctl = LCPLL2_CTL,
> +               .cfgcr1 = DPLL1_CFGCR1,
> +               .cfgcr2 = DPLL1_CFGCR2,
> +       },
> +       {
> +               /* DPLL 2 */
> +               .ctl = WRPLL_CTL1,
> +               .cfgcr1 = DPLL2_CFGCR1,
> +               .cfgcr2 = DPLL2_CFGCR2,
> +       },
> +       {
> +               /* DPLL 3 */
> +               .ctl = WRPLL_CTL2,
> +               .cfgcr1 = DPLL3_CFGCR1,
> +               .cfgcr2 = DPLL3_CFGCR2,
> +       },
> +};
> +
> +static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
> +                              struct intel_shared_dpll *pll)
> +{
> +       uint32_t val;
> +       unsigned int dpll;
> +       const struct skl_dpll_regs *regs = skl_dpll_regs;
> +
> +       /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
> +       dpll = pll->id + 1;
> +
> +       val = I915_READ(DPLL_CTRL1);
> +
> +       val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
> +                DPLL_CRTL1_LINK_RATE_MASK(dpll));
> +       val |= pll->hw_state.ctrl1 << (dpll * 6);
> +
> +       I915_WRITE(DPLL_CTRL1, val);
> +       POSTING_READ(DPLL_CTRL1);
> +
> +       I915_WRITE(regs[pll->id].cfgcr1, pll->hw_state.cfgcr1);
> +       I915_WRITE(regs[pll->id].cfgcr2, pll->hw_state.cfgcr2);
> +       POSTING_READ(regs[pll->id].cfgcr1);
> +       POSTING_READ(regs[pll->id].cfgcr2);
> +
> +       /* the enable bit is always bit 31 */
> +       I915_WRITE(regs[pll->id].ctl,
> +                  I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
> +
> +       if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
> +               DRM_ERROR("DPLL %d not locked\n", dpll);
> +}
> +
> +static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
> +                               struct intel_shared_dpll *pll)
> +{
> +       const struct skl_dpll_regs *regs = skl_dpll_regs;
> +
> +       /* the enable bit is always bit 31 */
> +       I915_WRITE(regs[pll->id].ctl,
> +                  I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
> +       POSTING_READ(regs[pll->id].ctl);
> +}
> +
> +static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
> +                                    struct intel_shared_dpll *pll,
> +                                    struct intel_dpll_hw_state *hw_state)
> +{
> +       uint32_t val;
> +       unsigned int dpll;
> +       const struct skl_dpll_regs *regs = skl_dpll_regs;
> +
> +       if (!intel_display_power_enabled(dev_priv, POWER_DOMAIN_PLLS))
> +               return false;
> +
> +       /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
> +       dpll = pll->id + 1;
> +
> +       val = I915_READ(regs[pll->id].ctl);
> +       if (!(val & LCPLL_PLL_ENABLE))
> +               return false;
> +
> +       val = I915_READ(DPLL_CTRL1);
> +       hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
> +
> +       /* avoid reading back stale values if HDMI mode is not enabled */
> +       if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
> +               hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
> +               hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
> +       }
> +
> +       return true;
> +}
> +
> +static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
> +{
> +       int i;
> +
> +       dev_priv->num_shared_dpll = 3;
> +
> +       for (i = 0; i < dev_priv->num_shared_dpll; i++) {
> +               dev_priv->shared_dplls[i].id = i;
> +               dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
> +               dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
> +               dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
> +               dev_priv->shared_dplls[i].get_hw_state =
> +                       skl_ddi_pll_get_hw_state;
> +       }
> +}
> +
>  void intel_ddi_pll_init(struct drm_device *dev)
>  {
>         struct drm_i915_private *dev_priv = dev->dev_private;
>         uint32_t val = I915_READ(LCPLL_CTL);
>
> -       hsw_shared_dplls_init(dev_priv);
> +       if (IS_SKYLAKE(dev))
> +               skl_shared_dplls_init(dev_priv);
> +       else
> +               hsw_shared_dplls_init(dev_priv);
>
>         DRM_DEBUG_KMS("CDCLK running at %dKHz\n",
>                       intel_ddi_get_cdclk_freq(dev_priv));
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 64/89] drm/i915/skl: Adjust the port PLL selection code
  2014-09-04 11:27 ` [PATCH 64/89] drm/i915/skl: Adjust the port PLL selection code Damien Lespiau
@ 2014-09-23 14:39   ` Paulo Zanoni
  0 siblings, 0 replies; 286+ messages in thread
From: Paulo Zanoni @ 2014-09-23 14:39 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>
> Skylake deprecates the usage of PORT_CLK_SEL and we are advised to use
> the new DPLL_CRTL2 for the DDI->PLL mapping.
>
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 30 +++++++++++++++++++++++++-----
>  1 file changed, 25 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 53ac23d..439cd50 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1223,7 +1223,8 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
>  static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
>  {
>         struct drm_encoder *encoder = &intel_encoder->base;
> -       struct drm_i915_private *dev_priv = encoder->dev->dev_private;
> +       struct drm_device *dev = encoder->dev;

Bikeshed: this could be avoided if you just used dev_priv for the
IS_SKYLAKE macro, now that it accepts it :)


> +       struct drm_i915_private *dev_priv = dev->dev_private;
>         struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
>         enum port port = intel_ddi_get_encoder_port(intel_encoder);
>         int type = intel_encoder->type;
> @@ -1242,8 +1243,22 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
>                 intel_edp_panel_on(intel_dp);
>         }
>
> -       WARN_ON(crtc->config.ddi_pll_sel == PORT_CLK_SEL_NONE);
> -       I915_WRITE(PORT_CLK_SEL(port), crtc->config.ddi_pll_sel);
> +       if (IS_SKYLAKE(dev)) {

Bikeshed: invert the check so future gens are on the "else".


> +               enum skl_dpll dpll = crtc->config.ddi_pll_sel;
> +               uint32_t val;
> +
> +               val = I915_READ(DPLL_CTRL2);
> +
> +               val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
> +                       DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
> +               val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
> +                       DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
> +
> +               I915_WRITE(DPLL_CTRL2, val);
> +       } else {
> +               WARN_ON(crtc->config.ddi_pll_sel == PORT_CLK_SEL_NONE);
> +               I915_WRITE(PORT_CLK_SEL(port), crtc->config.ddi_pll_sel);
> +       }

Bikeshed: extract this chunk to intel_ddi_set_port_clock() or some other name.


>
>         if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
>                 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> @@ -1267,7 +1282,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
>  static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
>  {
>         struct drm_encoder *encoder = &intel_encoder->base;
> -       struct drm_i915_private *dev_priv = encoder->dev->dev_private;
> +       struct drm_device *dev = encoder->dev;
> +       struct drm_i915_private *dev_priv = dev->dev_private;
>         enum port port = intel_ddi_get_encoder_port(intel_encoder);
>         int type = intel_encoder->type;
>         uint32_t val;
> @@ -1295,7 +1311,11 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
>                 intel_edp_panel_off(intel_dp);
>         }
>
> -       I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
> +       if (IS_SKYLAKE(dev))

Same here.

With or without any changes: Reviewed-by: Paulo Zanoni
<paulo.r.zanoni@intel.com>

> +               I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
> +                                       DPLL_CTRL2_DDI_CLK_OFF(port)));
> +       else
> +               I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
>  }
>
>  static void intel_enable_ddi(struct intel_encoder *intel_encoder)
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 65/89] drm/i915/skl: Always use DPLL0 for eDP
  2014-09-04 11:27 ` [PATCH 65/89] drm/i915/skl: Always use DPLL0 for eDP Damien Lespiau
@ 2014-09-23 15:07   ` Paulo Zanoni
  2014-10-01 10:52     ` M, Satheeshakrishna
  0 siblings, 1 reply; 286+ messages in thread
From: Paulo Zanoni @ 2014-09-23 15:07 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>
> DPLL0 is not part of the shared PLL infrastructure. We'll use on for
> eDP and rely on what the BIOS does for now.
>
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dp.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 5755f59..93bd9bf 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1005,7 +1005,10 @@ found:
>                                 &pipe_config->dp_m2_n2);
>         }
>
> -       if (IS_HASWELL(dev) || IS_BROADWELL(dev))
> +       if (IS_SKYLAKE(dev)) {
> +               if (is_edp(intel_dp))
> +                       pipe_config->ddi_pll_sel = SKL_DPLL0;

So we just don't assign anything else for the other ports? Why exactly?


> +       } else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>                 hsw_dp_set_ddi_pll_sel(pipe_config, intel_dp->link_bw);
>         else
>                 intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* [PATCH 45/89 v4] drm/i915/skl: Definition of SKL WM param structs for pipe/plane
  2014-09-23  8:16       ` Daniel Vetter
@ 2014-09-23 15:10         ` Damien Lespiau
  2014-10-28 15:11           ` Ville Syrjälä
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-23 15:10 UTC (permalink / raw)
  To: intel-gfx; +Cc: Pradeep Bhat

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch defines the structures needed for computation of
watermarks of pipes and planes for SKL.

v2: Incorporated Damien's review comments and removed unused fields
    in structs for future features like rotation, drrs and scaling.
    The skl_wm_values struct is now made more generic across planes
    and cursor planes for all pipes.

v3: implemented the plane/cursor split.

v4: Change the wm union back to a structure (Ville, Daniel)

Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h  | 18 ++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h |  8 ++++++++
 drivers/gpu/drm/i915/intel_pm.c  |  8 ++++++++
 3 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8eb116c1..481ebd8 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1395,6 +1395,24 @@ struct ilk_wm_values {
 	enum intel_ddb_partitioning partitioning;
 };
 
+struct skl_wm_values {
+	bool dirty[I915_MAX_PIPES];
+	uint32_t wm_linetime[I915_MAX_PIPES];
+	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
+	uint32_t cursor[I915_MAX_PIPES][8];
+	uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
+	uint32_t cursor_trans[I915_MAX_PIPES];
+};
+
+struct skl_wm_level {
+	bool plane_en[I915_MAX_PLANES];
+	uint16_t plane_res_b[I915_MAX_PLANES];
+	uint8_t plane_res_l[I915_MAX_PLANES];
+	bool cursor_en;
+	uint16_t cursor_res_b;
+	uint8_t cursor_res_l;
+};
+
 /*
  * This struct helps tracking the state needed for runtime PM, which puts the
  * device in PCI D3 state. Notice that when this happens, nothing on the
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 072e69f..4438a05 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -399,6 +399,12 @@ struct intel_mmio_flip {
 	u32 ring_id;
 };
 
+struct skl_pipe_wm {
+	struct skl_wm_level wm[8];
+	struct skl_wm_level trans_wm;
+	uint32_t linetime;
+};
+
 struct intel_crtc {
 	struct drm_crtc base;
 	enum pipe pipe;
@@ -446,6 +452,8 @@ struct intel_crtc {
 	struct {
 		/* watermarks currently being used  */
 		struct intel_pipe_wm active;
+		/* SKL wm values currently in use */
+		struct skl_pipe_wm skl_active;
 	} wm;
 
 	int scanline_offset;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index fadf376..299dd7e 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1953,6 +1953,14 @@ static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels,
 	return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2;
 }
 
+struct skl_pipe_wm_parameters {
+	bool active;
+	uint32_t pipe_htotal;
+	uint32_t pixel_rate; /* in KHz */
+	struct intel_plane_wm_parameters plane[I915_MAX_PLANES];
+	struct intel_plane_wm_parameters cursor;
+};
+
 struct ilk_pipe_wm_parameters {
 	bool active;
 	uint32_t pipe_htotal;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* Re: [PATCH 66/89] drm/i915/skl: Implementation of SKL DPLL programming
  2014-09-04 11:27 ` [PATCH 66/89] drm/i915/skl: Implementation of SKL DPLL programming Damien Lespiau
@ 2014-09-23 18:05   ` Paulo Zanoni
  2014-10-01 10:52     ` M, Satheeshakrishna
  2014-11-04 16:26     ` [PATCH 66/89 v9] " Damien Lespiau
  2015-05-13 14:54   ` [PATCH 66/89] " Tvrtko Ursulin
  1 sibling, 2 replies; 286+ messages in thread
From: Paulo Zanoni @ 2014-09-23 18:05 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>
> This patch implements SKL DPLL programming that includes:
>         - DPLL allocation
>         - wide range PLL calculation and programming
>         - DP link rate programming
>         - DDI to DPLL mapping
>
> v2: Incorporated following changes
>         - Added vfunc for function required outside
>         - Fixed multiple comments in WRPLL calculation
>
> v3: - Fix the DCO computation
>     - Move the initialization up to not clobber the computed values
>     - Use the correct macro for DP link rate programming.
>     - Use wait_for() to wait for the PLL locked bit
>
> v4: Rebase on top of nigthly (Damien)
>
> v5: A few code cleanups in the WRPLL computation (Damien)
>     - Use uint32_t when possible
>     - Use abs_diff() in the WRPLL computation
>     - Make the 64bits divisions use div64_u64()
>     - Fix typo in dco_central_feq_deviation (freq)
>     - Replace the chain of breaks with a goto
>
> v6: Port of the patch to work on top of the shared DPLLs (Damien)
> v7: Don't try to handle eDP in ddi_pll_select() (Damien)
>
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v3)
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 225 ++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 224 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 439cd50..f68e04c 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -915,6 +915,225 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
>         return true;
>  }
>
> +struct skl_wrpll_params {
> +       uint32_t        dco_fraction;
> +       uint32_t        dco_integer;
> +       uint32_t        qdiv_ratio;
> +       uint32_t        qdiv_mode;
> +       uint32_t        kdiv;
> +       uint32_t        pdiv;
> +       uint32_t        central_freq;
> +};
> +
> +static void
> +skl_ddi_calculate_wrpll(int clock /* in Hz */,
> +                       struct skl_wrpll_params *wrpll_params)
> +{
> +       uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
> +       uint64_t dco_central_freq[3] = {8400000000, 9000000000, 9600000000};
> +       uint32_t min_dco_deviation = 400;
> +       uint32_t min_dco_index = 3;
> +       uint32_t P0[4] = {1, 2, 3, 7};
> +       uint32_t P2[4] = {1, 2, 3, 5};
> +       bool found = false;
> +       uint32_t candidate_p = 0;
> +       uint32_t candidate_p0[3] = {0}, candidate_p1[3] = {0};
> +       uint32_t candidate_p2[3] = {0};
> +       uint32_t dco_central_freq_deviation[3];
> +       uint32_t i, P1, k, dco_count;
> +       bool retry_with_odd = false;
> +       uint64_t dco_freq;
> +
> +       /* Determine P0, P1 or P2 */
> +       for (dco_count = 0; dco_count < 3; dco_count++) {
> +               found = false;
> +               candidate_p =
> +                       div64_u64(dco_central_freq[dco_count], afe_clock);
> +               if (retry_with_odd == false)
> +                       candidate_p = (candidate_p % 2 == 0 ?
> +                               candidate_p : candidate_p + 1);
> +
> +               for (P1 = 1; P1 < candidate_p; P1++) {
> +                       for (i = 0; i < 4; i++) {
> +                               if (!(P0[i] != 1 || P1 == 1))

I'd invert the logic of  the statement above to match the spec.


> +                                       continue;
> +
> +                               for (k = 0; k < 4; k++) {
> +                                       if (!((P2[k] != 2 && P1 == 1) ||
> +                                               (P2[k] == 2)))

This doesn't seem to match the docs. Why is the "P2[k] == 2" there?

>From the bikeshedding department, there's also a minor coding style
problem (missing "*" char in second line of comment) below, and the
usual "is_skl" check leaving gen10+ on the same case as hsw/bdw.

Everything else looks like to be according to the specs.

With or without changes: Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

> +                                               continue;
> +
> +                                       if (candidate_p == P0[i] * P1 * P2[k]) {
> +                                               /* Found possible P0, P1, P2 */
> +                                               found = true;
> +                                               candidate_p0[dco_count] = P0[i];
> +                                               candidate_p1[dco_count] = P1;
> +                                               candidate_p2[dco_count] = P2[k];
> +                                               goto found;
> +                                       }
> +
> +                               }
> +                       }
> +               }
> +
> +found:
> +               if (found) {
> +                       dco_central_freq_deviation[dco_count] =
> +                               div64_u64(10000 *
> +                                         abs_diff((candidate_p * afe_clock),
> +                                                  dco_central_freq[dco_count]),
> +                                         dco_central_freq[dco_count]);
> +
> +                       if (dco_central_freq_deviation[dco_count] <
> +                               min_dco_deviation) {
> +                               min_dco_deviation =
> +                                       dco_central_freq_deviation[dco_count];
> +                               min_dco_index = dco_count;
> +                       }
> +               }
> +
> +               if (min_dco_index > 2 && dco_count == 2) {
> +                       retry_with_odd = true;
> +                       dco_count = 0;
> +               }
> +       }
> +
> +       if (min_dco_index > 2) {
> +               WARN(1, "No valid values found for the given pixel clock\n");
> +       } else {
> +                wrpll_params->central_freq = dco_central_freq[min_dco_index];
> +
> +                switch (dco_central_freq[min_dco_index]) {
> +                case 9600000000:
> +                       wrpll_params->central_freq = 0;
> +                       break;
> +                case 9000000000:
> +                       wrpll_params->central_freq = 1;
> +                       break;
> +                case 8400000000:
> +                       wrpll_params->central_freq = 3;
> +                }
> +
> +                switch (candidate_p0[min_dco_index]) {
> +                case 1:
> +                       wrpll_params->pdiv = 0;
> +                       break;
> +                case 2:
> +                       wrpll_params->pdiv = 1;
> +                       break;
> +                case 3:
> +                       wrpll_params->pdiv = 2;
> +                       break;
> +                case 7:
> +                       wrpll_params->pdiv = 4;
> +                       break;
> +                default:
> +                       WARN(1, "Incorrect PDiv\n");
> +                }
> +
> +                switch (candidate_p2[min_dco_index]) {
> +                case 5:
> +                       wrpll_params->kdiv = 0;
> +                       break;
> +                case 2:
> +                       wrpll_params->kdiv = 1;
> +                       break;
> +                case 3:
> +                       wrpll_params->kdiv = 2;
> +                       break;
> +                case 1:
> +                       wrpll_params->kdiv = 3;
> +                       break;
> +                default:
> +                       WARN(1, "Incorrect KDiv\n");
> +                }
> +
> +                wrpll_params->qdiv_ratio = candidate_p1[min_dco_index];
> +                wrpll_params->qdiv_mode =
> +                       (wrpll_params->qdiv_ratio == 1) ? 0 : 1;
> +
> +                dco_freq = candidate_p0[min_dco_index] *
> +                        candidate_p1[min_dco_index] *
> +                        candidate_p2[min_dco_index] * afe_clock;
> +
> +                /* Intermediate values are in Hz.
> +                   Divide by MHz to match bsepc */
> +                wrpll_params->dco_integer = div_u64(dco_freq, (24 * MHz(1)));
> +                wrpll_params->dco_fraction =
> +                        div_u64(((div_u64(dco_freq, 24) -
> +                                  wrpll_params->dco_integer * MHz(1)) * 0x8000), MHz(1));
> +
> +       }
> +}
> +
> +
> +static bool
> +skl_ddi_pll_select(struct intel_crtc *intel_crtc,
> +                  struct intel_encoder *intel_encoder,
> +                  int clock)
> +{
> +       struct intel_shared_dpll *pll;
> +       uint32_t ctrl1, cfgcr1, cfgcr2;
> +
> +       /*
> +        * See comment in intel_dpll_hw_state to understand why we always use 0
> +        * as the DPLL id in this function.
> +        */
> +
> +       ctrl1 = DPLL_CTRL1_OVERRIDE(0);
> +
> +       if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
> +               struct skl_wrpll_params wrpll_params = { 0, };
> +
> +               ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
> +
> +               skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params);
> +
> +               cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
> +                        DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
> +                        wrpll_params.dco_integer;
> +
> +               cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
> +                        DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
> +                        DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
> +                        DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
> +                        wrpll_params.central_freq;
> +       } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
> +               struct drm_encoder *encoder = &intel_encoder->base;
> +               struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> +
> +               switch (intel_dp->link_bw) {
> +               case DP_LINK_BW_1_62:
> +                       ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_810, 0);
> +                       break;
> +               case DP_LINK_BW_2_7:
> +                       ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_1350, 0);
> +                       break;
> +               case DP_LINK_BW_5_4:
> +                       ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_2700, 0);
> +                       break;
> +               }
> +
> +               cfgcr1 = cfgcr2 = 0;
> +       } else /* eDP */
> +               return true;
> +
> +       intel_crtc->config.dpll_hw_state.ctrl1 = ctrl1;
> +       intel_crtc->config.dpll_hw_state.cfgcr1 = cfgcr1;
> +       intel_crtc->config.dpll_hw_state.cfgcr2 = cfgcr2;
> +
> +       pll = intel_get_shared_dpll(intel_crtc);
> +       if (pll == NULL) {
> +               DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
> +                                pipe_name(intel_crtc->pipe));
> +               return false;
> +       }
> +
> +       /* shared DPLL id 0 is DPLL 1 */
> +       intel_crtc->config.ddi_pll_sel = pll->id + 1;
> +
> +       return true;
> +}
>
>  /*
>   * Tries to find a *shared* PLL for the CRTC and store it in
> @@ -926,12 +1145,16 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
>  bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
>  {
>         struct drm_crtc *crtc = &intel_crtc->base;
> +       struct drm_device *dev = crtc->dev;
>         struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
>         int clock = intel_crtc->config.port_clock;
>
>         intel_put_shared_dpll(intel_crtc);
>
> -       return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock);
> +       if (IS_SKYLAKE(dev))
> +               return skl_ddi_pll_select(intel_crtc, intel_encoder, clock);
> +       else
> +               return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock);
>  }
>
>  void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 67/89] drm/i915/skl: Provide skl-specific pll hw state cross-checking
  2014-09-04 11:27 ` [PATCH 67/89] drm/i915/skl: Provide skl-specific pll hw state cross-checking Damien Lespiau
@ 2014-09-23 18:07   ` Paulo Zanoni
  0 siblings, 0 replies; 286+ messages in thread
From: Paulo Zanoni @ 2014-09-23 18:07 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> v2: rebase on top of the hw state flattening.

Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 6e71250..0a4dd00 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -10775,6 +10775,9 @@ intel_pipe_config_compare(struct drm_device *dev,
>         PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
>         PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
>         PIPE_CONF_CHECK_X(dpll_hw_state.wrpll);
> +       PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1);
> +       PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
> +       PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
>
>         if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5)
>                 PIPE_CONF_CHECK_I(pipe_bpp);
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 68/89] drm/i915/skl: Apply eDP WA only for gen < 9
  2014-09-04 11:27 ` [PATCH 68/89] drm/i915/skl: Apply eDP WA only for gen < 9 Damien Lespiau
@ 2014-09-23 18:11   ` Paulo Zanoni
  0 siblings, 0 replies; 286+ messages in thread
From: Paulo Zanoni @ 2014-09-23 18:11 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> From: Vandana Kannan <vandana.kannan@intel.com>
>
> The eDP WA to stop link train based on port type is for HSW/BDW, not
> required for SKL+.
> Suggested by Satheesh
>
> v2: Simplified the check befoe stop_link_train. Suggested by Satheesh.
>
> v3: stop_link_train need not be called from intel_enable_ddi for gen >= 9

Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

>
> Suggested-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> Reviewed-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
> Cc: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index f68e04c..2561b40 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1491,7 +1491,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
>                 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
>                 intel_dp_start_link_train(intel_dp);
>                 intel_dp_complete_link_train(intel_dp);
> -               if (port != PORT_A)
> +               if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
>                         intel_dp_stop_link_train(intel_dp);
>         } else if (type == INTEL_OUTPUT_HDMI) {
>                 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
> @@ -1567,7 +1567,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
>         } else if (type == INTEL_OUTPUT_EDP) {
>                 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>
> -               if (port == PORT_A)
> +               if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
>                         intel_dp_stop_link_train(intel_dp);
>
>                 intel_edp_backlight_on(intel_dp);
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 74/89] drm/i915/skl: Implement queue_flip
  2014-09-04 11:27 ` [PATCH 74/89] drm/i915/skl: Implement queue_flip Damien Lespiau
@ 2014-09-23 20:06   ` Paulo Zanoni
  2014-09-29 16:54     ` Damien Lespiau
  2014-09-29 17:13     ` [PATCH 74/89 v4] " Damien Lespiau
  0 siblings, 2 replies; 286+ messages in thread
From: Paulo Zanoni @ 2014-09-23 20:06 UTC (permalink / raw)
  To: Damien Lespiau, Ville Syrjälä; +Cc: Intel Graphics Development

2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> A few bits have changed in MI_DISPLAY_FLIP to accomodate the new planes.
> DE_RRMR seems to have kept its plane flip bits backward compatible.
>
> v2: Rebase on top of nightly
> v2: Rebase on top of nightly (minor conflict in i915_reg.h)
>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h      | 10 +++++
>  drivers/gpu/drm/i915/intel_display.c | 78 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 88 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 84a0de6..176e84e 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -240,6 +240,16 @@
>  #define   MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19)
>  #define   MI_DISPLAY_FLIP_IVB_PLANE_C  (4 << 19)
>  #define   MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19)
> +/* SKL ones */
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_1_A        (0 << 8)
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_1_B        (1 << 8)
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_1_C        (2 << 8)
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_2_A        (4 << 8)
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_2_B        (5 << 8)
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_2_C        (6 << 8)
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_3_A        (7 << 8)
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_3_B        (8 << 8)
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_3_C        (9 << 8)

BSpec seems to mention these bits on CHV too... Maybe we want the new
function to run on CHV + GEN9? Ping Ville.


>  #define MI_SEMAPHORE_MBOX      MI_INSTR(0x16, 1) /* gen6, gen7 */
>  #define   MI_SEMAPHORE_GLOBAL_GTT    (1<<22)
>  #define   MI_SEMAPHORE_UPDATE      (1<<21)
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index abd4201..393bd19 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -9913,6 +9913,81 @@ static int intel_queue_mmio_flip(struct drm_device *dev,
>         return 0;
>  }
>
> +static int intel_gen9_queue_flip(struct drm_device *dev,
> +                                struct drm_crtc *crtc,
> +                                struct drm_framebuffer *fb,
> +                                struct drm_i915_gem_object *obj,
> +                                struct intel_engine_cs *ring,
> +                                uint32_t flags)
> +{
> +       struct drm_i915_private *dev_priv = dev->dev_private;
> +       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +       uint32_t plane = 0, stride;
> +       int ret;
> +
> +       ring = obj->ring;
> +       if (ring == NULL || ring->id != BCS)
> +               ring = &dev_priv->ring[RCS];

Why do we need these lines above? The other Gens don't have it. And it
looks like ring shouldn't really be NULL, otherwise the other gens are
going to crash.


> +
> +       ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
> +       if (ret)
> +               goto err;

Our only caller (intel_crtc_page_flip) seems to do this for us
already. Also, the other gens don't do this at their queue_flip
implementations.


> +
> +       switch(intel_crtc->pipe) {
> +       case PIPE_A:
> +               plane = MI_DISPLAY_FLIP_SKL_PLANE_1_A;
> +               break;
> +       case PIPE_B:
> +               plane = MI_DISPLAY_FLIP_SKL_PLANE_1_B;
> +               break;
> +       case PIPE_C:
> +               plane = MI_DISPLAY_FLIP_SKL_PLANE_1_C;
> +               break;
> +       default:
> +               BUG();

The gen7 version does WARN_ONCE() and returns -ENODEV instead of
BUG(). Seems more reasonable to just not update the screen instead of
killing the whole machine.


> +       }
> +
> +       switch (obj->tiling_mode) {
> +       case I915_TILING_NONE:
> +               stride = fb->pitches[0] >> 6;
> +               break;
> +       case I915_TILING_X:
> +               stride = fb->pitches[0] >> 9;
> +               break;
> +       default:
> +               BUG();

Also replace this for a WARN and return an error code?

> +       }
> +
> +       ret = intel_ring_begin(ring, 10);
> +       if (ret)
> +               goto err_unpin;
> +
> +       intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
> +       intel_ring_emit(ring, DERRMR);
> +       intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE |
> +                               DERRMR_PIPEB_PRI_FLIP_DONE |
> +                               DERRMR_PIPEC_PRI_FLIP_DONE));
> +       intel_ring_emit(ring, MI_STORE_REGISTER_MEM_GEN8(1) |
> +                             MI_SRM_LRM_GLOBAL_GTT);
> +       intel_ring_emit(ring, DERRMR);
> +       intel_ring_emit(ring, ring->scratch.gtt_offset + 256);
> +       intel_ring_emit(ring, 0);

Do we still need the DERRMR thing? BSpec doesn't seem to mention it
anymore on the SKL page. And we only do it for RCS on Gens 7/8.


> +
> +       intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane);
> +       intel_ring_emit(ring, stride << 6 | obj->tiling_mode);
> +       intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj));

Gen 7 uses intel_crtc->unpin_work->gtt_offset, which seems to be a
little faster than calling i915_gem_obj_ggtt_offset() again. The
work->gtt_offset was just set by the function that calls queue_flip(),
so it should be correct.


> +
> +       intel_mark_page_flip_active(intel_crtc);
> +       __intel_ring_advance(ring);
> +
> +       return 0;
> +
> +err_unpin:
> +       intel_unpin_fb_obj(obj);
> +err:
> +       return ret;
> +}
> +
>  static int intel_default_queue_flip(struct drm_device *dev,
>                                     struct drm_crtc *crtc,
>                                     struct drm_framebuffer *fb,
> @@ -12740,6 +12815,9 @@ static void intel_init_display(struct drm_device *dev)
>         case 8: /* FIXME(BDW): Check that the gen8 RCS flip works. */
>                 dev_priv->display.queue_flip = intel_gen7_queue_flip;
>                 break;
> +       case 9:
> +               dev_priv->display.queue_flip = intel_gen9_queue_flip;
> +               break;
>         }
>
>         intel_panel_init_backlight_funcs(dev);
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 75/89] drm/i915/skl: fetch, enable/disable pfit as needed
  2014-09-04 11:27 ` [PATCH 75/89] drm/i915/skl: fetch, enable/disable pfit as needed Damien Lespiau
@ 2014-09-23 20:50   ` Paulo Zanoni
  2014-09-24 10:44     ` Damien Lespiau
  2014-09-25 14:48     ` Jesse Barnes
  2014-09-25 17:58   ` [PATCH] drm/i915/skl: fetch, enable/disable pfit as needed v2 Jesse Barnes
  1 sibling, 2 replies; 286+ messages in thread
From: Paulo Zanoni @ 2014-09-23 20:50 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> From: Jesse Barnes <jbarnes@virtuousgeek.org>
>
> This moved around on SKL, so we need to make sure we read/write the
> correct regs.
>
> Signed-off-by: Jesse Barnes <jbarnes@virtuougseek.org>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h      | 13 ++++++++
>  drivers/gpu/drm/i915/intel_display.c | 61 +++++++++++++++++++++++++++++++++---
>  2 files changed, 70 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 176e84e..35c0759 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4833,6 +4833,19 @@ enum skl_disp_power_wells {
>  #define PF_VSCALE(pipe)                _PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE)
>  #define PF_HSCALE(pipe)                _PIPE(pipe, _PFA_HSCALE, _PFB_HSCALE)
>
> +#define _PSA_CTL               0x68180
> +#define _PSB_CTL               0x68980
> +#define PS_ENABLE              (1<<31)
> +#define PS_PIPE_SEL(pipe)      ((pipe)<<27)

The PS_PIPE_SEL define is wrong, but it is also not used in the code
you wrote, so just remove this line.


> +#define _PSA_WIN_SZ            0x68174
> +#define _PSB_WIN_SZ            0x68974
> +#define _PSA_WIN_POS           0x68178

0x68170

> +#define _PSB_WIN_POS           0x68978

0x68970

> +
> +#define PS_CTL(pipe)           _PIPE(pipe, _PSA_CTL, _PSB_CTL)
> +#define PS_WIN_SZ(pipe)                _PIPE(pipe, _PSA_WIN_SZ, _PSB_WIN_SZ)
> +#define PS_WIN_POS(pipe)       _PIPE(pipe, _PSA_WIN_POS, _PSB_WIN_POS)
> +
>  /* legacy palette */
>  #define _LGC_PALETTE_A           0x4a000
>  #define _LGC_PALETTE_B           0x4a800
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 393bd19..9b31342 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3882,6 +3882,19 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe)
>         }
>  }
>
> +static void skylake_pfit_enable(struct intel_crtc *crtc)
> +{
> +       struct drm_device *dev = crtc->base.dev;
> +       struct drm_i915_private *dev_priv = dev->dev_private;
> +       int pipe = crtc->pipe;
> +
> +       if (crtc->config.pch_pfit.enabled) {
> +               I915_WRITE(PS_CTL(pipe), PS_ENABLE);
> +               I915_WRITE(PS_WIN_POS(pipe), crtc->config.pch_pfit.pos);
> +               I915_WRITE(PS_WIN_SZ(pipe), crtc->config.pch_pfit.size);
> +       }
> +}
> +
>  static void ironlake_pfit_enable(struct intel_crtc *crtc)
>  {
>         struct drm_device *dev = crtc->base.dev;
> @@ -4264,7 +4277,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>
>         intel_ddi_enable_pipe_clock(intel_crtc);
>
> -       ironlake_pfit_enable(intel_crtc);
> +       if (IS_SKYLAKE(dev))
> +               skylake_pfit_enable(intel_crtc);
> +       else
> +               ironlake_pfit_enable(intel_crtc);
>
>         /*
>          * On ILK+ LUT must be loaded before the pipe is running but with
> @@ -4295,6 +4311,20 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>         intel_crtc_enable_planes(crtc);
>  }
>
> +static void skylake_pfit_disable(struct intel_crtc *crtc)
> +{
> +       struct drm_device *dev = crtc->base.dev;
> +       struct drm_i915_private *dev_priv = dev->dev_private;
> +       int pipe = crtc->pipe;
> +
> +       /* To avoid upsetting the power well on haswell only disable the pfit if
> +        * it's in use. The hw state code will make sure we get this right. */
> +       if (crtc->config.pch_pfit.enabled) {
> +               I915_WRITE(PS_CTL(pipe), 0);
> +               I915_WRITE(PS_WIN_SZ(pipe), 0);

Why not also zero _POS just like HSW? Can this affect the HW state
checker output?

Everything else looks correct.

> +       }
> +}
> +
>  static void ironlake_pfit_disable(struct intel_crtc *crtc)
>  {
>         struct drm_device *dev = crtc->base.dev;
> @@ -4399,7 +4429,10 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
>
>         intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
>
> -       ironlake_pfit_disable(intel_crtc);
> +       if (IS_SKYLAKE(dev))
> +               skylake_pfit_disable(intel_crtc);
> +       else
> +               ironlake_pfit_disable(intel_crtc);
>
>         intel_ddi_disable_pipe_clock(intel_crtc);
>
> @@ -7382,6 +7415,22 @@ static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
>                                      &pipe_config->fdi_m_n, NULL);
>  }
>
> +static void skylake_get_pfit_config(struct intel_crtc *crtc,
> +                                   struct intel_crtc_config *pipe_config)
> +{
> +       struct drm_device *dev = crtc->base.dev;
> +       struct drm_i915_private *dev_priv = dev->dev_private;
> +       uint32_t tmp;
> +
> +       tmp = I915_READ(PS_CTL(crtc->pipe));
> +
> +       if (tmp & PS_ENABLE) {
> +               pipe_config->pch_pfit.enabled = true;
> +               pipe_config->pch_pfit.pos = I915_READ(PS_WIN_POS(crtc->pipe));
> +               pipe_config->pch_pfit.size = I915_READ(PS_WIN_SZ(crtc->pipe));
> +       }
> +}
> +
>  static void ironlake_get_pfit_config(struct intel_crtc *crtc,
>                                      struct intel_crtc_config *pipe_config)
>  {
> @@ -7940,8 +7989,12 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
>         intel_get_pipe_timings(crtc, pipe_config);
>
>         pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
> -       if (intel_display_power_enabled(dev_priv, pfit_domain))
> -               ironlake_get_pfit_config(crtc, pipe_config);
> +       if (intel_display_power_enabled(dev_priv, pfit_domain)) {
> +               if (IS_SKYLAKE(dev))
> +                       skylake_get_pfit_config(crtc, pipe_config);
> +               else
> +                       ironlake_get_pfit_config(crtc, pipe_config);
> +       }
>
>         if (IS_HASWELL(dev))
>                 pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) &&
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 75/89] drm/i915/skl: fetch, enable/disable pfit as needed
  2014-09-23 20:50   ` Paulo Zanoni
@ 2014-09-24 10:44     ` Damien Lespiau
  2014-09-25 14:48     ` Jesse Barnes
  1 sibling, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-24 10:44 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: Intel Graphics Development, jbarnes

Hi Jesse,

Mind looking at those review comments?

-- 
Damien

On Tue, Sep 23, 2014 at 05:50:29PM -0300, Paulo Zanoni wrote:
> 2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> > From: Jesse Barnes <jbarnes@virtuousgeek.org>
> >
> > This moved around on SKL, so we need to make sure we read/write the
> > correct regs.
> >
> > Signed-off-by: Jesse Barnes <jbarnes@virtuougseek.org>
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_reg.h      | 13 ++++++++
> >  drivers/gpu/drm/i915/intel_display.c | 61 +++++++++++++++++++++++++++++++++---
> >  2 files changed, 70 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> > index 176e84e..35c0759 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -4833,6 +4833,19 @@ enum skl_disp_power_wells {
> >  #define PF_VSCALE(pipe)                _PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE)
> >  #define PF_HSCALE(pipe)                _PIPE(pipe, _PFA_HSCALE, _PFB_HSCALE)
> >
> > +#define _PSA_CTL               0x68180
> > +#define _PSB_CTL               0x68980
> > +#define PS_ENABLE              (1<<31)
> > +#define PS_PIPE_SEL(pipe)      ((pipe)<<27)
> 
> The PS_PIPE_SEL define is wrong, but it is also not used in the code
> you wrote, so just remove this line.
> 
> 
> > +#define _PSA_WIN_SZ            0x68174
> > +#define _PSB_WIN_SZ            0x68974
> > +#define _PSA_WIN_POS           0x68178
> 
> 0x68170
> 
> > +#define _PSB_WIN_POS           0x68978
> 
> 0x68970
> 
> > +
> > +#define PS_CTL(pipe)           _PIPE(pipe, _PSA_CTL, _PSB_CTL)
> > +#define PS_WIN_SZ(pipe)                _PIPE(pipe, _PSA_WIN_SZ, _PSB_WIN_SZ)
> > +#define PS_WIN_POS(pipe)       _PIPE(pipe, _PSA_WIN_POS, _PSB_WIN_POS)
> > +
> >  /* legacy palette */
> >  #define _LGC_PALETTE_A           0x4a000
> >  #define _LGC_PALETTE_B           0x4a800
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 393bd19..9b31342 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -3882,6 +3882,19 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe)
> >         }
> >  }
> >
> > +static void skylake_pfit_enable(struct intel_crtc *crtc)
> > +{
> > +       struct drm_device *dev = crtc->base.dev;
> > +       struct drm_i915_private *dev_priv = dev->dev_private;
> > +       int pipe = crtc->pipe;
> > +
> > +       if (crtc->config.pch_pfit.enabled) {
> > +               I915_WRITE(PS_CTL(pipe), PS_ENABLE);
> > +               I915_WRITE(PS_WIN_POS(pipe), crtc->config.pch_pfit.pos);
> > +               I915_WRITE(PS_WIN_SZ(pipe), crtc->config.pch_pfit.size);
> > +       }
> > +}
> > +
> >  static void ironlake_pfit_enable(struct intel_crtc *crtc)
> >  {
> >         struct drm_device *dev = crtc->base.dev;
> > @@ -4264,7 +4277,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
> >
> >         intel_ddi_enable_pipe_clock(intel_crtc);
> >
> > -       ironlake_pfit_enable(intel_crtc);
> > +       if (IS_SKYLAKE(dev))
> > +               skylake_pfit_enable(intel_crtc);
> > +       else
> > +               ironlake_pfit_enable(intel_crtc);
> >
> >         /*
> >          * On ILK+ LUT must be loaded before the pipe is running but with
> > @@ -4295,6 +4311,20 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
> >         intel_crtc_enable_planes(crtc);
> >  }
> >
> > +static void skylake_pfit_disable(struct intel_crtc *crtc)
> > +{
> > +       struct drm_device *dev = crtc->base.dev;
> > +       struct drm_i915_private *dev_priv = dev->dev_private;
> > +       int pipe = crtc->pipe;
> > +
> > +       /* To avoid upsetting the power well on haswell only disable the pfit if
> > +        * it's in use. The hw state code will make sure we get this right. */
> > +       if (crtc->config.pch_pfit.enabled) {
> > +               I915_WRITE(PS_CTL(pipe), 0);
> > +               I915_WRITE(PS_WIN_SZ(pipe), 0);
> 
> Why not also zero _POS just like HSW? Can this affect the HW state
> checker output?
> 
> Everything else looks correct.
> 
> > +       }
> > +}
> > +
> >  static void ironlake_pfit_disable(struct intel_crtc *crtc)
> >  {
> >         struct drm_device *dev = crtc->base.dev;
> > @@ -4399,7 +4429,10 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
> >
> >         intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
> >
> > -       ironlake_pfit_disable(intel_crtc);
> > +       if (IS_SKYLAKE(dev))
> > +               skylake_pfit_disable(intel_crtc);
> > +       else
> > +               ironlake_pfit_disable(intel_crtc);
> >
> >         intel_ddi_disable_pipe_clock(intel_crtc);
> >
> > @@ -7382,6 +7415,22 @@ static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
> >                                      &pipe_config->fdi_m_n, NULL);
> >  }
> >
> > +static void skylake_get_pfit_config(struct intel_crtc *crtc,
> > +                                   struct intel_crtc_config *pipe_config)
> > +{
> > +       struct drm_device *dev = crtc->base.dev;
> > +       struct drm_i915_private *dev_priv = dev->dev_private;
> > +       uint32_t tmp;
> > +
> > +       tmp = I915_READ(PS_CTL(crtc->pipe));
> > +
> > +       if (tmp & PS_ENABLE) {
> > +               pipe_config->pch_pfit.enabled = true;
> > +               pipe_config->pch_pfit.pos = I915_READ(PS_WIN_POS(crtc->pipe));
> > +               pipe_config->pch_pfit.size = I915_READ(PS_WIN_SZ(crtc->pipe));
> > +       }
> > +}
> > +
> >  static void ironlake_get_pfit_config(struct intel_crtc *crtc,
> >                                      struct intel_crtc_config *pipe_config)
> >  {
> > @@ -7940,8 +7989,12 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
> >         intel_get_pipe_timings(crtc, pipe_config);
> >
> >         pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
> > -       if (intel_display_power_enabled(dev_priv, pfit_domain))
> > -               ironlake_get_pfit_config(crtc, pipe_config);
> > +       if (intel_display_power_enabled(dev_priv, pfit_domain)) {
> > +               if (IS_SKYLAKE(dev))
> > +                       skylake_get_pfit_config(crtc, pipe_config);
> > +               else
> > +                       ironlake_get_pfit_config(crtc, pipe_config);
> > +       }
> >
> >         if (IS_HASWELL(dev))
> >                 pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) &&
> > --
> > 1.8.3.1
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> 
> 
> -- 
> Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 56/89] drm/i915: Gen9 shadowed registers
  2014-09-04 11:27 ` [PATCH 56/89] drm/i915: Gen9 shadowed registers Damien Lespiau
@ 2014-09-24 13:36   ` Mika Kuoppala
  2014-09-24 18:16     ` Bob Wang
  0 siblings, 1 reply; 286+ messages in thread
From: Mika Kuoppala @ 2014-09-24 13:36 UTC (permalink / raw)
  To: Damien Lespiau, intel-gfx

Damien Lespiau <damien.lespiau@intel.com> writes:

> From: Zhe Wang <zhe1.wang@intel.com>
>
> For MMIO registers which are shadowed, force wake is not needed to
> write to these registers.
>
> v2: Rebase on top of nightly (Damien)
>
> Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_uncore.c | 26 +++++++++++++++++++++++++-
>  1 file changed, 25 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index f289f4f..ce1214b 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -1028,13 +1028,37 @@ chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
>  	REG_WRITE_FOOTER; \
>  }
>  
> +static const u32 gen9_shadowed_regs[] = {
> +	FORCEWAKE_MEDIA_GEN9,
> +	FORCEWAKE_RENDER_GEN9,
> +	FORCEWAKE_BLITTER_GEN9,

You might want to move the ring tails first on the list
and forcewake regs to bottom, to reflect the popularity
of access.

> +	GEN6_RPNSWREQ,
> +	GEN6_RC_VIDEO_FREQ,
> +	RING_TAIL(RENDER_RING_BASE),
> +	RING_TAIL(GEN6_BSD_RING_BASE),
> +	RING_TAIL(VEBOX_RING_BASE),
> +	RING_TAIL(BLT_RING_BASE),
> +	/* TODO: Other registers are not yet used */

I think we need exec list ones here also, but couldn't find 
certain proof. Atleast with bdw we are missing them.

-Mika

> +};
> +
> +static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg)
> +{
> +	int i;
> +	for (i = 0; i < ARRAY_SIZE(gen9_shadowed_regs); i++)
> +		if (reg == gen9_shadowed_regs[i])
> +			return true;
> +
> +	return false;
> +}
> +
>  #define __gen9_write(x) \
>  static void \
>  gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
>  		bool trace) { \
>  	REG_WRITE_HEADER; \
>  	if (!NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
> -			FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg)) { \
> +			FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) || \
> +			is_gen9_shadowed(dev_priv, reg)) { \
>  		__raw_i915_write##x(dev_priv, reg, val); \
>  	} else { \
>  		unsigned fwengine = 0; \
> -- 
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 52/89] drm/i915/gen9: Disable WM if corresponding latency is 0
  2014-09-19 10:05   ` Ville Syrjälä
@ 2014-09-24 14:06     ` Damien Lespiau
  2014-10-29 19:05       ` Ville Syrjälä
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-24 14:06 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Fri, Sep 19, 2014 at 01:05:02PM +0300, Ville Syrjälä wrote:
> 
> If we're going to be paranoid I think we should disable all higher WM
> levels whose latency is lower than any of the lower levels. And I
> think we'll want something like dev_priv->wm.max_wm_level instead of
> relying on the zero latency tricks. That thing has been on my TODO
> list since forever.

Can we go step by step? add this patch and then I noted this as a task
for post merge work. No sure who will end up doing and and if the
sanitazing code can be shared between platforms (probably yes?), but
that can wait a bit longer?

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 54/89] drm/i915/skl: Enable Gen9 RC6
  2014-09-22 13:15   ` Mika Kuoppala
@ 2014-09-24 17:58     ` Bob Wang
  0 siblings, 0 replies; 286+ messages in thread
From: Bob Wang @ 2014-09-24 17:58 UTC (permalink / raw)
  To: Mika Kuoppala; +Cc: intel-gfx

On 09/22/2014 02:15 PM, Mika Kuoppala wrote:
> Damien Lespiau <damien.lespiau@intel.com> writes:
>
>> From: Zhe Wang <zhe1.wang@intel.com>
>>
>> Configure and enable RC6 for Gen9.
>>
>> v2: Rebase on top of BDW rc6 support (Damien)
>>
>> Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
>> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
>> ---
>>   drivers/gpu/drm/i915/intel_pm.c | 52 ++++++++++++++++++++++++++++++++++++++++-
>>   1 file changed, 51 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
>> index fdf297f..74a8519 100644
>> --- a/drivers/gpu/drm/i915/intel_pm.c
>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>> @@ -4332,6 +4332,13 @@ static void gen8_disable_rps_interrupts(struct drm_device *dev)
>>   	}
>>   }
>>   
>> +static void gen9_disable_rps(struct drm_device *dev)
>> +{
>> +	struct drm_i915_private *dev_priv = dev->dev_private;
>> +
>> +	I915_WRITE(GEN6_RC_CONTROL, 0);
>> +}
>> +
>>   static void gen6_disable_rps_interrupts(struct drm_device *dev)
>>   {
>>   	struct drm_i915_private *dev_priv = dev->dev_private;
>> @@ -4579,6 +4586,45 @@ void bdw_software_turbo(struct drm_device *dev)
>>   			&current_time, &current_c0);
>>   }
>>   
>> +static void gen9_enable_rps(struct drm_device *dev)
>> +{
>> +	struct drm_i915_private *dev_priv = dev->dev_private;
>> +	struct intel_engine_cs *ring;
>> +	uint32_t rc6_mask = 0;
>> +	int unused;
>> +
>> +	/* 1a: Software RC state - RC0 */
>> +	I915_WRITE(GEN6_RC_STATE, 0);
>> +
>> +	/* 1b: Get forcewake during program sequence. Although the driver
>> +	 * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
>> +	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
>> +
>> +	/* 2a: Disable RC states. */
>> +	I915_WRITE(GEN6_RC_CONTROL, 0);
>> +
>> +	/* 2b: Program RC6 thresholds.*/
>> +	I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
> 40 << 16
>
>> +	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
>> +	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
>> +	for_each_ring(ring, dev_priv, unused)
>> +		I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
>> +	I915_WRITE(GEN6_RC_SLEEP, 0);
>> +	I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */
> 50000 50ms/125ms per EI
>
>> +
>> +	/* 3a: Enable RC6 */
>> +	if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
>> +		rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
>> +	DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
>> +			"on" : "off");
>> +	I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
>> +				   GEN6_RC_CTL_EI_MODE(1) |
>> +				   rc6_mask);
>> +
>> +	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
>> +
>> +}
>> +
>>   static void gen8_enable_rps(struct drm_device *dev)
>>   {
>>   	struct drm_i915_private *dev_priv = dev->dev_private;
>> @@ -6158,7 +6204,9 @@ void intel_disable_gt_powersave(struct drm_device *dev)
>>   		intel_suspend_gt_powersave(dev);
>>   
>>   		mutex_lock(&dev_priv->rps.hw_lock);
>> -		if (IS_CHERRYVIEW(dev))
>> +		if (INTEL_INFO(dev)->gen >= 9)
>> +			gen9_disable_rps(dev);
>> +		else if (IS_CHERRYVIEW(dev))
>>   			cherryview_disable_rps(dev);
>>   		else if (IS_VALLEYVIEW(dev))
>>   			valleyview_disable_rps(dev);
>> @@ -6184,6 +6232,8 @@ static void intel_gen6_powersave_work(struct work_struct *work)
>>   		cherryview_enable_rps(dev);
>>   	} else if (IS_VALLEYVIEW(dev)) {
>>   		valleyview_enable_rps(dev);
>> +	} else if (INTEL_INFO(dev)->gen >= 9) {
>> +		gen9_enable_rps(dev);
>>   	} else if (IS_BROADWELL(dev)) {
>>   		gen8_enable_rps(dev);
>>   		__gen6_update_ring_freq(dev);
>> -- 
>> 1.8.3.1
> I couldn't find out if those values suggested are newer than the values
> in this patch. We need to visit this are when we are wiser.
>
> Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
The new values are from power performance study on more recent 
platforms. So we decided to start with those as initial version.

We will definitely revisit these numbers and update if there are 
different numbers recommended from architecture team for Gen9.
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 55/89] drm/i915/skl: Gen9 multi-engine forcewake
  2014-09-22 15:11   ` Mika Kuoppala
@ 2014-09-24 18:08     ` Bob Wang
  2014-09-25  7:32       ` Mika Kuoppala
  0 siblings, 1 reply; 286+ messages in thread
From: Bob Wang @ 2014-09-24 18:08 UTC (permalink / raw)
  To: Mika Kuoppala; +Cc: intel-gfx

On 09/22/2014 04:11 PM, Mika Kuoppala wrote:
> Damien Lespiau <damien.lespiau@intel.com> writes:
>
>> From: Zhe Wang <zhe1.wang@intel.com>
>>
>> Enable multi-engine forcewake for Gen9.
>>
>> v2: Rebase on top of nightly
>>      Move the register range definitions to intel_uncore.c
>>      Whitespace fixes
>>      (Damien)
>>
>> Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
>> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
>> ---
>>   drivers/gpu/drm/i915/intel_uncore.c | 120 ++++++++++++++++++++++++++++++++++++
>>   1 file changed, 120 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
>> index 7b7fc9e..f289f4f 100644
>> --- a/drivers/gpu/drm/i915/intel_uncore.c
>> +++ b/drivers/gpu/drm/i915/intel_uncore.c
>> @@ -674,6 +674,34 @@ void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
>>   	 REG_RANGE((reg), 0x14000, 0x14400) || \
>>   	 REG_RANGE((reg), 0x22000, 0x24000))
>>   
>> +#define FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) \
>> +	((reg) >= 0xC00 && (reg) < 0x2000)
>> +
>> +#define FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) \
>> +	(((reg) >= 0x2000 && (reg) < 0x4000) || \
>> +	((reg) >= 0x5200 && (reg) < 0x8000) || \
>> +	((reg) >= 0x8300 && (reg) < 0x8500) || \
>> +	((reg) >= 0x8C00 && (reg) < 0x8D00) || \
>> +	((reg) >= 0xB000 && (reg) < 0xB480) || \
>> +	((reg) >= 0xE000 && (reg) < 0xE800))
>> +
>> +#define FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) \
>> +	(((reg) >= 0x8800 && (reg) < 0x8A00) || \
>> +	((reg) >= 0xD000 && (reg) < 0xD800) || \
>> +	((reg) >= 0x12000 && (reg) < 0x14000) || \
>> +	((reg) >= 0x1A000 && (reg) < 0x1EA00) || \
>> +	((reg) >= 0x30000 && (reg) < 0x40000))
>> +
>> +#define FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg) \
>> +	((reg) >= 0x9400 && (reg) < 0x9800)
> Please use REG_RANGE for all above.
ok, we can change this for these macros.
>> +#define FORCEWAKE_GEN9_BLITTER_RANGE_OFFSET(reg) \
>> +	((reg) < 0x40000 &&\
>> +	!FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) && \
>> +	!FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) && \
>> +	!FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) && \
>> +	!FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg))
>> +
>>   static void
>>   ilk_dummy_write(struct drm_i915_private *dev_priv)
>>   {
>> @@ -804,6 +832,43 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>>   	REG_READ_FOOTER; \
>>   }
>>   
>> +#define __gen9_read(x) \
>> +static u##x \
>> +gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>> +	REG_READ_HEADER(x); \
>> +	if (!NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
> As gen9 doesn't have FORCEWAKE register, you can save one
> comparison here if you discard the macro and opencode.
Hi Mika,
Excuse me, I didn't really get this. can you explain more on it?

Gen9 has 3 separate forcewake registers.
we still have to check for 2 ranges to ensure forcewake is not required
1. >= 0x40000
2. 0xC00-0x1FFF (this range is new and always accessible)

Thanks,
Bob
>> +			FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg)) { \
>> +		val = __raw_i915_read##x(dev_priv, reg); \
>> +	} else { \
>> +		unsigned fwengine = 0; \
>> +		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
>> +			if (dev_priv->uncore.fw_rendercount == 0) \
>> +				fwengine = FORCEWAKE_RENDER; \
>> +		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
>> +			if (dev_priv->uncore.fw_mediacount == 0) \
>> +				fwengine = FORCEWAKE_MEDIA; \
>> +		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
>> +			if (dev_priv->uncore.fw_rendercount == 0) \
>> +				fwengine |= FORCEWAKE_RENDER; \
>> +			if (dev_priv->uncore.fw_mediacount == 0) \
>> +				fwengine |= FORCEWAKE_MEDIA; \
>> +		} else { \
>> +			if (dev_priv->uncore.fw_blittercount == 0) \
>> +				fwengine = FORCEWAKE_BLITTER; \
>> +		} \
>> +		if (fwengine) \
>> +			dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
>> +		val = __raw_i915_read##x(dev_priv, reg); \
>> +		if (fwengine) \
>> +			dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
>> +	} \
>> +	REG_READ_FOOTER; \
>> +}
>> +
>> +__gen9_read(8)
>> +__gen9_read(16)
>> +__gen9_read(32)
>> +__gen9_read(64)
>>   __chv_read(8)
>>   __chv_read(16)
>>   __chv_read(32)
>> @@ -825,6 +890,7 @@ __gen4_read(16)
>>   __gen4_read(32)
>>   __gen4_read(64)
>>   
>> +#undef __gen9_read
>>   #undef __chv_read
>>   #undef __vlv_read
>>   #undef __gen6_read
>> @@ -962,6 +1028,46 @@ chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
>>   	REG_WRITE_FOOTER; \
>>   }
>>   
>> +#define __gen9_write(x) \
>> +static void \
>> +gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
>> +		bool trace) { \
>> +	REG_WRITE_HEADER; \
>> +	if (!NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
> ditto
>
> -Mika
>
>> +			FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg)) { \
>> +		__raw_i915_write##x(dev_priv, reg, val); \
>> +	} else { \
>> +		unsigned fwengine = 0; \
>> +		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
>> +			if (dev_priv->uncore.fw_rendercount == 0) \
>> +				fwengine = FORCEWAKE_RENDER; \
>> +		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
>> +			if (dev_priv->uncore.fw_mediacount == 0) \
>> +				fwengine = FORCEWAKE_MEDIA; \
>> +		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
>> +			if (dev_priv->uncore.fw_rendercount == 0) \
>> +				fwengine |= FORCEWAKE_RENDER; \
>> +			if (dev_priv->uncore.fw_mediacount == 0) \
>> +				fwengine |= FORCEWAKE_MEDIA; \
>> +		} else { \
>> +			if (dev_priv->uncore.fw_blittercount == 0) \
>> +				fwengine = FORCEWAKE_BLITTER; \
>> +		} \
>> +		if (fwengine) \
>> +			dev_priv->uncore.funcs.force_wake_get(dev_priv, \
>> +					fwengine); \
>> +		__raw_i915_write##x(dev_priv, reg, val); \
>> +		if (fwengine) \
>> +			dev_priv->uncore.funcs.force_wake_put(dev_priv, \
>> +					fwengine); \
>> +	} \
>> +	REG_WRITE_FOOTER; \
>> +}
>> +
>> +__gen9_write(8)
>> +__gen9_write(16)
>> +__gen9_write(32)
>> +__gen9_write(64)
>>   __chv_write(8)
>>   __chv_write(16)
>>   __chv_write(32)
>> @@ -987,6 +1093,7 @@ __gen4_write(16)
>>   __gen4_write(32)
>>   __gen4_write(64)
>>   
>> +#undef __gen9_write
>>   #undef __chv_write
>>   #undef __gen8_write
>>   #undef __hsw_write
>> @@ -1054,6 +1161,19 @@ void intel_uncore_init(struct drm_device *dev)
>>   
>>   	switch (INTEL_INFO(dev)->gen) {
>>   	default:
>> +		WARN_ON(1);
>> +		return;
>> +	case 9:
>> +		dev_priv->uncore.funcs.mmio_writeb  = gen9_write8;
>> +		dev_priv->uncore.funcs.mmio_writew  = gen9_write16;
>> +		dev_priv->uncore.funcs.mmio_writel  = gen9_write32;
>> +		dev_priv->uncore.funcs.mmio_writeq  = gen9_write64;
>> +		dev_priv->uncore.funcs.mmio_readb  = gen9_read8;
>> +		dev_priv->uncore.funcs.mmio_readw  = gen9_read16;
>> +		dev_priv->uncore.funcs.mmio_readl  = gen9_read32;
>> +		dev_priv->uncore.funcs.mmio_readq  = gen9_read64;
>> +		break;
>> +	case 8:
>>   		if (IS_CHERRYVIEW(dev)) {
>>   			dev_priv->uncore.funcs.mmio_writeb  = chv_write8;
>>   			dev_priv->uncore.funcs.mmio_writew  = chv_write16;
>> -- 
>> 1.8.3.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 56/89] drm/i915: Gen9 shadowed registers
  2014-09-24 13:36   ` Mika Kuoppala
@ 2014-09-24 18:16     ` Bob Wang
  2014-09-25  8:58       ` Mika Kuoppala
  0 siblings, 1 reply; 286+ messages in thread
From: Bob Wang @ 2014-09-24 18:16 UTC (permalink / raw)
  To: Mika Kuoppala; +Cc: intel-gfx

On 09/24/2014 02:36 PM, Mika Kuoppala wrote:
> Damien Lespiau <damien.lespiau@intel.com> writes:
>
>> From: Zhe Wang <zhe1.wang@intel.com>
>>
>> For MMIO registers which are shadowed, force wake is not needed to
>> write to these registers.
>>
>> v2: Rebase on top of nightly (Damien)
>>
>> Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
>> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
>> ---
>>   drivers/gpu/drm/i915/intel_uncore.c | 26 +++++++++++++++++++++++++-
>>   1 file changed, 25 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
>> index f289f4f..ce1214b 100644
>> --- a/drivers/gpu/drm/i915/intel_uncore.c
>> +++ b/drivers/gpu/drm/i915/intel_uncore.c
>> @@ -1028,13 +1028,37 @@ chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
>>   	REG_WRITE_FOOTER; \
>>   }
>>   
>> +static const u32 gen9_shadowed_regs[] = {
>> +	FORCEWAKE_MEDIA_GEN9,
>> +	FORCEWAKE_RENDER_GEN9,
>> +	FORCEWAKE_BLITTER_GEN9,
> You might want to move the ring tails first on the list
> and forcewake regs to bottom, to reflect the popularity
> of access.
good suggestion. a better order I can think of. comments welcomed.

RING_TAIL(RENDER_RING_BASE),
RING_TAIL(GEN6_BSD_RING_BASE),
RING_TAIL(VEBOX_RING_BASE),
RING_TAIL(BLT_RING_BASE),
FORCEWAKE_BLITTER_GEN9,
FORCEWAKE_RENDER_GEN9,
FORCEWAKE_MEDIA_GEN9,
GEN6_RPNSWREQ,
GEN6_RC_VIDEO_FREQ,


>> +	GEN6_RPNSWREQ,
>> +	GEN6_RC_VIDEO_FREQ,
>> +	RING_TAIL(RENDER_RING_BASE),
>> +	RING_TAIL(GEN6_BSD_RING_BASE),
>> +	RING_TAIL(VEBOX_RING_BASE),
>> +	RING_TAIL(BLT_RING_BASE),
>> +	/* TODO: Other registers are not yet used */
> I think we need exec list ones here also, but couldn't find
> certain proof. Atleast with bdw we are missing them.
>
> -Mika
Good catch. Execlist ones are on the list. We need to add those since 
execlist is enabled.
>> +};
>> +
>> +static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg)
>> +{
>> +	int i;
>> +	for (i = 0; i < ARRAY_SIZE(gen9_shadowed_regs); i++)
>> +		if (reg == gen9_shadowed_regs[i])
>> +			return true;
>> +
>> +	return false;
>> +}
>> +
>>   #define __gen9_write(x) \
>>   static void \
>>   gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
>>   		bool trace) { \
>>   	REG_WRITE_HEADER; \
>>   	if (!NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
>> -			FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg)) { \
>> +			FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) || \
>> +			is_gen9_shadowed(dev_priv, reg)) { \
>>   		__raw_i915_write##x(dev_priv, reg, val); \
>>   	} else { \
>>   		unsigned fwengine = 0; \
>> -- 
>> 1.8.3.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 55/89] drm/i915/skl: Gen9 multi-engine forcewake
  2014-09-24 18:08     ` Bob Wang
@ 2014-09-25  7:32       ` Mika Kuoppala
  2014-11-03 17:09         ` [PATCH 55/59 v4] " Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Mika Kuoppala @ 2014-09-25  7:32 UTC (permalink / raw)
  To: Bob Wang; +Cc: intel-gfx

Bob Wang <zhe1.wang@intel.com> writes:

> On 09/22/2014 04:11 PM, Mika Kuoppala wrote:
>> Damien Lespiau <damien.lespiau@intel.com> writes:
>>
>>> From: Zhe Wang <zhe1.wang@intel.com>
>>>
>>> Enable multi-engine forcewake for Gen9.
>>>
>>> v2: Rebase on top of nightly
>>>      Move the register range definitions to intel_uncore.c
>>>      Whitespace fixes
>>>      (Damien)
>>>
>>> Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
>>> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
>>> ---
>>>   drivers/gpu/drm/i915/intel_uncore.c | 120 ++++++++++++++++++++++++++++++++++++
>>>   1 file changed, 120 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
>>> index 7b7fc9e..f289f4f 100644
>>> --- a/drivers/gpu/drm/i915/intel_uncore.c
>>> +++ b/drivers/gpu/drm/i915/intel_uncore.c
>>> @@ -674,6 +674,34 @@ void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
>>>   	 REG_RANGE((reg), 0x14000, 0x14400) || \
>>>   	 REG_RANGE((reg), 0x22000, 0x24000))
>>>   
>>> +#define FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) \
>>> +	((reg) >= 0xC00 && (reg) < 0x2000)
>>> +
>>> +#define FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) \
>>> +	(((reg) >= 0x2000 && (reg) < 0x4000) || \
>>> +	((reg) >= 0x5200 && (reg) < 0x8000) || \
>>> +	((reg) >= 0x8300 && (reg) < 0x8500) || \
>>> +	((reg) >= 0x8C00 && (reg) < 0x8D00) || \
>>> +	((reg) >= 0xB000 && (reg) < 0xB480) || \
>>> +	((reg) >= 0xE000 && (reg) < 0xE800))
>>> +
>>> +#define FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) \
>>> +	(((reg) >= 0x8800 && (reg) < 0x8A00) || \
>>> +	((reg) >= 0xD000 && (reg) < 0xD800) || \
>>> +	((reg) >= 0x12000 && (reg) < 0x14000) || \
>>> +	((reg) >= 0x1A000 && (reg) < 0x1EA00) || \
>>> +	((reg) >= 0x30000 && (reg) < 0x40000))
>>> +
>>> +#define FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg) \
>>> +	((reg) >= 0x9400 && (reg) < 0x9800)
>> Please use REG_RANGE for all above.
> ok, we can change this for these macros.
>>> +#define FORCEWAKE_GEN9_BLITTER_RANGE_OFFSET(reg) \
>>> +	((reg) < 0x40000 &&\
>>> +	!FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) && \
>>> +	!FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) && \
>>> +	!FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) && \
>>> +	!FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg))
>>> +
>>>   static void
>>>   ilk_dummy_write(struct drm_i915_private *dev_priv)
>>>   {
>>> @@ -804,6 +832,43 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>>>   	REG_READ_FOOTER; \
>>>   }
>>>   
>>> +#define __gen9_read(x) \
>>> +static u##x \
>>> +gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>>> +	REG_READ_HEADER(x); \
>>> +	if (!NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
>> As gen9 doesn't have FORCEWAKE register, you can save one
>> comparison here if you discard the macro and opencode.
> Hi Mika,
> Excuse me, I didn't really get this. can you explain more on it?
>
> Gen9 has 3 separate forcewake registers.
> we still have to check for 2 ranges to ensure forcewake is not required
> 1. >= 0x40000
> 2. 0xC00-0x1FFF (this range is new and always accessible)

I was a little bit vague on what macro I was talking about.

The macro in question is:

/* We give fast paths for the really cool registers */
#define NEEDS_FORCE_WAKE(dev_priv, reg) \
         ((reg) < 0x40000 && (reg) != FORCEWAKE)

and as we dont have generic FORCEWAKE (0xA18C) on gen9,
we end up doing one needless != for each register access.

-Mika

> Thanks,
> Bob
>>> +			FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg)) { \
>>> +		val = __raw_i915_read##x(dev_priv, reg); \
>>> +	} else { \
>>> +		unsigned fwengine = 0; \
>>> +		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
>>> +			if (dev_priv->uncore.fw_rendercount == 0) \
>>> +				fwengine = FORCEWAKE_RENDER; \
>>> +		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
>>> +			if (dev_priv->uncore.fw_mediacount == 0) \
>>> +				fwengine = FORCEWAKE_MEDIA; \
>>> +		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
>>> +			if (dev_priv->uncore.fw_rendercount == 0) \
>>> +				fwengine |= FORCEWAKE_RENDER; \
>>> +			if (dev_priv->uncore.fw_mediacount == 0) \
>>> +				fwengine |= FORCEWAKE_MEDIA; \
>>> +		} else { \
>>> +			if (dev_priv->uncore.fw_blittercount == 0) \
>>> +				fwengine = FORCEWAKE_BLITTER; \
>>> +		} \
>>> +		if (fwengine) \
>>> +			dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
>>> +		val = __raw_i915_read##x(dev_priv, reg); \
>>> +		if (fwengine) \
>>> +			dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
>>> +	} \
>>> +	REG_READ_FOOTER; \
>>> +}
>>> +
>>> +__gen9_read(8)
>>> +__gen9_read(16)
>>> +__gen9_read(32)
>>> +__gen9_read(64)
>>>   __chv_read(8)
>>>   __chv_read(16)
>>>   __chv_read(32)
>>> @@ -825,6 +890,7 @@ __gen4_read(16)
>>>   __gen4_read(32)
>>>   __gen4_read(64)
>>>   
>>> +#undef __gen9_read
>>>   #undef __chv_read
>>>   #undef __vlv_read
>>>   #undef __gen6_read
>>> @@ -962,6 +1028,46 @@ chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
>>>   	REG_WRITE_FOOTER; \
>>>   }
>>>   
>>> +#define __gen9_write(x) \
>>> +static void \
>>> +gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
>>> +		bool trace) { \
>>> +	REG_WRITE_HEADER; \
>>> +	if (!NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
>> ditto
>>
>> -Mika
>>
>>> +			FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg)) { \
>>> +		__raw_i915_write##x(dev_priv, reg, val); \
>>> +	} else { \
>>> +		unsigned fwengine = 0; \
>>> +		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
>>> +			if (dev_priv->uncore.fw_rendercount == 0) \
>>> +				fwengine = FORCEWAKE_RENDER; \
>>> +		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
>>> +			if (dev_priv->uncore.fw_mediacount == 0) \
>>> +				fwengine = FORCEWAKE_MEDIA; \
>>> +		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
>>> +			if (dev_priv->uncore.fw_rendercount == 0) \
>>> +				fwengine |= FORCEWAKE_RENDER; \
>>> +			if (dev_priv->uncore.fw_mediacount == 0) \
>>> +				fwengine |= FORCEWAKE_MEDIA; \
>>> +		} else { \
>>> +			if (dev_priv->uncore.fw_blittercount == 0) \
>>> +				fwengine = FORCEWAKE_BLITTER; \
>>> +		} \
>>> +		if (fwengine) \
>>> +			dev_priv->uncore.funcs.force_wake_get(dev_priv, \
>>> +					fwengine); \
>>> +		__raw_i915_write##x(dev_priv, reg, val); \
>>> +		if (fwengine) \
>>> +			dev_priv->uncore.funcs.force_wake_put(dev_priv, \
>>> +					fwengine); \
>>> +	} \
>>> +	REG_WRITE_FOOTER; \
>>> +}
>>> +
>>> +__gen9_write(8)
>>> +__gen9_write(16)
>>> +__gen9_write(32)
>>> +__gen9_write(64)
>>>   __chv_write(8)
>>>   __chv_write(16)
>>>   __chv_write(32)
>>> @@ -987,6 +1093,7 @@ __gen4_write(16)
>>>   __gen4_write(32)
>>>   __gen4_write(64)
>>>   
>>> +#undef __gen9_write
>>>   #undef __chv_write
>>>   #undef __gen8_write
>>>   #undef __hsw_write
>>> @@ -1054,6 +1161,19 @@ void intel_uncore_init(struct drm_device *dev)
>>>   
>>>   	switch (INTEL_INFO(dev)->gen) {
>>>   	default:
>>> +		WARN_ON(1);
>>> +		return;
>>> +	case 9:
>>> +		dev_priv->uncore.funcs.mmio_writeb  = gen9_write8;
>>> +		dev_priv->uncore.funcs.mmio_writew  = gen9_write16;
>>> +		dev_priv->uncore.funcs.mmio_writel  = gen9_write32;
>>> +		dev_priv->uncore.funcs.mmio_writeq  = gen9_write64;
>>> +		dev_priv->uncore.funcs.mmio_readb  = gen9_read8;
>>> +		dev_priv->uncore.funcs.mmio_readw  = gen9_read16;
>>> +		dev_priv->uncore.funcs.mmio_readl  = gen9_read32;
>>> +		dev_priv->uncore.funcs.mmio_readq  = gen9_read64;
>>> +		break;
>>> +	case 8:
>>>   		if (IS_CHERRYVIEW(dev)) {
>>>   			dev_priv->uncore.funcs.mmio_writeb  = chv_write8;
>>>   			dev_priv->uncore.funcs.mmio_writew  = chv_write16;
>>> -- 
>>> 1.8.3.1
>>>
>>> _______________________________________________
>>> Intel-gfx mailing list
>>> Intel-gfx@lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 56/89] drm/i915: Gen9 shadowed registers
  2014-09-24 18:16     ` Bob Wang
@ 2014-09-25  8:58       ` Mika Kuoppala
  2014-11-03 17:45         ` [PATCH 56/89 v4] " Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Mika Kuoppala @ 2014-09-25  8:58 UTC (permalink / raw)
  To: Bob Wang; +Cc: intel-gfx

Bob Wang <zhe1.wang@intel.com> writes:

> On 09/24/2014 02:36 PM, Mika Kuoppala wrote:
>> Damien Lespiau <damien.lespiau@intel.com> writes:
>>
>>> From: Zhe Wang <zhe1.wang@intel.com>
>>>
>>> For MMIO registers which are shadowed, force wake is not needed to
>>> write to these registers.
>>>
>>> v2: Rebase on top of nightly (Damien)
>>>
>>> Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
>>> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
>>> ---
>>>   drivers/gpu/drm/i915/intel_uncore.c | 26 +++++++++++++++++++++++++-
>>>   1 file changed, 25 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
>>> index f289f4f..ce1214b 100644
>>> --- a/drivers/gpu/drm/i915/intel_uncore.c
>>> +++ b/drivers/gpu/drm/i915/intel_uncore.c
>>> @@ -1028,13 +1028,37 @@ chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
>>>   	REG_WRITE_FOOTER; \
>>>   }
>>>   
>>> +static const u32 gen9_shadowed_regs[] = {
>>> +	FORCEWAKE_MEDIA_GEN9,
>>> +	FORCEWAKE_RENDER_GEN9,
>>> +	FORCEWAKE_BLITTER_GEN9,
>> You might want to move the ring tails first on the list
>> and forcewake regs to bottom, to reflect the popularity
>> of access.
> good suggestion. a better order I can think of. comments welcomed.
>
> RING_TAIL(RENDER_RING_BASE),
> RING_TAIL(GEN6_BSD_RING_BASE),
> RING_TAIL(VEBOX_RING_BASE),
> RING_TAIL(BLT_RING_BASE),
> FORCEWAKE_BLITTER_GEN9,
> FORCEWAKE_RENDER_GEN9,
> FORCEWAKE_MEDIA_GEN9,
> GEN6_RPNSWREQ,
> GEN6_RC_VIDEO_FREQ,
>
>
>>> +	GEN6_RPNSWREQ,
>>> +	GEN6_RC_VIDEO_FREQ,
>>> +	RING_TAIL(RENDER_RING_BASE),
>>> +	RING_TAIL(GEN6_BSD_RING_BASE),
>>> +	RING_TAIL(VEBOX_RING_BASE),
>>> +	RING_TAIL(BLT_RING_BASE),
>>> +	/* TODO: Other registers are not yet used */
>> I think we need exec list ones here also, but couldn't find
>> certain proof. Atleast with bdw we are missing them.
>>
>> -Mika
> Good catch. Execlist ones are on the list. We need to add those since 
> execlist is enabled.

On closer look, it seems that the exec lists do their own forcewake
handling.

-Mika

>>> +};
>>> +
>>> +static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg)
>>> +{
>>> +	int i;
>>> +	for (i = 0; i < ARRAY_SIZE(gen9_shadowed_regs); i++)
>>> +		if (reg == gen9_shadowed_regs[i])
>>> +			return true;
>>> +
>>> +	return false;
>>> +}
>>> +
>>>   #define __gen9_write(x) \
>>>   static void \
>>>   gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
>>>   		bool trace) { \
>>>   	REG_WRITE_HEADER; \
>>>   	if (!NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
>>> -			FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg)) { \
>>> +			FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) || \
>>> +			is_gen9_shadowed(dev_priv, reg)) { \
>>>   		__raw_i915_write##x(dev_priv, reg, val); \
>>>   	} else { \
>>>   		unsigned fwengine = 0; \
>>> -- 
>>> 1.8.3.1
>>>
>>> _______________________________________________
>>> Intel-gfx mailing list
>>> Intel-gfx@lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 75/89] drm/i915/skl: fetch, enable/disable pfit as needed
  2014-09-23 20:50   ` Paulo Zanoni
  2014-09-24 10:44     ` Damien Lespiau
@ 2014-09-25 14:48     ` Jesse Barnes
  2014-09-25 14:55       ` Damien Lespiau
  1 sibling, 1 reply; 286+ messages in thread
From: Jesse Barnes @ 2014-09-25 14:48 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: Intel Graphics Development

On Tue, 23 Sep 2014 17:50:29 -0300
Paulo Zanoni <przanoni@gmail.com> wrote:

> 2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> > From: Jesse Barnes <jbarnes@virtuousgeek.org>
> >
> > This moved around on SKL, so we need to make sure we read/write the
> > correct regs.
> >
> > Signed-off-by: Jesse Barnes <jbarnes@virtuougseek.org>
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_reg.h      | 13 ++++++++
> >  drivers/gpu/drm/i915/intel_display.c | 61 +++++++++++++++++++++++++++++++++---
> >  2 files changed, 70 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> > index 176e84e..35c0759 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -4833,6 +4833,19 @@ enum skl_disp_power_wells {
> >  #define PF_VSCALE(pipe)                _PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE)
> >  #define PF_HSCALE(pipe)                _PIPE(pipe, _PFA_HSCALE, _PFB_HSCALE)
> >
> > +#define _PSA_CTL               0x68180
> > +#define _PSB_CTL               0x68980
> > +#define PS_ENABLE              (1<<31)
> > +#define PS_PIPE_SEL(pipe)      ((pipe)<<27)
> 
> The PS_PIPE_SEL define is wrong, but it is also not used in the code
> you wrote, so just remove this line.

Yeah that sounds fine.

> 
> 
> > +#define _PSA_WIN_SZ            0x68174
> > +#define _PSB_WIN_SZ            0x68974
> > +#define _PSA_WIN_POS           0x68178
> 
> 0x68170
> 
> > +#define _PSB_WIN_POS           0x68978
> 
> 0x68970

Ooh thanks.

> 
> > +
> > +#define PS_CTL(pipe)           _PIPE(pipe, _PSA_CTL, _PSB_CTL)
> > +#define PS_WIN_SZ(pipe)                _PIPE(pipe, _PSA_WIN_SZ, _PSB_WIN_SZ)
> > +#define PS_WIN_POS(pipe)       _PIPE(pipe, _PSA_WIN_POS, _PSB_WIN_POS)
> > +
> >  /* legacy palette */
> >  #define _LGC_PALETTE_A           0x4a000
> >  #define _LGC_PALETTE_B           0x4a800
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 393bd19..9b31342 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -3882,6 +3882,19 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe)
> >         }
> >  }
> >
> > +static void skylake_pfit_enable(struct intel_crtc *crtc)
> > +{
> > +       struct drm_device *dev = crtc->base.dev;
> > +       struct drm_i915_private *dev_priv = dev->dev_private;
> > +       int pipe = crtc->pipe;
> > +
> > +       if (crtc->config.pch_pfit.enabled) {
> > +               I915_WRITE(PS_CTL(pipe), PS_ENABLE);
> > +               I915_WRITE(PS_WIN_POS(pipe), crtc->config.pch_pfit.pos);
> > +               I915_WRITE(PS_WIN_SZ(pipe), crtc->config.pch_pfit.size);
> > +       }
> > +}
> > +
> >  static void ironlake_pfit_enable(struct intel_crtc *crtc)
> >  {
> >         struct drm_device *dev = crtc->base.dev;
> > @@ -4264,7 +4277,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
> >
> >         intel_ddi_enable_pipe_clock(intel_crtc);
> >
> > -       ironlake_pfit_enable(intel_crtc);
> > +       if (IS_SKYLAKE(dev))
> > +               skylake_pfit_enable(intel_crtc);
> > +       else
> > +               ironlake_pfit_enable(intel_crtc);
> >
> >         /*
> >          * On ILK+ LUT must be loaded before the pipe is running but with
> > @@ -4295,6 +4311,20 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
> >         intel_crtc_enable_planes(crtc);
> >  }
> >
> > +static void skylake_pfit_disable(struct intel_crtc *crtc)
> > +{
> > +       struct drm_device *dev = crtc->base.dev;
> > +       struct drm_i915_private *dev_priv = dev->dev_private;
> > +       int pipe = crtc->pipe;
> > +
> > +       /* To avoid upsetting the power well on haswell only disable the pfit if
> > +        * it's in use. The hw state code will make sure we get this right. */
> > +       if (crtc->config.pch_pfit.enabled) {
> > +               I915_WRITE(PS_CTL(pipe), 0);
> > +               I915_WRITE(PS_WIN_SZ(pipe), 0);
> 
> Why not also zero _POS just like HSW? Can this affect the HW state
> checker output?
> 
> Everything else looks correct.

The checker will only if the fitter is enabled, but yeah it looks like
it would be safer to zero it.

Damien, did you want to make these changes as part of your re-post or
should I send an updated patch to replace this one?

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 75/89] drm/i915/skl: fetch, enable/disable pfit as needed
  2014-09-25 14:48     ` Jesse Barnes
@ 2014-09-25 14:55       ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-25 14:55 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: Intel Graphics Development

On Thu, Sep 25, 2014 at 07:48:34AM -0700, Jesse Barnes wrote:
> Damien, did you want to make these changes as part of your re-post or
> should I send an updated patch to replace this one?

I wasn't planning to go through this one but let the author works for
his commit :)

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* [PATCH] drm/i915/skl: fetch, enable/disable pfit as needed v2
  2014-09-04 11:27 ` [PATCH 75/89] drm/i915/skl: fetch, enable/disable pfit as needed Damien Lespiau
  2014-09-23 20:50   ` Paulo Zanoni
@ 2014-09-25 17:58   ` Jesse Barnes
  2014-09-25 18:06     ` Paulo Zanoni
  1 sibling, 1 reply; 286+ messages in thread
From: Jesse Barnes @ 2014-09-25 17:58 UTC (permalink / raw)
  To: intel-gfx

This moved around on SKL, so we need to make sure we read/write the
correct regs.

v2: fixup WIN_POS offsets (Paulo)
    zero out WIN_POS reg at disable time (Paulo)

Signed-off-by: Jesse Barnes <jbarnes@virtuougseek.org>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h      | 12 +++++++
 drivers/gpu/drm/i915/intel_display.c | 62 +++++++++++++++++++++++++++++++++---
 2 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 6f5a70f..44133fb 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4760,6 +4760,18 @@ enum punit_power_well {
 #define PF_VSCALE(pipe)		_PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE)
 #define PF_HSCALE(pipe)		_PIPE(pipe, _PFA_HSCALE, _PFB_HSCALE)
 
+#define _PSA_CTL		0x68180
+#define _PSB_CTL		0x68980
+#define PS_ENABLE		(1<<31)
+#define _PSA_WIN_SZ		0x68174
+#define _PSB_WIN_SZ		0x68974
+#define _PSA_WIN_POS		0x68170
+#define _PSB_WIN_POS		0x68970
+
+#define PS_CTL(pipe)		_PIPE(pipe, _PSA_CTL, _PSB_CTL)
+#define PS_WIN_SZ(pipe)		_PIPE(pipe, _PSA_WIN_SZ, _PSB_WIN_SZ)
+#define PS_WIN_POS(pipe)	_PIPE(pipe, _PSA_WIN_POS, _PSB_WIN_POS)
+
 /* legacy palette */
 #define _LGC_PALETTE_A           0x4a000
 #define _LGC_PALETTE_B           0x4a800
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b8488a8..550cde3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3911,6 +3911,19 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe)
 	}
 }
 
+static void skylake_pfit_enable(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = crtc->pipe;
+
+	if (crtc->config.pch_pfit.enabled) {
+		I915_WRITE(PS_CTL(pipe), PS_ENABLE);
+		I915_WRITE(PS_WIN_POS(pipe), crtc->config.pch_pfit.pos);
+		I915_WRITE(PS_WIN_SZ(pipe), crtc->config.pch_pfit.size);
+	}
+}
+
 static void ironlake_pfit_enable(struct intel_crtc *crtc)
 {
 	struct drm_device *dev = crtc->base.dev;
@@ -4288,7 +4301,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 
 	intel_ddi_enable_pipe_clock(intel_crtc);
 
-	ironlake_pfit_enable(intel_crtc);
+	if (IS_SKYLAKE(dev))
+		skylake_pfit_enable(intel_crtc);
+	else
+		ironlake_pfit_enable(intel_crtc);
 
 	/*
 	 * On ILK+ LUT must be loaded before the pipe is running but with
@@ -4322,6 +4338,21 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	intel_crtc_enable_planes(crtc);
 }
 
+static void skylake_pfit_disable(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = crtc->pipe;
+
+	/* To avoid upsetting the power well on haswell only disable the pfit if
+	 * it's in use. The hw state code will make sure we get this right. */
+	if (crtc->config.pch_pfit.enabled) {
+		I915_WRITE(PS_CTL(pipe), 0);
+		I915_WRITE(PS_WIN_POS(pipe), 0);
+		I915_WRITE(PS_WIN_SZ(pipe), 0);
+	}
+}
+
 static void ironlake_pfit_disable(struct intel_crtc *crtc)
 {
 	struct drm_device *dev = crtc->base.dev;
@@ -4433,7 +4464,10 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
 
 	intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
 
-	ironlake_pfit_disable(intel_crtc);
+	if (IS_SKYLAKE(dev))
+		skylake_pfit_disable(intel_crtc);
+	else
+		ironlake_pfit_disable(intel_crtc);
 
 	intel_ddi_disable_pipe_clock(intel_crtc);
 
@@ -7412,6 +7446,22 @@ static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
 				     &pipe_config->fdi_m_n, NULL);
 }
 
+static void skylake_get_pfit_config(struct intel_crtc *crtc,
+				    struct intel_crtc_config *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t tmp;
+
+	tmp = I915_READ(PS_CTL(crtc->pipe));
+
+	if (tmp & PS_ENABLE) {
+		pipe_config->pch_pfit.enabled = true;
+		pipe_config->pch_pfit.pos = I915_READ(PS_WIN_POS(crtc->pipe));
+		pipe_config->pch_pfit.size = I915_READ(PS_WIN_SZ(crtc->pipe));
+	}
+}
+
 static void ironlake_get_pfit_config(struct intel_crtc *crtc,
 				     struct intel_crtc_config *pipe_config)
 {
@@ -7944,8 +7994,12 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 	intel_get_pipe_timings(crtc, pipe_config);
 
 	pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
-	if (intel_display_power_enabled(dev_priv, pfit_domain))
-		ironlake_get_pfit_config(crtc, pipe_config);
+	if (intel_display_power_enabled(dev_priv, pfit_domain)) {
+		if (IS_SKYLAKE(dev))
+			skylake_get_pfit_config(crtc, pipe_config);
+		else
+			ironlake_get_pfit_config(crtc, pipe_config);
+	}
 
 	if (IS_HASWELL(dev))
 		pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) &&
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* Re: [PATCH] drm/i915/skl: fetch, enable/disable pfit as needed v2
  2014-09-25 17:58   ` [PATCH] drm/i915/skl: fetch, enable/disable pfit as needed v2 Jesse Barnes
@ 2014-09-25 18:06     ` Paulo Zanoni
  2014-09-29 13:51       ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Paulo Zanoni @ 2014-09-25 18:06 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: Intel Graphics Development

2014-09-25 14:58 GMT-03:00 Jesse Barnes <jbarnes@virtuousgeek.org>:
> This moved around on SKL, so we need to make sure we read/write the
> correct regs.
>
> v2: fixup WIN_POS offsets (Paulo)
>     zero out WIN_POS reg at disable time (Paulo)

Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

>
> Signed-off-by: Jesse Barnes <jbarnes@virtuougseek.org>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h      | 12 +++++++
>  drivers/gpu/drm/i915/intel_display.c | 62 +++++++++++++++++++++++++++++++++---
>  2 files changed, 70 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 6f5a70f..44133fb 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4760,6 +4760,18 @@ enum punit_power_well {
>  #define PF_VSCALE(pipe)                _PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE)
>  #define PF_HSCALE(pipe)                _PIPE(pipe, _PFA_HSCALE, _PFB_HSCALE)
>
> +#define _PSA_CTL               0x68180
> +#define _PSB_CTL               0x68980
> +#define PS_ENABLE              (1<<31)
> +#define _PSA_WIN_SZ            0x68174
> +#define _PSB_WIN_SZ            0x68974
> +#define _PSA_WIN_POS           0x68170
> +#define _PSB_WIN_POS           0x68970
> +
> +#define PS_CTL(pipe)           _PIPE(pipe, _PSA_CTL, _PSB_CTL)
> +#define PS_WIN_SZ(pipe)                _PIPE(pipe, _PSA_WIN_SZ, _PSB_WIN_SZ)
> +#define PS_WIN_POS(pipe)       _PIPE(pipe, _PSA_WIN_POS, _PSB_WIN_POS)
> +
>  /* legacy palette */
>  #define _LGC_PALETTE_A           0x4a000
>  #define _LGC_PALETTE_B           0x4a800
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index b8488a8..550cde3 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3911,6 +3911,19 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe)
>         }
>  }
>
> +static void skylake_pfit_enable(struct intel_crtc *crtc)
> +{
> +       struct drm_device *dev = crtc->base.dev;
> +       struct drm_i915_private *dev_priv = dev->dev_private;
> +       int pipe = crtc->pipe;
> +
> +       if (crtc->config.pch_pfit.enabled) {
> +               I915_WRITE(PS_CTL(pipe), PS_ENABLE);
> +               I915_WRITE(PS_WIN_POS(pipe), crtc->config.pch_pfit.pos);
> +               I915_WRITE(PS_WIN_SZ(pipe), crtc->config.pch_pfit.size);
> +       }
> +}
> +
>  static void ironlake_pfit_enable(struct intel_crtc *crtc)
>  {
>         struct drm_device *dev = crtc->base.dev;
> @@ -4288,7 +4301,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>
>         intel_ddi_enable_pipe_clock(intel_crtc);
>
> -       ironlake_pfit_enable(intel_crtc);
> +       if (IS_SKYLAKE(dev))
> +               skylake_pfit_enable(intel_crtc);
> +       else
> +               ironlake_pfit_enable(intel_crtc);
>
>         /*
>          * On ILK+ LUT must be loaded before the pipe is running but with
> @@ -4322,6 +4338,21 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>         intel_crtc_enable_planes(crtc);
>  }
>
> +static void skylake_pfit_disable(struct intel_crtc *crtc)
> +{
> +       struct drm_device *dev = crtc->base.dev;
> +       struct drm_i915_private *dev_priv = dev->dev_private;
> +       int pipe = crtc->pipe;
> +
> +       /* To avoid upsetting the power well on haswell only disable the pfit if
> +        * it's in use. The hw state code will make sure we get this right. */
> +       if (crtc->config.pch_pfit.enabled) {
> +               I915_WRITE(PS_CTL(pipe), 0);
> +               I915_WRITE(PS_WIN_POS(pipe), 0);
> +               I915_WRITE(PS_WIN_SZ(pipe), 0);
> +       }
> +}
> +
>  static void ironlake_pfit_disable(struct intel_crtc *crtc)
>  {
>         struct drm_device *dev = crtc->base.dev;
> @@ -4433,7 +4464,10 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
>
>         intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
>
> -       ironlake_pfit_disable(intel_crtc);
> +       if (IS_SKYLAKE(dev))
> +               skylake_pfit_disable(intel_crtc);
> +       else
> +               ironlake_pfit_disable(intel_crtc);
>
>         intel_ddi_disable_pipe_clock(intel_crtc);
>
> @@ -7412,6 +7446,22 @@ static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
>                                      &pipe_config->fdi_m_n, NULL);
>  }
>
> +static void skylake_get_pfit_config(struct intel_crtc *crtc,
> +                                   struct intel_crtc_config *pipe_config)
> +{
> +       struct drm_device *dev = crtc->base.dev;
> +       struct drm_i915_private *dev_priv = dev->dev_private;
> +       uint32_t tmp;
> +
> +       tmp = I915_READ(PS_CTL(crtc->pipe));
> +
> +       if (tmp & PS_ENABLE) {
> +               pipe_config->pch_pfit.enabled = true;
> +               pipe_config->pch_pfit.pos = I915_READ(PS_WIN_POS(crtc->pipe));
> +               pipe_config->pch_pfit.size = I915_READ(PS_WIN_SZ(crtc->pipe));
> +       }
> +}
> +
>  static void ironlake_get_pfit_config(struct intel_crtc *crtc,
>                                      struct intel_crtc_config *pipe_config)
>  {
> @@ -7944,8 +7994,12 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
>         intel_get_pipe_timings(crtc, pipe_config);
>
>         pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
> -       if (intel_display_power_enabled(dev_priv, pfit_domain))
> -               ironlake_get_pfit_config(crtc, pipe_config);
> +       if (intel_display_power_enabled(dev_priv, pfit_domain)) {
> +               if (IS_SKYLAKE(dev))
> +                       skylake_get_pfit_config(crtc, pipe_config);
> +               else
> +                       ironlake_get_pfit_config(crtc, pipe_config);
> +       }
>
>         if (IS_HASWELL(dev))
>                 pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) &&
> --
> 1.9.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 84/89] drm/i915/skl: add turbo support
  2014-09-04 11:27 ` [PATCH 84/89] drm/i915/skl: add turbo support Damien Lespiau
@ 2014-09-26 14:55   ` Mika Kuoppala
  0 siblings, 0 replies; 286+ messages in thread
From: Mika Kuoppala @ 2014-09-26 14:55 UTC (permalink / raw)
  To: Damien Lespiau, intel-gfx

Damien Lespiau <damien.lespiau@intel.com> writes:

> From: Jesse Barnes <jbarnes@virtuousgeek.org>
>
> Per latest PM programming guide.
>
> v2: the wrong flavour of the function updating the ring frequency was
>     called, leading to dead locks (Tvrtko)
>
> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index ff0d8cb..9e9377a 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4708,9 +4708,36 @@ void bdw_software_turbo(struct drm_device *dev)
>  			&current_time, &current_c0);
>  }
>  
> +/* See the Gen9_GT_PM_Programming_Guide doc for the below */
>  static void gen9_enable_rps(struct drm_device *dev)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +
> +	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
> +
> +	I915_WRITE(GEN6_RPNSWREQ, 0xc800000);
> +	I915_WRITE(GEN6_RC_VIDEO_FREQ, 0xc800000);
> +
> +	I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 0xf4240);
> +	I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, 0x12060000);
> +	I915_WRITE(GEN6_RP_UP_THRESHOLD, 0xe808);
> +	I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 0x3bd08);
> +	I915_WRITE(GEN6_RP_UP_EI, 0x101d0);
> +	I915_WRITE(GEN6_RP_DOWN_EI, 0x55730);
> +	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 0xa);
> +	I915_WRITE(GEN6_PMINTRMSK, 0x6);
> +	I915_WRITE(GEN6_RP_CONTROL, GEN6_RP_MEDIA_TURBO |
> +		   GEN6_RP_MEDIA_HW_MODE | GEN6_RP_ENABLE |
> +		   GEN6_RP_UP_BUSY_AVG | GEN6_RP_DOWN_IDLE_AVG);

GEN6_RP_MEDIA_IS_GFX missing?

-Mika

> +
> +	gen8_enable_rps_interrupts(dev);
> +
> +	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
> +}
> +
> +static void gen9_enable_rc6(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_engine_cs *ring;
>  	uint32_t rc6_mask = 0;
>  	int unused;
> @@ -6355,7 +6382,9 @@ static void intel_gen6_powersave_work(struct work_struct *work)
>  	} else if (IS_VALLEYVIEW(dev)) {
>  		valleyview_enable_rps(dev);
>  	} else if (INTEL_INFO(dev)->gen >= 9) {
> +		gen9_enable_rc6(dev);
>  		gen9_enable_rps(dev);
> +		__gen6_update_ring_freq(dev);
>  	} else if (IS_BROADWELL(dev)) {
>  		gen8_enable_rps(dev);
>  		__gen6_update_ring_freq(dev);
> -- 
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 85/89] drm/i915/skl: Retrieve the frequency limits
  2014-09-04 11:27 ` [PATCH 85/89] drm/i915/skl: Retrieve the frequency limits Damien Lespiau
@ 2014-09-26 15:09   ` Mika Kuoppala
  0 siblings, 0 replies; 286+ messages in thread
From: Mika Kuoppala @ 2014-09-26 15:09 UTC (permalink / raw)
  To: Damien Lespiau, intel-gfx

Damien Lespiau <damien.lespiau@intel.com> writes:

> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_pm.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 9e9377a..77e1d52 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4712,9 +4712,13 @@ void bdw_software_turbo(struct drm_device *dev)
>  static void gen9_enable_rps(struct drm_device *dev)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	u32 rp_state_cap;
>  
>  	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
>  
> +	rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
> +	parse_rp_state_cap(dev_priv, rp_state_cap);
> +
>  	I915_WRITE(GEN6_RPNSWREQ, 0xc800000);
>  	I915_WRITE(GEN6_RC_VIDEO_FREQ, 0xc800000);
>  
> -- 
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 87/89] drm/i915/skl: AUX irqs have moved
  2014-09-04 11:27 ` [PATCH 87/89] drm/i915/skl: AUX irqs have moved Damien Lespiau
@ 2014-09-26 15:21   ` Mika Kuoppala
  0 siblings, 0 replies; 286+ messages in thread
From: Mika Kuoppala @ 2014-09-26 15:21 UTC (permalink / raw)
  To: Damien Lespiau, intel-gfx

Damien Lespiau <damien.lespiau@intel.com> writes:

> From: Jesse Barnes <jbarnes@virtuousgeek.org>
>
> Use the new AUX port irq bits where needed.
>
> v2: Rebase on top of upstream changes
> v3: Rebase on top of Oscar change to write IIR as soon as possible (Damien)
> v4: Rebase on top of the for_each_pipe() change adding dev_priv as first
>     argument (Damien)
>
> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>

> ---
>  drivers/gpu/drm/i915/i915_irq.c | 17 +++++++++++++----
>  drivers/gpu/drm/i915/i915_reg.h |  3 +++
>  2 files changed, 16 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 734b73e..8c7fbfb 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -2542,6 +2542,11 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
>  	irqreturn_t ret = IRQ_NONE;
>  	uint32_t tmp = 0;
>  	enum pipe pipe;
> +	u32 aux_mask = GEN8_AUX_CHANNEL_A;
> +
> +	if (IS_GEN9(dev))
> +		aux_mask |=  GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
> +			GEN9_AUX_CHANNEL_D;
>  
>  	master_ctl = I915_READ(GEN8_MASTER_IRQ);
>  	master_ctl &= ~GEN8_MASTER_IRQ_CONTROL;
> @@ -2574,7 +2579,8 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
>  		if (tmp) {
>  			I915_WRITE(GEN8_DE_PORT_IIR, tmp);
>  			ret = IRQ_HANDLED;
> -			if (tmp & GEN8_AUX_CHANNEL_A)
> +
> +			if (tmp & aux_mask)
>  				dp_aux_irq_handler(dev);
>  			else
>  				DRM_ERROR("Unexpected DE Port interrupt\n");
> @@ -3859,11 +3865,14 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
>  	uint32_t de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE;
>  	uint32_t de_pipe_enables;
>  	int pipe;
> +	u32 aux_en = GEN8_AUX_CHANNEL_A;
>  
> -	if (IS_GEN9(dev_priv))
> +	if (IS_GEN9(dev_priv)) {
>  		de_pipe_masked |= GEN9_PIPE_PLANE1_FLIP_DONE |
>  				  GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
> -	else
> +		aux_en |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
> +			GEN9_AUX_CHANNEL_D;
> +	} else
>  		de_pipe_masked |= GEN8_PIPE_PRIMARY_FLIP_DONE |
>  				  GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
>  
> @@ -3881,7 +3890,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
>  					  dev_priv->de_irq_mask[pipe],
>  					  de_pipe_enables);
>  
> -	GEN5_IRQ_INIT(GEN8_DE_PORT_, ~GEN8_AUX_CHANNEL_A, GEN8_AUX_CHANNEL_A);
> +	GEN5_IRQ_INIT(GEN8_DE_PORT_, ~aux_en, aux_en);
>  }
>  
>  static int gen8_irq_postinstall(struct drm_device *dev)
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 35c0759..217001d 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4990,6 +4990,9 @@ enum skl_disp_power_wells {
>  #define GEN8_DE_PORT_IIR 0x44448
>  #define GEN8_DE_PORT_IER 0x4444c
>  #define  GEN8_PORT_DP_A_HOTPLUG		(1 << 3)
> +#define  GEN9_AUX_CHANNEL_D		(1 << 27)
> +#define  GEN9_AUX_CHANNEL_C		(1 << 26)
> +#define  GEN9_AUX_CHANNEL_B		(1 << 25)
>  #define  GEN8_AUX_CHANNEL_A		(1 << 0)
>  
>  #define GEN8_DE_MISC_ISR 0x44460
> -- 
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 89/89] drm/i915/skl: Disable contexts if execlists aren't enabled
  2014-09-04 11:27 ` [PATCH 89/89] drm/i915/skl: Disable contexts if execlists aren't enabled Damien Lespiau
@ 2014-09-26 15:28   ` Mika Kuoppala
  2014-09-26 15:47     ` Chris Wilson
  0 siblings, 1 reply; 286+ messages in thread
From: Mika Kuoppala @ 2014-09-26 15:28 UTC (permalink / raw)
  To: Damien Lespiau, intel-gfx

Damien Lespiau <damien.lespiau@intel.com> writes:

> We were hiting a BUG() in get_context_size() with execlist disabled.
>
> "legacy" contexts are not supported on gen9 so we don't have a gen9
> specific size to add in there. Instead, let's disable legacy contexts
> altogether on gen9, whether we're booting with execlist enabled or not.
>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>

> ---
>  drivers/gpu/drm/i915/i915_gem_context.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index a5221d8..ec81d8a 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -320,7 +320,7 @@ int i915_gem_context_init(struct drm_device *dev)
>  	if (WARN_ON(dev_priv->ring[RCS].default_context))
>  		return 0;
>  
> -	if (i915.enable_execlists) {
> +	if (INTEL_INFO(dev)->gen >= 9 || i915.enable_execlists) {
>  		/* NB: intentionally left blank. We will allocate our own
>  		 * backing objects as we need them, thank you very much */
>  		dev_priv->hw_context_size = 0;
> -- 
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 89/89] drm/i915/skl: Disable contexts if execlists aren't enabled
  2014-09-26 15:28   ` Mika Kuoppala
@ 2014-09-26 15:47     ` Chris Wilson
  0 siblings, 0 replies; 286+ messages in thread
From: Chris Wilson @ 2014-09-26 15:47 UTC (permalink / raw)
  To: Mika Kuoppala; +Cc: intel-gfx

On Fri, Sep 26, 2014 at 06:28:53PM +0300, Mika Kuoppala wrote:
> Damien Lespiau <damien.lespiau@intel.com> writes:
> 
> > We were hiting a BUG() in get_context_size() with execlist disabled.
> >
> > "legacy" contexts are not supported on gen9 so we don't have a gen9
> > specific size to add in there. Instead, let's disable legacy contexts
> > altogether on gen9, whether we're booting with execlist enabled or not.
> >
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> 
> Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
> 
> > ---
> >  drivers/gpu/drm/i915/i915_gem_context.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> > index a5221d8..ec81d8a 100644
> > --- a/drivers/gpu/drm/i915/i915_gem_context.c
> > +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> > @@ -320,7 +320,7 @@ int i915_gem_context_init(struct drm_device *dev)
> >  	if (WARN_ON(dev_priv->ring[RCS].default_context))
> >  		return 0;
> >  
> > -	if (i915.enable_execlists) {
> > +	if (INTEL_INFO(dev)->gen >= 9 || i915.enable_execlists) {
> >  		/* NB: intentionally left blank. We will allocate our own
> >  		 * backing objects as we need them, thank you very much */
> >  		dev_priv->hw_context_size = 0;

I wouldn't have written it like this, since this hides the error, and
confuddles the intention of that branch, rather than embracing it.

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 102e8a7bcef6..f471b3511d80 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -129,7 +129,10 @@ static int get_context_size(struct drm_device *dev)
                ret = GEN8_CXT_TOTAL_SIZE;
                break;
        default:
-               BUG();
+               WARN("context size not known for gen %d\n",
+                    INTEL_INFO(dev)->gen);
+               ret = -1;
+               break;
        }
 

Would keep the fixme in place and keep the kernel running.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 48/89 v6] drm/i915/skl: Allocate DDB portions for display planes
  2014-09-19  9:58   ` Ville Syrjälä
@ 2014-09-27 14:15     ` Damien Lespiau
  2014-10-29 17:12       ` Ville Syrjälä
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-27 14:15 UTC (permalink / raw)
  To: intel-gfx

v2: Fix the 3rd plane/cursor logic (Pradeep Bhat)
v3: Fix one-by-one error in the DDB allocation code
v4: Rebase on top of the skl_pipe_pixel_rate() argument change
v5: Replace the available/start/end output parameters of
    skl_ddb_get_pipe_allocation_limits() by a single ddb entry constify
    a few arguments
    Make nth_active_pipe 0 indexed
    Use sizeof(variable) instead of sizeof(type)
    (Ville)
v6: Use the for_each_crtc() macro instead of list_for_each_entry()

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 148 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 148 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 1db4aa8..3dc689e 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2965,6 +2965,153 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
 	return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
 }
 
+/*
+ * On gen9, we need to allocate Display Data Buffer (DDB) portions to the
+ * different active planes.
+ */
+
+#define SKL_DDB_SIZE		896	/* in blocks */
+
+static void
+skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
+				   struct drm_crtc *for_crtc,
+				   const struct intel_wm_config *config,
+				   const struct skl_pipe_wm_parameters *params,
+				   struct skl_ddb_entry *alloc /* out */)
+{
+	struct drm_crtc *crtc;
+	unsigned int pipe_size, ddb_size;
+	int nth_active_pipe;
+
+	if (!params->active) {
+		alloc->start = 0;
+		alloc->end = 0;
+		return;
+	}
+
+	ddb_size = SKL_DDB_SIZE;
+
+	ddb_size -= 4; /* 4 blocks for bypass path allocation */
+
+	nth_active_pipe = 0;
+	for_each_crtc(dev, crtc) {
+		if (!intel_crtc_active(crtc))
+			continue;
+
+		if (crtc == for_crtc)
+			break;
+
+		nth_active_pipe++;
+	}
+
+	pipe_size = ddb_size / config->num_pipes_active;
+	alloc->start = nth_active_pipe * ddb_size / config->num_pipes_active;
+	alloc->end = alloc->start + pipe_size - 1;
+}
+
+static unsigned int skl_cursor_allocation(const struct intel_wm_config *config)
+{
+	if (config->num_pipes_active == 1)
+		return 32;
+
+	return 8;
+}
+
+static unsigned int
+skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p)
+{
+	return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel;
+}
+
+/*
+ * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching
+ * a 8192x4096@32bpp framebuffer:
+ *   3 * 4096 * 8192  * 4 < 2^32
+ */
+static unsigned int
+skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc,
+				 const struct skl_pipe_wm_parameters *params)
+{
+	unsigned int total_data_rate = 0;
+	int plane;
+
+	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
+		const struct intel_plane_wm_parameters *p;
+
+		p = &params->plane[plane];
+		if (!p->enabled)
+			continue;
+
+		total_data_rate += skl_plane_relative_data_rate(p);
+	}
+
+	return total_data_rate;
+}
+
+static void
+skl_allocate_pipe_ddb(struct drm_crtc *crtc,
+		      const struct intel_wm_config *config,
+		      const struct skl_pipe_wm_parameters *params,
+		      struct skl_ddb_allocation *ddb /* out */)
+{
+	struct drm_device *dev = crtc->dev;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	enum pipe pipe = intel_crtc->pipe;
+	struct skl_ddb_entry alloc;
+	uint16_t alloc_size, start, cursor_blocks;
+	unsigned int total_data_rate;
+	int plane;
+
+	skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, &alloc);
+	alloc_size = skl_ddb_entry_size(&alloc);
+	if (alloc_size == 0) {
+		memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
+		memset(&ddb->cursor[pipe], 0, sizeof(ddb->cursor[pipe]));
+		return;
+	}
+
+	cursor_blocks = skl_cursor_allocation(config);
+	ddb->cursor[pipe].start = alloc.end - cursor_blocks + 1;
+	ddb->cursor[pipe].end = alloc.end;
+
+	alloc_size -= cursor_blocks;
+	alloc.end -= cursor_blocks;
+
+	/*
+	 * Each active plane get a portion of the remaining space, in
+	 * proportion to the amount of data they need to fetch from memory.
+	 *
+	 * FIXME: we may not allocate every single block here.
+	 */
+	total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params);
+
+	start = alloc.start;
+	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
+		const struct intel_plane_wm_parameters *p;
+		unsigned int data_rate;
+		uint16_t plane_blocks;
+
+		p = &params->plane[plane];
+		if (!p->enabled)
+			continue;
+
+		data_rate = skl_plane_relative_data_rate(p);
+
+		/*
+		 * promote the expression to 64 bits to avoid overflowing, the
+		 * result is < available as data_rate / total_data_rate < 1
+		 */
+		plane_blocks = div_u64((uint64_t)alloc_size * data_rate,
+				       total_data_rate);
+
+		ddb->plane[pipe][plane].start = start;
+		ddb->plane[pipe][plane].end = start + plane_blocks - 1;
+
+		start += plane_blocks;
+	}
+
+}
+
 static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_config *config)
 {
 	/* TODO: Take into account the scalers once we support them */
@@ -3286,6 +3433,7 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
 	skl_compute_wm_pipe_parameters(crtc, params);
+	skl_allocate_pipe_ddb(crtc, config, params, ddb);
 	skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
 
 	if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* Re: [PATCH 49/89] drm/i915/skl: Program the DDB allocation
  2014-09-19 10:03   ` Ville Syrjälä
@ 2014-09-27 14:17     ` Damien Lespiau
  2014-10-29 18:42       ` Ville Syrjälä
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-27 14:17 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Fri, Sep 19, 2014 at 01:03:15PM +0300, Ville Syrjälä wrote:
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index 0ddcbad..756ff16 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -3393,6 +3393,15 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
> >  				I915_WRITE(PLANE_WM_TRANS(pipe, i),
> >  						new->plane_trans[pipe][i]);
> >  			I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
> > +
> > +			for (i = 0; i < intel_num_planes(crtc); i++)
> > +				I915_WRITE(PLANE_BUF_CFG(pipe, i),
> > +					   new->ddb.plane[pipe][i].end << 16 |
> 
> The spec doesn't say if end is inclusive or exclusive. Someone actually
> confirmed that from someone or tested it?

I remember testing it and having the end of a plane match the start of
another produces artefacts.

> > +					   new->ddb.plane[pipe][i].start);
> > +
> > +			I915_WRITE(CUR_BUF_CFG(pipe),
> > +				   new->ddb.cursor[pipe].end << 16 |
> > +				   new->ddb.cursor[pipe].start);
> >  		}
> >  	}
> 
> And here we land in deep doodoo wrt. changing the DDB allocation
> for active pipes. Someone needs to implement the correct logic to
> sequence the DDB allocation changes so that the allocations don't
> overlap at any point in time.
> 
> So this needs a big FIXME at the very least.

As seen on IRC, the DDB regs are double buffered and the "flush" patch
is supposed to take care of that.

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* [PATCH 80/89 v2] drm/i915/skl: Augment the latency debugfs files for SKL
  2014-09-19 10:53   ` Ville Syrjälä
@ 2014-09-29 13:37     ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-29 13:37 UTC (permalink / raw)
  To: intel-gfx

v2: Use the gen >= 9 in the debugfs file condition (Ville)

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 76 ++++++++++++++++++++++++++++++-------
 1 file changed, 62 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 4e629e1..069b6a6 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3513,7 +3513,7 @@ static const struct file_operations i915_display_crc_ctl_fops = {
 	.write = display_crc_ctl_write
 };
 
-static void wm_latency_show(struct seq_file *m, const uint16_t wm[5])
+static void wm_latency_show(struct seq_file *m, const uint16_t wm[8])
 {
 	struct drm_device *dev = m->private;
 	int num_levels = ilk_wm_max_level(dev) + 1;
@@ -3524,13 +3524,17 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[5])
 	for (level = 0; level < num_levels; level++) {
 		unsigned int latency = wm[level];
 
-		/* WM1+ latency values in 0.5us units */
-		if (level > 0)
+		/*
+		 * - WM1+ latency values in 0.5us units
+		 * - latencies are in us on gen9
+		 */
+		if (INTEL_INFO(dev)->gen >= 9)
+			latency *= 10;
+		else if (level > 0)
 			latency *= 5;
 
 		seq_printf(m, "WM%d %u (%u.%u usec)\n",
-			   level, wm[level],
-			   latency / 10, latency % 10);
+			   level, wm[level], latency / 10, latency % 10);
 	}
 
 	drm_modeset_unlock_all(dev);
@@ -3539,8 +3543,15 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[5])
 static int pri_wm_latency_show(struct seq_file *m, void *data)
 {
 	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const uint16_t *latencies;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.pri_latency;
 
-	wm_latency_show(m, to_i915(dev)->wm.pri_latency);
+	wm_latency_show(m, latencies);
 
 	return 0;
 }
@@ -3548,8 +3559,15 @@ static int pri_wm_latency_show(struct seq_file *m, void *data)
 static int spr_wm_latency_show(struct seq_file *m, void *data)
 {
 	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const uint16_t *latencies;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.spr_latency;
 
-	wm_latency_show(m, to_i915(dev)->wm.spr_latency);
+	wm_latency_show(m, latencies);
 
 	return 0;
 }
@@ -3557,8 +3575,15 @@ static int spr_wm_latency_show(struct seq_file *m, void *data)
 static int cur_wm_latency_show(struct seq_file *m, void *data)
 {
 	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	const uint16_t *latencies;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.cur_latency;
 
-	wm_latency_show(m, to_i915(dev)->wm.cur_latency);
+	wm_latency_show(m, latencies);
 
 	return 0;
 }
@@ -3594,11 +3619,11 @@ static int cur_wm_latency_open(struct inode *inode, struct file *file)
 }
 
 static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
-				size_t len, loff_t *offp, uint16_t wm[5])
+				size_t len, loff_t *offp, uint16_t wm[8])
 {
 	struct seq_file *m = file->private_data;
 	struct drm_device *dev = m->private;
-	uint16_t new[5] = { 0 };
+	uint16_t new[8] = { 0 };
 	int num_levels = ilk_wm_max_level(dev) + 1;
 	int level;
 	int ret;
@@ -3612,7 +3637,9 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
 
 	tmp[len] = '\0';
 
-	ret = sscanf(tmp, "%hu %hu %hu %hu %hu", &new[0], &new[1], &new[2], &new[3], &new[4]);
+	ret = sscanf(tmp, "%hu %hu %hu %hu %hu %hu %hu %hu",
+		     &new[0], &new[1], &new[2], &new[3],
+		     &new[4], &new[5], &new[6], &new[7]);
 	if (ret != num_levels)
 		return -EINVAL;
 
@@ -3632,8 +3659,15 @@ static ssize_t pri_wm_latency_write(struct file *file, const char __user *ubuf,
 {
 	struct seq_file *m = file->private_data;
 	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint16_t *latencies;
 
-	return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.pri_latency);
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.pri_latency;
+
+	return wm_latency_write(file, ubuf, len, offp, latencies);
 }
 
 static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf,
@@ -3641,8 +3675,15 @@ static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf,
 {
 	struct seq_file *m = file->private_data;
 	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint16_t *latencies;
 
-	return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.spr_latency);
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.spr_latency;
+
+	return wm_latency_write(file, ubuf, len, offp, latencies);
 }
 
 static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
@@ -3650,8 +3691,15 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
 {
 	struct seq_file *m = file->private_data;
 	struct drm_device *dev = m->private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint16_t *latencies;
+
+	if (INTEL_INFO(dev)->gen >= 9)
+		latencies = dev_priv->wm.skl_latency;
+	else
+		latencies = to_i915(dev)->wm.cur_latency;
 
-	return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.cur_latency);
+	return wm_latency_write(file, ubuf, len, offp, latencies);
 }
 
 static const struct file_operations i915_pri_wm_latency_fops = {
-- 
1.8.3.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* Re: [PATCH] drm/i915/skl: fetch, enable/disable pfit as needed v2
  2014-09-25 18:06     ` Paulo Zanoni
@ 2014-09-29 13:51       ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-29 13:51 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: Intel Graphics Development

On Thu, Sep 25, 2014 at 03:06:17PM -0300, Paulo Zanoni wrote:
> 2014-09-25 14:58 GMT-03:00 Jesse Barnes <jbarnes@virtuousgeek.org>:
> > This moved around on SKL, so we need to make sure we read/write the
> > correct regs.
> >
> > v2: fixup WIN_POS offsets (Paulo)
> >     zero out WIN_POS reg at disable time (Paulo)
> 
> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

Thanks for the patch and review, I've queued it in my SKL branch that's
queued for Daniel.

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 74/89] drm/i915/skl: Implement queue_flip
  2014-09-23 20:06   ` Paulo Zanoni
@ 2014-09-29 16:54     ` Damien Lespiau
  2014-09-29 17:13     ` [PATCH 74/89 v4] " Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-29 16:54 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: Intel Graphics Development

On Tue, Sep 23, 2014 at 05:06:35PM -0300, Paulo Zanoni wrote:
> 2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> > A few bits have changed in MI_DISPLAY_FLIP to accomodate the new planes.
> > DE_RRMR seems to have kept its plane flip bits backward compatible.
> >
> > v2: Rebase on top of nightly
> > v2: Rebase on top of nightly (minor conflict in i915_reg.h)

v3

> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

Some answers below, others in v4 that should follow shortly.

> > ---
> >  drivers/gpu/drm/i915/i915_reg.h      | 10 +++++
> >  drivers/gpu/drm/i915/intel_display.c | 78 ++++++++++++++++++++++++++++++++++++
> >  2 files changed, 88 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> > index 84a0de6..176e84e 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -240,6 +240,16 @@
> >  #define   MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19)
> >  #define   MI_DISPLAY_FLIP_IVB_PLANE_C  (4 << 19)
> >  #define   MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19)
> > +/* SKL ones */
> > +#define   MI_DISPLAY_FLIP_SKL_PLANE_1_A        (0 << 8)
> > +#define   MI_DISPLAY_FLIP_SKL_PLANE_1_B        (1 << 8)
> > +#define   MI_DISPLAY_FLIP_SKL_PLANE_1_C        (2 << 8)
> > +#define   MI_DISPLAY_FLIP_SKL_PLANE_2_A        (4 << 8)
> > +#define   MI_DISPLAY_FLIP_SKL_PLANE_2_B        (5 << 8)
> > +#define   MI_DISPLAY_FLIP_SKL_PLANE_2_C        (6 << 8)
> > +#define   MI_DISPLAY_FLIP_SKL_PLANE_3_A        (7 << 8)
> > +#define   MI_DISPLAY_FLIP_SKL_PLANE_3_B        (8 << 8)
> > +#define   MI_DISPLAY_FLIP_SKL_PLANE_3_C        (9 << 8)
> 
> BSpec seems to mention these bits on CHV too... Maybe we want the new
> function to run on CHV + GEN9? Ping Ville.

Funnily the bits at 21:19 are still documented on CHV. So maybe the
current code works? Considering we only use queue_flip() for the primary
planes at the moment ad we want to move to MMIO based flips in the near
future, probably doesn't matter too much here.

> >  #define MI_SEMAPHORE_MBOX      MI_INSTR(0x16, 1) /* gen6, gen7 */
> >  #define   MI_SEMAPHORE_GLOBAL_GTT    (1<<22)
> >  #define   MI_SEMAPHORE_UPDATE      (1<<21)
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index abd4201..393bd19 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -9913,6 +9913,81 @@ static int intel_queue_mmio_flip(struct drm_device *dev,
> >         return 0;
> >  }
> >
> > +static int intel_gen9_queue_flip(struct drm_device *dev,
> > +                                struct drm_crtc *crtc,
> > +                                struct drm_framebuffer *fb,
> > +                                struct drm_i915_gem_object *obj,
> > +                                struct intel_engine_cs *ring,
> > +                                uint32_t flags)
> > +{
> > +       struct drm_i915_private *dev_priv = dev->dev_private;
> > +       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +       uint32_t plane = 0, stride;
> > +       int ret;
> > +
> > +       ring = obj->ring;
> > +       if (ring == NULL || ring->id != BCS)
> > +               ring = &dev_priv->ring[RCS];
> 
> Why do we need these lines above? The other Gens don't have it. And it
> looks like ring shouldn't really be NULL, otherwise the other gens are
> going to crash.
> 
> 
> > +
> > +       ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
> > +       if (ret)
> > +               goto err;
> 
> Our only caller (intel_crtc_page_flip) seems to do this for us
> already. Also, the other gens don't do this at their queue_flip
> implementations.

If you're looking for reasons, it's because the code elsewhere used to
look like that and rebasing still worked, so this patch implements
queue_flip() like it used to be implemented at the time of its writing.
Should be fixed now.

> > +
> > +       switch(intel_crtc->pipe) {
> > +       case PIPE_A:
> > +               plane = MI_DISPLAY_FLIP_SKL_PLANE_1_A;
> > +               break;
> > +       case PIPE_B:
> > +               plane = MI_DISPLAY_FLIP_SKL_PLANE_1_B;
> > +               break;
> > +       case PIPE_C:
> > +               plane = MI_DISPLAY_FLIP_SKL_PLANE_1_C;
> > +               break;
> > +       default:
> > +               BUG();
> 
> The gen7 version does WARN_ONCE() and returns -ENODEV instead of
> BUG(). Seems more reasonable to just not update the screen instead of
> killing the whole machine.
> 
> 
> > +       }
> > +
> > +       switch (obj->tiling_mode) {
> > +       case I915_TILING_NONE:
> > +               stride = fb->pitches[0] >> 6;
> > +               break;
> > +       case I915_TILING_X:
> > +               stride = fb->pitches[0] >> 9;
> > +               break;
> > +       default:
> > +               BUG();
> 
> Also replace this for a WARN and return an error code?
> 
> > +       }
> > +
> > +       ret = intel_ring_begin(ring, 10);
> > +       if (ret)
> > +               goto err_unpin;
> > +
> > +       intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
> > +       intel_ring_emit(ring, DERRMR);
> > +       intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE |
> > +                               DERRMR_PIPEB_PRI_FLIP_DONE |
> > +                               DERRMR_PIPEC_PRI_FLIP_DONE));
> > +       intel_ring_emit(ring, MI_STORE_REGISTER_MEM_GEN8(1) |
> > +                             MI_SRM_LRM_GLOBAL_GTT);
> > +       intel_ring_emit(ring, DERRMR);
> > +       intel_ring_emit(ring, ring->scratch.gtt_offset + 256);
> > +       intel_ring_emit(ring, 0);
> 
> Do we still need the DERRMR thing? BSpec doesn't seem to mention it
> anymore on the SKL page. And we only do it for RCS on Gens 7/8.

The answer we had from the HW guys (Art) for that is that the need to
unmask DE_RRMR depends on the gen. Turns out, on gen9, we need to unmask
those bits for the CS to receive the message as some internal state
depends on receiving it. Without it, the flips weren't working.

> > +
> > +       intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane);
> > +       intel_ring_emit(ring, stride << 6 | obj->tiling_mode);
> > +       intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj));
> 
> Gen 7 uses intel_crtc->unpin_work->gtt_offset, which seems to be a
> little faster than calling i915_gem_obj_ggtt_offset() again. The
> work->gtt_offset was just set by the function that calls queue_flip(),
> so it should be correct.
> 
> 
> > +
> > +       intel_mark_page_flip_active(intel_crtc);
> > +       __intel_ring_advance(ring);
> > +
> > +       return 0;
> > +
> > +err_unpin:
> > +       intel_unpin_fb_obj(obj);
> > +err:
> > +       return ret;
> > +}
> > +
> >  static int intel_default_queue_flip(struct drm_device *dev,
> >                                     struct drm_crtc *crtc,
> >                                     struct drm_framebuffer *fb,
> > @@ -12740,6 +12815,9 @@ static void intel_init_display(struct drm_device *dev)
> >         case 8: /* FIXME(BDW): Check that the gen8 RCS flip works. */
> >                 dev_priv->display.queue_flip = intel_gen7_queue_flip;
> >                 break;
> > +       case 9:
> > +               dev_priv->display.queue_flip = intel_gen9_queue_flip;
> > +               break;
> >         }
> >
> >         intel_panel_init_backlight_funcs(dev);
> > --
> > 1.8.3.1
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> 
> 
> -- 
> Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* [PATCH 74/89 v4] drm/i915/skl: Implement queue_flip
  2014-09-23 20:06   ` Paulo Zanoni
  2014-09-29 16:54     ` Damien Lespiau
@ 2014-09-29 17:13     ` Damien Lespiau
  2014-09-30 12:08       ` Paulo Zanoni
  1 sibling, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-09-29 17:13 UTC (permalink / raw)
  To: intel-gfx

A few bits have changed in MI_DISPLAY_FLIP to accomodate the new planes.
DE_RRMR seems to have kept its plane flip bits backward compatible.

v2: Rebase on top of nightly
v3: Rebase on top of nightly (minor conflict in i915_reg.h)
v4: Remove code that is now part of intel_crtc_page_flip()
    Don't use BUG() in default:
    Use intel_crtc->unpin_work->gtt_offset
    (Paulo)

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h      | 10 ++++++
 drivers/gpu/drm/i915/intel_display.c | 66 ++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 98413a8..bbbd4d8 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -248,6 +248,16 @@
 #define   MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19)
 #define   MI_DISPLAY_FLIP_IVB_PLANE_C  (4 << 19)
 #define   MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19)
+/* SKL ones */
+#define   MI_DISPLAY_FLIP_SKL_PLANE_1_A	(0 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_1_B	(1 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_1_C	(2 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_2_A	(4 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_2_B	(5 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_2_C	(6 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_3_A	(7 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_3_B	(8 << 8)
+#define   MI_DISPLAY_FLIP_SKL_PLANE_3_C	(9 << 8)
 #define MI_SEMAPHORE_MBOX	MI_INSTR(0x16, 1) /* gen6, gen7 */
 #define   MI_SEMAPHORE_GLOBAL_GTT    (1<<22)
 #define   MI_SEMAPHORE_UPDATE	    (1<<21)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 070c417..feed6d7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9748,6 +9748,69 @@ static int intel_queue_mmio_flip(struct drm_device *dev,
 	return 0;
 }
 
+static int intel_gen9_queue_flip(struct drm_device *dev,
+				 struct drm_crtc *crtc,
+				 struct drm_framebuffer *fb,
+				 struct drm_i915_gem_object *obj,
+				 struct intel_engine_cs *ring,
+				 uint32_t flags)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	uint32_t plane = 0, stride;
+	int ret;
+
+	switch(intel_crtc->pipe) {
+	case PIPE_A:
+		plane = MI_DISPLAY_FLIP_SKL_PLANE_1_A;
+		break;
+	case PIPE_B:
+		plane = MI_DISPLAY_FLIP_SKL_PLANE_1_B;
+		break;
+	case PIPE_C:
+		plane = MI_DISPLAY_FLIP_SKL_PLANE_1_C;
+		break;
+	default:
+		WARN_ONCE(1, "unknown plane in flip command\n");
+		return -ENODEV;
+	}
+
+	switch (obj->tiling_mode) {
+	case I915_TILING_NONE:
+		stride = fb->pitches[0] >> 6;
+		break;
+	case I915_TILING_X:
+		stride = fb->pitches[0] >> 9;
+		break;
+	default:
+		WARN_ONCE(1, "unknown tiling in flip command\n");
+		return -ENODEV;
+	}
+
+	ret = intel_ring_begin(ring, 10);
+	if (ret)
+		return ret;
+
+	intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
+	intel_ring_emit(ring, DERRMR);
+	intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE |
+				DERRMR_PIPEB_PRI_FLIP_DONE |
+				DERRMR_PIPEC_PRI_FLIP_DONE));
+	intel_ring_emit(ring, MI_STORE_REGISTER_MEM_GEN8(1) |
+			      MI_SRM_LRM_GLOBAL_GTT);
+	intel_ring_emit(ring, DERRMR);
+	intel_ring_emit(ring, ring->scratch.gtt_offset + 256);
+	intel_ring_emit(ring, 0);
+
+	intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane);
+	intel_ring_emit(ring, stride << 6 | obj->tiling_mode);
+	intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset);
+
+	intel_mark_page_flip_active(intel_crtc);
+	__intel_ring_advance(ring);
+
+	return 0;
+}
+
 static int intel_default_queue_flip(struct drm_device *dev,
 				    struct drm_crtc *crtc,
 				    struct drm_framebuffer *fb,
@@ -12678,6 +12741,9 @@ static void intel_init_display(struct drm_device *dev)
 	case 8: /* FIXME(BDW): Check that the gen8 RCS flip works. */
 		dev_priv->display.queue_flip = intel_gen7_queue_flip;
 		break;
+	case 9:
+		dev_priv->display.queue_flip = intel_gen9_queue_flip;
+		break;
 	}
 
 	intel_panel_init_backlight_funcs(dev);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* Re: [PATCH 74/89 v4] drm/i915/skl: Implement queue_flip
  2014-09-29 17:13     ` [PATCH 74/89 v4] " Damien Lespiau
@ 2014-09-30 12:08       ` Paulo Zanoni
  2014-09-30 12:19         ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Paulo Zanoni @ 2014-09-30 12:08 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

2014-09-29 14:13 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> A few bits have changed in MI_DISPLAY_FLIP to accomodate the new planes.
> DE_RRMR seems to have kept its plane flip bits backward compatible.
>
> v2: Rebase on top of nightly
> v3: Rebase on top of nightly (minor conflict in i915_reg.h)
> v4: Remove code that is now part of intel_crtc_page_flip()
>     Don't use BUG() in default:
>     Use intel_crtc->unpin_work->gtt_offset
>     (Paulo)
>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h      | 10 ++++++
>  drivers/gpu/drm/i915/intel_display.c | 66 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 76 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 98413a8..bbbd4d8 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -248,6 +248,16 @@
>  #define   MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19)
>  #define   MI_DISPLAY_FLIP_IVB_PLANE_C  (4 << 19)
>  #define   MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19)
> +/* SKL ones */
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_1_A        (0 << 8)
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_1_B        (1 << 8)
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_1_C        (2 << 8)
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_2_A        (4 << 8)
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_2_B        (5 << 8)
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_2_C        (6 << 8)
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_3_A        (7 << 8)
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_3_B        (8 << 8)
> +#define   MI_DISPLAY_FLIP_SKL_PLANE_3_C        (9 << 8)
>  #define MI_SEMAPHORE_MBOX      MI_INSTR(0x16, 1) /* gen6, gen7 */
>  #define   MI_SEMAPHORE_GLOBAL_GTT    (1<<22)
>  #define   MI_SEMAPHORE_UPDATE      (1<<21)
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 070c417..feed6d7 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -9748,6 +9748,69 @@ static int intel_queue_mmio_flip(struct drm_device *dev,
>         return 0;
>  }
>
> +static int intel_gen9_queue_flip(struct drm_device *dev,
> +                                struct drm_crtc *crtc,
> +                                struct drm_framebuffer *fb,
> +                                struct drm_i915_gem_object *obj,
> +                                struct intel_engine_cs *ring,
> +                                uint32_t flags)
> +{
> +       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +       uint32_t plane = 0, stride;
> +       int ret;
> +
> +       switch(intel_crtc->pipe) {

I just noticed that the gen7 function checks for intel_crtc->plane
instead of ->pipe. This shouldn't be a problem on Gen 9, right?

If that's not a problem: Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

> +       case PIPE_A:
> +               plane = MI_DISPLAY_FLIP_SKL_PLANE_1_A;
> +               break;
> +       case PIPE_B:
> +               plane = MI_DISPLAY_FLIP_SKL_PLANE_1_B;
> +               break;
> +       case PIPE_C:
> +               plane = MI_DISPLAY_FLIP_SKL_PLANE_1_C;
> +               break;
> +       default:
> +               WARN_ONCE(1, "unknown plane in flip command\n");
> +               return -ENODEV;
> +       }
> +
> +       switch (obj->tiling_mode) {
> +       case I915_TILING_NONE:
> +               stride = fb->pitches[0] >> 6;
> +               break;
> +       case I915_TILING_X:
> +               stride = fb->pitches[0] >> 9;
> +               break;
> +       default:
> +               WARN_ONCE(1, "unknown tiling in flip command\n");
> +               return -ENODEV;
> +       }
> +
> +       ret = intel_ring_begin(ring, 10);
> +       if (ret)
> +               return ret;
> +
> +       intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
> +       intel_ring_emit(ring, DERRMR);
> +       intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE |
> +                               DERRMR_PIPEB_PRI_FLIP_DONE |
> +                               DERRMR_PIPEC_PRI_FLIP_DONE));
> +       intel_ring_emit(ring, MI_STORE_REGISTER_MEM_GEN8(1) |
> +                             MI_SRM_LRM_GLOBAL_GTT);
> +       intel_ring_emit(ring, DERRMR);
> +       intel_ring_emit(ring, ring->scratch.gtt_offset + 256);
> +       intel_ring_emit(ring, 0);
> +
> +       intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane);
> +       intel_ring_emit(ring, stride << 6 | obj->tiling_mode);
> +       intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset);
> +
> +       intel_mark_page_flip_active(intel_crtc);
> +       __intel_ring_advance(ring);
> +
> +       return 0;
> +}
> +
>  static int intel_default_queue_flip(struct drm_device *dev,
>                                     struct drm_crtc *crtc,
>                                     struct drm_framebuffer *fb,
> @@ -12678,6 +12741,9 @@ static void intel_init_display(struct drm_device *dev)
>         case 8: /* FIXME(BDW): Check that the gen8 RCS flip works. */
>                 dev_priv->display.queue_flip = intel_gen7_queue_flip;
>                 break;
> +       case 9:
> +               dev_priv->display.queue_flip = intel_gen9_queue_flip;
> +               break;
>         }
>
>         intel_panel_init_backlight_funcs(dev);
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 74/89 v4] drm/i915/skl: Implement queue_flip
  2014-09-30 12:08       ` Paulo Zanoni
@ 2014-09-30 12:19         ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-09-30 12:19 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: Intel Graphics Development

On Tue, Sep 30, 2014 at 09:08:35AM -0300, Paulo Zanoni wrote:
> > +static int intel_gen9_queue_flip(struct drm_device *dev,
> > +                                struct drm_crtc *crtc,
> > +                                struct drm_framebuffer *fb,
> > +                                struct drm_i915_gem_object *obj,
> > +                                struct intel_engine_cs *ring,
> > +                                uint32_t flags)
> > +{
> > +       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +       uint32_t plane = 0, stride;
> > +       int ret;
> > +
> > +       switch(intel_crtc->pipe) {
> 
> I just noticed that the gen7 function checks for intel_crtc->plane
> instead of ->pipe. This shouldn't be a problem on Gen 9, right?
> 
> If that's not a problem: Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

Indeed, not a problem for all the platforms where crtc->plane ==
crtc->pipe (and I used pipe because I wanted to forget about that dark
past).

AFAICS, the only case where crtc->plane != crtc->pipe is when:

  (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4) is true

(see intel_primary_plane_create())

Thanks for the review!

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 58/89] drm/i915/skl: Register definitions for SKL Clocks
  2014-09-22 18:17   ` Paulo Zanoni
@ 2014-10-01 10:51     ` M, Satheeshakrishna
  2014-11-04 16:11     ` [PATCH 58/89 v5] " Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: M, Satheeshakrishna @ 2014-10-01 10:51 UTC (permalink / raw)
  To: Paulo Zanoni, Damien Lespiau; +Cc: Intel Graphics Development

On 9/22/2014 11:47 PM, Paulo Zanoni wrote:
> 2014-09-04 8:27 GMT-03:00 Damien Lespiau<damien.lespiau@intel.com>:
>> From: Satheeshakrishna M<satheeshakrishna.m@intel.com>
>>
>> This patch defines the necessary SKL registers for implementing the
>> new clocking mechanism.
>>
>> v2: Addressed review comments by Damien
>>          - Added code comment
>>          - Introduced enum for WRPLL values
>>
>> v3: Rebase on top of nightly (minor conflict in i915_reg.h)
>>
>> v4: Use 0x, not 0X (Ville)
> Bikeshed: One of my worries with this patch is that names like
> CDCLK_CTL and DPLL_CTRL1 are too generic. Basically every platform has
> a CDCLK and DPLLs... Maybe adding _SKL in their names would help a
> little. Or maybe we don't need it, since the functions using these
> defines will already be surrounded by IS_SKL+ checks...
Tried to keep the names to match bspec. I haven't any instance where 
register name remains same and offset changes from one platform to another.
>> Signed-off-by: Satheeshakrishna M<satheeshakrishna.m@intel.com>  (v2)
>> Signed-off-by: Damien Lespiau<damien.lespiau@intel.com>  (v3,v4)
>> ---
>>   drivers/gpu/drm/i915/i915_reg.h | 84 +++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 84 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>> index 417075d..2364ece 100644
>> --- a/drivers/gpu/drm/i915/i915_reg.h
>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>> @@ -6336,6 +6336,90 @@ enum punit_power_well {
>>   #define  LCPLL_CD_SOURCE_FCLK          (1<<21)
>>   #define  LCPLL_CD_SOURCE_FCLK_DONE     (1<<19)
>>
>> +/*
>> + * SKL Clocks
>> + */
>> +
>> +/* CDCLK_CTL */
>> +#define CDCLK_CTL                      0x46000
>> +#define  CDCLK_FREQ_SEL_MASK           (3<<26)
>> +#define  CDCLK_FREQ_450_432            (0<<26)
>> +#define  CDCLK_FREQ_540                        (1<<26)
>> +#define  CDCLK_FREQ_337_308            (2<<26)
>> +#define  CDCLK_FREQ_675_617            (3<<26)
>> +#define         CDCLK_FREQ_DECIMAL_MASK        (0x7ff)
> <ocd> Please replace the tab for a space on the line above. </ocd>
ok
>> +
>> +/* LCPLL_CTL */
>> +#define LCPLL1_CTL             0x46010
>> +#define LCPLL2_CTL             0x46014
>> +#define  LCPLL_PLL_ENABLE      (1<<31)
>> +
>> +/* DPLL control1 */
>> +#define DPLL_CTRL1             0x6C058
>> +#define  DPLL_CTRL1_HDMI_MODE(id)              (1<<((id)*6+5))
>> +#define  DPLL_CTRL1_SSC(id)                    (1<<((id)*6+4))
>> +#define  DPLL_CRTL1_LINK_RATE_MASK(id)         (7<<((id)*6+1))
>> +#define  DPLL_CRTL1_LINK_RATE(linkrate, id)    ((linkrate)<<((id)*6+1))
>> +#define  DPLL_CTRL1_OVERRIDE(id)               (1<<((id)*6))
>> +#define  DPLL_CRTL1_LINK_RATE_2700             0
>> +#define  DPLL_CRTL1_LINK_RATE_1350             1
>> +#define  DPLL_CRTL1_LINK_RATE_810              2
>> +#define  DPLL_CRTL1_LINK_RATE_1620             3
>> +#define  DPLL_CRTL1_LINK_RATE_1080             4
>> +#define  DPLL_CRTL1_LINK_RATE_2160             5
>> +
>> +/* DPLL control2 */
>> +#define DPLL_CTRL2                             0x6C05C
>> +#define  DPLL_CTRL2_DDI_CLK_OFF(port)          (1<<(port+15))
>> +#define  DPLL_CTRL2_DDI_CLK_SEL_MASK(port)     (3<<((port)*3+1))
>> +#define  DPLL_CTRL2_DDI_CLK_SEL(clk, port)     (clk<<((port)*3+1))
>> +#define  DPLL_CTRL2_DDI_SEL_OVERRIDE(port)     (1<<(port*3))
>> +
>> +/* DPLL Status */
>> +#define DPLL_STATUS    0x6C060
>> +#define         DPLL_LOCK(id)  (1<<((id)*8))
> Bad tab here too.
ok, will take care of this.
>
>> +
>> +/* DPLL cfg */
>> +#define DPLL1_CFGCR1   0x6C040
>> +#define DPLL2_CFGCR1   0x6C048
>> +#define DPLL3_CFGCR1   0x6C050
>> +#define  DPLL_CFGCR1_FREQ_ENABLE       (1<<31)
>> +#define  DPLL_CFGCR1_DCO_FRACTION_MASK (0x7fff<<9)
>> +#define  DPLL_CFGCR1_DCO_FRACTION(x)   (x<<9)
>> +#define  DPLL_CFGCR1_DCO_INTEGER_MASK  (0x1ff)
>> +
>> +#define DPLL1_CFGCR2   0x6C044
>> +#define DPLL2_CFGCR2   0x6C04C
>> +#define DPLL3_CFGCR2   0x6C054
>> +#define  DPLL_CFGCR2_QDIV_RATIO_MASK   (0xff<<8)
>> +#define  DPLL_CFGCR2_QDIV_RATIO(x)     (x<<8)
>> +#define  DPLL_CFGCR2_QDIV_MODE(x)      (x<<7)
>> +#define  DPLL_CFGCR2_KDIV_MASK         (3<<5)
>> +#define  DPLL_CFGCR2_KDIV(x)           (x<<5)
>> +#define  DPLL_CFGCR2_PDIV_MASK         (7<<2)
>> +#define  DPLL_CFGCR2_PDIV(x)           (x<<2)
>> +#define  DPLL_CFGCR2_CENTRAL_FREQ_MASK (3)
>> +
>> +enum central_freq {
>> +       freq_9600 = 0,
>> +       freq_9000 = 1,
>> +       freq_8400 = 3,
>> +};
>> +
>> +enum pdiv {
>> +       pdiv_1 = 0,
>> +       pdiv_2 = 1,
>> +       pdiv_3 = 2,
>> +       pdiv_7 = 4,
>> +};
>> +
>> +enum kdiv {
>> +       kdiv_5 = 0,
>> +       kdiv_2 = 1,
>> +       kdiv_3 = 2,
>> +       kdiv_1 = 3,
>> +};
>> +
> I find it weird that we're using enums here. We don't have the
> tradition to do this, so it's a deviation from the usual coding style.
ok, will change this to #define
> With or without changes:
> Reviewed-by: Paulo Zanoni<paulo.r.zanoni@intel.com>
>
>>   /* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register,
>>    * since on HSW we can't write to it using I915_WRITE. */
>>   #define D_COMP_HSW                     (MCHBAR_MIRROR_BASE_SNB + 0x5F0C)
>> --
>> 1.8.3.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 60/89] drm/i915/skl: CD clock back calculation for SKL
  2014-09-22 19:19   ` Paulo Zanoni
@ 2014-10-01 10:51     ` M, Satheeshakrishna
  2014-11-04 16:15     ` [PATCH 60/89 v5] " Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: M, Satheeshakrishna @ 2014-10-01 10:51 UTC (permalink / raw)
  To: Paulo Zanoni, Damien Lespiau; +Cc: Intel Graphics Development

On 9/23/2014 12:49 AM, Paulo Zanoni wrote:
> 2014-09-04 8:27 GMT-03:00 Damien Lespiau<damien.lespiau@intel.com>:
>> From: Satheeshakrishna M<satheeshakrishna.m@intel.com>
>>
>> Determine programmed cd clock for SKL.
>>
>> v2: Fix the LCPLL1 enable warning logic
>>
>> v3: Rebase over the hsw pll rework.
>>
>> v4: Rebase on top of the per-platform split (Damien)
>>
>> Signed-off-by: Satheeshakrishna M<satheeshakrishna.m@intel.com>
>> Signed-off-by: Damien Lespiau<damien.lespiau@intel.com>
>> ---
>>   drivers/gpu/drm/i915/intel_ddi.c | 76 +++++++++++++++++++++++++++++++++++-----
>>   1 file changed, 67 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
>> index ba1103f..e7a5428 100644
>> --- a/drivers/gpu/drm/i915/intel_ddi.c
>> +++ b/drivers/gpu/drm/i915/intel_ddi.c
>> @@ -1260,6 +1260,55 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
>>          }
>>   }
>>
>> +static int skl_get_cdclk_freq(struct drm_i915_private *dev_priv)
>> +{
>> +       uint32_t lcpll1 = I915_READ(LCPLL1_CTL);
>> +       uint32_t cdctl = I915_READ(CDCLK_CTL);
>> +       uint32_t linkrate;
>> +
>> +       if (!(lcpll1 & LCPLL_PLL_ENABLE)) {
>> +               WARN(1, "LCPLL1 not enabled\n");
>> +               return 24000; /* 24MHz is the cd freq with NSSC ref */
>> +       }
>> +
>> +       if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540)
>> +               return 540000;
>> +
>> +       linkrate = (I915_READ(DPLL_CTRL1) &
>> +                   DPLL_CRTL1_LINK_RATE_MASK(SKL_DPLL0)) >> 1;
>> +
>> +       if (linkrate == DPLL_CRTL1_LINK_RATE_2160 ||
>> +           linkrate == DPLL_CRTL1_LINK_RATE_1080) {
>> +               /* vco 8640 */
>> +               switch (cdctl & CDCLK_FREQ_SEL_MASK) {
>> +               case CDCLK_FREQ_450_432:
>> +                       return 432000;
>> +               case CDCLK_FREQ_337_308:
>> +                       return 308570;
>> +               case CDCLK_FREQ_675_617:
>> +                       return 617140;
>> +                       break;
> This is the only line with a "break" after a return :)
oops.. will remove it
>
>> +               default:
>> +                       WARN(1, "Unknown cd freq selection\n");
>> +               }
>> +       } else {
>> +               /* vco 8100 */
>> +               switch (cdctl & CDCLK_FREQ_SEL_MASK) {
>> +               case CDCLK_FREQ_450_432:
>> +                       return 450000;
>> +               case CDCLK_FREQ_337_308:
>> +                       return 337500;
>> +               case CDCLK_FREQ_675_617:
>> +                       return 675000;
>> +               default:
>> +                       WARN(1, "Unknown cd freq selection\n");
>> +               }
>> +       }
>> +
>> +       /* error case, do as if DPLL0 isn't enabled */
>> +       return 24000;
>> +}
>> +
>>   static int bdw_get_cdclk_freq(struct drm_i915_private *dev_priv)
>>   {
>>          uint32_t lcpll = I915_READ(LCPLL_CTL);
>> @@ -1301,6 +1350,9 @@ int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
>>   {
>>          struct drm_device *dev = dev_priv->dev;
>>
>> +       if (IS_SKYLAKE(dev))
>> +               return skl_get_cdclk_freq(dev_priv);
>> +
> I hope someone will replace this with a "switch (INTEL_INFO(gen))"
> before Gen 15 :)
>
> With or without changes: Reviewed-by: Paulo Zanoni<paulo.r.zanoni@intel.com>
>
>
>>          if (IS_BROADWELL(dev))
>>                  return bdw_get_cdclk_freq(dev_priv);
>>
>> @@ -1369,19 +1421,25 @@ void intel_ddi_pll_init(struct drm_device *dev)
>>
>>          hsw_shared_dplls_init(dev_priv);
>>
>> -       /* The LCPLL register should be turned on by the BIOS. For now let's
>> -        * just check its state and print errors in case something is wrong.
>> -        * Don't even try to turn it on.
>> -        */
>> -
>>          DRM_DEBUG_KMS("CDCLK running at %dKHz\n",
>>                        intel_ddi_get_cdclk_freq(dev_priv));
>>
>> -       if (val & LCPLL_CD_SOURCE_FCLK)
>> -               DRM_ERROR("CDCLK source is not LCPLL\n");
>> +       if (IS_SKYLAKE(dev)) {
>> +               if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
>> +                       DRM_ERROR("LCPLL1 is disabled\n");
>> +       } else {
>> +               /*
>> +                * The LCPLL register should be turned on by the BIOS. For now
>> +                * let's just check its state and print errors in case
>> +                * something is wrong.  Don't even try to turn it on.
>> +                */
>> +
>> +               if (val & LCPLL_CD_SOURCE_FCLK)
>> +                       DRM_ERROR("CDCLK source is not LCPLL\n");
>>
>> -       if (val & LCPLL_PLL_DISABLE)
>> -               DRM_ERROR("LCPLL is disabled\n");
>> +               if (val & LCPLL_PLL_DISABLE)
>> +                       DRM_ERROR("LCPLL is disabled\n");
>> +       }
>>   }
>>
>>   void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
>> --
>> 1.8.3.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 61/89] drm/i915/skl: Determine enabled PLL and its linkrate/pixel clock
  2014-09-22 20:12   ` Paulo Zanoni
@ 2014-10-01 10:51     ` M, Satheeshakrishna
  2014-10-03 18:25       ` Paulo Zanoni
  2014-11-04 16:17     ` [PATCH 61/89 v4] " Damien Lespiau
  1 sibling, 1 reply; 286+ messages in thread
From: M, Satheeshakrishna @ 2014-10-01 10:51 UTC (permalink / raw)
  To: Paulo Zanoni, Damien Lespiau; +Cc: Intel Graphics Development

On 9/23/2014 1:42 AM, Paulo Zanoni wrote:
> 2014-09-04 8:27 GMT-03:00 Damien Lespiau<damien.lespiau@intel.com>:
>> From: Satheeshakrishna M<satheeshakrishna.m@intel.com>
>>
>> v2: Fixup compilation due to the removal of the intel_ddi_dpll_id enum.
>> And add a fixme about the abuse of pipe_config here.
>>
>> v3: Rebase on top of the hsw_ddi_clock_get() rename (Damien)
>>
>> Signed-off-by: Satheeshakrishna M<satheeshakrishna.m@intel.com>  (v1)
>> Signed-off-by: Damien Lespiau<damien.lespiau@intel.com>  (v3)
>> Signed-off-by: Daniel Vetter<daniel.vetter@ffwll.ch>  (v2)
>> ---
>>   drivers/gpu/drm/i915/i915_reg.h  |   5 ++
>>   drivers/gpu/drm/i915/intel_ddi.c | 114 ++++++++++++++++++++++++++++++++++++++-
>>   2 files changed, 118 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>> index 2364ece..794d0ba 100644
>> --- a/drivers/gpu/drm/i915/i915_reg.h
>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>> @@ -6367,6 +6367,7 @@ enum punit_power_well {
>>   #define  DPLL_CRTL1_LINK_RATE_1620             3
>>   #define  DPLL_CRTL1_LINK_RATE_1080             4
>>   #define  DPLL_CRTL1_LINK_RATE_2160             5
>> +#define  DPLL_CRTL1_LINK_RATE_SHIFT(id)                ((id)*6+1)
> I'd move this to a few lines above, where the MASK and RATE
> definitions are. Possibly reimplement the other macros using the new
> one (if the lines don't look to big/ugly).
I will move it next to MASK and RATE definitions. I didn't really get 
what you meant my reimplement here :(
>>   /* DPLL control2 */
>>   #define DPLL_CTRL2                             0x6C05C
>> @@ -6374,6 +6375,7 @@ enum punit_power_well {
>>   #define  DPLL_CTRL2_DDI_CLK_SEL_MASK(port)     (3<<((port)*3+1))
>>   #define  DPLL_CTRL2_DDI_CLK_SEL(clk, port)     (clk<<((port)*3+1))
>>   #define  DPLL_CTRL2_DDI_SEL_OVERRIDE(port)     (1<<(port*3))
>> +#define  DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port)    (port*3+1)
> Same here: move a few lines above, and possibly reimplement the others
> using the new one. Also, use "(port)" instead of "port", since we
> don't want to risk really-hard-to-debug bugs due to operator
> precedence on those "*" and "+" operations.
Will move up CLK_SEL and add parenthesis. Again didn't get the what to 
reimplement here.
>>   /* DPLL Status */
>>   #define DPLL_STATUS    0x6C060
>> @@ -6400,6 +6402,9 @@ enum punit_power_well {
>>   #define  DPLL_CFGCR2_PDIV(x)           (x<<2)
>>   #define  DPLL_CFGCR2_CENTRAL_FREQ_MASK (3)
>>
>> +#define GET_CFG_CR1_REG(id) (DPLL1_CFGCR1 + (id - 1) * 8)
>> +#define GET_CFG_CR2_REG(id) (DPLL1_CFGCR2 + (id - 1) * 8)
> The macros above are not really trivial due to the fact that the "id"
> is undefined and confusing. Please convert this to an inline function,
> since what we're actually expecting here is "enum intel_dpll_id",
> which has ID 0 for DPLL 1, which can be super confusing (imagine
> someone passing ID 1 for DPLL 1, not realizing it should be using the
> correct enum...). If we use a function we can specify the correct
> expected enum for the ID type, which helps the programmer find out
> what is the expected thing to pass to the function.
Expectation is that user of this macro should know value passed :) 
Anyway, let me try to have a inline function here.
>
>> +
>>   enum central_freq {
>>          freq_9600 = 0,
>>          freq_9000 = 1,
>> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
>> index e7a5428..b5cfb07 100644
>> --- a/drivers/gpu/drm/i915/intel_ddi.c
>> +++ b/drivers/gpu/drm/i915/intel_ddi.c
>> @@ -649,6 +649,114 @@ static int intel_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
>>          return (refclk * n * 100) / (p * r);
>>   }
>>
>> +static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
>> +                              enum intel_dpll_id dpll)
>> +{
>> +       uint32_t cfgcr1_reg, cfgcr2_reg;
>> +       uint32_t cfgcr1, cfgcr2;
>> +       uint32_t p0, p1, p2, dco_freq;
>> +
>> +       cfgcr1_reg = GET_CFG_CR1_REG(dpll);
>> +       cfgcr2_reg = GET_CFG_CR2_REG(dpll);
>> +
>> +       cfgcr1 = I915_READ(cfgcr1_reg);
>> +       cfgcr2 = I915_READ(cfgcr2_reg);
> Bikeshed: I'd probably call these cfgcr{1,2}_val to avoid confusion.
ok
>> +
>> +       p0 = (cfgcr2 & DPLL_CFGCR2_PDIV_MASK) >> 2;
>> +       p2 = (cfgcr2 & DPLL_CFGCR2_KDIV_MASK) >> 5;
>> +
>> +       if (cfgcr2 &  DPLL_CFGCR2_QDIV_MODE(1))
>> +               p1 = (cfgcr2 & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
>> +       else
>> +               p1 = 1;
>> +
>> +
>> +       switch (p0) {
>> +       case pdiv_1:
>> +               p0 = 1;
>> +               break;
>> +       case pdiv_2:
>> +               p0 = 2;
>> +               break;
>> +       case pdiv_3:
>> +               p0 = 3;
>> +               break;
>> +       case pdiv_7:
>> +               p0 = 7;
>> +               break;
>> +       }
>> +
>> +       switch (p2) {
>> +       case kdiv_5:
>> +               p2 = 5;
>> +               break;
>> +       case kdiv_2:
>> +               p2 = 2;
>> +               break;
>> +       case kdiv_3:
>> +               p2 = 3;
>> +               break;
>> +       case kdiv_1:
>> +               p2 = 1;
>> +               break;
>> +       }
> I really think that if we had something like:
> #define DPLL_CFGCR2_PDIV_7 (4 << 2)
> we'd be able to avoid this "convert to enum and then get the value"
> part, making the function much simpler...
ok
>
>> +
>> +       dco_freq = (cfgcr1 & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
>> +
>> +       dco_freq += (((cfgcr1 & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
>> +               1000) / 0x8000;
>> +
>> +       return dco_freq / (p0 * p1 * p2 * 5);
>> +}
>> +
>> +
>> +static void skl_ddi_clock_get(struct intel_encoder *encoder,
>> +                               struct intel_crtc_config *pipe_config)
>> +{
>> +       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
>> +       enum port port = intel_ddi_get_encoder_port(encoder);
>> +       int link_clock = 0;
>> +       uint32_t dpll_ctl1, dpll;
>> +
>> +       /* FIXME: This should be tracked in the pipe config. */
>> +       dpll = I915_READ(DPLL_CTRL2);
>> +       dpll &= DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
>> +       dpll >>= DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port);
>> +
>> +       dpll_ctl1 = I915_READ(DPLL_CTRL1);
>> +
>> +       if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
>> +               link_clock = skl_calc_wrpll_link(dev_priv, dpll);
>> +       } else {
>> +               link_clock = dpll_ctl1 & DPLL_CRTL1_LINK_RATE_MASK(dpll);
>> +               link_clock >>= DPLL_CRTL1_LINK_RATE_SHIFT(dpll);
>> +
>> +               switch (link_clock) {
>> +               case DPLL_CRTL1_LINK_RATE_810:
>> +                       link_clock = 81000;
>> +                       break;
>> +               case DPLL_CRTL1_LINK_RATE_1350:
>> +                       link_clock = 135000;
>> +                       break;
>> +               case DPLL_CRTL1_LINK_RATE_2700:
>> +                       link_clock = 270000;
>> +                       break;
> What about 1620 and 1080?
>
>
>> +               default:
>> +                       break;
> We're just silently failing here, which will probably result in later
> WARNs on the HW state readout/check code. So we should probably give a
> WARN() here to make debugging easier :)
Since link_clock is read out from the HW, we'll never end up in default 
case. Anyway, I'll add a WARN()
>
>> +               }
>> +               link_clock *= 2;
>> +       }
>> +
>> +       pipe_config->port_clock = link_clock;
>> +
>> +       if (pipe_config->has_dp_encoder)
>> +               pipe_config->adjusted_mode.crtc_clock =
>> +                       intel_dotclock_calculate(pipe_config->port_clock,
>> +                                                &pipe_config->dp_m_n);
>> +       else
>> +               pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock;
>> +}
>> +
>>   static void hsw_ddi_clock_get(struct intel_encoder *encoder,
>>                                struct intel_crtc_config *pipe_config)
>>   {
>> @@ -1535,6 +1643,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>>          struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
>>          enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
>>          u32 temp, flags = 0;
>> +       struct drm_device *dev = dev_priv->dev;
>>
>>          temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
>>          if (temp & TRANS_DDI_PHSYNC)
>> @@ -1606,7 +1715,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>>                  dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
>>          }
>>
>> -       hsw_ddi_clock_get(encoder, pipe_config);
>> +       if (INTEL_INFO(dev)->gen < 9)
> I'm sure Daniel would request a change to "<= 8" instead of "< 9" here :)
Couldn't figure of what the convention is. Will fix this instance :)
> I should probably also complain about the fact that clock calculation
> is a very confusing thing, and I never know which value should be
> assigned where, and I also never know when to multiply by 2 or 5 or
> divide by 10...
>
> Note: not everything mentioned above is a hard requirement for a R-B
> tag. Deciding what's a bikeshed and what's not is left as an exercise
> to the reader.
>
>> +               hsw_ddi_clock_get(encoder, pipe_config);
>> +       else
>> +               skl_ddi_clock_get(encoder, pipe_config);
>>   }
>>
>>   static void intel_ddi_destroy(struct drm_encoder *encoder)
>> --
>> 1.8.3.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 62/89] drm/i915/skl: Query DPLL attached to port on SKL
  2014-09-22 20:24   ` Paulo Zanoni
@ 2014-10-01 10:51     ` M, Satheeshakrishna
  2014-11-04 16:19     ` [PATCH 62/89 v3] " Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: M, Satheeshakrishna @ 2014-10-01 10:51 UTC (permalink / raw)
  To: Paulo Zanoni, Damien Lespiau; +Cc: Intel Graphics Development

On 9/23/2014 1:54 AM, Paulo Zanoni wrote:
> 2014-09-04 8:27 GMT-03:00 Damien Lespiau<damien.lespiau@intel.com>:
>> From: Satheeshakrishna M<satheeshakrishna.m@intel.com>
>>
>> Modify the implementation to query DPLL attached to a SKL port.
>>
>> v2: Rebase on top of the run-time PM on DPMS series (Damien)
>>
>> Signed-off-by: Satheeshakrishna M<satheeshakrishna.m@intel.com>
>> Signed-off-by: Damien Lespiau<damien.lespiau@intel.com>
>> ---
>>   drivers/gpu/drm/i915/intel_display.c | 27 ++++++++++++++++++++++++++-
>>   drivers/gpu/drm/i915/intel_drv.h     |  5 ++++-
>>   2 files changed, 30 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index 69e023a..6e71250 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -7789,6 +7789,28 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
>>          return 0;
>>   }
>>
>> +static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv,
>> +                               enum port port,
>> +                               struct intel_crtc_config *pipe_config)
>> +{
>> +       u32 temp;
>> +
>> +       temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
>> +       pipe_config->ddi_pll_sel = temp >> (port * 3 + 1);
> Since we're relying on the fact that ddi_pll_sel is actually "enum
> skl_dpll", I'd change the definition of the enum and explicitly
> declare SKL_DPLL0 to be "0", and SKL_DPLL1 to be 1, and so on.
Makes sense
>> +
>> +       switch (pipe_config->ddi_pll_sel) {
>> +       case SKL_DPLL1:
>> +               pipe_config->shared_dpll = DPLL_ID_SKL_DPLL1;
>> +               break;
>> +       case SKL_DPLL2:
>> +               pipe_config->shared_dpll = DPLL_ID_SKL_DPLL2;
>> +               break;
>> +       case SKL_DPLL3:
>> +               pipe_config->shared_dpll = DPLL_ID_SKL_DPLL3;
>> +               break;
> Please also add a WARN() to the default case, especially since there
> are 4 possible values and we're just checking 3.
ok
>> +       }
>> +}
>> +
>>   static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
>>                                  enum port port,
>>                                  struct intel_crtc_config *pipe_config)
>> @@ -7818,7 +7840,10 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
>>
>>          port = (tmp & TRANS_DDI_PORT_MASK) >> TRANS_DDI_PORT_SHIFT;
>>
>> -       haswell_get_ddi_pll(dev_priv, port, pipe_config);
>> +       if (IS_SKYLAKE(dev))
> If you invert the check so that SKL is on the "else" part (as you did
> in your previous patch), you'll make sure we're ready for the next
> Gens in case they happen to be same as SKL. It's more likely they will
> be the same as SKL instead of being the same as HSW :)
>
>
> With at least the WARN added on the switch statement: Reviewed-by:
> Paulo Zanoni<paulo.r.zanoni@intel.com>
>
>> +               skylake_get_ddi_pll(dev_priv, port, pipe_config);
>> +       else
>> +               haswell_get_ddi_pll(dev_priv, port, pipe_config);
>>
>>          if (pipe_config->shared_dpll >= 0) {
>>                  pll = &dev_priv->shared_dplls[pipe_config->shared_dpll];
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
>> index 559b747..9558f07 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -323,7 +323,10 @@ struct intel_crtc_config {
>>          /* Selected dpll when shared or DPLL_ID_PRIVATE. */
>>          enum intel_dpll_id shared_dpll;
>>
>> -       /* PORT_CLK_SEL for DDI ports. */
>> +       /*
>> +        * - PORT_CLK_SEL for DDI ports on HSW/BDW.
>> +        * - enum skl_dpll on SKL
>> +        */
>>          uint32_t ddi_pll_sel;
>>
>>          /* Actual register state of the dpll, for shared dpll cross-checking. */
>> --
>> 1.8.3.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 63/89] drm/i915/skl: Define shared DPLLs for Skylake
  2014-09-23 14:28   ` Paulo Zanoni
@ 2014-10-01 10:52     ` M, Satheeshakrishna
  0 siblings, 0 replies; 286+ messages in thread
From: M, Satheeshakrishna @ 2014-10-01 10:52 UTC (permalink / raw)
  To: Paulo Zanoni, Damien Lespiau; +Cc: Intel Graphics Development

On 9/23/2014 7:58 PM, Paulo Zanoni wrote:
> 2014-09-04 8:27 GMT-03:00 Damien Lespiau<damien.lespiau@intel.com>:
>> From: Satheeshakrishna M<satheeshakrishna.m@intel.com>
>>
>> On skylake, DPLL 1, 2 and 3 can be used for DP and HDMI. The shared dpll
>> framework allows us to share those DPLLs among DDIs when possible.
>>
>> The most tricky part is to provide a DPLL state that can be easily
>> compared. DPLL_CRTL1 is shared by all the DPLLs, 6 bits each. The
>> per-dpll crtl1 field of the hw state is then normalized to be the same
>> value if 2 DPLLs do indeed have identical values for those 6 bits.
>>
>> v2: Port the code to the shared DPLL infrastructure (Damien)
>>
>> XXX: This patch would benefit from a bunchf of macros for handling ctrl1
>> to encapsulate the masking and shifting (Daniel)
> Are you planning to do the XXX above before merging?
>
> The only suspect thing is that the spec doesn't mention
> if/when/how-much we need to sleep after enabling the clocks... I hope
> this won't be a problem later :)
We added a very conservative number, so shouldn't be a problem.
> Reviewed-by: Paulo Zanoni<paulo.r.zanoni@intel.com>
>
>> Signed-off-by: Satheeshakrishna M<satheeshakrishna.m@intel.com>  (v1)
>> Signed-off-by: Damien Lespiau<damien.lespiau@intel.com>
>> ---
>>   drivers/gpu/drm/i915/i915_drv.h  |  11 ++++
>>   drivers/gpu/drm/i915/intel_ddi.c | 126 ++++++++++++++++++++++++++++++++++++++-
>>   2 files changed, 136 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 65e5ffb..a6e14db 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -225,6 +225,17 @@ struct intel_dpll_hw_state {
>>
>>          /* hsw, bdw */
>>          uint32_t wrpll;
>> +
>> +       /* skl */
>> +       /*
>> +        * DPLL_CTRL1 has 6 bits for each each this DPLL. We store those in
>> +        * lower part of crtl1 and they get shifted into position when writing
>> +        * the register.  This allows us to easily compare the state to share
>> +        * the DPLL.
>> +        */
>> +       uint32_t ctrl1;
>> +       /* HDMI only, 0 when used for DP */
>> +       uint32_t cfgcr1, cfgcr2;
>>   };
>>
>>   struct intel_shared_dpll {
>> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
>> index b5cfb07..53ac23d 100644
>> --- a/drivers/gpu/drm/i915/intel_ddi.c
>> +++ b/drivers/gpu/drm/i915/intel_ddi.c
>> @@ -1522,12 +1522,136 @@ static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
>>          }
>>   }
>>
>> +static const char * const skl_ddi_pll_names[] = {
>> +       "DPLL 1",
>> +       "DPLL 2",
>> +       "DPLL 3",
>> +};
>> +
>> +struct skl_dpll_regs {
>> +       u32 ctl, cfgcr1, cfgcr2;
>> +};
>> +
>> +/* this array is indexed by the *shared* pll id */
>> +static const struct skl_dpll_regs skl_dpll_regs[3] = {
>> +       {
>> +               /* DPLL 1 */
>> +               .ctl = LCPLL2_CTL,
>> +               .cfgcr1 = DPLL1_CFGCR1,
>> +               .cfgcr2 = DPLL1_CFGCR2,
>> +       },
>> +       {
>> +               /* DPLL 2 */
>> +               .ctl = WRPLL_CTL1,
>> +               .cfgcr1 = DPLL2_CFGCR1,
>> +               .cfgcr2 = DPLL2_CFGCR2,
>> +       },
>> +       {
>> +               /* DPLL 3 */
>> +               .ctl = WRPLL_CTL2,
>> +               .cfgcr1 = DPLL3_CFGCR1,
>> +               .cfgcr2 = DPLL3_CFGCR2,
>> +       },
>> +};
>> +
>> +static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
>> +                              struct intel_shared_dpll *pll)
>> +{
>> +       uint32_t val;
>> +       unsigned int dpll;
>> +       const struct skl_dpll_regs *regs = skl_dpll_regs;
>> +
>> +       /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
>> +       dpll = pll->id + 1;
>> +
>> +       val = I915_READ(DPLL_CTRL1);
>> +
>> +       val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
>> +                DPLL_CRTL1_LINK_RATE_MASK(dpll));
>> +       val |= pll->hw_state.ctrl1 << (dpll * 6);
>> +
>> +       I915_WRITE(DPLL_CTRL1, val);
>> +       POSTING_READ(DPLL_CTRL1);
>> +
>> +       I915_WRITE(regs[pll->id].cfgcr1, pll->hw_state.cfgcr1);
>> +       I915_WRITE(regs[pll->id].cfgcr2, pll->hw_state.cfgcr2);
>> +       POSTING_READ(regs[pll->id].cfgcr1);
>> +       POSTING_READ(regs[pll->id].cfgcr2);
>> +
>> +       /* the enable bit is always bit 31 */
>> +       I915_WRITE(regs[pll->id].ctl,
>> +                  I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
>> +
>> +       if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
>> +               DRM_ERROR("DPLL %d not locked\n", dpll);
>> +}
>> +
>> +static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
>> +                               struct intel_shared_dpll *pll)
>> +{
>> +       const struct skl_dpll_regs *regs = skl_dpll_regs;
>> +
>> +       /* the enable bit is always bit 31 */
>> +       I915_WRITE(regs[pll->id].ctl,
>> +                  I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
>> +       POSTING_READ(regs[pll->id].ctl);
>> +}
>> +
>> +static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
>> +                                    struct intel_shared_dpll *pll,
>> +                                    struct intel_dpll_hw_state *hw_state)
>> +{
>> +       uint32_t val;
>> +       unsigned int dpll;
>> +       const struct skl_dpll_regs *regs = skl_dpll_regs;
>> +
>> +       if (!intel_display_power_enabled(dev_priv, POWER_DOMAIN_PLLS))
>> +               return false;
>> +
>> +       /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
>> +       dpll = pll->id + 1;
>> +
>> +       val = I915_READ(regs[pll->id].ctl);
>> +       if (!(val & LCPLL_PLL_ENABLE))
>> +               return false;
>> +
>> +       val = I915_READ(DPLL_CTRL1);
>> +       hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
>> +
>> +       /* avoid reading back stale values if HDMI mode is not enabled */
>> +       if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
>> +               hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
>> +               hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
>> +       }
>> +
>> +       return true;
>> +}
>> +
>> +static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
>> +{
>> +       int i;
>> +
>> +       dev_priv->num_shared_dpll = 3;
>> +
>> +       for (i = 0; i < dev_priv->num_shared_dpll; i++) {
>> +               dev_priv->shared_dplls[i].id = i;
>> +               dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
>> +               dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
>> +               dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
>> +               dev_priv->shared_dplls[i].get_hw_state =
>> +                       skl_ddi_pll_get_hw_state;
>> +       }
>> +}
>> +
>>   void intel_ddi_pll_init(struct drm_device *dev)
>>   {
>>          struct drm_i915_private *dev_priv = dev->dev_private;
>>          uint32_t val = I915_READ(LCPLL_CTL);
>>
>> -       hsw_shared_dplls_init(dev_priv);
>> +       if (IS_SKYLAKE(dev))
>> +               skl_shared_dplls_init(dev_priv);
>> +       else
>> +               hsw_shared_dplls_init(dev_priv);
>>
>>          DRM_DEBUG_KMS("CDCLK running at %dKHz\n",
>>                        intel_ddi_get_cdclk_freq(dev_priv));
>> --
>> 1.8.3.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 65/89] drm/i915/skl: Always use DPLL0 for eDP
  2014-09-23 15:07   ` Paulo Zanoni
@ 2014-10-01 10:52     ` M, Satheeshakrishna
  0 siblings, 0 replies; 286+ messages in thread
From: M, Satheeshakrishna @ 2014-10-01 10:52 UTC (permalink / raw)
  To: Paulo Zanoni, Damien Lespiau; +Cc: Intel Graphics Development

On 9/23/2014 8:37 PM, Paulo Zanoni wrote:
> 2014-09-04 8:27 GMT-03:00 Damien Lespiau<damien.lespiau@intel.com>:
>> From: Satheeshakrishna M<satheeshakrishna.m@intel.com>
>>
>> DPLL0 is not part of the shared PLL infrastructure. We'll use on for
>> eDP and rely on what the BIOS does for now.
>>
>> Signed-off-by: Satheeshakrishna M<satheeshakrishna.m@intel.com>
>> Signed-off-by: Damien Lespiau<damien.lespiau@intel.com>
>> ---
>>   drivers/gpu/drm/i915/intel_dp.c | 5 ++++-
>>   1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
>> index 5755f59..93bd9bf 100644
>> --- a/drivers/gpu/drm/i915/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>> @@ -1005,7 +1005,10 @@ found:
>>                                  &pipe_config->dp_m2_n2);
>>          }
>>
>> -       if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>> +       if (IS_SKYLAKE(dev)) {
>> +               if (is_edp(intel_dp))
>> +                       pipe_config->ddi_pll_sel = SKL_DPLL0;
> So we just don't assign anything else for the other ports? Why exactly?
Other ports follow the shared dpll logic and assignment happens in intel_ddi
>
>> +       } else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>>                  hsw_dp_set_ddi_pll_sel(pipe_config, intel_dp->link_bw);
>>          else
>>                  intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
>> --
>> 1.8.3.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 66/89] drm/i915/skl: Implementation of SKL DPLL programming
  2014-09-23 18:05   ` Paulo Zanoni
@ 2014-10-01 10:52     ` M, Satheeshakrishna
  2014-11-04 16:26     ` [PATCH 66/89 v9] " Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: M, Satheeshakrishna @ 2014-10-01 10:52 UTC (permalink / raw)
  To: Paulo Zanoni, Damien Lespiau; +Cc: Intel Graphics Development


[-- Attachment #1.1: Type: text/plain, Size: 12740 bytes --]

On 9/23/2014 11:35 PM, Paulo Zanoni wrote:
> 2014-09-04 8:27 GMT-03:00 Damien Lespiau<damien.lespiau@intel.com>:
>> From: Satheeshakrishna M<satheeshakrishna.m@intel.com>
>>
>> This patch implements SKL DPLL programming that includes:
>>          - DPLL allocation
>>          - wide range PLL calculation and programming
>>          - DP link rate programming
>>          - DDI to DPLL mapping
>>
>> v2: Incorporated following changes
>>          - Added vfunc for function required outside
>>          - Fixed multiple comments in WRPLL calculation
>>
>> v3: - Fix the DCO computation
>>      - Move the initialization up to not clobber the computed values
>>      - Use the correct macro for DP link rate programming.
>>      - Use wait_for() to wait for the PLL locked bit
>>
>> v4: Rebase on top of nigthly (Damien)
>>
>> v5: A few code cleanups in the WRPLL computation (Damien)
>>      - Use uint32_t when possible
>>      - Use abs_diff() in the WRPLL computation
>>      - Make the 64bits divisions use div64_u64()
>>      - Fix typo in dco_central_feq_deviation (freq)
>>      - Replace the chain of breaks with a goto
>>
>> v6: Port of the patch to work on top of the shared DPLLs (Damien)
>> v7: Don't try to handle eDP in ddi_pll_select() (Damien)
>>
>> Signed-off-by: Satheeshakrishna M<satheeshakrishna.m@intel.com>  (v3)
>> Signed-off-by: Damien Lespiau<damien.lespiau@intel.com>
>> ---
>>   drivers/gpu/drm/i915/intel_ddi.c | 225 ++++++++++++++++++++++++++++++++++++++-
>>   1 file changed, 224 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
>> index 439cd50..f68e04c 100644
>> --- a/drivers/gpu/drm/i915/intel_ddi.c
>> +++ b/drivers/gpu/drm/i915/intel_ddi.c
>> @@ -915,6 +915,225 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
>>          return true;
>>   }
>>
>> +struct skl_wrpll_params {
>> +       uint32_t        dco_fraction;
>> +       uint32_t        dco_integer;
>> +       uint32_t        qdiv_ratio;
>> +       uint32_t        qdiv_mode;
>> +       uint32_t        kdiv;
>> +       uint32_t        pdiv;
>> +       uint32_t        central_freq;
>> +};
>> +
>> +static void
>> +skl_ddi_calculate_wrpll(int clock /* in Hz */,
>> +                       struct skl_wrpll_params *wrpll_params)
>> +{
>> +       uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
>> +       uint64_t dco_central_freq[3] = {8400000000, 9000000000, 9600000000};
>> +       uint32_t min_dco_deviation = 400;
>> +       uint32_t min_dco_index = 3;
>> +       uint32_t P0[4] = {1, 2, 3, 7};
>> +       uint32_t P2[4] = {1, 2, 3, 5};
>> +       bool found = false;
>> +       uint32_t candidate_p = 0;
>> +       uint32_t candidate_p0[3] = {0}, candidate_p1[3] = {0};
>> +       uint32_t candidate_p2[3] = {0};
>> +       uint32_t dco_central_freq_deviation[3];
>> +       uint32_t i, P1, k, dco_count;
>> +       bool retry_with_odd = false;
>> +       uint64_t dco_freq;
>> +
>> +       /* Determine P0, P1 or P2 */
>> +       for (dco_count = 0; dco_count < 3; dco_count++) {
>> +               found = false;
>> +               candidate_p =
>> +                       div64_u64(dco_central_freq[dco_count], afe_clock);
>> +               if (retry_with_odd == false)
>> +                       candidate_p = (candidate_p % 2 == 0 ?
>> +                               candidate_p : candidate_p + 1);
>> +
>> +               for (P1 = 1; P1 < candidate_p; P1++) {
>> +                       for (i = 0; i < 4; i++) {
>> +                               if (!(P0[i] != 1 || P1 == 1))
> I'd invert the logic of  the statement above to match the spec.
That's how it was. I had to change it to avoid multiple indentation and 
hence to meet max line length
>
>> +                                       continue;
>> +
>> +                               for (k = 0; k < 4; k++) {
>> +                                       if (!((P2[k] != 2 && P1 == 1) ||
>> +                                               (P2[k] == 2)))
> This doesn't seem to match the docs. Why is the "P2[k] == 2" there?
ok, this can be simplified.
>  From the bikeshedding department, there's also a minor coding style
> problem (missing "*" char in second line of comment) below, and the
> usual "is_skl" check leaving gen10+ on the same case as hsw/bdw.
>
> Everything else looks like to be according to the specs.
>
> With or without changes: Reviewed-by: Paulo Zanoni<paulo.r.zanoni@intel.com>
>
>> +                                               continue;
>> +
>> +                                       if (candidate_p == P0[i] * P1 * P2[k]) {
>> +                                               /* Found possible P0, P1, P2 */
>> +                                               found = true;
>> +                                               candidate_p0[dco_count] = P0[i];
>> +                                               candidate_p1[dco_count] = P1;
>> +                                               candidate_p2[dco_count] = P2[k];
>> +                                               goto found;
>> +                                       }
>> +
>> +                               }
>> +                       }
>> +               }
>> +
>> +found:
>> +               if (found) {
>> +                       dco_central_freq_deviation[dco_count] =
>> +                               div64_u64(10000 *
>> +                                         abs_diff((candidate_p * afe_clock),
>> +                                                  dco_central_freq[dco_count]),
>> +                                         dco_central_freq[dco_count]);
>> +
>> +                       if (dco_central_freq_deviation[dco_count] <
>> +                               min_dco_deviation) {
>> +                               min_dco_deviation =
>> +                                       dco_central_freq_deviation[dco_count];
>> +                               min_dco_index = dco_count;
>> +                       }
>> +               }
>> +
>> +               if (min_dco_index > 2 && dco_count == 2) {
>> +                       retry_with_odd = true;
>> +                       dco_count = 0;
>> +               }
>> +       }
>> +
>> +       if (min_dco_index > 2) {
>> +               WARN(1, "No valid values found for the given pixel clock\n");
>> +       } else {
>> +                wrpll_params->central_freq = dco_central_freq[min_dco_index];
>> +
>> +                switch (dco_central_freq[min_dco_index]) {
>> +                case 9600000000:
>> +                       wrpll_params->central_freq = 0;
>> +                       break;
>> +                case 9000000000:
>> +                       wrpll_params->central_freq = 1;
>> +                       break;
>> +                case 8400000000:
>> +                       wrpll_params->central_freq = 3;
>> +                }
>> +
>> +                switch (candidate_p0[min_dco_index]) {
>> +                case 1:
>> +                       wrpll_params->pdiv = 0;
>> +                       break;
>> +                case 2:
>> +                       wrpll_params->pdiv = 1;
>> +                       break;
>> +                case 3:
>> +                       wrpll_params->pdiv = 2;
>> +                       break;
>> +                case 7:
>> +                       wrpll_params->pdiv = 4;
>> +                       break;
>> +                default:
>> +                       WARN(1, "Incorrect PDiv\n");
>> +                }
>> +
>> +                switch (candidate_p2[min_dco_index]) {
>> +                case 5:
>> +                       wrpll_params->kdiv = 0;
>> +                       break;
>> +                case 2:
>> +                       wrpll_params->kdiv = 1;
>> +                       break;
>> +                case 3:
>> +                       wrpll_params->kdiv = 2;
>> +                       break;
>> +                case 1:
>> +                       wrpll_params->kdiv = 3;
>> +                       break;
>> +                default:
>> +                       WARN(1, "Incorrect KDiv\n");
>> +                }
>> +
>> +                wrpll_params->qdiv_ratio = candidate_p1[min_dco_index];
>> +                wrpll_params->qdiv_mode =
>> +                       (wrpll_params->qdiv_ratio == 1) ? 0 : 1;
>> +
>> +                dco_freq = candidate_p0[min_dco_index] *
>> +                        candidate_p1[min_dco_index] *
>> +                        candidate_p2[min_dco_index] * afe_clock;
>> +
>> +                /* Intermediate values are in Hz.
>> +                   Divide by MHz to match bsepc */
>> +                wrpll_params->dco_integer = div_u64(dco_freq, (24 * MHz(1)));
>> +                wrpll_params->dco_fraction =
>> +                        div_u64(((div_u64(dco_freq, 24) -
>> +                                  wrpll_params->dco_integer * MHz(1)) * 0x8000), MHz(1));
>> +
>> +       }
>> +}
>> +
>> +
>> +static bool
>> +skl_ddi_pll_select(struct intel_crtc *intel_crtc,
>> +                  struct intel_encoder *intel_encoder,
>> +                  int clock)
>> +{
>> +       struct intel_shared_dpll *pll;
>> +       uint32_t ctrl1, cfgcr1, cfgcr2;
>> +
>> +       /*
>> +        * See comment in intel_dpll_hw_state to understand why we always use 0
>> +        * as the DPLL id in this function.
>> +        */
>> +
>> +       ctrl1 = DPLL_CTRL1_OVERRIDE(0);
>> +
>> +       if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
>> +               struct skl_wrpll_params wrpll_params = { 0, };
>> +
>> +               ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
>> +
>> +               skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params);
>> +
>> +               cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
>> +                        DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
>> +                        wrpll_params.dco_integer;
>> +
>> +               cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
>> +                        DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
>> +                        DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
>> +                        DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
>> +                        wrpll_params.central_freq;
>> +       } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
>> +               struct drm_encoder *encoder = &intel_encoder->base;
>> +               struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>> +
>> +               switch (intel_dp->link_bw) {
>> +               case DP_LINK_BW_1_62:
>> +                       ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_810, 0);
>> +                       break;
>> +               case DP_LINK_BW_2_7:
>> +                       ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_1350, 0);
>> +                       break;
>> +               case DP_LINK_BW_5_4:
>> +                       ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_2700, 0);
>> +                       break;
>> +               }
>> +
>> +               cfgcr1 = cfgcr2 = 0;
>> +       } else /* eDP */
>> +               return true;
>> +
>> +       intel_crtc->config.dpll_hw_state.ctrl1 = ctrl1;
>> +       intel_crtc->config.dpll_hw_state.cfgcr1 = cfgcr1;
>> +       intel_crtc->config.dpll_hw_state.cfgcr2 = cfgcr2;
>> +
>> +       pll = intel_get_shared_dpll(intel_crtc);
>> +       if (pll == NULL) {
>> +               DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
>> +                                pipe_name(intel_crtc->pipe));
>> +               return false;
>> +       }
>> +
>> +       /* shared DPLL id 0 is DPLL 1 */
>> +       intel_crtc->config.ddi_pll_sel = pll->id + 1;
>> +
>> +       return true;
>> +}
>>
>>   /*
>>    * Tries to find a *shared* PLL for the CRTC and store it in
>> @@ -926,12 +1145,16 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
>>   bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
>>   {
>>          struct drm_crtc *crtc = &intel_crtc->base;
>> +       struct drm_device *dev = crtc->dev;
>>          struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
>>          int clock = intel_crtc->config.port_clock;
>>
>>          intel_put_shared_dpll(intel_crtc);
>>
>> -       return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock);
>> +       if (IS_SKYLAKE(dev))
>> +               return skl_ddi_pll_select(intel_crtc, intel_encoder, clock);
>> +       else
>> +               return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock);
>>   }
>>
>>   void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
>> --
>> 1.8.3.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>


[-- Attachment #1.2: Type: text/html, Size: 14171 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 61/89] drm/i915/skl: Determine enabled PLL and its linkrate/pixel clock
  2014-10-01 10:51     ` M, Satheeshakrishna
@ 2014-10-03 18:25       ` Paulo Zanoni
  0 siblings, 0 replies; 286+ messages in thread
From: Paulo Zanoni @ 2014-10-03 18:25 UTC (permalink / raw)
  To: M, Satheeshakrishna; +Cc: Intel Graphics Development

2014-10-01 7:51 GMT-03:00 M, Satheeshakrishna <satheeshakrishna.m@intel.com>:
> On 9/23/2014 1:42 AM, Paulo Zanoni wrote:
>>
>> 2014-09-04 8:27 GMT-03:00 Damien Lespiau<damien.lespiau@intel.com>:
>>>
>>> From: Satheeshakrishna M<satheeshakrishna.m@intel.com>
>>>
>>> v2: Fixup compilation due to the removal of the intel_ddi_dpll_id enum.
>>> And add a fixme about the abuse of pipe_config here.
>>>
>>> v3: Rebase on top of the hsw_ddi_clock_get() rename (Damien)
>>>
>>> Signed-off-by: Satheeshakrishna M<satheeshakrishna.m@intel.com>  (v1)
>>> Signed-off-by: Damien Lespiau<damien.lespiau@intel.com>  (v3)
>>> Signed-off-by: Daniel Vetter<daniel.vetter@ffwll.ch>  (v2)
>>> ---
>>>   drivers/gpu/drm/i915/i915_reg.h  |   5 ++
>>>   drivers/gpu/drm/i915/intel_ddi.c | 114
>>> ++++++++++++++++++++++++++++++++++++++-
>>>   2 files changed, 118 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/i915_reg.h
>>> b/drivers/gpu/drm/i915/i915_reg.h
>>> index 2364ece..794d0ba 100644
>>> --- a/drivers/gpu/drm/i915/i915_reg.h
>>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>>> @@ -6367,6 +6367,7 @@ enum punit_power_well {
>>>   #define  DPLL_CRTL1_LINK_RATE_1620             3
>>>   #define  DPLL_CRTL1_LINK_RATE_1080             4
>>>   #define  DPLL_CRTL1_LINK_RATE_2160             5
>>> +#define  DPLL_CRTL1_LINK_RATE_SHIFT(id)                ((id)*6+1)
>>
>> I'd move this to a few lines above, where the MASK and RATE
>> definitions are. Possibly reimplement the other macros using the new
>> one (if the lines don't look to big/ugly).
>
> I will move it next to MASK and RATE definitions. I didn't really get what
> you meant my reimplement here :(
>>>
>>>   /* DPLL control2 */
>>>   #define DPLL_CTRL2                             0x6C05C
>>> @@ -6374,6 +6375,7 @@ enum punit_power_well {
>>>   #define  DPLL_CTRL2_DDI_CLK_SEL_MASK(port)     (3<<((port)*3+1))
>>>   #define  DPLL_CTRL2_DDI_CLK_SEL(clk, port)     (clk<<((port)*3+1))
>>>   #define  DPLL_CTRL2_DDI_SEL_OVERRIDE(port)     (1<<(port*3))
>>> +#define  DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port)    (port*3+1)
>>
>> Same here: move a few lines above, and possibly reimplement the others
>> using the new one. Also, use "(port)" instead of "port", since we
>> don't want to risk really-hard-to-debug bugs due to operator
>> precedence on those "*" and "+" operations.
>
> Will move up CLK_SEL and add parenthesis. Again didn't get the what to
> reimplement here.

What I meant is: since you created a macro that expands to
"(port*3+1)", you could use it in the definition of the other macros,
instead of writing "(port*3+1)" again. The downside is that you'd have
to type many more characters, so maybe this change is not worth it.

So we'd have something like:
#define DPLL_CTRL2_XX_SHIFT(port) (port*3+1)
#define DPLL_CTRL2_XX_SEL_MASK(port) (3 << DPLL_CTRL2_XX_SHIFT(port))
#define DPLL_CTRL2_XX_SEL(clk, port) ((clk) << DPLL_CTRL2_XX_SHIFT(port))

Etc.

>>>
>>>   /* DPLL Status */
>>>   #define DPLL_STATUS    0x6C060
>>> @@ -6400,6 +6402,9 @@ enum punit_power_well {
>>>   #define  DPLL_CFGCR2_PDIV(x)           (x<<2)
>>>   #define  DPLL_CFGCR2_CENTRAL_FREQ_MASK (3)
>>>
>>> +#define GET_CFG_CR1_REG(id) (DPLL1_CFGCR1 + (id - 1) * 8)
>>> +#define GET_CFG_CR2_REG(id) (DPLL1_CFGCR2 + (id - 1) * 8)
>>
>> The macros above are not really trivial due to the fact that the "id"
>> is undefined and confusing. Please convert this to an inline function,
>> since what we're actually expecting here is "enum intel_dpll_id",
>> which has ID 0 for DPLL 1, which can be super confusing (imagine
>> someone passing ID 1 for DPLL 1, not realizing it should be using the
>> correct enum...). If we use a function we can specify the correct
>> expected enum for the ID type, which helps the programmer find out
>> what is the expected thing to pass to the function.
>
> Expectation is that user of this macro should know value passed :) Anyway,
> let me try to have a inline function here.

But currently, he'll have to read a lot of code to know which value to
pass: this is what I did while reviewing the patch. If this were a
real function, all that would be needed would be to look at the
function declaration.


>>
>>
>>> +
>>>   enum central_freq {
>>>          freq_9600 = 0,
>>>          freq_9000 = 1,
>>> diff --git a/drivers/gpu/drm/i915/intel_ddi.c
>>> b/drivers/gpu/drm/i915/intel_ddi.c
>>> index e7a5428..b5cfb07 100644
>>> --- a/drivers/gpu/drm/i915/intel_ddi.c
>>> +++ b/drivers/gpu/drm/i915/intel_ddi.c
>>> @@ -649,6 +649,114 @@ static int intel_ddi_calc_wrpll_link(struct
>>> drm_i915_private *dev_priv,
>>>          return (refclk * n * 100) / (p * r);
>>>   }
>>>
>>> +static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
>>> +                              enum intel_dpll_id dpll)
>>> +{
>>> +       uint32_t cfgcr1_reg, cfgcr2_reg;
>>> +       uint32_t cfgcr1, cfgcr2;
>>> +       uint32_t p0, p1, p2, dco_freq;
>>> +
>>> +       cfgcr1_reg = GET_CFG_CR1_REG(dpll);
>>> +       cfgcr2_reg = GET_CFG_CR2_REG(dpll);
>>> +
>>> +       cfgcr1 = I915_READ(cfgcr1_reg);
>>> +       cfgcr2 = I915_READ(cfgcr2_reg);
>>
>> Bikeshed: I'd probably call these cfgcr{1,2}_val to avoid confusion.
>
> ok
>
>>> +
>>> +       p0 = (cfgcr2 & DPLL_CFGCR2_PDIV_MASK) >> 2;
>>> +       p2 = (cfgcr2 & DPLL_CFGCR2_KDIV_MASK) >> 5;
>>> +
>>> +       if (cfgcr2 &  DPLL_CFGCR2_QDIV_MODE(1))
>>> +               p1 = (cfgcr2 & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
>>> +       else
>>> +               p1 = 1;
>>> +
>>> +
>>> +       switch (p0) {
>>> +       case pdiv_1:
>>> +               p0 = 1;
>>> +               break;
>>> +       case pdiv_2:
>>> +               p0 = 2;
>>> +               break;
>>> +       case pdiv_3:
>>> +               p0 = 3;
>>> +               break;
>>> +       case pdiv_7:
>>> +               p0 = 7;
>>> +               break;
>>> +       }
>>> +
>>> +       switch (p2) {
>>> +       case kdiv_5:
>>> +               p2 = 5;
>>> +               break;
>>> +       case kdiv_2:
>>> +               p2 = 2;
>>> +               break;
>>> +       case kdiv_3:
>>> +               p2 = 3;
>>> +               break;
>>> +       case kdiv_1:
>>> +               p2 = 1;
>>> +               break;
>>> +       }
>>
>> I really think that if we had something like:
>> #define DPLL_CFGCR2_PDIV_7 (4 << 2)
>> we'd be able to avoid this "convert to enum and then get the value"
>> part, making the function much simpler...
>
> ok
>
>>
>>> +
>>> +       dco_freq = (cfgcr1 & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
>>> +
>>> +       dco_freq += (((cfgcr1 & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24
>>> *
>>> +               1000) / 0x8000;
>>> +
>>> +       return dco_freq / (p0 * p1 * p2 * 5);
>>> +}
>>> +
>>> +
>>> +static void skl_ddi_clock_get(struct intel_encoder *encoder,
>>> +                               struct intel_crtc_config *pipe_config)
>>> +{
>>> +       struct drm_i915_private *dev_priv =
>>> encoder->base.dev->dev_private;
>>> +       enum port port = intel_ddi_get_encoder_port(encoder);
>>> +       int link_clock = 0;
>>> +       uint32_t dpll_ctl1, dpll;
>>> +
>>> +       /* FIXME: This should be tracked in the pipe config. */
>>> +       dpll = I915_READ(DPLL_CTRL2);
>>> +       dpll &= DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
>>> +       dpll >>= DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port);
>>> +
>>> +       dpll_ctl1 = I915_READ(DPLL_CTRL1);
>>> +
>>> +       if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
>>> +               link_clock = skl_calc_wrpll_link(dev_priv, dpll);
>>> +       } else {
>>> +               link_clock = dpll_ctl1 & DPLL_CRTL1_LINK_RATE_MASK(dpll);
>>> +               link_clock >>= DPLL_CRTL1_LINK_RATE_SHIFT(dpll);
>>> +
>>> +               switch (link_clock) {
>>> +               case DPLL_CRTL1_LINK_RATE_810:
>>> +                       link_clock = 81000;
>>> +                       break;
>>> +               case DPLL_CRTL1_LINK_RATE_1350:
>>> +                       link_clock = 135000;
>>> +                       break;
>>> +               case DPLL_CRTL1_LINK_RATE_2700:
>>> +                       link_clock = 270000;
>>> +                       break;
>>
>> What about 1620 and 1080?
>>
>>
>>> +               default:
>>> +                       break;
>>
>> We're just silently failing here, which will probably result in later
>> WARNs on the HW state readout/check code. So we should probably give a
>> WARN() here to make debugging easier :)
>
> Since link_clock is read out from the HW, we'll never end up in default
> case. Anyway, I'll add a WARN()

Yeah, but maybe in some gen the register address will change, then
we'll start reading garbage and silently do the wrong thing. Or maybe
we have some serious memory corruption, or IDK. I know this is a
little too paranoid, but we have tons of WARNs on our code and they do
help us catch bugs, especially on the automated IGT tests where QA is
not really looking at the screen to check if it is actually working,
but there's a bot looking at new dmesg WARNs.


>
>>
>>> +               }
>>> +               link_clock *= 2;
>>> +       }
>>> +
>>> +       pipe_config->port_clock = link_clock;
>>> +
>>> +       if (pipe_config->has_dp_encoder)
>>> +               pipe_config->adjusted_mode.crtc_clock =
>>> +                       intel_dotclock_calculate(pipe_config->port_clock,
>>> +                                                &pipe_config->dp_m_n);
>>> +       else
>>> +               pipe_config->adjusted_mode.crtc_clock =
>>> pipe_config->port_clock;
>>> +}
>>> +
>>>   static void hsw_ddi_clock_get(struct intel_encoder *encoder,
>>>                                struct intel_crtc_config *pipe_config)
>>>   {
>>> @@ -1535,6 +1643,7 @@ void intel_ddi_get_config(struct intel_encoder
>>> *encoder,
>>>          struct intel_crtc *intel_crtc =
>>> to_intel_crtc(encoder->base.crtc);
>>>          enum transcoder cpu_transcoder =
>>> intel_crtc->config.cpu_transcoder;
>>>          u32 temp, flags = 0;
>>> +       struct drm_device *dev = dev_priv->dev;
>>>
>>>          temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
>>>          if (temp & TRANS_DDI_PHSYNC)
>>> @@ -1606,7 +1715,10 @@ void intel_ddi_get_config(struct intel_encoder
>>> *encoder,
>>>                  dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
>>>          }
>>>
>>> -       hsw_ddi_clock_get(encoder, pipe_config);
>>> +       if (INTEL_INFO(dev)->gen < 9)
>>
>> I'm sure Daniel would request a change to "<= 8" instead of "< 9" here :)
>
> Couldn't figure of what the convention is. Will fix this instance :)
>
>> I should probably also complain about the fact that clock calculation
>> is a very confusing thing, and I never know which value should be
>> assigned where, and I also never know when to multiply by 2 or 5 or
>> divide by 10...
>>
>> Note: not everything mentioned above is a hard requirement for a R-B
>> tag. Deciding what's a bikeshed and what's not is left as an exercise
>> to the reader.
>>
>>> +               hsw_ddi_clock_get(encoder, pipe_config);
>>> +       else
>>> +               skl_ddi_clock_get(encoder, pipe_config);
>>>   }
>>>
>>>   static void intel_ddi_destroy(struct drm_encoder *encoder)
>>> --
>>> 1.8.3.1
>>>
>>> _______________________________________________
>>> Intel-gfx mailing list
>>> Intel-gfx@lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>
>>
>



-- 
Paulo Zanoni

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 00/89] Basic Skylake enabling (reviewers)
  2014-09-04 14:16 ` [PATCH 00/89] Basic Skylake enabling (reviewers) Damien Lespiau
  2014-09-16 14:51   ` Thomas Wood
@ 2014-10-17 14:29   ` Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-10-17 14:29 UTC (permalink / raw)
  To: intel-gfx; +Cc: ville.syrjala

Hi Ville,

I've compiled the list of patches for which I finally have versions that
should fix your comments and still require your r-b tag. You're in luck!
there are also a few additional follow-up patches, some to address your
concerns and one to address a known issue I listed here.

On Thu, Sep 04, 2014 at 03:16:03PM +0100, Damien Lespiau wrote:
> 
> Known issues:
> 
>   - There a known limitation in the DDB allocation code. It doesn't
>     respect the minimal allocation of 8 blocks. When we're trying to
>     scannout two planes (not counting the cursor) that have widely
>     different data rates (1080p and 64x64), we'll under-allocate the
>     small plane and hit underuns.

This is addressed by:

  drm/i915/skl: Make sure to allocate mininum sizes in the DDB
  http://lists.freedesktop.org/archives/intel-gfx/2014-October/053713.html

There's also a series addresses some of the concerns on top of the
initial patches as they were big enough to need a diff IMHO. This series
is:

  [PATCH 0/8] SKL WM fixups
  http://lists.freedesktop.org/archives/intel-gfx/2014-October/053571.html

And finally a rework of the DDB flush logic:

  [PATCH 0/3] Rework of the WM flush (for the DDB allocation)
  http://lists.freedesktop.org/archives/intel-gfx/2014-October/053605.html

> Patches 43 to 52: Ville (WM)

Remaining here:
  - 45: there's a v4
  - 46: the +1/-1 is addresses in the "SKL WM fixups" series
  - 47: v11 of the patch + some fixes in the "SKL WM fixups" series
  - 48: v6
  - 49: no need for anything more I believe
  - 50: needs review
  - 52: I think it can go as is, we may to track the work you're
	mentioning in Jira, I have it on my TODO list too now, but
	rather low prioriy

> Patches 76 to 83: Ville (WM part2)

Remaining here:
  - 76: needs review, trivial
  - 78: addressed in the "Rework of the WM flush (for the DDB
    allocation)" series
  - 81: trivial
  - 82: debugfs file to display the state of the DDB allocation
  - 83: DDB state readout and cross-check (it already helped me catch a
       problem when doing the 'end exclusive' patches)

Thanks!

-- 
Damien

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 45/89 v4] drm/i915/skl: Definition of SKL WM param structs for pipe/plane
  2014-09-23 15:10         ` [PATCH 45/89 v4] " Damien Lespiau
@ 2014-10-28 15:11           ` Ville Syrjälä
  0 siblings, 0 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-10-28 15:11 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx, Pradeep Bhat

On Tue, Sep 23, 2014 at 04:10:51PM +0100, Damien Lespiau wrote:
> From: Pradeep Bhat <pradeep.bhat@intel.com>
> 
> This patch defines the structures needed for computation of
> watermarks of pipes and planes for SKL.
> 
> v2: Incorporated Damien's review comments and removed unused fields
>     in structs for future features like rotation, drrs and scaling.
>     The skl_wm_values struct is now made more generic across planes
>     and cursor planes for all pipes.
> 
> v3: implemented the plane/cursor split.
> 
> v4: Change the wm union back to a structure (Ville, Daniel)
> 
> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

Yeah let's o with this for now. We need to do some house cleaning later
but what else is new.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/i915/i915_drv.h  | 18 ++++++++++++++++++
>  drivers/gpu/drm/i915/intel_drv.h |  8 ++++++++
>  drivers/gpu/drm/i915/intel_pm.c  |  8 ++++++++
>  3 files changed, 34 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 8eb116c1..481ebd8 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1395,6 +1395,24 @@ struct ilk_wm_values {
>  	enum intel_ddb_partitioning partitioning;
>  };
>  
> +struct skl_wm_values {
> +	bool dirty[I915_MAX_PIPES];
> +	uint32_t wm_linetime[I915_MAX_PIPES];
> +	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
> +	uint32_t cursor[I915_MAX_PIPES][8];
> +	uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
> +	uint32_t cursor_trans[I915_MAX_PIPES];
> +};
> +
> +struct skl_wm_level {
> +	bool plane_en[I915_MAX_PLANES];
> +	uint16_t plane_res_b[I915_MAX_PLANES];
> +	uint8_t plane_res_l[I915_MAX_PLANES];
> +	bool cursor_en;
> +	uint16_t cursor_res_b;
> +	uint8_t cursor_res_l;
> +};
> +
>  /*
>   * This struct helps tracking the state needed for runtime PM, which puts the
>   * device in PCI D3 state. Notice that when this happens, nothing on the
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 072e69f..4438a05 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -399,6 +399,12 @@ struct intel_mmio_flip {
>  	u32 ring_id;
>  };
>  
> +struct skl_pipe_wm {
> +	struct skl_wm_level wm[8];
> +	struct skl_wm_level trans_wm;
> +	uint32_t linetime;
> +};
> +
>  struct intel_crtc {
>  	struct drm_crtc base;
>  	enum pipe pipe;
> @@ -446,6 +452,8 @@ struct intel_crtc {
>  	struct {
>  		/* watermarks currently being used  */
>  		struct intel_pipe_wm active;
> +		/* SKL wm values currently in use */
> +		struct skl_pipe_wm skl_active;
>  	} wm;
>  
>  	int scanline_offset;
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index fadf376..299dd7e 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -1953,6 +1953,14 @@ static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels,
>  	return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2;
>  }
>  
> +struct skl_pipe_wm_parameters {
> +	bool active;
> +	uint32_t pipe_htotal;
> +	uint32_t pixel_rate; /* in KHz */
> +	struct intel_plane_wm_parameters plane[I915_MAX_PLANES];
> +	struct intel_plane_wm_parameters cursor;
> +};
> +
>  struct ilk_pipe_wm_parameters {
>  	bool active;
>  	uint32_t pipe_htotal;
> -- 
> 1.8.3.1

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 46/89] drm/i915/skl: Add DDB allocation management structures
  2014-09-04 11:27 ` [PATCH 46/89] drm/i915/skl: Add DDB allocation management structures Damien Lespiau
  2014-09-17 10:47   ` Ville Syrjälä
@ 2014-10-29 15:32   ` Ville Syrjälä
  1 sibling, 0 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-10-29 15:32 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:27:12PM +0100, Damien Lespiau wrote:
> We now need to allocate space in the DDB for planes being scanned out
> ourselves. The data structure to represent an allocation mirrors what
> we'll need to write in the registers later on: (start, end).
> 
> We add that allocation datat to the skl_wm_values structure as part of
> the values to program the hardware with.
> 
> v2: Split planes and cursor for consistency.
> 
> v3: Make the skl_ddb_entry_size() parameter const
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

Yeah I'm mostly happy with the fixup patch for the inclusive vs.
exclusive, so
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/i915/i915_drv.h | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 3764ad5..de278a5 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1381,8 +1381,27 @@ struct ilk_wm_values {
>  	enum intel_ddb_partitioning partitioning;
>  };
>  
> +struct skl_ddb_entry {
> +	uint16_t start, end;	/* in number of blocks */
> +};
> +
> +static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry)
> +{
> +	/* end not set, clearly no allocation here. start can be 0 though */
> +	if (entry->end == 0)
> +		return 0;
> +
> +	return entry->end - entry->start + 1;
> +}
> +
> +struct skl_ddb_allocation {
> +	struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
> +	struct skl_ddb_entry cursor[I915_MAX_PIPES];
> +};
> +
>  struct skl_wm_values {
>  	bool dirty[I915_MAX_PIPES];
> +	struct skl_ddb_allocation ddb;
>  	uint32_t wm_linetime[I915_MAX_PIPES];
>  	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
>  	uint32_t cursor[I915_MAX_PIPES][8];
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 47/89 v11] drm/i915/skl: SKL Watermark Computation
  2014-09-23 11:13     ` [PATCH 47/89 v11] " Damien Lespiau
@ 2014-10-29 17:07       ` Ville Syrjälä
  0 siblings, 0 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-10-29 17:07 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx, Pradeep Bhat

On Tue, Sep 23, 2014 at 12:13:50PM +0100, Damien Lespiau wrote:
> From: Pradeep Bhat <pradeep.bhat@intel.com>
> 
> This patch implements the watermark algorithm and its necessary
> functions. Two function pointers skl_update_wm and
> skl_update_sprite_wm are provided. The skl_update_wm will update
> the watermarks for the crtc provided as an argument and then
> checks for change in DDB allocation for other active pipes and
> recomputes the watermarks for those Pipes and planes as well.
> Finally it does the register programming for all dirty pipes.
> The trigger of the Watermark double buffer registers will have
> to be once the plane configurations are done by the caller.
> 
> v2: fixed the divide-by-0 error in the results computation func.
>     Also reworked the PLANE_WM register values computation func to
>     make it more compact. Incorporated all other review comments
>     from Damien.
> 
> v3: Changed the skl_compute_plane_wm function to now return success
>     or failure. Also the result blocks and lines are computed here
>     instead of in skl_compute_wm_results function.
> 
> v4: Adjust skl_ddb_alloc_changed() to the new planes/cursor split
>     (Damien)
> 
> v5: Reworked the affected functions to implement new plane/cursor
>     split.
> 
> v6: Rework the logic that triggers the DDB allocation and WM computation
>     of skl_update_other_pipe_wm() to not depend on non-computed DDB
>     values.
>     Always give a valid cursor_width (at boot it's 0) to keep the
>     invariant that we consider the cursor plane always enabled.
>     Otherwise we end up dividing by 0 in skl_compute_plane_wm()
>     (Damien Lespiau)
> 
> v7: Spell out allocation
>     skl_ddb_ functions should have the ddb as first argument
>     Make the skl_ddb_alloc_changed() parameters const
>     (Damien)
> 
> v8: Rebase on top of the crtc->primary changes
> 
> v9: Split the staging results structure to not exceed the 1Kb stack
>     allocation in skl_update_wm()
> 
> v10: Make skl_pipe_pixel_rate() take a pointer to the pipe config
>      Add a comment about overflow considerations for skl_wm_method1()
>      Various additions of const
>      Various use of sizeof(variable) instead of sizeof(type)
>      Various move of variable definitons to a narrower scope
>      Zero initialize some stack allocated structures to make sure we
>      don't have garbage in case we don't write all the values
>      (Ville)
> 
> v11: Remove non-necessary default number of blocks/lines when the plane
>      is disabled (Ville)
> 
> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

Looks OK. The fixup to move the validity check still seems to need a
bit of tweaking but otherwise I think it's sane enough.

I seem to recall that I went through all of the little details the
first time around, so I decided to not do that this time. Hopefully
my memory is correct ;)

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/i915/i915_drv.h |  12 +-
>  drivers/gpu/drm/i915/intel_pm.c | 422 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 433 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 0301a91..cde5136 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1722,8 +1722,18 @@ struct drm_i915_private {
>  		 */
>  		uint16_t skl_latency[8];
>  
> +		/*
> +		 * The skl_wm_values structure is a bit too big for stack
> +		 * allocation, so we keep the staging struct where we store
> +		 * intermediate results here instead.
> +		 */
> +		struct skl_wm_values skl_results;
> +
>  		/* current hardware state */
> -		struct ilk_wm_values hw;
> +		union {
> +			struct ilk_wm_values hw;
> +			struct skl_wm_values skl_hw;
> +		};
>  	} wm;
>  
>  	struct i915_runtime_pm pm;
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 768890e..e69a833 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2957,6 +2957,426 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
>  	return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
>  }
>  
> +static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_config *config)
> +{
> +	/* TODO: Take into account the scalers once we support them */
> +	return config->adjusted_mode.crtc_clock;
> +}
> +
> +/*
> + * The max latency should be 257 (max the punit can code is 255 and we add 2us
> + * for the read latency) and bytes_per_pixel should always be <= 8, so that
> + * should allow pixel_rate up to ~2 GHz which seems sufficient since max
> + * 2xcdclk is 1350 MHz and the pixel rate should never exceed that.
> +*/
> +static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel,
> +			       uint32_t latency)
> +{
> +	uint32_t wm_intermediate_val, ret;
> +
> +	if (latency == 0)
> +		return UINT_MAX;
> +
> +	wm_intermediate_val = latency * pixel_rate * bytes_per_pixel;
> +	ret = DIV_ROUND_UP(wm_intermediate_val, 1000);
> +
> +	return ret;
> +}
> +
> +static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
> +			       uint32_t horiz_pixels, uint8_t bytes_per_pixel,
> +			       uint32_t latency)
> +{
> +	uint32_t ret, plane_bytes_per_line, wm_intermediate_val;
> +
> +	if (latency == 0)
> +		return UINT_MAX;
> +
> +	plane_bytes_per_line = horiz_pixels * bytes_per_pixel;
> +	wm_intermediate_val = latency * pixel_rate;
> +	ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) *
> +				plane_bytes_per_line;
> +
> +	return ret;
> +}
> +
> +static void skl_compute_transition_wm(struct drm_crtc *crtc,
> +				  struct skl_pipe_wm_parameters *params,
> +				  struct skl_pipe_wm *pipe_wm)
> +{
> +	/*
> +	 * For now it is suggested to use the LP0 wm val of corresponding
> +	 * plane as transition wm val. This is done while computing results.
> +	 */
> +	if (!params->active)
> +		return;
> +}
> +
> +static uint32_t
> +skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p)
> +{
> +	if (!intel_crtc_active(crtc))
> +		return 0;
> +
> +	return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate);
> +
> +}
> +
> +static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
> +				       const struct intel_crtc *intel_crtc)
> +{
> +	struct drm_device *dev = intel_crtc->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	const struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
> +	enum pipe pipe = intel_crtc->pipe;
> +
> +	if (memcmp(new_ddb->plane[pipe], cur_ddb->plane[pipe],
> +		   sizeof(new_ddb->plane[pipe])))
> +		return true;
> +
> +	if (memcmp(&new_ddb->cursor[pipe], &cur_ddb->cursor[pipe],
> +		    sizeof(new_ddb->cursor[pipe])))
> +		return true;
> +
> +	return false;
> +}
> +
> +static void skl_compute_wm_global_parameters(struct drm_device *dev,
> +					     struct intel_wm_config *config)
> +{
> +	struct drm_crtc *crtc;
> +	struct drm_plane *plane;
> +
> +	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
> +		config->num_pipes_active += intel_crtc_active(crtc);
> +
> +	/* FIXME: I don't think we need those two global parameters on SKL */
> +	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> +		struct intel_plane *intel_plane = to_intel_plane(plane);
> +
> +		config->sprites_enabled |= intel_plane->wm.enabled;
> +		config->sprites_scaled |= intel_plane->wm.scaled;
> +	}
> +}
> +
> +static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
> +					   struct skl_pipe_wm_parameters *p)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	enum pipe pipe = intel_crtc->pipe;
> +	struct drm_plane *plane;
> +	int i = 1; /* Index for sprite planes start */
> +
> +	p->active = intel_crtc_active(crtc);
> +	if (p->active) {
> +		p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal;
> +		p->pixel_rate = skl_pipe_pixel_rate(&intel_crtc->config);
> +
> +		/*
> +		 * For now, assume primary and cursor planes are always enabled.
> +		 */
> +		p->plane[0].enabled = true;
> +		p->plane[0].bytes_per_pixel =
> +			crtc->primary->fb->bits_per_pixel / 8;
> +		p->plane[0].horiz_pixels = intel_crtc->config.pipe_src_w;
> +		p->plane[0].vert_pixels = intel_crtc->config.pipe_src_h;
> +
> +		p->cursor.enabled = true;
> +		p->cursor.bytes_per_pixel = 4;
> +		p->cursor.horiz_pixels = intel_crtc->cursor_width ?
> +					 intel_crtc->cursor_width : 64;
> +	}
> +
> +	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> +		struct intel_plane *intel_plane = to_intel_plane(plane);
> +
> +		if (intel_plane->pipe == pipe)
> +			p->plane[i++] = intel_plane->wm;
> +	}
> +}
> +
> +static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
> +				   struct intel_plane_wm_parameters *p_params,
> +				   uint16_t max_page_buff_alloc,
> +				   uint32_t mem_value,
> +				   uint16_t *res_blocks, /* out */
> +				   uint8_t *res_lines /* out */)
> +{
> +	uint32_t method1, method2, plane_bytes_per_line;
> +	uint32_t result_bytes;
> +
> +	if (!p->active || !p_params->enabled)
> +		return false;
> +
> +	method1 = skl_wm_method1(p->pixel_rate,
> +				 p_params->bytes_per_pixel,
> +				 mem_value);
> +	method2 = skl_wm_method2(p->pixel_rate,
> +				 p->pipe_htotal,
> +				 p_params->horiz_pixels,
> +				 p_params->bytes_per_pixel,
> +				 mem_value);
> +
> +	plane_bytes_per_line = p_params->horiz_pixels *
> +					p_params->bytes_per_pixel;
> +
> +	/* For now xtile and linear */
> +	if (((max_page_buff_alloc * 512) / plane_bytes_per_line) >= 1)
> +		result_bytes = min(method1, method2);
> +	else
> +		result_bytes = method1;
> +
> +	*res_blocks = DIV_ROUND_UP(result_bytes, 512) + 1;
> +	*res_lines = DIV_ROUND_UP(result_bytes, plane_bytes_per_line);
> +
> +	return true;
> +}
> +
> +static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
> +				 struct skl_ddb_allocation *ddb,
> +				 struct skl_pipe_wm_parameters *p,
> +				 enum pipe pipe,
> +				 int level,
> +				 int num_planes,
> +				 struct skl_wm_level *result)
> +{
> +	uint16_t latency = dev_priv->wm.skl_latency[level];
> +	uint16_t ddb_blocks;
> +	int i;
> +
> +	for (i = 0; i < num_planes; i++) {
> +		ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
> +
> +		result->plane_en[i] = skl_compute_plane_wm(p, &p->plane[i],
> +						ddb_blocks,
> +						latency,
> +						&result->plane_res_b[i],
> +						&result->plane_res_l[i]);
> +	}
> +
> +	ddb_blocks = skl_ddb_entry_size(&ddb->cursor[pipe]);
> +	result->cursor_en = skl_compute_plane_wm(p, &p->cursor, ddb_blocks,
> +						 latency, &result->cursor_res_b,
> +						 &result->cursor_res_l);
> +}
> +
> +static void skl_compute_pipe_wm(struct drm_crtc *crtc,
> +				struct skl_ddb_allocation *ddb,
> +				struct skl_pipe_wm_parameters *params,
> +				struct skl_pipe_wm *pipe_wm)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	const struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	int level, max_level = ilk_wm_max_level(dev);
> +
> +	for (level = 0; level <= max_level; level++) {
> +		skl_compute_wm_level(dev_priv, ddb, params, intel_crtc->pipe,
> +				     level, intel_num_planes(intel_crtc),
> +				     &pipe_wm->wm[level]);
> +	}
> +	pipe_wm->linetime = skl_compute_linetime_wm(crtc, params);
> +
> +	skl_compute_transition_wm(crtc, params, pipe_wm);
> +}
> +
> +static void skl_compute_wm_results(struct drm_device *dev,
> +				   struct skl_pipe_wm_parameters *p,
> +				   struct skl_pipe_wm *p_wm,
> +				   struct skl_wm_values *r,
> +				   struct intel_crtc *intel_crtc)
> +{
> +	int level, max_level = ilk_wm_max_level(dev);
> +	enum pipe pipe = intel_crtc->pipe;
> +
> +	for (level = 0; level <= max_level; level++) {
> +		uint16_t ddb_blocks;
> +		uint32_t temp;
> +		int i;
> +
> +		for (i = 0; i < intel_num_planes(intel_crtc); i++) {
> +			temp = 0;
> +			ddb_blocks = skl_ddb_entry_size(&r->ddb.plane[pipe][i]);
> +
> +			if ((p_wm->wm[level].plane_res_b[i] > ddb_blocks) ||
> +				(p_wm->wm[level].plane_res_l[i] > 31))
> +				p_wm->wm[level].plane_en[i] = false;
> +
> +			temp |= p_wm->wm[level].plane_res_l[i] <<
> +					PLANE_WM_LINES_SHIFT;
> +			temp |= p_wm->wm[level].plane_res_b[i];
> +			if (p_wm->wm[level].plane_en[i])
> +				temp |= PLANE_WM_EN;
> +
> +			r->plane[pipe][i][level] = temp;
> +			/* Use the LP0 WM value for transition WM for now. */
> +			if (level == 0)
> +				r->plane_trans[pipe][i] = temp;
> +		}
> +
> +		temp = 0;
> +		ddb_blocks = skl_ddb_entry_size(&r->ddb.cursor[pipe]);
> +
> +		if ((p_wm->wm[level].cursor_res_b > ddb_blocks) ||
> +			(p_wm->wm[level].cursor_res_l > 31))
> +			p_wm->wm[level].cursor_en = false;
> +
> +		temp |= p_wm->wm[level].cursor_res_l << PLANE_WM_LINES_SHIFT;
> +		temp |= p_wm->wm[level].cursor_res_b;
> +
> +		if (p_wm->wm[level].cursor_en)
> +			temp |= PLANE_WM_EN;
> +
> +		r->cursor[pipe][level] = temp;
> +		/* Use the LP0 WM value for transition WM for now. */
> +		if (level == 0)
> +			r->cursor_trans[pipe] = temp;
> +
> +	}
> +
> +	r->wm_linetime[pipe] = p_wm->linetime;
> +}
> +
> +static void skl_write_wm_values(struct drm_i915_private *dev_priv,
> +				const struct skl_wm_values *new)
> +{
> +	struct drm_device *dev = dev_priv->dev;
> +	struct intel_crtc *crtc;
> +
> +	list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
> +		int i, level, max_level = ilk_wm_max_level(dev);
> +		enum pipe pipe = crtc->pipe;
> +
> +		if (new->dirty[pipe]) {
> +			I915_WRITE(PIPE_WM_LINETIME(pipe),
> +					new->wm_linetime[pipe]);
> +
> +			for (level = 0; level <= max_level; level++) {
> +				for (i = 0; i < intel_num_planes(crtc); i++)
> +					I915_WRITE(PLANE_WM(pipe, i, level),
> +						new->plane[pipe][i][level]);
> +				I915_WRITE(CUR_WM(pipe, level),
> +					new->cursor[pipe][level]);
> +			}
> +			for (i = 0; i < intel_num_planes(crtc); i++)
> +				I915_WRITE(PLANE_WM_TRANS(pipe, i),
> +						new->plane_trans[pipe][i]);
> +			I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
> +		}
> +	}
> +
> +	dev_priv->wm.skl_hw = *new;
> +}
> +
> +static bool skl_update_pipe_wm(struct drm_crtc *crtc,
> +			       struct skl_pipe_wm_parameters *params,
> +			       struct intel_wm_config *config,
> +			       struct skl_ddb_allocation *ddb, /* out */
> +			       struct skl_pipe_wm *pipe_wm /* out */)
> +{
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +
> +	skl_compute_wm_pipe_parameters(crtc, params);
> +	skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
> +
> +	if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
> +		return false;
> +
> +	intel_crtc->wm.skl_active = *pipe_wm;
> +	return true;
> +}
> +
> +static void skl_update_other_pipe_wm(struct drm_device *dev,
> +				     struct drm_crtc *crtc,
> +				     struct intel_wm_config *config,
> +				     struct skl_wm_values *r)
> +{
> +	struct intel_crtc *intel_crtc;
> +	struct intel_crtc *this_crtc = to_intel_crtc(crtc);
> +
> +	/*
> +	 * If the WM update hasn't changed the allocation for this_crtc (the
> +	 * crtc we are currently computing the new WM values for), other
> +	 * enabled crtcs will keep the same allocation and we don't need to
> +	 * recompute anything for them.
> +	 */
> +	if (!skl_ddb_allocation_changed(&r->ddb, this_crtc))
> +		return;
> +
> +	/*
> +	 * Otherwise, because of this_crtc being freshly enabled/disabled, the
> +	 * other active pipes need new DDB allocation and WM values.
> +	 */
> +	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
> +				base.head) {
> +		struct skl_pipe_wm_parameters params = {};
> +		struct skl_pipe_wm pipe_wm = {};
> +		bool wm_changed;
> +
> +		if (this_crtc->pipe == intel_crtc->pipe)
> +			continue;
> +
> +		if (!intel_crtc->active)
> +			continue;
> +
> +		wm_changed = skl_update_pipe_wm(&intel_crtc->base,
> +						&params, config,
> +						&r->ddb, &pipe_wm);
> +
> +		/*
> +		 * If we end up re-computing the other pipe WM values, it's
> +		 * because it was really needed, so we expect the WM values to
> +		 * be different.
> +		 */
> +		WARN_ON(!wm_changed);
> +
> +		skl_compute_wm_results(dev, &params, &pipe_wm, r, intel_crtc);
> +		r->dirty[intel_crtc->pipe] = true;
> +	}
> +}
> +
> +static void skl_update_wm(struct drm_crtc *crtc)
> +{
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct drm_device *dev = crtc->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct skl_pipe_wm_parameters params = {};
> +	struct skl_wm_values *results = &dev_priv->wm.skl_results;
> +	struct skl_pipe_wm pipe_wm = {};
> +	struct intel_wm_config config = {};
> +
> +	memset(results, 0, sizeof(*results));
> +
> +	skl_compute_wm_global_parameters(dev, &config);
> +
> +	if (!skl_update_pipe_wm(crtc, &params, &config,
> +				&results->ddb, &pipe_wm))
> +		return;
> +
> +	skl_compute_wm_results(dev, &params, &pipe_wm, results, intel_crtc);
> +	results->dirty[intel_crtc->pipe] = true;
> +
> +	skl_update_other_pipe_wm(dev, crtc, &config, results);
> +	skl_write_wm_values(dev_priv, results);
> +}
> +
> +static void
> +skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc,
> +		     uint32_t sprite_width, uint32_t sprite_height,
> +		     int pixel_size, bool enabled, bool scaled)
> +{
> +	struct intel_plane *intel_plane = to_intel_plane(plane);
> +
> +	intel_plane->wm.enabled = enabled;
> +	intel_plane->wm.scaled = scaled;
> +	intel_plane->wm.horiz_pixels = sprite_width;
> +	intel_plane->wm.vert_pixels = sprite_height;
> +	intel_plane->wm.bytes_per_pixel = pixel_size;
> +
> +	skl_update_wm(crtc);
> +}
> +
>  static void ilk_update_wm(struct drm_crtc *crtc)
>  {
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> @@ -7486,6 +7906,8 @@ void intel_init_pm(struct drm_device *dev)
>  		skl_setup_wm_latency(dev);
>  
>  		dev_priv->display.init_clock_gating = gen9_init_clock_gating;
> +		dev_priv->display.update_wm = skl_update_wm;
> +		dev_priv->display.update_sprite_wm = skl_update_sprite_wm;
>  	} else if (HAS_PCH_SPLIT(dev)) {
>  		ilk_setup_wm_latency(dev);
>  
> -- 
> 1.8.3.1

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 48/89 v6] drm/i915/skl: Allocate DDB portions for display planes
  2014-09-27 14:15     ` [PATCH 48/89 v6] " Damien Lespiau
@ 2014-10-29 17:12       ` Ville Syrjälä
  0 siblings, 0 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-10-29 17:12 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Sat, Sep 27, 2014 at 03:15:00PM +0100, Damien Lespiau wrote:
> v2: Fix the 3rd plane/cursor logic (Pradeep Bhat)
> v3: Fix one-by-one error in the DDB allocation code
> v4: Rebase on top of the skl_pipe_pixel_rate() argument change
> v5: Replace the available/start/end output parameters of
>     skl_ddb_get_pipe_allocation_limits() by a single ddb entry constify
>     a few arguments
>     Make nth_active_pipe 0 indexed
>     Use sizeof(variable) instead of sizeof(type)
>     (Ville)
> v6: Use the for_each_crtc() macro instead of list_for_each_entry()
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

Looks good.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/i915/intel_pm.c | 148 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 148 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 1db4aa8..3dc689e 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2965,6 +2965,153 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
>  	return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
>  }
>  
> +/*
> + * On gen9, we need to allocate Display Data Buffer (DDB) portions to the
> + * different active planes.
> + */
> +
> +#define SKL_DDB_SIZE		896	/* in blocks */
> +
> +static void
> +skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
> +				   struct drm_crtc *for_crtc,
> +				   const struct intel_wm_config *config,
> +				   const struct skl_pipe_wm_parameters *params,
> +				   struct skl_ddb_entry *alloc /* out */)
> +{
> +	struct drm_crtc *crtc;
> +	unsigned int pipe_size, ddb_size;
> +	int nth_active_pipe;
> +
> +	if (!params->active) {
> +		alloc->start = 0;
> +		alloc->end = 0;
> +		return;
> +	}
> +
> +	ddb_size = SKL_DDB_SIZE;
> +
> +	ddb_size -= 4; /* 4 blocks for bypass path allocation */
> +
> +	nth_active_pipe = 0;
> +	for_each_crtc(dev, crtc) {
> +		if (!intel_crtc_active(crtc))
> +			continue;
> +
> +		if (crtc == for_crtc)
> +			break;
> +
> +		nth_active_pipe++;
> +	}
> +
> +	pipe_size = ddb_size / config->num_pipes_active;
> +	alloc->start = nth_active_pipe * ddb_size / config->num_pipes_active;
> +	alloc->end = alloc->start + pipe_size - 1;
> +}
> +
> +static unsigned int skl_cursor_allocation(const struct intel_wm_config *config)
> +{
> +	if (config->num_pipes_active == 1)
> +		return 32;
> +
> +	return 8;
> +}
> +
> +static unsigned int
> +skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p)
> +{
> +	return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel;
> +}
> +
> +/*
> + * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching
> + * a 8192x4096@32bpp framebuffer:
> + *   3 * 4096 * 8192  * 4 < 2^32
> + */
> +static unsigned int
> +skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc,
> +				 const struct skl_pipe_wm_parameters *params)
> +{
> +	unsigned int total_data_rate = 0;
> +	int plane;
> +
> +	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
> +		const struct intel_plane_wm_parameters *p;
> +
> +		p = &params->plane[plane];
> +		if (!p->enabled)
> +			continue;
> +
> +		total_data_rate += skl_plane_relative_data_rate(p);
> +	}
> +
> +	return total_data_rate;
> +}
> +
> +static void
> +skl_allocate_pipe_ddb(struct drm_crtc *crtc,
> +		      const struct intel_wm_config *config,
> +		      const struct skl_pipe_wm_parameters *params,
> +		      struct skl_ddb_allocation *ddb /* out */)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	enum pipe pipe = intel_crtc->pipe;
> +	struct skl_ddb_entry alloc;
> +	uint16_t alloc_size, start, cursor_blocks;
> +	unsigned int total_data_rate;
> +	int plane;
> +
> +	skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, &alloc);
> +	alloc_size = skl_ddb_entry_size(&alloc);
> +	if (alloc_size == 0) {
> +		memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
> +		memset(&ddb->cursor[pipe], 0, sizeof(ddb->cursor[pipe]));
> +		return;
> +	}
> +
> +	cursor_blocks = skl_cursor_allocation(config);
> +	ddb->cursor[pipe].start = alloc.end - cursor_blocks + 1;
> +	ddb->cursor[pipe].end = alloc.end;
> +
> +	alloc_size -= cursor_blocks;
> +	alloc.end -= cursor_blocks;
> +
> +	/*
> +	 * Each active plane get a portion of the remaining space, in
> +	 * proportion to the amount of data they need to fetch from memory.
> +	 *
> +	 * FIXME: we may not allocate every single block here.
> +	 */
> +	total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params);
> +
> +	start = alloc.start;
> +	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
> +		const struct intel_plane_wm_parameters *p;
> +		unsigned int data_rate;
> +		uint16_t plane_blocks;
> +
> +		p = &params->plane[plane];
> +		if (!p->enabled)
> +			continue;
> +
> +		data_rate = skl_plane_relative_data_rate(p);
> +
> +		/*
> +		 * promote the expression to 64 bits to avoid overflowing, the
> +		 * result is < available as data_rate / total_data_rate < 1
> +		 */
> +		plane_blocks = div_u64((uint64_t)alloc_size * data_rate,
> +				       total_data_rate);
> +
> +		ddb->plane[pipe][plane].start = start;
> +		ddb->plane[pipe][plane].end = start + plane_blocks - 1;
> +
> +		start += plane_blocks;
> +	}
> +
> +}
> +
>  static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_config *config)
>  {
>  	/* TODO: Take into account the scalers once we support them */
> @@ -3286,6 +3433,7 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  
>  	skl_compute_wm_pipe_parameters(crtc, params);
> +	skl_allocate_pipe_ddb(crtc, config, params, ddb);
>  	skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
>  
>  	if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 49/89] drm/i915/skl: Program the DDB allocation
  2014-09-27 14:17     ` Damien Lespiau
@ 2014-10-29 18:42       ` Ville Syrjälä
  0 siblings, 0 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-10-29 18:42 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Sat, Sep 27, 2014 at 03:17:58PM +0100, Damien Lespiau wrote:
> On Fri, Sep 19, 2014 at 01:03:15PM +0300, Ville Syrjälä wrote:
> > > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > > index 0ddcbad..756ff16 100644
> > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > @@ -3393,6 +3393,15 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
> > >  				I915_WRITE(PLANE_WM_TRANS(pipe, i),
> > >  						new->plane_trans[pipe][i]);
> > >  			I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
> > > +
> > > +			for (i = 0; i < intel_num_planes(crtc); i++)
> > > +				I915_WRITE(PLANE_BUF_CFG(pipe, i),
> > > +					   new->ddb.plane[pipe][i].end << 16 |
> > 
> > The spec doesn't say if end is inclusive or exclusive. Someone actually
> > confirmed that from someone or tested it?
> 
> I remember testing it and having the end of a plane match the start of
> another produces artefacts.
> 
> > > +					   new->ddb.plane[pipe][i].start);
> > > +
> > > +			I915_WRITE(CUR_BUF_CFG(pipe),
> > > +				   new->ddb.cursor[pipe].end << 16 |
> > > +				   new->ddb.cursor[pipe].start);
> > >  		}
> > >  	}
> > 
> > And here we land in deep doodoo wrt. changing the DDB allocation
> > for active pipes. Someone needs to implement the correct logic to
> > sequence the DDB allocation changes so that the allocations don't
> > overlap at any point in time.
> > 
> > So this needs a big FIXME at the very least.
> 
> As seen on IRC, the DDB regs are double buffered and the "flush" patch
> is supposed to take care of that.

Just went through the new and improved flush patch. The algorithm is
solid now, just need to keep moving it towards the atomic stuff, but in
the meantime I think we can move forward with this stuff.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 50/89] drm/i915/skl: Read the pipe WM HW state
  2014-09-04 11:27 ` [PATCH 50/89] drm/i915/skl: Read the pipe WM HW state Damien Lespiau
@ 2014-10-29 19:02   ` Ville Syrjälä
  2014-10-30 12:03     ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Ville Syrjälä @ 2014-10-29 19:02 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx, Pradeep Bhat

On Thu, Sep 04, 2014 at 12:27:16PM +0100, Damien Lespiau wrote:
> From: Pradeep Bhat <pradeep.bhat@intel.com>
> 
> This patch provides the implementation for reading the pipe wm HW
> state.
> 
> v2: Incorporated Damien's review comments and also made modifications
>     to incorporate the plane/cursor split.
> 
> v3: No need to ident a line that was fitting 80 chars
>     Return early instead of indenting the remaining of a function
>     (Damien)
> 
> v4: Rebase on top of nightly (minor conflect in intel_drv.h)
> 
> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c |   4 +-
>  drivers/gpu/drm/i915/intel_drv.h     |   1 +
>  drivers/gpu/drm/i915/intel_pm.c      | 104 +++++++++++++++++++++++++++++++++++
>  3 files changed, 108 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 3d9f447..69e023a 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13375,7 +13375,9 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
>  		pll->on = false;
>  	}
>  
> -	if (HAS_PCH_SPLIT(dev))
> +	if (IS_GEN9(dev))
> +		skl_wm_get_hw_state(dev);
> +	else if (HAS_PCH_SPLIT(dev))
>  		ilk_wm_get_hw_state(dev);
>  
>  	if (force_restore) {
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 268087f..559b747 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1102,6 +1102,7 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv);
>  void intel_init_runtime_pm(struct drm_i915_private *dev_priv);
>  void intel_fini_runtime_pm(struct drm_i915_private *dev_priv);
>  void ilk_wm_get_hw_state(struct drm_device *dev);
> +void skl_wm_get_hw_state(struct drm_device *dev);
>  
>  
>  /* intel_sdvo.c */
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 756ff16..1e56067 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3591,6 +3591,110 @@ ilk_update_sprite_wm(struct drm_plane *plane,
>  	ilk_update_wm(crtc);
>  }
>  
> +static void skl_pipe_wm_active_state(uint32_t val,
> +				     struct skl_pipe_wm *active,
> +				     bool is_transwm,
> +				     bool is_cursor,
> +				     int i,
> +				     int level)
> +{
> +	bool is_enabled = (val & PLANE_WM_EN) != 0;
> +
> +	if (!is_transwm) {
> +		if (!is_cursor) {
> +			active->wm[level].plane_en[i] = is_enabled;
> +			active->wm[level].plane_res_b[i] =
> +					val & PLANE_WM_BLOCKS_MASK;
> +			active->wm[level].plane_res_l[i] =
> +					(val >> PLANE_WM_LINES_SHIFT) &
> +						PLANE_WM_LINES_MASK;
> +		} else {
> +			active->wm[level].cursor_en = is_enabled;
> +			active->wm[level].cursor_res_b =
> +					val & PLANE_WM_BLOCKS_MASK;
> +			active->wm[level].cursor_res_l =
> +					(val >> PLANE_WM_LINES_SHIFT) &
> +						PLANE_WM_LINES_MASK;
> +		}
> +	} else {
> +		if (!is_cursor) {
> +			active->trans_wm.plane_en[i] = is_enabled;
> +			active->trans_wm.plane_res_b[i] =
> +					val & PLANE_WM_BLOCKS_MASK;
> +			active->trans_wm.plane_res_l[i] =
> +					(val >> PLANE_WM_LINES_SHIFT) &
> +						PLANE_WM_LINES_MASK;
> +		} else {
> +			active->trans_wm.cursor_en = is_enabled;
> +			active->trans_wm.cursor_res_b =
> +					val & PLANE_WM_BLOCKS_MASK;
> +			active->trans_wm.cursor_res_l =
> +					(val >> PLANE_WM_LINES_SHIFT) &
> +						PLANE_WM_LINES_MASK;
> +		}
> +	}
> +}

Am I imagining it or could this function be reduced to four lines if you
would just pass the target struct as a parameter instead of the
(is_transwm,is_cursor,i,level) tuple? Ah no, crap, SoA strikes back. So I
think I mentioned it already during my first round of reviews that I'd
like make a bunch of this stuff AoS instead. But that's a recipe for
massive conflicts so let's get the current stuff in first before we go
tearing into those structures.

Apart from that horror of a function this looks like it does what it's
meant to so:
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> +static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct skl_pipe_wm *active = &intel_crtc->wm.skl_active;
> +	enum pipe pipe = intel_crtc->pipe;
> +	int level, i, max_level;
> +	uint32_t temp;
> +
> +	max_level = ilk_wm_max_level(dev);
> +
> +	hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe));
> +
> +	for (level = 0; level <= max_level; level++) {
> +		for (i = 0; i < intel_num_planes(intel_crtc); i++)
> +			hw->plane[pipe][i][level] =
> +					I915_READ(PLANE_WM(pipe, i, level));
> +		hw->cursor[pipe][level] = I915_READ(CUR_WM(pipe, level));
> +	}
> +
> +	for (i = 0; i < intel_num_planes(intel_crtc); i++)
> +		hw->plane_trans[pipe][i] = I915_READ(PLANE_WM_TRANS(pipe, i));
> +	hw->cursor_trans[pipe] = I915_READ(CUR_WM_TRANS(pipe));
> +
> +	if (!intel_crtc_active(crtc))
> +		return;
> +
> +	hw->dirty[pipe] = true;
> +
> +	active->linetime = hw->wm_linetime[pipe];
> +
> +	for (level = 0; level <= max_level; level++) {
> +		for (i = 0; i < intel_num_planes(intel_crtc); i++) {
> +			temp = hw->plane[pipe][i][level];
> +			skl_pipe_wm_active_state(temp, active, false,
> +						false, i, level);
> +		}
> +		temp = hw->cursor[pipe][level];
> +		skl_pipe_wm_active_state(temp, active, false, true, i, level);
> +	}
> +
> +	for (i = 0; i < intel_num_planes(intel_crtc); i++) {
> +		temp = hw->plane_trans[pipe][i];
> +		skl_pipe_wm_active_state(temp, active, true, false, i, 0);
> +	}
> +
> +	temp = hw->cursor_trans[pipe];
> +	skl_pipe_wm_active_state(temp, active, true, true, i, 0);
> +}
> +
> +void skl_wm_get_hw_state(struct drm_device *dev)
> +{
> +	struct drm_crtc *crtc;
> +
> +	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
> +		skl_pipe_wm_get_hw_state(crtc);
> +}
> +
>  static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
>  {
>  	struct drm_device *dev = crtc->dev;
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 52/89] drm/i915/gen9: Disable WM if corresponding latency is 0
  2014-09-24 14:06     ` Damien Lespiau
@ 2014-10-29 19:05       ` Ville Syrjälä
  0 siblings, 0 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-10-29 19:05 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Wed, Sep 24, 2014 at 03:06:11PM +0100, Damien Lespiau wrote:
> On Fri, Sep 19, 2014 at 01:05:02PM +0300, Ville Syrjälä wrote:
> > 
> > If we're going to be paranoid I think we should disable all higher WM
> > levels whose latency is lower than any of the lower levels. And I
> > think we'll want something like dev_priv->wm.max_wm_level instead of
> > relying on the zero latency tricks. That thing has been on my TODO
> > list since forever.
> 
> Can we go step by step? add this patch and then I noted this as a task
> for post merge work. No sure who will end up doing and and if the
> sanitazing code can be shared between platforms (probably yes?), but
> that can wait a bit longer?

Sure. This seems fine for now.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 83/89] drm/i915/skl: Check the DDB state at modeset
  2014-09-04 13:27   ` Daniel Vetter
@ 2014-10-29 19:16     ` Ville Syrjälä
  0 siblings, 0 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-10-29 19:16 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 03:27:49PM +0200, Daniel Vetter wrote:
> On Thu, Sep 04, 2014 at 12:27:49PM +0100, Damien Lespiau wrote:
> > v2: Don't check DDB on pre-SKL platforms
> >     Don't check DDB state on disabled pipes
> > 
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> 
> We probably want to do this with a vfunc eventually ... but reall
> deferring to Ville here, he'll know best what might be useful to make sure
> that the wm readout/takeover is accurate enough. So lgtm for now.

Yeah seems fine as is for now. On SKL checking the WMs too would be
fairly easy I guess. On ILK it'd be a bit more fuzzy due to the
(eventual) two part update + multi pipe merging stuff.

Doing it unconditionally at modeset time seems OK since it's a slow
operation anyway. We might want to do it for plane updates as well, but
I think that probably needs to be hidden behind some debug knob since we
don't want to pile on too much overhead there.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> -Daniel
> 
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h      |  9 +++++++
> >  drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++++++++++++++++++
> >  2 files changed, 60 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 95e57dc..0baf7f3 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -1424,6 +1424,15 @@ static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry)
> >  	return entry->end - entry->start + 1;
> >  }
> >  
> > +static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
> > +				       const struct skl_ddb_entry *e2)
> > +{
> > +	if (e1->start == e2->start && e1->end == e2->end)
> > +		return true;
> > +
> > +	return false;
> > +}
> > +
> >  struct skl_ddb_allocation {
> >  	struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
> >  	struct skl_ddb_entry cursor[I915_MAX_PIPES];
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 9b31342..35d3389 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -10944,6 +10944,56 @@ intel_pipe_config_compare(struct drm_device *dev,
> >  	return true;
> >  }
> >  
> > +static void check_wm_state(struct drm_device *dev)
> > +{
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	struct skl_ddb_allocation hw_ddb, *sw_ddb;
> > +	struct intel_crtc *intel_crtc;
> > +	int plane;
> > +
> > +	if (INTEL_INFO(dev)->gen < 9)
> > +		return;
> > +
> > +	skl_ddb_get_hw_state(dev_priv, &hw_ddb);
> > +	sw_ddb = &dev_priv->wm.skl_hw.ddb;
> > +
> > +	for_each_intel_crtc(dev, intel_crtc) {
> > +		struct skl_ddb_entry *hw_entry, *sw_entry;
> > +		const enum pipe pipe = intel_crtc->pipe;
> > +
> > +		if (!intel_crtc->active)
> > +			continue;
> > +
> > +		/* planes */
> > +		for_each_plane(pipe, plane) {
> > +			hw_entry = &hw_ddb.plane[pipe][plane];
> > +			sw_entry = &sw_ddb->plane[pipe][plane];
> > +
> > +			if (skl_ddb_entry_equal(hw_entry, sw_entry))
> > +				continue;
> > +
> > +			DRM_ERROR("mismatch in DDB state pipe %c plane %d "
> > +				  "(expected (%u,%u), found (%u,%u))\n",
> > +				  pipe_name(pipe), plane + 1,
> > +				  sw_entry->start, sw_entry->end,
> > +				  hw_entry->start, hw_entry->end);
> > +		}
> > +
> > +		/* cursor */
> > +		hw_entry = &hw_ddb.cursor[pipe];
> > +		sw_entry = &sw_ddb->cursor[pipe];
> > +
> > +		if (skl_ddb_entry_equal(hw_entry, sw_entry))
> > +			continue;
> > +
> > +		DRM_ERROR("mismatch in DDB state pipe %c cursor "
> > +			  "(expected (%u,%u), found (%u,%u))\n",
> > +			  pipe_name(pipe),
> > +			  sw_entry->start, sw_entry->end,
> > +			  hw_entry->start, hw_entry->end);
> > +	}
> > +}
> > +
> >  static void
> >  check_connector_state(struct drm_device *dev)
> >  {
> > @@ -11143,6 +11193,7 @@ check_shared_dpll_state(struct drm_device *dev)
> >  void
> >  intel_modeset_check_state(struct drm_device *dev)
> >  {
> > +	check_wm_state(dev);
> >  	check_connector_state(dev);
> >  	check_encoder_state(dev);
> >  	check_crtc_state(dev);
> > -- 
> > 1.8.3.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 76/89] drm/i915/skl: Store the new WM state at the very end of the update
  2014-09-04 11:27 ` [PATCH 76/89] drm/i915/skl: Store the new WM state at the very end of the update Damien Lespiau
@ 2014-10-29 19:19   ` Ville Syrjälä
  0 siblings, 0 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-10-29 19:19 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:27:42PM +0100, Damien Lespiau wrote:
> We're going to add a new step, let's not hide the copy of the new WM
> state inside one inner function, but as a 1st level operation in the WM
> update.

The new step being the flush which needs to compare the currnet and new
ddb state to figure out how to perform the update.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> 
> v2: Split the staging results structure to not exceed the 1Kb stack
>     allocation in skl_update_wm()
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_pm.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 5425d85..7f7a2e2 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3432,8 +3432,6 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
>  				   new->ddb.cursor[pipe].start);
>  		}
>  	}
> -
> -	dev_priv->wm.skl_hw = *new;
>  }
>  
>  static bool skl_update_pipe_wm(struct drm_crtc *crtc,
> @@ -3527,6 +3525,9 @@ static void skl_update_wm(struct drm_crtc *crtc)
>  
>  	skl_update_other_pipe_wm(dev, crtc, &config, results);
>  	skl_write_wm_values(dev_priv, results);
> +
> +	/* store the new configuration */
> +	dev_priv->wm.skl_hw = *results;
>  }
>  
>  static void
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 81/89] drm/i915/skl: Expose skl_ddb_get_hw_state()
  2014-09-04 11:27 ` [PATCH 81/89] drm/i915/skl: Expose skl_ddb_get_hw_state() Damien Lespiau
@ 2014-10-29 19:21   ` Ville Syrjälä
  2014-10-29 23:49     ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Ville Syrjälä @ 2014-10-29 19:21 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:27:47PM +0100, Damien Lespiau wrote:
> So we can use it in the modeset checker.
> 
> v2: Rebase on top of nigthly
> 
> v3: Rebase on top of -nigthly (minor conflict in intel_drv.h)
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

I don't know if I should even bother with the r-b. Feel free to slap
one on if you want :)

> ---
>  drivers/gpu/drm/i915/intel_drv.h | 2 ++
>  drivers/gpu/drm/i915/intel_pm.c  | 4 ++--
>  2 files changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index a407d04..782dfbc 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1108,6 +1108,8 @@ void intel_init_runtime_pm(struct drm_i915_private *dev_priv);
>  void intel_fini_runtime_pm(struct drm_i915_private *dev_priv);
>  void ilk_wm_get_hw_state(struct drm_device *dev);
>  void skl_wm_get_hw_state(struct drm_device *dev);
> +void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
> +			  struct skl_ddb_allocation *ddb /* out */);
>  
>  
>  /* intel_sdvo.c */
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 8d24a4d..ff0d8cb 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3026,8 +3026,8 @@ static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg)
>  	entry->end = (reg >> 16) & 0x3ff;
>  }
>  
> -static void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
> -				 struct skl_ddb_allocation *ddb /* out */)
> +void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
> +			  struct skl_ddb_allocation *ddb /* out */)
>  {
>  	struct drm_device *dev = dev_priv->dev;
>  	enum pipe pipe;
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 82/89] drm/i915/skl: Add a debugfs file to dump the DDB allocation
  2014-09-04 11:27 ` [PATCH 82/89] drm/i915/skl: Add a debugfs file to dump the DDB allocation Damien Lespiau
@ 2014-10-29 19:23   ` Ville Syrjälä
  0 siblings, 0 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-10-29 19:23 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Thu, Sep 04, 2014 at 12:27:48PM +0100, Damien Lespiau wrote:
> v2: minor conflict in i915_debugfs.c
> v3: Rebase on top of the for_each_pipe() change adding dev_priv as first
>     argument.
> v4: minor conflict in the i915_debugfs_files array
> v5: minor conflict in the i915_debugfs_files array
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/i915/i915_debugfs.c | 37 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 37 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 1520d1f..0468ec9 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -2669,6 +2669,42 @@ static int i915_wa_registers(struct seq_file *m, void *unused)
>  	return 0;
>  }
>  
> +static int i915_ddb_info(struct seq_file *m, void *unused)
> +{
> +	struct drm_info_node *node = m->private;
> +	struct drm_device *dev = node->minor->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct skl_ddb_allocation *ddb;
> +	struct skl_ddb_entry *entry;
> +	enum pipe pipe;
> +	int plane;
> +
> +	drm_modeset_lock_all(dev);
> +
> +	ddb = &dev_priv->wm.skl_hw.ddb;
> +
> +	seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
> +
> +	for_each_pipe(dev_priv, pipe) {
> +		seq_printf(m, "Pipe %c\n", pipe_name(pipe));
> +
> +		for_each_plane(pipe, plane) {
> +			entry = &ddb->plane[pipe][plane];
> +			seq_printf(m, "  Plane%-8d%8u%8u%8u\n", plane + 1,
> +				   entry->start, entry->end,
> +				   skl_ddb_entry_size(entry));
> +		}
> +
> +		entry = &ddb->cursor[pipe];
> +		seq_printf(m, "  %-13s%8u%8u%8u\n", "Cursor", entry->start,
> +			   entry->end, skl_ddb_entry_size(entry));
> +	}
> +
> +	drm_modeset_unlock_all(dev);
> +
> +	return 0;
> +}
> +
>  struct pipe_crc_info {
>  	const char *name;
>  	struct drm_device *dev;
> @@ -4249,6 +4285,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
>  	{"i915_shared_dplls_info", i915_shared_dplls_info, 0},
>  	{"i915_dp_mst_info", i915_dp_mst_info, 0},
>  	{"i915_wa_registers", i915_wa_registers, 0},
> +	{"i915_ddb_info", i915_ddb_info, 0},
>  };
>  #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
>  
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 81/89] drm/i915/skl: Expose skl_ddb_get_hw_state()
  2014-10-29 19:21   ` Ville Syrjälä
@ 2014-10-29 23:49     ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-10-29 23:49 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Wed, Oct 29, 2014 at 09:21:20PM +0200, Ville Syrjälä wrote:
> On Thu, Sep 04, 2014 at 12:27:47PM +0100, Damien Lespiau wrote:
> > So we can use it in the modeset checker.
> > 
> > v2: Rebase on top of nigthly
> > 
> > v3: Rebase on top of -nigthly (minor conflict in intel_drv.h)
> > 
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> 
> I don't know if I should even bother with the r-b. Feel free to slap
> one on if you want :)

I do feel dirty, this patch was before we agreed it wasn't a necessity
to split those kind of changes, but put them along with the patch using
them.

Will fold into the right patch if I remember it.

-- 
Damien
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 50/89] drm/i915/skl: Read the pipe WM HW state
  2014-10-29 19:02   ` Ville Syrjälä
@ 2014-10-30 12:03     ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-10-30 12:03 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Wed, Oct 29, 2014 at 09:02:58PM +0200, Ville Syrjälä wrote:
> Am I imagining it or could this function be reduced to four lines if you
> would just pass the target struct as a parameter instead of the
> (is_transwm,is_cursor,i,level) tuple? Ah no, crap, SoA strikes back. So I
> think I mentioned it already during my first round of reviews that I'd
> like make a bunch of this stuff AoS instead. But that's a recipe for
> massive conflicts so let's get the current stuff in first before we go
> tearing into those structures.

I have to concur, it looks ugly. I also like the pragmatic r-b + list of
improvements, thanks or that. We even have a Jira task for the rework
now, things need to settle down a bit before I can address this (or we
find someone else to do it).

-- 
Damien
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* [PATCH 55/59 v4] drm/i915/skl: Gen9 multi-engine forcewake
  2014-09-25  7:32       ` Mika Kuoppala
@ 2014-11-03 17:09         ` Damien Lespiau
  2014-11-19 13:25           ` Mika Kuoppala
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-11-03 17:09 UTC (permalink / raw)
  To: intel-gfx

From: Zhe Wang <zhe1.wang@intel.com>

Enable multi-engine forcewake for Gen9.

v2: (Damien)
- Rebase on top of nightly
- Move the register range definitions to intel_uncore.c
- Whitespace fixes

v3: (Addressing Mika's comment, done by Damien)
- Use REG_RANGE() (introduced after the patch was written)
- Add a SKL_NEEDS_FORCE_WAKE() macro that gets rid of a useless
  comparison to FORCEWAKE (reg 0xa18c is not used on SKL)

v4: (Damien)
- Use newly introduced ASSIGN_READ/WRITE_MMIO_VFUNCS() macros

Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_uncore.c | 115 ++++++++++++++++++++++++++++++++++++
 1 file changed, 115 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 68e722b..8ce56f6 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -678,6 +678,34 @@ void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
 	 REG_RANGE((reg), 0x14000, 0x14400) || \
 	 REG_RANGE((reg), 0x22000, 0x24000))
 
+#define FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) \
+	REG_RANGE((reg), 0xC00,  0x2000)
+
+#define FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) \
+	(REG_RANGE((reg), 0x2000, 0x4000) || \
+	 REG_RANGE((reg), 0x5200, 0x8000) || \
+	 REG_RANGE((reg), 0x8300, 0x8500) || \
+	 REG_RANGE((reg), 0x8C00, 0x8D00) || \
+	 REG_RANGE((reg), 0xB000, 0xB480) || \
+	 REG_RANGE((reg), 0xE000, 0xE800))
+
+#define FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) \
+	(REG_RANGE((reg), 0x8800, 0x8A00) || \
+	 REG_RANGE((reg), 0xD000, 0xD800) || \
+	 REG_RANGE((reg), 0x12000, 0x14000) || \
+	 REG_RANGE((reg), 0x1A000, 0x1EA00) || \
+	 REG_RANGE((reg), 0x30000, 0x40000))
+
+#define FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg) \
+	REG_RANGE((reg), 0x9400, 0x9800)
+
+#define FORCEWAKE_GEN9_BLITTER_RANGE_OFFSET(reg) \
+	((reg) < 0x40000 &&\
+	 !FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) && \
+	 !FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) && \
+	 !FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) && \
+	 !FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg))
+
 static void
 ilk_dummy_write(struct drm_i915_private *dev_priv)
 {
@@ -808,6 +836,45 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
 	REG_READ_FOOTER; \
 }
 
+#define SKL_NEEDS_FORCE_WAKE(dev_priv, reg)	\
+	 ((reg) < 0x40000 && !FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg))
+
+#define __gen9_read(x) \
+static u##x \
+gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
+	REG_READ_HEADER(x); \
+	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
+		val = __raw_i915_read##x(dev_priv, reg); \
+	} else { \
+		unsigned fwengine = 0; \
+		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
+			if (dev_priv->uncore.fw_rendercount == 0) \
+				fwengine = FORCEWAKE_RENDER; \
+		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
+			if (dev_priv->uncore.fw_mediacount == 0) \
+				fwengine = FORCEWAKE_MEDIA; \
+		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
+			if (dev_priv->uncore.fw_rendercount == 0) \
+				fwengine |= FORCEWAKE_RENDER; \
+			if (dev_priv->uncore.fw_mediacount == 0) \
+				fwengine |= FORCEWAKE_MEDIA; \
+		} else { \
+			if (dev_priv->uncore.fw_blittercount == 0) \
+				fwengine = FORCEWAKE_BLITTER; \
+		} \
+		if (fwengine) \
+			dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
+		val = __raw_i915_read##x(dev_priv, reg); \
+		if (fwengine) \
+			dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
+	} \
+	REG_READ_FOOTER; \
+}
+
+__gen9_read(8)
+__gen9_read(16)
+__gen9_read(32)
+__gen9_read(64)
 __chv_read(8)
 __chv_read(16)
 __chv_read(32)
@@ -829,6 +896,7 @@ __gen4_read(16)
 __gen4_read(32)
 __gen4_read(64)
 
+#undef __gen9_read
 #undef __chv_read
 #undef __vlv_read
 #undef __gen6_read
@@ -966,6 +1034,45 @@ chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
 	REG_WRITE_FOOTER; \
 }
 
+#define __gen9_write(x) \
+static void \
+gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
+		bool trace) { \
+	REG_WRITE_HEADER; \
+	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
+		__raw_i915_write##x(dev_priv, reg, val); \
+	} else { \
+		unsigned fwengine = 0; \
+		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
+			if (dev_priv->uncore.fw_rendercount == 0) \
+				fwengine = FORCEWAKE_RENDER; \
+		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
+			if (dev_priv->uncore.fw_mediacount == 0) \
+				fwengine = FORCEWAKE_MEDIA; \
+		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
+			if (dev_priv->uncore.fw_rendercount == 0) \
+				fwengine |= FORCEWAKE_RENDER; \
+			if (dev_priv->uncore.fw_mediacount == 0) \
+				fwengine |= FORCEWAKE_MEDIA; \
+		} else { \
+			if (dev_priv->uncore.fw_blittercount == 0) \
+				fwengine = FORCEWAKE_BLITTER; \
+		} \
+		if (fwengine) \
+			dev_priv->uncore.funcs.force_wake_get(dev_priv, \
+					fwengine); \
+		__raw_i915_write##x(dev_priv, reg, val); \
+		if (fwengine) \
+			dev_priv->uncore.funcs.force_wake_put(dev_priv, \
+					fwengine); \
+	} \
+	REG_WRITE_FOOTER; \
+}
+
+__gen9_write(8)
+__gen9_write(16)
+__gen9_write(32)
+__gen9_write(64)
 __chv_write(8)
 __chv_write(16)
 __chv_write(32)
@@ -991,6 +1098,7 @@ __gen4_write(16)
 __gen4_write(32)
 __gen4_write(64)
 
+#undef __gen9_write
 #undef __chv_write
 #undef __gen8_write
 #undef __hsw_write
@@ -1074,6 +1182,13 @@ void intel_uncore_init(struct drm_device *dev)
 
 	switch (INTEL_INFO(dev)->gen) {
 	default:
+		WARN_ON(1);
+		return;
+	case 9:
+		ASSIGN_WRITE_MMIO_VFUNCS(gen9);
+		ASSIGN_READ_MMIO_VFUNCS(gen9);
+		break;
+	case 8:
 		if (IS_CHERRYVIEW(dev)) {
 			ASSIGN_WRITE_MMIO_VFUNCS(chv);
 			ASSIGN_READ_MMIO_VFUNCS(chv);
-- 
1.8.3.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 56/89 v4] drm/i915: Gen9 shadowed registers
  2014-09-25  8:58       ` Mika Kuoppala
@ 2014-11-03 17:45         ` Damien Lespiau
  2014-11-19 13:25           ` Mika Kuoppala
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-11-03 17:45 UTC (permalink / raw)
  To: intel-gfx

From: Zhe Wang <zhe1.wang@intel.com>

For MMIO registers which are shadowed, force wake is not needed to
write to these registers.

v2: Rebase on top of nightly (Damien)

v3: Rebase on top of "Gen9 multiple-engine forcewake" changes

v4: (Mika, Bob, done by Damien)
- Reorder the shadowed registers by popularity

Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_uncore.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 8ce56f6..4b46976 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -1034,12 +1034,36 @@ chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
 	REG_WRITE_FOOTER; \
 }
 
+static const u32 gen9_shadowed_regs[] = {
+	RING_TAIL(RENDER_RING_BASE),
+	RING_TAIL(GEN6_BSD_RING_BASE),
+	RING_TAIL(VEBOX_RING_BASE),
+	RING_TAIL(BLT_RING_BASE),
+	FORCEWAKE_BLITTER_GEN9,
+	FORCEWAKE_RENDER_GEN9,
+	FORCEWAKE_MEDIA_GEN9,
+	GEN6_RPNSWREQ,
+	GEN6_RC_VIDEO_FREQ,
+	/* TODO: Other registers are not yet used */
+};
+
+static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(gen9_shadowed_regs); i++)
+		if (reg == gen9_shadowed_regs[i])
+			return true;
+
+	return false;
+}
+
 #define __gen9_write(x) \
 static void \
 gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
 		bool trace) { \
 	REG_WRITE_HEADER; \
-	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
+	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
+			is_gen9_shadowed(dev_priv, reg)) { \
 		__raw_i915_write##x(dev_priv, reg, val); \
 	} else { \
 		unsigned fwengine = 0; \
-- 
1.8.3.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 58/89 v5] drm/i915/skl: Register definitions for SKL Clocks
  2014-09-22 18:17   ` Paulo Zanoni
  2014-10-01 10:51     ` M, Satheeshakrishna
@ 2014-11-04 16:11     ` Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-11-04 16:11 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

This patch defines the necessary SKL registers for implementing the
new clocking mechanism.

v2: Addressed review comments by Damien
	- Added code comment
	- Introduced enum for WRPLL values

v3: Rebase on top of nightly (minor conflict in i915_reg.h)

v4: Use 0x, not 0X (Ville)

v5: Modified as per review comments from Paulo

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v2)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v3,v4)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h | 72 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 15f227b..eb35d05 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6434,6 +6434,78 @@ enum punit_power_well {
 #define  LCPLL_CD_SOURCE_FCLK		(1<<21)
 #define  LCPLL_CD_SOURCE_FCLK_DONE	(1<<19)
 
+/*
+ * SKL Clocks
+ */
+
+/* CDCLK_CTL */
+#define CDCLK_CTL			0x46000
+#define  CDCLK_FREQ_SEL_MASK		(3<<26)
+#define  CDCLK_FREQ_450_432		(0<<26)
+#define  CDCLK_FREQ_540			(1<<26)
+#define  CDCLK_FREQ_337_308		(2<<26)
+#define  CDCLK_FREQ_675_617		(3<<26)
+#define  CDCLK_FREQ_DECIMAL_MASK	(0x7ff)
+
+/* LCPLL_CTL */
+#define LCPLL1_CTL		0x46010
+#define LCPLL2_CTL		0x46014
+#define  LCPLL_PLL_ENABLE	(1<<31)
+
+/* DPLL control1 */
+#define DPLL_CTRL1		0x6C058
+#define  DPLL_CTRL1_HDMI_MODE(id)		(1<<((id)*6+5))
+#define  DPLL_CTRL1_SSC(id)			(1<<((id)*6+4))
+#define  DPLL_CRTL1_LINK_RATE_MASK(id)		(7<<((id)*6+1))
+#define  DPLL_CRTL1_LINK_RATE(linkrate, id)	((linkrate)<<((id)*6+1))
+#define  DPLL_CTRL1_OVERRIDE(id)		(1<<((id)*6))
+#define  DPLL_CRTL1_LINK_RATE_2700		0
+#define  DPLL_CRTL1_LINK_RATE_1350		1
+#define  DPLL_CRTL1_LINK_RATE_810		2
+#define  DPLL_CRTL1_LINK_RATE_1620		3
+#define  DPLL_CRTL1_LINK_RATE_1080		4
+#define  DPLL_CRTL1_LINK_RATE_2160		5
+
+/* DPLL control2 */
+#define DPLL_CTRL2				0x6C05C
+#define  DPLL_CTRL2_DDI_CLK_OFF(port)		(1<<(port+15))
+#define  DPLL_CTRL2_DDI_CLK_SEL_MASK(port)	(3<<((port)*3+1))
+#define  DPLL_CTRL2_DDI_CLK_SEL(clk, port)	(clk<<((port)*3+1))
+#define  DPLL_CTRL2_DDI_SEL_OVERRIDE(port)     (1<<((port)*3))
+
+/* DPLL Status */
+#define DPLL_STATUS	0x6C060
+#define  DPLL_LOCK(id) (1<<((id)*8))
+
+/* DPLL cfg */
+#define DPLL1_CFGCR1	0x6C040
+#define DPLL2_CFGCR1	0x6C048
+#define DPLL3_CFGCR1	0x6C050
+#define  DPLL_CFGCR1_FREQ_ENABLE	(1<<31)
+#define  DPLL_CFGCR1_DCO_FRACTION_MASK	(0x7fff<<9)
+#define  DPLL_CFGCR1_DCO_FRACTION(x)	(x<<9)
+#define  DPLL_CFGCR1_DCO_INTEGER_MASK	(0x1ff)
+
+#define DPLL1_CFGCR2	0x6C044
+#define DPLL2_CFGCR2	0x6C04C
+#define DPLL3_CFGCR2	0x6C054
+#define  DPLL_CFGCR2_QDIV_RATIO_MASK	(0xff<<8)
+#define  DPLL_CFGCR2_QDIV_RATIO(x)	(x<<8)
+#define  DPLL_CFGCR2_QDIV_MODE(x)	(x<<7)
+#define  DPLL_CFGCR2_KDIV_MASK		(3<<5)
+#define  DPLL_CFGCR2_KDIV(x)		(x<<5)
+#define  DPLL_CFGCR2_KDIV_5 (0<<5)
+#define  DPLL_CFGCR2_KDIV_2 (1<<5)
+#define  DPLL_CFGCR2_KDIV_3 (2<<5)
+#define  DPLL_CFGCR2_KDIV_1 (3<<5)
+#define  DPLL_CFGCR2_PDIV_MASK		(7<<2)
+#define  DPLL_CFGCR2_PDIV(x)		(x<<2)
+#define  DPLL_CFGCR2_PDIV_1 (0<<2)
+#define  DPLL_CFGCR2_PDIV_2 (1<<2)
+#define  DPLL_CFGCR2_PDIV_3 (2<<2)
+#define  DPLL_CFGCR2_PDIV_7 (4<<2)
+#define  DPLL_CFGCR2_CENTRAL_FREQ_MASK	(3)
+
 /* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register,
  * since on HSW we can't write to it using I915_WRITE. */
 #define D_COMP_HSW			(MCHBAR_MIRROR_BASE_SNB + 0x5F0C)
-- 
1.8.3.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* Re: [PATCH 59/89] drm/i915/skl: Structure/enum definitions for SKL clocks
  2014-09-22 18:25   ` Paulo Zanoni
@ 2014-11-04 16:12     ` Damien Lespiau
  2014-11-05  9:11       ` Daniel Vetter
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-11-04 16:12 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: Intel Graphics Development

On Mon, Sep 22, 2014 at 03:25:30PM -0300, Paulo Zanoni wrote:
> 2014-09-04 8:27 GMT-03:00 Damien Lespiau <damien.lespiau@intel.com>:
> > From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
> >
> > Adding structure/enum for SKL clocking implementation.
> >
> > v2: Addressed Damien's comment
> >         - Removed internal structure from this header file
> >
> > v3: Stove this into the generic intel_dpll_id enum and give them the established
> > DPLL_ID_ prefixes. (Daniel)
> >
> > v4: - We'll only try to share DPLL1/2/3, leaving DPLL0 to eDP
> >     - Use SKL in the skylake shared DPLL names
> >     - Re-add the skl_dpll enum
> >     (Damien)
> >
> > v5: Remove SKL_DPLL_NONE (Daniel)
> >
> > Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v2)
> > Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v4,v5)
> > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v3)
> 
> The changes contained on this patch should be part of another patch. I
> can't really review this if I don't know how those things, especially
> enum skl_dpll are going to be used. And it also makes the lives of
> backporters harder.
> 
> Also, I guess that a patch with 3 signed-off-by stamps shouldn't
> really need an additional reviewed-by stamp, right? So maybe this
> should just be merged.

Well, I can add my r-b tag here, why not.

Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>

-- 
Damien
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* [PATCH 60/89 v5] drm/i915/skl: CD clock back calculation for SKL
  2014-09-22 19:19   ` Paulo Zanoni
  2014-10-01 10:51     ` M, Satheeshakrishna
@ 2014-11-04 16:15     ` Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-11-04 16:15 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

Determine programmed cd clock for SKL.

v2: Fix the LCPLL1 enable warning logic

v3: Rebase over the hsw pll rework.

v4: Rebase on top of the per-platform split (Damien)

v5: Modified as per review comments from Paulo

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 75 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 66 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index a49f454..72691ec 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1276,6 +1276,54 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
 	}
 }
 
+static int skl_get_cdclk_freq(struct drm_i915_private *dev_priv)
+{
+	uint32_t lcpll1 = I915_READ(LCPLL1_CTL);
+	uint32_t cdctl = I915_READ(CDCLK_CTL);
+	uint32_t linkrate;
+
+	if (!(lcpll1 & LCPLL_PLL_ENABLE)) {
+		WARN(1, "LCPLL1 not enabled\n");
+		return 24000; /* 24MHz is the cd freq with NSSC ref */
+	}
+
+	if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540)
+		return 540000;
+
+	linkrate = (I915_READ(DPLL_CTRL1) &
+		    DPLL_CRTL1_LINK_RATE_MASK(SKL_DPLL0)) >> 1;
+
+	if (linkrate == DPLL_CRTL1_LINK_RATE_2160 ||
+	    linkrate == DPLL_CRTL1_LINK_RATE_1080) {
+		/* vco 8640 */
+		switch (cdctl & CDCLK_FREQ_SEL_MASK) {
+		case CDCLK_FREQ_450_432:
+			return 432000;
+		case CDCLK_FREQ_337_308:
+			return 308570;
+		case CDCLK_FREQ_675_617:
+			return 617140;
+		default:
+			WARN(1, "Unknown cd freq selection\n");
+		}
+	} else {
+		/* vco 8100 */
+		switch (cdctl & CDCLK_FREQ_SEL_MASK) {
+		case CDCLK_FREQ_450_432:
+			return 450000;
+		case CDCLK_FREQ_337_308:
+			return 337500;
+		case CDCLK_FREQ_675_617:
+			return 675000;
+		default:
+			WARN(1, "Unknown cd freq selection\n");
+		}
+	}
+
+	/* error case, do as if DPLL0 isn't enabled */
+	return 24000;
+}
+
 static int bdw_get_cdclk_freq(struct drm_i915_private *dev_priv)
 {
 	uint32_t lcpll = I915_READ(LCPLL_CTL);
@@ -1317,6 +1365,9 @@ int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
 {
 	struct drm_device *dev = dev_priv->dev;
 
+	if (IS_SKYLAKE(dev))
+		return skl_get_cdclk_freq(dev_priv);
+
 	if (IS_BROADWELL(dev))
 		return bdw_get_cdclk_freq(dev_priv);
 
@@ -1385,19 +1436,25 @@ void intel_ddi_pll_init(struct drm_device *dev)
 
 	hsw_shared_dplls_init(dev_priv);
 
-	/* The LCPLL register should be turned on by the BIOS. For now let's
-	 * just check its state and print errors in case something is wrong.
-	 * Don't even try to turn it on.
-	 */
-
 	DRM_DEBUG_KMS("CDCLK running at %dKHz\n",
 		      intel_ddi_get_cdclk_freq(dev_priv));
 
-	if (val & LCPLL_CD_SOURCE_FCLK)
-		DRM_ERROR("CDCLK source is not LCPLL\n");
+	if (IS_SKYLAKE(dev)) {
+		if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
+			DRM_ERROR("LCPLL1 is disabled\n");
+	} else {
+		/*
+		 * The LCPLL register should be turned on by the BIOS. For now
+		 * let's just check its state and print errors in case
+		 * something is wrong.  Don't even try to turn it on.
+		 */
+
+		if (val & LCPLL_CD_SOURCE_FCLK)
+			DRM_ERROR("CDCLK source is not LCPLL\n");
 
-	if (val & LCPLL_PLL_DISABLE)
-		DRM_ERROR("LCPLL is disabled\n");
+		if (val & LCPLL_PLL_DISABLE)
+			DRM_ERROR("LCPLL is disabled\n");
+	}
 }
 
 void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
-- 
1.8.3.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 61/89 v4] drm/i915/skl: Determine enabled PLL and its linkrate/pixel clock
  2014-09-22 20:12   ` Paulo Zanoni
  2014-10-01 10:51     ` M, Satheeshakrishna
@ 2014-11-04 16:17     ` Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-11-04 16:17 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

v2: Fixup compilation due to the removal of the intel_ddi_dpll_id enum.
And add a fixme about the abuse of pipe_config here.

v3: Rebase on top of the hsw_ddi_clock_get() rename (Damien)

v4: Modified as per review comments from Paulo

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v1)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v3)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v2)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h  |   5 ++
 drivers/gpu/drm/i915/intel_ddi.c | 115 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 119 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index eb35d05..3ef0312 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6457,6 +6457,7 @@ enum punit_power_well {
 #define  DPLL_CTRL1_HDMI_MODE(id)		(1<<((id)*6+5))
 #define  DPLL_CTRL1_SSC(id)			(1<<((id)*6+4))
 #define  DPLL_CRTL1_LINK_RATE_MASK(id)		(7<<((id)*6+1))
+#define  DPLL_CRTL1_LINK_RATE_SHIFT(id)		((id)*6+1)
 #define  DPLL_CRTL1_LINK_RATE(linkrate, id)	((linkrate)<<((id)*6+1))
 #define  DPLL_CTRL1_OVERRIDE(id)		(1<<((id)*6))
 #define  DPLL_CRTL1_LINK_RATE_2700		0
@@ -6470,6 +6471,7 @@ enum punit_power_well {
 #define DPLL_CTRL2				0x6C05C
 #define  DPLL_CTRL2_DDI_CLK_OFF(port)		(1<<(port+15))
 #define  DPLL_CTRL2_DDI_CLK_SEL_MASK(port)	(3<<((port)*3+1))
+#define  DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port)    ((port)*3+1)
 #define  DPLL_CTRL2_DDI_CLK_SEL(clk, port)	(clk<<((port)*3+1))
 #define  DPLL_CTRL2_DDI_SEL_OVERRIDE(port)     (1<<((port)*3))
 
@@ -6506,6 +6508,9 @@ enum punit_power_well {
 #define  DPLL_CFGCR2_PDIV_7 (4<<2)
 #define  DPLL_CFGCR2_CENTRAL_FREQ_MASK	(3)
 
+#define GET_CFG_CR1_REG(id) (DPLL1_CFGCR1 + (id - SKL_DPLL1) * 8)
+#define GET_CFG_CR2_REG(id) (DPLL1_CFGCR2 + (id - SKL_DPLL1) * 8)
+
 /* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register,
  * since on HSW we can't write to it using I915_WRITE. */
 #define D_COMP_HSW			(MCHBAR_MIRROR_BASE_SNB + 0x5F0C)
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 72691ec..f5dd4d3 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -687,6 +687,115 @@ static int intel_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
 	return (refclk * n * 100) / (p * r);
 }
 
+static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
+			       uint32_t dpll)
+{
+	uint32_t cfgcr1_reg, cfgcr2_reg;
+	uint32_t cfgcr1_val, cfgcr2_val;
+	uint32_t p0, p1, p2, dco_freq;
+
+	cfgcr1_reg = GET_CFG_CR1_REG(dpll);
+	cfgcr2_reg = GET_CFG_CR2_REG(dpll);
+
+	cfgcr1_val = I915_READ(cfgcr1_reg);
+	cfgcr2_val = I915_READ(cfgcr2_reg);
+
+	p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
+	p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
+
+	if (cfgcr2_val &  DPLL_CFGCR2_QDIV_MODE(1))
+		p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
+	else
+		p1 = 1;
+
+
+	switch (p0) {
+	case DPLL_CFGCR2_PDIV_1:
+		p0 = 1;
+		break;
+	case DPLL_CFGCR2_PDIV_2:
+		p0 = 2;
+		break;
+	case DPLL_CFGCR2_PDIV_3:
+		p0 = 3;
+		break;
+	case DPLL_CFGCR2_PDIV_7:
+		p0 = 7;
+		break;
+	}
+
+	switch (p2) {
+	case DPLL_CFGCR2_KDIV_5:
+		p2 = 5;
+		break;
+	case DPLL_CFGCR2_KDIV_2:
+		p2 = 2;
+		break;
+	case DPLL_CFGCR2_KDIV_3:
+		p2 = 3;
+		break;
+	case DPLL_CFGCR2_KDIV_1:
+		p2 = 1;
+		break;
+	}
+
+	dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
+
+	dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
+		1000) / 0x8000;
+
+	return dco_freq / (p0 * p1 * p2 * 5);
+}
+
+
+static void skl_ddi_clock_get(struct intel_encoder *encoder,
+				struct intel_crtc_config *pipe_config)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	enum port port = intel_ddi_get_encoder_port(encoder);
+	int link_clock = 0;
+	uint32_t dpll_ctl1, dpll;
+
+	/* FIXME: This should be tracked in the pipe config. */
+	dpll = I915_READ(DPLL_CTRL2);
+	dpll &= DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
+	dpll >>= DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port);
+
+	dpll_ctl1 = I915_READ(DPLL_CTRL1);
+
+	if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
+		link_clock = skl_calc_wrpll_link(dev_priv, dpll);
+	} else {
+		link_clock = dpll_ctl1 & DPLL_CRTL1_LINK_RATE_MASK(dpll);
+		link_clock >>= DPLL_CRTL1_LINK_RATE_SHIFT(dpll);
+
+		switch (link_clock) {
+		case DPLL_CRTL1_LINK_RATE_810:
+			link_clock = 81000;
+			break;
+		case DPLL_CRTL1_LINK_RATE_1350:
+			link_clock = 135000;
+			break;
+		case DPLL_CRTL1_LINK_RATE_2700:
+			link_clock = 270000;
+			break;
+		default:
+			WARN(1, "Unsupported link rate\n");
+			break;
+		}
+		link_clock *= 2;
+	}
+
+	pipe_config->port_clock = link_clock;
+
+	if (pipe_config->has_dp_encoder)
+		pipe_config->adjusted_mode.crtc_clock =
+			intel_dotclock_calculate(pipe_config->port_clock,
+						 &pipe_config->dp_m_n);
+	else
+		pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock;
+}
+
 static void hsw_ddi_clock_get(struct intel_encoder *encoder,
 			      struct intel_crtc_config *pipe_config)
 {
@@ -1550,6 +1659,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
 	enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
 	u32 temp, flags = 0;
+	struct drm_device *dev = dev_priv->dev;
 
 	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
 	if (temp & TRANS_DDI_PHSYNC)
@@ -1621,7 +1731,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 		dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
 	}
 
-	hsw_ddi_clock_get(encoder, pipe_config);
+	if (INTEL_INFO(dev)->gen <= 8)
+		hsw_ddi_clock_get(encoder, pipe_config);
+	else
+		skl_ddi_clock_get(encoder, pipe_config);
 }
 
 static void intel_ddi_destroy(struct drm_encoder *encoder)
-- 
1.8.3.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 62/89 v3] drm/i915/skl: Query DPLL attached to port on SKL
  2014-09-22 20:24   ` Paulo Zanoni
  2014-10-01 10:51     ` M, Satheeshakrishna
@ 2014-11-04 16:19     ` Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-11-04 16:19 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

Modify the implementation to query DPLL attached to a SKL port.

v2: Rebase on top of the run-time PM on DPMS series (Damien)

v3: Modified as per review comments from Paulo

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 29 ++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_drv.h     |  5 ++++-
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9ec1ab7..72ee814 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7968,6 +7968,30 @@ static int haswell_crtc_compute_clock(struct intel_crtc *crtc)
 	return 0;
 }
 
+static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv,
+				enum port port,
+				struct intel_crtc_config *pipe_config)
+{
+	u32 temp;
+
+	temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
+	pipe_config->ddi_pll_sel = temp >> (port * 3 + 1);
+
+	switch (pipe_config->ddi_pll_sel) {
+	case SKL_DPLL1:
+		pipe_config->shared_dpll = DPLL_ID_SKL_DPLL1;
+		break;
+	case SKL_DPLL2:
+		pipe_config->shared_dpll = DPLL_ID_SKL_DPLL2;
+		break;
+	case SKL_DPLL3:
+		pipe_config->shared_dpll = DPLL_ID_SKL_DPLL3;
+		break;
+	default:
+		WARN(1, "Unknown DPLL programmed\n");
+	}
+}
+
 static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
 				enum port port,
 				struct intel_crtc_config *pipe_config)
@@ -7997,7 +8021,10 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
 
 	port = (tmp & TRANS_DDI_PORT_MASK) >> TRANS_DDI_PORT_SHIFT;
 
-	haswell_get_ddi_pll(dev_priv, port, pipe_config);
+	if (IS_SKYLAKE(dev))
+		skylake_get_ddi_pll(dev_priv, port, pipe_config);
+	else
+		haswell_get_ddi_pll(dev_priv, port, pipe_config);
 
 	if (pipe_config->shared_dpll >= 0) {
 		pll = &dev_priv->shared_dplls[pipe_config->shared_dpll];
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index cb0e9db..ece8b82 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -340,7 +340,10 @@ struct intel_crtc_config {
 	/* Selected dpll when shared or DPLL_ID_PRIVATE. */
 	enum intel_dpll_id shared_dpll;
 
-	/* PORT_CLK_SEL for DDI ports. */
+	/*
+	 * - PORT_CLK_SEL for DDI ports on HSW/BDW.
+	 * - enum skl_dpll on SKL
+	 */
 	uint32_t ddi_pll_sel;
 
 	/* Actual register state of the dpll, for shared dpll cross-checking. */
-- 
1.8.3.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* [PATCH 66/89 v9] drm/i915/skl: Implementation of SKL DPLL programming
  2014-09-23 18:05   ` Paulo Zanoni
  2014-10-01 10:52     ` M, Satheeshakrishna
@ 2014-11-04 16:26     ` Damien Lespiau
  2014-11-07 19:56       ` Paulo Zanoni
  1 sibling, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-11-04 16:26 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

This patch implements SKL DPLL programming that includes:
        - DPLL allocation
        - wide range PLL calculation and programming
        - DP link rate programming
        - DDI to DPLL mapping

v2: Incorporated following changes
        - Added vfunc for function required outside
        - Fixed multiple comments in WRPLL calculation

v3: - Fix the DCO computation
    - Move the initialization up to not clobber the computed values
    - Use the correct macro for DP link rate programming.
    - Use wait_for() to wait for the PLL locked bit

v4: Rebase on top of nigthly (Damien)

v5: A few code cleanups in the WRPLL computation (Damien)
    - Use uint32_t when possible
    - Use abs_diff() in the WRPLL computation
    - Make the 64bits divisions use div64_u64()
    - Fix typo in dco_central_feq_deviation (freq)
    - Replace the chain of breaks with a goto

v6: Port of the patch to work on top of the shared DPLLs (Damien)
v7: Don't try to handle eDP in ddi_pll_select() (Damien)
v8: Modified as per review comments from Paulo (Satheesh)
v9: Rebase on top of Ander's clock computation staging work for atomic (Damien)

Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v3)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 226 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 225 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index e8cdc1a..9e1f4b2 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -954,6 +954,226 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
 	return true;
 }
 
+struct skl_wrpll_params {
+	uint32_t        dco_fraction;
+	uint32_t        dco_integer;
+	uint32_t        qdiv_ratio;
+	uint32_t        qdiv_mode;
+	uint32_t        kdiv;
+	uint32_t        pdiv;
+	uint32_t        central_freq;
+};
+
+static void
+skl_ddi_calculate_wrpll(int clock /* in Hz */,
+			struct skl_wrpll_params *wrpll_params)
+{
+	uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
+	uint64_t dco_central_freq[3] = {8400000000, 9000000000, 9600000000};
+	uint32_t min_dco_deviation = 400;
+	uint32_t min_dco_index = 3;
+	uint32_t P0[4] = {1, 2, 3, 7};
+	uint32_t P2[4] = {1, 2, 3, 5};
+	bool found = false;
+	uint32_t candidate_p = 0;
+	uint32_t candidate_p0[3] = {0}, candidate_p1[3] = {0};
+	uint32_t candidate_p2[3] = {0};
+	uint32_t dco_central_freq_deviation[3];
+	uint32_t i, P1, k, dco_count;
+	bool retry_with_odd = false;
+	uint64_t dco_freq;
+
+	/* Determine P0, P1 or P2 */
+	for (dco_count = 0; dco_count < 3; dco_count++) {
+		found = false;
+		candidate_p =
+			div64_u64(dco_central_freq[dco_count], afe_clock);
+		if (retry_with_odd == false)
+			candidate_p = (candidate_p % 2 == 0 ?
+				candidate_p : candidate_p + 1);
+
+		for (P1 = 1; P1 < candidate_p; P1++) {
+			for (i = 0; i < 4; i++) {
+				if (!(P0[i] != 1 || P1 == 1))
+					continue;
+
+				for (k = 0; k < 4; k++) {
+					if (P1 != 1 && P2[k] != 2)
+						continue;
+
+					if (candidate_p == P0[i] * P1 * P2[k]) {
+						/* Found possible P0, P1, P2 */
+						found = true;
+						candidate_p0[dco_count] = P0[i];
+						candidate_p1[dco_count] = P1;
+						candidate_p2[dco_count] = P2[k];
+						goto found;
+					}
+
+				}
+			}
+		}
+
+found:
+		if (found) {
+			dco_central_freq_deviation[dco_count] =
+				div64_u64(10000 *
+					  abs_diff((candidate_p * afe_clock),
+						   dco_central_freq[dco_count]),
+					  dco_central_freq[dco_count]);
+
+			if (dco_central_freq_deviation[dco_count] <
+				min_dco_deviation) {
+				min_dco_deviation =
+					dco_central_freq_deviation[dco_count];
+				min_dco_index = dco_count;
+			}
+		}
+
+		if (min_dco_index > 2 && dco_count == 2) {
+			retry_with_odd = true;
+			dco_count = 0;
+		}
+	}
+
+	if (min_dco_index > 2) {
+		WARN(1, "No valid values found for the given pixel clock\n");
+	} else {
+		 wrpll_params->central_freq = dco_central_freq[min_dco_index];
+
+		 switch (dco_central_freq[min_dco_index]) {
+		 case 9600000000:
+			wrpll_params->central_freq = 0;
+			break;
+		 case 9000000000:
+			wrpll_params->central_freq = 1;
+			break;
+		 case 8400000000:
+			wrpll_params->central_freq = 3;
+		 }
+
+		 switch (candidate_p0[min_dco_index]) {
+		 case 1:
+			wrpll_params->pdiv = 0;
+			break;
+		 case 2:
+			wrpll_params->pdiv = 1;
+			break;
+		 case 3:
+			wrpll_params->pdiv = 2;
+			break;
+		 case 7:
+			wrpll_params->pdiv = 4;
+			break;
+		 default:
+			WARN(1, "Incorrect PDiv\n");
+		 }
+
+		 switch (candidate_p2[min_dco_index]) {
+		 case 5:
+			wrpll_params->kdiv = 0;
+			break;
+		 case 2:
+			wrpll_params->kdiv = 1;
+			break;
+		 case 3:
+			wrpll_params->kdiv = 2;
+			break;
+		 case 1:
+			wrpll_params->kdiv = 3;
+			break;
+		 default:
+			WARN(1, "Incorrect KDiv\n");
+		 }
+
+		 wrpll_params->qdiv_ratio = candidate_p1[min_dco_index];
+		 wrpll_params->qdiv_mode =
+			(wrpll_params->qdiv_ratio == 1) ? 0 : 1;
+
+		 dco_freq = candidate_p0[min_dco_index] *
+			 candidate_p1[min_dco_index] *
+			 candidate_p2[min_dco_index] * afe_clock;
+
+		/*
+		* Intermediate values are in Hz.
+		* Divide by MHz to match bsepc
+		*/
+		 wrpll_params->dco_integer = div_u64(dco_freq, (24 * MHz(1)));
+		 wrpll_params->dco_fraction =
+			 div_u64(((div_u64(dco_freq, 24) -
+				   wrpll_params->dco_integer * MHz(1)) * 0x8000), MHz(1));
+
+	}
+}
+
+
+static bool
+skl_ddi_pll_select(struct intel_crtc *intel_crtc,
+		   struct intel_encoder *intel_encoder,
+		   int clock)
+{
+	struct intel_shared_dpll *pll;
+	uint32_t ctrl1, cfgcr1, cfgcr2;
+
+	/*
+	 * See comment in intel_dpll_hw_state to understand why we always use 0
+	 * as the DPLL id in this function.
+	 */
+
+	ctrl1 = DPLL_CTRL1_OVERRIDE(0);
+
+	if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
+		struct skl_wrpll_params wrpll_params = { 0, };
+
+		ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
+
+		skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params);
+
+		cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
+			 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
+			 wrpll_params.dco_integer;
+
+		cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
+			 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
+			 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
+			 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
+			 wrpll_params.central_freq;
+	} else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
+		struct drm_encoder *encoder = &intel_encoder->base;
+		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+		switch (intel_dp->link_bw) {
+		case DP_LINK_BW_1_62:
+			ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_810, 0);
+			break;
+		case DP_LINK_BW_2_7:
+			ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_1350, 0);
+			break;
+		case DP_LINK_BW_5_4:
+			ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_2700, 0);
+			break;
+		}
+
+		cfgcr1 = cfgcr2 = 0;
+	} else /* eDP */
+		return true;
+
+	intel_crtc->new_config->dpll_hw_state.ctrl1 = ctrl1;
+	intel_crtc->new_config->dpll_hw_state.cfgcr1 = cfgcr1;
+	intel_crtc->new_config->dpll_hw_state.cfgcr2 = cfgcr2;
+
+	pll = intel_get_shared_dpll(intel_crtc);
+	if (pll == NULL) {
+		DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
+				 pipe_name(intel_crtc->pipe));
+		return false;
+	}
+
+	/* shared DPLL id 0 is DPLL 1 */
+	intel_crtc->new_config->ddi_pll_sel = pll->id + 1;
+
+	return true;
+}
 
 /*
  * Tries to find a *shared* PLL for the CRTC and store it in
@@ -964,11 +1184,15 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
  */
 bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
 {
+	struct drm_device *dev = intel_crtc->base.dev;
 	struct intel_encoder *intel_encoder =
 		intel_ddi_get_crtc_new_encoder(intel_crtc);
 	int clock = intel_crtc->new_config->port_clock;
 
-	return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock);
+	if (IS_SKYLAKE(dev))
+		return skl_ddi_pll_select(intel_crtc, intel_encoder, clock);
+	else
+		return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock);
 }
 
 void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
-- 
1.8.3.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* Re: [PATCH 59/89] drm/i915/skl: Structure/enum definitions for SKL clocks
  2014-11-04 16:12     ` Damien Lespiau
@ 2014-11-05  9:11       ` Daniel Vetter
  0 siblings, 0 replies; 286+ messages in thread
From: Daniel Vetter @ 2014-11-05  9:11 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

On Tue, Nov 04, 2014 at 04:12:47PM +0000, Damien Lespiau wrote:
> On Mon, Sep 22, 2014 at 03:25:30PM -0300, Paulo Zanoni wrote:
> > Also, I guess that a patch with 3 signed-off-by stamps shouldn't
> > really need an additional reviewed-by stamp, right? So maybe this
> > should just be merged.

The sob stamps are because of the rebases in -internal. I've made it
practice to not just augment the patch revision log, but also add my name
somewhere so that blame can be assigned. But that doesn't mean I've
actually reviewed the beast at all complete, just that I've made some
adaptions to make it work again on upstream.

For this case here where Damien completely rewrote the patch the self-r-b
is kinda pointless. So yeah even when the patch has been passed around a
lot (and for a long time) and don't think that's a good reason not to
throw review at it. Ofc this patch here is really simple ;-)

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* [PATCH 69/89 v5] drm/i915/skl: Adding power domains for AUX controllers
  2014-09-16 12:35   ` Imre Deak
  2014-09-18 13:56     ` Damien Lespiau
@ 2014-11-05 14:23     ` Damien Lespiau
  1 sibling, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-11-05 14:23 UTC (permalink / raw)
  To: intel-gfx

From: Satheeshakrishna M <satheeshakrishna.m@intel.com>

Adding new power doamins for AUX controllers

v2: Added new power domains in power_domain_str per Imre's comment

v3: Added AUX power domains to older platforms

v4: Rebase on top of POWER_DOMAIN_PLLS.

v5: Modified to address review comments from Imre

Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v3)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c     |  8 ++++++++
 drivers/gpu/drm/i915/i915_drv.h         |  4 ++++
 drivers/gpu/drm/i915/intel_runtime_pm.c | 15 +++++++++++++++
 3 files changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 319da61..5b0f324 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2290,6 +2290,14 @@ static const char *power_domain_str(enum intel_display_power_domain domain)
 		return "AUDIO";
 	case POWER_DOMAIN_PLLS:
 		return "PLLS";
+	case POWER_DOMAIN_AUX_A:
+		return "AUX_A";
+	case POWER_DOMAIN_AUX_B:
+		return "AUX_B";
+	case POWER_DOMAIN_AUX_C:
+		return "AUX_C";
+	case POWER_DOMAIN_AUX_D:
+		return "AUX_D";
 	case POWER_DOMAIN_INIT:
 		return "INIT";
 	default:
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6fdca4b..a4c776a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -143,6 +143,10 @@ enum intel_display_power_domain {
 	POWER_DOMAIN_VGA,
 	POWER_DOMAIN_AUDIO,
 	POWER_DOMAIN_PLLS,
+	POWER_DOMAIN_AUX_A,
+	POWER_DOMAIN_AUX_B,
+	POWER_DOMAIN_AUX_C,
+	POWER_DOMAIN_AUX_D,
 	POWER_DOMAIN_INIT,
 
 	POWER_DOMAIN_NUM,
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index dcbecff..e059cae 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -710,6 +710,10 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 	BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |		\
 	BIT(POWER_DOMAIN_PORT_CRT) |			\
 	BIT(POWER_DOMAIN_PLLS) |			\
+	BIT(POWER_DOMAIN_AUX_A) |			\
+	BIT(POWER_DOMAIN_AUX_B) |			\
+	BIT(POWER_DOMAIN_AUX_C) |			\
+	BIT(POWER_DOMAIN_AUX_D) |			\
 	BIT(POWER_DOMAIN_INIT))
 #define HSW_DISPLAY_POWER_DOMAINS (				\
 	(POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) |	\
@@ -731,24 +735,30 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |	\
 	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |	\
 	BIT(POWER_DOMAIN_PORT_CRT) |		\
+	BIT(POWER_DOMAIN_AUX_B) |		\
+	BIT(POWER_DOMAIN_AUX_C) |		\
 	BIT(POWER_DOMAIN_INIT))
 
 #define VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS (	\
 	BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |	\
 	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_B) |		\
 	BIT(POWER_DOMAIN_INIT))
 
 #define VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS (	\
 	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_B) |		\
 	BIT(POWER_DOMAIN_INIT))
 
 #define VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS (	\
 	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |	\
 	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_C) |		\
 	BIT(POWER_DOMAIN_INIT))
 
 #define VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS (	\
 	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_C) |		\
 	BIT(POWER_DOMAIN_INIT))
 
 #define CHV_PIPE_A_POWER_DOMAINS (	\
@@ -768,20 +778,25 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 	BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |	\
 	BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |	\
 	BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_B) |		\
+	BIT(POWER_DOMAIN_AUX_C) |		\
 	BIT(POWER_DOMAIN_INIT))
 
 #define CHV_DPIO_CMN_D_POWER_DOMAINS (		\
 	BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) |	\
 	BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_D) |		\
 	BIT(POWER_DOMAIN_INIT))
 
 #define CHV_DPIO_TX_D_LANES_01_POWER_DOMAINS (	\
 	BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) |	\
 	BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_D) |		\
 	BIT(POWER_DOMAIN_INIT))
 
 #define CHV_DPIO_TX_D_LANES_23_POWER_DOMAINS (	\
 	BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |	\
+	BIT(POWER_DOMAIN_AUX_D) |		\
 	BIT(POWER_DOMAIN_INIT))
 
 static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
-- 
1.8.3.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 286+ messages in thread

* Re: [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction
  2014-09-16 13:19   ` Imre Deak
  2014-09-16 16:13     ` Daniel Vetter
@ 2014-11-07 12:08     ` Damien Lespiau
  2014-11-10 19:21       ` Imre Deak
  2014-11-07 13:11     ` Damien Lespiau
  2 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-11-07 12:08 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

On Tue, Sep 16, 2014 at 04:19:07PM +0300, Imre Deak wrote:
> > @@ -1233,6 +1233,9 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp)
> >  	power_domain = intel_display_port_power_domain(intel_encoder);
> >  	intel_display_power_get(dev_priv, power_domain);
> >  
> > +	power_domain = intel_display_aux_power_domain(intel_encoder);
> > +	intel_display_power_get(dev_priv, power_domain);
> > +
> 
> The AUX power domains were added to save power when only AUX
> functionality is needed, since then we don't need to power on the power
> domain needed for full port functionality.

Hum I'm not sure about this. It seems to me that the value of the AUX
power domain is to be able to shutdown the AUX hardware when AUX is not
needed. That's slightly different from what you're saying; The cases
where "only AUX functionality is needed" seem very transient to me,
while having the main lanes working and no need for AUX sounds like the
case where it's interesting to have the AUX hw powered down. Of course,
with PSR we can do both.

> With the above change and everywhere else below we'll end up enabling
> both power domains, though we only need AUX functionality.

If we're powering up the panel that's probably to use it very soon, so I
don't really see the value not powering the main lanes at the same time,
they are going to be used for training very soon? I'm probably missing
something.

> The power wells needed for AUX are a subset of those needed for full
> port functionality on all platforms (at least atm), so this patch won't
> change anything. The patch would make sense, if you requested only the
> AUX domains.

I think it's fine if this patch is not changing anything, at least for
now, until we get to use this power domain to good ends?

This patch still need the reworks you mentionned in the previous mail,
of course.

-- 
Damien
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction
  2014-09-16 13:19   ` Imre Deak
  2014-09-16 16:13     ` Daniel Vetter
  2014-11-07 12:08     ` Damien Lespiau
@ 2014-11-07 13:11     ` Damien Lespiau
  2014-11-07 13:31       ` Ville Syrjälä
  2 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-11-07 13:11 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

On Tue, Sep 16, 2014 at 04:19:07PM +0300, Imre Deak wrote:
> This patch needs to be rebased on the recent PPS changes at least
> getting/putting the AUX power domain in pps_lock()/pps_unlock() too.
> Also it should be squashed into 69/89. Some more comments below.

Hum, do we really need to hold a reference to the AUX power in
pps_lock(), it doesn't seem that the PPS hw should a specific dependency
on the AUX power domain. We might as well just get the "port" power
domain if that's enough.

-- 
Damien
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction
  2014-11-07 13:11     ` Damien Lespiau
@ 2014-11-07 13:31       ` Ville Syrjälä
  2014-11-07 13:49         ` Damien Lespiau
  0 siblings, 1 reply; 286+ messages in thread
From: Ville Syrjälä @ 2014-11-07 13:31 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Fri, Nov 07, 2014 at 01:11:13PM +0000, Damien Lespiau wrote:
> On Tue, Sep 16, 2014 at 04:19:07PM +0300, Imre Deak wrote:
> > This patch needs to be rebased on the recent PPS changes at least
> > getting/putting the AUX power domain in pps_lock()/pps_unlock() too.
> > Also it should be squashed into 69/89. Some more comments below.
> 
> Hum, do we really need to hold a reference to the AUX power in
> pps_lock(), it doesn't seem that the PPS hw should a specific dependency
> on the AUX power domain. We might as well just get the "port" power
> domain if that's enough.

pps_lock() doesn't *really* need any power domain references. The thing
is that the VLV/CHV display power well hooks need to reset the pps_pipe
assignment which means they should grab pps_mutex. However the vdd code
can grab power domain references while already holding pps_mutex, which
gets us into a neat locking inversion with the power domain mutex.

The workaround I did was to grab the power domain references always around
pps_mutex, so that we dodge the problem. A better solution would be to
never grab power domain references while already holding pps_mutex, but
I wasn't happy with how the code started to look when I tried that. But I
would welcome any efforts to make that happen since the current trick is
rather hackish. Also the code is now otherwise cleaner than what it was
when I tried to do that, so maybe it's easier now.

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction
  2014-11-07 13:31       ` Ville Syrjälä
@ 2014-11-07 13:49         ` Damien Lespiau
  2014-11-07 14:05           ` Ville Syrjälä
  0 siblings, 1 reply; 286+ messages in thread
From: Damien Lespiau @ 2014-11-07 13:49 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Fri, Nov 07, 2014 at 03:31:20PM +0200, Ville Syrjälä wrote:
> On Fri, Nov 07, 2014 at 01:11:13PM +0000, Damien Lespiau wrote:
> > On Tue, Sep 16, 2014 at 04:19:07PM +0300, Imre Deak wrote:
> > > This patch needs to be rebased on the recent PPS changes at least
> > > getting/putting the AUX power domain in pps_lock()/pps_unlock() too.
> > > Also it should be squashed into 69/89. Some more comments below.
> > 
> > Hum, do we really need to hold a reference to the AUX power in
> > pps_lock(), it doesn't seem that the PPS hw should a specific dependency
> > on the AUX power domain. We might as well just get the "port" power
> > domain if that's enough.
> 
> pps_lock() doesn't *really* need any power domain references. The thing
> is that the VLV/CHV display power well hooks need to reset the pps_pipe
> assignment which means they should grab pps_mutex. However the vdd code
> can grab power domain references while already holding pps_mutex, which
> gets us into a neat locking inversion with the power domain mutex.
> 
> The workaround I did was to grab the power domain references always around
> pps_mutex, so that we dodge the problem. A better solution would be to
> never grab power domain references while already holding pps_mutex, but
> I wasn't happy with how the code started to look when I tried that. But I
> would welcome any efforts to make that happen since the current trick is
> rather hackish. Also the code is now otherwise cleaner than what it was
> when I tried to do that, so maybe it's easier now.

Right, but then the remark was that we don't need the aux power domain
to keep the power well on on VLV/CHV, so would you be happy to just take
the port power domain around pps_lock/unlock().

-- 
Damien
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction
  2014-11-07 13:49         ` Damien Lespiau
@ 2014-11-07 14:05           ` Ville Syrjälä
  0 siblings, 0 replies; 286+ messages in thread
From: Ville Syrjälä @ 2014-11-07 14:05 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Fri, Nov 07, 2014 at 01:49:43PM +0000, Damien Lespiau wrote:
> On Fri, Nov 07, 2014 at 03:31:20PM +0200, Ville Syrjälä wrote:
> > On Fri, Nov 07, 2014 at 01:11:13PM +0000, Damien Lespiau wrote:
> > > On Tue, Sep 16, 2014 at 04:19:07PM +0300, Imre Deak wrote:
> > > > This patch needs to be rebased on the recent PPS changes at least
> > > > getting/putting the AUX power domain in pps_lock()/pps_unlock() too.
> > > > Also it should be squashed into 69/89. Some more comments below.
> > > 
> > > Hum, do we really need to hold a reference to the AUX power in
> > > pps_lock(), it doesn't seem that the PPS hw should a specific dependency
> > > on the AUX power domain. We might as well just get the "port" power
> > > domain if that's enough.
> > 
> > pps_lock() doesn't *really* need any power domain references. The thing
> > is that the VLV/CHV display power well hooks need to reset the pps_pipe
> > assignment which means they should grab pps_mutex. However the vdd code
> > can grab power domain references while already holding pps_mutex, which
> > gets us into a neat locking inversion with the power domain mutex.
> > 
> > The workaround I did was to grab the power domain references always around
> > pps_mutex, so that we dodge the problem. A better solution would be to
> > never grab power domain references while already holding pps_mutex, but
> > I wasn't happy with how the code started to look when I tried that. But I
> > would welcome any efforts to make that happen since the current trick is
> > rather hackish. Also the code is now otherwise cleaner than what it was
> > when I tried to do that, so maybe it's easier now.
> 
> Right, but then the remark was that we don't need the aux power domain
> to keep the power well on on VLV/CHV, so would you be happy to just take
> the port power domain around pps_lock/unlock().

Yeah. Actually just the disp2/pipe-a well is needed, so even the port
domains are pointless but I was feeling lazy when I came up with the
hack.

I (or someone) should also do some tests on vlv/chv to see which power
wells are actually needed for AUX. disp2d/pipe-a obviously just for the
registers, but then I'm not sure if the phy cmnlane well is needed. On
chv the docs do say that the AUX stuff is in the common lane, but IIRC
on vlv it was said to be more of a separate lane. Anyway would be nice
to know for sure.

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 66/89 v9] drm/i915/skl: Implementation of SKL DPLL programming
  2014-11-04 16:26     ` [PATCH 66/89 v9] " Damien Lespiau
@ 2014-11-07 19:56       ` Paulo Zanoni
  0 siblings, 0 replies; 286+ messages in thread
From: Paulo Zanoni @ 2014-11-07 19:56 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: Intel Graphics Development

Hi

With this and the other patches you resent, you can add "Reviewed-by:
Paulo Zanoni <paulo.r.zanoni@intel.com>" to patches 58, 59, 60, 61, 62
and 66. And I guess this makes the "clocks" part of the series
complete and ready to merge.

That said, this patch has some weird comment syntax on the comment
that contains "Intermediate values are in HZ". I guess Daniel can add
the 2 missing white spaces when merging :)

The only 2 requested bikesheds that I really miss would be an inline
function to replace GET_CFG_CRx_REG() (from patch 61) and adding
explicit values to "enum skl_dpll" (requested in my review to patch
62). But if we decide to do this, it's probably better to just do this
in separate patches: let's not block this series anymore due to
bikeshedding :)

Thanks,
Paulo

2014-11-04 14:26 GMT-02:00 Damien Lespiau <damien.lespiau@intel.com>:
> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>
> This patch implements SKL DPLL programming that includes:
>         - DPLL allocation
>         - wide range PLL calculation and programming
>         - DP link rate programming
>         - DDI to DPLL mapping
>
> v2: Incorporated following changes
>         - Added vfunc for function required outside
>         - Fixed multiple comments in WRPLL calculation
>
> v3: - Fix the DCO computation
>     - Move the initialization up to not clobber the computed values
>     - Use the correct macro for DP link rate programming.
>     - Use wait_for() to wait for the PLL locked bit
>
> v4: Rebase on top of nigthly (Damien)
>
> v5: A few code cleanups in the WRPLL computation (Damien)
>     - Use uint32_t when possible
>     - Use abs_diff() in the WRPLL computation
>     - Make the 64bits divisions use div64_u64()
>     - Fix typo in dco_central_feq_deviation (freq)
>     - Replace the chain of breaks with a goto
>
> v6: Port of the patch to work on top of the shared DPLLs (Damien)
> v7: Don't try to handle eDP in ddi_pll_select() (Damien)
> v8: Modified as per review comments from Paulo (Satheesh)
> v9: Rebase on top of Ander's clock computation staging work for atomic (Damien)
>
> Signed-off-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v3)
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 226 ++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 225 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index e8cdc1a..9e1f4b2 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -954,6 +954,226 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
>         return true;
>  }
>
> +struct skl_wrpll_params {
> +       uint32_t        dco_fraction;
> +       uint32_t        dco_integer;
> +       uint32_t        qdiv_ratio;
> +       uint32_t        qdiv_mode;
> +       uint32_t        kdiv;
> +       uint32_t        pdiv;
> +       uint32_t        central_freq;
> +};
> +
> +static void
> +skl_ddi_calculate_wrpll(int clock /* in Hz */,
> +                       struct skl_wrpll_params *wrpll_params)
> +{
> +       uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
> +       uint64_t dco_central_freq[3] = {8400000000, 9000000000, 9600000000};
> +       uint32_t min_dco_deviation = 400;
> +       uint32_t min_dco_index = 3;
> +       uint32_t P0[4] = {1, 2, 3, 7};
> +       uint32_t P2[4] = {1, 2, 3, 5};
> +       bool found = false;
> +       uint32_t candidate_p = 0;
> +       uint32_t candidate_p0[3] = {0}, candidate_p1[3] = {0};
> +       uint32_t candidate_p2[3] = {0};
> +       uint32_t dco_central_freq_deviation[3];
> +       uint32_t i, P1, k, dco_count;
> +       bool retry_with_odd = false;
> +       uint64_t dco_freq;
> +
> +       /* Determine P0, P1 or P2 */
> +       for (dco_count = 0; dco_count < 3; dco_count++) {
> +               found = false;
> +               candidate_p =
> +                       div64_u64(dco_central_freq[dco_count], afe_clock);
> +               if (retry_with_odd == false)
> +                       candidate_p = (candidate_p % 2 == 0 ?
> +                               candidate_p : candidate_p + 1);
> +
> +               for (P1 = 1; P1 < candidate_p; P1++) {
> +                       for (i = 0; i < 4; i++) {
> +                               if (!(P0[i] != 1 || P1 == 1))
> +                                       continue;
> +
> +                               for (k = 0; k < 4; k++) {
> +                                       if (P1 != 1 && P2[k] != 2)
> +                                               continue;
> +
> +                                       if (candidate_p == P0[i] * P1 * P2[k]) {
> +                                               /* Found possible P0, P1, P2 */
> +                                               found = true;
> +                                               candidate_p0[dco_count] = P0[i];
> +                                               candidate_p1[dco_count] = P1;
> +                                               candidate_p2[dco_count] = P2[k];
> +                                               goto found;
> +                                       }
> +
> +                               }
> +                       }
> +               }
> +
> +found:
> +               if (found) {
> +                       dco_central_freq_deviation[dco_count] =
> +                               div64_u64(10000 *
> +                                         abs_diff((candidate_p * afe_clock),
> +                                                  dco_central_freq[dco_count]),
> +                                         dco_central_freq[dco_count]);
> +
> +                       if (dco_central_freq_deviation[dco_count] <
> +                               min_dco_deviation) {
> +                               min_dco_deviation =
> +                                       dco_central_freq_deviation[dco_count];
> +                               min_dco_index = dco_count;
> +                       }
> +               }
> +
> +               if (min_dco_index > 2 && dco_count == 2) {
> +                       retry_with_odd = true;
> +                       dco_count = 0;
> +               }
> +       }
> +
> +       if (min_dco_index > 2) {
> +               WARN(1, "No valid values found for the given pixel clock\n");
> +       } else {
> +                wrpll_params->central_freq = dco_central_freq[min_dco_index];
> +
> +                switch (dco_central_freq[min_dco_index]) {
> +                case 9600000000:
> +                       wrpll_params->central_freq = 0;
> +                       break;
> +                case 9000000000:
> +                       wrpll_params->central_freq = 1;
> +                       break;
> +                case 8400000000:
> +                       wrpll_params->central_freq = 3;
> +                }
> +
> +                switch (candidate_p0[min_dco_index]) {
> +                case 1:
> +                       wrpll_params->pdiv = 0;
> +                       break;
> +                case 2:
> +                       wrpll_params->pdiv = 1;
> +                       break;
> +                case 3:
> +                       wrpll_params->pdiv = 2;
> +                       break;
> +                case 7:
> +                       wrpll_params->pdiv = 4;
> +                       break;
> +                default:
> +                       WARN(1, "Incorrect PDiv\n");
> +                }
> +
> +                switch (candidate_p2[min_dco_index]) {
> +                case 5:
> +                       wrpll_params->kdiv = 0;
> +                       break;
> +                case 2:
> +                       wrpll_params->kdiv = 1;
> +                       break;
> +                case 3:
> +                       wrpll_params->kdiv = 2;
> +                       break;
> +                case 1:
> +                       wrpll_params->kdiv = 3;
> +                       break;
> +                default:
> +                       WARN(1, "Incorrect KDiv\n");
> +                }
> +
> +                wrpll_params->qdiv_ratio = candidate_p1[min_dco_index];
> +                wrpll_params->qdiv_mode =
> +                       (wrpll_params->qdiv_ratio == 1) ? 0 : 1;
> +
> +                dco_freq = candidate_p0[min_dco_index] *
> +                        candidate_p1[min_dco_index] *
> +                        candidate_p2[min_dco_index] * afe_clock;
> +
> +               /*
> +               * Intermediate values are in Hz.
> +               * Divide by MHz to match bsepc
> +               */
> +                wrpll_params->dco_integer = div_u64(dco_freq, (24 * MHz(1)));
> +                wrpll_params->dco_fraction =
> +                        div_u64(((div_u64(dco_freq, 24) -
> +                                  wrpll_params->dco_integer * MHz(1)) * 0x8000), MHz(1));
> +
> +       }
> +}
> +
> +
> +static bool
> +skl_ddi_pll_select(struct intel_crtc *intel_crtc,
> +                  struct intel_encoder *intel_encoder,
> +                  int clock)
> +{
> +       struct intel_shared_dpll *pll;
> +       uint32_t ctrl1, cfgcr1, cfgcr2;
> +
> +       /*
> +        * See comment in intel_dpll_hw_state to understand why we always use 0
> +        * as the DPLL id in this function.
> +        */
> +
> +       ctrl1 = DPLL_CTRL1_OVERRIDE(0);
> +
> +       if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
> +               struct skl_wrpll_params wrpll_params = { 0, };
> +
> +               ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
> +
> +               skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params);
> +
> +               cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
> +                        DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
> +                        wrpll_params.dco_integer;
> +
> +               cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
> +                        DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
> +                        DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
> +                        DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
> +                        wrpll_params.central_freq;
> +       } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
> +               struct drm_encoder *encoder = &intel_encoder->base;
> +               struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> +
> +               switch (intel_dp->link_bw) {
> +               case DP_LINK_BW_1_62:
> +                       ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_810, 0);
> +                       break;
> +               case DP_LINK_BW_2_7:
> +                       ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_1350, 0);
> +                       break;
> +               case DP_LINK_BW_5_4:
> +                       ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_2700, 0);
> +                       break;
> +               }
> +
> +               cfgcr1 = cfgcr2 = 0;
> +       } else /* eDP */
> +               return true;
> +
> +       intel_crtc->new_config->dpll_hw_state.ctrl1 = ctrl1;
> +       intel_crtc->new_config->dpll_hw_state.cfgcr1 = cfgcr1;
> +       intel_crtc->new_config->dpll_hw_state.cfgcr2 = cfgcr2;
> +
> +       pll = intel_get_shared_dpll(intel_crtc);
> +       if (pll == NULL) {
> +               DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
> +                                pipe_name(intel_crtc->pipe));
> +               return false;
> +       }
> +
> +       /* shared DPLL id 0 is DPLL 1 */
> +       intel_crtc->new_config->ddi_pll_sel = pll->id + 1;
> +
> +       return true;
> +}
>
>  /*
>   * Tries to find a *shared* PLL for the CRTC and store it in
> @@ -964,11 +1184,15 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
>   */
>  bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
>  {
> +       struct drm_device *dev = intel_crtc->base.dev;
>         struct intel_encoder *intel_encoder =
>                 intel_ddi_get_crtc_new_encoder(intel_crtc);
>         int clock = intel_crtc->new_config->port_clock;
>
> -       return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock);
> +       if (IS_SKYLAKE(dev))
> +               return skl_ddi_pll_select(intel_crtc, intel_encoder, clock);
> +       else
> +               return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock);
>  }
>
>  void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
> --
> 1.8.3.1
>



-- 
Paulo Zanoni
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction
  2014-11-07 12:08     ` Damien Lespiau
@ 2014-11-10 19:21       ` Imre Deak
  2014-11-11 12:22         ` Damien Lespiau
  2014-11-11 14:41         ` Daniel Vetter
  0 siblings, 2 replies; 286+ messages in thread
From: Imre Deak @ 2014-11-10 19:21 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Fri, 2014-11-07 at 12:08 +0000, Damien Lespiau wrote:
> On Tue, Sep 16, 2014 at 04:19:07PM +0300, Imre Deak wrote:
> > > @@ -1233,6 +1233,9 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp)
> > >  	power_domain = intel_display_port_power_domain(intel_encoder);
> > >  	intel_display_power_get(dev_priv, power_domain);
> > >  
> > > +	power_domain = intel_display_aux_power_domain(intel_encoder);
> > > +	intel_display_power_get(dev_priv, power_domain);
> > > +
> > 
> > The AUX power domains were added to save power when only AUX
> > functionality is needed, since then we don't need to power on the power
> > domain needed for full port functionality.
> 
> Hum I'm not sure about this. It seems to me that the value of the AUX
> power domain is to be able to shutdown the AUX hardware when AUX is not
> needed. That's slightly different from what you're saying;

Ok, I didn't describe all uses cases where the AUX domains are useful,
your description here was more complete. To summarize that for later
reference:

1. only AUX (output inactive, we only do a connector detection)
2. only main lanes (most of the time when the output is active)
3. AUX+main lanes (link training/re-training)
4. no AUX, no main lanes (output is inactive)

> The cases where "only AUX functionality is needed" seem very transient
> to me, while having the main lanes working and no need for AUX sounds
> like the case where it's interesting to have the AUX hw powered down.
> Of course, with PSR we can do both.

Perhaps, if case 1. above isn't very frequent. But my arguments were
valid even for case 2. and 3.

> > With the above change and everywhere else below we'll end up enabling
> > both power domains, though we only need AUX functionality.
> 
> If we're powering up the panel that's probably to use it very soon, so I
> don't really see the value not powering the main lanes at the same time,
> they are going to be used for training very soon? I'm probably missing
> something.

Again depends how important case 1. is. But my point was that in all the
functions where this patch takes the AUX power domain (after rebasing
the edp vdd on/off and the pps_lock/unlock functions) we only want to
enable the resources needed for AUX communication. The power domain
needed for main port functionality (that is the port power domain) is
already taken in display.modeset_global_resources() for case 2. and 3.
above.

> > The power wells needed for AUX are a subset of those needed for full
> > port functionality on all platforms (at least atm), so this patch won't
> > change anything. The patch would make sense, if you requested only the
> > AUX domains.
> 
> I think it's fine if this patch is not changing anything, at least for
> now, until we get to use this power domain to good ends?

Well I'm ok not to change the functionality for now, but I'd still do
this by taking here only the AUX power domain. Then by having the same
power domain->power well mapping in intel_runtime_pm.c for the AUX
domains as for the port domains we keep the existing behavior. This is
actually done already for all existing platforms in patch 69/89 in your
SKL patchset (except for CHV). Patch 71/89 adds the mappings for SKL and
it doesn't include the SKL DDI_A_E,B,C,D power wells in the AUX power
domains. I think this would need to be tested if it really works
(triggering case 1. above), but you could also just do the easier thing
for now and set the AUX mappings to be identical to the corresponding
port mappings, as it's done for the other platforms.

--Imre

> This patch still need the reworks you mentionned in the previous mail,
> of course.


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction
  2014-11-10 19:21       ` Imre Deak
@ 2014-11-11 12:22         ` Damien Lespiau
  2014-11-11 13:11           ` Imre Deak
  2014-11-11 14:43           ` Daniel Vetter
  2014-11-11 14:41         ` Daniel Vetter
  1 sibling, 2 replies; 286+ messages in thread
From: Damien Lespiau @ 2014-11-11 12:22 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

On Mon, Nov 10, 2014 at 09:21:47PM +0200, Imre Deak wrote:
> On Fri, 2014-11-07 at 12:08 +0000, Damien Lespiau wrote:
> > On Tue, Sep 16, 2014 at 04:19:07PM +0300, Imre Deak wrote:
> > > > @@ -1233,6 +1233,9 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp)
> > > >  	power_domain = intel_display_port_power_domain(intel_encoder);
> > > >  	intel_display_power_get(dev_priv, power_domain);
> > > >  
> > > > +	power_domain = intel_display_aux_power_domain(intel_encoder);
> > > > +	intel_display_power_get(dev_priv, power_domain);
> > > > +
> > > 
> > > The AUX power domains were added to save power when only AUX
> > > functionality is needed, since then we don't need to power on the power
> > > domain needed for full port functionality.
> > 
> > Hum I'm not sure about this. It seems to me that the value of the AUX
> > power domain is to be able to shutdown the AUX hardware when AUX is not
> > needed. That's slightly different from what you're saying;
> 
> Ok, I didn't describe all uses cases where the AUX domains are useful,
> your description here was more complete. To summarize that for later
> reference:
> 
> 1. only AUX (output inactive, we only do a connector detection)
> 2. only main lanes (most of the time when the output is active)
> 3. AUX+main lanes (link training/re-training)
> 4. no AUX, no main lanes (output is inactive)
> 
> > The cases where "only AUX functionality is needed" seem very transient
> > to me, while having the main lanes working and no need for AUX sounds
> > like the case where it's interesting to have the AUX hw powered down.
> > Of course, with PSR we can do both.
> 
> Perhaps, if case 1. above isn't very frequent. But my arguments were
> valid even for case 2. and 3.

I agree with case 2., The training case (3.) is a transient state as
well where we can have the AUX power well always on. But yes, we should
make sure to turn off the AUX power domain most of the time when the
display is on, you're absolutely right on that.

> > I think it's fine if this patch is not changing anything, at least for
> > now, until we get to use this power domain to good ends?
> 
> Well I'm ok not to change the functionality for now, but I'd still do
> this by taking here only the AUX power domain. Then by having the same
> power domain->power well mapping in intel_runtime_pm.c for the AUX
> domains as for the port domains we keep the existing behavior. This is
> actually done already for all existing platforms in patch 69/89 in your
> SKL patchset (except for CHV). Patch 71/89 adds the mappings for SKL and
> it doesn't include the SKL DDI_A_E,B,C,D power wells in the AUX power
> domains. I think this would need to be tested if it really works
> (triggering case 1. above), but you could also just do the easier thing
> for now and set the AUX mappings to be identical to the corresponding
> port mappings, as it's done for the other platforms.

Ok, had another look, and, granted, it looks funny. What I'll try:

Have us always take the AUX power domain in the AUX ->transfer vfunc.
This won't toggle the power well on/off for each transfer if we
correctly wrap known heavy users of the AUX channel, intel_dp_detect(),
intel_dp_get_edid(), intel_dp_force and intel_dp_hpd_pulse() so we keep
the power well alive for the duration of those. This will also allow
one-of AUX transfers from DRM core when the power is down.

-- 
Damien
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction
  2014-11-11 12:22         ` Damien Lespiau
@ 2014-11-11 13:11           ` Imre Deak
  2014-11-11 14:43           ` Daniel Vetter
  1 sibling, 0 replies; 286+ messages in thread
From: Imre Deak @ 2014-11-11 13:11 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Tue, 2014-11-11 at 12:22 +0000, Damien Lespiau wrote:
> On Mon, Nov 10, 2014 at 09:21:47PM +0200, Imre Deak wrote:
> > On Fri, 2014-11-07 at 12:08 +0000, Damien Lespiau wrote:
> > > On Tue, Sep 16, 2014 at 04:19:07PM +0300, Imre Deak wrote:
> > > > > @@ -1233,6 +1233,9 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp)
> > > > >  	power_domain = intel_display_port_power_domain(intel_encoder);
> > > > >  	intel_display_power_get(dev_priv, power_domain);
> > > > >  
> > > > > +	power_domain = intel_display_aux_power_domain(intel_encoder);
> > > > > +	intel_display_power_get(dev_priv, power_domain);
> > > > > +
> > > > 
> > > > The AUX power domains were added to save power when only AUX
> > > > functionality is needed, since then we don't need to power on the power
> > > > domain needed for full port functionality.
> > > 
> > > Hum I'm not sure about this. It seems to me that the value of the AUX
> > > power domain is to be able to shutdown the AUX hardware when AUX is not
> > > needed. That's slightly different from what you're saying;
> > 
> > Ok, I didn't describe all uses cases where the AUX domains are useful,
> > your description here was more complete. To summarize that for later
> > reference:
> > 
> > 1. only AUX (output inactive, we only do a connector detection)
> > 2. only main lanes (most of the time when the output is active)
> > 3. AUX+main lanes (link training/re-training)
> > 4. no AUX, no main lanes (output is inactive)
> > 
> > > The cases where "only AUX functionality is needed" seem very transient
> > > to me, while having the main lanes working and no need for AUX sounds
> > > like the case where it's interesting to have the AUX hw powered down.
> > > Of course, with PSR we can do both.
> > 
> > Perhaps, if case 1. above isn't very frequent. But my arguments were
> > valid even for case 2. and 3.
> 
> I agree with case 2., The training case (3.) is a transient state as
> well where we can have the AUX power well always on. But yes, we should
> make sure to turn off the AUX power domain most of the time when the
> display is on, you're absolutely right on that.
> 
> > > I think it's fine if this patch is not changing anything, at least for
> > > now, until we get to use this power domain to good ends?
> > 
> > Well I'm ok not to change the functionality for now, but I'd still do
> > this by taking here only the AUX power domain. Then by having the same
> > power domain->power well mapping in intel_runtime_pm.c for the AUX
> > domains as for the port domains we keep the existing behavior. This is
> > actually done already for all existing platforms in patch 69/89 in your
> > SKL patchset (except for CHV). Patch 71/89 adds the mappings for SKL and
> > it doesn't include the SKL DDI_A_E,B,C,D power wells in the AUX power
> > domains. I think this would need to be tested if it really works
> > (triggering case 1. above), but you could also just do the easier thing
> > for now and set the AUX mappings to be identical to the corresponding
> > port mappings, as it's done for the other platforms.
> 
> Ok, had another look, and, granted, it looks funny. What I'll try:
> 
> Have us always take the AUX power domain in the AUX ->transfer vfunc.
> This won't toggle the power well on/off for each transfer if we
> correctly wrap known heavy users of the AUX channel, intel_dp_detect(),
> intel_dp_get_edid(), intel_dp_force and intel_dp_hpd_pulse() so we keep
> the power well alive for the duration of those. This will also allow
> one-of AUX transfers from DRM core when the power is down.

Yes, this sounds ok to me. Iiuc this will change all places in
intel_dp.c to take the AUX domain instead of the port domain.
intel_dp_get_hw_state() should still check the port domain, since there
we are only interested in the HW state for the main lanes not the HW
state for AUX.

--Imre

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction
  2014-11-10 19:21       ` Imre Deak
  2014-11-11 12:22         ` Damien Lespiau
@ 2014-11-11 14:41         ` Daniel Vetter
  1 sibling, 0 replies; 286+ messages in thread
From: Daniel Vetter @ 2014-11-11 14:41 UTC (permalink / raw)
  To: Imre Deak; +Cc: intel-gfx

On Mon, Nov 10, 2014 at 09:21:47PM +0200, Imre Deak wrote:
> On Fri, 2014-11-07 at 12:08 +0000, Damien Lespiau wrote:
> > On Tue, Sep 16, 2014 at 04:19:07PM +0300, Imre Deak wrote:
> > > > @@ -1233,6 +1233,9 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp)
> > > >  	power_domain = intel_display_port_power_domain(intel_encoder);
> > > >  	intel_display_power_get(dev_priv, power_domain);
> > > >  
> > > > +	power_domain = intel_display_aux_power_domain(intel_encoder);
> > > > +	intel_display_power_get(dev_priv, power_domain);
> > > > +
> > > 
> > > The AUX power domains were added to save power when only AUX
> > > functionality is needed, since then we don't need to power on the power
> > > domain needed for full port functionality.
> > 
> > Hum I'm not sure about this. It seems to me that the value of the AUX
> > power domain is to be able to shutdown the AUX hardware when AUX is not
> > needed. That's slightly different from what you're saying;
> 
> Ok, I didn't describe all uses cases where the AUX domains are useful,
> your description here was more complete. To summarize that for later
> reference:
> 
> 1. only AUX (output inactive, we only do a connector detection)
> 2. only main lanes (most of the time when the output is active)
> 3. AUX+main lanes (link training/re-training)
> 4. no AUX, no main lanes (output is inactive)
> 
> > The cases where "only AUX functionality is needed" seem very transient
> > to me, while having the main lanes working and no need for AUX sounds
> > like the case where it's interesting to have the AUX hw powered down.
> > Of course, with PSR we can do both.
> 
> Perhaps, if case 1. above isn't very frequent. But my arguments were
> valid even for case 2. and 3.

I've thought the point of case 1 is that we don't have to fire up the
entire display clocks and power wells when just doing a few dp aux
transactions to probe for outputs.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction
  2014-11-11 12:22         ` Damien Lespiau
  2014-11-11 13:11           ` Imre Deak
@ 2014-11-11 14:43           ` Daniel Vetter
  1 sibling, 0 replies; 286+ messages in thread
From: Daniel Vetter @ 2014-11-11 14:43 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx

On Tue, Nov 11, 2014 at 12:22:28PM +0000, Damien Lespiau wrote:
> Have us always take the AUX power domain in the AUX ->transfer vfunc.
> This won't toggle the power well on/off for each transfer if we
> correctly wrap known heavy users of the AUX channel, intel_dp_detect(),
> intel_dp_get_edid(), intel_dp_force and intel_dp_hpd_pulse() so we keep
> the power well alive for the duration of those. This will also allow
> one-of AUX transfers from DRM core when the power is down.

This kind of high-freq flip-flop of power domains is why the linux power
domain and runtime pm code has a disable timer. I guess as predicted,
we'll eventually implement it all ;-)
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 55/59 v4] drm/i915/skl: Gen9 multi-engine forcewake
  2014-11-03 17:09         ` [PATCH 55/59 v4] " Damien Lespiau
@ 2014-11-19 13:25           ` Mika Kuoppala
  0 siblings, 0 replies; 286+ messages in thread
From: Mika Kuoppala @ 2014-11-19 13:25 UTC (permalink / raw)
  To: Damien Lespiau, intel-gfx

Damien Lespiau <damien.lespiau@intel.com> writes:

> From: Zhe Wang <zhe1.wang@intel.com>
>
> Enable multi-engine forcewake for Gen9.
>
> v2: (Damien)
> - Rebase on top of nightly
> - Move the register range definitions to intel_uncore.c
> - Whitespace fixes
>
> v3: (Addressing Mika's comment, done by Damien)
> - Use REG_RANGE() (introduced after the patch was written)
> - Add a SKL_NEEDS_FORCE_WAKE() macro that gets rid of a useless
>   comparison to FORCEWAKE (reg 0xa18c is not used on SKL)
>
> v4: (Damien)
> - Use newly introduced ASSIGN_READ/WRITE_MMIO_VFUNCS() macros
>
> Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_uncore.c | 115 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 115 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 68e722b..8ce56f6 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -678,6 +678,34 @@ void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
>  	 REG_RANGE((reg), 0x14000, 0x14400) || \
>  	 REG_RANGE((reg), 0x22000, 0x24000))
>  
> +#define FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) \
> +	REG_RANGE((reg), 0xC00,  0x2000)
> +
> +#define FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) \
> +	(REG_RANGE((reg), 0x2000, 0x4000) || \
> +	 REG_RANGE((reg), 0x5200, 0x8000) || \
> +	 REG_RANGE((reg), 0x8300, 0x8500) || \
> +	 REG_RANGE((reg), 0x8C00, 0x8D00) || \
> +	 REG_RANGE((reg), 0xB000, 0xB480) || \
> +	 REG_RANGE((reg), 0xE000, 0xE800))
> +
> +#define FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) \
> +	(REG_RANGE((reg), 0x8800, 0x8A00) || \
> +	 REG_RANGE((reg), 0xD000, 0xD800) || \
> +	 REG_RANGE((reg), 0x12000, 0x14000) || \
> +	 REG_RANGE((reg), 0x1A000, 0x1EA00) || \
> +	 REG_RANGE((reg), 0x30000, 0x40000))
> +
> +#define FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg) \
> +	REG_RANGE((reg), 0x9400, 0x9800)
> +
> +#define FORCEWAKE_GEN9_BLITTER_RANGE_OFFSET(reg) \
> +	((reg) < 0x40000 &&\
> +	 !FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) && \
> +	 !FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) && \
> +	 !FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) && \
> +	 !FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg))
> +
>  static void
>  ilk_dummy_write(struct drm_i915_private *dev_priv)
>  {
> @@ -808,6 +836,45 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>  	REG_READ_FOOTER; \
>  }
>  
> +#define SKL_NEEDS_FORCE_WAKE(dev_priv, reg)	\
> +	 ((reg) < 0x40000 && !FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg))
> +
> +#define __gen9_read(x) \
> +static u##x \
> +gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
> +	REG_READ_HEADER(x); \
> +	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
> +		val = __raw_i915_read##x(dev_priv, reg); \
> +	} else { \
> +		unsigned fwengine = 0; \
> +		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
> +			if (dev_priv->uncore.fw_rendercount == 0) \
> +				fwengine = FORCEWAKE_RENDER; \
> +		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
> +			if (dev_priv->uncore.fw_mediacount == 0) \
> +				fwengine = FORCEWAKE_MEDIA; \
> +		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
> +			if (dev_priv->uncore.fw_rendercount == 0) \
> +				fwengine |= FORCEWAKE_RENDER; \
> +			if (dev_priv->uncore.fw_mediacount == 0) \
> +				fwengine |= FORCEWAKE_MEDIA; \
> +		} else { \
> +			if (dev_priv->uncore.fw_blittercount == 0) \
> +				fwengine = FORCEWAKE_BLITTER; \
> +		} \
> +		if (fwengine) \
> +			dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
> +		val = __raw_i915_read##x(dev_priv, reg); \
> +		if (fwengine) \
> +			dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
> +	} \
> +	REG_READ_FOOTER; \
> +}
> +
> +__gen9_read(8)
> +__gen9_read(16)
> +__gen9_read(32)
> +__gen9_read(64)
>  __chv_read(8)
>  __chv_read(16)
>  __chv_read(32)
> @@ -829,6 +896,7 @@ __gen4_read(16)
>  __gen4_read(32)
>  __gen4_read(64)
>  
> +#undef __gen9_read
>  #undef __chv_read
>  #undef __vlv_read
>  #undef __gen6_read
> @@ -966,6 +1034,45 @@ chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
>  	REG_WRITE_FOOTER; \
>  }
>  
> +#define __gen9_write(x) \
> +static void \
> +gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
> +		bool trace) { \
> +	REG_WRITE_HEADER; \
> +	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
> +		__raw_i915_write##x(dev_priv, reg, val); \
> +	} else { \
> +		unsigned fwengine = 0; \
> +		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
> +			if (dev_priv->uncore.fw_rendercount == 0) \
> +				fwengine = FORCEWAKE_RENDER; \
> +		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
> +			if (dev_priv->uncore.fw_mediacount == 0) \
> +				fwengine = FORCEWAKE_MEDIA; \
> +		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
> +			if (dev_priv->uncore.fw_rendercount == 0) \
> +				fwengine |= FORCEWAKE_RENDER; \
> +			if (dev_priv->uncore.fw_mediacount == 0) \
> +				fwengine |= FORCEWAKE_MEDIA; \
> +		} else { \
> +			if (dev_priv->uncore.fw_blittercount == 0) \
> +				fwengine = FORCEWAKE_BLITTER; \
> +		} \
> +		if (fwengine) \
> +			dev_priv->uncore.funcs.force_wake_get(dev_priv, \
> +					fwengine); \
> +		__raw_i915_write##x(dev_priv, reg, val); \
> +		if (fwengine) \
> +			dev_priv->uncore.funcs.force_wake_put(dev_priv, \
> +					fwengine); \
> +	} \
> +	REG_WRITE_FOOTER; \
> +}
> +
> +__gen9_write(8)
> +__gen9_write(16)
> +__gen9_write(32)
> +__gen9_write(64)
>  __chv_write(8)
>  __chv_write(16)
>  __chv_write(32)
> @@ -991,6 +1098,7 @@ __gen4_write(16)
>  __gen4_write(32)
>  __gen4_write(64)
>  
> +#undef __gen9_write
>  #undef __chv_write
>  #undef __gen8_write
>  #undef __hsw_write
> @@ -1074,6 +1182,13 @@ void intel_uncore_init(struct drm_device *dev)
>  
>  	switch (INTEL_INFO(dev)->gen) {
>  	default:
> +		WARN_ON(1);
> +		return;
> +	case 9:
> +		ASSIGN_WRITE_MMIO_VFUNCS(gen9);
> +		ASSIGN_READ_MMIO_VFUNCS(gen9);
> +		break;
> +	case 8:
>  		if (IS_CHERRYVIEW(dev)) {
>  			ASSIGN_WRITE_MMIO_VFUNCS(chv);
>  			ASSIGN_READ_MMIO_VFUNCS(chv);
> -- 
> 1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 56/89 v4] drm/i915: Gen9 shadowed registers
  2014-11-03 17:45         ` [PATCH 56/89 v4] " Damien Lespiau
@ 2014-11-19 13:25           ` Mika Kuoppala
  0 siblings, 0 replies; 286+ messages in thread
From: Mika Kuoppala @ 2014-11-19 13:25 UTC (permalink / raw)
  To: Damien Lespiau, intel-gfx

Damien Lespiau <damien.lespiau@intel.com> writes:

> From: Zhe Wang <zhe1.wang@intel.com>
>
> For MMIO registers which are shadowed, force wake is not needed to
> write to these registers.
>
> v2: Rebase on top of nightly (Damien)
>
> v3: Rebase on top of "Gen9 multiple-engine forcewake" changes
>
> v4: (Mika, Bob, done by Damien)
> - Reorder the shadowed registers by popularity
>
> Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_uncore.c | 26 +++++++++++++++++++++++++-
>  1 file changed, 25 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 8ce56f6..4b46976 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -1034,12 +1034,36 @@ chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
>  	REG_WRITE_FOOTER; \
>  }
>  
> +static const u32 gen9_shadowed_regs[] = {
> +	RING_TAIL(RENDER_RING_BASE),
> +	RING_TAIL(GEN6_BSD_RING_BASE),
> +	RING_TAIL(VEBOX_RING_BASE),
> +	RING_TAIL(BLT_RING_BASE),
> +	FORCEWAKE_BLITTER_GEN9,
> +	FORCEWAKE_RENDER_GEN9,
> +	FORCEWAKE_MEDIA_GEN9,
> +	GEN6_RPNSWREQ,
> +	GEN6_RC_VIDEO_FREQ,
> +	/* TODO: Other registers are not yet used */
> +};
> +
> +static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg)
> +{
> +	int i;
> +	for (i = 0; i < ARRAY_SIZE(gen9_shadowed_regs); i++)
> +		if (reg == gen9_shadowed_regs[i])
> +			return true;
> +
> +	return false;
> +}
> +
>  #define __gen9_write(x) \
>  static void \
>  gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
>  		bool trace) { \
>  	REG_WRITE_HEADER; \
> -	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
> +	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
> +			is_gen9_shadowed(dev_priv, reg)) { \
>  		__raw_i915_write##x(dev_priv, reg, val); \
>  	} else { \
>  		unsigned fwengine = 0; \
> -- 
> 1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 66/89] drm/i915/skl: Implementation of SKL DPLL programming
  2014-09-04 11:27 ` [PATCH 66/89] drm/i915/skl: Implementation of SKL DPLL programming Damien Lespiau
  2014-09-23 18:05   ` Paulo Zanoni
@ 2015-05-13 14:54   ` Tvrtko Ursulin
  2015-05-13 15:31     ` Damien Lespiau
  1 sibling, 1 reply; 286+ messages in thread
From: Tvrtko Ursulin @ 2015-05-13 14:54 UTC (permalink / raw)
  To: Satheeshakrishna M; +Cc: Ander Conselvan de Oliveira, intel-gfx


Hi,

On 09/04/2014 12:27 PM, Damien Lespiau wrote:
> From: Satheeshakrishna M <satheeshakrishna.m@intel.com>
>
> This patch implements SKL DPLL programming that includes:
>          - DPLL allocation
>          - wide range PLL calculation and programming
>          - DP link rate programming
>          - DDI to DPLL mapping
>
> v2: Incorporated following changes
>          - Added vfunc for function required outside
>          - Fixed multiple comments in WRPLL calculation
>
> v3: - Fix the DCO computation
>      - Move the initialization up to not clobber the computed values
>      - Use the correct macro for DP link rate programming.
>      - Use wait_for() to wait for the PLL locked bit
>
> v4: Rebase on top of nigthly (Damien)
>
> v5: A few code cleanups in the WRPLL computation (Damien)
>      - Use uint32_t when possible
>      - Use abs_diff() in the WRPLL computation
>      - Make the 64bits divisions use div64_u64()
>      - Fix typo in dco_central_feq_deviation (freq)
>      - Replace the chain of breaks with a goto
>
> v6: Port of the patch to work on top of the shared DPLLs (Damien)
> v7: Don't try to handle eDP in ddi_pll_select() (Damien)

[snip]

> +static bool
> +skl_ddi_pll_select(struct intel_crtc *intel_crtc,
> +		   struct intel_encoder *intel_encoder,
> +		   int clock)
> +{
> +	struct intel_shared_dpll *pll;
> +	uint32_t ctrl1, cfgcr1, cfgcr2;
> +
> +	/*
> +	 * See comment in intel_dpll_hw_state to understand why we always use 0
> +	 * as the DPLL id in this function.
> +	 */
> +
> +	ctrl1 = DPLL_CTRL1_OVERRIDE(0);
> +
> +	if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
> +		struct skl_wrpll_params wrpll_params = { 0, };
> +
> +		ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
> +
> +		skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params);
> +
> +		cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
> +			 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
> +			 wrpll_params.dco_integer;
> +
> +		cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
> +			 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
> +			 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
> +			 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
> +			 wrpll_params.central_freq;
> +	} else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
> +		struct drm_encoder *encoder = &intel_encoder->base;
> +		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> +
> +		switch (intel_dp->link_bw) {
> +		case DP_LINK_BW_1_62:
> +			ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_810, 0);
> +			break;
> +		case DP_LINK_BW_2_7:
> +			ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_1350, 0);
> +			break;
> +		case DP_LINK_BW_5_4:
> +			ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_2700, 0);
> +			break;
> +		}
> +
> +		cfgcr1 = cfgcr2 = 0;
> +	} else /* eDP */
> +		return true;
>
> +	intel_crtc->config.dpll_hw_state.ctrl1 = ctrl1;
> +	intel_crtc->config.dpll_hw_state.cfgcr1 = cfgcr1;
> +	intel_crtc->config.dpll_hw_state.cfgcr2 = cfgcr2;

The return before updating the dpll_hw_state in the eDP case interacts with:

commit 4978cc93d9ac240b435ce60431aef24239b4c270
Author: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Date:   Tue Apr 21 17:13:21 2015 +0300

     drm/i915: Preserve shared DPLL information in new pipe_config

And results with a bunch of:

[drm:check_crtc_state [i915]] *ERROR* mismatch in dpll_hw_state.ctrl1 
(expected 0x00000000, found 0x00000001)

On boot and afterwards.

Not sure what is the fix so maybe someone knows?

Regards,

Tvrtko
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

* Re: [PATCH 66/89] drm/i915/skl: Implementation of SKL DPLL programming
  2015-05-13 14:54   ` [PATCH 66/89] " Tvrtko Ursulin
@ 2015-05-13 15:31     ` Damien Lespiau
  0 siblings, 0 replies; 286+ messages in thread
From: Damien Lespiau @ 2015-05-13 15:31 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Wed, May 13, 2015 at 03:54:32PM +0100, Tvrtko Ursulin wrote:
> 
> Hi,

Hi Tvrtko,

> >+static bool
> >+skl_ddi_pll_select(struct intel_crtc *intel_crtc,
> >+		   struct intel_encoder *intel_encoder,
> >+		   int clock)
> >+{
> >+	struct intel_shared_dpll *pll;
> >+	uint32_t ctrl1, cfgcr1, cfgcr2;
> >+
> >+	/*
> >+	 * See comment in intel_dpll_hw_state to understand why we always use 0
> >+	 * as the DPLL id in this function.
> >+	 */
> >+
> >+	ctrl1 = DPLL_CTRL1_OVERRIDE(0);
> >+
> >+	if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
> >+		struct skl_wrpll_params wrpll_params = { 0, };
> >+
> >+		ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
> >+
> >+		skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params);
> >+
> >+		cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
> >+			 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
> >+			 wrpll_params.dco_integer;
> >+
> >+		cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
> >+			 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
> >+			 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
> >+			 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
> >+			 wrpll_params.central_freq;
> >+	} else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
> >+		struct drm_encoder *encoder = &intel_encoder->base;
> >+		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> >+
> >+		switch (intel_dp->link_bw) {
> >+		case DP_LINK_BW_1_62:
> >+			ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_810, 0);
> >+			break;
> >+		case DP_LINK_BW_2_7:
> >+			ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_1350, 0);
> >+			break;
> >+		case DP_LINK_BW_5_4:
> >+			ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_2700, 0);
> >+			break;
> >+		}
> >+
> >+		cfgcr1 = cfgcr2 = 0;
> >+	} else /* eDP */
> >+		return true;
> >
> >+	intel_crtc->config.dpll_hw_state.ctrl1 = ctrl1;
> >+	intel_crtc->config.dpll_hw_state.cfgcr1 = cfgcr1;
> >+	intel_crtc->config.dpll_hw_state.cfgcr2 = cfgcr2;
> 
> The return before updating the dpll_hw_state in the eDP case interacts with:
> 
> commit 4978cc93d9ac240b435ce60431aef24239b4c270
> Author: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
> Date:   Tue Apr 21 17:13:21 2015 +0300
> 
>     drm/i915: Preserve shared DPLL information in new pipe_config
> 
> And results with a bunch of:
> 
> [drm:check_crtc_state [i915]] *ERROR* mismatch in dpll_hw_state.ctrl1
> (expected 0x00000000, found 0x00000001)
> 
> On boot and afterwards.
> 
> Not sure what is the fix so maybe someone knows?

I, since then, added the hint:

/*
 * Tries to find a *shared* PLL for the CRTC and store it in
 * intel_crtc->ddi_pll_sel.
 *
 * For private DPLLs, compute_config() should do the selection for us. This
 * function should be folded into compute_config() eventually.
 */

The mess is because of the shared vs private PLLs. For eDP skl_edp_set_pll_config()
in intel_dp.c should take care of computing the state.

-- 
Damien
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 286+ messages in thread

end of thread, other threads:[~2015-05-13 15:31 UTC | newest]

Thread overview: 286+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-04 11:26 [PATCH 00/89] Basic Skylake enabling Damien Lespiau
2014-09-04 11:26 ` [PATCH 01/89] drm/i915/skl: Add the Skylake PCI ids Damien Lespiau
2014-09-04 11:26 ` [PATCH 02/89] drm/i915/skl: Add an IS_GEN9() define Damien Lespiau
2014-09-04 11:26 ` [PATCH 03/89] drm/i915/skl: Add an IS_SKYLAKE macro Damien Lespiau
2014-09-04 11:26 ` [PATCH 04/89] drm/i915/skl: SKL FBC enablement Damien Lespiau
2014-09-04 11:26 ` [PATCH 05/89] drm/i915/skl: i915_swizzle_info gen9 fix Damien Lespiau
2014-09-04 13:14   ` Daniel Vetter
2014-09-04 15:26     ` Damien Lespiau
2014-09-04 11:26 ` [PATCH 06/89] drm/i915/skl: Fence registers on SKL are the same as SNB Damien Lespiau
2014-09-04 11:26 ` [PATCH 07/89] drm/i915/skl: Provide a placeholder for init_clock_gating() Damien Lespiau
2014-09-04 11:26 ` [PATCH 08/89] drm/i915/skl: Use gen8_ring_dispatch_execbuffer() on GEN9 Damien Lespiau
2014-09-16 14:53   ` Thomas Wood
2014-09-19 11:09     ` Damien Lespiau
2014-09-04 11:26 ` [PATCH 09/89] drm/i915/skl: Skylake shares the interrupt logic with Broadwell Damien Lespiau
2014-09-04 11:26 ` [PATCH 10/89] drm/i915/skl: don't set the AsyncFlip performance mode for Gen9+ Damien Lespiau
2014-09-04 11:26 ` [PATCH 11/89] drm/i915/skl: Framebuffers need to be aligned to 256Kb on Skylake Damien Lespiau
2014-09-16 14:54   ` Thomas Wood
2014-09-19 11:26     ` [PATCH 11/89 v2] drm/i915/skl: Framebuffers need to be aligned to 256KB " Damien Lespiau
2014-09-19 13:46       ` Thomas Wood
2014-09-04 11:26 ` [PATCH 12/89] drm/i915/skl: Implement thew new update_plane() for primary planes Damien Lespiau
2014-09-17  0:49   ` Rodrigo Vivi
2014-09-22 11:18     ` [PATCH 12/89 v8] drm/i915/skl: Implement the " Damien Lespiau
2014-09-04 11:26 ` [PATCH 13/89] drm/i915/skl: Don't create a VGA connector on Skylake Damien Lespiau
2014-09-04 11:26 ` [PATCH 14/89] drm/i915/skl: Don't try to read out the PCH transcoder state if not present Damien Lespiau
2014-09-04 11:26 ` [PATCH 15/89] drm/i915/skl: Program the DDI buffer translation tables Damien Lespiau
2014-09-04 18:58   ` [PATCH 15/89 v7] " Damien Lespiau
2014-09-04 11:26 ` [PATCH 16/89] drm/i915/skl: Add support for DP voltage swings and pre-emphasis Damien Lespiau
2014-09-04 11:26 ` [PATCH 17/89] drm/i915/skl: Skylake doesn't need the DP AUX clock divider programmed Damien Lespiau
2014-09-04 11:26 ` [PATCH 18/89] drm/i915/skl: Skylake moves AUX_CTL from PCH to CPU Damien Lespiau
2014-09-04 11:26 ` [PATCH 19/89] drm/i915/skl: Add the additional graphics stolen sizes Damien Lespiau
2014-09-04 11:26 ` [PATCH 20/89] drm/i915/skl: gen9 uses the same bind_vma() vfuncs as gen6+ Damien Lespiau
2014-09-04 11:26 ` [PATCH 21/89] drm/i915/skl: Implement the get_aux_clock_divider() DP vfunc Damien Lespiau
2014-09-17  1:12   ` Rodrigo Vivi
2014-09-22 13:21     ` Damien Lespiau
2014-09-22 19:33       ` Rodrigo Vivi
2014-09-04 11:26 ` [PATCH 22/89] drm/i915/skl: Provide a get_aux_send_ctl() vfunc for skylake Damien Lespiau
2014-09-17  1:16   ` Rodrigo Vivi
2014-09-04 11:26 ` [PATCH 23/89] drm/i915/skl: Initialize PPGTT like gen8 Damien Lespiau
2014-09-17  1:17   ` Rodrigo Vivi
2014-09-04 11:26 ` [PATCH 24/89] drm/i915/skl: Allow the reg_read ioctl to return RCS_TIMESTAMP Damien Lespiau
2014-09-17  1:27   ` Rodrigo Vivi
2014-09-22 13:27     ` Damien Lespiau
2014-09-04 11:26 ` [PATCH 25/89] drm/i915/skl: report the same INSTDONE registers as gen8 Damien Lespiau
2014-09-17  1:28   ` Rodrigo Vivi
2014-09-04 11:26 ` [PATCH 26/89] drm/i915/skl: Report the PDP regs as in gen8 Damien Lespiau
2014-09-17  1:33   ` Rodrigo Vivi
2014-09-04 11:26 ` [PATCH 27/89] drm/i915/skl: SKL shares the same underrun interrupt as BDW Damien Lespiau
2014-09-17  1:39   ` Rodrigo Vivi
2014-09-04 11:26 ` [PATCH 28/89] drm/i915/skl: SKL pipe misc programming Damien Lespiau
2014-09-17  1:43   ` Rodrigo Vivi
2014-09-04 11:26 ` [PATCH 29/89] drm/i915/skl: vfuncs for skl eld and global resource Damien Lespiau
2014-09-17  1:50   ` Rodrigo Vivi
2014-09-22 13:32     ` Damien Lespiau
2014-09-04 11:26 ` [PATCH 30/89] drm/i915/skl: SKL backlight enabling Damien Lespiau
2014-09-17  1:56   ` Rodrigo Vivi
2014-09-17  9:09     ` Jani Nikula
2014-09-17 13:46       ` Rodrigo Vivi
2014-09-17 14:56         ` Rodrigo Vivi
2014-09-04 11:26 ` [PATCH 31/89] drm/i915/skl: Restore pipe B/C interrupts Damien Lespiau
2014-09-04 11:26 ` [PATCH 32/89] drm/i915/skl: Adjust the display engine interrupts Damien Lespiau
2014-09-04 13:19   ` Daniel Vetter
2014-09-17 18:41     ` Rodrigo Vivi
2014-09-22 13:38       ` Damien Lespiau
2014-09-04 11:26 ` [PATCH 33/89] drm/i915/skl: Sunrise Point PCH detection Damien Lespiau
2014-09-17 22:18   ` Rodrigo Vivi
2014-09-22 13:42     ` Damien Lespiau
2014-09-22 19:34       ` Rodrigo Vivi
2014-09-04 11:27 ` [PATCH 34/89] drm/i915/skl: Implement WaDisableSDEUnitClockGating:skl Damien Lespiau
2014-09-17 18:48   ` Rodrigo Vivi
2014-09-04 11:27 ` [PATCH 35/89] drm/i915/skl: Implement Wa4x4STCOptimizationDisable:skl Damien Lespiau
2014-09-17 19:00   ` Rodrigo Vivi
2014-09-17 19:00     ` Rodrigo Vivi
2014-09-22 13:49       ` Damien Lespiau
2014-09-04 11:27 ` [PATCH 36/89] drm/i915/skl: Implement WaDisableDgMirrorFixInHalfSliceChicken5:skl Damien Lespiau
2014-09-17 21:22   ` Rodrigo Vivi
2014-09-04 11:27 ` [PATCH 37/89] drm/i915/skl: Skylake has 2 "sprite" planes per pipe Damien Lespiau
2014-09-17 21:25   ` Rodrigo Vivi
2014-09-04 11:27 ` [PATCH 38/89] drm/i915/skl: Implement drm_plane vfuncs Damien Lespiau
2014-09-04 13:21   ` Daniel Vetter
2014-09-16 13:20     ` Damien Lespiau
2014-09-17 22:08   ` Rodrigo Vivi
2014-09-04 11:27 ` [PATCH 39/89] drm/i915/skl: Adjust assert_sprites_disabled() Damien Lespiau
2014-09-17 22:10   ` Rodrigo Vivi
2014-09-04 11:27 ` [PATCH 40/89] drm/i915/skl: Introduce a I915_MAX_PLANES macro Damien Lespiau
2014-09-17 22:12   ` Rodrigo Vivi
2014-09-04 11:27 ` [PATCH 41/89] drm/i915/skl: Introduce intel_num_planes() Damien Lespiau
2014-09-17 22:13   ` Rodrigo Vivi
2014-09-04 11:27 ` [PATCH 42/89] drm/i915/skl: Move gen9 pm initialization into its own branch Damien Lespiau
2014-09-17 22:16   ` Rodrigo Vivi
2014-09-04 11:27 ` [PATCH 43/89] drm/i915/skl: Read the Memory Latency Values for WM computation Damien Lespiau
2014-09-04 18:49   ` [PATCH 43/89 v6] " Damien Lespiau
2014-09-10 17:37     ` Ville Syrjälä
2014-09-05  8:25   ` [PATCH 43/89] " Ville Syrjälä
2014-09-05  8:29     ` Damien Lespiau
2014-09-05  8:42       ` Ville Syrjälä
2014-09-05 12:56         ` Damien Lespiau
2014-09-04 11:27 ` [PATCH 44/89] drm/i915/skl: Register definitions and macros for SKL Watermark regs Damien Lespiau
2014-09-10 18:04   ` Ville Syrjälä
2014-09-16 14:11     ` Damien Lespiau
2014-09-17 13:40     ` [PATCH 44/89 v4] " Damien Lespiau
2014-09-23 11:17   ` [PATCH 44/89 v5] " Damien Lespiau
2014-09-04 11:27 ` [PATCH 45/89] drm/i915/skl: Definition of SKL WM param structs for pipe/plane Damien Lespiau
2014-09-10 18:39   ` Ville Syrjälä
2014-09-17 13:59     ` Damien Lespiau
2014-09-17 15:59       ` Daniel Vetter
2014-09-22 14:00         ` Damien Lespiau
2014-09-22 14:06   ` Ville Syrjälä
2014-09-22 14:21     ` Damien Lespiau
2014-09-23  8:16       ` Daniel Vetter
2014-09-23 15:10         ` [PATCH 45/89 v4] " Damien Lespiau
2014-10-28 15:11           ` Ville Syrjälä
2014-09-04 11:27 ` [PATCH 46/89] drm/i915/skl: Add DDB allocation management structures Damien Lespiau
2014-09-17 10:47   ` Ville Syrjälä
2014-09-22 14:08     ` Damien Lespiau
2014-09-22 18:26       ` Ville Syrjälä
2014-10-29 15:32   ` Ville Syrjälä
2014-09-04 11:27 ` [PATCH 47/89] drm/i915/skl: SKL Watermark Computation Damien Lespiau
2014-09-17 12:07   ` Ville Syrjälä
2014-09-22 22:36     ` Damien Lespiau
2014-09-23  6:00       ` Satheeshakrishna M
2014-09-23 11:13     ` [PATCH 47/89 v11] " Damien Lespiau
2014-10-29 17:07       ` Ville Syrjälä
2014-09-23 11:14     ` [PATCH 47/89] " Damien Lespiau
2014-09-04 11:27 ` [PATCH 48/89] drm/i915/skl: Allocate DDB portions for display planes Damien Lespiau
2014-09-19  9:58   ` Ville Syrjälä
2014-09-27 14:15     ` [PATCH 48/89 v6] " Damien Lespiau
2014-10-29 17:12       ` Ville Syrjälä
2014-09-23 11:19   ` [PATCH 48/89 v4] " Damien Lespiau
2014-09-04 11:27 ` [PATCH 49/89] drm/i915/skl: Program the DDB allocation Damien Lespiau
2014-09-19 10:03   ` Ville Syrjälä
2014-09-27 14:17     ` Damien Lespiau
2014-10-29 18:42       ` Ville Syrjälä
2014-09-04 11:27 ` [PATCH 50/89] drm/i915/skl: Read the pipe WM HW state Damien Lespiau
2014-10-29 19:02   ` Ville Syrjälä
2014-10-30 12:03     ` Damien Lespiau
2014-09-04 11:27 ` [PATCH 51/89] drm/i915/gen9: Add 2us read latency to WM level Damien Lespiau
2014-09-19 10:04   ` Ville Syrjälä
2014-09-04 11:27 ` [PATCH 52/89] drm/i915/gen9: Disable WM if corresponding latency is 0 Damien Lespiau
2014-09-19 10:05   ` Ville Syrjälä
2014-09-24 14:06     ` Damien Lespiau
2014-10-29 19:05       ` Ville Syrjälä
2014-09-04 11:27 ` [PATCH 53/89] drm/i915/skl: Gen9 Forcewake Damien Lespiau
2014-09-10 13:44   ` Mika Kuoppala
2014-09-16 13:49     ` [PATCH 53/89 v2] " Damien Lespiau
2014-09-04 11:27 ` [PATCH 54/89] drm/i915/skl: Enable Gen9 RC6 Damien Lespiau
2014-09-22 13:15   ` Mika Kuoppala
2014-09-24 17:58     ` Bob Wang
2014-09-04 11:27 ` [PATCH 55/89] drm/i915/skl: Gen9 multi-engine forcewake Damien Lespiau
2014-09-22 15:11   ` Mika Kuoppala
2014-09-24 18:08     ` Bob Wang
2014-09-25  7:32       ` Mika Kuoppala
2014-11-03 17:09         ` [PATCH 55/59 v4] " Damien Lespiau
2014-11-19 13:25           ` Mika Kuoppala
2014-09-04 11:27 ` [PATCH 56/89] drm/i915: Gen9 shadowed registers Damien Lespiau
2014-09-24 13:36   ` Mika Kuoppala
2014-09-24 18:16     ` Bob Wang
2014-09-25  8:58       ` Mika Kuoppala
2014-11-03 17:45         ` [PATCH 56/89 v4] " Damien Lespiau
2014-11-19 13:25           ` Mika Kuoppala
2014-09-04 11:27 ` [PATCH 57/89] drm/i915: Rewrite ABS_DIFF() in a safer manner Damien Lespiau
2014-09-04 12:11   ` Jani Nikula
2014-09-04 12:32     ` Damien Lespiau
2014-09-04 13:11       ` Daniel Vetter
2014-09-04 11:27 ` [PATCH 58/89] drm/i915/skl: Register definitions for SKL Clocks Damien Lespiau
2014-09-22 18:17   ` Paulo Zanoni
2014-10-01 10:51     ` M, Satheeshakrishna
2014-11-04 16:11     ` [PATCH 58/89 v5] " Damien Lespiau
2014-09-04 11:27 ` [PATCH 59/89] drm/i915/skl: Structure/enum definitions for SKL clocks Damien Lespiau
2014-09-22 18:25   ` Paulo Zanoni
2014-11-04 16:12     ` Damien Lespiau
2014-11-05  9:11       ` Daniel Vetter
2014-09-04 11:27 ` [PATCH 60/89] drm/i915/skl: CD clock back calculation for SKL Damien Lespiau
2014-09-22 19:19   ` Paulo Zanoni
2014-10-01 10:51     ` M, Satheeshakrishna
2014-11-04 16:15     ` [PATCH 60/89 v5] " Damien Lespiau
2014-09-04 11:27 ` [PATCH 61/89] drm/i915/skl: Determine enabled PLL and its linkrate/pixel clock Damien Lespiau
2014-09-22 20:12   ` Paulo Zanoni
2014-10-01 10:51     ` M, Satheeshakrishna
2014-10-03 18:25       ` Paulo Zanoni
2014-11-04 16:17     ` [PATCH 61/89 v4] " Damien Lespiau
2014-09-04 11:27 ` [PATCH 62/89] drm/i915/skl: Query DPLL attached to port on SKL Damien Lespiau
2014-09-22 20:24   ` Paulo Zanoni
2014-10-01 10:51     ` M, Satheeshakrishna
2014-11-04 16:19     ` [PATCH 62/89 v3] " Damien Lespiau
2014-09-04 11:27 ` [PATCH 63/89] drm/i915/skl: Define shared DPLLs for Skylake Damien Lespiau
2014-09-23 14:28   ` Paulo Zanoni
2014-10-01 10:52     ` M, Satheeshakrishna
2014-09-04 11:27 ` [PATCH 64/89] drm/i915/skl: Adjust the port PLL selection code Damien Lespiau
2014-09-23 14:39   ` Paulo Zanoni
2014-09-04 11:27 ` [PATCH 65/89] drm/i915/skl: Always use DPLL0 for eDP Damien Lespiau
2014-09-23 15:07   ` Paulo Zanoni
2014-10-01 10:52     ` M, Satheeshakrishna
2014-09-04 11:27 ` [PATCH 66/89] drm/i915/skl: Implementation of SKL DPLL programming Damien Lespiau
2014-09-23 18:05   ` Paulo Zanoni
2014-10-01 10:52     ` M, Satheeshakrishna
2014-11-04 16:26     ` [PATCH 66/89 v9] " Damien Lespiau
2014-11-07 19:56       ` Paulo Zanoni
2015-05-13 14:54   ` [PATCH 66/89] " Tvrtko Ursulin
2015-05-13 15:31     ` Damien Lespiau
2014-09-04 11:27 ` [PATCH 67/89] drm/i915/skl: Provide skl-specific pll hw state cross-checking Damien Lespiau
2014-09-23 18:07   ` Paulo Zanoni
2014-09-04 11:27 ` [PATCH 68/89] drm/i915/skl: Apply eDP WA only for gen < 9 Damien Lespiau
2014-09-23 18:11   ` Paulo Zanoni
2014-09-04 11:27 ` [PATCH 69/89] drm/i915/skl: Adding power domains for AUX controllers Damien Lespiau
2014-09-16 12:35   ` Imre Deak
2014-09-18 13:56     ` Damien Lespiau
2014-09-18 14:23       ` Imre Deak
2014-09-18 14:29         ` Ville Syrjälä
2014-11-05 14:23     ` [PATCH 69/89 v5] " Damien Lespiau
2014-09-04 11:27 ` [PATCH 70/89] drm/i915/skl: Register definition for SKL power well Damien Lespiau
2014-09-16 12:43   ` Imre Deak
2014-09-04 11:27 ` [PATCH 71/89] drm/i915/skl: Implementation of SKL display power well support Damien Lespiau
2014-09-16 13:56   ` Imre Deak
2014-09-16 14:19     ` Imre Deak
2014-09-04 11:27 ` [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction Damien Lespiau
2014-09-16 13:19   ` Imre Deak
2014-09-16 16:13     ` Daniel Vetter
2014-11-07 12:08     ` Damien Lespiau
2014-11-10 19:21       ` Imre Deak
2014-11-11 12:22         ` Damien Lespiau
2014-11-11 13:11           ` Imre Deak
2014-11-11 14:43           ` Daniel Vetter
2014-11-11 14:41         ` Daniel Vetter
2014-11-07 13:11     ` Damien Lespiau
2014-11-07 13:31       ` Ville Syrjälä
2014-11-07 13:49         ` Damien Lespiau
2014-11-07 14:05           ` Ville Syrjälä
2014-09-04 11:27 ` [PATCH 73/89] drm/i915/skl: Enabling MISC IO power well Damien Lespiau
2014-09-16 14:12   ` Imre Deak
2014-09-04 11:27 ` [PATCH 74/89] drm/i915/skl: Implement queue_flip Damien Lespiau
2014-09-23 20:06   ` Paulo Zanoni
2014-09-29 16:54     ` Damien Lespiau
2014-09-29 17:13     ` [PATCH 74/89 v4] " Damien Lespiau
2014-09-30 12:08       ` Paulo Zanoni
2014-09-30 12:19         ` Damien Lespiau
2014-09-04 11:27 ` [PATCH 75/89] drm/i915/skl: fetch, enable/disable pfit as needed Damien Lespiau
2014-09-23 20:50   ` Paulo Zanoni
2014-09-24 10:44     ` Damien Lespiau
2014-09-25 14:48     ` Jesse Barnes
2014-09-25 14:55       ` Damien Lespiau
2014-09-25 17:58   ` [PATCH] drm/i915/skl: fetch, enable/disable pfit as needed v2 Jesse Barnes
2014-09-25 18:06     ` Paulo Zanoni
2014-09-29 13:51       ` Damien Lespiau
2014-09-04 11:27 ` [PATCH 76/89] drm/i915/skl: Store the new WM state at the very end of the update Damien Lespiau
2014-10-29 19:19   ` Ville Syrjälä
2014-09-04 11:27 ` [PATCH 77/89] drm/i915: Introduce a for_each_plane() macro Damien Lespiau
2014-09-04 13:26   ` Daniel Vetter
2014-09-04 13:32   ` Chris Wilson
2014-09-04 14:00     ` Daniel Vetter
2014-09-04 14:05       ` Damien Lespiau
2014-09-04 14:16         ` Daniel Vetter
2014-09-04 14:02     ` Damien Lespiau
2014-09-04 11:27 ` [PATCH 78/89] drm/i915/skl: Flush the WM configuration Damien Lespiau
2014-09-19 10:46   ` Ville Syrjälä
2014-09-04 11:27 ` [PATCH 79/89] drm/i915/skl: Read back the DDB allocation hw state Damien Lespiau
2014-09-19 10:54   ` Ville Syrjälä
2014-09-04 11:27 ` [PATCH 80/89] drm/i915/skl: Augment the latency debugfs files for SKL Damien Lespiau
2014-09-19 10:53   ` Ville Syrjälä
2014-09-29 13:37     ` [PATCH 80/89 v2] " Damien Lespiau
2014-09-04 11:27 ` [PATCH 81/89] drm/i915/skl: Expose skl_ddb_get_hw_state() Damien Lespiau
2014-10-29 19:21   ` Ville Syrjälä
2014-10-29 23:49     ` Damien Lespiau
2014-09-04 11:27 ` [PATCH 82/89] drm/i915/skl: Add a debugfs file to dump the DDB allocation Damien Lespiau
2014-10-29 19:23   ` Ville Syrjälä
2014-09-04 11:27 ` [PATCH 83/89] drm/i915/skl: Check the DDB state at modeset Damien Lespiau
2014-09-04 13:27   ` Daniel Vetter
2014-10-29 19:16     ` Ville Syrjälä
2014-09-04 11:27 ` [PATCH 84/89] drm/i915/skl: add turbo support Damien Lespiau
2014-09-26 14:55   ` Mika Kuoppala
2014-09-04 11:27 ` [PATCH 85/89] drm/i915/skl: Retrieve the frequency limits Damien Lespiau
2014-09-26 15:09   ` Mika Kuoppala
2014-09-04 11:27 ` [PATCH 86/89] drm/i915: only reset media, blt, and render engines on GPU hangs Damien Lespiau
2014-09-04 12:03   ` Jani Nikula
2014-09-04 12:29     ` Damien Lespiau
2014-09-04 13:13       ` Daniel Vetter
2014-09-04 15:46       ` Jesse Barnes
2014-09-04 12:36   ` Mika Kuoppala
2014-09-04 11:27 ` [PATCH 87/89] drm/i915/skl: AUX irqs have moved Damien Lespiau
2014-09-26 15:21   ` Mika Kuoppala
2014-09-04 11:27 ` [PATCH 88/89] drm/i915/skl: Add Gen9 LRC size Damien Lespiau
2014-09-04 11:27 ` [PATCH 89/89] drm/i915/skl: Disable contexts if execlists aren't enabled Damien Lespiau
2014-09-26 15:28   ` Mika Kuoppala
2014-09-26 15:47     ` Chris Wilson
2014-09-04 14:16 ` [PATCH 00/89] Basic Skylake enabling (reviewers) Damien Lespiau
2014-09-16 14:51   ` Thomas Wood
2014-10-17 14:29   ` Damien Lespiau

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.