* [RFC PATCH 0/2] drm/i915: get backlight max from vbt
@ 2015-05-07 12:59 Jani Nikula
2015-05-07 12:59 ` [RFC PATCH 1/2] drm/i915: move intel_hrawclk() to intel_display.c Jani Nikula
2015-05-07 13:00 ` [RFC PATCH 2/2] drm/i915: initialize backlight max from VBT Jani Nikula
0 siblings, 2 replies; 3+ messages in thread
From: Jani Nikula @ 2015-05-07 12:59 UTC (permalink / raw)
To: intel-gfx; +Cc: jani.nikula
Found this while cleaning up some old branches I have in my repo...
I'm posting this more as archival for posterity than as a serious
attempt to get this merged. There was a bunch of archeology involved in
figuring out the Hz to PWM modulation frequency conversion, so someone
might find that useful.
Particularly the vlv setup could use some cleanup and only falling back
to the hardcoded value if vbt is not set. And the hardcoded default
could now be expressed in Hz instead of raw pwm value. But meh until
someone really needs this.
BR,
Jani.
Jani Nikula (2):
drm/i915: move intel_hrawclk() to intel_display.c
drm/i915: initialize backlight max from VBT
drivers/gpu/drm/i915/i915_drv.h | 2 +
drivers/gpu/drm/i915/i915_reg.h | 1 +
drivers/gpu/drm/i915/intel_display.c | 33 ++++++++
drivers/gpu/drm/i915/intel_dp.c | 34 --------
drivers/gpu/drm/i915/intel_drv.h | 1 +
drivers/gpu/drm/i915/intel_panel.c | 160 +++++++++++++++++++++++++++++++++--
6 files changed, 190 insertions(+), 41 deletions(-)
--
2.1.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 3+ messages in thread
* [RFC PATCH 1/2] drm/i915: move intel_hrawclk() to intel_display.c
2015-05-07 12:59 [RFC PATCH 0/2] drm/i915: get backlight max from vbt Jani Nikula
@ 2015-05-07 12:59 ` Jani Nikula
2015-05-07 13:00 ` [RFC PATCH 2/2] drm/i915: initialize backlight max from VBT Jani Nikula
1 sibling, 0 replies; 3+ messages in thread
From: Jani Nikula @ 2015-05-07 12:59 UTC (permalink / raw)
To: intel-gfx; +Cc: jani.nikula
Make it available outside of intel_dp.c.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 33 +++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_dp.c | 34 ----------------------------------
drivers/gpu/drm/i915/intel_drv.h | 1 +
3 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index c297cdc136e5..6cf7ad29b378 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -142,6 +142,39 @@ intel_pch_rawclk(struct drm_device *dev)
return I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK;
}
+/* hrawclock is 1/4 the FSB frequency */
+int intel_hrawclk(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ uint32_t clkcfg;
+
+ /* There is no CLKCFG reg in Valleyview. VLV hrawclk is 200 MHz */
+ if (IS_VALLEYVIEW(dev))
+ return 200;
+
+ clkcfg = I915_READ(CLKCFG);
+ switch (clkcfg & CLKCFG_FSB_MASK) {
+ case CLKCFG_FSB_400:
+ return 100;
+ case CLKCFG_FSB_533:
+ return 133;
+ case CLKCFG_FSB_667:
+ return 166;
+ case CLKCFG_FSB_800:
+ return 200;
+ case CLKCFG_FSB_1067:
+ return 266;
+ case CLKCFG_FSB_1333:
+ return 333;
+ /* these two are just a guess; one of them might be right */
+ case CLKCFG_FSB_1600:
+ case CLKCFG_FSB_1600_ALT:
+ return 400;
+ default:
+ return 133;
+ }
+}
+
static inline u32 /* units of 100MHz */
intel_fdi_link_freq(struct drm_device *dev)
{
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5bd73ad310d4..9d5505ec5904 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -254,40 +254,6 @@ static void intel_dp_unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes)
dst[i] = src >> ((3-i) * 8);
}
-/* hrawclock is 1/4 the FSB frequency */
-static int
-intel_hrawclk(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- uint32_t clkcfg;
-
- /* There is no CLKCFG reg in Valleyview. VLV hrawclk is 200 MHz */
- if (IS_VALLEYVIEW(dev))
- return 200;
-
- clkcfg = I915_READ(CLKCFG);
- switch (clkcfg & CLKCFG_FSB_MASK) {
- case CLKCFG_FSB_400:
- return 100;
- case CLKCFG_FSB_533:
- return 133;
- case CLKCFG_FSB_667:
- return 166;
- case CLKCFG_FSB_800:
- return 200;
- case CLKCFG_FSB_1067:
- return 266;
- case CLKCFG_FSB_1333:
- return 333;
- /* these two are just a guess; one of them might be right */
- case CLKCFG_FSB_1600:
- case CLKCFG_FSB_1600_ALT:
- return 400;
- default:
- return 133;
- }
-}
-
static void
intel_dp_init_panel_power_sequencer(struct drm_device *dev,
struct intel_dp *intel_dp);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 930ea6916d9f..3fc9c2df1689 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -981,6 +981,7 @@ void i915_audio_component_cleanup(struct drm_i915_private *dev_priv);
extern const struct drm_plane_funcs intel_plane_funcs;
bool intel_has_pending_fb_unpin(struct drm_device *dev);
int intel_pch_rawclk(struct drm_device *dev);
+int intel_hrawclk(struct drm_device *dev);
void intel_mark_busy(struct drm_device *dev);
void intel_mark_idle(struct drm_device *dev);
void intel_crtc_restore_mode(struct drm_crtc *crtc);
--
2.1.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [RFC PATCH 2/2] drm/i915: initialize backlight max from VBT
2015-05-07 12:59 [RFC PATCH 0/2] drm/i915: get backlight max from vbt Jani Nikula
2015-05-07 12:59 ` [RFC PATCH 1/2] drm/i915: move intel_hrawclk() to intel_display.c Jani Nikula
@ 2015-05-07 13:00 ` Jani Nikula
1 sibling, 0 replies; 3+ messages in thread
From: Jani Nikula @ 2015-05-07 13:00 UTC (permalink / raw)
To: intel-gfx; +Cc: jani.nikula
Normally we determine the backlight PWM modulation frequency (which we
also use as backlight max value) from the backlight registers at module
load time, expecting the registers have been initialized by the BIOS. If
this is not the case, we fail.
The VBT contains the backlight modulation frequency in Hz. Add platform
specific functions to convert the frequency in Hz to backlight PWM
modulation frequency, and use them to initialize the backlight when the
registers are not initialized by the BIOS.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 2 +
drivers/gpu/drm/i915/i915_reg.h | 1 +
drivers/gpu/drm/i915/intel_panel.c | 160 +++++++++++++++++++++++++++++++++++--
3 files changed, 156 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 87fe4f7d5ce5..82f3d3120190 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -602,6 +602,8 @@ struct drm_i915_display_funcs {
uint32_t level);
void (*disable_backlight)(struct intel_connector *connector);
void (*enable_backlight)(struct intel_connector *connector);
+ uint32_t (*backlight_hz_to_pwm)(struct intel_connector *connector,
+ uint32_t hz);
};
enum forcewake_domain_id {
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index ebe55704fa0e..73bd94ea4d7d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6168,6 +6168,7 @@ enum skl_disp_power_wells {
#define SOUTH_CHICKEN2 0xc2004
#define FDI_MPHY_IOSFSB_RESET_STATUS (1<<13)
#define FDI_MPHY_IOSFSB_RESET_CTL (1<<12)
+#define PWM_GRANULARITY (1<<5) /* LPT */
#define DPLS_EDP_PPS_FIX_DIS (1<<0)
#define _FDI_RXA_CHICKEN 0xc200c
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 7d83527f95f7..319cd922f8f3 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -1166,10 +1166,125 @@ static void intel_backlight_device_unregister(struct intel_connector *connector)
#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
/*
- * Note: The setup hooks can't assume pipe is set!
+ * HSW/BDW: This value represents the period of the PWM stream in clock periods
+ * multiplied by 128 (default increment) or 16 (alternate increment, selected in
+ * LPT SOUTH_CHICKEN2 register bit 5).
*
- * XXX: Query mode clock or hardware clock and program PWM modulation frequency
- * appropriately when it's 0. Use VBT and/or sane defaults.
+ * XXX: This only works when driving the PCH PWM. When driving the CPU PWM on
+ * the utility pin, the granularity needs to be determined by BLC_PWM_CTL bit
+ * 27.
+ */
+static u32 hsw_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+ struct drm_device *dev = connector->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 mul, clock;
+
+ if (I915_READ(SOUTH_CHICKEN2) & PWM_GRANULARITY)
+ mul = 16;
+ else
+ mul = 128;
+
+ if (dev_priv->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE)
+ clock = MHz(135); /* LPT:H */
+ else
+ clock = MHz(24); /* LPT:LP */
+
+ return clock / (pwm_freq_hz * mul);
+}
+
+/*
+ * ILK/SNB/IVB: This value represents the period of the PWM stream in PCH
+ * display raw clocks multiplied by 128.
+ */
+static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+ struct drm_device *dev = connector->base.dev;
+ int clock = MHz(intel_pch_rawclk(dev));
+
+ return clock / (pwm_freq_hz * 128);
+}
+
+/*
+ * Gen2: This field determines the number of time base events (display core
+ * clock frequency/32) in total for a complete cycle of modulated backlight
+ * control.
+ *
+ * Gen3: A time base event equals the display core clock ([DevPNV] HRAW clock)
+ * divided by 32.
+ */
+static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+ struct drm_device *dev = connector->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int clock;
+
+ if (IS_PINEVIEW(dev))
+ clock = intel_hrawclk(dev);
+ else
+ clock = 1000 * dev_priv->display.get_display_clock_speed(dev);
+
+ return clock / (pwm_freq_hz * 32);
+}
+
+/*
+ * Gen4: This value represents the period of the PWM stream in display core
+ * clocks multiplied by 128.
+ */
+static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+ struct drm_device *dev = connector->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int clock = 1000 * dev_priv->display.get_display_clock_speed(dev);
+
+ return clock / (pwm_freq_hz * 128);
+}
+
+/*
+ * VLV: This value represents the period of the PWM stream in display core
+ * clocks ([DevCTG] 100MHz HRAW clocks) multiplied by 128 or 25MHz S0IX clocks
+ * multiplied by 16.
+ *
+ * XXX: Where is this selected???
+ */
+static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+{
+ if (1)
+ return MHz(25) / (pwm_freq_hz * 16);
+ else
+ return MHz(100) / (pwm_freq_hz * 128);
+}
+
+static u32 get_backlight_max_vbt(struct intel_connector *connector)
+{
+ struct drm_device *dev = connector->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz;
+ u32 pwm;
+
+ if (!pwm_freq_hz) {
+ DRM_DEBUG_KMS("backlight frequency not specified in VBT\n");
+ return 0;
+ }
+
+ if (!dev_priv->display.backlight_hz_to_pwm) {
+ DRM_DEBUG_KMS("backlight frequency setting from VBT currently not supported on this platform\n");
+ return 0;
+ }
+
+ pwm = dev_priv->display.backlight_hz_to_pwm(connector, pwm_freq_hz);
+ if (!pwm) {
+ DRM_DEBUG_KMS("backlight frequency conversion failed\n");
+ return 0;
+ }
+
+ DRM_DEBUG_KMS("backlight frequency %u Hz from VBT\n", pwm_freq_hz);
+
+ return pwm;
+}
+
+/*
+ * Note: The setup hooks can't assume pipe is set!
*/
static u32 get_backlight_min_vbt(struct intel_connector *connector)
{
@@ -1209,6 +1324,10 @@ static int bdw_setup_backlight(struct intel_connector *connector, enum pipe unus
pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
panel->backlight.max = pch_ctl2 >> 16;
+
+ if (!panel->backlight.max)
+ panel->backlight.max = get_backlight_max_vbt(connector);
+
if (!panel->backlight.max)
return -ENODEV;
@@ -1235,6 +1354,10 @@ static int pch_setup_backlight(struct intel_connector *connector, enum pipe unus
pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
panel->backlight.max = pch_ctl2 >> 16;
+
+ if (!panel->backlight.max)
+ panel->backlight.max = get_backlight_max_vbt(connector);
+
if (!panel->backlight.max)
return -ENODEV;
@@ -1266,12 +1389,18 @@ static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unu
panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
panel->backlight.max = ctl >> 17;
- if (panel->backlight.combination_mode)
- panel->backlight.max *= 0xff;
+
+ if (!panel->backlight.max) {
+ panel->backlight.max = get_backlight_max_vbt(connector);
+ panel->backlight.max >>= 1;
+ }
if (!panel->backlight.max)
return -ENODEV;
+ if (panel->backlight.combination_mode)
+ panel->backlight.max *= 0xff;
+
panel->backlight.min = get_backlight_min_vbt(connector);
val = i9xx_get_backlight(connector);
@@ -1295,12 +1424,16 @@ static int i965_setup_backlight(struct intel_connector *connector, enum pipe unu
ctl = I915_READ(BLC_PWM_CTL);
panel->backlight.max = ctl >> 16;
- if (panel->backlight.combination_mode)
- panel->backlight.max *= 0xff;
+
+ if (!panel->backlight.max)
+ panel->backlight.max = get_backlight_max_vbt(connector);
if (!panel->backlight.max)
return -ENODEV;
+ if (panel->backlight.combination_mode)
+ panel->backlight.max *= 0xff;
+
panel->backlight.min = get_backlight_min_vbt(connector);
val = i9xx_get_backlight(connector);
@@ -1340,6 +1473,10 @@ static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe
ctl = I915_READ(VLV_BLC_PWM_CTL(pipe));
panel->backlight.max = ctl >> 16;
+
+ if (!panel->backlight.max)
+ panel->backlight.max = get_backlight_max_vbt(connector);
+
if (!panel->backlight.max)
return -ENODEV;
@@ -1366,6 +1503,10 @@ bxt_setup_backlight(struct intel_connector *connector, enum pipe unused)
panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
panel->backlight.max = I915_READ(BXT_BLC_PWM_FREQ1);
+
+ if (!panel->backlight.max)
+ panel->backlight.max = get_backlight_max_vbt(connector);
+
if (!panel->backlight.max)
return -ENODEV;
@@ -1441,30 +1582,35 @@ void intel_panel_init_backlight_funcs(struct drm_device *dev)
dev_priv->display.disable_backlight = pch_disable_backlight;
dev_priv->display.set_backlight = bdw_set_backlight;
dev_priv->display.get_backlight = bdw_get_backlight;
+ dev_priv->display.backlight_hz_to_pwm = hsw_hz_to_pwm;
} else if (HAS_PCH_SPLIT(dev)) {
dev_priv->display.setup_backlight = pch_setup_backlight;
dev_priv->display.enable_backlight = pch_enable_backlight;
dev_priv->display.disable_backlight = pch_disable_backlight;
dev_priv->display.set_backlight = pch_set_backlight;
dev_priv->display.get_backlight = pch_get_backlight;
+ dev_priv->display.backlight_hz_to_pwm = pch_hz_to_pwm;
} else if (IS_VALLEYVIEW(dev)) {
dev_priv->display.setup_backlight = vlv_setup_backlight;
dev_priv->display.enable_backlight = vlv_enable_backlight;
dev_priv->display.disable_backlight = vlv_disable_backlight;
dev_priv->display.set_backlight = vlv_set_backlight;
dev_priv->display.get_backlight = vlv_get_backlight;
+ dev_priv->display.backlight_hz_to_pwm = vlv_hz_to_pwm;
} else if (IS_GEN4(dev)) {
dev_priv->display.setup_backlight = i965_setup_backlight;
dev_priv->display.enable_backlight = i965_enable_backlight;
dev_priv->display.disable_backlight = i965_disable_backlight;
dev_priv->display.set_backlight = i9xx_set_backlight;
dev_priv->display.get_backlight = i9xx_get_backlight;
+ dev_priv->display.backlight_hz_to_pwm = i965_hz_to_pwm;
} else {
dev_priv->display.setup_backlight = i9xx_setup_backlight;
dev_priv->display.enable_backlight = i9xx_enable_backlight;
dev_priv->display.disable_backlight = i9xx_disable_backlight;
dev_priv->display.set_backlight = i9xx_set_backlight;
dev_priv->display.get_backlight = i9xx_get_backlight;
+ dev_priv->display.backlight_hz_to_pwm = i9xx_hz_to_pwm;
}
}
--
2.1.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2015-05-07 12:58 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-07 12:59 [RFC PATCH 0/2] drm/i915: get backlight max from vbt Jani Nikula
2015-05-07 12:59 ` [RFC PATCH 1/2] drm/i915: move intel_hrawclk() to intel_display.c Jani Nikula
2015-05-07 13:00 ` [RFC PATCH 2/2] drm/i915: initialize backlight max from VBT Jani Nikula
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox