From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751190AbeCHXZt (ORCPT ); Thu, 8 Mar 2018 18:25:49 -0500 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:37956 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751223AbeCHXYa (ORCPT ); Thu, 8 Mar 2018 18:24:30 -0500 From: Lyude Paul To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Cc: Manasi Navare , =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi , David Airlie , linux-kernel@vger.kernel.org Subject: [PATCH 2/6] drm/i915: Move DP modeset retry work into intel_dp Date: Thu, 8 Mar 2018 18:24:16 -0500 Message-Id: <20180308232421.14049-3-lyude@redhat.com> In-Reply-To: <20180308232421.14049-1-lyude@redhat.com> References: <20180308232421.14049-1-lyude@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org While having the modeset_retry_work in intel_connector makes sense with SST, this paradigm doesn't make a whole ton of sense when it comes to MST since we have to deal with multiple connectors. In most cases, it's more useful to just use the intel_dp struct since it indicates whether or not we're dealing with an MST device, along with being able to easily trace the intel_dp struct back to it's respective connector (if there is any). So, move the modeset_retry_work function out of the intel_connector struct and into intel_dp. Signed-off-by: Lyude Paul Cc: Manasi Navare Cc: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 23 +++++++++++++++++++++-- drivers/gpu/drm/i915/intel_dp.c | 10 ++++------ drivers/gpu/drm/i915/intel_dp_link_training.c | 2 +- drivers/gpu/drm/i915/intel_drv.h | 9 ++++++--- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f424fff477f6..85d5af4e4f5b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -15394,16 +15394,35 @@ static void intel_hpd_poll_fini(struct drm_device *dev) { struct intel_connector *connector; struct drm_connector_list_iter conn_iter; + struct work_struct *work; /* Kill all the work that may have been queued by hpd. */ drm_connector_list_iter_begin(dev, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { - if (connector->modeset_retry_work.func) - cancel_work_sync(&connector->modeset_retry_work); if (connector->hdcp_shim) { cancel_delayed_work_sync(&connector->hdcp_check_work); cancel_work_sync(&connector->hdcp_prop_work); } + + if (connector->base.connector_type != + DRM_MODE_CONNECTOR_DisplayPort) + continue; + + if (connector->mst_port) { + work = &connector->mst_port->modeset_retry_work; + } else { + struct intel_encoder *intel_encoder = + connector->encoder; + struct intel_dp *intel_dp; + + if (!intel_encoder) + continue; + + intel_dp = enc_to_intel_dp(&intel_encoder->base); + work = &intel_dp->modeset_retry_work; + } + + cancel_work_sync(work); } drm_connector_list_iter_end(&conn_iter); } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 4dd1b2287dd6..5abf0c95725a 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -6261,12 +6261,10 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, static void intel_dp_modeset_retry_work_fn(struct work_struct *work) { - struct intel_connector *intel_connector; - struct drm_connector *connector; + struct intel_dp *intel_dp = container_of(work, typeof(*intel_dp), + modeset_retry_work); + struct drm_connector *connector = &intel_dp->attached_connector->base; - intel_connector = container_of(work, typeof(*intel_connector), - modeset_retry_work); - connector = &intel_connector->base; DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); @@ -6295,7 +6293,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, int type; /* Initialize the work for modeset in case of link train failure */ - INIT_WORK(&intel_connector->modeset_retry_work, + INIT_WORK(&intel_dp->modeset_retry_work, intel_dp_modeset_retry_work_fn); if (WARN(intel_dig_port->max_lanes < 1, diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c index f59b59bb0a21..2cfa58ce1f95 100644 --- a/drivers/gpu/drm/i915/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c @@ -340,7 +340,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) intel_dp->link_rate, intel_dp->lane_count)) /* Schedule a Hotplug Uevent to userspace to start modeset */ - schedule_work(&intel_connector->modeset_retry_work); + schedule_work(&intel_dp->modeset_retry_work); } else { DRM_ERROR("[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d", intel_connector->base.base.id, diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 83e5ca889d9c..3700fcfddb1f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -406,14 +406,14 @@ struct intel_connector { struct intel_dp *mst_port; - /* Work struct to schedule a uevent on link train failure */ - struct work_struct modeset_retry_work; - const struct intel_hdcp_shim *hdcp_shim; struct mutex hdcp_mutex; uint64_t hdcp_value; /* protected by hdcp_mutex */ struct delayed_work hdcp_check_work; struct work_struct hdcp_prop_work; + + /* Work struct to schedule a uevent on link train failure */ + struct work_struct modeset_retry_work; }; struct intel_digital_connector_state { @@ -1135,6 +1135,9 @@ struct intel_dp { /* Displayport compliance testing */ struct intel_dp_compliance compliance; + + /* Work struct to schedule a uevent on link train failure */ + struct work_struct modeset_retry_work; }; struct intel_lspcon { -- 2.14.3 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Lyude Paul Subject: [PATCH 2/6] drm/i915: Move DP modeset retry work into intel_dp Date: Thu, 8 Mar 2018 18:24:16 -0500 Message-ID: <20180308232421.14049-3-lyude@redhat.com> References: <20180308232421.14049-1-lyude@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20180308232421.14049-1-lyude@redhat.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Cc: David Airlie , linux-kernel@vger.kernel.org, Rodrigo Vivi List-Id: dri-devel@lists.freedesktop.org V2hpbGUgaGF2aW5nIHRoZSBtb2Rlc2V0X3JldHJ5X3dvcmsgaW4gaW50ZWxfY29ubmVjdG9yIG1h a2VzIHNlbnNlIHdpdGgKU1NULCB0aGlzIHBhcmFkaWdtIGRvZXNuJ3QgbWFrZSBhIHdob2xlIHRv biBvZiBzZW5zZSB3aGVuIGl0IGNvbWVzIHRvCk1TVCBzaW5jZSB3ZSBoYXZlIHRvIGRlYWwgd2l0 aCBtdWx0aXBsZSBjb25uZWN0b3JzLiBJbiBtb3N0IGNhc2VzLCBpdCdzCm1vcmUgdXNlZnVsIHRv IGp1c3QgdXNlIHRoZSBpbnRlbF9kcCBzdHJ1Y3Qgc2luY2UgaXQgaW5kaWNhdGVzIHdoZXRoZXIK b3Igbm90IHdlJ3JlIGRlYWxpbmcgd2l0aCBhbiBNU1QgZGV2aWNlLCBhbG9uZyB3aXRoIGJlaW5n IGFibGUgdG8gZWFzaWx5CnRyYWNlIHRoZSBpbnRlbF9kcCBzdHJ1Y3QgYmFjayB0byBpdCdzIHJl c3BlY3RpdmUgY29ubmVjdG9yIChpZiB0aGVyZSBpcwphbnkpLiBTbywgbW92ZSB0aGUgbW9kZXNl dF9yZXRyeV93b3JrIGZ1bmN0aW9uIG91dCBvZiB0aGUKaW50ZWxfY29ubmVjdG9yIHN0cnVjdCBh bmQgaW50byBpbnRlbF9kcC4KClNpZ25lZC1vZmYtYnk6IEx5dWRlIFBhdWwgPGx5dWRlQHJlZGhh dC5jb20+CkNjOiBNYW5hc2kgTmF2YXJlIDxtYW5hc2kuZC5uYXZhcmVAaW50ZWwuY29tPgpDYzog VmlsbGUgU3lyasOkbMOkIDx2aWxsZS5zeXJqYWxhQGxpbnV4LmludGVsLmNvbT4KLS0tCiBkcml2 ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9kaXNwbGF5LmMgICAgICAgICAgfCAyMyArKysrKysrKysr KysrKysrKysrKystLQogZHJpdmVycy9ncHUvZHJtL2k5MTUvaW50ZWxfZHAuYyAgICAgICAgICAg ICAgIHwgMTAgKysrKy0tLS0tLQogZHJpdmVycy9ncHUvZHJtL2k5MTUvaW50ZWxfZHBfbGlua190 cmFpbmluZy5jIHwgIDIgKy0KIGRyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX2Rydi5oICAgICAg ICAgICAgICB8ICA5ICsrKysrKy0tLQogNCBmaWxlcyBjaGFuZ2VkLCAzMiBpbnNlcnRpb25zKCsp LCAxMiBkZWxldGlvbnMoLSkKCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRl bF9kaXNwbGF5LmMgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9kaXNwbGF5LmMKaW5kZXgg ZjQyNGZmZjQ3N2Y2Li44NWQ1YWY0ZTRmNWIgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9p OTE1L2ludGVsX2Rpc3BsYXkuYworKysgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9kaXNw bGF5LmMKQEAgLTE1Mzk0LDE2ICsxNTM5NCwzNSBAQCBzdGF0aWMgdm9pZCBpbnRlbF9ocGRfcG9s bF9maW5pKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYpCiB7CiAJc3RydWN0IGludGVsX2Nvbm5lY3Rv ciAqY29ubmVjdG9yOwogCXN0cnVjdCBkcm1fY29ubmVjdG9yX2xpc3RfaXRlciBjb25uX2l0ZXI7 CisJc3RydWN0IHdvcmtfc3RydWN0ICp3b3JrOwogCiAJLyogS2lsbCBhbGwgdGhlIHdvcmsgdGhh dCBtYXkgaGF2ZSBiZWVuIHF1ZXVlZCBieSBocGQuICovCiAJZHJtX2Nvbm5lY3Rvcl9saXN0X2l0 ZXJfYmVnaW4oZGV2LCAmY29ubl9pdGVyKTsKIAlmb3JfZWFjaF9pbnRlbF9jb25uZWN0b3JfaXRl cihjb25uZWN0b3IsICZjb25uX2l0ZXIpIHsKLQkJaWYgKGNvbm5lY3Rvci0+bW9kZXNldF9yZXRy eV93b3JrLmZ1bmMpCi0JCQljYW5jZWxfd29ya19zeW5jKCZjb25uZWN0b3ItPm1vZGVzZXRfcmV0 cnlfd29yayk7CiAJCWlmIChjb25uZWN0b3ItPmhkY3Bfc2hpbSkgewogCQkJY2FuY2VsX2RlbGF5 ZWRfd29ya19zeW5jKCZjb25uZWN0b3ItPmhkY3BfY2hlY2tfd29yayk7CiAJCQljYW5jZWxfd29y a19zeW5jKCZjb25uZWN0b3ItPmhkY3BfcHJvcF93b3JrKTsKIAkJfQorCisJCWlmIChjb25uZWN0 b3ItPmJhc2UuY29ubmVjdG9yX3R5cGUgIT0KKwkJICAgIERSTV9NT0RFX0NPTk5FQ1RPUl9EaXNw bGF5UG9ydCkKKwkJCWNvbnRpbnVlOworCisJCWlmIChjb25uZWN0b3ItPm1zdF9wb3J0KSB7CisJ CQl3b3JrID0gJmNvbm5lY3Rvci0+bXN0X3BvcnQtPm1vZGVzZXRfcmV0cnlfd29yazsKKwkJfSBl bHNlIHsKKwkJCXN0cnVjdCBpbnRlbF9lbmNvZGVyICppbnRlbF9lbmNvZGVyID0KKwkJCQljb25u ZWN0b3ItPmVuY29kZXI7CisJCQlzdHJ1Y3QgaW50ZWxfZHAgKmludGVsX2RwOworCisJCQlpZiAo IWludGVsX2VuY29kZXIpCisJCQkJY29udGludWU7CisKKwkJCWludGVsX2RwID0gZW5jX3RvX2lu dGVsX2RwKCZpbnRlbF9lbmNvZGVyLT5iYXNlKTsKKwkJCXdvcmsgPSAmaW50ZWxfZHAtPm1vZGVz ZXRfcmV0cnlfd29yazsKKwkJfQorCisJCWNhbmNlbF93b3JrX3N5bmMod29yayk7CiAJfQogCWRy bV9jb25uZWN0b3JfbGlzdF9pdGVyX2VuZCgmY29ubl9pdGVyKTsKIH0KZGlmZiAtLWdpdCBhL2Ry aXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX2RwLmMgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRl bF9kcC5jCmluZGV4IDRkZDFiMjI4N2RkNi4uNWFiZjBjOTU3MjVhIDEwMDY0NAotLS0gYS9kcml2 ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9kcC5jCisrKyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2lu dGVsX2RwLmMKQEAgLTYyNjEsMTIgKzYyNjEsMTAgQEAgc3RhdGljIGJvb2wgaW50ZWxfZWRwX2lu aXRfY29ubmVjdG9yKHN0cnVjdCBpbnRlbF9kcCAqaW50ZWxfZHAsCiAKIHN0YXRpYyB2b2lkIGlu dGVsX2RwX21vZGVzZXRfcmV0cnlfd29ya19mbihzdHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcmspCiB7 Ci0Jc3RydWN0IGludGVsX2Nvbm5lY3RvciAqaW50ZWxfY29ubmVjdG9yOwotCXN0cnVjdCBkcm1f Y29ubmVjdG9yICpjb25uZWN0b3I7CisJc3RydWN0IGludGVsX2RwICppbnRlbF9kcCA9IGNvbnRh aW5lcl9vZih3b3JrLCB0eXBlb2YoKmludGVsX2RwKSwKKwkJCQkJCSBtb2Rlc2V0X3JldHJ5X3dv cmspOworCXN0cnVjdCBkcm1fY29ubmVjdG9yICpjb25uZWN0b3IgPSAmaW50ZWxfZHAtPmF0dGFj aGVkX2Nvbm5lY3Rvci0+YmFzZTsKIAotCWludGVsX2Nvbm5lY3RvciA9IGNvbnRhaW5lcl9vZih3 b3JrLCB0eXBlb2YoKmludGVsX2Nvbm5lY3RvciksCi0JCQkJICAgICAgIG1vZGVzZXRfcmV0cnlf d29yayk7Ci0JY29ubmVjdG9yID0gJmludGVsX2Nvbm5lY3Rvci0+YmFzZTsKIAlEUk1fREVCVUdf S01TKCJbQ09OTkVDVE9SOiVkOiVzXVxuIiwgY29ubmVjdG9yLT5iYXNlLmlkLAogCQkgICAgICBj b25uZWN0b3ItPm5hbWUpOwogCkBAIC02Mjk1LDcgKzYyOTMsNyBAQCBpbnRlbF9kcF9pbml0X2Nv bm5lY3RvcihzdHJ1Y3QgaW50ZWxfZGlnaXRhbF9wb3J0ICppbnRlbF9kaWdfcG9ydCwKIAlpbnQg dHlwZTsKIAogCS8qIEluaXRpYWxpemUgdGhlIHdvcmsgZm9yIG1vZGVzZXQgaW4gY2FzZSBvZiBs aW5rIHRyYWluIGZhaWx1cmUgKi8KLQlJTklUX1dPUksoJmludGVsX2Nvbm5lY3Rvci0+bW9kZXNl dF9yZXRyeV93b3JrLAorCUlOSVRfV09SSygmaW50ZWxfZHAtPm1vZGVzZXRfcmV0cnlfd29yaywK IAkJICBpbnRlbF9kcF9tb2Rlc2V0X3JldHJ5X3dvcmtfZm4pOwogCiAJaWYgKFdBUk4oaW50ZWxf ZGlnX3BvcnQtPm1heF9sYW5lcyA8IDEsCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaTkx NS9pbnRlbF9kcF9saW5rX3RyYWluaW5nLmMgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9k cF9saW5rX3RyYWluaW5nLmMKaW5kZXggZjU5YjU5YmIwYTIxLi4yY2ZhNThjZTFmOTUgMTAwNjQ0 Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX2RwX2xpbmtfdHJhaW5pbmcuYworKysg Yi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9kcF9saW5rX3RyYWluaW5nLmMKQEAgLTM0MCw3 ICszNDAsNyBAQCBpbnRlbF9kcF9zdGFydF9saW5rX3RyYWluKHN0cnVjdCBpbnRlbF9kcCAqaW50 ZWxfZHApCiAJCQkJCQkJICAgICBpbnRlbF9kcC0+bGlua19yYXRlLAogCQkJCQkJCSAgICAgaW50 ZWxfZHAtPmxhbmVfY291bnQpKQogCQkJLyogU2NoZWR1bGUgYSBIb3RwbHVnIFVldmVudCB0byB1 c2Vyc3BhY2UgdG8gc3RhcnQgbW9kZXNldCAqLwotCQkJc2NoZWR1bGVfd29yaygmaW50ZWxfY29u bmVjdG9yLT5tb2Rlc2V0X3JldHJ5X3dvcmspOworCQkJc2NoZWR1bGVfd29yaygmaW50ZWxfZHAt Pm1vZGVzZXRfcmV0cnlfd29yayk7CiAJfSBlbHNlIHsKIAkJRFJNX0VSUk9SKCJbQ09OTkVDVE9S OiVkOiVzXSBMaW5rIFRyYWluaW5nIGZhaWxlZCBhdCBsaW5rIHJhdGUgPSAlZCwgbGFuZSBjb3Vu dCA9ICVkIiwKIAkJCSAgaW50ZWxfY29ubmVjdG9yLT5iYXNlLmJhc2UuaWQsCmRpZmYgLS1naXQg YS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9kcnYuaCBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1 L2ludGVsX2Rydi5oCmluZGV4IDgzZTVjYTg4OWQ5Yy4uMzcwMGZjZmRkYjFmIDEwMDY0NAotLS0g YS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9kcnYuaAorKysgYi9kcml2ZXJzL2dwdS9kcm0v aTkxNS9pbnRlbF9kcnYuaApAQCAtNDA2LDE0ICs0MDYsMTQgQEAgc3RydWN0IGludGVsX2Nvbm5l Y3RvciB7CiAKIAlzdHJ1Y3QgaW50ZWxfZHAgKm1zdF9wb3J0OwogCi0JLyogV29yayBzdHJ1Y3Qg dG8gc2NoZWR1bGUgYSB1ZXZlbnQgb24gbGluayB0cmFpbiBmYWlsdXJlICovCi0Jc3RydWN0IHdv cmtfc3RydWN0IG1vZGVzZXRfcmV0cnlfd29yazsKLQogCWNvbnN0IHN0cnVjdCBpbnRlbF9oZGNw X3NoaW0gKmhkY3Bfc2hpbTsKIAlzdHJ1Y3QgbXV0ZXggaGRjcF9tdXRleDsKIAl1aW50NjRfdCBo ZGNwX3ZhbHVlOyAvKiBwcm90ZWN0ZWQgYnkgaGRjcF9tdXRleCAqLwogCXN0cnVjdCBkZWxheWVk X3dvcmsgaGRjcF9jaGVja193b3JrOwogCXN0cnVjdCB3b3JrX3N0cnVjdCBoZGNwX3Byb3Bfd29y azsKKworCS8qIFdvcmsgc3RydWN0IHRvIHNjaGVkdWxlIGEgdWV2ZW50IG9uIGxpbmsgdHJhaW4g ZmFpbHVyZSAqLworCXN0cnVjdCB3b3JrX3N0cnVjdCBtb2Rlc2V0X3JldHJ5X3dvcms7CiB9Owog CiBzdHJ1Y3QgaW50ZWxfZGlnaXRhbF9jb25uZWN0b3Jfc3RhdGUgewpAQCAtMTEzNSw2ICsxMTM1 LDkgQEAgc3RydWN0IGludGVsX2RwIHsKIAogCS8qIERpc3BsYXlwb3J0IGNvbXBsaWFuY2UgdGVz dGluZyAqLwogCXN0cnVjdCBpbnRlbF9kcF9jb21wbGlhbmNlIGNvbXBsaWFuY2U7CisKKwkvKiBX b3JrIHN0cnVjdCB0byBzY2hlZHVsZSBhIHVldmVudCBvbiBsaW5rIHRyYWluIGZhaWx1cmUgKi8K KwlzdHJ1Y3Qgd29ya19zdHJ1Y3QgbW9kZXNldF9yZXRyeV93b3JrOwogfTsKIAogc3RydWN0IGlu dGVsX2xzcGNvbiB7Ci0tIAoyLjE0LjMKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fCkludGVsLWdmeCBtYWlsaW5nIGxpc3QKSW50ZWwtZ2Z4QGxpc3RzLmZy ZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3Rp bmZvL2ludGVsLWdmeAo=