Re: Power saving using Display port HPD

Arun Chandran
2014-04-14T07:43:16Z

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

Hi,

Finally I did it. Interested parties can find it below. If anybody has
better ways to do it please suggest.

1) Revert the commit 77961eb984c7e5394bd29cc7be2ab0bf0cc7e7b1.
With this commit DP hotplug events are not coming after doing "xset dpms
force off"

commit bfcbf45b5b458ebdc38118ca67279a1cd90e085d
Author: Arun Chandran <achandran@mvista.com>
Date: Fri Apr 11 16:16:32 2014 +0530

Revert "drm/i915: power domains: add vlv power wells"

This reverts commit 77961eb984c7e5394bd29cc7be2ab0bf0cc7e7b1.

2) Modify the code to inject uvents when DP cable is removed/inserted

#################################
diff --git a/drivers/gpu/drm/i915/i915_irq.c
b/drivers/gpu/drm/i915/i915_irq.c
index 4069703..84b3251 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -987,6 +987,12 @@ static bool intel_hpd_irq_event(struct drm_device *dev,
*/
#define I915_REENABLE_HOTPLUG_DELAY (2*60*1000)

+static int hpd_status;
+static struct intel_dp *intel_attached_dp(struct drm_connector *connector)
+{
+ return enc_to_intel_dp(&intel_attached_encoder(connector)->base);
+}
+
static void i915_hotplug_work_func(struct work_struct *work)
{
struct drm_i915_private *dev_priv =
@@ -994,6 +1000,7 @@ static void i915_hotplug_work_func(struct work_struct
*work)
struct drm_device *dev = dev_priv->dev;
struct drm_mode_config *mode_config = &dev->mode_config;
struct intel_connector *intel_connector;
+ struct intel_dp *intel_dp;
struct intel_encoder *intel_encoder;
struct drm_connector *connector;
unsigned long irqflags;
@@ -1045,6 +1052,15 @@ static void i915_hotplug_work_func(struct
work_struct *work)
list_for_each_entry(connector, &mode_config->connector_list, head) {
intel_connector = to_intel_connector(connector);
intel_encoder = intel_connector->encoder;
+ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+ DRM_DEBUG_KMS("arun edp %x\n", hpd_status);
+ intel_dp = intel_attached_dp(connector);
+
+ if (hpd_status & (1 << 28))
+ kobject_uevent(&intel_dp->aux.ddc.dev.kobj,
KOBJ_ADD);
+ else
+ kobject_uevent(&intel_dp->aux.ddc.dev.kobj,
KOBJ_REMOVE);
+ }
if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
if (intel_encoder->hot_plug)
intel_encoder->hot_plug(intel_encoder);
@@ -1639,11 +1655,14 @@ static void valleyview_pipestat_irq_handler(struct
drm_device *dev, u32 iir)
gmbus_irq_handler(dev);
}

+
static void i9xx_hpd_irq_handler(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);

+ hpd_status = hotplug_status;
+
if (IS_G4X(dev)) {
u32 hotplug_trigger = hotplug_status &
HOTPLUG_INT_STATUS_G4X;

##########################################

3) Add a udev rule
arun@arun-valley-view:~$ cat /etc/udev/rules.d/95-dpmonitor-hotplug.rules
KERNEL=="i2c-7", SUBSYSTEM=="i2c", ATTR{name}=="DPDDC-C",
RUN+="/usr/local/bin/hpd.sh"

4) Finally the script doing on/off

arun@arun-valley-view:~$ cat /usr/local/bin/hpd.sh
#! /bin/bash
export XAUTHORITY=/home/arun/.Xauthority
export DISPLAY=:0

echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" >> /tmp/hpd.log
echo "`date`" >> /tmp/hpd.log

if [ "$ACTION" == "add" ] ; then
echo "Powering on" >> /tmp/hpd.log
xset dpms force on
fi

if [ "$ACTION" == "remove" ] ; then
echo "Powering off" >> /tmp/hpd.log
sleep 1; xset dpms force off
fi

Regards,
Arun C

On Thu, Apr 10, 2014 at 3:58 PM, Arun Chandran <achandran@mvista.com> wrote:

> Hi,
>
> On Thu, Apr 10, 2014 at 12:54 PM, Daniel Vetter <daniel@ffwll.ch> wrote:
>
>> On Thu, Apr 10, 2014 at 12:06:15PM +0530, Arun Chandran wrote:
>> > I have connected only a DP monitor on Bayley Bay platform and booting
>> > ubuntu 13.10 with the kernel
>> > http://cgit.freedesktop.org/drm-intel/log/?h=drm-intel-fixes.
>> >
>> > I am experimenting with the HPD feature of display port with debug
>> > messages enabled. (drm.debug=0xe).
>> >
>> > When I plug in/out DP cable I am able to see the below kernel messages
>> > and ubuntu desktop is displayed on the DP monitor
>> >
>> > ##############################
>> >
>> >
>> > root@arun-valley-view:~# uname -a
>> > Linux arun-valley-view 3.14.0-00528-g67e9d82 #34 SMP PREEMPT Wed Apr 9
>> > 18:48:30 IST 2014 i686 i686 i686 GNU/Linux
>> >
>> > root@arun-valley-view:~# dmesg -c
>> >
>> > [ 1028.506188] [drm:intel_hpd_irq_handler] hotplug event received,
>> > stat 0x00100000
>> > [ 1028.506217] [drm:intel_hpd_irq_handler] Received HPD interrupt on
>> > PIN 5 - cnt: 0
>> > [ 1028.513858] [drm:i915_hotplug_work_func] running encoder hotplug
>> functions
>> > [ 1028.513880] [drm:i915_hotplug_work_func] Connector eDP-1 (pin 5)
>> > received hotplug event.
>> > [ 1028.513896] [drm:i915_hotplug_work_func] Connector HDMI-A-2 (pin 5)
>> > received hotplug event.
>> > [ 1028.513913] [drm:_edp_panel_vdd_on] Turning eDP VDD on
>> > [ 1028.513931] [drm:_edp_panel_vdd_on] PP_STATUS: 0x80000008
>> > PP_CONTROL: 0xabcd000f
>> > [ 1028.515064] [drm:intel_dp_get_dpcd] DPCD: 11 0a 84 01 01 00 01 80
>> > 02 00 00 00 00 00 00
>> > [ 1028.516563] [drm:intel_dp_check_link_status] TMDS-22: channel EQ
>> > not ok, retraining
>> > [ 1028.530884] [drm:intel_dp_set_signal_levels] Using signal levels
>> 00000000
>> > [ 1028.546113] [drm:intel_dp_set_signal_levels] Using signal levels
>> 00000000
>> > [ 1028.547233] [drm:intel_dp_start_link_train] clock recovery OK
>> > [ 1028.548711] [drm:intel_dp_complete_link_train] Channel EQ done. DP
>> > Training successful
>> > [ 1028.549264] [drm:intel_dp_detect] [CONNECTOR:23:eDP-1]
>> > [ 1028.549761] [drm:intel_dp_probe_oui] Sink OUI: 00e04c
>> > [ 1028.550262] [drm:intel_dp_probe_oui] Branch OUI: 000000
>> > [ 1028.550343] [drm:intel_hdmi_detect] [CONNECTOR:21:HDMI-A-2]
>> > [ 1028.550595] [drm:gmbus_xfer] GMBUS [i915 gmbus dpc] NAK for addr:
>> 0050 r(1)
>> > [ 1028.550611] [drm:drm_do_probe_ddc_edid] drm: skipping non-existent
>> > adapter i915 gmbus dpc
>> >
>> > ##################################
>> >
>> > After booting I am executing the below steps
>> >
>> > 1) unplug DP cable.
>> >
>> > 2) Mask the pin 18 (HPD) of DP cable using a paper strip then connect it
>> > back
>> > I have checked the dmesg output and the there is no messages
>> related to
>> > HPD. So kernel is
>> > unaware that I have connected a DP monitor
>> >
>> > But still I see ubuntu desktop coming on the DP monitor. This means
>> kernel
>> > does not stop pumping display data after step 1.
>> >
>> > Is this the right behavior? . When kernel knows that the last existing
>> > display is removed (via the HPD feature) it can save power by stopping
>> the
>> > data output to DP monitor (or shutting down the DP hardware related
>> part.)
>> >
>> > Does anybody knows how to use the HPD feature to save power? Or anybody
>> has
>> > done this before?
>>
>> Yes, this is expected behaviour. Userspace asked the kernel to shovel
>> pixels to the DP screen, the kernel obeyed. If you want to kill the pipe
>> when unplugged, you need to make that policy decision in userspace.
>>
>>
> OK I understood that this is the expected behavior.
>
> In order to simulate power-saving with HPD I am now doing.
>
> 1) Boot http://cgit.freedesktop.org/drm-intel/log/?h=drm-intel-nightly<http://cgit.freedesktop.org/drm-intel/log/?h=drm-intel-fixes>
> arun@arun-valley-view:~$ uname -a
> Linux arun-valley-view 3.14.0-00345-gd22313b #35 SMP PREEMPT Thu Apr 10
> 14:54:09 IST 2014 i686 i686 i686 GNU/Linux
>
>
> 2) sudo dmesg -c > /dev/null; xset dpms force off ( I am planning to do
> this when DP cable is unplugged by sending event to userspace)
>
> Then take dmesg from serial console after display goes blank.
>
> ####################################
> arun@arun-valley-view:~$ sudo dmesg -c
> [ 955.521469] [drm:valleyview_set_rps] GPU freq request from 167 MHz
> (191) to 542 MHz (209)
> [ 956.085890] [drm:valleyview_set_rps] GPU freq request from 167 MHz
> (191) to 791 MHz (221)
> [ 956.101376] [drm:valleyview_set_rps] GPU freq request from 791 MHz
> (221) to 791 MHz (221)
> [ 956.102478] [drm:valleyview_set_rps] GPU freq request from 791 MHz
> (221) to 791 MHz (221)
> [ 956.103167] [drm:valleyview_set_rps] GPU freq request from 791 MHz
> (221) to 791 MHz (221)
> [ 958.852674] [drm:valleyview_set_rps] GPU freq request from 167 MHz
> (191) to 542 MHz (209)
> [ 963.907584] [drm:_edp_panel_vdd_on] Turning eDP VDD on
> [ 963.907614] [drm:_edp_panel_vdd_on] PP_STATUS: 0x80000008 PP_CONTROL:
> 0xabcd000f
> [ 963.907631] [drm:intel_panel_actually_set_backlight] set backlight PWM
> = 0
> [ 963.907646] [drm:intel_edp_backlight_off]
> [ 963.908150] [drm:intel_edp_panel_off] Turn eDP power off
> [ 964.109165] [drm:wait_panel_off] Wait for panel power off time
> [ 964.109194] [drm:wait_panel_status] mask b0000000 value 00000000 status
> 80000008 control abcd0000
> [ 964.153214] [drm:wait_panel_status] Wait complete
> [ 964.181035] [drm:intel_dp_link_down]
> [ 964.233101] ------------[ cut here ]------------
> [ 964.233139] WARNING: CPU: 0 PID: 1013 at
> drivers/gpu/drm/i915/intel_display.c:768 g4x_wait_for_vblank+0xa5/0xbe()
> [ 964.233150] vblank wait timed out
> [ 964.233159] Modules linked in:
> [ 964.233181] CPU: 0 PID: 1013 Comm: Xorg Tainted: G W
> 3.14.0-00345-gd22313b #35
> [ 964.233193] Hardware name: Intel Corp. VALLEYVIEW B0 PLATFORM/NOTEBOOK,
> BIOS BYTICRB1.86C.0072.R11.1401221240 01/22/2014
> [ 964.233204] 00000300 ee793d68 c090f720 c0b2bb3f ee793d80 c0436ce0
> c06f63b4 f3b40000
> [ 964.233239] 001f0040 0000041b ee793d98 c0436d5b 00000009 ee793d90
> c0b2dd12 ee793dac
> [ 964.233271] ee793dc0 c06f63b4 c0b2bb3f 00000300 c0b2dd12 000a1ab1
> 000a1ae4 f3b40000
> [ 964.233304] Call Trace:
> [ 964.233327] [<c090f720>] dump_stack+0x48/0x70
> [ 964.233349] [<c0436ce0>] warn_slowpath_common+0x63/0x7a
> [ 964.233368] [<c06f63b4>] ? g4x_wait_for_vblank+0xa5/0xbe
> [ 964.233387] [<c0436d5b>] warn_slowpath_fmt+0x26/0x2a
> [ 964.233407] [<c06f63b4>] g4x_wait_for_vblank+0xa5/0xbe
> [ 964.233426] [<c06f63f1>] intel_wait_for_vblank+0x24/0xe6
> [ 964.233447] [<c070ab0d>] intel_dp_link_down+0xdb/0x18f
> [ 964.233468] [<c070abcc>] vlv_post_disable_dp+0xb/0xd
> [ 964.233488] [<c06fdba4>] i9xx_crtc_disable+0x151/0x237
> [ 964.233510] [<c06ee8f5>] intel_crtc_update_dpms+0x56/0x68
> [ 964.233529] [<c06f85b2>] intel_connector_dpms+0x3e/0x48
> [ 964.233550] [<c06b1c01>] drm_mode_obj_set_property_ioctl+0x1c0/0x2e7
> [ 964.233573] [<c0605c99>] ? kobject_uevent+0xc/0xc
> [ 964.233592] [<c06f8574>] ? intel_modeset_check_state+0x6f/0x6f
> [ 964.233612] [<c06b1d57>]
> drm_mode_connector_property_set_ioctl+0x2f/0x37
> [ 964.233631] [<c06a9370>] drm_ioctl+0x248/0x350
> [ 964.233650] [<c06b1d28>] ? drm_mode_obj_set_property_ioctl+0x2e7/0x2e7
> [ 964.233672] [<c047e9b4>] ? __call_rcu_core+0x11/0xc2
> [ 964.233692] [<c0507280>] ? mntput_no_expire+0x20/0x108
> [ 964.233710] [<c050738a>] ? mntput+0x22/0x24
> [ 964.233728] [<c06a9128>] ? drm_ioctl_permit+0x6a/0x6a
> [ 964.233748] [<c04fde57>] do_vfs_ioctl+0x219/0x232
> [ 964.233767] [<c04fdeac>] SyS_ioctl+0x3c/0x56
> [ 964.233789] [<c0913bbe>] sysenter_do_call+0x12/0x26
> [ 964.233802] ---[ end trace a3724fec7053be94 ]---
> [ 964.284395] [drm:valleyview_update_wm] Setting FIFO watermarks - A:
> plane=2, cursor=2, B: plane=2, cursor=2, SR: plane=0, cursor=0
> [ 964.284666] [drm:check_encoder_state] [ENCODER:13:DAC-13]
> [ 964.284703] [drm:check_encoder_state] [ENCODER:14:TMDS-14]
> [ 964.284771] [drm:check_encoder_state] [ENCODER:18:TMDS-18]
> [ 964.284839] [drm:check_encoder_state] [ENCODER:20:TMDS-20]
> [ 964.284907] [drm:check_encoder_state] [ENCODER:22:TMDS-22]
> [ 964.285029] [drm:check_crtc_state] [CRTC:5]
> [ 964.285110] [drm:check_crtc_state] [CRTC:9]
> [ 964.285192] [drm:drm_mode_setcrtc] [CRTC:5]
> [ 964.285207] [drm:intel_crtc_set_config] [CRTC:5] [NOFB]
> [ 964.285226] [drm:intel_set_config_compute_mode_changes] computed
> changes for [CRTC:5], mode_changed=1, fb_changed=0
> [ 964.285240] [drm:intel_modeset_stage_output_state] [CONNECTOR:23:eDP-1]
> to [NOCRTC]
> [ 964.285252] [drm:intel_modeset_stage_output_state] encoder changed,
> full mode switch
> [ 964.285264] [drm:intel_modeset_stage_output_state] crtc changed, full
> mode switch
> [ 964.285276] [drm:intel_modeset_stage_output_state] crtc disabled, full
> mode switch
> [ 964.285293] [drm:intel_modeset_affected_pipes] set mode pipe masks:
> modeset: 0, prepare: 0, disable: 1
> [ 964.285358] [drm:intel_display_power_put] disabling dpio-tx-c-23
> [ 964.287059] [drm:intel_display_power_put] disabling dpio-tx-c-01
> [ 964.293119] [drm:intel_display_power_put] disabling dpio-tx-b-23
> [ 964.301223] [drm:intel_display_power_put] disabling dpio-tx-b-01
> [ 964.303065] [drm:intel_display_power_put] disabling dpio-common
> [ 964.305075] [drm:intel_display_power_put] disabling display
> [ 964.307260] [drm:check_encoder_state] [ENCODER:13:DAC-13]
> [ 964.307291] [drm:check_encoder_state] [ENCODER:14:TMDS-14]
> [ 964.307316] [drm:check_encoder_state] [ENCODER:18:TMDS-18]
> [ 964.307340] [drm:check_encoder_state] [ENCODER:20:TMDS-20]
> [ 964.307364] [drm:check_encoder_state] [ENCODER:22:TMDS-22]
> [ 964.307388] [drm:check_crtc_state] [CRTC:5]
> [ 964.307411] [drm:check_crtc_state] [CRTC:9]
>
> #############################################
>
> 3) Unplug DP cable
>
> arun@arun-valley-view:~$ sudo dmesg -c
>
> (empty printk buffer)
>
> 4) Plug DP cable (planning to send event to userspace to do '$xset dpms
> force on'
> arun@arun-valley-view:~$ sudo dmesg -c
>
> (empty printk buffer)
>
> I was hoping to see HPD events from step 3&4. But no events are generated.
>
> Is there any way to keep the HPD detection part awake so that I can send
> it to userspace to do '$xset dpms force on'
>
>
> Regards,
> Arun C
>

[-- Attachment #1.2: Type: text/html, Size: 18347 bytes --]

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org