Skip to content

Commit ee7b9f9

Browse files
jbarnes993danvet
authored andcommitted
drm/i915: manage PCH PLLs separately from pipes
PCH PLLs aren't required for outputs on the CPU, so we shouldn't just treat them as part of the pipe. So split the code out and manage PCH PLLs separately, allocating them when needed or trying to re-use existing PCH PLL setups when the timings match. v2: add num_pch_pll field to dev_priv (Daniel) don't NULL the pch_pll pointer in disable or DPMS will fail (Jesse) put register offsets in pll struct (Chris) v3: Decouple enable/disable of PLLs from get/put. v4: Track temporary PLL disabling during modeset v5: Tidy PLL initialisation by only checking for num_pch_pll == 0 (Eugeni) v6: Avoid mishandling allocation failure by embedding the small array of PLLs into the device struct Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=44309 Signed-off-by: Jesse Barnes <[email protected]> (up to v2) Signed-off-by: Chris Wilson <[email protected]> (v3+) Reviewed-by: Eugeni Dodonov <[email protected]> Tested-by: Jesse Barnes <[email protected]> Reviewed-by: Jesse Barnes <[email protected]> Signed-off-by: Daniel Vetter <[email protected]>
1 parent c2798b1 commit ee7b9f9

File tree

7 files changed

+222
-81
lines changed

7 files changed

+222
-81
lines changed

drivers/gpu/drm/i915/i915_drv.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,18 +377,23 @@ void intel_detect_pch(struct drm_device *dev)
377377

378378
if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
379379
dev_priv->pch_type = PCH_IBX;
380+
dev_priv->num_pch_pll = 2;
380381
DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
381382
} else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
382383
dev_priv->pch_type = PCH_CPT;
384+
dev_priv->num_pch_pll = 2;
383385
DRM_DEBUG_KMS("Found CougarPoint PCH\n");
384386
} else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
385387
/* PantherPoint is CPT compatible */
386388
dev_priv->pch_type = PCH_CPT;
389+
dev_priv->num_pch_pll = 2;
387390
DRM_DEBUG_KMS("Found PatherPoint PCH\n");
388391
} else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
389392
dev_priv->pch_type = PCH_LPT;
393+
dev_priv->num_pch_pll = 0;
390394
DRM_DEBUG_KMS("Found LynxPoint PCH\n");
391395
}
396+
BUG_ON(dev_priv->num_pch_pll > I915_NUM_PLLS);
392397
}
393398
pci_dev_put(pch);
394399
}

drivers/gpu/drm/i915/i915_drv.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ enum port {
7878

7979
#define for_each_pipe(p) for ((p) = 0; (p) < dev_priv->num_pipe; (p)++)
8080

81+
struct intel_pch_pll {
82+
int refcount; /* count of number of CRTCs sharing this PLL */
83+
int active; /* count of number of active CRTCs (i.e. DPMS on) */
84+
bool on; /* is the PLL actually active? Disabled during modeset */
85+
int pll_reg;
86+
int fp0_reg;
87+
int fp1_reg;
88+
};
89+
#define I915_NUM_PLLS 2
90+
8191
/* Interface history:
8292
*
8393
* 1.1: Original.
@@ -233,6 +243,7 @@ struct drm_i915_display_funcs {
233243
struct drm_display_mode *adjusted_mode,
234244
int x, int y,
235245
struct drm_framebuffer *old_fb);
246+
void (*off)(struct drm_crtc *crtc);
236247
void (*write_eld)(struct drm_connector *connector,
237248
struct drm_crtc *crtc);
238249
void (*fdi_link_train)(struct drm_crtc *crtc);
@@ -391,6 +402,7 @@ typedef struct drm_i915_private {
391402
unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
392403
int vblank_pipe;
393404
int num_pipe;
405+
int num_pch_pll;
394406

395407
/* For hangcheck timer */
396408
#define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */
@@ -753,6 +765,8 @@ typedef struct drm_i915_private {
753765
wait_queue_head_t pending_flip_queue;
754766
bool flip_pending_is_done;
755767

768+
struct intel_pch_pll pch_plls[I915_NUM_PLLS];
769+
756770
/* Reclocking support */
757771
bool render_reclock_avail;
758772
bool lvds_downclock_avail;

drivers/gpu/drm/i915/i915_reg.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3402,15 +3402,15 @@
34023402

34033403
#define _PCH_DPLL_A 0xc6014
34043404
#define _PCH_DPLL_B 0xc6018
3405-
#define PCH_DPLL(pipe) (pipe == 0 ? _PCH_DPLL_A : _PCH_DPLL_B)
3405+
#define _PCH_DPLL(pll) (pll == 0 ? _PCH_DPLL_A : _PCH_DPLL_B)
34063406

34073407
#define _PCH_FPA0 0xc6040
34083408
#define FP_CB_TUNE (0x3<<22)
34093409
#define _PCH_FPA1 0xc6044
34103410
#define _PCH_FPB0 0xc6048
34113411
#define _PCH_FPB1 0xc604c
3412-
#define PCH_FP0(pipe) (pipe == 0 ? _PCH_FPA0 : _PCH_FPB0)
3413-
#define PCH_FP1(pipe) (pipe == 0 ? _PCH_FPA1 : _PCH_FPB1)
3412+
#define _PCH_FP0(pll) (pll == 0 ? _PCH_FPA0 : _PCH_FPB0)
3413+
#define _PCH_FP1(pll) (pll == 0 ? _PCH_FPA1 : _PCH_FPB1)
34143414

34153415
#define PCH_DPLL_TEST 0xc606c
34163416

drivers/gpu/drm/i915/i915_suspend.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
4040
return false;
4141

4242
if (HAS_PCH_SPLIT(dev))
43-
dpll_reg = PCH_DPLL(pipe);
43+
dpll_reg = _PCH_DPLL(pipe);
4444
else
4545
dpll_reg = (pipe == PIPE_A) ? _DPLL_A : _DPLL_B;
4646

0 commit comments

Comments
 (0)