From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, MIME_BASE64_TEXT,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5CC4FC433E1 for ; Fri, 19 Jun 2020 09:42:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1A29D2080C for ; Fri, 19 Jun 2020 09:42:32 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="lxIKatnx" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732203AbgFSJma (ORCPT ); Fri, 19 Jun 2020 05:42:30 -0400 Received: from mailgw02.mediatek.com ([210.61.82.184]:56638 "EHLO mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1732173AbgFSJm0 (ORCPT ); Fri, 19 Jun 2020 05:42:26 -0400 X-UUID: 391b4275a91c42c084f542a0c227f688-20200619 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=xmg1w3ypX4AvT1+i24MnshAnpwzBsGKjigr9tp4Uf7E=; b=lxIKatnx5Z+RsisdwUs86yNdT7R3ChAuisRRAcOSmvnPyuuGdgnr4UO3QWqb8HbOjDkAlGmqqzypQ7vQHixlMEMa7PE1R74yvwld494sLB5Acbs2noDI8lXgEm0jAx5llt+CrQ8PGJaXs6oMuPKO9y849qgBwTkdJ+Cn604xiK0=; X-UUID: 391b4275a91c42c084f542a0c227f688-20200619 Received: from mtkcas08.mediatek.inc [(172.21.101.126)] by mailgw02.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 677885380; Fri, 19 Jun 2020 17:42:07 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs02n2.mediatek.inc (172.21.101.101) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 19 Jun 2020 17:42:03 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 19 Jun 2020 17:42:02 +0800 From: Neal Liu To: Rob Herring , Matthias Brugger CC: Neal Liu , , , , , Subject: [PATCH v2 2/2] soc: mediatek: devapc: add devapc-mt6873 driver Date: Fri, 19 Jun 2020 17:42:00 +0800 Message-ID: <1592559720-8482-3-git-send-email-neal.liu@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1592559720-8482-1-git-send-email-neal.liu@mediatek.com> References: <1592559720-8482-1-git-send-email-neal.liu@mediatek.com> MIME-Version: 1.0 Content-Type: text/plain X-TM-SNTS-SMTP: E0B163962F1135967F8C685B03557F40BC5F0C13593F6F8072F8DD8B2E6A36CD2000:8 X-MTK: N Content-Transfer-Encoding: base64 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org TVQ2ODczIGJ1cyBmcmFicmljIHByb3ZpZGVzIFRydXN0Wm9uZSBzZWN1cml0eSBzdXBwb3J0IGFu ZCBkYXRhDQpwcm90ZWN0aW9uIHRvIHByZXZlbnQgc2xhdmVzIGZyb20gYmVpbmcgYWNjZXNzZWQg YnkgdW5leHBlY3RlZA0KbWFzdGVycy4NClRoZSBzZWN1cml0eSB2aW9sYXRpb25zIGFyZSBsb2dn ZWQgYW5kIHNlbnQgdG8gdGhlIHByb2Nlc3NvciBmb3INCmZ1cnRoZXIgYW5hbHlzaXMgb3IgY291 bnRlcm1lYXN1cmVzLg0KDQpBbnkgb2NjdXJyZW5jZSBvZiBzZWN1cml0eSB2aW9sYXRpb24gd291 bGQgcmFpc2UgYW4gaW50ZXJydXB0LCBhbmQNCml0IHdpbGwgYmUgaGFuZGxlZCBieSBkZXZhcGMt bXQ2ODczIGRyaXZlci4gVGhlIHZpb2xhdGlvbg0KaW5mb3JtYXRpb24gaXMgcHJpbnRlZCBpbiBv cmRlciB0byBmaW5kIHRoZSBtdXJkZXJlci4NCg0KU2lnbmVkLW9mZi1ieTogTmVhbCBMaXUgPG5l YWwubGl1QG1lZGlhdGVrLmNvbT4NCi0tLQ0KIGRyaXZlcnMvc29jL21lZGlhdGVrL0tjb25maWcg ICAgICAgICAgICAgICAgICAgICAgfCAgICA2ICsNCiBkcml2ZXJzL3NvYy9tZWRpYXRlay9NYWtl ZmlsZSAgICAgICAgICAgICAgICAgICAgIHwgICAgMSArDQogZHJpdmVycy9zb2MvbWVkaWF0ZWsv ZGV2YXBjL0tjb25maWcgICAgICAgICAgICAgICB8ICAgMjUgKw0KIGRyaXZlcnMvc29jL21lZGlh dGVrL2RldmFwYy9NYWtlZmlsZSAgICAgICAgICAgICAgfCAgIDEzICsNCiBkcml2ZXJzL3NvYy9t ZWRpYXRlay9kZXZhcGMvZGV2YXBjLW10Njg3My5jICAgICAgIHwgMTY1MiArKysrKysrKysrKysr KysrKysrKysNCiBkcml2ZXJzL3NvYy9tZWRpYXRlay9kZXZhcGMvZGV2YXBjLW10Njg3My5oICAg ICAgIHwgIDExMSArKw0KIGRyaXZlcnMvc29jL21lZGlhdGVrL2RldmFwYy9kZXZhcGMtbXRrLW11 bHRpLWFvLmMgfCAgNzU2ICsrKysrKysrKysNCiBkcml2ZXJzL3NvYy9tZWRpYXRlay9kZXZhcGMv ZGV2YXBjLW10ay1tdWx0aS1hby5oIHwgIDE4MiArKysNCiA4IGZpbGVzIGNoYW5nZWQsIDI3NDYg aW5zZXJ0aW9ucygrKQ0KIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3NvYy9tZWRpYXRlay9k ZXZhcGMvS2NvbmZpZw0KIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3NvYy9tZWRpYXRlay9k ZXZhcGMvTWFrZWZpbGUNCiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9zb2MvbWVkaWF0ZWsv ZGV2YXBjL2RldmFwYy1tdDY4NzMuYw0KIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3NvYy9t ZWRpYXRlay9kZXZhcGMvZGV2YXBjLW10Njg3My5oDQogY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZl cnMvc29jL21lZGlhdGVrL2RldmFwYy9kZXZhcGMtbXRrLW11bHRpLWFvLmMNCiBjcmVhdGUgbW9k ZSAxMDA2NDQgZHJpdmVycy9zb2MvbWVkaWF0ZWsvZGV2YXBjL2RldmFwYy1tdGstbXVsdGktYW8u aA0KDQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9zb2MvbWVkaWF0ZWsvS2NvbmZpZyBiL2RyaXZlcnMv c29jL21lZGlhdGVrL0tjb25maWcNCmluZGV4IDU5YTU2Y2QuLjJjOWFkMWYgMTAwNjQ0DQotLS0g YS9kcml2ZXJzL3NvYy9tZWRpYXRlay9LY29uZmlnDQorKysgYi9kcml2ZXJzL3NvYy9tZWRpYXRl ay9LY29uZmlnDQpAQCAtNTEsNCArNTEsMTAgQEAgY29uZmlnIE1US19NTVNZUw0KIAkgIFNheSB5 ZXMgaGVyZSB0byBhZGQgc3VwcG9ydCBmb3IgdGhlIE1lZGlhVGVrIE11bHRpbWVkaWENCiAJICBT dWJzeXN0ZW0gKE1NU1lTKS4NCiANCittZW51ICJTZWN1cml0eSINCisNCitzb3VyY2UgImRyaXZl cnMvc29jL21lZGlhdGVrL2RldmFwYy9LY29uZmlnIg0KKw0KK2VuZG1lbnUgIyBTZWN1cml0eQ0K Kw0KIGVuZG1lbnUNCmRpZmYgLS1naXQgYS9kcml2ZXJzL3NvYy9tZWRpYXRlay9NYWtlZmlsZSBi L2RyaXZlcnMvc29jL21lZGlhdGVrL01ha2VmaWxlDQppbmRleCAwMWY5Zjg3Li5kNjcxN2E4MSAx MDA2NDQNCi0tLSBhL2RyaXZlcnMvc29jL21lZGlhdGVrL01ha2VmaWxlDQorKysgYi9kcml2ZXJz L3NvYy9tZWRpYXRlay9NYWtlZmlsZQ0KQEAgLTEsNSArMSw2IEBADQogIyBTUERYLUxpY2Vuc2Ut SWRlbnRpZmllcjogR1BMLTIuMC1vbmx5DQogb2JqLSQoQ09ORklHX01US19DTURRKSArPSBtdGst Y21kcS1oZWxwZXIubw0KK29iai0kKENPTkZJR19NVEtfREVWQVBDKSArPSBkZXZhcGMvDQogb2Jq LSQoQ09ORklHX01US19JTkZSQUNGRykgKz0gbXRrLWluZnJhY2ZnLm8NCiBvYmotJChDT05GSUdf TVRLX1BNSUNfV1JBUCkgKz0gbXRrLXBtaWMtd3JhcC5vDQogb2JqLSQoQ09ORklHX01US19TQ1BT WVMpICs9IG10ay1zY3BzeXMubw0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvc29jL21lZGlhdGVrL2Rl dmFwYy9LY29uZmlnIGIvZHJpdmVycy9zb2MvbWVkaWF0ZWsvZGV2YXBjL0tjb25maWcNCm5ldyBm aWxlIG1vZGUgMTAwNjQ0DQppbmRleCAwMDAwMDAwLi45NDI4MzYwDQotLS0gL2Rldi9udWxsDQor KysgYi9kcml2ZXJzL3NvYy9tZWRpYXRlay9kZXZhcGMvS2NvbmZpZw0KQEAgLTAsMCArMSwyNSBA QA0KK2NvbmZpZyBNVEtfREVWQVBDDQorCXRyaXN0YXRlICJNZWRpYXRlayBEZXZpY2UgQVBDIFN1 cHBvcnQiDQorCWhlbHANCisJICBEZXZpY2UgQVBDIGlzIGEga2VybmVsIGRyaXZlciBjb250cm9s bGluZyBpbnRlcm5hbCBkZXZpY2Ugc2VjdXJpdHkuDQorCSAgSWYgc29tZW9uZSB0cmllcyB0byBh Y2Nlc3MgYSBkZXZpY2UsIHdoaWNoIGlzIG5vdCBhbGxvd2VkIGJ5IHRoZQ0KKwkgIGRldmljZSwg aXQgY2Fubm90IGFjY2VzcyB0aGUgZGV2aWNlIGFuZCB3aWxsIGdldCBhIHZpb2xhdGlvbg0KKwkg IGludGVycnVwdC4gRGV2aWNlIEFQQyBwcmV2ZW50cyBtYWxpY2lvdXMgYWNjZXNzIHRvIGludGVy bmFsIGRldmljZXMuDQorDQorY29uZmlnIERFVkFQQ19BUkNIX01VTFRJDQorCXRyaXN0YXRlICJN ZWRpYXRlayBEZXZpY2UgQVBDIGRyaXZlciBhcmNoaXRlY3R1cmUgbXVsdGkiDQorCWhlbHANCisJ ICBTYXkgeWVzIGhlcmUgdG8gZW5hYmxlIHN1cHBvcnQgTWVkaWF0ZWsNCisJICBEZXZpY2UgQVBD IGRyaXZlciB3aGljaCBpcyBiYXNlZCBvbiBJbmZyYQ0KKwkgIGFyY2hpdGVjdHVyZS4NCisJICBU aGlzIGFyY2hpdGVjdHVyZSBzdXBwb3J0cyBtdWx0aXBsZSBJbmZyYSBBTy4NCisNCitjb25maWcg REVWQVBDX01UNjg3Mw0KKwl0cmlzdGF0ZSAiTWVkaWF0ZWsgTVQ2ODczIERldmljZSBBUEMgZHJp dmVyIg0KKwlzZWxlY3QgTVRLX0RFVkFQQw0KKwlzZWxlY3QgREVWQVBDX0FSQ0hfTVVMVEkNCisJ aGVscA0KKwkgIFNheSB5ZXMgaGVyZSB0byBlbmFibGUgc3VwcG9ydCBNZWRpYXRlayBNVDY4NzMN CisJICBEZXZpY2UgQVBDIGRyaXZlci4NCisJICBUaGlzIGRyaXZlciBpcyBjb21iaW5lZCB3aXRo IERFVkFQQ19BUkNIX01VTFRJIGZvcg0KKwkgIGNvbW1vbiBoYW5kbGUgZmxvdy4NCmRpZmYgLS1n aXQgYS9kcml2ZXJzL3NvYy9tZWRpYXRlay9kZXZhcGMvTWFrZWZpbGUgYi9kcml2ZXJzL3NvYy9t ZWRpYXRlay9kZXZhcGMvTWFrZWZpbGUNCm5ldyBmaWxlIG1vZGUgMTAwNjQ0DQppbmRleCAwMDAw MDAwLi5iZDQ3MWYyDQotLS0gL2Rldi9udWxsDQorKysgYi9kcml2ZXJzL3NvYy9tZWRpYXRlay9k ZXZhcGMvTWFrZWZpbGUNCkBAIC0wLDAgKzEsMTMgQEANCisjIFNQRFgtTGljZW5zZS1JZGVudGlm aWVyOiBHUEwtMi4wDQorDQoraWZlcSAoJChDT05GSUdfTVRLX0dDT1ZfS0VSTkVMKSx5KQ0KK0dD T1ZfUFJPRklMRSA6PSB5DQorZW5kaWYNCisNCitvYmotJChDT05GSUdfTVRLX0RFVkFQQykgOj0g ZGV2YXBjLm8NCisNCisjIENvcmUNCitkZXZhcGMtJChDT05GSUdfREVWQVBDX0FSQ0hfTVVMVEkp ICs9IGRldmFwYy1tdGstbXVsdGktYW8ubw0KKw0KKyMgUGxhdGZvcm0NCitkZXZhcGMtJChDT05G SUdfREVWQVBDX01UNjg3MykgKz0gZGV2YXBjLW10Njg3My5vDQpkaWZmIC0tZ2l0IGEvZHJpdmVy cy9zb2MvbWVkaWF0ZWsvZGV2YXBjL2RldmFwYy1tdDY4NzMuYyBiL2RyaXZlcnMvc29jL21lZGlh dGVrL2RldmFwYy9kZXZhcGMtbXQ2ODczLmMNCm5ldyBmaWxlIG1vZGUgMTAwNjQ0DQppbmRleCAw MDAwMDAwLi43NWEyMTQwDQotLS0gL2Rldi9udWxsDQorKysgYi9kcml2ZXJzL3NvYy9tZWRpYXRl ay9kZXZhcGMvZGV2YXBjLW10Njg3My5jDQpAQCAtMCwwICsxLDE2NTIgQEANCisvLyBTUERYLUxp Y2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMA0KKy8qDQorICogQ29weXJpZ2h0IChDKSAyMDIwIE1l ZGlhVGVrIEluYy4NCisgKi8NCisNCisjaW5jbHVkZSA8bGludXgvYnVnLmg+DQorI2luY2x1ZGUg PGxpbnV4L21vZHVsZS5oPg0KKyNpbmNsdWRlIDxsaW51eC9vZi5oPg0KKyNpbmNsdWRlIDxsaW51 eC9wbGF0Zm9ybV9kZXZpY2UuaD4NCisjaW5jbHVkZSA8YXNtLWdlbmVyaWMvaW8uaD4NCisNCisj aW5jbHVkZSAiZGV2YXBjLW10Njg3My5oIg0KKyNpbmNsdWRlICJkZXZhcGMtbXRrLW11bHRpLWFv LmgiDQorDQorc3RhdGljIHN0cnVjdCBtdGtfZGV2aWNlX2luZm8gbXQ2ODczX2RldmljZXNfaW5m cmFbXSA9IHsNCisJLyogc3lzX2lkeCwgY3RybF9pZHgsIHZpb19pZHggKi8NCisJLyogMCAqLw0K Kwl7MCwgMCwgMH0sDQorCXswLCAxLCAxfSwNCisJezAsIDIsIDJ9LA0KKwl7MCwgMywgM30sDQor CXswLCA0LCA0fSwNCisJezAsIDUsIDV9LA0KKwl7MCwgNiwgNn0sDQorCXswLCA3LCA3fSwNCisJ ezAsIDgsIDh9LA0KKwl7MCwgOSwgOX0sDQorDQorCS8qIDEwICovDQorCXswLCAxMCwgMTB9LA0K Kwl7MCwgMTEsIDExfSwNCisJezAsIDEyLCAxMn0sDQorCXswLCAxMywgMTN9LA0KKwl7MCwgMTQs IDE0fSwNCisJezAsIDE1LCAxNX0sDQorCXswLCAxNiwgMTZ9LA0KKwl7MCwgMTcsIDE3fSwNCisJ ezAsIDE4LCAxOH0sDQorCXswLCAxOSwgMTl9LA0KKw0KKwkvKiAyMCAqLw0KKwl7MCwgMjAsIDIw fSwNCisJezAsIDIxLCAyMX0sDQorCXswLCAyMiwgMzUyfSwNCisJezEsIDAsIDIyfSwNCisJezEs IDEsIDIzfSwNCisJezEsIDIsIDI0fSwNCisJezEsIDMsIDI1fSwNCisJezEsIDQsIDI2fSwNCisJ ezEsIDUsIDI3fSwNCisJezEsIDYsIDI4fSwNCisNCisJLyogMzAgKi8NCisJezEsIDcsIDI5fSwN CisJezEsIDgsIDMwfSwNCisJezEsIDksIDMxfSwNCisJezEsIDEwLCAzMn0sDQorCXsxLCAxMSwg MzN9LA0KKwl7MSwgMTIsIDM0fSwNCisJezEsIDEzLCAzNX0sDQorCXsxLCAxNCwgMzZ9LA0KKwl7 MSwgMTUsIDM3fSwNCisJezEsIDE2LCAzOH0sDQorDQorCS8qIDQwICovDQorCXsxLCAxNywgMzl9 LA0KKwl7MSwgMTgsIDQwfSwNCisJezEsIDE5LCA0MX0sDQorCXsxLCAyMCwgNDJ9LA0KKwl7MSwg MjEsIDQzfSwNCisJezEsIDIyLCA0NH0sDQorCXsxLCAyMywgNDV9LA0KKwl7MSwgMjQsIDQ2fSwN CisJezEsIDI1LCA0N30sDQorCXsxLCAyNiwgNDh9LA0KKw0KKwkvKiA1MCAqLw0KKwl7MSwgMjcs IDQ5fSwNCisJezEsIDI4LCA1MH0sDQorCXsxLCAyOSwgNTF9LA0KKwl7MSwgMzAsIDUyfSwNCisJ ezEsIDMxLCA1M30sDQorCXsxLCAzMiwgNTR9LA0KKwl7MSwgMzMsIDU1fSwNCisJezEsIDM0LCA1 Nn0sDQorCXsxLCAzNSwgNTd9LA0KKwl7MSwgMzYsIDU4fSwNCisNCisJLyogNjAgKi8NCisJezEs IDM3LCA1OX0sDQorCXsxLCAzOCwgNjB9LA0KKwl7MSwgMzksIDYxfSwNCisJezEsIDQwLCA2Mn0s DQorCXsxLCA0MSwgNjN9LA0KKwl7MSwgNDIsIDY0fSwNCisJezEsIDQzLCA2NX0sDQorCXsxLCA0 NCwgNjZ9LA0KKwl7MSwgNDUsIDY3fSwNCisJezEsIDQ2LCA2OH0sDQorDQorCS8qIDcwICovDQor CXsxLCA0NywgNjl9LA0KKwl7MSwgNDgsIDcwfSwNCisJezEsIDQ5LCA3MX0sDQorCXsxLCA1MCwg NzJ9LA0KKwl7MSwgNTEsIDczfSwNCisJezEsIDUyLCA3NH0sDQorCXsxLCA1MywgNzV9LA0KKwl7 MSwgNTQsIDc2fSwNCisJezEsIDU1LCA3N30sDQorCXsxLCA1NiwgNzh9LA0KKw0KKwkvKiA4MCAq Lw0KKwl7MSwgNTcsIDc5fSwNCisJezEsIDU4LCA4MH0sDQorCXsxLCA1OSwgODF9LA0KKwl7MSwg NjAsIDgyfSwNCisJezEsIDYxLCA4M30sDQorCXsxLCA2MiwgODR9LA0KKwl7MSwgNjMsIDg1fSwN CisJezEsIDY0LCA4Nn0sDQorCXsxLCA2NSwgODd9LA0KKwl7MSwgNjYsIDg4fSwNCisNCisJLyog OTAgKi8NCisJezEsIDY3LCA4OX0sDQorCXsxLCA2OCwgOTB9LA0KKwl7MSwgNjksIDkxfSwNCisJ ezEsIDcwLCA5Mn0sDQorCXsxLCA3MSwgOTN9LA0KKwl7MSwgNzIsIDk0fSwNCisJezEsIDczLCA5 NX0sDQorCXsxLCA3NCwgOTZ9LA0KKwl7MSwgNzUsIDk3fSwNCisJezEsIDc2LCA5OH0sDQorDQor CS8qIDEwMCAqLw0KKwl7MSwgNzcsIDk5fSwNCisJezEsIDc4LCAxMDB9LA0KKwl7MSwgNzksIDEw MX0sDQorCXsxLCA4MCwgMTAyfSwNCisJezEsIDgxLCAxMDN9LA0KKwl7MSwgODIsIDEwNH0sDQor CXsxLCA4MywgMTA1fSwNCisJezEsIDg0LCAxMDZ9LA0KKwl7MSwgODUsIDEwN30sDQorCXsxLCA4 NiwgMTA4fSwNCisNCisJLyogMTEwICovDQorCXsxLCA4NywgMTA5fSwNCisJezEsIDg4LCAxMTB9 LA0KKwl7MSwgODksIDExMX0sDQorCXsxLCA5MCwgMTEyfSwNCisJezEsIDkxLCAxMTN9LA0KKwl7 MSwgOTIsIDExNH0sDQorCXsxLCA5MywgMTE1fSwNCisJezEsIDk0LCAxMTZ9LA0KKwl7MSwgOTUs IDExN30sDQorCXsxLCA5NiwgMTE4fSwNCisNCisJLyogMTIwICovDQorCXsxLCA5NywgMTE5fSwN CisJezEsIDk4LCAxMjB9LA0KKwl7MSwgOTksIDEyMX0sDQorCXsxLCAxMDAsIDEyMn0sDQorCXsx LCAxMDEsIDEyM30sDQorCXsxLCAxMDIsIDEyNH0sDQorCXsxLCAxMDMsIDEyNX0sDQorCXsxLCAx MDQsIDEyNn0sDQorCXsxLCAxMDUsIDEyN30sDQorCXsxLCAxMDYsIDEyOH0sDQorDQorCS8qIDEz MCAqLw0KKwl7MSwgMTA3LCAxMjl9LA0KKwl7MSwgMTA4LCAxMzB9LA0KKwl7MSwgMTA5LCAxMzF9 LA0KKwl7MSwgMTEwLCAxMzJ9LA0KKwl7MSwgMTExLCAxMzN9LA0KKwl7MSwgMTEyLCAxMzR9LA0K Kwl7MSwgMTEzLCAxMzV9LA0KKwl7MSwgMTE0LCAxMzZ9LA0KKwl7MSwgMTE1LCAxMzd9LA0KKwl7 MSwgMTE2LCAxMzh9LA0KKw0KKwkvKiAxNDAgKi8NCisJezEsIDExNywgMTM5fSwNCisJezEsIDEx OCwgMTQwfSwNCisJezEsIDExOSwgMTQxfSwNCisJezEsIDEyMCwgMTQyfSwNCisJezEsIDEyMSwg MTQzfSwNCisJezEsIDEyMiwgMTQ0fSwNCisJezEsIDEyMywgMTQ1fSwNCisJezEsIDEyNCwgMTQ2 fSwNCisJezEsIDEyNSwgMTQ3fSwNCisJezEsIDEyNiwgMTQ4fSwNCisNCisJLyogMTUwICovDQor CXsxLCAxMjcsIDE0OX0sDQorCXsxLCAxMjgsIDE1MH0sDQorCXsxLCAxMjksIDE1MX0sDQorCXsx LCAxMzAsIDE1Mn0sDQorCXsxLCAxMzEsIDE1M30sDQorCXsxLCAxMzIsIDE1NH0sDQorCXsxLCAx MzMsIDE1NX0sDQorCXsxLCAxMzQsIDE1Nn0sDQorCXsxLCAxMzUsIDE1N30sDQorCXsxLCAxMzYs IDE1OH0sDQorDQorCS8qIDE2MCAqLw0KKwl7MSwgMTM3LCAxNTl9LA0KKwl7MSwgMTM4LCAxNjB9 LA0KKwl7MSwgMTM5LCAxNjF9LA0KKwl7MSwgMTQwLCAxNjJ9LA0KKwl7MSwgMTQxLCAxNjN9LA0K Kwl7MSwgMTQyLCAxNjR9LA0KKwl7MSwgMTQzLCAxNjV9LA0KKwl7MSwgMTQ0LCAxNjZ9LA0KKwl7 MSwgMTQ1LCAxNjd9LA0KKwl7MSwgMTQ2LCAxNjh9LA0KKw0KKwkvKiAxNzAgKi8NCisJezEsIDE0 NywgMTY5fSwNCisJezEsIDE0OCwgMTcwfSwNCisJezEsIDE0OSwgMTcxfSwNCisJezEsIDE1MCwg MTcyfSwNCisJezEsIDE1MSwgMTczfSwNCisJezEsIDE1MiwgMTc0fSwNCisJezEsIDE1MywgMTc1 fSwNCisJezEsIDE1NCwgMTc2fSwNCisJezEsIDE1NSwgMTc3fSwNCisJezEsIDE1NiwgMTc4fSwN CisNCisJLyogMTgwICovDQorCXsxLCAxNTcsIDE3OX0sDQorCXsxLCAxNTgsIDE4MH0sDQorCXsx LCAxNTksIDE4MX0sDQorCXsxLCAxNjAsIDE4Mn0sDQorCXsxLCAxNjEsIDE4M30sDQorCXsxLCAx NjIsIDE4NH0sDQorCXsxLCAxNjMsIDE4NX0sDQorCXsxLCAxNjQsIDE4Nn0sDQorCXsxLCAxNjUs IDE4N30sDQorCXsxLCAxNjYsIDE4OH0sDQorDQorCS8qIDE5MCAqLw0KKwl7MSwgMTY3LCAxODl9 LA0KKwl7MSwgMTY4LCAxOTB9LA0KKwl7MSwgMTY5LCAxOTF9LA0KKwl7MSwgMTcwLCAxOTJ9LA0K Kwl7MSwgMTcxLCAxOTN9LA0KKwl7MSwgMTcyLCAxOTR9LA0KKwl7MSwgMTczLCAxOTV9LA0KKwl7 MSwgMTc0LCAxOTZ9LA0KKwl7MSwgMTc1LCAxOTd9LA0KKwl7MSwgMTc2LCAxOTh9LA0KKw0KKwkv KiAyMDAgKi8NCisJezEsIDE3NywgMTk5fSwNCisJezEsIDE3OCwgMjAwfSwNCisJezEsIDE3OSwg MjAxfSwNCisJezEsIDE4MCwgMjAyfSwNCisJezEsIDE4MSwgMjAzfSwNCisJezEsIDE4MiwgMjA0 fSwNCisJezEsIDE4MywgMjA1fSwNCisJezEsIDE4NCwgMjA2fSwNCisJezEsIDE4NSwgMjA3fSwN CisJezEsIDE4NiwgMjA4fSwNCisNCisJLyogMjEwICovDQorCXsxLCAxODcsIDIwOX0sDQorCXsx LCAxODgsIDIxMH0sDQorCXsxLCAxODksIDIxMX0sDQorCXsxLCAxOTAsIDIxMn0sDQorCXsxLCAx OTEsIDIxM30sDQorCXsxLCAxOTIsIDIxNH0sDQorCXsxLCAxOTMsIDIxNX0sDQorCXsxLCAxOTQs IDIxNn0sDQorCXsxLCAxOTUsIDIxN30sDQorCXsxLCAxOTYsIDIxOH0sDQorDQorCS8qIDIyMCAq Lw0KKwl7MSwgMTk3LCAyMTl9LA0KKwl7MSwgMTk4LCAyMjB9LA0KKwl7MSwgMTk5LCAyMjF9LA0K Kwl7MSwgMjAwLCAyMjJ9LA0KKwl7MSwgMjAxLCAyMjN9LA0KKwl7MSwgMjAyLCAyMjR9LA0KKwl7 MSwgMjAzLCAyMjV9LA0KKwl7MSwgMjA0LCAyMjZ9LA0KKwl7MSwgMjA1LCAyMjd9LA0KKwl7MSwg MjA2LCAyMjh9LA0KKw0KKwkvKiAyMzAgKi8NCisJezEsIDIwNywgMjI5fSwNCisJezEsIDIwOCwg MjMwfSwNCisJezEsIDIwOSwgMjMxfSwNCisJezEsIDIxMCwgMjMyfSwNCisJezEsIDIxMSwgMjMz fSwNCisJezEsIDIxMiwgMjM0fSwNCisJezEsIDIxMywgMjM1fSwNCisJezEsIDIxNCwgMjM2fSwN CisJezEsIDIxNSwgMjM3fSwNCisJezEsIDIxNiwgMjM4fSwNCisNCisJLyogMjQwICovDQorCXsx LCAyMTcsIDIzOX0sDQorCXsxLCAyMTgsIDI0MH0sDQorCXsxLCAyMTksIDI0MX0sDQorCXsxLCAy MjAsIDI0Mn0sDQorCXsxLCAyMjEsIDI0M30sDQorCXsxLCAyMjIsIDI0NH0sDQorCXsxLCAyMjMs IDI0NX0sDQorCXsxLCAyMjQsIDI0Nn0sDQorCXsxLCAyMjUsIDI0N30sDQorCXsxLCAyMjYsIDI0 OH0sDQorDQorCS8qIDI1MCAqLw0KKwl7MSwgMjI3LCAyNDl9LA0KKwl7MSwgMjI4LCAyNTB9LA0K Kwl7MSwgMjI5LCAyNTF9LA0KKwl7MSwgMjMwLCAyNTJ9LA0KKwl7MSwgMjMxLCAyNTN9LA0KKwl7 MSwgMjMyLCAyNTR9LA0KKwl7MSwgMjMzLCAyNTV9LA0KKwl7MSwgMjM0LCAyNTZ9LA0KKwl7MSwg MjM1LCAyNTd9LA0KKwl7MSwgMjM2LCAyNTh9LA0KKw0KKwkvKiAyNjAgKi8NCisJezEsIDIzNywg MjU5fSwNCisJezEsIDIzOCwgMjYwfSwNCisJezEsIDIzOSwgMjYxfSwNCisJezEsIDI0MCwgMjYy fSwNCisJezEsIDI0MSwgMjYzfSwNCisJezEsIDI0MiwgMjY0fSwNCisJezEsIDI0MywgMjY1fSwN CisJezEsIDI0NCwgMjY2fSwNCisJezEsIDI0NSwgMjY3fSwNCisJezEsIDI0NiwgMjY4fSwNCisN CisJLyogMjcwICovDQorCXsxLCAyNDcsIDI2OX0sDQorCXsxLCAyNDgsIDI3MH0sDQorCXsxLCAy NDksIDI3MX0sDQorCXsxLCAyNTAsIDI3Mn0sDQorCXsxLCAyNTEsIDI3M30sDQorCXsxLCAyNTIs IDI3NH0sDQorCXsxLCAyNTMsIDI3NX0sDQorCXsxLCAyNTQsIDI3Nn0sDQorCXsxLCAyNTUsIDI3 N30sDQorCXsyLCAwLCAyNzh9LA0KKw0KKwkvKiAyODAgKi8NCisJezIsIDEsIDI3OX0sDQorCXsy LCAyLCAyODB9LA0KKwl7MiwgMywgMjgxfSwNCisJezIsIDQsIDI4Mn0sDQorCXsyLCA1LCAyODN9 LA0KKwl7MiwgNiwgMjg0fSwNCisJezIsIDcsIDI4NX0sDQorCXsyLCA4LCAyODZ9LA0KKwl7Miwg OSwgMjg3fSwNCisJezIsIDEwLCAyODh9LA0KKw0KKwkvKiAyOTAgKi8NCisJezIsIDExLCAyODl9 LA0KKwl7MiwgMTIsIDI5MH0sDQorCXsyLCAxMywgMjkxfSwNCisJezIsIDE0LCAyOTJ9LA0KKwl7 MiwgMTUsIDI5M30sDQorCXsyLCAxNiwgMjk0fSwNCisJezIsIDE3LCAyOTV9LA0KKwl7MiwgMTgs IDI5Nn0sDQorCXsyLCAxOSwgMjk3fSwNCisJezIsIDIwLCAyOTh9LA0KKw0KKwkvKiAzMDAgKi8N CisJezIsIDIxLCAyOTl9LA0KKwl7MiwgMjIsIDMwMH0sDQorCXsyLCAyMywgMzAxfSwNCisJezIs IDI0LCAzMDJ9LA0KKwl7MiwgMjUsIDMwM30sDQorCXsyLCAyNiwgMzA0fSwNCisJezIsIDI3LCAz MDV9LA0KKwl7MiwgMjgsIDMwNn0sDQorCXsyLCAyOSwgMzA3fSwNCisJezIsIDMwLCAzMDh9LA0K Kw0KKwkvKiAzMTAgKi8NCisJezIsIDMxLCAzMDl9LA0KKwl7MiwgMzIsIDMxMH0sDQorCXsyLCAz MywgMzExfSwNCisJezIsIDM0LCAzMTJ9LA0KKwl7MiwgMzUsIDMxM30sDQorCXsyLCAzNiwgMzE0 fSwNCisJezIsIDM3LCAzMTV9LA0KKwl7MiwgMzgsIDMxNn0sDQorCXsyLCAzOSwgMzE3fSwNCisJ ezIsIDQwLCAzMTh9LA0KKw0KKwkvKiAzMjAgKi8NCisJezIsIDQxLCAzMTl9LA0KKwl7MiwgNDIs IDMyMH0sDQorCXsyLCA0MywgMzIxfSwNCisJezIsIDQ0LCAzMjJ9LA0KKwl7MiwgNDUsIDMyM30s DQorCXsyLCA0NiwgMzI0fSwNCisJezIsIDQ3LCAzMjV9LA0KKwl7MiwgNDgsIDMyNn0sDQorCXsy LCA0OSwgMzI3fSwNCisJezIsIDUwLCAzMjh9LA0KKw0KKwkvKiAzMzAgKi8NCisJezIsIDUxLCAz Mjl9LA0KKwl7MiwgNTIsIDMzMH0sDQorCXsyLCA1MywgMzMxfSwNCisJezIsIDU0LCAzMzJ9LA0K Kwl7MiwgNTUsIDMzM30sDQorCXsyLCA1NiwgMzM0fSwNCisJezIsIDU3LCAzMzV9LA0KKwl7Miwg NTgsIDMzNn0sDQorCXsyLCA1OSwgMzM3fSwNCisJezIsIDYwLCAzMzh9LA0KKw0KKwkvKiAzNDAg Ki8NCisJezIsIDYxLCAzMzl9LA0KKwl7MiwgNjIsIDM0MH0sDQorCXsyLCA2MywgMzQxfSwNCisJ ezIsIDY0LCAzNDJ9LA0KKwl7MiwgNjUsIDM0M30sDQorCXsyLCA2NiwgMzQ0fSwNCisJezIsIDY3 LCAzNDV9LA0KKwl7MiwgNjgsIDM0Nn0sDQorCXsyLCA2OSwgMzQ3fSwNCisJey0xLCAtMSwgMzU1 fSwNCisNCisJLyogMzUwICovDQorCXstMSwgLTEsIDM1Nn0sDQorCXstMSwgLTEsIDM1N30sDQor CXstMSwgLTEsIDM1OH0sDQorCXstMSwgLTEsIDM1OX0sDQorCXstMSwgLTEsIDM2MH0sDQorCXst MSwgLTEsIDM2MX0sDQorCXstMSwgLTEsIDM2Mn0sDQorCXstMSwgLTEsIDM2M30sDQorCXstMSwg LTEsIDM2NH0sDQorCXstMSwgLTEsIDM2NX0sDQorDQorCS8qIDM2MCAqLw0KKwl7LTEsIC0xLCAz NjZ9LA0KKwl7LTEsIC0xLCAzNjd9LA0KKwl7LTEsIC0xLCAzNjh9LA0KKwl7LTEsIC0xLCAzNjl9 LA0KKwl7LTEsIC0xLCAzNzB9LA0KKwl7LTEsIC0xLCAzNzF9LA0KKw0KK307DQorDQorc3RhdGlj IHN0cnVjdCBtdGtfZGV2aWNlX2luZm8gbXQ2ODczX2RldmljZXNfcGVyaVtdID0gew0KKwkvKiBz eXNfaWR4LCBjdHJsX2lkeCwgdmlvX2lkeCAqLw0KKwkvKiAwICovDQorCXswLCAwLCAwfSwNCisJ ezAsIDEsIDF9LA0KKwl7MCwgMiwgMn0sDQorCXswLCAzLCAzfSwNCisJezAsIDQsIDR9LA0KKwl7 MCwgNSwgNX0sDQorCXswLCA2LCA2fSwNCisJezAsIDcsIDd9LA0KKwl7MCwgOCwgOH0sDQorCXsw LCA5LCA5fSwNCisNCisJLyogMTAgKi8NCisJezAsIDEwLCAxMH0sDQorCXswLCAxMSwgMTF9LA0K Kwl7MCwgMTIsIDEzfSwNCisJezAsIDEzLCAxNH0sDQorCXswLCAxNCwgMTV9LA0KKwl7MCwgMTUs IDE2fSwNCisJezAsIDE2LCAxN30sDQorCXswLCAxNywgMTh9LA0KKwl7MCwgMTgsIDE5fSwNCisJ ezAsIDE5LCAyMH0sDQorDQorCS8qIDIwICovDQorCXswLCAyMCwgMjF9LA0KKwl7MCwgMjEsIDIz fSwNCisJezAsIDIyLCAyNH0sDQorCXswLCAyMywgMjV9LA0KKwl7MCwgMjQsIDI2fSwNCisJezAs IDI1LCAyN30sDQorCXswLCAyNiwgMjh9LA0KKwl7MCwgMjcsIDI5fSwNCisJezAsIDI4LCAzMH0s DQorCXswLCAyOSwgMzF9LA0KKw0KKwkvKiAzMCAqLw0KKwl7MCwgMzAsIDMyfSwNCisJezAsIDMx LCAzM30sDQorCXswLCAzMiwgMzR9LA0KKwl7MCwgMzMsIDM1fSwNCisJezAsIDM0LCAzNn0sDQor CXswLCAzNSwgMzd9LA0KKwl7MCwgMzYsIDM4fSwNCisJezAsIDM3LCA2Mn0sDQorCXswLCAzOCwg NjN9LA0KKwl7MCwgMzksIDY0fSwNCisNCisJLyogNDAgKi8NCisJezAsIDQwLCA2NX0sDQorCXsw LCA0MSwgNjZ9LA0KKwl7MCwgNDIsIDY3fSwNCisJezAsIDQzLCA2OH0sDQorCXswLCA0NCwgNjl9 LA0KKwl7MCwgNDUsIDcwfSwNCisJezAsIDQ2LCA3MX0sDQorCXswLCA0NywgNzJ9LA0KKwl7MCwg NDgsIDczfSwNCisJezAsIDQ5LCA3NH0sDQorDQorCS8qIDUwICovDQorCXswLCA1MCwgMTE5fSwN CisJezAsIDUxLCAxMjB9LA0KKwl7MCwgNTIsIDEyMX0sDQorCXswLCA1MywgMTIyfSwNCisJezAs IDU0LCAxMjN9LA0KKwl7MCwgNTUsIDEyNH0sDQorCXswLCA1NiwgMTI1fSwNCisJezAsIDU3LCAx MjZ9LA0KKwl7MCwgNTgsIDEyN30sDQorCXswLCA1OSwgMTI4fSwNCisNCisJLyogNjAgKi8NCisJ ezAsIDYwLCAxMjl9LA0KKwl7MCwgNjEsIDEzMH0sDQorCXswLCA2MiwgMTM3fSwNCisJezAsIDYz LCAxNDN9LA0KKwl7MCwgNjQsIDE0NH0sDQorCXswLCA2NSwgMTQ1fSwNCisJezAsIDY2LCAxNDZ9 LA0KKwl7MCwgNjcsIDE0N30sDQorCXswLCA2OCwgMTQ4fSwNCisJezAsIDY5LCAxNDl9LA0KKw0K KwkvKiA3MCAqLw0KKwl7MCwgNzAsIDE1MH0sDQorCXswLCA3MSwgMTUxfSwNCisJezAsIDcyLCAx NTJ9LA0KKwl7MCwgNzMsIDE1M30sDQorCXswLCA3NCwgMTU0fSwNCisJezAsIDc1LCAxNTV9LA0K Kwl7MCwgNzYsIDE1Nn0sDQorCXswLCA3NywgMTU3fSwNCisJezAsIDc4LCAxNTh9LA0KKwl7MCwg NzksIDE1OX0sDQorDQorCS8qIDgwICovDQorCXswLCA4MCwgMTYwfSwNCisJezAsIDgxLCAxNjF9 LA0KKwl7MCwgODIsIDE2Mn0sDQorCXswLCA4MywgMTYzfSwNCisJezAsIDg0LCAxNjR9LA0KKwl7 MCwgODUsIDE2NX0sDQorCXswLCA4NiwgMTY2fSwNCisJezAsIDg3LCAxNjd9LA0KKwl7MCwgODgs IDE2OH0sDQorCXswLCA4OSwgMTY5fSwNCisNCisJLyogOTAgKi8NCisJezAsIDkwLCAxNzB9LA0K Kwl7MCwgOTEsIDE3MX0sDQorCXswLCA5MiwgMTc0fSwNCisJezAsIDkzLCAxNzV9LA0KKwl7MCwg OTQsIDE3Nn0sDQorCXswLCA5NSwgMTc3fSwNCisJezAsIDk2LCAxNzh9LA0KKwl7MCwgOTcsIDE3 OX0sDQorCXswLCA5OCwgMTgwfSwNCisJezAsIDk5LCAxODF9LA0KKw0KKwkvKiAxMDAgKi8NCisJ ezAsIDEwMCwgMTgyfSwNCisJezAsIDEwMSwgMTgzfSwNCisJezAsIDEwMiwgMTg0fSwNCisJezAs IDEwMywgMTg1fSwNCisJezAsIDEwNCwgMTg2fSwNCisJezEsIDAsIDM5fSwNCisJezEsIDEsIDQw fSwNCisJezEsIDIsIDQxfSwNCisJezEsIDMsIDQyfSwNCisJezEsIDQsIDQzfSwNCisNCisJLyog MTEwICovDQorCXsxLCA1LCA0NH0sDQorCXsxLCA2LCA0NX0sDQorCXsxLCA3LCA0Nn0sDQorCXsx LCA4LCA0N30sDQorCXsxLCA5LCA0OH0sDQorCXsxLCAxMCwgNDl9LA0KKwl7MSwgMTEsIDUwfSwN CisJezEsIDEyLCA1MX0sDQorCXsxLCAxMywgNTJ9LA0KKwl7MSwgMTQsIDUzfSwNCisNCisJLyog MTIwICovDQorCXsxLCAxNSwgNTR9LA0KKwl7MSwgMTYsIDU1fSwNCisJezEsIDE3LCA1Nn0sDQor CXsxLCAxOCwgNTd9LA0KKwl7MSwgMTksIDU4fSwNCisJezEsIDIwLCA1OX0sDQorCXsxLCAyMSwg NjB9LA0KKwl7MSwgMjIsIDYxfSwNCisJezEsIDIzLCA3Nn0sDQorCXsxLCAyNCwgNzd9LA0KKw0K KwkvKiAxMzAgKi8NCisJezEsIDI1LCA3OH0sDQorCXsxLCAyNiwgNzl9LA0KKwl7MSwgMjcsIDgw fSwNCisJezEsIDI4LCA4MX0sDQorCXsxLCAyOSwgODJ9LA0KKwl7MSwgMzAsIDgzfSwNCisJezEs IDMxLCA4NH0sDQorCXsxLCAzMiwgODV9LA0KKwl7MSwgMzMsIDg2fSwNCisJezEsIDM0LCA4N30s DQorDQorCS8qIDE0MCAqLw0KKwl7MSwgMzUsIDg4fSwNCisJezEsIDM2LCA4OX0sDQorCXsxLCAz NywgOTB9LA0KKwl7MSwgMzgsIDkxfSwNCisJezEsIDM5LCA5Mn0sDQorCXsxLCA0MCwgOTN9LA0K Kwl7MSwgNDEsIDk0fSwNCisJezEsIDQyLCA5NX0sDQorCXsxLCA0MywgOTZ9LA0KKwl7MSwgNDQs IDk3fSwNCisNCisJLyogMTUwICovDQorCXsxLCA0NSwgOTh9LA0KKwl7MSwgNDYsIDk5fSwNCisJ ezEsIDQ3LCAxMDB9LA0KKwl7MSwgNDgsIDEwMX0sDQorCXsxLCA0OSwgMTAyfSwNCisJezEsIDUw LCAxMDN9LA0KKwl7MSwgNTEsIDEwNH0sDQorCXsxLCA1MiwgMTA1fSwNCisJezEsIDUzLCAxMDZ9 LA0KKwl7MSwgNTQsIDEwN30sDQorDQorCS8qIDE2MCAqLw0KKwl7MSwgNTUsIDEwOH0sDQorCXsx LCA1NiwgMTA5fSwNCisJezEsIDU3LCAxMTB9LA0KKwl7MSwgNTgsIDExMX0sDQorCXsxLCA1OSwg MTEyfSwNCisJezEsIDYwLCAxMTN9LA0KKwl7MSwgNjEsIDExNH0sDQorCXsxLCA2MiwgMTE1fSwN CisJezEsIDYzLCAxMTZ9LA0KKwl7MSwgNjQsIDExN30sDQorDQorCS8qIDE3MCAqLw0KKwl7MSwg NjUsIDExOH0sDQorCXsyLCAwLCA3NX0sDQorCXstMSwgLTEsIDE4N30sDQorCXstMSwgLTEsIDE4 OH0sDQorCXstMSwgLTEsIDE4OX0sDQorCXstMSwgLTEsIDE5MH0sDQorCXstMSwgLTEsIDE5MX0s DQorCXstMSwgLTEsIDE5Mn0sDQorCXstMSwgLTEsIDE5M30sDQorCXstMSwgLTEsIDE5NH0sDQor DQorCS8qIDE4MCAqLw0KKwl7LTEsIC0xLCAxOTV9LA0KKwl7LTEsIC0xLCAxOTZ9LA0KKwl7LTEs IC0xLCAxOTd9LA0KKwl7LTEsIC0xLCAxOTh9LA0KKwl7LTEsIC0xLCAxOTl9LA0KKwl7LTEsIC0x LCAyMDB9LA0KKwl7LTEsIC0xLCAyMDF9LA0KKwl7LTEsIC0xLCAyMDJ9LA0KKwl7LTEsIC0xLCAy MDN9LA0KKwl7LTEsIC0xLCAyMDR9LA0KKw0KKwkvKiAxOTAgKi8NCisJey0xLCAtMSwgMjA1fSwN CisJey0xLCAtMSwgMjA2fSwNCisJey0xLCAtMSwgMjA3fSwNCisJey0xLCAtMSwgMjA4fSwNCisJ ey0xLCAtMSwgMjA5fSwNCisJey0xLCAtMSwgMjEwfSwNCisJey0xLCAtMSwgMjExfSwNCisJey0x LCAtMSwgMjEyfSwNCisJey0xLCAtMSwgMjEzfSwNCisJey0xLCAtMSwgMjE0fSwNCisNCisJLyog MjAwICovDQorCXstMSwgLTEsIDIxNX0sDQorCXstMSwgLTEsIDIxNn0sDQorCXstMSwgLTEsIDIx N30sDQorCXstMSwgLTEsIDIxOH0sDQorCXstMSwgLTEsIDIxOX0sDQorCXstMSwgLTEsIDIyMH0s DQorCXstMSwgLTEsIDIyMX0sDQorCXstMSwgLTEsIDIyMn0sDQorCXstMSwgLTEsIDIyM30sDQor CXstMSwgLTEsIDIyNH0sDQorDQorCS8qIDIxMCAqLw0KKwl7LTEsIC0xLCAyMjV9LA0KKwl7LTEs IC0xLCAyMjZ9LA0KKwl7LTEsIC0xLCAyMjd9LA0KKwl7LTEsIC0xLCAyMjh9LA0KKwl7LTEsIC0x LCAyMjl9LA0KKwl7LTEsIC0xLCAyMzB9LA0KKwl7LTEsIC0xLCAyMzF9LA0KKwl7LTEsIC0xLCAy MzJ9LA0KKwl7LTEsIC0xLCAyMzN9LA0KKwl7LTEsIC0xLCAyMzR9LA0KKw0KKwkvKiAyMjAgKi8N CisJey0xLCAtMSwgMjM1fSwNCisJey0xLCAtMSwgMjM2fSwNCisJey0xLCAtMSwgMjM3fSwNCisJ ey0xLCAtMSwgMjM4fSwNCisJey0xLCAtMSwgMjM5fSwNCisJey0xLCAtMSwgMjQwfSwNCisJey0x LCAtMSwgMjQxfSwNCisJey0xLCAtMSwgMjQyfSwNCisJey0xLCAtMSwgMjQzfSwNCisJey0xLCAt MSwgMjQ0fSwNCisNCisJLyogMjMwICovDQorCXstMSwgLTEsIDI0NX0sDQorCXstMSwgLTEsIDI0 Nn0sDQorCXstMSwgLTEsIDI0N30sDQorCXstMSwgLTEsIDI0OH0sDQorCXstMSwgLTEsIDI0OX0s DQorCXstMSwgLTEsIDI1MH0sDQorCXstMSwgLTEsIDI1MX0sDQorCXstMSwgLTEsIDI1Mn0sDQor CXstMSwgLTEsIDI1M30sDQorCXstMSwgLTEsIDI1NH0sDQorDQorCS8qIDI0MCAqLw0KKwl7LTEs IC0xLCAyNTV9LA0KKwl7LTEsIC0xLCAyNTZ9LA0KKwl7LTEsIC0xLCAyNTd9LA0KKwl7LTEsIC0x LCAyNTh9LA0KKwl7LTEsIC0xLCAyNTl9LA0KKwl7LTEsIC0xLCAyNjB9LA0KKwl7LTEsIC0xLCAy NjF9LA0KKwl7LTEsIC0xLCAyNjJ9LA0KKwl7LTEsIC0xLCAyNjN9LA0KKwl7LTEsIC0xLCAyNjR9 LA0KKw0KKwkvKiAyNTAgKi8NCisJey0xLCAtMSwgMjY1fSwNCisJey0xLCAtMSwgMjY2fSwNCisJ ey0xLCAtMSwgMjY3fSwNCisJey0xLCAtMSwgMjY4fSwNCisJey0xLCAtMSwgMjY5fSwNCisJey0x LCAtMSwgMjcwfSwNCisJey0xLCAtMSwgMjcxfSwNCisJey0xLCAtMSwgMjcyfSwNCisJey0xLCAt MSwgMjczfSwNCisJey0xLCAtMSwgMjc0fSwNCisNCisJLyogMjYwICovDQorCXstMSwgLTEsIDI3 NX0sDQorCXstMSwgLTEsIDI3Nn0sDQorCXstMSwgLTEsIDI3N30sDQorCXstMSwgLTEsIDI3OH0s DQorCXstMSwgLTEsIDI3OX0sDQorCXstMSwgLTEsIDI4MH0sDQorCXstMSwgLTEsIDI4MX0sDQor CXstMSwgLTEsIDI4Mn0sDQorCXstMSwgLTEsIDI4M30sDQorCXstMSwgLTEsIDI4NH0sDQorDQor CS8qIDI3MCAqLw0KKwl7LTEsIC0xLCAyODV9LA0KKwl7LTEsIC0xLCAyODZ9LA0KKwl7LTEsIC0x LCAyODd9LA0KKwl7LTEsIC0xLCAyODh9LA0KKwl7LTEsIC0xLCAyODl9LA0KKwl7LTEsIC0xLCAy OTB9LA0KKwl7LTEsIC0xLCAyOTF9LA0KKwl7LTEsIC0xLCAyOTJ9LA0KKwl7LTEsIC0xLCAyOTN9 LA0KKwl7LTEsIC0xLCAyOTR9LA0KKw0KKwkvKiAyODAgKi8NCisJey0xLCAtMSwgMjk1fSwNCisJ ey0xLCAtMSwgMjk2fSwNCisJey0xLCAtMSwgMjk3fSwNCisJey0xLCAtMSwgMjk4fSwNCisNCit9 Ow0KKw0KK3N0YXRpYyBzdHJ1Y3QgbXRrX2RldmljZV9pbmZvIG10Njg3M19kZXZpY2VzX3Blcmky W10gPSB7DQorCS8qIHN5c19pZHgsIGN0cmxfaWR4LCB2aW9faWR4ICovDQorCS8qIDAgKi8NCisJ ezAsIDAsIDB9LA0KKwl7MCwgMSwgMX0sDQorCXswLCAyLCAyfSwNCisJezAsIDMsIDN9LA0KKwl7 MCwgNCwgNH0sDQorCXswLCA1LCA1fSwNCisJezAsIDYsIDZ9LA0KKwl7MCwgNywgN30sDQorCXsw LCA4LCA4fSwNCisJezAsIDksIDl9LA0KKw0KKwkvKiAxMCAqLw0KKwl7MCwgMTAsIDEwfSwNCisJ ezAsIDExLCAxMX0sDQorCXswLCAxMiwgMTJ9LA0KKwl7MCwgMTMsIDEzfSwNCisJezAsIDE0LCAx NH0sDQorCXswLCAxNSwgMTV9LA0KKwl7MCwgMTYsIDE2fSwNCisJezAsIDE3LCAxN30sDQorCXsw LCAxOCwgMTh9LA0KKwl7MCwgMTksIDE5fSwNCisNCisJLyogMjAgKi8NCisJezAsIDIwLCAyMH0s DQorCXswLCAyMSwgMjF9LA0KKwl7MCwgMjIsIDIyfSwNCisJezAsIDIzLCAyM30sDQorCXswLCAy NCwgMjR9LA0KKwl7MCwgMjUsIDI1fSwNCisJezAsIDI2LCAyNn0sDQorCXswLCAyNywgMjd9LA0K Kwl7MCwgMjgsIDI4fSwNCisJezAsIDI5LCAyOX0sDQorDQorCS8qIDMwICovDQorCXswLCAzMCwg MzB9LA0KKwl7MCwgMzEsIDMxfSwNCisJezAsIDMyLCAzMn0sDQorCXswLCAzMywgMzN9LA0KKwl7 MCwgMzQsIDM0fSwNCisJezAsIDM1LCAzNX0sDQorCXswLCAzNiwgMzZ9LA0KKwl7MCwgMzcsIDM3 fSwNCisJezAsIDM4LCAzOH0sDQorCXswLCAzOSwgMzl9LA0KKw0KKwkvKiA0MCAqLw0KKwl7MCwg NDAsIDQwfSwNCisJezAsIDQxLCA0MX0sDQorCXswLCA0MiwgNDJ9LA0KKwl7MCwgNDMsIDQzfSwN CisJezAsIDQ0LCA0NH0sDQorCXswLCA0NSwgNDV9LA0KKwl7MCwgNDYsIDQ2fSwNCisJezAsIDQ3 LCA0N30sDQorCXswLCA0OCwgNDh9LA0KKwl7MCwgNDksIDQ5fSwNCisNCisJLyogNTAgKi8NCisJ ezAsIDUwLCA1MH0sDQorCXswLCA1MSwgNTF9LA0KKwl7MCwgNTIsIDUyfSwNCisJezAsIDUzLCA1 M30sDQorCXswLCA1NCwgNTR9LA0KKwl7MCwgNTUsIDU1fSwNCisJezAsIDU2LCA1Nn0sDQorCXsw LCA1NywgNTd9LA0KKwl7MCwgNTgsIDU4fSwNCisJezAsIDU5LCA1OX0sDQorDQorCS8qIDYwICov DQorCXswLCA2MCwgNjB9LA0KKwl7MCwgNjEsIDYxfSwNCisJezAsIDYyLCA2Mn0sDQorCXswLCA2 MywgNjN9LA0KKwl7MCwgNjQsIDY0fSwNCisJezAsIDY1LCA2NX0sDQorCXswLCA2NiwgNjZ9LA0K Kwl7MCwgNjcsIDY3fSwNCisJezAsIDY4LCA2OH0sDQorCXswLCA2OSwgNjl9LA0KKw0KKwkvKiA3 MCAqLw0KKwl7MCwgNzAsIDcwfSwNCisJezAsIDcxLCA3MX0sDQorCXswLCA3MiwgNzJ9LA0KKwl7 MCwgNzMsIDczfSwNCisJezAsIDc0LCA3NH0sDQorCXswLCA3NSwgNzV9LA0KKwl7MCwgNzYsIDc2 fSwNCisJezAsIDc3LCA3N30sDQorCXswLCA3OCwgNzh9LA0KKwl7MCwgNzksIDc5fSwNCisNCisJ LyogODAgKi8NCisJezAsIDgwLCA4MH0sDQorCXswLCA4MSwgODF9LA0KKwl7MCwgODIsIDgyfSwN CisJezAsIDgzLCA4M30sDQorCXswLCA4NCwgODR9LA0KKwl7MCwgODUsIDg1fSwNCisJezAsIDg2 LCA4Nn0sDQorCXswLCA4NywgODd9LA0KKwl7MCwgODgsIDg4fSwNCisJezAsIDg5LCA4OX0sDQor DQorCS8qIDkwICovDQorCXswLCA5MCwgOTB9LA0KKwl7MCwgOTEsIDkxfSwNCisJezAsIDkyLCA5 Mn0sDQorCXswLCA5MywgOTN9LA0KKwl7MCwgOTQsIDk0fSwNCisJezAsIDk1LCA5NX0sDQorCXsw LCA5NiwgOTZ9LA0KKwl7MCwgOTcsIDk3fSwNCisJezAsIDk4LCA5OH0sDQorCXswLCA5OSwgOTl9 LA0KKw0KKwkvKiAxMDAgKi8NCisJezAsIDEwMCwgMTAwfSwNCisJezAsIDEwMSwgMTAzfSwNCisJ ezAsIDEwMiwgMTA0fSwNCisJezAsIDEwMywgMTA1fSwNCisJezAsIDEwNCwgMTA2fSwNCisJezAs IDEwNSwgMTA3fSwNCisJezAsIDEwNiwgMTA4fSwNCisJezAsIDEwNywgMTA5fSwNCisJezAsIDEw OCwgMTEwfSwNCisJezAsIDEwOSwgMTExfSwNCisNCisJLyogMTEwICovDQorCXswLCAxMTAsIDEx Mn0sDQorCXswLCAxMTEsIDExM30sDQorCXswLCAxMTIsIDExNH0sDQorCXswLCAxMTMsIDExNX0s DQorCXswLCAxMTQsIDExNn0sDQorCXstMSwgLTEsIDExN30sDQorCXstMSwgLTEsIDExOH0sDQor CXstMSwgLTEsIDExOX0sDQorCXstMSwgLTEsIDEyMH0sDQorCXstMSwgLTEsIDEyMX0sDQorDQor CS8qIDEyMCAqLw0KKwl7LTEsIC0xLCAxMjJ9LA0KKwl7LTEsIC0xLCAxMjN9LA0KKwl7LTEsIC0x LCAxMjR9LA0KKwl7LTEsIC0xLCAxMjV9LA0KKwl7LTEsIC0xLCAxMjZ9LA0KKwl7LTEsIC0xLCAx Mjd9LA0KKwl7LTEsIC0xLCAxMjh9LA0KKwl7LTEsIC0xLCAxMjl9LA0KKwl7LTEsIC0xLCAxMzB9 LA0KKwl7LTEsIC0xLCAxMzF9LA0KKw0KKwkvKiAxMzAgKi8NCisJey0xLCAtMSwgMTMyfSwNCisJ ey0xLCAtMSwgMTMzfSwNCisJey0xLCAtMSwgMTM0fSwNCisJey0xLCAtMSwgMTM1fSwNCisJey0x LCAtMSwgMTM2fSwNCisJey0xLCAtMSwgMTM3fSwNCisJey0xLCAtMSwgMTM4fSwNCisJey0xLCAt MSwgMTM5fSwNCisJey0xLCAtMSwgMTQwfSwNCisJey0xLCAtMSwgMTQxfSwNCisNCisJLyogMTQw ICovDQorCXstMSwgLTEsIDE0Mn0sDQorCXstMSwgLTEsIDE0M30sDQorCXstMSwgLTEsIDE0NH0s DQorCXstMSwgLTEsIDE0NX0sDQorCXstMSwgLTEsIDE0Nn0sDQorCXstMSwgLTEsIDE0N30sDQor CXstMSwgLTEsIDE0OH0sDQorCXstMSwgLTEsIDE0OX0sDQorCXstMSwgLTEsIDE1MH0sDQorCXst MSwgLTEsIDE1MX0sDQorDQorCS8qIDE1MCAqLw0KKwl7LTEsIC0xLCAxNTJ9LA0KKwl7LTEsIC0x LCAxNTN9LA0KKwl7LTEsIC0xLCAxNTR9LA0KKwl7LTEsIC0xLCAxNTV9LA0KKwl7LTEsIC0xLCAx NTZ9LA0KKwl7LTEsIC0xLCAxNTd9LA0KKwl7LTEsIC0xLCAxNTh9LA0KKwl7LTEsIC0xLCAxNTl9 LA0KKwl7LTEsIC0xLCAxNjB9LA0KKwl7LTEsIC0xLCAxNjF9LA0KKw0KKwkvKiAxNjAgKi8NCisJ ey0xLCAtMSwgMTYyfSwNCisJey0xLCAtMSwgMTYzfSwNCisJey0xLCAtMSwgMTY0fSwNCisJey0x LCAtMSwgMTY1fSwNCisJey0xLCAtMSwgMTY2fSwNCisJey0xLCAtMSwgMTY3fSwNCisJey0xLCAt MSwgMTY4fSwNCisJey0xLCAtMSwgMTY5fSwNCisJey0xLCAtMSwgMTcwfSwNCisJey0xLCAtMSwg MTcxfSwNCisNCisJLyogMTcwICovDQorCXstMSwgLTEsIDE3Mn0sDQorCXstMSwgLTEsIDE3M30s DQorCXstMSwgLTEsIDE3NH0sDQorCXstMSwgLTEsIDE3NX0sDQorCXstMSwgLTEsIDE3Nn0sDQor CXstMSwgLTEsIDE3N30sDQorCXstMSwgLTEsIDE3OH0sDQorCXstMSwgLTEsIDE3OX0sDQorCXst MSwgLTEsIDE4MH0sDQorCXstMSwgLTEsIDE4MX0sDQorDQorCS8qIDE4MCAqLw0KKwl7LTEsIC0x LCAxODJ9LA0KKwl7LTEsIC0xLCAxODN9LA0KKwl7LTEsIC0xLCAxODR9LA0KKwl7LTEsIC0xLCAx ODV9LA0KKwl7LTEsIC0xLCAxODZ9LA0KKwl7LTEsIC0xLCAxODd9LA0KKwl7LTEsIC0xLCAxODh9 LA0KKwl7LTEsIC0xLCAxODl9LA0KKwl7LTEsIC0xLCAxOTB9LA0KKwl7LTEsIC0xLCAxOTF9LA0K Kw0KKwkvKiAxOTAgKi8NCisJey0xLCAtMSwgMTkyfSwNCisJey0xLCAtMSwgMTkzfSwNCisJey0x LCAtMSwgMTk0fSwNCisJey0xLCAtMSwgMTk1fSwNCisJey0xLCAtMSwgMTk2fSwNCisJey0xLCAt MSwgMTk3fSwNCisJey0xLCAtMSwgMTk4fSwNCisJey0xLCAtMSwgMTk5fSwNCisJey0xLCAtMSwg MjAwfSwNCisJey0xLCAtMSwgMjAxfSwNCisNCisJLyogMjAwICovDQorCXstMSwgLTEsIDIwMn0s DQorCXstMSwgLTEsIDIwM30sDQorCXstMSwgLTEsIDIwNH0sDQorCXstMSwgLTEsIDIwNX0sDQor CXstMSwgLTEsIDIwNn0sDQorCXstMSwgLTEsIDIwN30sDQorCXstMSwgLTEsIDIwOH0sDQorCXst MSwgLTEsIDIwOX0sDQorCXstMSwgLTEsIDIxMH0sDQorCXstMSwgLTEsIDIxMX0sDQorDQorCS8q IDIxMCAqLw0KKwl7LTEsIC0xLCAyMTJ9LA0KKwl7LTEsIC0xLCAyMTN9LA0KKwl7LTEsIC0xLCAy MTR9LA0KKwl7LTEsIC0xLCAyMTV9LA0KKwl7LTEsIC0xLCAyMTZ9LA0KKwl7LTEsIC0xLCAyMTd9 LA0KKwl7LTEsIC0xLCAyMTh9LA0KKwl7LTEsIC0xLCAyMTl9LA0KKwl7LTEsIC0xLCAyMjB9LA0K Kwl7LTEsIC0xLCAyMjF9LA0KKw0KKwkvKiAyMjAgKi8NCisJey0xLCAtMSwgMjIyfSwNCisJey0x LCAtMSwgMjIzfSwNCisJey0xLCAtMSwgMjI0fSwNCisJey0xLCAtMSwgMjI1fSwNCisJey0xLCAt MSwgMjI2fSwNCisJey0xLCAtMSwgMjI3fSwNCisJey0xLCAtMSwgMjI4fSwNCisJey0xLCAtMSwg MjI5fSwNCisJey0xLCAtMSwgMjMwfSwNCisJey0xLCAtMSwgMjMxfSwNCisNCisJLyogMjMwICov DQorCXstMSwgLTEsIDIzMn0sDQorCXstMSwgLTEsIDIzM30sDQorCXstMSwgLTEsIDIzNH0sDQor CXstMSwgLTEsIDIzNX0sDQorCXstMSwgLTEsIDIzNn0sDQorCXstMSwgLTEsIDIzN30sDQorCXst MSwgLTEsIDIzOH0sDQorCXstMSwgLTEsIDIzOX0sDQorCXstMSwgLTEsIDI0MH0sDQorCXstMSwg LTEsIDI0MX0sDQorDQorCS8qIDI0MCAqLw0KKwl7LTEsIC0xLCAyNDJ9LA0KKwl7LTEsIC0xLCAy NDN9LA0KKwl7LTEsIC0xLCAyNDR9LA0KKwl7LTEsIC0xLCAyNDV9LA0KKwl7LTEsIC0xLCAyNDZ9 LA0KKwl7LTEsIC0xLCAyNDd9LA0KKwl7LTEsIC0xLCAyNDh9LA0KKw0KK307DQorDQorc3RhdGlj IHN0cnVjdCBtdGtfZGV2aWNlX2luZm8gbXQ2ODczX2RldmljZXNfcGVyaV9wYXJbXSA9IHsNCisJ Lyogc3lzX2lkeCwgY3RybF9pZHgsIHZpb19pZHggKi8NCisJLyogMCAqLw0KKwl7MCwgMCwgMH0s DQorCXswLCAxLCAxfSwNCisJezAsIDIsIDJ9LA0KKwl7MCwgMywgM30sDQorCXswLCA0LCA0fSwN CisJezAsIDUsIDV9LA0KKwl7MCwgNiwgNn0sDQorCXswLCA3LCA3fSwNCisJezAsIDgsIDh9LA0K Kwl7MCwgOSwgOX0sDQorDQorCS8qIDEwICovDQorCXswLCAxMCwgMTB9LA0KKwl7MCwgMTEsIDEx fSwNCisJezAsIDEyLCAxMn0sDQorCXswLCAxMywgMTN9LA0KKwl7MCwgMTQsIDE0fSwNCisJezAs IDE1LCAxNX0sDQorCXswLCAxNiwgMTZ9LA0KKwl7MCwgMTcsIDE3fSwNCisJezAsIDE4LCAxOH0s DQorCXswLCAxOSwgMTl9LA0KKw0KKwkvKiAyMCAqLw0KKwl7MCwgMjAsIDIwfSwNCisJezAsIDIx LCAyMX0sDQorCXswLCAyMiwgMjJ9LA0KKwl7MCwgMjMsIDIzfSwNCisJezAsIDI0LCAyNH0sDQor CXswLCAyNSwgMjV9LA0KKwl7MCwgMjYsIDI2fSwNCisJey0xLCAtMSwgMjd9LA0KKwl7LTEsIC0x LCAyOH0sDQorCXstMSwgLTEsIDI5fSwNCisNCisJLyogMzAgKi8NCisJey0xLCAtMSwgMzB9LA0K Kwl7LTEsIC0xLCAzMX0sDQorCXstMSwgLTEsIDMyfSwNCisJey0xLCAtMSwgMzN9LA0KKwl7LTEs IC0xLCAzNH0sDQorCXstMSwgLTEsIDM1fSwNCisJey0xLCAtMSwgMzZ9LA0KKwl7LTEsIC0xLCAz N30sDQorCXstMSwgLTEsIDM4fSwNCisJey0xLCAtMSwgMzl9LA0KKw0KKwkvKiA0MCAqLw0KKwl7 LTEsIC0xLCA0MH0sDQorCXstMSwgLTEsIDQxfSwNCisJey0xLCAtMSwgNDJ9LA0KKwl7LTEsIC0x LCA0M30sDQorCXstMSwgLTEsIDQ0fSwNCisJey0xLCAtMSwgNDV9LA0KKwl7LTEsIC0xLCA0Nn0s DQorCXstMSwgLTEsIDQ3fSwNCisJey0xLCAtMSwgNDh9LA0KKwl7LTEsIC0xLCA0OX0sDQorDQor CS8qIDUwICovDQorCXstMSwgLTEsIDUwfSwNCisJey0xLCAtMSwgNTF9LA0KKwl7LTEsIC0xLCA1 Mn0sDQorCXstMSwgLTEsIDUzfSwNCisJey0xLCAtMSwgNTR9LA0KKwl7LTEsIC0xLCA1NX0sDQor CXstMSwgLTEsIDU2fSwNCisJey0xLCAtMSwgNTd9LA0KKw0KK307DQorDQorc3RhdGljIHN0cnVj dCBtdGtfZGV2aWNlX251bSBtdGs2ODczX2RldmljZXNfbnVtW10gPSB7DQorCXtTTEFWRV9UWVBF X0lORlJBLCBWSU9fU0xBVkVfTlVNX0lORlJBfSwNCisJe1NMQVZFX1RZUEVfUEVSSSwgVklPX1NM QVZFX05VTV9QRVJJfSwNCisJe1NMQVZFX1RZUEVfUEVSSTIsIFZJT19TTEFWRV9OVU1fUEVSSTJ9 LA0KKwl7U0xBVkVfVFlQRV9QRVJJX1BBUiwgVklPX1NMQVZFX05VTV9QRVJJX1BBUn0sDQorfTsN CisNCitzdGF0aWMgc3RydWN0IElORlJBQVhJX0lEX0lORk8gcGVyaV9taV9pZF90b19tYXN0ZXJb XSA9IHsNCisJeyJUSEVSTTIiLCAgICAweDAsIDB4N30sDQorCXsiU1BNIiwgICAgICAgMHgyLCAw eDd9LA0KKwl7IkNDVSIsICAgICAgIDB4NCwgMHg3fSwNCisJeyJUSEVSTSIsICAgICAweDYsIDB4 N30sDQorCXsiU1BNX0RSQU1DIiwgMHgzLCAweDd9LA0KK307DQorDQorc3RhdGljIHN0cnVjdCBJ TkZSQUFYSV9JRF9JTkZPIGluZnJhX21pX2lkX3RvX21hc3RlcltdID0gew0KKwl7IkNPTk5TWVNf V0ZETUEiLCAgIDB4MCwgICAgMHgzZmZmfSwNCisJeyJDT05OU1lTX0lDQVAiLCAgICAweDEwLCAg IDB4M2ZmZn0sDQorCXsiQ09OTlNZU19NQ1VfU1lTIiwgMHgyMCwgICAweDNmZmZ9LA0KKwl7IkNP Tk5TWVNfR1BTIiwgICAgIDB4MzAsICAgMHgzZmZmfSwNCisJeyJUaW55c3lzIiwgICAgICAgICAw eDIsICAgIDB4M2MwZn0sDQorCXsiQ1FfRE1BIiwgICAgICAgICAgMHg0LCAgICAweDNjN2Z9LA0K Kwl7IkRlYnVnVG9wIiwgICAgICAgIDB4MTQsICAgMHgzZjdmfSwNCisJeyJTU1VTQiIsICAgICAg ICAgICAweDI0LCAgIDB4ZmZmfSwNCisJeyJTU1VTQjIiLCAgICAgICAgICAweDQyNCwgIDB4ZmZm fSwNCisJeyJOT1IiLCAgICAgICAgICAgICAweDgyNCwgIDB4ZmZmfSwNCisJeyJQV00iLCAgICAg ICAgICAgICAweGMyNCwgIDB4M2ZmZn0sDQorCXsiU1BJNiIsICAgICAgICAgICAgMHgyYzI0LCAw eDNmZmZ9LA0KKwl7IlNQSTAiLCAgICAgICAgICAgIDB4M2MyNCwgMHgzZmZmfSwNCisJeyJBUFUi LCAgICAgICAgICAgICAweGE0LCAgIDB4MzNmZn0sDQorCXsiU1BJMiIsICAgICAgICAgICAgMHgx MjQsICAweDNmZmZ9LA0KKwl7IlNQSTMiLCAgICAgICAgICAgIDB4NTI0LCAgMHgzZmZmfSwNCisJ eyJTUEk0IiwgICAgICAgICAgICAweDkyNCwgIDB4M2ZmZn0sDQorCXsiU1BJNSIsICAgICAgICAg ICAgMHhkMjQsICAweDNmZmZ9LA0KKwl7IlNQSTciLCAgICAgICAgICAgIDB4MWE0LCAgMHgzZmZm fSwNCisJeyJBdWRpbyIsICAgICAgICAgICAweDlhNCwgIDB4M2ZmZn0sDQorCXsiU1BJMSIsICAg ICAgICAgICAgMHhkYTQsICAweDNmZmZ9LA0KKwl7IkFQX0RNQV9FWFQiLCAgICAgIDB4MjI0LCAg MHgyM2ZmfSwNCisJeyJUSEVSTTIiLCAgICAgICAgICAweDJhNCwgIDB4M2ZmZn0sDQorCXsiU1BN IiwgICAgICAgICAgICAgMHg2YTQsICAweDNmZmZ9LA0KKwl7IkNDVSIsICAgICAgICAgICAgIDB4 YWE0LCAgMHgzZmZmfSwNCisJeyJUSEVSTSIsICAgICAgICAgICAweGVhNCwgIDB4M2ZmZn0sDQor CXsiRFhfQ0MiLCAgICAgICAgICAgMHgzNCwgICAweDM4N2Z9LA0KKwl7IkdDRSIsICAgICAgICAg ICAgIDB4NDQsICAgMHgzZTdmfSwNCisJeyJQQ0lFIiwgICAgICAgICAgICAweDY0LCAgIDB4MzA3 Zn0sDQorCXsiRFBNQUlGIiwgICAgICAgICAgMHg2LCAgICAweDNmMGZ9LA0KKwl7IlNTUE0iLCAg ICAgICAgICAgIDB4OCwgICAgMHgzZjhmfSwNCisJeyJVRlMiLCAgICAgICAgICAgICAweGEsICAg IDB4M2Y5Zn0sDQorCXsiTVNEQzAiLCAgICAgICAgICAgMHgxYSwgICAweDNmZmZ9LA0KKwl7Ik1T REMxIiwgICAgICAgICAgIDB4M2EsICAgMHgzZmZmfSwNCisJeyJNU0RDMiIsICAgICAgICAgICAw eDdhLCAgIDB4M2ZmZn0sDQorCXsiQ1BVRUIiLCAgICAgICAgICAgMHhjLCAgICAweDNjMGZ9LA0K Kwl7IkFQTUNVX3dyaXRlIiwgICAgIDB4MSwgICAgMHgzZmUxfSwNCisJeyJBUE1DVV93cml0ZSIs ICAgICAweDgxLCAgIDB4M2ZlMX0sDQorCXsiQVBNQ1Vfd3JpdGUiLCAgICAgMHgyMDEsICAweDNl MDF9LA0KKwl7IkFQTUNVX3JlYWQiLCAgICAgIDB4MSwgICAgMHgzZmUxfSwNCisJeyJBUE1DVV9y ZWFkIiwgICAgICAweDgxLCAgIDB4M2ZlMX0sDQorCXsiQVBNQ1VfcmVhZCIsICAgICAgMHgxMDEs ICAweDNmZmR9LA0KKwl7IkFQTUNVX3JlYWQiLCAgICAgIDB4MTA1LCAgMHgzZmZkfSwNCisJeyJB UE1DVV9yZWFkIiwgICAgICAweDIwMSwgIDB4M2UwMX0sDQorCXsiQVBNQ1VfcmVhZCIsICAgICAg MHg0MDEsICAweDNjMDF9LA0KK307DQorDQorc3RhdGljIGNvbnN0IGNoYXIgKmluZnJhX21pX3Ry YW5zKHUzMiBidXNfaWQpDQorew0KKwlpbnQgbWFzdGVyX2NvdW50ID0gQVJSQVlfU0laRShpbmZy YV9taV9pZF90b19tYXN0ZXIpOw0KKwljb25zdCBjaGFyICptYXN0ZXIgPSAiVU5LTk9XTl9NQVNU RVJfRlJPTV9JTkZSQSI7DQorCWludCBpOw0KKw0KKwlmb3IgKGkgPSAwOyBpIDwgbWFzdGVyX2Nv dW50OyBpKyspIHsNCisJCWlmICgoYnVzX2lkICYgaW5mcmFfbWlfaWRfdG9fbWFzdGVyW2ldLm1h c2spID09DQorCQkgICAgaW5mcmFfbWlfaWRfdG9fbWFzdGVyW2ldLmJ1c19pZCkNCisJCQltYXN0 ZXIgPSBpbmZyYV9taV9pZF90b19tYXN0ZXJbaV0ubWFzdGVyOw0KKwl9DQorDQorCXJldHVybiBt YXN0ZXI7DQorfQ0KKw0KK3N0YXRpYyBjb25zdCBjaGFyICpwZXJpX21pX3RyYW5zKHUzMiBidXNf aWQpDQorew0KKwlpbnQgbWFzdGVyX2NvdW50ID0gQVJSQVlfU0laRShwZXJpX21pX2lkX3RvX21h c3Rlcik7DQorCWNvbnN0IGNoYXIgKm1hc3RlciA9ICJVTktOT1dOX01BU1RFUl9GUk9NX1BFUkki Ow0KKwlpbnQgaTsNCisNCisJaWYgKChidXNfaWQgJiAweDMpID09IDB4MCkNCisJCXJldHVybiBp bmZyYV9taV90cmFucyhidXNfaWQgPj4gMik7DQorCWVsc2UgaWYgKChidXNfaWQgJiAweDMpID09 IDB4MikNCisJCXJldHVybiAiTURfQVBfTSI7DQorCWVsc2UgaWYgKChidXNfaWQgJiAweDMpID09 IDB4MykNCisJCXJldHVybiAiQVBfRE1BX00iOw0KKw0KKwlidXNfaWQgPSBidXNfaWQgPj4gMjsN CisNCisJZm9yIChpID0gMCA7IGkgPCBtYXN0ZXJfY291bnQ7IGkrKykgew0KKwkJaWYgKChidXNf aWQgJiBwZXJpX21pX2lkX3RvX21hc3RlcltpXS5tYXNrKSA9PQ0KKwkJICAgIHBlcmlfbWlfaWRf dG9fbWFzdGVyW2ldLmJ1c19pZCkNCisJCQltYXN0ZXIgPSBpbmZyYV9taV9pZF90b19tYXN0ZXJb aV0ubWFzdGVyOw0KKwl9DQorDQorCXJldHVybiBtYXN0ZXI7DQorfQ0KKw0KK3N0YXRpYyBjb25z dCBjaGFyICptdDY4NzNfYnVzX2lkX3RvX21hc3Rlcih1MzIgYnVzX2lkLCB1MzIgdmlvX2FkZHIs DQorCQkJCQkgICBpbnQgc2xhdmVfdHlwZSwgaW50IHNoaWZ0X3N0YV9iaXQsDQorCQkJCQkgICBp bnQgZG9tYWluKQ0KK3sNCisJdTggaF8xYnl0ZTsNCisNCisJaWYgKGJ1c19pZCA9PSAweDAgJiYg dmlvX2FkZHIgPT0gMHgwKQ0KKwkJcmV0dXJuIE5VTEw7DQorDQorCWhfMWJ5dGUgPSAodmlvX2Fk ZHIgPj4gMjQpICYgMHhGRjsNCisNCisJaWYgKHNsYXZlX3R5cGUgPT0gU0xBVkVfVFlQRV9JTkZS QSkgew0KKwkJaWYgKHZpb19hZGRyIDw9IDB4MUZGRkZGKSB7DQorCQkJaWYgKChidXNfaWQgJiAw eDEpID09IDApDQorCQkJCXJldHVybiAiRU1JX0wyQ19NIjsNCisNCisJCQlyZXR1cm4gaW5mcmFf bWlfdHJhbnMoYnVzX2lkID4+IDEpOw0KKw0KKwkJfSBlbHNlIGlmIChzaGlmdF9zdGFfYml0ID09 IDMpIHsNCisJCQlpZiAoKGJ1c19pZCAmIDB4MSkgPT0gMCkNCisJCQkJcmV0dXJuICJFTUlfTDJD X00iOw0KKw0KKwkJCXJldHVybiBpbmZyYV9taV90cmFucyhidXNfaWQgPj4gMSk7DQorDQorCQl9 IGVsc2UgaWYgKHNoaWZ0X3N0YV9iaXQgPT0gNCkgew0KKwkJCWlmICgoYnVzX2lkICYgMHgxKSA9 PSAxKQ0KKwkJCQlyZXR1cm4gIkdDRV9NIjsNCisNCisJCQlyZXR1cm4gaW5mcmFfbWlfdHJhbnMo YnVzX2lkID4+IDEpOw0KKwkJfQ0KKw0KKwkJcmV0dXJuIGluZnJhX21pX3RyYW5zKGJ1c19pZCk7 DQorDQorCX0gZWxzZSBpZiAoc2xhdmVfdHlwZSA9PSBTTEFWRV9UWVBFX1BFUkkpIHsNCisJCWlm ICgoaF8xYnl0ZSA+PSAweDE0ICYmIGhfMWJ5dGUgPCAweDE4KSB8fA0KKwkJICAgIChoXzFieXRl ID49IDB4MUEgJiYgaF8xYnl0ZSA8IDB4MUMpIHx8DQorCQkgICAgKGhfMWJ5dGUgPj0gMHgxRiAm JiBoXzFieXRlIDwgMHgyMCkpIHsNCisJCQlpZiAoKGJ1c19pZCAmIDB4MSkgPT0gMSkNCisJCQkJ cmV0dXJuICJHQ0VfTSI7DQorDQorCQkJcmV0dXJuIGluZnJhX21pX3RyYW5zKGJ1c19pZCA+PiAx KTsNCisJCX0NCisNCisJCWlmIChzaGlmdF9zdGFfYml0ID09IDMgfHwgc2hpZnRfc3RhX2JpdCA9 PSA0IHx8DQorCQkgICAgc2hpZnRfc3RhX2JpdCA9PSA4KSB7DQorCQkJaWYgKChidXNfaWQgJiAw eDEpID09IDApDQorCQkJCXJldHVybiAiTURfQVBfTSI7DQorDQorCQkJcmV0dXJuIHBlcmlfbWlf dHJhbnMoYnVzX2lkID4+IDEpOw0KKwkJfQ0KKwkJcmV0dXJuIHBlcmlfbWlfdHJhbnMoYnVzX2lk KTsNCisNCisJfSBlbHNlIGlmIChzbGF2ZV90eXBlID09IFNMQVZFX1RZUEVfUEVSSTIpIHsNCisJ CXJldHVybiBwZXJpX21pX3RyYW5zKGJ1c19pZCk7DQorDQorCX0gZWxzZSBpZiAoc2xhdmVfdHlw ZSA9PSBTTEFWRV9UWVBFX1BFUklfUEFSKSB7DQorCQlyZXR1cm4gcGVyaV9taV90cmFucyhidXNf aWQpOw0KKwl9DQorDQorCXJldHVybiAiVU5LTk9XTl9NQVNURVIiOw0KK30NCisNCitzdGF0aWMg dm9pZCBtbTJuZF92aW9faGFuZGxlcih2b2lkIF9faW9tZW0gKmluZnJhY2ZnLA0KKwkJCSAgICAg IHN0cnVjdCBtdGtfZGV2YXBjX3Zpb19pbmZvICp2aW9faW5mbywNCisJCQkgICAgICBib29sIG1k cF92aW8sIGJvb2wgZGlzcDJfdmlvLCBib29sIG1tc3lzX3ZpbykNCit7DQorCXUzMiB2aW9fc3Rh LCB2aW9fZGJnLCBydzsNCisJdTMyIHZpb19zdGFfbnVtOw0KKwl1MzIgdmlvMF9vZmZzZXQ7DQor CWNoYXIgbW1fc3RyWzY0XSA9IHswfTsNCisJdm9pZCBfX2lvbWVtICpyZWc7DQorCWludCBpOw0K Kw0KKwlpZiAoIWluZnJhY2ZnKQ0KKwkJcmV0dXJuOw0KKw0KKwlpZiAobWRwX3Zpbykgew0KKwkJ dmlvX3N0YV9udW0gPSBJTkZSQUNGR19NRFBfVklPX1NUQV9OVU07DQorCQl2aW8wX29mZnNldCA9 IElORlJBQ0ZHX01EUF9TRUNfVklPMF9PRkZTRVQ7DQorDQorCQlzdHJuY3B5KG1tX3N0ciwgIklO RlJBQ0ZHX01EUF9TRUNfVklPIiwNCisJCQlzaXplb2YoIklORlJBQ0ZHX01EUF9TRUNfVklPIikp Ow0KKw0KKwl9IGVsc2UgaWYgKG1tc3lzX3Zpbykgew0KKwkJdmlvX3N0YV9udW0gPSBJTkZSQUNG R19NTV9WSU9fU1RBX05VTTsNCisJCXZpbzBfb2Zmc2V0ID0gSU5GUkFDRkdfTU1fU0VDX1ZJTzBf T0ZGU0VUOw0KKw0KKwkJc3RybmNweShtbV9zdHIsICJJTkZSQUNGR19NTV9TRUNfVklPIiwNCisJ CQlzaXplb2YoIklORlJBQ0ZHX01NX1NFQ19WSU8iKSk7DQorDQorCX0gZWxzZSB7DQorCQlwcl9l cnIoUEZYICIlczogcGFyYW0gY2hlY2sgZmFpbGVkLCBtZHBfdmlvOiVzLCBkaXNwMl92aW86JXMs IG1tc3lzX3Zpbzolc1xuIiwNCisJCSAgICAgICBfX2Z1bmNfXywgbWRwX3ZpbyA/ICJ0cnVlIiA6 ICJmYWxzZSIsDQorCQkgICAgICAgZGlzcDJfdmlvID8gInRydWUiIDogImZhbHNlIiwNCisJCSAg ICAgICBtbXN5c192aW8gPyAidHJ1ZSIgOiAiZmFsc2UiKTsNCisJCXJldHVybjsNCisJfQ0KKw0K KwkvKiBHZXQgbW0ybmQgdmlvbGF0aW9uIHN0YXR1cyAqLw0KKwlmb3IgKGkgPSAwOyBpIDwgdmlv X3N0YV9udW07IGkrKykgew0KKwkJcmVnID0gaW5mcmFjZmcgKyB2aW8wX29mZnNldCArIGkgKiA0 Ow0KKwkJdmlvX3N0YSA9IHJlYWRsKHJlZyk7DQorCQlpZiAodmlvX3N0YSkNCisJCQlwcl9pbmZv KFBGWCAiTU0gMm5kIHZpb2xhdGlvbjogJXMlZDoweCV4XG4iLA0KKwkJCQltbV9zdHIsIGksIHZp b19zdGEpOw0KKwl9DQorDQorCS8qIEdldCBtbTJuZCB2aW9sYXRpb24gYWRkcmVzcyAqLw0KKwly ZWcgPSBpbmZyYWNmZyArIHZpbzBfb2Zmc2V0ICsgaSAqIDQ7DQorCXZpb19pbmZvLT52aW9fYWRk ciA9IHJlYWRsKHJlZyk7DQorDQorCS8qIEdldCBtbTJuZCB2aW9sYXRpb24gaW5mb3JtYXRpb24g Ki8NCisJcmVnID0gaW5mcmFjZmcgKyB2aW8wX29mZnNldCArIChpICsgMSkgKiA0Ow0KKwl2aW9f ZGJnID0gcmVhZGwocmVnKTsNCisNCisJdmlvX2luZm8tPmRvbWFpbl9pZCA9ICh2aW9fZGJnICYg SU5GUkFDRkdfTU0yTkRfVklPX0RPTUFJTl9NQVNLKSA+Pg0KKwkJSU5GUkFDRkdfTU0yTkRfVklP X0RPTUFJTl9TSElGVDsNCisNCisJdmlvX2luZm8tPm1hc3Rlcl9pZCA9ICh2aW9fZGJnICYgSU5G UkFDRkdfTU0yTkRfVklPX0lEX01BU0spID4+DQorCQlJTkZSQUNGR19NTTJORF9WSU9fSURfU0hJ RlQ7DQorDQorCXJ3ID0gKHZpb19kYmcgJiBJTkZSQUNGR19NTTJORF9WSU9fUldfTUFTSykgPj4N CisJCUlORlJBQ0ZHX01NMk5EX1ZJT19SV19TSElGVDsNCisJdmlvX2luZm8tPnJlYWQgPSAocncg PT0gMCk7DQorCXZpb19pbmZvLT53cml0ZSA9IChydyA9PSAxKTsNCit9DQorDQorc3RhdGljIHUz MiBtdDY4NzNfc2hpZnRfZ3JvdXBfZ2V0KGludCBzbGF2ZV90eXBlLCB1MzIgdmlvX2lkeCkNCit7 DQorCWlmIChzbGF2ZV90eXBlID09IFNMQVZFX1RZUEVfSU5GUkEpIHsNCisJCWlmICgodmlvX2lk eCA+PSAwICYmIHZpb19pZHggPD0gOCkgfHwgdmlvX2lkeCA9PSAzNTUpDQorCQkJcmV0dXJuIDA7 DQorCQllbHNlIGlmICgodmlvX2lkeCA+PSA5ICYmIHZpb19pZHggPD0gMTQpIHx8IHZpb19pZHgg PT0gMzU2KQ0KKwkJCXJldHVybiAxOw0KKwkJZWxzZSBpZiAoKHZpb19pZHggPj0gMTUgJiYgdmlv X2lkeCA8PSAxOSkgfHwgdmlvX2lkeCA9PSAzNTcpDQorCQkJcmV0dXJuIDI7DQorCQllbHNlIGlm ICgodmlvX2lkeCA+PSAyMCAmJiB2aW9faWR4IDw9IDIxKSB8fCB2aW9faWR4ID09IDM1OCkNCisJ CQlyZXR1cm4gMzsNCisJCWVsc2UgaWYgKHZpb19pZHggPj0gMjIgJiYgdmlvX2lkeCA8PSAzNDcp DQorCQkJcmV0dXJuIDQ7DQorCQllbHNlIGlmICgodmlvX2lkeCA+PSAzNDggJiYgdmlvX2lkeCA8 PSAzNTQpIHx8DQorCQkJICh2aW9faWR4ID49IDM1OSAmJiB2aW9faWR4IDw9IDM2NSkgfHwNCisJ CQkgdmlvX2lkeCA9PSAzNjYpDQorCQkJcmV0dXJuIDU7DQorDQorCQlwcl9lcnIoUEZYICIlczol ZCBXcm9uZyB2aW9faWR4OjB4JXhcbiIsDQorCQkgICAgICAgX19mdW5jX18sIF9fTElORV9fLCB2 aW9faWR4KTsNCisNCisJfSBlbHNlIGlmIChzbGF2ZV90eXBlID09IFNMQVZFX1RZUEVfUEVSSSkg ew0KKwkJaWYgKHZpb19pZHggPj0gMCAmJiB2aW9faWR4IDw9IDQpDQorCQkJcmV0dXJuIDA7DQor CQllbHNlIGlmICh2aW9faWR4ID49IDUgJiYgdmlvX2lkeCA8PSA2KQ0KKwkJCXJldHVybiAxOw0K KwkJZWxzZSBpZiAoKHZpb19pZHggPj0gNyAmJiB2aW9faWR4IDw9IDM4KSB8fCB2aW9faWR4ID09 IDE4NyB8fA0KKwkJCSAodmlvX2lkeCA+PSAxODggJiYgdmlvX2lkeCA8PSAyMTkpIHx8DQorCQkJ IHZpb19pZHggPT0gMjg2KQ0KKwkJCXJldHVybiAyOw0KKwkJZWxzZSBpZiAoKHZpb19pZHggPj0g MzkgJiYgdmlvX2lkeCA8PSA2MSkgfHwgdmlvX2lkeCA9PSAyMjApDQorCQkJcmV0dXJuIDM7DQor CQllbHNlIGlmICgodmlvX2lkeCA+PSA2MiAmJiB2aW9faWR4IDw9IDcyKSB8fCB2aW9faWR4ID09 IDIyMSkNCisJCQlyZXR1cm4gNDsNCisJCWVsc2UgaWYgKCh2aW9faWR4ID49IDczICYmIHZpb19p ZHggPD0gNzQpIHx8IHZpb19pZHggPT0gMjIyKQ0KKwkJCXJldHVybiA1Ow0KKwkJZWxzZSBpZiAo dmlvX2lkeCA9PSA3NSB8fCB2aW9faWR4ID09IDIyMykNCisJCQlyZXR1cm4gNjsNCisJCWVsc2Ug aWYgKCh2aW9faWR4ID49IDc2ICYmIHZpb19pZHggPD0gMTE4KSB8fCB2aW9faWR4ID09IDIyNCkN CisJCQlyZXR1cm4gNzsNCisJCWVsc2UgaWYgKCh2aW9faWR4ID49IDExOSAmJiB2aW9faWR4IDw9 IDEyMSkgfHwgdmlvX2lkeCA9PSAyMjUpDQorCQkJcmV0dXJuIDg7DQorCQlpZiAodmlvX2lkeCA+ PSAxMjIgJiYgdmlvX2lkeCA8PSAxMjUpDQorCQkJcmV0dXJuIDk7DQorCQllbHNlIGlmICh2aW9f aWR4ID09IDEyNiB8fCAodmlvX2lkeCA+PSAyMjYgJiYgdmlvX2lkeCA8PSAyMjcpIHx8DQorCQkJ IHZpb19pZHggPT0gMjg3KQ0KKwkJCXJldHVybiAxMDsNCisJCWlmICh2aW9faWR4ID49IDEyNyAm JiB2aW9faWR4IDw9IDEyOCkNCisJCQlyZXR1cm4gMTE7DQorCQlpZiAodmlvX2lkeCA+PSAxMjkg JiYgdmlvX2lkeCA8PSAxMzApDQorCQkJcmV0dXJuIDEyOw0KKwkJZWxzZSBpZiAoKHZpb19pZHgg Pj0gMTMxICYmIHZpb19pZHggPD0gMTQxKSB8fA0KKwkJCSAodmlvX2lkeCA+PSAyMjggJiYgdmlv X2lkeCA8PSAyMzgpIHx8DQorCQkJIHZpb19pZHggPT0gMjg4KQ0KKwkJCXJldHVybiAxMzsNCisJ CWVsc2UgaWYgKCh2aW9faWR4ID49IDE0MiAmJiB2aW9faWR4IDw9IDE0MykgfHwNCisJCQkgKHZp b19pZHggPj0gMjM5ICYmIHZpb19pZHggPD0gMjQwKSB8fA0KKwkJCSB2aW9faWR4ID09IDI4OSkN CisJCQlyZXR1cm4gMTQ7DQorCQllbHNlIGlmICgodmlvX2lkeCA+PSAxNDQgJiYgdmlvX2lkeCA8 PSAxNzMpIHx8IHZpb19pZHggPT0gMjQxIHx8DQorCQkJICh2aW9faWR4ID49IDI0MiAmJiB2aW9f aWR4IDw9IDI3MSkgfHwNCisJCQkgdmlvX2lkeCA9PSAyOTApDQorCQkJcmV0dXJuIDE1Ow0KKwkJ ZWxzZSBpZiAoKHZpb19pZHggPj0gMTc0ICYmIHZpb19pZHggPD0gMTg2KSB8fCB2aW9faWR4ID09 IDI3MiB8fA0KKwkJCSAodmlvX2lkeCA+PSAyNzMgJiYgdmlvX2lkeCA8PSAyODUpIHx8DQorCQkJ IHZpb19pZHggPT0gMjkxKQ0KKwkJCXJldHVybiAxNjsNCisNCisJCXByX2VycihQRlggIiVzOiVk IFdyb25nIHZpb19pZHg6MHgleFxuIiwNCisJCSAgICAgICBfX2Z1bmNfXywgX19MSU5FX18sIHZp b19pZHgpOw0KKw0KKwl9IGVsc2UgaWYgKHNsYXZlX3R5cGUgPT0gU0xBVkVfVFlQRV9QRVJJMikg ew0KKwkJaWYgKCh2aW9faWR4ID49IDAgJiYgdmlvX2lkeCA8PSAxMikgfHwgdmlvX2lkeCA9PSAx MTcgfHwNCisJCSAgICAodmlvX2lkeCA+PSAxMTggJiYgdmlvX2lkeCA8PSAxMzApIHx8DQorCQkg ICAgdmlvX2lkeCA9PSAyMzQpDQorCQkJcmV0dXJuIDA7DQorCQllbHNlIGlmICh2aW9faWR4ID49 IDEzICYmIHZpb19pZHggPD0gMTYpDQorCQkJcmV0dXJuIDE7DQorCQllbHNlIGlmICh2aW9faWR4 ID49IDE3ICYmIHZpb19pZHggPD0gMjApDQorCQkJcmV0dXJuIDI7DQorCQllbHNlIGlmICgodmlv X2lkeCA+PSAyMSAmJiB2aW9faWR4IDw9IDM2KSB8fCB2aW9faWR4ID09IDEzMSB8fA0KKwkJCSAo dmlvX2lkeCA+PSAxMzIgJiYgdmlvX2lkeCA8PSAxNDcpIHx8DQorCQkJIHZpb19pZHggPT0gMjM1 KQ0KKwkJCXJldHVybiAzOw0KKwkJZWxzZSBpZiAoKHZpb19pZHggPj0gMzcgJiYgdmlvX2lkeCA8 PSA0NCkgfHwgdmlvX2lkeCA9PSAxNDggfHwNCisJCQkgKHZpb19pZHggPj0gMTQ5ICYmIHZpb19p ZHggPD0gMTU2KSB8fA0KKwkJCSB2aW9faWR4ID09IDIzNikNCisJCQlyZXR1cm4gNDsNCisJCWVs c2UgaWYgKCh2aW9faWR4ID49IDQ1ICYmIHZpb19pZHggPD0gNjApIHx8IHZpb19pZHggPT0gMTU3 IHx8DQorCQkJICh2aW9faWR4ID49IDE1OCAmJiB2aW9faWR4IDw9IDE3MykgfHwNCisJCQkgdmlv X2lkeCA9PSAyMzcpDQorCQkJcmV0dXJuIDU7DQorCQllbHNlIGlmICgodmlvX2lkeCA+PSA2MSAm JiB2aW9faWR4IDw9IDc2KSB8fCB2aW9faWR4ID09IDE3NCB8fA0KKwkJCSAodmlvX2lkeCA+PSAx NzUgJiYgdmlvX2lkeCA8PSAxOTApIHx8DQorCQkJIHZpb19pZHggPT0gMjM4KQ0KKwkJCXJldHVy biA2Ow0KKwkJZWxzZSBpZiAoKHZpb19pZHggPj0gNzcgJiYgdmlvX2lkeCA8PSA4NCkgfHwgdmlv X2lkeCA9PSAxOTEgfHwNCisJCQkgKHZpb19pZHggPj0gMTkyICYmIHZpb19pZHggPD0gMTk5KSB8 fA0KKwkJCSB2aW9faWR4ID09IDIzOSkNCisJCQlyZXR1cm4gNzsNCisJCWVsc2UgaWYgKCh2aW9f aWR4ID49IDg1ICYmIHZpb19pZHggPD0gMTA1KSB8fCB2aW9faWR4ID09IDIwMCB8fA0KKwkJCSAo dmlvX2lkeCA+PSAyMDEgJiYgdmlvX2lkeCA8PSAyMjEpIHx8DQorCQkJIHZpb19pZHggPT0gMjQw KQ0KKwkJCXJldHVybiA4Ow0KKwkJZWxzZSBpZiAoKHZpb19pZHggPj0gMTA2ICYmIHZpb19pZHgg PD0gMTE2KSB8fCB2aW9faWR4ID09IDIyMiB8fA0KKwkJCSAodmlvX2lkeCA+PSAyMjMgJiYgdmlv X2lkeCA8PSAyMzMpIHx8DQorCQkJIHZpb19pZHggPT0gMjQxKQ0KKwkJCXJldHVybiA5Ow0KKw0K KwkJcHJfZXJyKFBGWCAiJXM6JWQgV3JvbmcgdmlvX2lkeDoweCV4XG4iLA0KKwkJICAgICAgIF9f ZnVuY19fLCBfX0xJTkVfXywgdmlvX2lkeCk7DQorDQorCX0gZWxzZSBpZiAoc2xhdmVfdHlwZSA9 PSBTTEFWRV9UWVBFX1BFUklfUEFSKSB7DQorCQlpZiAoKHZpb19pZHggPj0gMCAmJiB2aW9faWR4 IDw9IDIzKSB8fCB2aW9faWR4ID09IDI3IHx8DQorCQkgICAgKHZpb19pZHggPj0gMjggJiYgdmlv X2lkeCA8PSA1MSkgfHwNCisJCSAgICB2aW9faWR4ID09IDU2KQ0KKwkJCXJldHVybiAwOw0KKwkJ ZWxzZSBpZiAoKHZpb19pZHggPj0gMjQgJiYgdmlvX2lkeCA8PSAyNikgfHwgdmlvX2lkeCA9PSA1 MiB8fA0KKwkJCSAodmlvX2lkeCA+PSA1MyAmJiB2aW9faWR4IDw9IDU1KSB8fA0KKwkJCSB2aW9f aWR4ID09IDU3KQ0KKwkJCXJldHVybiAxOw0KKw0KKwkJcHJfZXJyKFBGWCAiJXM6JWQgV3Jvbmcg dmlvX2lkeDoweCV4XG4iLA0KKwkJICAgICAgIF9fZnVuY19fLCBfX0xJTkVfXywgdmlvX2lkeCk7 DQorDQorCX0gZWxzZSB7DQorCQlwcl9lcnIoUEZYICIlczolZCBXcm9uZyBzbGF2ZV90eXBlOjB4 JXhcbiIsDQorCQkgICAgICAgX19mdW5jX18sIF9fTElORV9fLCBzbGF2ZV90eXBlKTsNCisJfQ0K Kw0KKwlyZXR1cm4gMzE7DQorfQ0KKw0KK3N0YXRpYyBzdHJ1Y3QgbXRrX2RldmFwY19kYmdfc3Rh dHVzIG10Njg3M19kZXZhcGNfZGJnX3N0YXQgPSB7DQorCS5lbmFibGVfdXQgPSBQTEFUX0RCR19V VF9ERUZBVUxULA0KKwkuZW5hYmxlX2RhcGMgPSBQTEFUX0RCR19EQVBDX0RFRkFVTFQsDQorfTsN CisNCitzdGF0aWMgY29uc3QgY2hhciAqIGNvbnN0IHNsYXZlX3R5cGVfdG9fc3RyW10gPSB7DQor CSJTTEFWRV9UWVBFX0lORlJBIiwNCisJIlNMQVZFX1RZUEVfUEVSSSIsDQorCSJTTEFWRV9UWVBF X1BFUkkyIiwNCisJIlNMQVZFX1RZUEVfUEVSSV9QQVIiLA0KKwkiV1JPTkdfU0xBVkVfVFlQRSIs DQorfTsNCisNCitzdGF0aWMgaW50IG10a192aW9fbWFza19zdGFfbnVtW10gPSB7DQorCVZJT19N QVNLX1NUQV9OVU1fSU5GUkEsDQorCVZJT19NQVNLX1NUQV9OVU1fUEVSSSwNCisJVklPX01BU0tf U1RBX05VTV9QRVJJMiwNCisJVklPX01BU0tfU1RBX05VTV9QRVJJX1BBUiwNCit9Ow0KKw0KK3N0 YXRpYyBzdHJ1Y3QgbXRrX2RldmFwY192aW9faW5mbyBtdDY4NzNfZGV2YXBjX3Zpb19pbmZvID0g ew0KKwkudmlvX21hc2tfc3RhX251bSA9IG10a192aW9fbWFza19zdGFfbnVtLA0KKwkuc3JhbXJv bV92aW9faWR4ID0gU1JBTVJPTV9WSU9fSU5ERVgsDQorCS5tZHBfdmlvX2lkeCA9IE1EUF9WSU9f SU5ERVgsDQorCS5kaXNwMl92aW9faWR4ID0gTURQX1ZJT19JTkRFWCwNCisJLm1tc3lzX3Zpb19p ZHggPSBNTVNZU19WSU9fSU5ERVgsDQorCS5zcmFtcm9tX3Nsdl90eXBlID0gU1JBTVJPTV9TTEFW RV9UWVBFLA0KKwkubW0ybmRfc2x2X3R5cGUgPSBNTTJORF9TTEFWRV9UWVBFLA0KK307DQorDQor c3RhdGljIGNvbnN0IHN0cnVjdCBtdGtfaW5mcmFfdmlvX2RiZ19kZXNjIG10Njg3M192aW9fZGJn cyA9IHsNCisJLnZpb19kYmdfbXN0aWQgPSBJTkZSQV9WSU9fREJHX01TVElELA0KKwkudmlvX2Ri Z19tc3RpZF9zdGFydF9iaXQgPSBJTkZSQV9WSU9fREJHX01TVElEX1NUQVJUX0JJVCwNCisJLnZp b19kYmdfZG1uaWQgPSBJTkZSQV9WSU9fREJHX0RNTklELA0KKwkudmlvX2RiZ19kbW5pZF9zdGFy dF9iaXQgPSBJTkZSQV9WSU9fREJHX0RNTklEX1NUQVJUX0JJVCwNCisJLnZpb19kYmdfd192aW8g PSBJTkZSQV9WSU9fREJHX1dfVklPLA0KKwkudmlvX2RiZ193X3Zpb19zdGFydF9iaXQgPSBJTkZS QV9WSU9fREJHX1dfVklPX1NUQVJUX0JJVCwNCisJLnZpb19kYmdfcl92aW8gPSBJTkZSQV9WSU9f REJHX1JfVklPLA0KKwkudmlvX2RiZ19yX3Zpb19zdGFydF9iaXQgPSBJTkZSQV9WSU9fREJHX1Jf VklPX1NUQVJUX0JJVCwNCisJLnZpb19hZGRyX2hpZ2ggPSBJTkZSQV9WSU9fQUREUl9ISUdILA0K KwkudmlvX2FkZHJfaGlnaF9zdGFydF9iaXQgPSBJTkZSQV9WSU9fQUREUl9ISUdIX1NUQVJUX0JJ VCwNCit9Ow0KKw0KK3N0YXRpYyBjb25zdCBzdHJ1Y3QgbXRrX3NyYW1yb21fc2VjX3Zpb19kZXNj IG10Njg3M19zcmFtcm9tX3NlY192aW9zID0gew0KKwkudmlvX2lkX21hc2sgPSBTUkFNUk9NX1NF Q19WSU9fSURfTUFTSywNCisJLnZpb19pZF9zaGlmdCA9IFNSQU1ST01fU0VDX1ZJT19JRF9TSElG VCwNCisJLnZpb19kb21haW5fbWFzayA9IFNSQU1ST01fU0VDX1ZJT19ET01BSU5fTUFTSywNCisJ LnZpb19kb21haW5fc2hpZnQgPSBTUkFNUk9NX1NFQ19WSU9fRE9NQUlOX1NISUZULA0KKwkudmlv X3J3X21hc2sgPSBTUkFNUk9NX1NFQ19WSU9fUldfTUFTSywNCisJLnZpb19yd19zaGlmdCA9IFNS QU1ST01fU0VDX1ZJT19SV19TSElGVCwNCit9Ow0KKw0KK3N0YXRpYyBjb25zdCB1MzIgbXQ2ODcz X2RldmFwY19wZHNbXSA9IHsNCisJUERfVklPX01BU0tfT0ZGU0VULA0KKwlQRF9WSU9fU1RBX09G RlNFVCwNCisJUERfVklPX0RCRzBfT0ZGU0VULA0KKwlQRF9WSU9fREJHMV9PRkZTRVQsDQorCVBE X1ZJT19EQkcyX09GRlNFVCwNCisJUERfQVBDX0NPTl9PRkZTRVQsDQorCVBEX1NISUZUX1NUQV9P RkZTRVQsDQorCVBEX1NISUZUX1NFTF9PRkZTRVQsDQorCVBEX1NISUZUX0NPTl9PRkZTRVQsDQor fTsNCisNCitzdGF0aWMgc3RydWN0IG10a19kZXZhcGNfc29jIG10Njg3M19kYXRhID0gew0KKwku ZGJnX3N0YXQgPSAmbXQ2ODczX2RldmFwY19kYmdfc3RhdCwNCisJLnNsYXZlX3R5cGVfYXJyID0g c2xhdmVfdHlwZV90b19zdHIsDQorCS5zbGF2ZV90eXBlX251bSA9IFNMQVZFX1RZUEVfTlVNLA0K KwkuZGV2aWNlX2luZm9bU0xBVkVfVFlQRV9JTkZSQV0gPSBtdDY4NzNfZGV2aWNlc19pbmZyYSwN CisJLmRldmljZV9pbmZvW1NMQVZFX1RZUEVfUEVSSV0gPSBtdDY4NzNfZGV2aWNlc19wZXJpLA0K KwkuZGV2aWNlX2luZm9bU0xBVkVfVFlQRV9QRVJJMl0gPSBtdDY4NzNfZGV2aWNlc19wZXJpMiwN CisJLmRldmljZV9pbmZvW1NMQVZFX1RZUEVfUEVSSV9QQVJdID0gbXQ2ODczX2RldmljZXNfcGVy aV9wYXIsDQorCS5uZGV2aWNlcyA9IG10azY4NzNfZGV2aWNlc19udW0sDQorCS52aW9faW5mbyA9 ICZtdDY4NzNfZGV2YXBjX3Zpb19pbmZvLA0KKwkudmlvX2RiZ3MgPSAmbXQ2ODczX3Zpb19kYmdz LA0KKwkuc3JhbXJvbV9zZWNfdmlvcyA9ICZtdDY4NzNfc3JhbXJvbV9zZWNfdmlvcywNCisJLmRl dmFwY19wZHMgPSBtdDY4NzNfZGV2YXBjX3BkcywNCisJLm1hc3Rlcl9nZXQgPSAmbXQ2ODczX2J1 c19pZF90b19tYXN0ZXIsDQorCS5tbTJuZF92aW9faGFuZGxlciA9ICZtbTJuZF92aW9faGFuZGxl ciwNCisJLnNoaWZ0X2dyb3VwX2dldCA9IG10Njg3M19zaGlmdF9ncm91cF9nZXQsDQorfTsNCisN CitzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBtdDY4NzNfZGV2YXBjX2R0X21hdGNo W10gPSB7DQorCXsgLmNvbXBhdGlibGUgPSAibWVkaWF0ZWssbXQ2ODczLWRldmFwYyIgfSwNCisJ e30sDQorfTsNCisNCitzdGF0aWMgaW50IG10Njg3M19kZXZhcGNfcHJvYmUoc3RydWN0IHBsYXRm b3JtX2RldmljZSAqcGRldikNCit7DQorCXJldHVybiBtdGtfZGV2YXBjX3Byb2JlKHBkZXYsICZt dDY4NzNfZGF0YSk7DQorfQ0KKw0KK3N0YXRpYyBpbnQgbXQ2ODczX2RldmFwY19yZW1vdmUoc3Ry dWN0IHBsYXRmb3JtX2RldmljZSAqZGV2KQ0KK3sNCisJcmV0dXJuIG10a19kZXZhcGNfcmVtb3Zl KGRldik7DQorfQ0KKw0KK3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIG10Njg3M19kZXZh cGNfZHJpdmVyID0gew0KKwkucHJvYmUgPSBtdDY4NzNfZGV2YXBjX3Byb2JlLA0KKwkucmVtb3Zl ID0gbXQ2ODczX2RldmFwY19yZW1vdmUsDQorCS5kcml2ZXIgPSB7DQorCQkubmFtZSA9IEtCVUlM RF9NT0ROQU1FLA0KKwkJLm9mX21hdGNoX3RhYmxlID0gbXQ2ODczX2RldmFwY19kdF9tYXRjaCwN CisJfSwNCit9Ow0KKw0KK21vZHVsZV9wbGF0Zm9ybV9kcml2ZXIobXQ2ODczX2RldmFwY19kcml2 ZXIpOw0KKw0KK01PRFVMRV9ERVNDUklQVElPTigiTWVkaWF0ZWsgTVQ2ODczIERldmljZSBBUEMg RHJpdmVyIik7DQorTU9EVUxFX0FVVEhPUigiTmVhbCBMaXUgPG5lYWwubGl1QG1lZGlhdGVrLmNv bT4iKTsNCitNT0RVTEVfTElDRU5TRSgiR1BMIik7DQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9zb2Mv bWVkaWF0ZWsvZGV2YXBjL2RldmFwYy1tdDY4NzMuaCBiL2RyaXZlcnMvc29jL21lZGlhdGVrL2Rl dmFwYy9kZXZhcGMtbXQ2ODczLmgNCm5ldyBmaWxlIG1vZGUgMTAwNjQ0DQppbmRleCAwMDAwMDAw Li4xNmJlMDllDQotLS0gL2Rldi9udWxsDQorKysgYi9kcml2ZXJzL3NvYy9tZWRpYXRlay9kZXZh cGMvZGV2YXBjLW10Njg3My5oDQpAQCAtMCwwICsxLDExMSBAQA0KKy8qIFNQRFgtTGljZW5zZS1J ZGVudGlmaWVyOiBHUEwtMi4wICovDQorLyoNCisgKiBDb3B5cmlnaHQgKEMpIDIwMjAgTWVkaWFU ZWsgSW5jLg0KKyAqLw0KKw0KKyNpZm5kZWYgX19ERVZBUENfTVQ2ODczX0hfXw0KKyNkZWZpbmUg X19ERVZBUENfTVQ2ODczX0hfXw0KKw0KKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioNCisgKiBWQVJJ QUJMRSBERUZJTklUSU9ODQorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8NCisvKiBkYmcgc3RhdHVz IGRlZmF1bHQgc2V0dGluZyAqLw0KKyNkZWZpbmUgUExBVF9EQkdfVVRfREVGQVVMVAkJZmFsc2UN CisjZGVmaW5lIFBMQVRfREJHX0RBUENfREVGQVVMVAkJZmFsc2UNCisNCisvKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqDQorICogU1RSVUNUVVJFIERFRklOSVRJT04NCisgKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqLw0KK2VudW0gREVWQVBDX1NMQVZFX1RZUEUgew0KKwlTTEFWRV9UWVBFX0lORlJBID0gMCwN CisJU0xBVkVfVFlQRV9QRVJJLA0KKwlTTEFWRV9UWVBFX1BFUkkyLA0KKwlTTEFWRV9UWVBFX1BF UklfUEFSLA0KKwlTTEFWRV9UWVBFX05VTSwNCit9Ow0KKw0KK2VudW0gREVWQVBDX1ZJT19NQVNL X1NUQV9OVU0gew0KKwlWSU9fTUFTS19TVEFfTlVNX0lORlJBID0gMTIsDQorCVZJT19NQVNLX1NU QV9OVU1fUEVSSSA9IDEwLA0KKwlWSU9fTUFTS19TVEFfTlVNX1BFUkkyID0gOCwNCisJVklPX01B U0tfU1RBX05VTV9QRVJJX1BBUiA9IDIsDQorfTsNCisNCitlbnVtIERFVkFQQ19WSU9fU0xBVkVf TlVNIHsNCisJVklPX1NMQVZFX05VTV9JTkZSQSA9IDM2NiwNCisJVklPX1NMQVZFX05VTV9QRVJJ ID0gMjg0LA0KKwlWSU9fU0xBVkVfTlVNX1BFUkkyID0gMjQ3LA0KKwlWSU9fU0xBVkVfTlVNX1BF UklfUEFSID0gNTgsDQorfTsNCisNCitlbnVtIERFVkFQQ19QRF9PRkZTRVQgew0KKwlQRF9WSU9f TUFTS19PRkZTRVQgPSAweDAsDQorCVBEX1ZJT19TVEFfT0ZGU0VUID0gMHg0MDAsDQorCVBEX1ZJ T19EQkcwX09GRlNFVCA9IDB4OTAwLA0KKwlQRF9WSU9fREJHMV9PRkZTRVQgPSAweDkwNCwNCisJ UERfVklPX0RCRzJfT0ZGU0VUID0gMHg5MDgsDQorCVBEX0FQQ19DT05fT0ZGU0VUID0gMHhGMDAs DQorCVBEX1NISUZUX1NUQV9PRkZTRVQgPSAweEYyMCwNCisJUERfU0hJRlRfU0VMX09GRlNFVCA9 IDB4RjMwLA0KKwlQRF9TSElGVF9DT05fT0ZGU0VUID0gMHhGMTAsDQorfTsNCisNCisjZGVmaW5l IFNSQU1ST01fU0xBVkVfVFlQRQlTTEFWRV9UWVBFX0lORlJBCS8qIEluZnJhICovDQorI2RlZmlu ZSBNTTJORF9TTEFWRV9UWVBFCVNMQVZFX1RZUEVfUEVSSQkJLyogUGVyaSAqLw0KKw0KK2VudW0g T1RIRVJfVFlQRVNfSU5ERVggew0KKwlTUkFNUk9NX1ZJT19JTkRFWCA9IDM2NywNCisJQ09OTl9W SU9fSU5ERVggPSA3NSwgLyogc3RhcnRzIGZyb20gMHgxOCAqLw0KKwlNRFBfVklPX0lOREVYID0g MjkyLA0KKwlNTVNZU19WSU9fSU5ERVggPSAyOTQsDQorfTsNCisNCitlbnVtIElORlJBQ0ZHX01N Mk5EX1ZJT19OVU0gew0KKwlJTkZSQUNGR19NTV9WSU9fU1RBX05VTSA9IDIsDQorCUlORlJBQ0ZH X01EUF9WSU9fU1RBX05VTSA9IDgsDQorfTsNCisNCitlbnVtIElORlJBQ0ZHX01NMk5EX09GRlNF VCB7DQorCUlORlJBQ0ZHX01NX1NFQ19WSU8wX09GRlNFVCA9IDB4QjMwLA0KKwlJTkZSQUNGR19N RFBfU0VDX1ZJTzBfT0ZGU0VUID0gMHhCNDAsDQorfTsNCisNCitzdHJ1Y3QgSU5GUkFBWElfSURf SU5GTyB7DQorCWNvbnN0IGNoYXIJKm1hc3RlcjsNCisJdTMyCQlidXNfaWQ7DQorCXUzMgkJbWFz azsNCit9Ow0KKw0KKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioNCisgKiBQTEFURk9STSBERUZJTkFU SU9ODQorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKi8NCisNCisvKiBGb3IgSW5mcmEgVklPX0RCRyAq Lw0KKyNkZWZpbmUgSU5GUkFfVklPX0RCR19NU1RJRAkJCTB4RkZGRkZGRkYNCisjZGVmaW5lIElO RlJBX1ZJT19EQkdfTVNUSURfU1RBUlRfQklUCQkwDQorI2RlZmluZSBJTkZSQV9WSU9fREJHX0RN TklECQkJMHgwMDAwMDAzRg0KKyNkZWZpbmUgSU5GUkFfVklPX0RCR19ETU5JRF9TVEFSVF9CSVQJ CTANCisjZGVmaW5lIElORlJBX1ZJT19EQkdfV19WSU8JCQkweDAwMDAwMDQwDQorI2RlZmluZSBJ TkZSQV9WSU9fREJHX1dfVklPX1NUQVJUX0JJVAkJNg0KKyNkZWZpbmUgSU5GUkFfVklPX0RCR19S X1ZJTwkJCTB4MDAwMDAwODANCisjZGVmaW5lIElORlJBX1ZJT19EQkdfUl9WSU9fU1RBUlRfQklU CQk3DQorI2RlZmluZSBJTkZSQV9WSU9fQUREUl9ISUdICQkJMHgwMDAwMEYwMA0KKyNkZWZpbmUg SU5GUkFfVklPX0FERFJfSElHSF9TVEFSVF9CSVQJCTgNCisNCisvKiBGb3IgU1JBTVJPTSBWSU8g Ki8NCisjZGVmaW5lIFNSQU1ST01fU0VDX1ZJT19JRF9NQVNLCQkJMHgwMEZGRkYwMA0KKyNkZWZp bmUgU1JBTVJPTV9TRUNfVklPX0lEX1NISUZUCQk4DQorI2RlZmluZSBTUkFNUk9NX1NFQ19WSU9f RE9NQUlOX01BU0sJCTB4MEYwMDAwMDANCisjZGVmaW5lIFNSQU1ST01fU0VDX1ZJT19ET01BSU5f U0hJRlQJCTI0DQorI2RlZmluZSBTUkFNUk9NX1NFQ19WSU9fUldfTUFTSwkJCTB4ODAwMDAwMDAN CisjZGVmaW5lIFNSQU1ST01fU0VDX1ZJT19SV19TSElGVAkJMzENCisNCisvKiBGb3IgTU0gMm5k IFZJTyAqLw0KKyNkZWZpbmUgSU5GUkFDRkdfTU0yTkRfVklPX0RPTUFJTl9NQVNLCQkweDAwMDAw MDMwDQorI2RlZmluZSBJTkZSQUNGR19NTTJORF9WSU9fRE9NQUlOX1NISUZUCQk0DQorI2RlZmlu ZSBJTkZSQUNGR19NTTJORF9WSU9fSURfTUFTSwkJMHgwMEZGRkYwMA0KKyNkZWZpbmUgSU5GUkFD RkdfTU0yTkRfVklPX0lEX1NISUZUCQk4DQorI2RlZmluZSBJTkZSQUNGR19NTTJORF9WSU9fUldf TUFTSwkJMHgwMTAwMDAwMA0KKyNkZWZpbmUgSU5GUkFDRkdfTU0yTkRfVklPX1JXX1NISUZUCQky NA0KKw0KKyNlbmRpZiAvKiBfX0RFVkFQQ19NVDY4NzNfSF9fICovDQpkaWZmIC0tZ2l0IGEvZHJp dmVycy9zb2MvbWVkaWF0ZWsvZGV2YXBjL2RldmFwYy1tdGstbXVsdGktYW8uYyBiL2RyaXZlcnMv c29jL21lZGlhdGVrL2RldmFwYy9kZXZhcGMtbXRrLW11bHRpLWFvLmMNCm5ldyBmaWxlIG1vZGUg MTAwNjQ0DQppbmRleCAwMDAwMDAwLi42YzRhOGVjDQotLS0gL2Rldi9udWxsDQorKysgYi9kcml2 ZXJzL3NvYy9tZWRpYXRlay9kZXZhcGMvZGV2YXBjLW10ay1tdWx0aS1hby5jDQpAQCAtMCwwICsx LDc1NiBAQA0KKy8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wDQorLyoNCisgKiBD b3B5cmlnaHQgKEMpIDIwMjAgTWVkaWFUZWsgSW5jLg0KKyAqLw0KKw0KKyNpbmNsdWRlIDxsaW51 eC9hcm0tc21jY2MuaD4NCisjaW5jbHVkZSA8bGludXgvY2xrLmg+DQorI2luY2x1ZGUgPGxpbnV4 L2ZzLmg+DQorI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPg0KKyNpbmNsdWRlIDxsaW51eC9t b2R1bGUuaD4NCisjaW5jbHVkZSA8bGludXgvb2ZfaXJxLmg+DQorI2luY2x1ZGUgPGxpbnV4L29m X2FkZHJlc3MuaD4NCisjaW5jbHVkZSA8bGludXgvc2NoZWQvZGVidWcuaD4NCisjaW5jbHVkZSA8 bGludXgvdWFjY2Vzcy5oPg0KKyNpbmNsdWRlIDxsaW51eC9zb2MvbWVkaWF0ZWsvbXRrX3NpcF9z dmMuaD4NCisjaW5jbHVkZSAiZGV2YXBjLW10ay1tdWx0aS1hby5oIg0KKw0KKy8qDQorICogbXRr X2RldmFwY19wZF9nZXQgLSBnZXQgZGV2YXBjIHBkX3R5cGVzIG9mIHJlZ2lzdGVyIGFkZHJlc3Mu DQorICoNCisgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiByZWcgYWRkcg0KKyAqLw0KK3N0YXRpYyB2 b2lkIF9faW9tZW0gKm10a19kZXZhcGNfcGRfZ2V0KHN0cnVjdCBtdGtfZGV2YXBjX2NvbnRleHQg KmRldmFwY19jdHgsDQorCQkJCSAgICAgICBpbnQgc2xhdmVfdHlwZSwNCisJCQkJICAgICAgIGVu dW0gREVWQVBDX1BEX1JFR19UWVBFIHBkX3JlZ190eXBlLA0KKwkJCQkgICAgICAgdTMyIGluZGV4 KQ0KK3sNCisJc3RydWN0IG10a19kZXZhcGNfdmlvX2luZm8gKnZpb19pbmZvID0gZGV2YXBjX2N0 eC0+c29jLT52aW9faW5mbzsNCisJdTMyIHNsYXZlX3R5cGVfbnVtID0gZGV2YXBjX2N0eC0+c29j LT5zbGF2ZV90eXBlX251bTsNCisJY29uc3QgdTMyICpkZXZhcGNfcGRzID0gZGV2YXBjX2N0eC0+ c29jLT5kZXZhcGNfcGRzOw0KKwl2b2lkIF9faW9tZW0gKnJlZzsNCisNCisJaWYgKCFkZXZhcGNf cGRzKQ0KKwkJcmV0dXJuIE5VTEw7DQorDQorCWlmICgoc2xhdmVfdHlwZSA8IHNsYXZlX3R5cGVf bnVtICYmDQorCSAgICAgaW5kZXggPCB2aW9faW5mby0+dmlvX21hc2tfc3RhX251bVtzbGF2ZV90 eXBlXSkgJiYNCisJICAgIHBkX3JlZ190eXBlIDwgUERfUkVHX1RZUEVfTlVNKSB7DQorCQlyZWcg PSBkZXZhcGNfY3R4LT5kZXZhcGNfcGRfYmFzZVtzbGF2ZV90eXBlXSArDQorCQkJZGV2YXBjX3Bk c1twZF9yZWdfdHlwZV07DQorDQorCQlpZiAocGRfcmVnX3R5cGUgPT0gVklPX01BU0sgfHwgcGRf cmVnX3R5cGUgPT0gVklPX1NUQSkNCisJCQlyZWcgKz0gMHg0ICogaW5kZXg7DQorDQorCX0gZWxz ZSB7DQorCQlwcl9lcnIoUEZYICJPdXQgT2YgQm91bmRhcnksIHNsYXZlX3R5cGU6MHgleC9wZF9y ZWdfdHlwZToweCV4L2luZGV4OjB4JXhcbiIsDQorCQkgICAgICAgc2xhdmVfdHlwZSwgcGRfcmVn X3R5cGUsIGluZGV4KTsNCisJCXJldHVybiBOVUxMOw0KKwl9DQorDQorCXJldHVybiByZWc7DQor fQ0KKw0KKy8qDQorICogc3JhbXJvbV92aW9faGFuZGxlciAtIGNsZWFuIHNyYW1yb20gdmlvbGF0 aW9uICYgcHJpbnQgdmlvbGF0aW9uIGluZm9ybWF0aW9uDQorICoJCQkgZm9yIGRlYnVnZ2luZy4N CisgKi8NCitzdGF0aWMgdm9pZCBzcmFtcm9tX3Zpb19oYW5kbGVyKHN0cnVjdCBtdGtfZGV2YXBj X2NvbnRleHQgKmRldmFwY19jdHgpDQorew0KKwljb25zdCBzdHJ1Y3QgbXRrX3NyYW1yb21fc2Vj X3Zpb19kZXNjICpzcmFtcm9tX3Zpb3M7DQorCXN0cnVjdCBtdGtfZGV2YXBjX3Zpb19pbmZvICp2 aW9faW5mbzsNCisJc3RydWN0IGFybV9zbWNjY19yZXMgcmVzOw0KKwlzaXplX3Qgc3JhbXJvbV92 aW9fc3RhOw0KKwlpbnQgc3JhbXJvbV92aW87DQorCXUzMiBydzsNCisNCisJc3JhbXJvbV92aW9z ID0gZGV2YXBjX2N0eC0+c29jLT5zcmFtcm9tX3NlY192aW9zOw0KKwl2aW9faW5mbyA9IGRldmFw Y19jdHgtPnNvYy0+dmlvX2luZm87DQorDQorCWFybV9zbWNjY19zbWMoTVRLX1NJUF9LRVJORUxf Q0xSX1NSQU1ST01fVklPLA0KKwkJICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgJnJlcyk7DQor DQorCXNyYW1yb21fdmlvID0gcmVzLmEwOw0KKwlzcmFtcm9tX3Zpb19zdGEgPSByZXMuYTE7DQor CXZpb19pbmZvLT52aW9fYWRkciA9IHJlcy5hMjsNCisNCisJaWYgKHNyYW1yb21fdmlvID09IFNS QU1fVklPTEFUSU9OKQ0KKwkJcHJfaW5mbyhQRlggIlNSQU0gdmlvbGF0aW9uIGlzIHRyaWdnZXJl ZFxuIik7DQorCWVsc2UgaWYgKHNyYW1yb21fdmlvID09IFJPTV9WSU9MQVRJT04pDQorCQlwcl9p bmZvKFBGWCAiUk9NIHZpb2xhdGlvbiBpcyB0cmlnZ2VyZWRcbiIpOw0KKwllbHNlDQorCQlyZXR1 cm47DQorDQorCXZpb19pbmZvLT5tYXN0ZXJfaWQgPSAoc3JhbXJvbV92aW9fc3RhICYgc3JhbXJv bV92aW9zLT52aW9faWRfbWFzaykNCisJCQk+PiBzcmFtcm9tX3Zpb3MtPnZpb19pZF9zaGlmdDsN CisJdmlvX2luZm8tPmRvbWFpbl9pZCA9IChzcmFtcm9tX3Zpb19zdGEgJiBzcmFtcm9tX3Zpb3Mt PnZpb19kb21haW5fbWFzaykNCisJCQk+PiBzcmFtcm9tX3Zpb3MtPnZpb19kb21haW5fc2hpZnQ7 DQorCXJ3ID0gKHNyYW1yb21fdmlvX3N0YSAmIHNyYW1yb21fdmlvcy0+dmlvX3J3X21hc2spID4+ DQorCQkJc3JhbXJvbV92aW9zLT52aW9fcndfc2hpZnQ7DQorDQorCWlmIChydykNCisJCXZpb19p bmZvLT53cml0ZSA9IDE7DQorCWVsc2UNCisJCXZpb19pbmZvLT5yZWFkID0gMTsNCisNCisJcHJf aW5mbyhQRlggIiVzOiBtYXN0ZXJfaWQ6MHgleCwgZG9tYWluX2lkOjB4JXgsIHJ3OiVzLCB2aW9f YWRkcjoweCV4XG4iLA0KKwkJX19mdW5jX18sIHZpb19pbmZvLT5tYXN0ZXJfaWQsIHZpb19pbmZv LT5kb21haW5faWQsDQorCQlydyA/ICJXcml0ZSIgOiAiUmVhZCIsIHZpb19pbmZvLT52aW9fYWRk cik7DQorfQ0KKw0KK3N0YXRpYyB2b2lkIG1hc2tfbW9kdWxlX2lycShzdHJ1Y3QgbXRrX2RldmFw Y19jb250ZXh0ICpkZXZhcGNfY3R4LA0KKwkJCSAgICBpbnQgc2xhdmVfdHlwZSwgdTMyIG1vZHVs ZSwgYm9vbCBtYXNrKQ0KK3sNCisJc3RydWN0IG10a19kZXZhcGNfdmlvX2luZm8gKnZpb19pbmZv ID0gZGV2YXBjX2N0eC0+c29jLT52aW9faW5mbzsNCisJdTMyIHNsYXZlX3R5cGVfbnVtID0gZGV2 YXBjX2N0eC0+c29jLT5zbGF2ZV90eXBlX251bTsNCisJdTMyIGFwY19yZWdpc3Rlcl9pbmRleDsN CisJdTMyIGFwY19zZXRfaW5kZXg7DQorCXZvaWQgX19pb21lbSAqcmVnOw0KKw0KKwlhcGNfcmVn aXN0ZXJfaW5kZXggPSBtb2R1bGUgLyAoTU9EX05PX0lOXzFfREVWQVBDICogMik7DQorCWFwY19z ZXRfaW5kZXggPSBtb2R1bGUgJSAoTU9EX05PX0lOXzFfREVWQVBDICogMik7DQorDQorCWlmIChz bGF2ZV90eXBlIDwgc2xhdmVfdHlwZV9udW0gJiYNCisJICAgIGFwY19yZWdpc3Rlcl9pbmRleCA8 IHZpb19pbmZvLT52aW9fbWFza19zdGFfbnVtW3NsYXZlX3R5cGVdKSB7DQorCQlyZWcgPSBtdGtf ZGV2YXBjX3BkX2dldChkZXZhcGNfY3R4LCBzbGF2ZV90eXBlLCBWSU9fTUFTSywNCisJCQkJCWFw Y19yZWdpc3Rlcl9pbmRleCk7DQorDQorCQlpZiAobWFzaykNCisJCQl3cml0ZWwocmVhZGwocmVn KSB8ICgxIDw8IGFwY19zZXRfaW5kZXgpLCByZWcpOw0KKwkJZWxzZQ0KKwkJCXdyaXRlbChyZWFk bChyZWcpICYgKH4oMSA8PCBhcGNfc2V0X2luZGV4KSksIHJlZyk7DQorDQorCX0gZWxzZSB7DQor CQlwcl9lcnIoUEZYICIlczogT3V0IE9mIEJvdW5kYXJ5LCBzbGF2ZV90eXBlOjB4JXgsIG1vZHVs ZV9pbmRleDoweCV4LCBtYXNrOiVzXG4iLA0KKwkJICAgICAgIF9fZnVuY19fLCBzbGF2ZV90eXBl LCBtb2R1bGUsIG1hc2sgPyAidHJ1ZSIgOiAiZmFsc2UiKTsNCisJfQ0KK30NCisNCitzdGF0aWMg aW50IGNoZWNrX3Zpb19tYXNrKHN0cnVjdCBtdGtfZGV2YXBjX2NvbnRleHQgKmRldmFwY19jdHgs IGludCBzbGF2ZV90eXBlLA0KKwkJCSAgdTMyIG1vZHVsZSkNCit7DQorCXN0cnVjdCBtdGtfZGV2 YXBjX3Zpb19pbmZvICp2aW9faW5mbyA9IGRldmFwY19jdHgtPnNvYy0+dmlvX2luZm87DQorCXUz MiBzbGF2ZV90eXBlX251bSA9IGRldmFwY19jdHgtPnNvYy0+c2xhdmVfdHlwZV9udW07DQorCXUz MiBhcGNfcmVnaXN0ZXJfaW5kZXg7DQorCXUzMiBhcGNfc2V0X2luZGV4Ow0KKwl2b2lkIF9faW9t ZW0gKnJlZzsNCisNCisJYXBjX3JlZ2lzdGVyX2luZGV4ID0gbW9kdWxlIC8gKE1PRF9OT19JTl8x X0RFVkFQQyAqIDIpOw0KKwlhcGNfc2V0X2luZGV4ID0gbW9kdWxlICUgKE1PRF9OT19JTl8xX0RF VkFQQyAqIDIpOw0KKw0KKwlpZiAoc2xhdmVfdHlwZSA8IHNsYXZlX3R5cGVfbnVtICYmDQorCSAg ICBhcGNfcmVnaXN0ZXJfaW5kZXggPCB2aW9faW5mby0+dmlvX21hc2tfc3RhX251bVtzbGF2ZV90 eXBlXSkNCisJCXJlZyA9IG10a19kZXZhcGNfcGRfZ2V0KGRldmFwY19jdHgsIHNsYXZlX3R5cGUs IFZJT19NQVNLLA0KKwkJCQkJYXBjX3JlZ2lzdGVyX2luZGV4KTsNCisJZWxzZQ0KKwkJcmV0dXJu IC1FT1ZFUkZMT1c7DQorDQorCWlmIChyZWFkbChyZWcpICYgKDB4MSA8PCBhcGNfc2V0X2luZGV4 KSkNCisJCXJldHVybiBWSU9MQVRJT05fTUFTS0VEOw0KKw0KKwlyZXR1cm4gMDsNCit9DQorDQor c3RhdGljIGludDMyX3QgY2hlY2tfdmlvX3N0YXR1cyhzdHJ1Y3QgbXRrX2RldmFwY19jb250ZXh0 ICpkZXZhcGNfY3R4LA0KKwkJCQlpbnQgc2xhdmVfdHlwZSwgdTMyIG1vZHVsZSkNCit7DQorCXN0 cnVjdCBtdGtfZGV2YXBjX3Zpb19pbmZvICp2aW9faW5mbyA9IGRldmFwY19jdHgtPnNvYy0+dmlv X2luZm87DQorCXUzMiBzbGF2ZV90eXBlX251bSA9IGRldmFwY19jdHgtPnNvYy0+c2xhdmVfdHlw ZV9udW07DQorCXUzMiBhcGNfcmVnaXN0ZXJfaW5kZXg7DQorCXUzMiBhcGNfc2V0X2luZGV4Ow0K Kwl2b2lkIF9faW9tZW0gKnJlZzsNCisNCisJYXBjX3JlZ2lzdGVyX2luZGV4ID0gbW9kdWxlIC8g KE1PRF9OT19JTl8xX0RFVkFQQyAqIDIpOw0KKwlhcGNfc2V0X2luZGV4ID0gbW9kdWxlICUgKE1P RF9OT19JTl8xX0RFVkFQQyAqIDIpOw0KKw0KKwlpZiAoc2xhdmVfdHlwZSA8IHNsYXZlX3R5cGVf bnVtICYmDQorCSAgICBhcGNfcmVnaXN0ZXJfaW5kZXggPCB2aW9faW5mby0+dmlvX21hc2tfc3Rh X251bVtzbGF2ZV90eXBlXSkgew0KKwkJcmVnID0gbXRrX2RldmFwY19wZF9nZXQoZGV2YXBjX2N0 eCwgc2xhdmVfdHlwZSwgVklPX1NUQSwNCisJCQkJCWFwY19yZWdpc3Rlcl9pbmRleCk7DQorDQor CX0gZWxzZSB7DQorCQlwcl9lcnIoUEZYICIlczogT3V0IE9mIEJvdW5kYXJ5LCBzbGF2ZV90eXBl OjB4JXgsIG1vZHVsZV9pbmRleDoweCV4XG4iLA0KKwkJICAgICAgIF9fZnVuY19fLCBzbGF2ZV90 eXBlLCBtb2R1bGUpOw0KKwkJcmV0dXJuIC1FT1ZFUkZMT1c7DQorCX0NCisNCisJaWYgKHJlYWRs KHJlZykgJiAoMHgxIDw8IGFwY19zZXRfaW5kZXgpKQ0KKwkJcmV0dXJuIFZJT0xBVElPTl9UUklH R0VSRUQ7DQorDQorCXJldHVybiAwOw0KK30NCisNCitzdGF0aWMgaW50MzJfdCBjbGVhcl92aW9f c3RhdHVzKHN0cnVjdCBtdGtfZGV2YXBjX2NvbnRleHQgKmRldmFwY19jdHgsDQorCQkJCWludCBz bGF2ZV90eXBlLCB1MzIgbW9kdWxlKQ0KK3sNCisJc3RydWN0IG10a19kZXZhcGNfdmlvX2luZm8g KnZpb19pbmZvID0gZGV2YXBjX2N0eC0+c29jLT52aW9faW5mbzsNCisJdTMyIHNsYXZlX3R5cGVf bnVtID0gZGV2YXBjX2N0eC0+c29jLT5zbGF2ZV90eXBlX251bTsNCisJdTMyIGFwY19yZWdpc3Rl cl9pbmRleDsNCisJdTMyIGFwY19zZXRfaW5kZXg7DQorCXZvaWQgX19pb21lbSAqcmVnOw0KKw0K KwlhcGNfcmVnaXN0ZXJfaW5kZXggPSBtb2R1bGUgLyAoTU9EX05PX0lOXzFfREVWQVBDICogMik7 DQorCWFwY19zZXRfaW5kZXggPSBtb2R1bGUgJSAoTU9EX05PX0lOXzFfREVWQVBDICogMik7DQor DQorCWlmIChzbGF2ZV90eXBlIDwgc2xhdmVfdHlwZV9udW0gJiYNCisJICAgIGFwY19yZWdpc3Rl cl9pbmRleCA8IHZpb19pbmZvLT52aW9fbWFza19zdGFfbnVtW3NsYXZlX3R5cGVdKSB7DQorCQly ZWcgPSBtdGtfZGV2YXBjX3BkX2dldChkZXZhcGNfY3R4LCBzbGF2ZV90eXBlLCBWSU9fU1RBLA0K KwkJCQkJYXBjX3JlZ2lzdGVyX2luZGV4KTsNCisJCXdyaXRlbCgweDEgPDwgYXBjX3NldF9pbmRl eCwgcmVnKTsNCisNCisJfSBlbHNlIHsNCisJCXByX2VycihQRlggIiVzOiBPdXQgT2YgQm91bmRh cnksIHNsYXZlX3R5cGU6MHgleCwgbW9kdWxlX2luZGV4OjB4JXhcbiIsDQorCQkgICAgICAgX19m dW5jX18sIHNsYXZlX3R5cGUsIG1vZHVsZSk7DQorCQlyZXR1cm4gLUVPVkVSRkxPVzsNCisJfQ0K Kw0KKwlpZiAoY2hlY2tfdmlvX3N0YXR1cyhkZXZhcGNfY3R4LCBzbGF2ZV90eXBlLCBtb2R1bGUp KQ0KKwkJcmV0dXJuIC1FSU87DQorDQorCXJldHVybiAwOw0KK30NCisNCitzdGF0aWMgdm9pZCBk ZXZhcGNfdmlvX2luZm9fcHJpbnQoc3RydWN0IG10a19kZXZhcGNfY29udGV4dCAqZGV2YXBjX2N0 eCkNCit7DQorCXN0cnVjdCBtdGtfZGV2YXBjX3Zpb19pbmZvICp2aW9faW5mbzsNCisNCisJdmlv X2luZm8gPSBkZXZhcGNfY3R4LT5zb2MtPnZpb19pbmZvOw0KKw0KKwkvKiBQcmludCB2aW9sYXRp b24gaW5mb3JtYXRpb24gKi8NCisJaWYgKHZpb19pbmZvLT53cml0ZSkNCisJCXByX2luZm8oUEZY ICJXcml0ZSBWaW9sYXRpb25cbiIpOw0KKwllbHNlIGlmICh2aW9faW5mby0+cmVhZCkNCisJCXBy X2luZm8oUEZYICJSZWFkIFZpb2xhdGlvblxuIik7DQorDQorCXByX2luZm8oUEZYICIlcyV4LCAl cyV4LCAlcyV4LCAlcyV4XG4iLA0KKwkJIlZpbyBBZGRyOjB4IiwgdmlvX2luZm8tPnZpb19hZGRy LA0KKwkJIkhpZ2g6MHgiLCB2aW9faW5mby0+dmlvX2FkZHJfaGlnaCwNCisJCSJCdXMgSUQ6MHgi LCB2aW9faW5mby0+bWFzdGVyX2lkLA0KKwkJIkRvbSBJRDoweCIsIHZpb19pbmZvLT5kb21haW5f aWQpOw0KK30NCisNCisvKg0KKyAqIGNoZWNrX3R5cGUyX3Zpb19zdGF0dXMgLSB0aGVyZSBhcmUg dHlwZSAyIHNsYXZlcyB3aGljaCB2aW9sYXRpb24gaW5mb3JtYXRpb24NCisgKgkJCSAgICBpcyBz dG9yZWQgaW4gZGlmZmVyZW50IHJlZ2lzdGVyIGJhbmsuDQorICoNCisgKiBSZXR1cm5zIHRydWUg aWYgdHlwZTIgdmlvbGF0aW9uIGlzIHRyaWdnZXJlZC4NCisgKi8NCitzdGF0aWMgYm9vbCBjaGVj a190eXBlMl92aW9fc3RhdHVzKHN0cnVjdCBtdGtfZGV2YXBjX2NvbnRleHQgKmRldmFwY19jdHgs DQorCQkJCSAgIGludCBzbGF2ZV90eXBlLCBpbnQgKnZpb19pZHgsIGludCAqaW5kZXgpDQorew0K Kwl1MzIgc3JhbXJvbV92aW9faWR4LCBtZHBfdmlvX2lkeCwgZGlzcDJfdmlvX2lkeCwgbW1zeXNf dmlvX2lkeDsNCisJY29uc3Qgc3RydWN0IG10a19kZXZpY2VfaW5mbyAqKmRldmljZV9pbmZvOw0K Kwljb25zdCBzdHJ1Y3QgbXRrX2RldmljZV9udW0gKm5kZXZpY2VzOw0KKwlpbnQgc3JhbXJvbV9z bHZfdHlwZSwgbW0ybmRfc2x2X3R5cGU7DQorCWJvb2wgbWRwX3ZpbywgZGlzcDJfdmlvLCBtbXN5 c192aW87DQorCWludCBpOw0KKw0KKwlzcmFtcm9tX3Nsdl90eXBlID0gZGV2YXBjX2N0eC0+c29j LT52aW9faW5mby0+c3JhbXJvbV9zbHZfdHlwZTsNCisJc3JhbXJvbV92aW9faWR4ID0gZGV2YXBj X2N0eC0+c29jLT52aW9faW5mby0+c3JhbXJvbV92aW9faWR4Ow0KKw0KKwltbTJuZF9zbHZfdHlw ZSA9IGRldmFwY19jdHgtPnNvYy0+dmlvX2luZm8tPm1tMm5kX3Nsdl90eXBlOw0KKwltZHBfdmlv X2lkeCA9IGRldmFwY19jdHgtPnNvYy0+dmlvX2luZm8tPm1kcF92aW9faWR4Ow0KKwlkaXNwMl92 aW9faWR4ID0gZGV2YXBjX2N0eC0+c29jLT52aW9faW5mby0+ZGlzcDJfdmlvX2lkeDsNCisJbW1z eXNfdmlvX2lkeCA9IGRldmFwY19jdHgtPnNvYy0+dmlvX2luZm8tPm1tc3lzX3Zpb19pZHg7DQor DQorCWRldmljZV9pbmZvID0gZGV2YXBjX2N0eC0+c29jLT5kZXZpY2VfaW5mbzsNCisJbmRldmlj ZXMgPSBkZXZhcGNfY3R4LT5zb2MtPm5kZXZpY2VzOw0KKw0KKwkvKiBjaGVjayBTUkFNUk9NIHZp b2xhdGlvbiAqLw0KKwlpZiAoc2xhdmVfdHlwZSA9PSBzcmFtcm9tX3Nsdl90eXBlICYmDQorCSAg ICBjaGVja192aW9fc3RhdHVzKGRldmFwY19jdHgsIHNsYXZlX3R5cGUsIHNyYW1yb21fdmlvX2lk eCkpIHsNCisJCXByX2luZm8oUEZYICJTUkFNUk9NIHZpb2xhdGlvbiBpcyB0cmlnZ2VyZWRcbiIp Ow0KKwkJc3JhbXJvbV92aW9faGFuZGxlcihkZXZhcGNfY3R4KTsNCisNCisJCSp2aW9faWR4ID0g c3JhbXJvbV92aW9faWR4Ow0KKwkJZm9yIChpID0gMDsgaSA8IG5kZXZpY2VzW3NsYXZlX3R5cGVd LnZpb19zbGF2ZV9udW07IGkrKykgew0KKwkJCWlmIChkZXZpY2VfaW5mb1tzbGF2ZV90eXBlXVtp XS52aW9faW5kZXggPT0gKnZpb19pZHgpDQorCQkJCSppbmRleCA9IGk7DQorCQl9DQorDQorCQly ZXR1cm4gdHJ1ZTsNCisJfQ0KKw0KKwkvKiBjaGVjayBNTSAybmQgbGV2ZWwgdmlvbGF0aW9uICov DQorCWlmIChzbGF2ZV90eXBlID09IG1tMm5kX3Nsdl90eXBlKSB7DQorCQltZHBfdmlvID0gY2hl Y2tfdmlvX3N0YXR1cyhkZXZhcGNfY3R4LCBzbGF2ZV90eXBlLA0KKwkJCQkJICAgbWRwX3Zpb19p ZHgpID09DQorCQkJCQkgICBWSU9MQVRJT05fVFJJR0dFUkVEOw0KKwkJZGlzcDJfdmlvID0gY2hl Y2tfdmlvX3N0YXR1cyhkZXZhcGNfY3R4LCBzbGF2ZV90eXBlLA0KKwkJCQkJICAgICBkaXNwMl92 aW9faWR4KSA9PQ0KKwkJCQkJICAgICBWSU9MQVRJT05fVFJJR0dFUkVEOw0KKwkJbW1zeXNfdmlv ID0gY2hlY2tfdmlvX3N0YXR1cyhkZXZhcGNfY3R4LCBzbGF2ZV90eXBlLA0KKwkJCQkJICAgICBt bXN5c192aW9faWR4KSA9PQ0KKwkJCQkJICAgICBWSU9MQVRJT05fVFJJR0dFUkVEOw0KKw0KKwkJ aWYgKG1kcF92aW8gfHwgZGlzcDJfdmlvIHx8IG1tc3lzX3Zpbykgew0KKwkJCXByX2luZm8oUEZY ICJNTTJuZCB2aW9sYXRpb24gaXMgdHJpZ2dlcmVkXG4iKTsNCisJCQlkZXZhcGNfY3R4LT5zb2Mt Pm1tMm5kX3Zpb19oYW5kbGVyDQorCQkJCShkZXZhcGNfY3R4LT5pbmZyYWNmZ19iYXNlLA0KKwkJ CQkgZGV2YXBjX2N0eC0+c29jLT52aW9faW5mbywNCisJCQkJIG1kcF92aW8sDQorCQkJCSBkaXNw Ml92aW8sDQorCQkJCSBtbXN5c192aW8pOw0KKwkJfSBlbHNlIHsNCisJCQlyZXR1cm4gZmFsc2U7 DQorCQl9DQorDQorCQlpZiAobWRwX3ZpbykNCisJCQkqdmlvX2lkeCA9IG1kcF92aW9faWR4Ow0K KwkJZWxzZSBpZiAoZGlzcDJfdmlvKQ0KKwkJCSp2aW9faWR4ID0gZGlzcDJfdmlvX2lkeDsNCisJ CWVsc2UgaWYgKG1tc3lzX3ZpbykNCisJCQkqdmlvX2lkeCA9IG1tc3lzX3Zpb19pZHg7DQorDQor CQlmb3IgKGkgPSAwOyBpIDwgbmRldmljZXNbc2xhdmVfdHlwZV0udmlvX3NsYXZlX251bTsgaSsr KSB7DQorCQkJaWYgKGRldmljZV9pbmZvW3NsYXZlX3R5cGVdW2ldLnZpb19pbmRleCA9PSAqdmlv X2lkeCkNCisJCQkJKmluZGV4ID0gaTsNCisJCX0NCisNCisJCWRldmFwY192aW9faW5mb19wcmlu dChkZXZhcGNfY3R4KTsNCisJCXJldHVybiB0cnVlOw0KKwl9DQorDQorCXJldHVybiBmYWxzZTsN Cit9DQorDQorLyoNCisgKiBzeW5jX3Zpb19kYmcgLSBzdGFydCB0byBnZXQgdmlvbGF0aW9uIGlu Zm9ybWF0aW9uIGJ5IHNlbGVjdGluZyB2aW9sYXRpb24NCisgKgkJICBncm91cCBhbmQgZW5hYmxl IHZpb2xhdGlvbiBzaGlmdC4NCisgKg0KKyAqIFJldHVybnMgc3luYyBkb25lIG9yIG5vdA0KKyAq Lw0KK3N0YXRpYyB1MzIgc3luY192aW9fZGJnKHN0cnVjdCBtdGtfZGV2YXBjX2NvbnRleHQgKmRl dmFwY19jdHgsIGludCBzbGF2ZV90eXBlLA0KKwkJCXUzMiBzaGlmdF9iaXQpDQorew0KKwl1MzIg c2xhdmVfdHlwZV9udW0gPSBkZXZhcGNfY3R4LT5zb2MtPnNsYXZlX3R5cGVfbnVtOw0KKwl2b2lk IF9faW9tZW0gKnBkX3Zpb19zaGlmdF9zdGFfcmVnOw0KKwl2b2lkIF9faW9tZW0gKnBkX3Zpb19z aGlmdF9zZWxfcmVnOw0KKwl2b2lkIF9faW9tZW0gKnBkX3Zpb19zaGlmdF9jb25fcmVnOw0KKwl1 MzIgc2hpZnRfY291bnQ7DQorCXUzMiBzeW5jX2RvbmU7DQorDQorCWlmIChzbGF2ZV90eXBlID49 IHNsYXZlX3R5cGVfbnVtIHx8DQorCSAgICBzaGlmdF9iaXQgPj0gKE1PRF9OT19JTl8xX0RFVkFQ QyAqIDIpKSB7DQorCQlwcl9lcnIoUEZYICJwYXJhbSBjaGVjayBmYWlsZWQsIHNsYXZlX3R5cGU6 MHgleCwgc2hpZnRfYml0OjB4JXhcbiIsDQorCQkgICAgICAgc2xhdmVfdHlwZSwgc2hpZnRfYml0 KTsNCisJCXJldHVybiAwOw0KKwl9DQorDQorCXBkX3Zpb19zaGlmdF9zdGFfcmVnID0gbXRrX2Rl dmFwY19wZF9nZXQoZGV2YXBjX2N0eCwgc2xhdmVfdHlwZSwNCisJCQkJCQkgVklPX1NISUZUX1NU QSwgMCk7DQorCXBkX3Zpb19zaGlmdF9zZWxfcmVnID0gbXRrX2RldmFwY19wZF9nZXQoZGV2YXBj X2N0eCwgc2xhdmVfdHlwZSwNCisJCQkJCQkgVklPX1NISUZUX1NFTCwgMCk7DQorCXBkX3Zpb19z aGlmdF9jb25fcmVnID0gbXRrX2RldmFwY19wZF9nZXQoZGV2YXBjX2N0eCwgc2xhdmVfdHlwZSwN CisJCQkJCQkgVklPX1NISUZUX0NPTiwgMCk7DQorDQorCXdyaXRlbCgweDEgPDwgc2hpZnRfYml0 LCBwZF92aW9fc2hpZnRfc2VsX3JlZyk7DQorCXdyaXRlbCgweDEsIHBkX3Zpb19zaGlmdF9jb25f cmVnKTsNCisNCisJZm9yIChzaGlmdF9jb3VudCA9IDA7IChzaGlmdF9jb3VudCA8IDEwMCkgJiYN CisJICAgICAoKHJlYWRsKHBkX3Zpb19zaGlmdF9jb25fcmVnKSAmIDB4MykgIT0gMHgzKTsNCisJ ICAgICArK3NoaWZ0X2NvdW50KQ0KKwkJOw0KKw0KKwlpZiAoKHJlYWRsKHBkX3Zpb19zaGlmdF9j b25fcmVnKSAmIDB4MykgPT0gMHgzKQ0KKwkJc3luY19kb25lID0gMTsNCisJZWxzZQ0KKwkJc3lu Y19kb25lID0gMDsNCisNCisJLyogRGlzYWJsZSBzaGlmdCBtZWNoYW5pc20gKi8NCisJd3JpdGVs KDB4MCwgcGRfdmlvX3NoaWZ0X2Nvbl9yZWcpOw0KKwl3cml0ZWwoMHgwLCBwZF92aW9fc2hpZnRf c2VsX3JlZyk7DQorCXdyaXRlbCgweDEgPDwgc2hpZnRfYml0LCBwZF92aW9fc2hpZnRfc3RhX3Jl Zyk7DQorDQorCXJldHVybiBzeW5jX2RvbmU7DQorfQ0KKw0KK3N0YXRpYyBjb25zdCBjaGFyICog Y29uc3QgcGVybV90b19zdHJbXSA9IHsNCisJIk5PX1BST1RFQ1RJT04iLA0KKwkiU0VDVVJFX1JX X09OTFkiLA0KKwkiU0VDVVJFX1JXX05TX1JfT05MWSIsDQorCSJGT1JCSURERU4iLA0KKwkiTk9f UEVSTV9DVFJMIg0KK307DQorDQorc3RhdGljIGNvbnN0IGNoYXIgKnBlcm1fdG9fc3RyaW5nKHU4 IHBlcm0pDQorew0KKwlpZiAocGVybSA8IFBFUk1fVFlQRV9OVU0pDQorCQlyZXR1cm4gcGVybV90 b19zdHJbcGVybV07DQorCWVsc2UNCisJCXJldHVybiBwZXJtX3RvX3N0cltQRVJNX1RZUEVfTlVN XTsNCit9DQorDQorc3RhdGljIHZvaWQgZGV2YXBjX3Zpb19yZWFzb24odTggcGVybSkNCit7DQor CXByX2luZm8oUEZYICJQZXJtaXNzaW9uIHNldHRpbmc6ICVzXG4iLCBwZXJtX3RvX3N0cmluZyhw ZXJtKSk7DQorDQorCWlmIChwZXJtID09IE5PX1BST1RFQ1RJT04gfHwgcGVybSA+PSBQRVJNX1RZ UEVfTlVNKQ0KKwkJcHJfaW5mbyhQRlggIlJlYXNvbjogcG93ZXIvY2xvY2sgaXMgbm90IGVuYWJs ZWRcbiIpOw0KKwllbHNlIGlmIChwZXJtID09IFNFQ19SV19PTkxZIHx8DQorCQkgcGVybSA9PSBT RUNfUldfTlNfUiB8fA0KKwkJIHBlcm0gPT0gRk9SQklEREVOKQ0KKwkJcHJfaW5mbyhQRlggIlJl YXNvbjogbWlnaHQgYmUgcGVybWlzc2lvbiBkZW5pZWRcbiIpOw0KK30NCisNCisvKg0KKyAqIGdl dF9wZXJtaXNzaW9uIC0gZ2V0IHNsYXZlJ3MgYWNjZXNzIHBlcm1pc3Npb24gb2YgZG9tYWluIGlk Lg0KKyAqDQorICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYWNjZXNzIHBlcm1pc3Npb24NCisgKi8N CitzdGF0aWMgdTggZ2V0X3Blcm1pc3Npb24oc3RydWN0IG10a19kZXZhcGNfY29udGV4dCAqZGV2 YXBjX2N0eCwgaW50IHNsYXZlX3R5cGUsDQorCQkJIGludCBtb2R1bGVfaW5kZXgsIGludCBkb21h aW4pDQorew0KKwl1MzIgc2xhdmVfdHlwZV9udW0gPSBkZXZhcGNfY3R4LT5zb2MtPnNsYXZlX3R5 cGVfbnVtOw0KKwljb25zdCBzdHJ1Y3QgbXRrX2RldmljZV9pbmZvICoqZGV2aWNlX2luZm87DQor CWNvbnN0IHN0cnVjdCBtdGtfZGV2aWNlX251bSAqbmRldmljZXM7DQorCWludCBzeXNfaW5kZXgs IGN0cmxfaW5kZXgsIHZpb19pbmRleDsNCisJc3RydWN0IGFybV9zbWNjY19yZXMgcmVzOw0KKwl1 MzIgcmV0LCBhcGNfc2V0X2luZGV4Ow0KKw0KKwluZGV2aWNlcyA9IGRldmFwY19jdHgtPnNvYy0+ bmRldmljZXM7DQorDQorCWlmIChzbGF2ZV90eXBlID49IHNsYXZlX3R5cGVfbnVtIHx8DQorCSAg ICBtb2R1bGVfaW5kZXggPj0gbmRldmljZXNbc2xhdmVfdHlwZV0udmlvX3NsYXZlX251bSkgew0K KwkJcHJfZXJyKFBGWCAiJXM6IHBhcmFtIGNoZWNrIGZhaWxlZCwgc2xhdmVfdHlwZToweCV4LCBt b2R1bGVfaW5kZXg6MHgleFxuIiwNCisJCSAgICAgICBfX2Z1bmNfXywgc2xhdmVfdHlwZSwgbW9k dWxlX2luZGV4KTsNCisJCXJldHVybiAweEZGOw0KKwl9DQorDQorCWRldmljZV9pbmZvID0gZGV2 YXBjX2N0eC0+c29jLT5kZXZpY2VfaW5mbzsNCisNCisJc3lzX2luZGV4ID0gZGV2aWNlX2luZm9b c2xhdmVfdHlwZV1bbW9kdWxlX2luZGV4XS5zeXNfaW5kZXg7DQorCWN0cmxfaW5kZXggPSBkZXZp Y2VfaW5mb1tzbGF2ZV90eXBlXVttb2R1bGVfaW5kZXhdLmN0cmxfaW5kZXg7DQorCXZpb19pbmRl eCA9IGRldmljZV9pbmZvW3NsYXZlX3R5cGVdW21vZHVsZV9pbmRleF0udmlvX2luZGV4Ow0KKw0K KwlpZiAoc3lzX2luZGV4ID09IC0xIHx8IGN0cmxfaW5kZXggPT0gLTEpDQorCQlyZXR1cm4gMHhG RjsNCisNCisJYXJtX3NtY2NjX3NtYyhNVEtfU0lQX0tFUk5FTF9EQVBDX1BFUk1fR0VULCBzbGF2 ZV90eXBlLCBzeXNfaW5kZXgsDQorCQkgICAgICBkb21haW4sIGN0cmxfaW5kZXgsIHZpb19pbmRl eCwgMCwgMCwgJnJlcyk7DQorCXJldCA9IHJlcy5hMDsNCisNCisJaWYgKHJldCA9PSBERUFEKSB7 DQorCQlwcl9lcnIoUEZYICJwZXJtaXNzaW9uIGdldCBmYWlsZWQsIHJldDoweCV4XG4iLCByZXQp Ow0KKwkJcmV0dXJuIDB4RkY7DQorCX0NCisNCisJYXBjX3NldF9pbmRleCA9IGN0cmxfaW5kZXgg JSBNT0RfTk9fSU5fMV9ERVZBUEM7DQorCXJldCA9IChyZXQgJiAoMHgzIDw8IChhcGNfc2V0X2lu ZGV4ICogMikpKSA+PiAoYXBjX3NldF9pbmRleCAqIDIpOw0KKw0KKwlyZXR1cm4gKHJldCAmIDB4 Myk7DQorfQ0KKw0KKy8qDQorICogbXRrX2RldmFwY192aW9fY2hlY2sgLSBjaGVjayB2aW9sYXRp b24gc2hpZnQgc3RhdHVzIGlzIHJhaXNlZCBvciBub3QuDQorICoNCisgKiBSZXR1cm5zIHRoZSB2 YWx1ZSBvZiB2aW9sYXRpb24gc2hpZnQgc3RhdHVzIHJlZw0KKyAqLw0KK3N0YXRpYyB2b2lkIG10 a19kZXZhcGNfdmlvX2NoZWNrKHN0cnVjdCBtdGtfZGV2YXBjX2NvbnRleHQgKmRldmFwY19jdHgs DQorCQkJCSBpbnQgc2xhdmVfdHlwZSwgaW50ICpzaGlmdF9iaXQpDQorew0KKwlzdHJ1Y3QgbXRr X2RldmFwY192aW9faW5mbyAqdmlvX2luZm87DQorCXUzMiB2aW9fc2hpZnRfc3RhOw0KKwlpbnQg aTsNCisNCisJdmlvX2luZm8gPSBkZXZhcGNfY3R4LT5zb2MtPnZpb19pbmZvOw0KKwl2aW9fc2hp ZnRfc3RhID0gcmVhZGwobXRrX2RldmFwY19wZF9nZXQoZGV2YXBjX2N0eCwgc2xhdmVfdHlwZSwN CisJCQkJCQlWSU9fU0hJRlRfU1RBLCAwKSk7DQorDQorCWlmICghdmlvX3NoaWZ0X3N0YSkgew0K KwkJcHJfaW5mbyhQRlggInZpb2xhdGlvbiBpcyB0cmlnZ2VyZWQgYmVmb3JlLiBzaGlmdF9iaXQ6 MHgleFxuIiwNCisJCQkqc2hpZnRfYml0KTsNCisNCisJfSBlbHNlIGlmICh2aW9fc2hpZnRfc3Rh ICYgKDB4MVVMIDw8ICpzaGlmdF9iaXQpKSB7DQorCQlwcl9kZWJ1ZyhQRlggInZpb19zaGlmdF9z dGE6MHgleCBpcyBtYXRjaGVkIHdpdGggc2hpZnRfYml0OiVkXG4iLA0KKwkJCSB2aW9fc2hpZnRf c3RhLCAqc2hpZnRfYml0KTsNCisNCisJfSBlbHNlIHsNCisJCXByX2luZm8oUEZYICJ2aW9fc2hp ZnRfc3RhOjB4JXggaXMgbm90IG1hdGNoZWQgd2l0aCBzaGlmdF9iaXQ6JWRcbiIsDQorCQkJdmlv X3NoaWZ0X3N0YSwgKnNoaWZ0X2JpdCk7DQorDQorCQlmb3IgKGkgPSAwOyBpIDwgTU9EX05PX0lO XzFfREVWQVBDICogMjsgaSsrKSB7DQorCQkJaWYgKHZpb19zaGlmdF9zdGEgJiAoMHgxIDw8IGkp KSB7DQorCQkJCSpzaGlmdF9iaXQgPSBpOw0KKwkJCQlicmVhazsNCisJCQl9DQorCQl9DQorCX0N CisNCisJdmlvX2luZm8tPnNoaWZ0X3N0YV9iaXQgPSAqc2hpZnRfYml0Ow0KK30NCisNCitzdGF0 aWMgdm9pZCBkZXZhcGNfZXh0cmFjdF92aW9fZGJnKHN0cnVjdCBtdGtfZGV2YXBjX2NvbnRleHQg KmRldmFwY19jdHgsDQorCQkJCSAgIGludCBzbGF2ZV90eXBlKQ0KK3sNCisJdm9pZCBfX2lvbWVt ICp2aW9fZGJnMF9yZWcsICp2aW9fZGJnMV9yZWcsICp2aW9fZGJnMl9yZWc7DQorCWNvbnN0IHN0 cnVjdCBtdGtfaW5mcmFfdmlvX2RiZ19kZXNjICp2aW9fZGJnczsNCisJc3RydWN0IG10a19kZXZh cGNfdmlvX2luZm8gKnZpb19pbmZvOw0KKwl1MzIgZGJnMDsNCisNCisJdmlvX2RiZzBfcmVnID0g bXRrX2RldmFwY19wZF9nZXQoZGV2YXBjX2N0eCwgc2xhdmVfdHlwZSwgVklPX0RCRzAsIDApOw0K Kwl2aW9fZGJnMV9yZWcgPSBtdGtfZGV2YXBjX3BkX2dldChkZXZhcGNfY3R4LCBzbGF2ZV90eXBl LCBWSU9fREJHMSwgMCk7DQorCXZpb19kYmcyX3JlZyA9IG10a19kZXZhcGNfcGRfZ2V0KGRldmFw Y19jdHgsIHNsYXZlX3R5cGUsIFZJT19EQkcyLCAwKTsNCisNCisJdmlvX2RiZ3MgPSBkZXZhcGNf Y3R4LT5zb2MtPnZpb19kYmdzOw0KKwl2aW9faW5mbyA9IGRldmFwY19jdHgtPnNvYy0+dmlvX2lu Zm87DQorDQorCS8qIEV4dHJhY3QgdmlvbGF0aW9uIGluZm9ybWF0aW9uICovDQorCWRiZzAgPSBy ZWFkbCh2aW9fZGJnMF9yZWcpOw0KKwl2aW9faW5mby0+bWFzdGVyX2lkID0gcmVhZGwodmlvX2Ri ZzFfcmVnKTsNCisJdmlvX2luZm8tPnZpb19hZGRyID0gcmVhZGwodmlvX2RiZzJfcmVnKTsNCisN CisJdmlvX2luZm8tPmRvbWFpbl9pZCA9IChkYmcwICYgdmlvX2RiZ3MtPnZpb19kYmdfZG1uaWQp DQorCQk+PiB2aW9fZGJncy0+dmlvX2RiZ19kbW5pZF9zdGFydF9iaXQ7DQorCXZpb19pbmZvLT53 cml0ZSA9ICgoZGJnMCAmIHZpb19kYmdzLT52aW9fZGJnX3dfdmlvKQ0KKwkJCT4+IHZpb19kYmdz LT52aW9fZGJnX3dfdmlvX3N0YXJ0X2JpdCkgPT0gMTsNCisJdmlvX2luZm8tPnJlYWQgPSAoKGRi ZzAgJiB2aW9fZGJncy0+dmlvX2RiZ19yX3ZpbykNCisJCQk+PiB2aW9fZGJncy0+dmlvX2RiZ19y X3Zpb19zdGFydF9iaXQpID09IDE7DQorCXZpb19pbmZvLT52aW9fYWRkcl9oaWdoID0gKGRiZzAg JiB2aW9fZGJncy0+dmlvX2FkZHJfaGlnaCkNCisJCT4+IHZpb19kYmdzLT52aW9fYWRkcl9oaWdo X3N0YXJ0X2JpdDsNCisNCisJZGV2YXBjX3Zpb19pbmZvX3ByaW50KGRldmFwY19jdHgpOw0KK30N CisNCisvKg0KKyAqIG10a19kZXZhcGNfZHVtcF92aW9fZGJnIC0gc2hpZnQgJiBkdW1wIHRoZSB2 aW9sYXRpb24gZGVidWcgaW5mb3JtYXRpb24uDQorICovDQorc3RhdGljIGJvb2wgbXRrX2RldmFw Y19kdW1wX3Zpb19kYmcoc3RydWN0IG10a19kZXZhcGNfY29udGV4dCAqZGV2YXBjX2N0eCwNCisJ CQkJICAgIGludCBzbGF2ZV90eXBlLCBpbnQgKnZpb19pZHgsIGludCAqaW5kZXgpDQorew0KKwlj b25zdCBzdHJ1Y3QgbXRrX2RldmljZV9pbmZvICoqZGV2aWNlX2luZm87DQorCWNvbnN0IHN0cnVj dCBtdGtfZGV2aWNlX251bSAqbmRldmljZXM7DQorCXZvaWQgX19pb21lbSAqcGRfdmlvX3NoaWZ0 X3N0YV9yZWc7DQorCXUzMiBzaGlmdF9iaXQ7DQorCWludCBpOw0KKw0KKwlpZiAoIXZpb19pZHgp DQorCQlyZXR1cm4gTlVMTDsNCisNCisJZGV2aWNlX2luZm8gPSBkZXZhcGNfY3R4LT5zb2MtPmRl dmljZV9pbmZvOw0KKwluZGV2aWNlcyA9IGRldmFwY19jdHgtPnNvYy0+bmRldmljZXM7DQorDQor CXBkX3Zpb19zaGlmdF9zdGFfcmVnID0gbXRrX2RldmFwY19wZF9nZXQoZGV2YXBjX2N0eCwgc2xh dmVfdHlwZSwNCisJCQkJCQkgVklPX1NISUZUX1NUQSwgMCk7DQorDQorCWZvciAoaSA9IDA7IGkg PCBuZGV2aWNlc1tzbGF2ZV90eXBlXS52aW9fc2xhdmVfbnVtOyBpKyspIHsNCisJCSp2aW9faWR4 ID0gZGV2aWNlX2luZm9bc2xhdmVfdHlwZV1baV0udmlvX2luZGV4Ow0KKw0KKwkJaWYgKGNoZWNr X3Zpb19tYXNrKGRldmFwY19jdHgsIHNsYXZlX3R5cGUsICp2aW9faWR4KSkNCisJCQljb250aW51 ZTsNCisNCisJCWlmIChjaGVja192aW9fc3RhdHVzKGRldmFwY19jdHgsIHNsYXZlX3R5cGUsICp2 aW9faWR4KSAhPQ0KKwkJCQlWSU9MQVRJT05fVFJJR0dFUkVEKQ0KKwkJCWNvbnRpbnVlOw0KKw0K KwkJc2hpZnRfYml0ID0gZGV2YXBjX2N0eC0+c29jLT5zaGlmdF9ncm91cF9nZXQoc2xhdmVfdHlw ZSwNCisJCQkJCQkJICAgICAqdmlvX2lkeCk7DQorDQorCQltdGtfZGV2YXBjX3Zpb19jaGVjayhk ZXZhcGNfY3R4LCBzbGF2ZV90eXBlLCAmc2hpZnRfYml0KTsNCisNCisJCWlmICghc3luY192aW9f ZGJnKGRldmFwY19jdHgsIHNsYXZlX3R5cGUsIHNoaWZ0X2JpdCkpDQorCQkJY29udGludWU7DQor DQorCQlkZXZhcGNfZXh0cmFjdF92aW9fZGJnKGRldmFwY19jdHgsIHNsYXZlX3R5cGUpOw0KKwkJ KmluZGV4ID0gaTsNCisNCisJCXJldHVybiB0cnVlOw0KKwl9DQorDQorCXJldHVybiBmYWxzZTsN Cit9DQorDQorLyoNCisgKiBzdGFydF9kZXZhcGMgLSBpbml0aWFsaXplIGRldmFwYyBzdGF0dXMg YW5kIHN0YXJ0IHJlY2VpdmluZyBpbnRlcnJ1cHQNCisgKgkJICB3aGlsZSBkZXZhcGMgdmlvbGF0 aW9uIGlzIHRyaWdnZXJlZC4NCisgKi8NCitzdGF0aWMgdm9pZCBzdGFydF9kZXZhcGMoc3RydWN0 IG10a19kZXZhcGNfY29udGV4dCAqZGV2YXBjX2N0eCkNCit7DQorCXUzMiBzbGF2ZV90eXBlX251 bSA9IGRldmFwY19jdHgtPnNvYy0+c2xhdmVfdHlwZV9udW07DQorCWNvbnN0IHN0cnVjdCBtdGtf ZGV2aWNlX2luZm8gKipkZXZpY2VfaW5mbzsNCisJY29uc3Qgc3RydWN0IG10a19kZXZpY2VfbnVt ICpuZGV2aWNlczsNCisJdm9pZCBfX2lvbWVtICpwZF92aW9fc2hpZnRfc3RhX3JlZzsNCisJdm9p ZCBfX2lvbWVtICpwZF9hcGNfY29uX3JlZzsNCisJaW50IHNsYXZlX3R5cGUsIGksIHZpb19pZHgs IGluZGV4Ow0KKwl1MzIgdmlvX3NoaWZ0X3N0YTsNCisNCisJbmRldmljZXMgPSBkZXZhcGNfY3R4 LT5zb2MtPm5kZXZpY2VzOw0KKw0KKwlkZXZpY2VfaW5mbyA9IGRldmFwY19jdHgtPnNvYy0+ZGV2 aWNlX2luZm87DQorDQorCWZvciAoc2xhdmVfdHlwZSA9IDA7IHNsYXZlX3R5cGUgPCBzbGF2ZV90 eXBlX251bTsgc2xhdmVfdHlwZSsrKSB7DQorCQlwZF9hcGNfY29uX3JlZyA9IG10a19kZXZhcGNf cGRfZ2V0KGRldmFwY19jdHgsIHNsYXZlX3R5cGUsDQorCQkJCQkJICAgQVBDX0NPTiwgMCk7DQor CQlwZF92aW9fc2hpZnRfc3RhX3JlZyA9IG10a19kZXZhcGNfcGRfZ2V0KGRldmFwY19jdHgsIHNs YXZlX3R5cGUsDQorCQkJCQkJCSBWSU9fU0hJRlRfU1RBLCAwKTsNCisNCisJCWlmICghcGRfYXBj X2Nvbl9yZWcgfHwgIXBkX3Zpb19zaGlmdF9zdGFfcmVnIHx8ICFkZXZpY2VfaW5mbykNCisJCQly ZXR1cm47DQorDQorCQkvKiBDbGVhciBERVZBUEMgdmlvbGF0aW9uIHN0YXR1cyAqLw0KKwkJd3Jp dGVsKEJJVCgzMSksIHBkX2FwY19jb25fcmVnKTsNCisNCisJCS8qIENsZWFyIHZpb2xhdGlvbiBz aGlmdCBzdGF0dXMgKi8NCisJCXZpb19zaGlmdF9zdGEgPSByZWFkbChwZF92aW9fc2hpZnRfc3Rh X3JlZyk7DQorCQlpZiAodmlvX3NoaWZ0X3N0YSkNCisJCQl3cml0ZWwodmlvX3NoaWZ0X3N0YSwg cGRfdmlvX3NoaWZ0X3N0YV9yZWcpOw0KKw0KKwkJLyogQ2xlYXIgdHlwZSAyIHZpb2xhdGlvbiBz dGF0dXMgKi8NCisJCWNoZWNrX3R5cGUyX3Zpb19zdGF0dXMoZGV2YXBjX2N0eCwgc2xhdmVfdHlw ZSwgJnZpb19pZHgsICZpKTsNCisNCisJCS8qIENsZWFyIHZpb2xhdGlvbiBzdGF0dXMgKi8NCisJ CWZvciAoaSA9IDA7IGkgPCBuZGV2aWNlc1tzbGF2ZV90eXBlXS52aW9fc2xhdmVfbnVtOyBpKysp IHsNCisJCQl2aW9faWR4ID0gZGV2aWNlX2luZm9bc2xhdmVfdHlwZV1baV0udmlvX2luZGV4Ow0K KwkJCWlmICgoY2hlY2tfdmlvX3N0YXR1cyhkZXZhcGNfY3R4LCBzbGF2ZV90eXBlLCB2aW9faWR4 KQ0KKwkJCQkJICAgICAgPT0gVklPTEFUSU9OX1RSSUdHRVJFRCkgJiYNCisJCQkgICAgIGNsZWFy X3Zpb19zdGF0dXMoZGV2YXBjX2N0eCwgc2xhdmVfdHlwZSwNCisJCQkJCSAgICAgIHZpb19pZHgp KSB7DQorCQkJCXByX3dhcm4oUEZYICJDbGVhciB2aW8gc3RhdHVzIGZhaWxlZCwgc2xhdmVfdHlw ZToweCV4LCB2aW9faW5kZXg6MHgleFxuIiwNCisJCQkJCXNsYXZlX3R5cGUsIHZpb19pZHgpOw0K Kw0KKwkJCQlpbmRleCA9IGk7DQorCQkJCW10a19kZXZhcGNfZHVtcF92aW9fZGJnKGRldmFwY19j dHgsIHNsYXZlX3R5cGUsDQorCQkJCQkJCSZ2aW9faWR4LCAmaW5kZXgpOw0KKwkJCQlpID0gaW5k ZXggLSAxOw0KKwkJCX0NCisNCisJCQltYXNrX21vZHVsZV9pcnEoZGV2YXBjX2N0eCwgc2xhdmVf dHlwZSwgdmlvX2lkeCwgZmFsc2UpOw0KKwkJfQ0KKwl9DQorfQ0KKw0KK3N0YXRpYyBERUZJTkVf U1BJTkxPQ0soZGV2YXBjX2xvY2spOw0KKw0KKy8qDQorICogZGV2YXBjX3Zpb2xhdGlvbl9pcnEg LSB0aGUgZGV2YXBjIEludGVycnVwdCBTZXJ2aWNlIFJvdXRpbmUgKElTUikgd2lsbCBkdW1wDQor ICoJCQkgIHZpb2xhdGlvbiBpbmZvcm1hdGlvbiBpbmNsdWRpbmcgd2hpY2ggbWFzdGVyIHZpb2xh dGVzDQorICoJCQkgIGFjY2VzcyBzbGF2ZS4NCisgKi8NCitzdGF0aWMgaXJxcmV0dXJuX3QgZGV2 YXBjX3Zpb2xhdGlvbl9pcnEoaW50IGlycV9udW1iZXIsDQorCQkJCQlzdHJ1Y3QgbXRrX2RldmFw Y19jb250ZXh0ICpkZXZhcGNfY3R4KQ0KK3sNCisJdTMyIHNsYXZlX3R5cGVfbnVtID0gZGV2YXBj X2N0eC0+c29jLT5zbGF2ZV90eXBlX251bTsNCisJY29uc3Qgc3RydWN0IG10a19kZXZpY2VfaW5m byAqKmRldmljZV9pbmZvOw0KKwlzdHJ1Y3QgbXRrX2RldmFwY192aW9faW5mbyAqdmlvX2luZm87 DQorCWludCBzbGF2ZV90eXBlLCB2aW9faWR4LCBpbmRleDsNCisJY29uc3QgY2hhciAqdmlvX21h c3RlcjsNCisJdW5zaWduZWQgbG9uZyBmbGFnczsNCisJdTggcGVybTsNCisNCisJc3Bpbl9sb2Nr X2lycXNhdmUoJmRldmFwY19sb2NrLCBmbGFncyk7DQorDQorCWRldmljZV9pbmZvID0gZGV2YXBj X2N0eC0+c29jLT5kZXZpY2VfaW5mbzsNCisJdmlvX2luZm8gPSBkZXZhcGNfY3R4LT5zb2MtPnZp b19pbmZvOw0KKwl2aW9faWR4ID0gLTE7DQorCWluZGV4ID0gLTE7DQorDQorCS8qIFRoZXJlIGFy ZSBtdWx0aXBsZSBERVZBUENfUEQgKi8NCisJZm9yIChzbGF2ZV90eXBlID0gMDsgc2xhdmVfdHlw ZSA8IHNsYXZlX3R5cGVfbnVtOyBzbGF2ZV90eXBlKyspIHsNCisJCWlmICghY2hlY2tfdHlwZTJf dmlvX3N0YXR1cyhkZXZhcGNfY3R4LCBzbGF2ZV90eXBlLCAmdmlvX2lkeCwNCisJCQkJCSAgICAm aW5kZXgpKQ0KKwkJCWlmICghbXRrX2RldmFwY19kdW1wX3Zpb19kYmcoZGV2YXBjX2N0eCwgc2xh dmVfdHlwZSwNCisJCQkJCQkgICAgICZ2aW9faWR4LCAmaW5kZXgpKQ0KKwkJCQljb250aW51ZTsN CisNCisJCS8qIEVuc3VyZSB0aGF0IHZpb2xhdGlvbiBpbmZvIGFyZSB3cml0dGVuIGJlZm9yZQ0K KwkJICogZnVydGhlciBvcGVyYXRpb25zDQorCQkgKi8NCisJCXNtcF9tYigpOw0KKw0KKwkJbWFz a19tb2R1bGVfaXJxKGRldmFwY19jdHgsIHNsYXZlX3R5cGUsIHZpb19pZHgsIHRydWUpOw0KKw0K KwkJY2xlYXJfdmlvX3N0YXR1cyhkZXZhcGNfY3R4LCBzbGF2ZV90eXBlLCB2aW9faWR4KTsNCisN CisJCXBlcm0gPSBnZXRfcGVybWlzc2lvbihkZXZhcGNfY3R4LCBzbGF2ZV90eXBlLCBpbmRleCwN CisJCQkJICAgICAgdmlvX2luZm8tPmRvbWFpbl9pZCk7DQorDQorCQl2aW9fbWFzdGVyID0gZGV2 YXBjX2N0eC0+c29jLT5tYXN0ZXJfZ2V0DQorCQkJKHZpb19pbmZvLT5tYXN0ZXJfaWQsDQorCQkJ IHZpb19pbmZvLT52aW9fYWRkciwNCisJCQkgc2xhdmVfdHlwZSwNCisJCQkgdmlvX2luZm8tPnNo aWZ0X3N0YV9iaXQsDQorCQkJIHZpb19pbmZvLT5kb21haW5faWQpOw0KKw0KKwkJaWYgKCF2aW9f bWFzdGVyKQ0KKwkJCXZpb19tYXN0ZXIgPSAiVU5LTk9XTl9NQVNURVIiOw0KKw0KKwkJcHJfaW5m byhQRlggIlZpb2xhdGlvbiAtIHNsYXZlX3R5cGU6MHgleCwgc3lzX2luZGV4OjB4JXgsIGN0cmxf aW5kZXg6MHgleCwgdmlvX2luZGV4OjB4JXhcbiIsDQorCQkJc2xhdmVfdHlwZSwNCisJCQlkZXZp Y2VfaW5mb1tzbGF2ZV90eXBlXVtpbmRleF0uc3lzX2luZGV4LA0KKwkJCWRldmljZV9pbmZvW3Ns YXZlX3R5cGVdW2luZGV4XS5jdHJsX2luZGV4LA0KKwkJCWRldmljZV9pbmZvW3NsYXZlX3R5cGVd W2luZGV4XS52aW9faW5kZXgpOw0KKw0KKwkJcHJfaW5mbyhQRlggIlZpb2xhdGlvbiBNYXN0ZXI6 ICVzXG4iLCB2aW9fbWFzdGVyKTsNCisNCisJCWRldmFwY192aW9fcmVhc29uKHBlcm0pOw0KKw0K KwkJbWFza19tb2R1bGVfaXJxKGRldmFwY19jdHgsIHNsYXZlX3R5cGUsIHZpb19pZHgsIGZhbHNl KTsNCisJfQ0KKw0KKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZkZXZhcGNfbG9jaywgZmxhZ3Mp Ow0KKwlyZXR1cm4gSVJRX0hBTkRMRUQ7DQorfQ0KKw0KK2ludCBtdGtfZGV2YXBjX3Byb2JlKHN0 cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYsIHN0cnVjdCBtdGtfZGV2YXBjX3NvYyAqc29jKQ0K K3sNCisJc3RydWN0IGRldmljZV9ub2RlICpub2RlID0gcGRldi0+ZGV2Lm9mX25vZGU7DQorCXN0 cnVjdCBtdGtfZGV2YXBjX2NvbnRleHQgKmRldmFwY19jdHg7DQorCXUzMiBzbGF2ZV90eXBlX251 bTsNCisJaW50IHNsYXZlX3R5cGU7DQorCWludCByZXQ7DQorDQorCWlmIChJU19FUlIobm9kZSkp DQorCQlyZXR1cm4gLUVOT0RFVjsNCisNCisJZGV2YXBjX2N0eCA9IGRldm1fa3phbGxvYygmcGRl di0+ZGV2LCBzaXplb2Yoc3RydWN0IG10a19kZXZhcGNfY29udGV4dCksDQorCQkJCSAgR0ZQX0tF Uk5FTCk7DQorCWlmICghZGV2YXBjX2N0eCkNCisJCXJldHVybiAtRU5PTUVNOw0KKw0KKwlkZXZh cGNfY3R4LT5zb2MgPSBzb2M7DQorCXNsYXZlX3R5cGVfbnVtID0gZGV2YXBjX2N0eC0+c29jLT5z bGF2ZV90eXBlX251bTsNCisNCisJZm9yIChzbGF2ZV90eXBlID0gMDsgc2xhdmVfdHlwZSA8IHNs YXZlX3R5cGVfbnVtOyBzbGF2ZV90eXBlKyspIHsNCisJCWRldmFwY19jdHgtPmRldmFwY19wZF9i YXNlW3NsYXZlX3R5cGVdID0NCisJCQlvZl9pb21hcChub2RlLCBzbGF2ZV90eXBlKTsNCisJCWlm ICghZGV2YXBjX2N0eC0+ZGV2YXBjX3BkX2Jhc2Vbc2xhdmVfdHlwZV0pDQorCQkJcmV0dXJuIC1F SU5WQUw7DQorCX0NCisNCisJZGV2YXBjX2N0eC0+aW5mcmFjZmdfYmFzZSA9IG9mX2lvbWFwKG5v ZGUsIHNsYXZlX3R5cGVfbnVtICsgMSk7DQorCWlmICghZGV2YXBjX2N0eC0+aW5mcmFjZmdfYmFz ZSkNCisJCXJldHVybiAtRUlOVkFMOw0KKw0KKwlkZXZhcGNfY3R4LT5kZXZhcGNfaXJxID0gaXJx X29mX3BhcnNlX2FuZF9tYXAobm9kZSwgMCk7DQorCWlmICghZGV2YXBjX2N0eC0+ZGV2YXBjX2ly cSkNCisJCXJldHVybiAtRUlOVkFMOw0KKw0KKwkvKiBDQ0YgKENvbW1vbiBDbG9jayBGcmFtZXdv cmspICovDQorCWRldmFwY19jdHgtPmRldmFwY19pbmZyYV9jbGsgPSBkZXZtX2Nsa19nZXQoJnBk ZXYtPmRldiwNCisJCQkJCQkgICAgImRldmFwYy1pbmZyYS1jbG9jayIpOw0KKw0KKwlpZiAoSVNf RVJSKGRldmFwY19jdHgtPmRldmFwY19pbmZyYV9jbGspKQ0KKwkJcmV0dXJuIC1FSU5WQUw7DQor DQorCWlmIChjbGtfcHJlcGFyZV9lbmFibGUoZGV2YXBjX2N0eC0+ZGV2YXBjX2luZnJhX2Nsaykp DQorCQlyZXR1cm4gLUVJTlZBTDsNCisNCisJc3RhcnRfZGV2YXBjKGRldmFwY19jdHgpOw0KKw0K KwlyZXQgPSBkZXZtX3JlcXVlc3RfaXJxKCZwZGV2LT5kZXYsIGRldmFwY19jdHgtPmRldmFwY19p cnEsDQorCQkJICAgICAgIChpcnFfaGFuZGxlcl90KWRldmFwY192aW9sYXRpb25faXJxLA0KKwkJ CSAgICAgICBJUlFGX1RSSUdHRVJfTk9ORSwgImRldmFwYyIsIGRldmFwY19jdHgpOw0KKwlpZiAo cmV0KQ0KKwkJcmV0dXJuIHJldDsNCisNCisJcmV0dXJuIDA7DQorfQ0KKw0KK2ludCBtdGtfZGV2 YXBjX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpkZXYpDQorew0KKwlyZXR1cm4gMDsN Cit9DQorDQorTU9EVUxFX0RFU0NSSVBUSU9OKCJNZWRpYXRlayBEZXZpY2UgQVBDIERyaXZlciIp Ow0KK01PRFVMRV9BVVRIT1IoIk5lYWwgTGl1IDxuZWFsLmxpdUBtZWRpYXRlay5jb20+Iik7DQor TU9EVUxFX0xJQ0VOU0UoIkdQTCIpOw0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvc29jL21lZGlhdGVr L2RldmFwYy9kZXZhcGMtbXRrLW11bHRpLWFvLmggYi9kcml2ZXJzL3NvYy9tZWRpYXRlay9kZXZh cGMvZGV2YXBjLW10ay1tdWx0aS1hby5oDQpuZXcgZmlsZSBtb2RlIDEwMDY0NA0KaW5kZXggMDAw MDAwMC4uMWU1OGEzZQ0KLS0tIC9kZXYvbnVsbA0KKysrIGIvZHJpdmVycy9zb2MvbWVkaWF0ZWsv ZGV2YXBjL2RldmFwYy1tdGstbXVsdGktYW8uaA0KQEAgLTAsMCArMSwxODIgQEANCisvKiBTUERY LUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMCAqLw0KKy8qDQorICogQ29weXJpZ2h0IChDKSAy MDIwIE1lZGlhVGVrIEluYy4NCisgKi8NCisNCisjaWZuZGVmIF9fREVWQVBDX01US19NVUxUSV9B T19IX18NCisjZGVmaW5lIF9fREVWQVBDX01US19NVUxUSV9BT19IX18NCisNCisjaW5jbHVkZSA8 bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+DQorI2luY2x1ZGUgPGxpbnV4L3R5cGVzLmg+DQorDQor LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKg0KKyAqIFZBUklBQkxFIERFRklOQVRJT04NCisgKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqLw0KKyNkZWZpbmUgTU9EX05PX0lOXzFfREVWQVBDCTE2DQorI2RlZmlu ZSBWSU9MQVRJT05fVFJJR0dFUkVECTENCisjZGVmaW5lIFZJT0xBVElPTl9NQVNLRUQJMQ0KKyNk ZWZpbmUgREVBRAkJCTB4ZGVhZGJlYWYNCisjZGVmaW5lIFBGWAkJCSJbREVWQVBDXTogIg0KKyNk ZWZpbmUgU0xBVkVfVFlQRV9OVU1fTUFYCTUNCisNCisjZGVmaW5lIGRldmFwY19sb2cocCwgcywg Zm10LCBhcmdzLi4uKSBcDQorCWRvIHsgXA0KKwkJdHlwZW9mKHApIChfcCkgPSAocCk7IFwNCisJ CSgoX3ApICs9IHNjbnByaW50ZihfcCwgc2l6ZW9mKHMpIC0gc3RybGVuKHMpLCBmbXQsICMjYXJn cykpOyBcDQorCX0gd2hpbGUgKDApDQorDQorI2RlZmluZSBVTlVTRUQoeCkJCSh2b2lkKSh4KQ0K Kw0KKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioNCisgKiBEQVRBIFNUUlVDVFVSRSAmIEZVTkNUSU9O IERFRklOQVRJT04NCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLw0KK2VudW0gREVWQVBDX1BEX1JF R19UWVBFIHsNCisJVklPX01BU0sgPSAwLA0KKwlWSU9fU1RBLA0KKwlWSU9fREJHMCwNCisJVklP X0RCRzEsDQorCVZJT19EQkcyLA0KKwlBUENfQ09OLA0KKwlWSU9fU0hJRlRfU1RBLA0KKwlWSU9f U0hJRlRfU0VMLA0KKwlWSU9fU0hJRlRfQ09OLA0KKwlQRF9SRUdfVFlQRV9OVU0sDQorfTsNCisN CitlbnVtIERFVkFQQ19VVF9DTUQgew0KKwlERVZBUENfVVRfREFQQ19WSU8gPSAxLA0KKwlERVZB UENfVVRfU1JBTV9WSU8sDQorfTsNCisNCitlbnVtIERFVkFQQ19ET01fSUQgew0KKwlET01BSU5f MCA9IDAsDQorCURPTUFJTl8xLA0KKwlET01BSU5fMiwNCisJRE9NQUlOXzMsDQorCURPTUFJTl80 LA0KKwlET01BSU5fNSwNCisJRE9NQUlOXzYsDQorCURPTUFJTl83LA0KKwlET01BSU5fOCwNCisJ RE9NQUlOXzksDQorCURPTUFJTl8xMCwNCisJRE9NQUlOXzExLA0KKwlET01BSU5fMTIsDQorCURP TUFJTl8xMywNCisJRE9NQUlOXzE0LA0KKwlET01BSU5fMTUsDQorCURPTUFJTl9PVEhFUlMsDQor fTsNCisNCitlbnVtIFNSQU1ST01fVklPIHsNCisJUk9NX1ZJT0xBVElPTiA9IDAsDQorCVNSQU1f VklPTEFUSU9OLA0KK307DQorDQorZW51bSBERVZBUENfUEVSTV9UWVBFIHsNCisJTk9fUFJPVEVD VElPTiA9IDAsDQorCVNFQ19SV19PTkxZLA0KKwlTRUNfUldfTlNfUiwNCisJRk9SQklEREVOLA0K KwlQRVJNX1RZUEVfTlVNLA0KK307DQorDQorc3RydWN0IG10a19kZXZhcGNfZGJnX3N0YXR1cyB7 DQorCWJvb2wgZW5hYmxlX3V0Ow0KKwlib29sIGVuYWJsZV9kYXBjOyAvKiBkdW1wIEFQQyAqLw0K K307DQorDQorc3RydWN0IG10a19kZXZpY2VfaW5mbyB7DQorCWludCBzeXNfaW5kZXg7DQorCWlu dCBjdHJsX2luZGV4Ow0KKwlpbnQgdmlvX2luZGV4Ow0KK307DQorDQorc3RydWN0IG10a19kZXZp Y2VfbnVtIHsNCisJaW50IHNsYXZlX3R5cGU7DQorCXUzMiB2aW9fc2xhdmVfbnVtOw0KK307DQor DQorc3RydWN0IG10a19kZXZhcGNfdmlvX2luZm8gew0KKwlib29sIHJlYWQ7DQorCWJvb2wgd3Jp dGU7DQorCXUzMiB2aW9fYWRkcjsNCisJdTMyIHZpb19hZGRyX2hpZ2g7DQorCXUzMiBtYXN0ZXJf aWQ7DQorCXUzMiBkb21haW5faWQ7DQorCWludCAqdmlvX21hc2tfc3RhX251bTsNCisJaW50IHNy YW1yb21fc2x2X3R5cGU7DQorCWludCBzcmFtcm9tX3Zpb19pZHg7DQorCWludCBtbTJuZF9zbHZf dHlwZTsNCisJaW50IG1kcF92aW9faWR4Ow0KKwlpbnQgZGlzcDJfdmlvX2lkeDsNCisJaW50IG1t c3lzX3Zpb19pZHg7DQorCWludCBzaGlmdF9zdGFfYml0Ow0KK307DQorDQorc3RydWN0IG10a19p bmZyYV92aW9fZGJnX2Rlc2Mgew0KKwl1MzIgdmlvX2RiZ19tc3RpZDsNCisJdTggdmlvX2RiZ19t c3RpZF9zdGFydF9iaXQ7DQorCXUzMiB2aW9fZGJnX2RtbmlkOw0KKwl1OCB2aW9fZGJnX2Rtbmlk X3N0YXJ0X2JpdDsNCisJdTMyIHZpb19kYmdfd192aW87DQorCXU4IHZpb19kYmdfd192aW9fc3Rh cnRfYml0Ow0KKwl1MzIgdmlvX2RiZ19yX3ZpbzsNCisJdTggdmlvX2RiZ19yX3Zpb19zdGFydF9i aXQ7DQorCXUzMiB2aW9fYWRkcl9oaWdoOw0KKwl1OCB2aW9fYWRkcl9oaWdoX3N0YXJ0X2JpdDsN Cit9Ow0KKw0KK3N0cnVjdCBtdGtfc3JhbXJvbV9zZWNfdmlvX2Rlc2Mgew0KKwl1MzIgdmlvX2lk X21hc2s7DQorCXU4IHZpb19pZF9zaGlmdDsNCisJdTMyIHZpb19kb21haW5fbWFzazsNCisJdTgg dmlvX2RvbWFpbl9zaGlmdDsNCisJdTMyIHZpb19yd19tYXNrOw0KKwl1OCB2aW9fcndfc2hpZnQ7 DQorfTsNCisNCitzdHJ1Y3QgbXRrX2RldmFwY19wZF9kZXNjIHsNCisJdTMyIHBkX3Zpb19tYXNr X29mZnNldDsNCisJdTMyIHBkX3Zpb19zdGFfb2Zmc2V0Ow0KKwl1MzIgcGRfdmlvX2RiZzBfb2Zm c2V0Ow0KKwl1MzIgcGRfdmlvX2RiZzFfb2Zmc2V0Ow0KKwl1MzIgcGRfYXBjX2Nvbl9vZmZzZXQ7 DQorCXUzMiBwZF9zaGlmdF9zdGFfb2Zmc2V0Ow0KKwl1MzIgcGRfc2hpZnRfc2VsX29mZnNldDsN CisJdTMyIHBkX3NoaWZ0X2Nvbl9vZmZzZXQ7DQorfTsNCisNCitzdHJ1Y3QgbXRrX2RldmFwY19z b2Mgew0KKwlzdHJ1Y3QgbXRrX2RldmFwY19kYmdfc3RhdHVzICpkYmdfc3RhdDsNCisJY29uc3Qg Y2hhciAqIGNvbnN0ICpzbGF2ZV90eXBlX2FycjsNCisJdTMyIHNsYXZlX3R5cGVfbnVtOw0KKwlj b25zdCBzdHJ1Y3QgbXRrX2RldmljZV9pbmZvICpkZXZpY2VfaW5mb1tTTEFWRV9UWVBFX05VTV9N QVhdOw0KKwljb25zdCBzdHJ1Y3QgbXRrX2RldmljZV9udW0gKm5kZXZpY2VzOw0KKwlzdHJ1Y3Qg bXRrX2RldmFwY192aW9faW5mbyAqdmlvX2luZm87DQorCWNvbnN0IHN0cnVjdCBtdGtfaW5mcmFf dmlvX2RiZ19kZXNjICp2aW9fZGJnczsNCisJY29uc3Qgc3RydWN0IG10a19zcmFtcm9tX3NlY192 aW9fZGVzYyAqc3JhbXJvbV9zZWNfdmlvczsNCisJY29uc3QgdTMyICpkZXZhcGNfcGRzOw0KKw0K KwkvKiBwbGF0Zm9ybSBzcGVjaWZpYyBvcGVyYXRpb25zICovDQorCWNvbnN0IGNoYXIqICgqbWFz dGVyX2dldCkodTMyIGJ1c19pZCwgdTMyIHZpb19hZGRyLA0KKwkJCQkgIGludCBzbGF2ZV90eXBl LCBpbnQgc2hpZnRfc3RhX2JpdCwNCisJCQkJICBpbnQgZG9tYWluKTsNCisJdm9pZCAoKm1tMm5k X3Zpb19oYW5kbGVyKSh2b2lkIF9faW9tZW0gKmluZnJhY2ZnLA0KKwkJCQkgIHN0cnVjdCBtdGtf ZGV2YXBjX3Zpb19pbmZvICp2aW9faW5mbywNCisJCQkJICBib29sIG1kcF92aW8sIGJvb2wgZGlz cDJfdmlvLCBib29sIG1tc3lzX3Zpbyk7DQorCXUzMiAoKnNoaWZ0X2dyb3VwX2dldCkoaW50IHNs YXZlX3R5cGUsIHUzMiB2aW9faW5kZXgpOw0KK307DQorDQorc3RydWN0IG10a19kZXZhcGNfY29u dGV4dCB7DQorCXN0cnVjdCBjbGsgKmRldmFwY19pbmZyYV9jbGs7DQorCXUzMiBkZXZhcGNfaXJx Ow0KKwl2b2lkIF9faW9tZW0gKmRldmFwY19wZF9iYXNlWzRdOw0KKwl2b2lkIF9faW9tZW0gKmlu ZnJhY2ZnX2Jhc2U7DQorCXN0cnVjdCBtdGtfZGV2YXBjX3NvYyAqc29jOw0KK307DQorDQoraW50 IG10a19kZXZhcGNfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldiwgc3RydWN0IG10 a19kZXZhcGNfc29jICpzb2MpOw0KK2ludCBtdGtfZGV2YXBjX3JlbW92ZShzdHJ1Y3QgcGxhdGZv cm1fZGV2aWNlICpkZXYpOw0KKw0KKyNlbmRpZiAvKiBfX0RFVkFQQ19NVEtfTVVMVElfQU9fSF9f ICovDQotLSANCjEuNy45LjUNCg== From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.7 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 07A24C433E0 for ; Fri, 19 Jun 2020 10:01:52 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C5BE620739 for ; Fri, 19 Jun 2020 10:01:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="NlW+zirU"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="lxIKatnx" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C5BE620739 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=cvoJqf1LSLTxa2VgORdoWqIyNzjNAceFJsQRedyj1sY=; b=NlW+zirUBcBo93 QGg4kQvC2L1AiEJkv2EJKjmkNPGjfdEaXwcl13zKxtxFVGdIGqqNf4jDR4kioiYsDOdJ7hF2idc/5 ls+hy0qZMXGUH2Q+6Qgsi565IuTczX0W+L78vEvkbMc58EhvRLIvMLjPoQ0MqAbsi5TCZbc3/UXUs X1ffkikeUsFFjXt7EHKKJLb/Yw4TCFmmJsCdR/GYyaREq/v3JHL1rUUjs1UiKHG0kF0CMYCkHYNCE svlfdqkcxuA/bLfQ8hDpdtveqdxsK7uPvC0NJzQY5HGAZSJZnclToILXPpNe6/DfuLK4f2v3UXkM9 TcsqUxdc+GAVfwoGe/CQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jmDgR-0005cA-Kp; Fri, 19 Jun 2020 09:51:39 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jmDfk-00056o-3n; Fri, 19 Jun 2020 09:51:00 +0000 X-UUID: 505ecbfd68ed4db4835c4a837dedc3f6-20200619 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=xmg1w3ypX4AvT1+i24MnshAnpwzBsGKjigr9tp4Uf7E=; b=lxIKatnx5Z+RsisdwUs86yNdT7R3ChAuisRRAcOSmvnPyuuGdgnr4UO3QWqb8HbOjDkAlGmqqzypQ7vQHixlMEMa7PE1R74yvwld494sLB5Acbs2noDI8lXgEm0jAx5llt+CrQ8PGJaXs6oMuPKO9y849qgBwTkdJ+Cn604xiK0=; X-UUID: 505ecbfd68ed4db4835c4a837dedc3f6-20200619 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 1307300018; Fri, 19 Jun 2020 01:51:40 -0800 Received: from MTKMBS02N2.mediatek.inc (172.21.101.101) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 19 Jun 2020 02:42:20 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs02n2.mediatek.inc (172.21.101.101) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 19 Jun 2020 17:42:03 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 19 Jun 2020 17:42:02 +0800 From: Neal Liu To: Rob Herring , Matthias Brugger Subject: [PATCH v2 2/2] soc: mediatek: devapc: add devapc-mt6873 driver Date: Fri, 19 Jun 2020 17:42:00 +0800 Message-ID: <1592559720-8482-3-git-send-email-neal.liu@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1592559720-8482-1-git-send-email-neal.liu@mediatek.com> References: <1592559720-8482-1-git-send-email-neal.liu@mediatek.com> MIME-Version: 1.0 X-TM-SNTS-SMTP: E0B163962F1135967F8C685B03557F40BC5F0C13593F6F8072F8DD8B2E6A36CD2000:8 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200619_025056_186851_6F4A0387 X-CRM114-Status: GOOD ( 14.75 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, wsd_upstream@mediatek.com, linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, Neal Liu , linux-arm-kernel@lists.infradead.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org MT6873 bus frabric provides TrustZone security support and data protection to prevent slaves from being accessed by unexpected masters. The security violations are logged and sent to the processor for further analysis or countermeasures. Any occurrence of security violation would raise an interrupt, and it will be handled by devapc-mt6873 driver. The violation information is printed in order to find the murderer. Signed-off-by: Neal Liu --- drivers/soc/mediatek/Kconfig | 6 + drivers/soc/mediatek/Makefile | 1 + drivers/soc/mediatek/devapc/Kconfig | 25 + drivers/soc/mediatek/devapc/Makefile | 13 + drivers/soc/mediatek/devapc/devapc-mt6873.c | 1652 +++++++++++++++++++++ drivers/soc/mediatek/devapc/devapc-mt6873.h | 111 ++ drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.c | 756 ++++++++++ drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.h | 182 +++ 8 files changed, 2746 insertions(+) create mode 100644 drivers/soc/mediatek/devapc/Kconfig create mode 100644 drivers/soc/mediatek/devapc/Makefile create mode 100644 drivers/soc/mediatek/devapc/devapc-mt6873.c create mode 100644 drivers/soc/mediatek/devapc/devapc-mt6873.h create mode 100644 drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.c create mode 100644 drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.h diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig index 59a56cd..2c9ad1f 100644 --- a/drivers/soc/mediatek/Kconfig +++ b/drivers/soc/mediatek/Kconfig @@ -51,4 +51,10 @@ config MTK_MMSYS Say yes here to add support for the MediaTek Multimedia Subsystem (MMSYS). +menu "Security" + +source "drivers/soc/mediatek/devapc/Kconfig" + +endmenu # Security + endmenu diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile index 01f9f87..d6717a81 100644 --- a/drivers/soc/mediatek/Makefile +++ b/drivers/soc/mediatek/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o +obj-$(CONFIG_MTK_DEVAPC) += devapc/ obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o diff --git a/drivers/soc/mediatek/devapc/Kconfig b/drivers/soc/mediatek/devapc/Kconfig new file mode 100644 index 0000000..9428360 --- /dev/null +++ b/drivers/soc/mediatek/devapc/Kconfig @@ -0,0 +1,25 @@ +config MTK_DEVAPC + tristate "Mediatek Device APC Support" + help + Device APC is a kernel driver controlling internal device security. + If someone tries to access a device, which is not allowed by the + device, it cannot access the device and will get a violation + interrupt. Device APC prevents malicious access to internal devices. + +config DEVAPC_ARCH_MULTI + tristate "Mediatek Device APC driver architecture multi" + help + Say yes here to enable support Mediatek + Device APC driver which is based on Infra + architecture. + This architecture supports multiple Infra AO. + +config DEVAPC_MT6873 + tristate "Mediatek MT6873 Device APC driver" + select MTK_DEVAPC + select DEVAPC_ARCH_MULTI + help + Say yes here to enable support Mediatek MT6873 + Device APC driver. + This driver is combined with DEVAPC_ARCH_MULTI for + common handle flow. diff --git a/drivers/soc/mediatek/devapc/Makefile b/drivers/soc/mediatek/devapc/Makefile new file mode 100644 index 0000000..bd471f2 --- /dev/null +++ b/drivers/soc/mediatek/devapc/Makefile @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 + +ifeq ($(CONFIG_MTK_GCOV_KERNEL),y) +GCOV_PROFILE := y +endif + +obj-$(CONFIG_MTK_DEVAPC) := devapc.o + +# Core +devapc-$(CONFIG_DEVAPC_ARCH_MULTI) += devapc-mtk-multi-ao.o + +# Platform +devapc-$(CONFIG_DEVAPC_MT6873) += devapc-mt6873.o diff --git a/drivers/soc/mediatek/devapc/devapc-mt6873.c b/drivers/soc/mediatek/devapc/devapc-mt6873.c new file mode 100644 index 0000000..75a2140 --- /dev/null +++ b/drivers/soc/mediatek/devapc/devapc-mt6873.c @@ -0,0 +1,1652 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 MediaTek Inc. + */ + +#include +#include +#include +#include +#include + +#include "devapc-mt6873.h" +#include "devapc-mtk-multi-ao.h" + +static struct mtk_device_info mt6873_devices_infra[] = { + /* sys_idx, ctrl_idx, vio_idx */ + /* 0 */ + {0, 0, 0}, + {0, 1, 1}, + {0, 2, 2}, + {0, 3, 3}, + {0, 4, 4}, + {0, 5, 5}, + {0, 6, 6}, + {0, 7, 7}, + {0, 8, 8}, + {0, 9, 9}, + + /* 10 */ + {0, 10, 10}, + {0, 11, 11}, + {0, 12, 12}, + {0, 13, 13}, + {0, 14, 14}, + {0, 15, 15}, + {0, 16, 16}, + {0, 17, 17}, + {0, 18, 18}, + {0, 19, 19}, + + /* 20 */ + {0, 20, 20}, + {0, 21, 21}, + {0, 22, 352}, + {1, 0, 22}, + {1, 1, 23}, + {1, 2, 24}, + {1, 3, 25}, + {1, 4, 26}, + {1, 5, 27}, + {1, 6, 28}, + + /* 30 */ + {1, 7, 29}, + {1, 8, 30}, + {1, 9, 31}, + {1, 10, 32}, + {1, 11, 33}, + {1, 12, 34}, + {1, 13, 35}, + {1, 14, 36}, + {1, 15, 37}, + {1, 16, 38}, + + /* 40 */ + {1, 17, 39}, + {1, 18, 40}, + {1, 19, 41}, + {1, 20, 42}, + {1, 21, 43}, + {1, 22, 44}, + {1, 23, 45}, + {1, 24, 46}, + {1, 25, 47}, + {1, 26, 48}, + + /* 50 */ + {1, 27, 49}, + {1, 28, 50}, + {1, 29, 51}, + {1, 30, 52}, + {1, 31, 53}, + {1, 32, 54}, + {1, 33, 55}, + {1, 34, 56}, + {1, 35, 57}, + {1, 36, 58}, + + /* 60 */ + {1, 37, 59}, + {1, 38, 60}, + {1, 39, 61}, + {1, 40, 62}, + {1, 41, 63}, + {1, 42, 64}, + {1, 43, 65}, + {1, 44, 66}, + {1, 45, 67}, + {1, 46, 68}, + + /* 70 */ + {1, 47, 69}, + {1, 48, 70}, + {1, 49, 71}, + {1, 50, 72}, + {1, 51, 73}, + {1, 52, 74}, + {1, 53, 75}, + {1, 54, 76}, + {1, 55, 77}, + {1, 56, 78}, + + /* 80 */ + {1, 57, 79}, + {1, 58, 80}, + {1, 59, 81}, + {1, 60, 82}, + {1, 61, 83}, + {1, 62, 84}, + {1, 63, 85}, + {1, 64, 86}, + {1, 65, 87}, + {1, 66, 88}, + + /* 90 */ + {1, 67, 89}, + {1, 68, 90}, + {1, 69, 91}, + {1, 70, 92}, + {1, 71, 93}, + {1, 72, 94}, + {1, 73, 95}, + {1, 74, 96}, + {1, 75, 97}, + {1, 76, 98}, + + /* 100 */ + {1, 77, 99}, + {1, 78, 100}, + {1, 79, 101}, + {1, 80, 102}, + {1, 81, 103}, + {1, 82, 104}, + {1, 83, 105}, + {1, 84, 106}, + {1, 85, 107}, + {1, 86, 108}, + + /* 110 */ + {1, 87, 109}, + {1, 88, 110}, + {1, 89, 111}, + {1, 90, 112}, + {1, 91, 113}, + {1, 92, 114}, + {1, 93, 115}, + {1, 94, 116}, + {1, 95, 117}, + {1, 96, 118}, + + /* 120 */ + {1, 97, 119}, + {1, 98, 120}, + {1, 99, 121}, + {1, 100, 122}, + {1, 101, 123}, + {1, 102, 124}, + {1, 103, 125}, + {1, 104, 126}, + {1, 105, 127}, + {1, 106, 128}, + + /* 130 */ + {1, 107, 129}, + {1, 108, 130}, + {1, 109, 131}, + {1, 110, 132}, + {1, 111, 133}, + {1, 112, 134}, + {1, 113, 135}, + {1, 114, 136}, + {1, 115, 137}, + {1, 116, 138}, + + /* 140 */ + {1, 117, 139}, + {1, 118, 140}, + {1, 119, 141}, + {1, 120, 142}, + {1, 121, 143}, + {1, 122, 144}, + {1, 123, 145}, + {1, 124, 146}, + {1, 125, 147}, + {1, 126, 148}, + + /* 150 */ + {1, 127, 149}, + {1, 128, 150}, + {1, 129, 151}, + {1, 130, 152}, + {1, 131, 153}, + {1, 132, 154}, + {1, 133, 155}, + {1, 134, 156}, + {1, 135, 157}, + {1, 136, 158}, + + /* 160 */ + {1, 137, 159}, + {1, 138, 160}, + {1, 139, 161}, + {1, 140, 162}, + {1, 141, 163}, + {1, 142, 164}, + {1, 143, 165}, + {1, 144, 166}, + {1, 145, 167}, + {1, 146, 168}, + + /* 170 */ + {1, 147, 169}, + {1, 148, 170}, + {1, 149, 171}, + {1, 150, 172}, + {1, 151, 173}, + {1, 152, 174}, + {1, 153, 175}, + {1, 154, 176}, + {1, 155, 177}, + {1, 156, 178}, + + /* 180 */ + {1, 157, 179}, + {1, 158, 180}, + {1, 159, 181}, + {1, 160, 182}, + {1, 161, 183}, + {1, 162, 184}, + {1, 163, 185}, + {1, 164, 186}, + {1, 165, 187}, + {1, 166, 188}, + + /* 190 */ + {1, 167, 189}, + {1, 168, 190}, + {1, 169, 191}, + {1, 170, 192}, + {1, 171, 193}, + {1, 172, 194}, + {1, 173, 195}, + {1, 174, 196}, + {1, 175, 197}, + {1, 176, 198}, + + /* 200 */ + {1, 177, 199}, + {1, 178, 200}, + {1, 179, 201}, + {1, 180, 202}, + {1, 181, 203}, + {1, 182, 204}, + {1, 183, 205}, + {1, 184, 206}, + {1, 185, 207}, + {1, 186, 208}, + + /* 210 */ + {1, 187, 209}, + {1, 188, 210}, + {1, 189, 211}, + {1, 190, 212}, + {1, 191, 213}, + {1, 192, 214}, + {1, 193, 215}, + {1, 194, 216}, + {1, 195, 217}, + {1, 196, 218}, + + /* 220 */ + {1, 197, 219}, + {1, 198, 220}, + {1, 199, 221}, + {1, 200, 222}, + {1, 201, 223}, + {1, 202, 224}, + {1, 203, 225}, + {1, 204, 226}, + {1, 205, 227}, + {1, 206, 228}, + + /* 230 */ + {1, 207, 229}, + {1, 208, 230}, + {1, 209, 231}, + {1, 210, 232}, + {1, 211, 233}, + {1, 212, 234}, + {1, 213, 235}, + {1, 214, 236}, + {1, 215, 237}, + {1, 216, 238}, + + /* 240 */ + {1, 217, 239}, + {1, 218, 240}, + {1, 219, 241}, + {1, 220, 242}, + {1, 221, 243}, + {1, 222, 244}, + {1, 223, 245}, + {1, 224, 246}, + {1, 225, 247}, + {1, 226, 248}, + + /* 250 */ + {1, 227, 249}, + {1, 228, 250}, + {1, 229, 251}, + {1, 230, 252}, + {1, 231, 253}, + {1, 232, 254}, + {1, 233, 255}, + {1, 234, 256}, + {1, 235, 257}, + {1, 236, 258}, + + /* 260 */ + {1, 237, 259}, + {1, 238, 260}, + {1, 239, 261}, + {1, 240, 262}, + {1, 241, 263}, + {1, 242, 264}, + {1, 243, 265}, + {1, 244, 266}, + {1, 245, 267}, + {1, 246, 268}, + + /* 270 */ + {1, 247, 269}, + {1, 248, 270}, + {1, 249, 271}, + {1, 250, 272}, + {1, 251, 273}, + {1, 252, 274}, + {1, 253, 275}, + {1, 254, 276}, + {1, 255, 277}, + {2, 0, 278}, + + /* 280 */ + {2, 1, 279}, + {2, 2, 280}, + {2, 3, 281}, + {2, 4, 282}, + {2, 5, 283}, + {2, 6, 284}, + {2, 7, 285}, + {2, 8, 286}, + {2, 9, 287}, + {2, 10, 288}, + + /* 290 */ + {2, 11, 289}, + {2, 12, 290}, + {2, 13, 291}, + {2, 14, 292}, + {2, 15, 293}, + {2, 16, 294}, + {2, 17, 295}, + {2, 18, 296}, + {2, 19, 297}, + {2, 20, 298}, + + /* 300 */ + {2, 21, 299}, + {2, 22, 300}, + {2, 23, 301}, + {2, 24, 302}, + {2, 25, 303}, + {2, 26, 304}, + {2, 27, 305}, + {2, 28, 306}, + {2, 29, 307}, + {2, 30, 308}, + + /* 310 */ + {2, 31, 309}, + {2, 32, 310}, + {2, 33, 311}, + {2, 34, 312}, + {2, 35, 313}, + {2, 36, 314}, + {2, 37, 315}, + {2, 38, 316}, + {2, 39, 317}, + {2, 40, 318}, + + /* 320 */ + {2, 41, 319}, + {2, 42, 320}, + {2, 43, 321}, + {2, 44, 322}, + {2, 45, 323}, + {2, 46, 324}, + {2, 47, 325}, + {2, 48, 326}, + {2, 49, 327}, + {2, 50, 328}, + + /* 330 */ + {2, 51, 329}, + {2, 52, 330}, + {2, 53, 331}, + {2, 54, 332}, + {2, 55, 333}, + {2, 56, 334}, + {2, 57, 335}, + {2, 58, 336}, + {2, 59, 337}, + {2, 60, 338}, + + /* 340 */ + {2, 61, 339}, + {2, 62, 340}, + {2, 63, 341}, + {2, 64, 342}, + {2, 65, 343}, + {2, 66, 344}, + {2, 67, 345}, + {2, 68, 346}, + {2, 69, 347}, + {-1, -1, 355}, + + /* 350 */ + {-1, -1, 356}, + {-1, -1, 357}, + {-1, -1, 358}, + {-1, -1, 359}, + {-1, -1, 360}, + {-1, -1, 361}, + {-1, -1, 362}, + {-1, -1, 363}, + {-1, -1, 364}, + {-1, -1, 365}, + + /* 360 */ + {-1, -1, 366}, + {-1, -1, 367}, + {-1, -1, 368}, + {-1, -1, 369}, + {-1, -1, 370}, + {-1, -1, 371}, + +}; + +static struct mtk_device_info mt6873_devices_peri[] = { + /* sys_idx, ctrl_idx, vio_idx */ + /* 0 */ + {0, 0, 0}, + {0, 1, 1}, + {0, 2, 2}, + {0, 3, 3}, + {0, 4, 4}, + {0, 5, 5}, + {0, 6, 6}, + {0, 7, 7}, + {0, 8, 8}, + {0, 9, 9}, + + /* 10 */ + {0, 10, 10}, + {0, 11, 11}, + {0, 12, 13}, + {0, 13, 14}, + {0, 14, 15}, + {0, 15, 16}, + {0, 16, 17}, + {0, 17, 18}, + {0, 18, 19}, + {0, 19, 20}, + + /* 20 */ + {0, 20, 21}, + {0, 21, 23}, + {0, 22, 24}, + {0, 23, 25}, + {0, 24, 26}, + {0, 25, 27}, + {0, 26, 28}, + {0, 27, 29}, + {0, 28, 30}, + {0, 29, 31}, + + /* 30 */ + {0, 30, 32}, + {0, 31, 33}, + {0, 32, 34}, + {0, 33, 35}, + {0, 34, 36}, + {0, 35, 37}, + {0, 36, 38}, + {0, 37, 62}, + {0, 38, 63}, + {0, 39, 64}, + + /* 40 */ + {0, 40, 65}, + {0, 41, 66}, + {0, 42, 67}, + {0, 43, 68}, + {0, 44, 69}, + {0, 45, 70}, + {0, 46, 71}, + {0, 47, 72}, + {0, 48, 73}, + {0, 49, 74}, + + /* 50 */ + {0, 50, 119}, + {0, 51, 120}, + {0, 52, 121}, + {0, 53, 122}, + {0, 54, 123}, + {0, 55, 124}, + {0, 56, 125}, + {0, 57, 126}, + {0, 58, 127}, + {0, 59, 128}, + + /* 60 */ + {0, 60, 129}, + {0, 61, 130}, + {0, 62, 137}, + {0, 63, 143}, + {0, 64, 144}, + {0, 65, 145}, + {0, 66, 146}, + {0, 67, 147}, + {0, 68, 148}, + {0, 69, 149}, + + /* 70 */ + {0, 70, 150}, + {0, 71, 151}, + {0, 72, 152}, + {0, 73, 153}, + {0, 74, 154}, + {0, 75, 155}, + {0, 76, 156}, + {0, 77, 157}, + {0, 78, 158}, + {0, 79, 159}, + + /* 80 */ + {0, 80, 160}, + {0, 81, 161}, + {0, 82, 162}, + {0, 83, 163}, + {0, 84, 164}, + {0, 85, 165}, + {0, 86, 166}, + {0, 87, 167}, + {0, 88, 168}, + {0, 89, 169}, + + /* 90 */ + {0, 90, 170}, + {0, 91, 171}, + {0, 92, 174}, + {0, 93, 175}, + {0, 94, 176}, + {0, 95, 177}, + {0, 96, 178}, + {0, 97, 179}, + {0, 98, 180}, + {0, 99, 181}, + + /* 100 */ + {0, 100, 182}, + {0, 101, 183}, + {0, 102, 184}, + {0, 103, 185}, + {0, 104, 186}, + {1, 0, 39}, + {1, 1, 40}, + {1, 2, 41}, + {1, 3, 42}, + {1, 4, 43}, + + /* 110 */ + {1, 5, 44}, + {1, 6, 45}, + {1, 7, 46}, + {1, 8, 47}, + {1, 9, 48}, + {1, 10, 49}, + {1, 11, 50}, + {1, 12, 51}, + {1, 13, 52}, + {1, 14, 53}, + + /* 120 */ + {1, 15, 54}, + {1, 16, 55}, + {1, 17, 56}, + {1, 18, 57}, + {1, 19, 58}, + {1, 20, 59}, + {1, 21, 60}, + {1, 22, 61}, + {1, 23, 76}, + {1, 24, 77}, + + /* 130 */ + {1, 25, 78}, + {1, 26, 79}, + {1, 27, 80}, + {1, 28, 81}, + {1, 29, 82}, + {1, 30, 83}, + {1, 31, 84}, + {1, 32, 85}, + {1, 33, 86}, + {1, 34, 87}, + + /* 140 */ + {1, 35, 88}, + {1, 36, 89}, + {1, 37, 90}, + {1, 38, 91}, + {1, 39, 92}, + {1, 40, 93}, + {1, 41, 94}, + {1, 42, 95}, + {1, 43, 96}, + {1, 44, 97}, + + /* 150 */ + {1, 45, 98}, + {1, 46, 99}, + {1, 47, 100}, + {1, 48, 101}, + {1, 49, 102}, + {1, 50, 103}, + {1, 51, 104}, + {1, 52, 105}, + {1, 53, 106}, + {1, 54, 107}, + + /* 160 */ + {1, 55, 108}, + {1, 56, 109}, + {1, 57, 110}, + {1, 58, 111}, + {1, 59, 112}, + {1, 60, 113}, + {1, 61, 114}, + {1, 62, 115}, + {1, 63, 116}, + {1, 64, 117}, + + /* 170 */ + {1, 65, 118}, + {2, 0, 75}, + {-1, -1, 187}, + {-1, -1, 188}, + {-1, -1, 189}, + {-1, -1, 190}, + {-1, -1, 191}, + {-1, -1, 192}, + {-1, -1, 193}, + {-1, -1, 194}, + + /* 180 */ + {-1, -1, 195}, + {-1, -1, 196}, + {-1, -1, 197}, + {-1, -1, 198}, + {-1, -1, 199}, + {-1, -1, 200}, + {-1, -1, 201}, + {-1, -1, 202}, + {-1, -1, 203}, + {-1, -1, 204}, + + /* 190 */ + {-1, -1, 205}, + {-1, -1, 206}, + {-1, -1, 207}, + {-1, -1, 208}, + {-1, -1, 209}, + {-1, -1, 210}, + {-1, -1, 211}, + {-1, -1, 212}, + {-1, -1, 213}, + {-1, -1, 214}, + + /* 200 */ + {-1, -1, 215}, + {-1, -1, 216}, + {-1, -1, 217}, + {-1, -1, 218}, + {-1, -1, 219}, + {-1, -1, 220}, + {-1, -1, 221}, + {-1, -1, 222}, + {-1, -1, 223}, + {-1, -1, 224}, + + /* 210 */ + {-1, -1, 225}, + {-1, -1, 226}, + {-1, -1, 227}, + {-1, -1, 228}, + {-1, -1, 229}, + {-1, -1, 230}, + {-1, -1, 231}, + {-1, -1, 232}, + {-1, -1, 233}, + {-1, -1, 234}, + + /* 220 */ + {-1, -1, 235}, + {-1, -1, 236}, + {-1, -1, 237}, + {-1, -1, 238}, + {-1, -1, 239}, + {-1, -1, 240}, + {-1, -1, 241}, + {-1, -1, 242}, + {-1, -1, 243}, + {-1, -1, 244}, + + /* 230 */ + {-1, -1, 245}, + {-1, -1, 246}, + {-1, -1, 247}, + {-1, -1, 248}, + {-1, -1, 249}, + {-1, -1, 250}, + {-1, -1, 251}, + {-1, -1, 252}, + {-1, -1, 253}, + {-1, -1, 254}, + + /* 240 */ + {-1, -1, 255}, + {-1, -1, 256}, + {-1, -1, 257}, + {-1, -1, 258}, + {-1, -1, 259}, + {-1, -1, 260}, + {-1, -1, 261}, + {-1, -1, 262}, + {-1, -1, 263}, + {-1, -1, 264}, + + /* 250 */ + {-1, -1, 265}, + {-1, -1, 266}, + {-1, -1, 267}, + {-1, -1, 268}, + {-1, -1, 269}, + {-1, -1, 270}, + {-1, -1, 271}, + {-1, -1, 272}, + {-1, -1, 273}, + {-1, -1, 274}, + + /* 260 */ + {-1, -1, 275}, + {-1, -1, 276}, + {-1, -1, 277}, + {-1, -1, 278}, + {-1, -1, 279}, + {-1, -1, 280}, + {-1, -1, 281}, + {-1, -1, 282}, + {-1, -1, 283}, + {-1, -1, 284}, + + /* 270 */ + {-1, -1, 285}, + {-1, -1, 286}, + {-1, -1, 287}, + {-1, -1, 288}, + {-1, -1, 289}, + {-1, -1, 290}, + {-1, -1, 291}, + {-1, -1, 292}, + {-1, -1, 293}, + {-1, -1, 294}, + + /* 280 */ + {-1, -1, 295}, + {-1, -1, 296}, + {-1, -1, 297}, + {-1, -1, 298}, + +}; + +static struct mtk_device_info mt6873_devices_peri2[] = { + /* sys_idx, ctrl_idx, vio_idx */ + /* 0 */ + {0, 0, 0}, + {0, 1, 1}, + {0, 2, 2}, + {0, 3, 3}, + {0, 4, 4}, + {0, 5, 5}, + {0, 6, 6}, + {0, 7, 7}, + {0, 8, 8}, + {0, 9, 9}, + + /* 10 */ + {0, 10, 10}, + {0, 11, 11}, + {0, 12, 12}, + {0, 13, 13}, + {0, 14, 14}, + {0, 15, 15}, + {0, 16, 16}, + {0, 17, 17}, + {0, 18, 18}, + {0, 19, 19}, + + /* 20 */ + {0, 20, 20}, + {0, 21, 21}, + {0, 22, 22}, + {0, 23, 23}, + {0, 24, 24}, + {0, 25, 25}, + {0, 26, 26}, + {0, 27, 27}, + {0, 28, 28}, + {0, 29, 29}, + + /* 30 */ + {0, 30, 30}, + {0, 31, 31}, + {0, 32, 32}, + {0, 33, 33}, + {0, 34, 34}, + {0, 35, 35}, + {0, 36, 36}, + {0, 37, 37}, + {0, 38, 38}, + {0, 39, 39}, + + /* 40 */ + {0, 40, 40}, + {0, 41, 41}, + {0, 42, 42}, + {0, 43, 43}, + {0, 44, 44}, + {0, 45, 45}, + {0, 46, 46}, + {0, 47, 47}, + {0, 48, 48}, + {0, 49, 49}, + + /* 50 */ + {0, 50, 50}, + {0, 51, 51}, + {0, 52, 52}, + {0, 53, 53}, + {0, 54, 54}, + {0, 55, 55}, + {0, 56, 56}, + {0, 57, 57}, + {0, 58, 58}, + {0, 59, 59}, + + /* 60 */ + {0, 60, 60}, + {0, 61, 61}, + {0, 62, 62}, + {0, 63, 63}, + {0, 64, 64}, + {0, 65, 65}, + {0, 66, 66}, + {0, 67, 67}, + {0, 68, 68}, + {0, 69, 69}, + + /* 70 */ + {0, 70, 70}, + {0, 71, 71}, + {0, 72, 72}, + {0, 73, 73}, + {0, 74, 74}, + {0, 75, 75}, + {0, 76, 76}, + {0, 77, 77}, + {0, 78, 78}, + {0, 79, 79}, + + /* 80 */ + {0, 80, 80}, + {0, 81, 81}, + {0, 82, 82}, + {0, 83, 83}, + {0, 84, 84}, + {0, 85, 85}, + {0, 86, 86}, + {0, 87, 87}, + {0, 88, 88}, + {0, 89, 89}, + + /* 90 */ + {0, 90, 90}, + {0, 91, 91}, + {0, 92, 92}, + {0, 93, 93}, + {0, 94, 94}, + {0, 95, 95}, + {0, 96, 96}, + {0, 97, 97}, + {0, 98, 98}, + {0, 99, 99}, + + /* 100 */ + {0, 100, 100}, + {0, 101, 103}, + {0, 102, 104}, + {0, 103, 105}, + {0, 104, 106}, + {0, 105, 107}, + {0, 106, 108}, + {0, 107, 109}, + {0, 108, 110}, + {0, 109, 111}, + + /* 110 */ + {0, 110, 112}, + {0, 111, 113}, + {0, 112, 114}, + {0, 113, 115}, + {0, 114, 116}, + {-1, -1, 117}, + {-1, -1, 118}, + {-1, -1, 119}, + {-1, -1, 120}, + {-1, -1, 121}, + + /* 120 */ + {-1, -1, 122}, + {-1, -1, 123}, + {-1, -1, 124}, + {-1, -1, 125}, + {-1, -1, 126}, + {-1, -1, 127}, + {-1, -1, 128}, + {-1, -1, 129}, + {-1, -1, 130}, + {-1, -1, 131}, + + /* 130 */ + {-1, -1, 132}, + {-1, -1, 133}, + {-1, -1, 134}, + {-1, -1, 135}, + {-1, -1, 136}, + {-1, -1, 137}, + {-1, -1, 138}, + {-1, -1, 139}, + {-1, -1, 140}, + {-1, -1, 141}, + + /* 140 */ + {-1, -1, 142}, + {-1, -1, 143}, + {-1, -1, 144}, + {-1, -1, 145}, + {-1, -1, 146}, + {-1, -1, 147}, + {-1, -1, 148}, + {-1, -1, 149}, + {-1, -1, 150}, + {-1, -1, 151}, + + /* 150 */ + {-1, -1, 152}, + {-1, -1, 153}, + {-1, -1, 154}, + {-1, -1, 155}, + {-1, -1, 156}, + {-1, -1, 157}, + {-1, -1, 158}, + {-1, -1, 159}, + {-1, -1, 160}, + {-1, -1, 161}, + + /* 160 */ + {-1, -1, 162}, + {-1, -1, 163}, + {-1, -1, 164}, + {-1, -1, 165}, + {-1, -1, 166}, + {-1, -1, 167}, + {-1, -1, 168}, + {-1, -1, 169}, + {-1, -1, 170}, + {-1, -1, 171}, + + /* 170 */ + {-1, -1, 172}, + {-1, -1, 173}, + {-1, -1, 174}, + {-1, -1, 175}, + {-1, -1, 176}, + {-1, -1, 177}, + {-1, -1, 178}, + {-1, -1, 179}, + {-1, -1, 180}, + {-1, -1, 181}, + + /* 180 */ + {-1, -1, 182}, + {-1, -1, 183}, + {-1, -1, 184}, + {-1, -1, 185}, + {-1, -1, 186}, + {-1, -1, 187}, + {-1, -1, 188}, + {-1, -1, 189}, + {-1, -1, 190}, + {-1, -1, 191}, + + /* 190 */ + {-1, -1, 192}, + {-1, -1, 193}, + {-1, -1, 194}, + {-1, -1, 195}, + {-1, -1, 196}, + {-1, -1, 197}, + {-1, -1, 198}, + {-1, -1, 199}, + {-1, -1, 200}, + {-1, -1, 201}, + + /* 200 */ + {-1, -1, 202}, + {-1, -1, 203}, + {-1, -1, 204}, + {-1, -1, 205}, + {-1, -1, 206}, + {-1, -1, 207}, + {-1, -1, 208}, + {-1, -1, 209}, + {-1, -1, 210}, + {-1, -1, 211}, + + /* 210 */ + {-1, -1, 212}, + {-1, -1, 213}, + {-1, -1, 214}, + {-1, -1, 215}, + {-1, -1, 216}, + {-1, -1, 217}, + {-1, -1, 218}, + {-1, -1, 219}, + {-1, -1, 220}, + {-1, -1, 221}, + + /* 220 */ + {-1, -1, 222}, + {-1, -1, 223}, + {-1, -1, 224}, + {-1, -1, 225}, + {-1, -1, 226}, + {-1, -1, 227}, + {-1, -1, 228}, + {-1, -1, 229}, + {-1, -1, 230}, + {-1, -1, 231}, + + /* 230 */ + {-1, -1, 232}, + {-1, -1, 233}, + {-1, -1, 234}, + {-1, -1, 235}, + {-1, -1, 236}, + {-1, -1, 237}, + {-1, -1, 238}, + {-1, -1, 239}, + {-1, -1, 240}, + {-1, -1, 241}, + + /* 240 */ + {-1, -1, 242}, + {-1, -1, 243}, + {-1, -1, 244}, + {-1, -1, 245}, + {-1, -1, 246}, + {-1, -1, 247}, + {-1, -1, 248}, + +}; + +static struct mtk_device_info mt6873_devices_peri_par[] = { + /* sys_idx, ctrl_idx, vio_idx */ + /* 0 */ + {0, 0, 0}, + {0, 1, 1}, + {0, 2, 2}, + {0, 3, 3}, + {0, 4, 4}, + {0, 5, 5}, + {0, 6, 6}, + {0, 7, 7}, + {0, 8, 8}, + {0, 9, 9}, + + /* 10 */ + {0, 10, 10}, + {0, 11, 11}, + {0, 12, 12}, + {0, 13, 13}, + {0, 14, 14}, + {0, 15, 15}, + {0, 16, 16}, + {0, 17, 17}, + {0, 18, 18}, + {0, 19, 19}, + + /* 20 */ + {0, 20, 20}, + {0, 21, 21}, + {0, 22, 22}, + {0, 23, 23}, + {0, 24, 24}, + {0, 25, 25}, + {0, 26, 26}, + {-1, -1, 27}, + {-1, -1, 28}, + {-1, -1, 29}, + + /* 30 */ + {-1, -1, 30}, + {-1, -1, 31}, + {-1, -1, 32}, + {-1, -1, 33}, + {-1, -1, 34}, + {-1, -1, 35}, + {-1, -1, 36}, + {-1, -1, 37}, + {-1, -1, 38}, + {-1, -1, 39}, + + /* 40 */ + {-1, -1, 40}, + {-1, -1, 41}, + {-1, -1, 42}, + {-1, -1, 43}, + {-1, -1, 44}, + {-1, -1, 45}, + {-1, -1, 46}, + {-1, -1, 47}, + {-1, -1, 48}, + {-1, -1, 49}, + + /* 50 */ + {-1, -1, 50}, + {-1, -1, 51}, + {-1, -1, 52}, + {-1, -1, 53}, + {-1, -1, 54}, + {-1, -1, 55}, + {-1, -1, 56}, + {-1, -1, 57}, + +}; + +static struct mtk_device_num mtk6873_devices_num[] = { + {SLAVE_TYPE_INFRA, VIO_SLAVE_NUM_INFRA}, + {SLAVE_TYPE_PERI, VIO_SLAVE_NUM_PERI}, + {SLAVE_TYPE_PERI2, VIO_SLAVE_NUM_PERI2}, + {SLAVE_TYPE_PERI_PAR, VIO_SLAVE_NUM_PERI_PAR}, +}; + +static struct INFRAAXI_ID_INFO peri_mi_id_to_master[] = { + {"THERM2", 0x0, 0x7}, + {"SPM", 0x2, 0x7}, + {"CCU", 0x4, 0x7}, + {"THERM", 0x6, 0x7}, + {"SPM_DRAMC", 0x3, 0x7}, +}; + +static struct INFRAAXI_ID_INFO infra_mi_id_to_master[] = { + {"CONNSYS_WFDMA", 0x0, 0x3fff}, + {"CONNSYS_ICAP", 0x10, 0x3fff}, + {"CONNSYS_MCU_SYS", 0x20, 0x3fff}, + {"CONNSYS_GPS", 0x30, 0x3fff}, + {"Tinysys", 0x2, 0x3c0f}, + {"CQ_DMA", 0x4, 0x3c7f}, + {"DebugTop", 0x14, 0x3f7f}, + {"SSUSB", 0x24, 0xfff}, + {"SSUSB2", 0x424, 0xfff}, + {"NOR", 0x824, 0xfff}, + {"PWM", 0xc24, 0x3fff}, + {"SPI6", 0x2c24, 0x3fff}, + {"SPI0", 0x3c24, 0x3fff}, + {"APU", 0xa4, 0x33ff}, + {"SPI2", 0x124, 0x3fff}, + {"SPI3", 0x524, 0x3fff}, + {"SPI4", 0x924, 0x3fff}, + {"SPI5", 0xd24, 0x3fff}, + {"SPI7", 0x1a4, 0x3fff}, + {"Audio", 0x9a4, 0x3fff}, + {"SPI1", 0xda4, 0x3fff}, + {"AP_DMA_EXT", 0x224, 0x23ff}, + {"THERM2", 0x2a4, 0x3fff}, + {"SPM", 0x6a4, 0x3fff}, + {"CCU", 0xaa4, 0x3fff}, + {"THERM", 0xea4, 0x3fff}, + {"DX_CC", 0x34, 0x387f}, + {"GCE", 0x44, 0x3e7f}, + {"PCIE", 0x64, 0x307f}, + {"DPMAIF", 0x6, 0x3f0f}, + {"SSPM", 0x8, 0x3f8f}, + {"UFS", 0xa, 0x3f9f}, + {"MSDC0", 0x1a, 0x3fff}, + {"MSDC1", 0x3a, 0x3fff}, + {"MSDC2", 0x7a, 0x3fff}, + {"CPUEB", 0xc, 0x3c0f}, + {"APMCU_write", 0x1, 0x3fe1}, + {"APMCU_write", 0x81, 0x3fe1}, + {"APMCU_write", 0x201, 0x3e01}, + {"APMCU_read", 0x1, 0x3fe1}, + {"APMCU_read", 0x81, 0x3fe1}, + {"APMCU_read", 0x101, 0x3ffd}, + {"APMCU_read", 0x105, 0x3ffd}, + {"APMCU_read", 0x201, 0x3e01}, + {"APMCU_read", 0x401, 0x3c01}, +}; + +static const char *infra_mi_trans(u32 bus_id) +{ + int master_count = ARRAY_SIZE(infra_mi_id_to_master); + const char *master = "UNKNOWN_MASTER_FROM_INFRA"; + int i; + + for (i = 0; i < master_count; i++) { + if ((bus_id & infra_mi_id_to_master[i].mask) == + infra_mi_id_to_master[i].bus_id) + master = infra_mi_id_to_master[i].master; + } + + return master; +} + +static const char *peri_mi_trans(u32 bus_id) +{ + int master_count = ARRAY_SIZE(peri_mi_id_to_master); + const char *master = "UNKNOWN_MASTER_FROM_PERI"; + int i; + + if ((bus_id & 0x3) == 0x0) + return infra_mi_trans(bus_id >> 2); + else if ((bus_id & 0x3) == 0x2) + return "MD_AP_M"; + else if ((bus_id & 0x3) == 0x3) + return "AP_DMA_M"; + + bus_id = bus_id >> 2; + + for (i = 0 ; i < master_count; i++) { + if ((bus_id & peri_mi_id_to_master[i].mask) == + peri_mi_id_to_master[i].bus_id) + master = infra_mi_id_to_master[i].master; + } + + return master; +} + +static const char *mt6873_bus_id_to_master(u32 bus_id, u32 vio_addr, + int slave_type, int shift_sta_bit, + int domain) +{ + u8 h_1byte; + + if (bus_id == 0x0 && vio_addr == 0x0) + return NULL; + + h_1byte = (vio_addr >> 24) & 0xFF; + + if (slave_type == SLAVE_TYPE_INFRA) { + if (vio_addr <= 0x1FFFFF) { + if ((bus_id & 0x1) == 0) + return "EMI_L2C_M"; + + return infra_mi_trans(bus_id >> 1); + + } else if (shift_sta_bit == 3) { + if ((bus_id & 0x1) == 0) + return "EMI_L2C_M"; + + return infra_mi_trans(bus_id >> 1); + + } else if (shift_sta_bit == 4) { + if ((bus_id & 0x1) == 1) + return "GCE_M"; + + return infra_mi_trans(bus_id >> 1); + } + + return infra_mi_trans(bus_id); + + } else if (slave_type == SLAVE_TYPE_PERI) { + if ((h_1byte >= 0x14 && h_1byte < 0x18) || + (h_1byte >= 0x1A && h_1byte < 0x1C) || + (h_1byte >= 0x1F && h_1byte < 0x20)) { + if ((bus_id & 0x1) == 1) + return "GCE_M"; + + return infra_mi_trans(bus_id >> 1); + } + + if (shift_sta_bit == 3 || shift_sta_bit == 4 || + shift_sta_bit == 8) { + if ((bus_id & 0x1) == 0) + return "MD_AP_M"; + + return peri_mi_trans(bus_id >> 1); + } + return peri_mi_trans(bus_id); + + } else if (slave_type == SLAVE_TYPE_PERI2) { + return peri_mi_trans(bus_id); + + } else if (slave_type == SLAVE_TYPE_PERI_PAR) { + return peri_mi_trans(bus_id); + } + + return "UNKNOWN_MASTER"; +} + +static void mm2nd_vio_handler(void __iomem *infracfg, + struct mtk_devapc_vio_info *vio_info, + bool mdp_vio, bool disp2_vio, bool mmsys_vio) +{ + u32 vio_sta, vio_dbg, rw; + u32 vio_sta_num; + u32 vio0_offset; + char mm_str[64] = {0}; + void __iomem *reg; + int i; + + if (!infracfg) + return; + + if (mdp_vio) { + vio_sta_num = INFRACFG_MDP_VIO_STA_NUM; + vio0_offset = INFRACFG_MDP_SEC_VIO0_OFFSET; + + strncpy(mm_str, "INFRACFG_MDP_SEC_VIO", + sizeof("INFRACFG_MDP_SEC_VIO")); + + } else if (mmsys_vio) { + vio_sta_num = INFRACFG_MM_VIO_STA_NUM; + vio0_offset = INFRACFG_MM_SEC_VIO0_OFFSET; + + strncpy(mm_str, "INFRACFG_MM_SEC_VIO", + sizeof("INFRACFG_MM_SEC_VIO")); + + } else { + pr_err(PFX "%s: param check failed, mdp_vio:%s, disp2_vio:%s, mmsys_vio:%s\n", + __func__, mdp_vio ? "true" : "false", + disp2_vio ? "true" : "false", + mmsys_vio ? "true" : "false"); + return; + } + + /* Get mm2nd violation status */ + for (i = 0; i < vio_sta_num; i++) { + reg = infracfg + vio0_offset + i * 4; + vio_sta = readl(reg); + if (vio_sta) + pr_info(PFX "MM 2nd violation: %s%d:0x%x\n", + mm_str, i, vio_sta); + } + + /* Get mm2nd violation address */ + reg = infracfg + vio0_offset + i * 4; + vio_info->vio_addr = readl(reg); + + /* Get mm2nd violation information */ + reg = infracfg + vio0_offset + (i + 1) * 4; + vio_dbg = readl(reg); + + vio_info->domain_id = (vio_dbg & INFRACFG_MM2ND_VIO_DOMAIN_MASK) >> + INFRACFG_MM2ND_VIO_DOMAIN_SHIFT; + + vio_info->master_id = (vio_dbg & INFRACFG_MM2ND_VIO_ID_MASK) >> + INFRACFG_MM2ND_VIO_ID_SHIFT; + + rw = (vio_dbg & INFRACFG_MM2ND_VIO_RW_MASK) >> + INFRACFG_MM2ND_VIO_RW_SHIFT; + vio_info->read = (rw == 0); + vio_info->write = (rw == 1); +} + +static u32 mt6873_shift_group_get(int slave_type, u32 vio_idx) +{ + if (slave_type == SLAVE_TYPE_INFRA) { + if ((vio_idx >= 0 && vio_idx <= 8) || vio_idx == 355) + return 0; + else if ((vio_idx >= 9 && vio_idx <= 14) || vio_idx == 356) + return 1; + else if ((vio_idx >= 15 && vio_idx <= 19) || vio_idx == 357) + return 2; + else if ((vio_idx >= 20 && vio_idx <= 21) || vio_idx == 358) + return 3; + else if (vio_idx >= 22 && vio_idx <= 347) + return 4; + else if ((vio_idx >= 348 && vio_idx <= 354) || + (vio_idx >= 359 && vio_idx <= 365) || + vio_idx == 366) + return 5; + + pr_err(PFX "%s:%d Wrong vio_idx:0x%x\n", + __func__, __LINE__, vio_idx); + + } else if (slave_type == SLAVE_TYPE_PERI) { + if (vio_idx >= 0 && vio_idx <= 4) + return 0; + else if (vio_idx >= 5 && vio_idx <= 6) + return 1; + else if ((vio_idx >= 7 && vio_idx <= 38) || vio_idx == 187 || + (vio_idx >= 188 && vio_idx <= 219) || + vio_idx == 286) + return 2; + else if ((vio_idx >= 39 && vio_idx <= 61) || vio_idx == 220) + return 3; + else if ((vio_idx >= 62 && vio_idx <= 72) || vio_idx == 221) + return 4; + else if ((vio_idx >= 73 && vio_idx <= 74) || vio_idx == 222) + return 5; + else if (vio_idx == 75 || vio_idx == 223) + return 6; + else if ((vio_idx >= 76 && vio_idx <= 118) || vio_idx == 224) + return 7; + else if ((vio_idx >= 119 && vio_idx <= 121) || vio_idx == 225) + return 8; + if (vio_idx >= 122 && vio_idx <= 125) + return 9; + else if (vio_idx == 126 || (vio_idx >= 226 && vio_idx <= 227) || + vio_idx == 287) + return 10; + if (vio_idx >= 127 && vio_idx <= 128) + return 11; + if (vio_idx >= 129 && vio_idx <= 130) + return 12; + else if ((vio_idx >= 131 && vio_idx <= 141) || + (vio_idx >= 228 && vio_idx <= 238) || + vio_idx == 288) + return 13; + else if ((vio_idx >= 142 && vio_idx <= 143) || + (vio_idx >= 239 && vio_idx <= 240) || + vio_idx == 289) + return 14; + else if ((vio_idx >= 144 && vio_idx <= 173) || vio_idx == 241 || + (vio_idx >= 242 && vio_idx <= 271) || + vio_idx == 290) + return 15; + else if ((vio_idx >= 174 && vio_idx <= 186) || vio_idx == 272 || + (vio_idx >= 273 && vio_idx <= 285) || + vio_idx == 291) + return 16; + + pr_err(PFX "%s:%d Wrong vio_idx:0x%x\n", + __func__, __LINE__, vio_idx); + + } else if (slave_type == SLAVE_TYPE_PERI2) { + if ((vio_idx >= 0 && vio_idx <= 12) || vio_idx == 117 || + (vio_idx >= 118 && vio_idx <= 130) || + vio_idx == 234) + return 0; + else if (vio_idx >= 13 && vio_idx <= 16) + return 1; + else if (vio_idx >= 17 && vio_idx <= 20) + return 2; + else if ((vio_idx >= 21 && vio_idx <= 36) || vio_idx == 131 || + (vio_idx >= 132 && vio_idx <= 147) || + vio_idx == 235) + return 3; + else if ((vio_idx >= 37 && vio_idx <= 44) || vio_idx == 148 || + (vio_idx >= 149 && vio_idx <= 156) || + vio_idx == 236) + return 4; + else if ((vio_idx >= 45 && vio_idx <= 60) || vio_idx == 157 || + (vio_idx >= 158 && vio_idx <= 173) || + vio_idx == 237) + return 5; + else if ((vio_idx >= 61 && vio_idx <= 76) || vio_idx == 174 || + (vio_idx >= 175 && vio_idx <= 190) || + vio_idx == 238) + return 6; + else if ((vio_idx >= 77 && vio_idx <= 84) || vio_idx == 191 || + (vio_idx >= 192 && vio_idx <= 199) || + vio_idx == 239) + return 7; + else if ((vio_idx >= 85 && vio_idx <= 105) || vio_idx == 200 || + (vio_idx >= 201 && vio_idx <= 221) || + vio_idx == 240) + return 8; + else if ((vio_idx >= 106 && vio_idx <= 116) || vio_idx == 222 || + (vio_idx >= 223 && vio_idx <= 233) || + vio_idx == 241) + return 9; + + pr_err(PFX "%s:%d Wrong vio_idx:0x%x\n", + __func__, __LINE__, vio_idx); + + } else if (slave_type == SLAVE_TYPE_PERI_PAR) { + if ((vio_idx >= 0 && vio_idx <= 23) || vio_idx == 27 || + (vio_idx >= 28 && vio_idx <= 51) || + vio_idx == 56) + return 0; + else if ((vio_idx >= 24 && vio_idx <= 26) || vio_idx == 52 || + (vio_idx >= 53 && vio_idx <= 55) || + vio_idx == 57) + return 1; + + pr_err(PFX "%s:%d Wrong vio_idx:0x%x\n", + __func__, __LINE__, vio_idx); + + } else { + pr_err(PFX "%s:%d Wrong slave_type:0x%x\n", + __func__, __LINE__, slave_type); + } + + return 31; +} + +static struct mtk_devapc_dbg_status mt6873_devapc_dbg_stat = { + .enable_ut = PLAT_DBG_UT_DEFAULT, + .enable_dapc = PLAT_DBG_DAPC_DEFAULT, +}; + +static const char * const slave_type_to_str[] = { + "SLAVE_TYPE_INFRA", + "SLAVE_TYPE_PERI", + "SLAVE_TYPE_PERI2", + "SLAVE_TYPE_PERI_PAR", + "WRONG_SLAVE_TYPE", +}; + +static int mtk_vio_mask_sta_num[] = { + VIO_MASK_STA_NUM_INFRA, + VIO_MASK_STA_NUM_PERI, + VIO_MASK_STA_NUM_PERI2, + VIO_MASK_STA_NUM_PERI_PAR, +}; + +static struct mtk_devapc_vio_info mt6873_devapc_vio_info = { + .vio_mask_sta_num = mtk_vio_mask_sta_num, + .sramrom_vio_idx = SRAMROM_VIO_INDEX, + .mdp_vio_idx = MDP_VIO_INDEX, + .disp2_vio_idx = MDP_VIO_INDEX, + .mmsys_vio_idx = MMSYS_VIO_INDEX, + .sramrom_slv_type = SRAMROM_SLAVE_TYPE, + .mm2nd_slv_type = MM2ND_SLAVE_TYPE, +}; + +static const struct mtk_infra_vio_dbg_desc mt6873_vio_dbgs = { + .vio_dbg_mstid = INFRA_VIO_DBG_MSTID, + .vio_dbg_mstid_start_bit = INFRA_VIO_DBG_MSTID_START_BIT, + .vio_dbg_dmnid = INFRA_VIO_DBG_DMNID, + .vio_dbg_dmnid_start_bit = INFRA_VIO_DBG_DMNID_START_BIT, + .vio_dbg_w_vio = INFRA_VIO_DBG_W_VIO, + .vio_dbg_w_vio_start_bit = INFRA_VIO_DBG_W_VIO_START_BIT, + .vio_dbg_r_vio = INFRA_VIO_DBG_R_VIO, + .vio_dbg_r_vio_start_bit = INFRA_VIO_DBG_R_VIO_START_BIT, + .vio_addr_high = INFRA_VIO_ADDR_HIGH, + .vio_addr_high_start_bit = INFRA_VIO_ADDR_HIGH_START_BIT, +}; + +static const struct mtk_sramrom_sec_vio_desc mt6873_sramrom_sec_vios = { + .vio_id_mask = SRAMROM_SEC_VIO_ID_MASK, + .vio_id_shift = SRAMROM_SEC_VIO_ID_SHIFT, + .vio_domain_mask = SRAMROM_SEC_VIO_DOMAIN_MASK, + .vio_domain_shift = SRAMROM_SEC_VIO_DOMAIN_SHIFT, + .vio_rw_mask = SRAMROM_SEC_VIO_RW_MASK, + .vio_rw_shift = SRAMROM_SEC_VIO_RW_SHIFT, +}; + +static const u32 mt6873_devapc_pds[] = { + PD_VIO_MASK_OFFSET, + PD_VIO_STA_OFFSET, + PD_VIO_DBG0_OFFSET, + PD_VIO_DBG1_OFFSET, + PD_VIO_DBG2_OFFSET, + PD_APC_CON_OFFSET, + PD_SHIFT_STA_OFFSET, + PD_SHIFT_SEL_OFFSET, + PD_SHIFT_CON_OFFSET, +}; + +static struct mtk_devapc_soc mt6873_data = { + .dbg_stat = &mt6873_devapc_dbg_stat, + .slave_type_arr = slave_type_to_str, + .slave_type_num = SLAVE_TYPE_NUM, + .device_info[SLAVE_TYPE_INFRA] = mt6873_devices_infra, + .device_info[SLAVE_TYPE_PERI] = mt6873_devices_peri, + .device_info[SLAVE_TYPE_PERI2] = mt6873_devices_peri2, + .device_info[SLAVE_TYPE_PERI_PAR] = mt6873_devices_peri_par, + .ndevices = mtk6873_devices_num, + .vio_info = &mt6873_devapc_vio_info, + .vio_dbgs = &mt6873_vio_dbgs, + .sramrom_sec_vios = &mt6873_sramrom_sec_vios, + .devapc_pds = mt6873_devapc_pds, + .master_get = &mt6873_bus_id_to_master, + .mm2nd_vio_handler = &mm2nd_vio_handler, + .shift_group_get = mt6873_shift_group_get, +}; + +static const struct of_device_id mt6873_devapc_dt_match[] = { + { .compatible = "mediatek,mt6873-devapc" }, + {}, +}; + +static int mt6873_devapc_probe(struct platform_device *pdev) +{ + return mtk_devapc_probe(pdev, &mt6873_data); +} + +static int mt6873_devapc_remove(struct platform_device *dev) +{ + return mtk_devapc_remove(dev); +} + +static struct platform_driver mt6873_devapc_driver = { + .probe = mt6873_devapc_probe, + .remove = mt6873_devapc_remove, + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = mt6873_devapc_dt_match, + }, +}; + +module_platform_driver(mt6873_devapc_driver); + +MODULE_DESCRIPTION("Mediatek MT6873 Device APC Driver"); +MODULE_AUTHOR("Neal Liu "); +MODULE_LICENSE("GPL"); diff --git a/drivers/soc/mediatek/devapc/devapc-mt6873.h b/drivers/soc/mediatek/devapc/devapc-mt6873.h new file mode 100644 index 0000000..16be09e --- /dev/null +++ b/drivers/soc/mediatek/devapc/devapc-mt6873.h @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 MediaTek Inc. + */ + +#ifndef __DEVAPC_MT6873_H__ +#define __DEVAPC_MT6873_H__ + +/****************************************************************************** + * VARIABLE DEFINITION + ******************************************************************************/ +/* dbg status default setting */ +#define PLAT_DBG_UT_DEFAULT false +#define PLAT_DBG_DAPC_DEFAULT false + +/****************************************************************************** + * STRUCTURE DEFINITION + ******************************************************************************/ +enum DEVAPC_SLAVE_TYPE { + SLAVE_TYPE_INFRA = 0, + SLAVE_TYPE_PERI, + SLAVE_TYPE_PERI2, + SLAVE_TYPE_PERI_PAR, + SLAVE_TYPE_NUM, +}; + +enum DEVAPC_VIO_MASK_STA_NUM { + VIO_MASK_STA_NUM_INFRA = 12, + VIO_MASK_STA_NUM_PERI = 10, + VIO_MASK_STA_NUM_PERI2 = 8, + VIO_MASK_STA_NUM_PERI_PAR = 2, +}; + +enum DEVAPC_VIO_SLAVE_NUM { + VIO_SLAVE_NUM_INFRA = 366, + VIO_SLAVE_NUM_PERI = 284, + VIO_SLAVE_NUM_PERI2 = 247, + VIO_SLAVE_NUM_PERI_PAR = 58, +}; + +enum DEVAPC_PD_OFFSET { + PD_VIO_MASK_OFFSET = 0x0, + PD_VIO_STA_OFFSET = 0x400, + PD_VIO_DBG0_OFFSET = 0x900, + PD_VIO_DBG1_OFFSET = 0x904, + PD_VIO_DBG2_OFFSET = 0x908, + PD_APC_CON_OFFSET = 0xF00, + PD_SHIFT_STA_OFFSET = 0xF20, + PD_SHIFT_SEL_OFFSET = 0xF30, + PD_SHIFT_CON_OFFSET = 0xF10, +}; + +#define SRAMROM_SLAVE_TYPE SLAVE_TYPE_INFRA /* Infra */ +#define MM2ND_SLAVE_TYPE SLAVE_TYPE_PERI /* Peri */ + +enum OTHER_TYPES_INDEX { + SRAMROM_VIO_INDEX = 367, + CONN_VIO_INDEX = 75, /* starts from 0x18 */ + MDP_VIO_INDEX = 292, + MMSYS_VIO_INDEX = 294, +}; + +enum INFRACFG_MM2ND_VIO_NUM { + INFRACFG_MM_VIO_STA_NUM = 2, + INFRACFG_MDP_VIO_STA_NUM = 8, +}; + +enum INFRACFG_MM2ND_OFFSET { + INFRACFG_MM_SEC_VIO0_OFFSET = 0xB30, + INFRACFG_MDP_SEC_VIO0_OFFSET = 0xB40, +}; + +struct INFRAAXI_ID_INFO { + const char *master; + u32 bus_id; + u32 mask; +}; + +/****************************************************************************** + * PLATFORM DEFINATION + ******************************************************************************/ + +/* For Infra VIO_DBG */ +#define INFRA_VIO_DBG_MSTID 0xFFFFFFFF +#define INFRA_VIO_DBG_MSTID_START_BIT 0 +#define INFRA_VIO_DBG_DMNID 0x0000003F +#define INFRA_VIO_DBG_DMNID_START_BIT 0 +#define INFRA_VIO_DBG_W_VIO 0x00000040 +#define INFRA_VIO_DBG_W_VIO_START_BIT 6 +#define INFRA_VIO_DBG_R_VIO 0x00000080 +#define INFRA_VIO_DBG_R_VIO_START_BIT 7 +#define INFRA_VIO_ADDR_HIGH 0x00000F00 +#define INFRA_VIO_ADDR_HIGH_START_BIT 8 + +/* For SRAMROM VIO */ +#define SRAMROM_SEC_VIO_ID_MASK 0x00FFFF00 +#define SRAMROM_SEC_VIO_ID_SHIFT 8 +#define SRAMROM_SEC_VIO_DOMAIN_MASK 0x0F000000 +#define SRAMROM_SEC_VIO_DOMAIN_SHIFT 24 +#define SRAMROM_SEC_VIO_RW_MASK 0x80000000 +#define SRAMROM_SEC_VIO_RW_SHIFT 31 + +/* For MM 2nd VIO */ +#define INFRACFG_MM2ND_VIO_DOMAIN_MASK 0x00000030 +#define INFRACFG_MM2ND_VIO_DOMAIN_SHIFT 4 +#define INFRACFG_MM2ND_VIO_ID_MASK 0x00FFFF00 +#define INFRACFG_MM2ND_VIO_ID_SHIFT 8 +#define INFRACFG_MM2ND_VIO_RW_MASK 0x01000000 +#define INFRACFG_MM2ND_VIO_RW_SHIFT 24 + +#endif /* __DEVAPC_MT6873_H__ */ diff --git a/drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.c b/drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.c new file mode 100644 index 0000000..6c4a8ec --- /dev/null +++ b/drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.c @@ -0,0 +1,756 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "devapc-mtk-multi-ao.h" + +/* + * mtk_devapc_pd_get - get devapc pd_types of register address. + * + * Returns the value of reg addr + */ +static void __iomem *mtk_devapc_pd_get(struct mtk_devapc_context *devapc_ctx, + int slave_type, + enum DEVAPC_PD_REG_TYPE pd_reg_type, + u32 index) +{ + struct mtk_devapc_vio_info *vio_info = devapc_ctx->soc->vio_info; + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + const u32 *devapc_pds = devapc_ctx->soc->devapc_pds; + void __iomem *reg; + + if (!devapc_pds) + return NULL; + + if ((slave_type < slave_type_num && + index < vio_info->vio_mask_sta_num[slave_type]) && + pd_reg_type < PD_REG_TYPE_NUM) { + reg = devapc_ctx->devapc_pd_base[slave_type] + + devapc_pds[pd_reg_type]; + + if (pd_reg_type == VIO_MASK || pd_reg_type == VIO_STA) + reg += 0x4 * index; + + } else { + pr_err(PFX "Out Of Boundary, slave_type:0x%x/pd_reg_type:0x%x/index:0x%x\n", + slave_type, pd_reg_type, index); + return NULL; + } + + return reg; +} + +/* + * sramrom_vio_handler - clean sramrom violation & print violation information + * for debugging. + */ +static void sramrom_vio_handler(struct mtk_devapc_context *devapc_ctx) +{ + const struct mtk_sramrom_sec_vio_desc *sramrom_vios; + struct mtk_devapc_vio_info *vio_info; + struct arm_smccc_res res; + size_t sramrom_vio_sta; + int sramrom_vio; + u32 rw; + + sramrom_vios = devapc_ctx->soc->sramrom_sec_vios; + vio_info = devapc_ctx->soc->vio_info; + + arm_smccc_smc(MTK_SIP_KERNEL_CLR_SRAMROM_VIO, + 0, 0, 0, 0, 0, 0, 0, &res); + + sramrom_vio = res.a0; + sramrom_vio_sta = res.a1; + vio_info->vio_addr = res.a2; + + if (sramrom_vio == SRAM_VIOLATION) + pr_info(PFX "SRAM violation is triggered\n"); + else if (sramrom_vio == ROM_VIOLATION) + pr_info(PFX "ROM violation is triggered\n"); + else + return; + + vio_info->master_id = (sramrom_vio_sta & sramrom_vios->vio_id_mask) + >> sramrom_vios->vio_id_shift; + vio_info->domain_id = (sramrom_vio_sta & sramrom_vios->vio_domain_mask) + >> sramrom_vios->vio_domain_shift; + rw = (sramrom_vio_sta & sramrom_vios->vio_rw_mask) >> + sramrom_vios->vio_rw_shift; + + if (rw) + vio_info->write = 1; + else + vio_info->read = 1; + + pr_info(PFX "%s: master_id:0x%x, domain_id:0x%x, rw:%s, vio_addr:0x%x\n", + __func__, vio_info->master_id, vio_info->domain_id, + rw ? "Write" : "Read", vio_info->vio_addr); +} + +static void mask_module_irq(struct mtk_devapc_context *devapc_ctx, + int slave_type, u32 module, bool mask) +{ + struct mtk_devapc_vio_info *vio_info = devapc_ctx->soc->vio_info; + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + u32 apc_register_index; + u32 apc_set_index; + void __iomem *reg; + + apc_register_index = module / (MOD_NO_IN_1_DEVAPC * 2); + apc_set_index = module % (MOD_NO_IN_1_DEVAPC * 2); + + if (slave_type < slave_type_num && + apc_register_index < vio_info->vio_mask_sta_num[slave_type]) { + reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_MASK, + apc_register_index); + + if (mask) + writel(readl(reg) | (1 << apc_set_index), reg); + else + writel(readl(reg) & (~(1 << apc_set_index)), reg); + + } else { + pr_err(PFX "%s: Out Of Boundary, slave_type:0x%x, module_index:0x%x, mask:%s\n", + __func__, slave_type, module, mask ? "true" : "false"); + } +} + +static int check_vio_mask(struct mtk_devapc_context *devapc_ctx, int slave_type, + u32 module) +{ + struct mtk_devapc_vio_info *vio_info = devapc_ctx->soc->vio_info; + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + u32 apc_register_index; + u32 apc_set_index; + void __iomem *reg; + + apc_register_index = module / (MOD_NO_IN_1_DEVAPC * 2); + apc_set_index = module % (MOD_NO_IN_1_DEVAPC * 2); + + if (slave_type < slave_type_num && + apc_register_index < vio_info->vio_mask_sta_num[slave_type]) + reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_MASK, + apc_register_index); + else + return -EOVERFLOW; + + if (readl(reg) & (0x1 << apc_set_index)) + return VIOLATION_MASKED; + + return 0; +} + +static int32_t check_vio_status(struct mtk_devapc_context *devapc_ctx, + int slave_type, u32 module) +{ + struct mtk_devapc_vio_info *vio_info = devapc_ctx->soc->vio_info; + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + u32 apc_register_index; + u32 apc_set_index; + void __iomem *reg; + + apc_register_index = module / (MOD_NO_IN_1_DEVAPC * 2); + apc_set_index = module % (MOD_NO_IN_1_DEVAPC * 2); + + if (slave_type < slave_type_num && + apc_register_index < vio_info->vio_mask_sta_num[slave_type]) { + reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_STA, + apc_register_index); + + } else { + pr_err(PFX "%s: Out Of Boundary, slave_type:0x%x, module_index:0x%x\n", + __func__, slave_type, module); + return -EOVERFLOW; + } + + if (readl(reg) & (0x1 << apc_set_index)) + return VIOLATION_TRIGGERED; + + return 0; +} + +static int32_t clear_vio_status(struct mtk_devapc_context *devapc_ctx, + int slave_type, u32 module) +{ + struct mtk_devapc_vio_info *vio_info = devapc_ctx->soc->vio_info; + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + u32 apc_register_index; + u32 apc_set_index; + void __iomem *reg; + + apc_register_index = module / (MOD_NO_IN_1_DEVAPC * 2); + apc_set_index = module % (MOD_NO_IN_1_DEVAPC * 2); + + if (slave_type < slave_type_num && + apc_register_index < vio_info->vio_mask_sta_num[slave_type]) { + reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_STA, + apc_register_index); + writel(0x1 << apc_set_index, reg); + + } else { + pr_err(PFX "%s: Out Of Boundary, slave_type:0x%x, module_index:0x%x\n", + __func__, slave_type, module); + return -EOVERFLOW; + } + + if (check_vio_status(devapc_ctx, slave_type, module)) + return -EIO; + + return 0; +} + +static void devapc_vio_info_print(struct mtk_devapc_context *devapc_ctx) +{ + struct mtk_devapc_vio_info *vio_info; + + vio_info = devapc_ctx->soc->vio_info; + + /* Print violation information */ + if (vio_info->write) + pr_info(PFX "Write Violation\n"); + else if (vio_info->read) + pr_info(PFX "Read Violation\n"); + + pr_info(PFX "%s%x, %s%x, %s%x, %s%x\n", + "Vio Addr:0x", vio_info->vio_addr, + "High:0x", vio_info->vio_addr_high, + "Bus ID:0x", vio_info->master_id, + "Dom ID:0x", vio_info->domain_id); +} + +/* + * check_type2_vio_status - there are type 2 slaves which violation information + * is stored in different register bank. + * + * Returns true if type2 violation is triggered. + */ +static bool check_type2_vio_status(struct mtk_devapc_context *devapc_ctx, + int slave_type, int *vio_idx, int *index) +{ + u32 sramrom_vio_idx, mdp_vio_idx, disp2_vio_idx, mmsys_vio_idx; + const struct mtk_device_info **device_info; + const struct mtk_device_num *ndevices; + int sramrom_slv_type, mm2nd_slv_type; + bool mdp_vio, disp2_vio, mmsys_vio; + int i; + + sramrom_slv_type = devapc_ctx->soc->vio_info->sramrom_slv_type; + sramrom_vio_idx = devapc_ctx->soc->vio_info->sramrom_vio_idx; + + mm2nd_slv_type = devapc_ctx->soc->vio_info->mm2nd_slv_type; + mdp_vio_idx = devapc_ctx->soc->vio_info->mdp_vio_idx; + disp2_vio_idx = devapc_ctx->soc->vio_info->disp2_vio_idx; + mmsys_vio_idx = devapc_ctx->soc->vio_info->mmsys_vio_idx; + + device_info = devapc_ctx->soc->device_info; + ndevices = devapc_ctx->soc->ndevices; + + /* check SRAMROM violation */ + if (slave_type == sramrom_slv_type && + check_vio_status(devapc_ctx, slave_type, sramrom_vio_idx)) { + pr_info(PFX "SRAMROM violation is triggered\n"); + sramrom_vio_handler(devapc_ctx); + + *vio_idx = sramrom_vio_idx; + for (i = 0; i < ndevices[slave_type].vio_slave_num; i++) { + if (device_info[slave_type][i].vio_index == *vio_idx) + *index = i; + } + + return true; + } + + /* check MM 2nd level violation */ + if (slave_type == mm2nd_slv_type) { + mdp_vio = check_vio_status(devapc_ctx, slave_type, + mdp_vio_idx) == + VIOLATION_TRIGGERED; + disp2_vio = check_vio_status(devapc_ctx, slave_type, + disp2_vio_idx) == + VIOLATION_TRIGGERED; + mmsys_vio = check_vio_status(devapc_ctx, slave_type, + mmsys_vio_idx) == + VIOLATION_TRIGGERED; + + if (mdp_vio || disp2_vio || mmsys_vio) { + pr_info(PFX "MM2nd violation is triggered\n"); + devapc_ctx->soc->mm2nd_vio_handler + (devapc_ctx->infracfg_base, + devapc_ctx->soc->vio_info, + mdp_vio, + disp2_vio, + mmsys_vio); + } else { + return false; + } + + if (mdp_vio) + *vio_idx = mdp_vio_idx; + else if (disp2_vio) + *vio_idx = disp2_vio_idx; + else if (mmsys_vio) + *vio_idx = mmsys_vio_idx; + + for (i = 0; i < ndevices[slave_type].vio_slave_num; i++) { + if (device_info[slave_type][i].vio_index == *vio_idx) + *index = i; + } + + devapc_vio_info_print(devapc_ctx); + return true; + } + + return false; +} + +/* + * sync_vio_dbg - start to get violation information by selecting violation + * group and enable violation shift. + * + * Returns sync done or not + */ +static u32 sync_vio_dbg(struct mtk_devapc_context *devapc_ctx, int slave_type, + u32 shift_bit) +{ + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + void __iomem *pd_vio_shift_sta_reg; + void __iomem *pd_vio_shift_sel_reg; + void __iomem *pd_vio_shift_con_reg; + u32 shift_count; + u32 sync_done; + + if (slave_type >= slave_type_num || + shift_bit >= (MOD_NO_IN_1_DEVAPC * 2)) { + pr_err(PFX "param check failed, slave_type:0x%x, shift_bit:0x%x\n", + slave_type, shift_bit); + return 0; + } + + pd_vio_shift_sta_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_STA, 0); + pd_vio_shift_sel_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_SEL, 0); + pd_vio_shift_con_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_CON, 0); + + writel(0x1 << shift_bit, pd_vio_shift_sel_reg); + writel(0x1, pd_vio_shift_con_reg); + + for (shift_count = 0; (shift_count < 100) && + ((readl(pd_vio_shift_con_reg) & 0x3) != 0x3); + ++shift_count) + ; + + if ((readl(pd_vio_shift_con_reg) & 0x3) == 0x3) + sync_done = 1; + else + sync_done = 0; + + /* Disable shift mechanism */ + writel(0x0, pd_vio_shift_con_reg); + writel(0x0, pd_vio_shift_sel_reg); + writel(0x1 << shift_bit, pd_vio_shift_sta_reg); + + return sync_done; +} + +static const char * const perm_to_str[] = { + "NO_PROTECTION", + "SECURE_RW_ONLY", + "SECURE_RW_NS_R_ONLY", + "FORBIDDEN", + "NO_PERM_CTRL" +}; + +static const char *perm_to_string(u8 perm) +{ + if (perm < PERM_TYPE_NUM) + return perm_to_str[perm]; + else + return perm_to_str[PERM_TYPE_NUM]; +} + +static void devapc_vio_reason(u8 perm) +{ + pr_info(PFX "Permission setting: %s\n", perm_to_string(perm)); + + if (perm == NO_PROTECTION || perm >= PERM_TYPE_NUM) + pr_info(PFX "Reason: power/clock is not enabled\n"); + else if (perm == SEC_RW_ONLY || + perm == SEC_RW_NS_R || + perm == FORBIDDEN) + pr_info(PFX "Reason: might be permission denied\n"); +} + +/* + * get_permission - get slave's access permission of domain id. + * + * Returns the value of access permission + */ +static u8 get_permission(struct mtk_devapc_context *devapc_ctx, int slave_type, + int module_index, int domain) +{ + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + const struct mtk_device_info **device_info; + const struct mtk_device_num *ndevices; + int sys_index, ctrl_index, vio_index; + struct arm_smccc_res res; + u32 ret, apc_set_index; + + ndevices = devapc_ctx->soc->ndevices; + + if (slave_type >= slave_type_num || + module_index >= ndevices[slave_type].vio_slave_num) { + pr_err(PFX "%s: param check failed, slave_type:0x%x, module_index:0x%x\n", + __func__, slave_type, module_index); + return 0xFF; + } + + device_info = devapc_ctx->soc->device_info; + + sys_index = device_info[slave_type][module_index].sys_index; + ctrl_index = device_info[slave_type][module_index].ctrl_index; + vio_index = device_info[slave_type][module_index].vio_index; + + if (sys_index == -1 || ctrl_index == -1) + return 0xFF; + + arm_smccc_smc(MTK_SIP_KERNEL_DAPC_PERM_GET, slave_type, sys_index, + domain, ctrl_index, vio_index, 0, 0, &res); + ret = res.a0; + + if (ret == DEAD) { + pr_err(PFX "permission get failed, ret:0x%x\n", ret); + return 0xFF; + } + + apc_set_index = ctrl_index % MOD_NO_IN_1_DEVAPC; + ret = (ret & (0x3 << (apc_set_index * 2))) >> (apc_set_index * 2); + + return (ret & 0x3); +} + +/* + * mtk_devapc_vio_check - check violation shift status is raised or not. + * + * Returns the value of violation shift status reg + */ +static void mtk_devapc_vio_check(struct mtk_devapc_context *devapc_ctx, + int slave_type, int *shift_bit) +{ + struct mtk_devapc_vio_info *vio_info; + u32 vio_shift_sta; + int i; + + vio_info = devapc_ctx->soc->vio_info; + vio_shift_sta = readl(mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_STA, 0)); + + if (!vio_shift_sta) { + pr_info(PFX "violation is triggered before. shift_bit:0x%x\n", + *shift_bit); + + } else if (vio_shift_sta & (0x1UL << *shift_bit)) { + pr_debug(PFX "vio_shift_sta:0x%x is matched with shift_bit:%d\n", + vio_shift_sta, *shift_bit); + + } else { + pr_info(PFX "vio_shift_sta:0x%x is not matched with shift_bit:%d\n", + vio_shift_sta, *shift_bit); + + for (i = 0; i < MOD_NO_IN_1_DEVAPC * 2; i++) { + if (vio_shift_sta & (0x1 << i)) { + *shift_bit = i; + break; + } + } + } + + vio_info->shift_sta_bit = *shift_bit; +} + +static void devapc_extract_vio_dbg(struct mtk_devapc_context *devapc_ctx, + int slave_type) +{ + void __iomem *vio_dbg0_reg, *vio_dbg1_reg, *vio_dbg2_reg; + const struct mtk_infra_vio_dbg_desc *vio_dbgs; + struct mtk_devapc_vio_info *vio_info; + u32 dbg0; + + vio_dbg0_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_DBG0, 0); + vio_dbg1_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_DBG1, 0); + vio_dbg2_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_DBG2, 0); + + vio_dbgs = devapc_ctx->soc->vio_dbgs; + vio_info = devapc_ctx->soc->vio_info; + + /* Extract violation information */ + dbg0 = readl(vio_dbg0_reg); + vio_info->master_id = readl(vio_dbg1_reg); + vio_info->vio_addr = readl(vio_dbg2_reg); + + vio_info->domain_id = (dbg0 & vio_dbgs->vio_dbg_dmnid) + >> vio_dbgs->vio_dbg_dmnid_start_bit; + vio_info->write = ((dbg0 & vio_dbgs->vio_dbg_w_vio) + >> vio_dbgs->vio_dbg_w_vio_start_bit) == 1; + vio_info->read = ((dbg0 & vio_dbgs->vio_dbg_r_vio) + >> vio_dbgs->vio_dbg_r_vio_start_bit) == 1; + vio_info->vio_addr_high = (dbg0 & vio_dbgs->vio_addr_high) + >> vio_dbgs->vio_addr_high_start_bit; + + devapc_vio_info_print(devapc_ctx); +} + +/* + * mtk_devapc_dump_vio_dbg - shift & dump the violation debug information. + */ +static bool mtk_devapc_dump_vio_dbg(struct mtk_devapc_context *devapc_ctx, + int slave_type, int *vio_idx, int *index) +{ + const struct mtk_device_info **device_info; + const struct mtk_device_num *ndevices; + void __iomem *pd_vio_shift_sta_reg; + u32 shift_bit; + int i; + + if (!vio_idx) + return NULL; + + device_info = devapc_ctx->soc->device_info; + ndevices = devapc_ctx->soc->ndevices; + + pd_vio_shift_sta_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_STA, 0); + + for (i = 0; i < ndevices[slave_type].vio_slave_num; i++) { + *vio_idx = device_info[slave_type][i].vio_index; + + if (check_vio_mask(devapc_ctx, slave_type, *vio_idx)) + continue; + + if (check_vio_status(devapc_ctx, slave_type, *vio_idx) != + VIOLATION_TRIGGERED) + continue; + + shift_bit = devapc_ctx->soc->shift_group_get(slave_type, + *vio_idx); + + mtk_devapc_vio_check(devapc_ctx, slave_type, &shift_bit); + + if (!sync_vio_dbg(devapc_ctx, slave_type, shift_bit)) + continue; + + devapc_extract_vio_dbg(devapc_ctx, slave_type); + *index = i; + + return true; + } + + return false; +} + +/* + * start_devapc - initialize devapc status and start receiving interrupt + * while devapc violation is triggered. + */ +static void start_devapc(struct mtk_devapc_context *devapc_ctx) +{ + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + const struct mtk_device_info **device_info; + const struct mtk_device_num *ndevices; + void __iomem *pd_vio_shift_sta_reg; + void __iomem *pd_apc_con_reg; + int slave_type, i, vio_idx, index; + u32 vio_shift_sta; + + ndevices = devapc_ctx->soc->ndevices; + + device_info = devapc_ctx->soc->device_info; + + for (slave_type = 0; slave_type < slave_type_num; slave_type++) { + pd_apc_con_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + APC_CON, 0); + pd_vio_shift_sta_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_STA, 0); + + if (!pd_apc_con_reg || !pd_vio_shift_sta_reg || !device_info) + return; + + /* Clear DEVAPC violation status */ + writel(BIT(31), pd_apc_con_reg); + + /* Clear violation shift status */ + vio_shift_sta = readl(pd_vio_shift_sta_reg); + if (vio_shift_sta) + writel(vio_shift_sta, pd_vio_shift_sta_reg); + + /* Clear type 2 violation status */ + check_type2_vio_status(devapc_ctx, slave_type, &vio_idx, &i); + + /* Clear violation status */ + for (i = 0; i < ndevices[slave_type].vio_slave_num; i++) { + vio_idx = device_info[slave_type][i].vio_index; + if ((check_vio_status(devapc_ctx, slave_type, vio_idx) + == VIOLATION_TRIGGERED) && + clear_vio_status(devapc_ctx, slave_type, + vio_idx)) { + pr_warn(PFX "Clear vio status failed, slave_type:0x%x, vio_index:0x%x\n", + slave_type, vio_idx); + + index = i; + mtk_devapc_dump_vio_dbg(devapc_ctx, slave_type, + &vio_idx, &index); + i = index - 1; + } + + mask_module_irq(devapc_ctx, slave_type, vio_idx, false); + } + } +} + +static DEFINE_SPINLOCK(devapc_lock); + +/* + * devapc_violation_irq - the devapc Interrupt Service Routine (ISR) will dump + * violation information including which master violates + * access slave. + */ +static irqreturn_t devapc_violation_irq(int irq_number, + struct mtk_devapc_context *devapc_ctx) +{ + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + const struct mtk_device_info **device_info; + struct mtk_devapc_vio_info *vio_info; + int slave_type, vio_idx, index; + const char *vio_master; + unsigned long flags; + u8 perm; + + spin_lock_irqsave(&devapc_lock, flags); + + device_info = devapc_ctx->soc->device_info; + vio_info = devapc_ctx->soc->vio_info; + vio_idx = -1; + index = -1; + + /* There are multiple DEVAPC_PD */ + for (slave_type = 0; slave_type < slave_type_num; slave_type++) { + if (!check_type2_vio_status(devapc_ctx, slave_type, &vio_idx, + &index)) + if (!mtk_devapc_dump_vio_dbg(devapc_ctx, slave_type, + &vio_idx, &index)) + continue; + + /* Ensure that violation info are written before + * further operations + */ + smp_mb(); + + mask_module_irq(devapc_ctx, slave_type, vio_idx, true); + + clear_vio_status(devapc_ctx, slave_type, vio_idx); + + perm = get_permission(devapc_ctx, slave_type, index, + vio_info->domain_id); + + vio_master = devapc_ctx->soc->master_get + (vio_info->master_id, + vio_info->vio_addr, + slave_type, + vio_info->shift_sta_bit, + vio_info->domain_id); + + if (!vio_master) + vio_master = "UNKNOWN_MASTER"; + + pr_info(PFX "Violation - slave_type:0x%x, sys_index:0x%x, ctrl_index:0x%x, vio_index:0x%x\n", + slave_type, + device_info[slave_type][index].sys_index, + device_info[slave_type][index].ctrl_index, + device_info[slave_type][index].vio_index); + + pr_info(PFX "Violation Master: %s\n", vio_master); + + devapc_vio_reason(perm); + + mask_module_irq(devapc_ctx, slave_type, vio_idx, false); + } + + spin_unlock_irqrestore(&devapc_lock, flags); + return IRQ_HANDLED; +} + +int mtk_devapc_probe(struct platform_device *pdev, struct mtk_devapc_soc *soc) +{ + struct device_node *node = pdev->dev.of_node; + struct mtk_devapc_context *devapc_ctx; + u32 slave_type_num; + int slave_type; + int ret; + + if (IS_ERR(node)) + return -ENODEV; + + devapc_ctx = devm_kzalloc(&pdev->dev, sizeof(struct mtk_devapc_context), + GFP_KERNEL); + if (!devapc_ctx) + return -ENOMEM; + + devapc_ctx->soc = soc; + slave_type_num = devapc_ctx->soc->slave_type_num; + + for (slave_type = 0; slave_type < slave_type_num; slave_type++) { + devapc_ctx->devapc_pd_base[slave_type] = + of_iomap(node, slave_type); + if (!devapc_ctx->devapc_pd_base[slave_type]) + return -EINVAL; + } + + devapc_ctx->infracfg_base = of_iomap(node, slave_type_num + 1); + if (!devapc_ctx->infracfg_base) + return -EINVAL; + + devapc_ctx->devapc_irq = irq_of_parse_and_map(node, 0); + if (!devapc_ctx->devapc_irq) + return -EINVAL; + + /* CCF (Common Clock Framework) */ + devapc_ctx->devapc_infra_clk = devm_clk_get(&pdev->dev, + "devapc-infra-clock"); + + if (IS_ERR(devapc_ctx->devapc_infra_clk)) + return -EINVAL; + + if (clk_prepare_enable(devapc_ctx->devapc_infra_clk)) + return -EINVAL; + + start_devapc(devapc_ctx); + + ret = devm_request_irq(&pdev->dev, devapc_ctx->devapc_irq, + (irq_handler_t)devapc_violation_irq, + IRQF_TRIGGER_NONE, "devapc", devapc_ctx); + if (ret) + return ret; + + return 0; +} + +int mtk_devapc_remove(struct platform_device *dev) +{ + return 0; +} + +MODULE_DESCRIPTION("Mediatek Device APC Driver"); +MODULE_AUTHOR("Neal Liu "); +MODULE_LICENSE("GPL"); diff --git a/drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.h b/drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.h new file mode 100644 index 0000000..1e58a3e --- /dev/null +++ b/drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.h @@ -0,0 +1,182 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 MediaTek Inc. + */ + +#ifndef __DEVAPC_MTK_MULTI_AO_H__ +#define __DEVAPC_MTK_MULTI_AO_H__ + +#include +#include + +/****************************************************************************** + * VARIABLE DEFINATION + ******************************************************************************/ +#define MOD_NO_IN_1_DEVAPC 16 +#define VIOLATION_TRIGGERED 1 +#define VIOLATION_MASKED 1 +#define DEAD 0xdeadbeaf +#define PFX "[DEVAPC]: " +#define SLAVE_TYPE_NUM_MAX 5 + +#define devapc_log(p, s, fmt, args...) \ + do { \ + typeof(p) (_p) = (p); \ + ((_p) += scnprintf(_p, sizeof(s) - strlen(s), fmt, ##args)); \ + } while (0) + +#define UNUSED(x) (void)(x) + +/****************************************************************************** + * DATA STRUCTURE & FUNCTION DEFINATION + ******************************************************************************/ +enum DEVAPC_PD_REG_TYPE { + VIO_MASK = 0, + VIO_STA, + VIO_DBG0, + VIO_DBG1, + VIO_DBG2, + APC_CON, + VIO_SHIFT_STA, + VIO_SHIFT_SEL, + VIO_SHIFT_CON, + PD_REG_TYPE_NUM, +}; + +enum DEVAPC_UT_CMD { + DEVAPC_UT_DAPC_VIO = 1, + DEVAPC_UT_SRAM_VIO, +}; + +enum DEVAPC_DOM_ID { + DOMAIN_0 = 0, + DOMAIN_1, + DOMAIN_2, + DOMAIN_3, + DOMAIN_4, + DOMAIN_5, + DOMAIN_6, + DOMAIN_7, + DOMAIN_8, + DOMAIN_9, + DOMAIN_10, + DOMAIN_11, + DOMAIN_12, + DOMAIN_13, + DOMAIN_14, + DOMAIN_15, + DOMAIN_OTHERS, +}; + +enum SRAMROM_VIO { + ROM_VIOLATION = 0, + SRAM_VIOLATION, +}; + +enum DEVAPC_PERM_TYPE { + NO_PROTECTION = 0, + SEC_RW_ONLY, + SEC_RW_NS_R, + FORBIDDEN, + PERM_TYPE_NUM, +}; + +struct mtk_devapc_dbg_status { + bool enable_ut; + bool enable_dapc; /* dump APC */ +}; + +struct mtk_device_info { + int sys_index; + int ctrl_index; + int vio_index; +}; + +struct mtk_device_num { + int slave_type; + u32 vio_slave_num; +}; + +struct mtk_devapc_vio_info { + bool read; + bool write; + u32 vio_addr; + u32 vio_addr_high; + u32 master_id; + u32 domain_id; + int *vio_mask_sta_num; + int sramrom_slv_type; + int sramrom_vio_idx; + int mm2nd_slv_type; + int mdp_vio_idx; + int disp2_vio_idx; + int mmsys_vio_idx; + int shift_sta_bit; +}; + +struct mtk_infra_vio_dbg_desc { + u32 vio_dbg_mstid; + u8 vio_dbg_mstid_start_bit; + u32 vio_dbg_dmnid; + u8 vio_dbg_dmnid_start_bit; + u32 vio_dbg_w_vio; + u8 vio_dbg_w_vio_start_bit; + u32 vio_dbg_r_vio; + u8 vio_dbg_r_vio_start_bit; + u32 vio_addr_high; + u8 vio_addr_high_start_bit; +}; + +struct mtk_sramrom_sec_vio_desc { + u32 vio_id_mask; + u8 vio_id_shift; + u32 vio_domain_mask; + u8 vio_domain_shift; + u32 vio_rw_mask; + u8 vio_rw_shift; +}; + +struct mtk_devapc_pd_desc { + u32 pd_vio_mask_offset; + u32 pd_vio_sta_offset; + u32 pd_vio_dbg0_offset; + u32 pd_vio_dbg1_offset; + u32 pd_apc_con_offset; + u32 pd_shift_sta_offset; + u32 pd_shift_sel_offset; + u32 pd_shift_con_offset; +}; + +struct mtk_devapc_soc { + struct mtk_devapc_dbg_status *dbg_stat; + const char * const *slave_type_arr; + u32 slave_type_num; + const struct mtk_device_info *device_info[SLAVE_TYPE_NUM_MAX]; + const struct mtk_device_num *ndevices; + struct mtk_devapc_vio_info *vio_info; + const struct mtk_infra_vio_dbg_desc *vio_dbgs; + const struct mtk_sramrom_sec_vio_desc *sramrom_sec_vios; + const u32 *devapc_pds; + + /* platform specific operations */ + const char* (*master_get)(u32 bus_id, u32 vio_addr, + int slave_type, int shift_sta_bit, + int domain); + void (*mm2nd_vio_handler)(void __iomem *infracfg, + struct mtk_devapc_vio_info *vio_info, + bool mdp_vio, bool disp2_vio, bool mmsys_vio); + u32 (*shift_group_get)(int slave_type, u32 vio_index); +}; + +struct mtk_devapc_context { + struct clk *devapc_infra_clk; + u32 devapc_irq; + void __iomem *devapc_pd_base[4]; + void __iomem *infracfg_base; + struct mtk_devapc_soc *soc; +}; + +int mtk_devapc_probe(struct platform_device *pdev, struct mtk_devapc_soc *soc); +int mtk_devapc_remove(struct platform_device *dev); + +#endif /* __DEVAPC_MTK_MULTI_AO_H__ */ -- 1.7.9.5 _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.7 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 09A75C433E0 for ; Fri, 19 Jun 2020 10:14:31 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C8E3C2073E for ; Fri, 19 Jun 2020 10:14:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="YYdPQv7O"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="lxIKatnx" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C8E3C2073E Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=R35seYTggFNjQGYguKEuGpBvKhXMsfUd2UfSwrzO0wk=; b=YYdPQv7OTLnYcF tJGos6LoFuHSYDCCKqjtxCIRtOrsvABWkGJHBpODJP48huG371+3ncCoY5V3EZY72zEehiE6/O8Ae 3Y+8p8ebXU/eafUpJdq13HiSfy2r4kPiH8v7rxiAvfrY2PP6+q8DcN+cWBKNhygHvbV1F3rHFc+PD y0cDRke7HGyqlupdH6ZxFC7yZTaR2Brc0Ad9zxPcFubzm3I0BAYQu7yS+H3eB2YZLHCSUpBluFQ1Z BfngJXbuat5dGwpjn/aTxbqQmHMgprOSJRdkwitNeZCZNfn7tPRsEd9mPyKBlGyF0l7b+aJNDBdyl H2qFUfJ56ATQVjbZyhNQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jmDg8-0005MQ-NP; Fri, 19 Jun 2020 09:51:20 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jmDfk-00056o-3n; Fri, 19 Jun 2020 09:51:00 +0000 X-UUID: 505ecbfd68ed4db4835c4a837dedc3f6-20200619 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=xmg1w3ypX4AvT1+i24MnshAnpwzBsGKjigr9tp4Uf7E=; b=lxIKatnx5Z+RsisdwUs86yNdT7R3ChAuisRRAcOSmvnPyuuGdgnr4UO3QWqb8HbOjDkAlGmqqzypQ7vQHixlMEMa7PE1R74yvwld494sLB5Acbs2noDI8lXgEm0jAx5llt+CrQ8PGJaXs6oMuPKO9y849qgBwTkdJ+Cn604xiK0=; X-UUID: 505ecbfd68ed4db4835c4a837dedc3f6-20200619 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 1307300018; Fri, 19 Jun 2020 01:51:40 -0800 Received: from MTKMBS02N2.mediatek.inc (172.21.101.101) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 19 Jun 2020 02:42:20 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs02n2.mediatek.inc (172.21.101.101) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 19 Jun 2020 17:42:03 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 19 Jun 2020 17:42:02 +0800 From: Neal Liu To: Rob Herring , Matthias Brugger Subject: [PATCH v2 2/2] soc: mediatek: devapc: add devapc-mt6873 driver Date: Fri, 19 Jun 2020 17:42:00 +0800 Message-ID: <1592559720-8482-3-git-send-email-neal.liu@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1592559720-8482-1-git-send-email-neal.liu@mediatek.com> References: <1592559720-8482-1-git-send-email-neal.liu@mediatek.com> MIME-Version: 1.0 X-TM-SNTS-SMTP: E0B163962F1135967F8C685B03557F40BC5F0C13593F6F8072F8DD8B2E6A36CD2000:8 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200619_025056_186851_6F4A0387 X-CRM114-Status: GOOD ( 14.75 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, wsd_upstream@mediatek.com, linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, Neal Liu , linux-arm-kernel@lists.infradead.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org MT6873 bus frabric provides TrustZone security support and data protection to prevent slaves from being accessed by unexpected masters. The security violations are logged and sent to the processor for further analysis or countermeasures. Any occurrence of security violation would raise an interrupt, and it will be handled by devapc-mt6873 driver. The violation information is printed in order to find the murderer. Signed-off-by: Neal Liu --- drivers/soc/mediatek/Kconfig | 6 + drivers/soc/mediatek/Makefile | 1 + drivers/soc/mediatek/devapc/Kconfig | 25 + drivers/soc/mediatek/devapc/Makefile | 13 + drivers/soc/mediatek/devapc/devapc-mt6873.c | 1652 +++++++++++++++++++++ drivers/soc/mediatek/devapc/devapc-mt6873.h | 111 ++ drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.c | 756 ++++++++++ drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.h | 182 +++ 8 files changed, 2746 insertions(+) create mode 100644 drivers/soc/mediatek/devapc/Kconfig create mode 100644 drivers/soc/mediatek/devapc/Makefile create mode 100644 drivers/soc/mediatek/devapc/devapc-mt6873.c create mode 100644 drivers/soc/mediatek/devapc/devapc-mt6873.h create mode 100644 drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.c create mode 100644 drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.h diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig index 59a56cd..2c9ad1f 100644 --- a/drivers/soc/mediatek/Kconfig +++ b/drivers/soc/mediatek/Kconfig @@ -51,4 +51,10 @@ config MTK_MMSYS Say yes here to add support for the MediaTek Multimedia Subsystem (MMSYS). +menu "Security" + +source "drivers/soc/mediatek/devapc/Kconfig" + +endmenu # Security + endmenu diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile index 01f9f87..d6717a81 100644 --- a/drivers/soc/mediatek/Makefile +++ b/drivers/soc/mediatek/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o +obj-$(CONFIG_MTK_DEVAPC) += devapc/ obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o diff --git a/drivers/soc/mediatek/devapc/Kconfig b/drivers/soc/mediatek/devapc/Kconfig new file mode 100644 index 0000000..9428360 --- /dev/null +++ b/drivers/soc/mediatek/devapc/Kconfig @@ -0,0 +1,25 @@ +config MTK_DEVAPC + tristate "Mediatek Device APC Support" + help + Device APC is a kernel driver controlling internal device security. + If someone tries to access a device, which is not allowed by the + device, it cannot access the device and will get a violation + interrupt. Device APC prevents malicious access to internal devices. + +config DEVAPC_ARCH_MULTI + tristate "Mediatek Device APC driver architecture multi" + help + Say yes here to enable support Mediatek + Device APC driver which is based on Infra + architecture. + This architecture supports multiple Infra AO. + +config DEVAPC_MT6873 + tristate "Mediatek MT6873 Device APC driver" + select MTK_DEVAPC + select DEVAPC_ARCH_MULTI + help + Say yes here to enable support Mediatek MT6873 + Device APC driver. + This driver is combined with DEVAPC_ARCH_MULTI for + common handle flow. diff --git a/drivers/soc/mediatek/devapc/Makefile b/drivers/soc/mediatek/devapc/Makefile new file mode 100644 index 0000000..bd471f2 --- /dev/null +++ b/drivers/soc/mediatek/devapc/Makefile @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 + +ifeq ($(CONFIG_MTK_GCOV_KERNEL),y) +GCOV_PROFILE := y +endif + +obj-$(CONFIG_MTK_DEVAPC) := devapc.o + +# Core +devapc-$(CONFIG_DEVAPC_ARCH_MULTI) += devapc-mtk-multi-ao.o + +# Platform +devapc-$(CONFIG_DEVAPC_MT6873) += devapc-mt6873.o diff --git a/drivers/soc/mediatek/devapc/devapc-mt6873.c b/drivers/soc/mediatek/devapc/devapc-mt6873.c new file mode 100644 index 0000000..75a2140 --- /dev/null +++ b/drivers/soc/mediatek/devapc/devapc-mt6873.c @@ -0,0 +1,1652 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 MediaTek Inc. + */ + +#include +#include +#include +#include +#include + +#include "devapc-mt6873.h" +#include "devapc-mtk-multi-ao.h" + +static struct mtk_device_info mt6873_devices_infra[] = { + /* sys_idx, ctrl_idx, vio_idx */ + /* 0 */ + {0, 0, 0}, + {0, 1, 1}, + {0, 2, 2}, + {0, 3, 3}, + {0, 4, 4}, + {0, 5, 5}, + {0, 6, 6}, + {0, 7, 7}, + {0, 8, 8}, + {0, 9, 9}, + + /* 10 */ + {0, 10, 10}, + {0, 11, 11}, + {0, 12, 12}, + {0, 13, 13}, + {0, 14, 14}, + {0, 15, 15}, + {0, 16, 16}, + {0, 17, 17}, + {0, 18, 18}, + {0, 19, 19}, + + /* 20 */ + {0, 20, 20}, + {0, 21, 21}, + {0, 22, 352}, + {1, 0, 22}, + {1, 1, 23}, + {1, 2, 24}, + {1, 3, 25}, + {1, 4, 26}, + {1, 5, 27}, + {1, 6, 28}, + + /* 30 */ + {1, 7, 29}, + {1, 8, 30}, + {1, 9, 31}, + {1, 10, 32}, + {1, 11, 33}, + {1, 12, 34}, + {1, 13, 35}, + {1, 14, 36}, + {1, 15, 37}, + {1, 16, 38}, + + /* 40 */ + {1, 17, 39}, + {1, 18, 40}, + {1, 19, 41}, + {1, 20, 42}, + {1, 21, 43}, + {1, 22, 44}, + {1, 23, 45}, + {1, 24, 46}, + {1, 25, 47}, + {1, 26, 48}, + + /* 50 */ + {1, 27, 49}, + {1, 28, 50}, + {1, 29, 51}, + {1, 30, 52}, + {1, 31, 53}, + {1, 32, 54}, + {1, 33, 55}, + {1, 34, 56}, + {1, 35, 57}, + {1, 36, 58}, + + /* 60 */ + {1, 37, 59}, + {1, 38, 60}, + {1, 39, 61}, + {1, 40, 62}, + {1, 41, 63}, + {1, 42, 64}, + {1, 43, 65}, + {1, 44, 66}, + {1, 45, 67}, + {1, 46, 68}, + + /* 70 */ + {1, 47, 69}, + {1, 48, 70}, + {1, 49, 71}, + {1, 50, 72}, + {1, 51, 73}, + {1, 52, 74}, + {1, 53, 75}, + {1, 54, 76}, + {1, 55, 77}, + {1, 56, 78}, + + /* 80 */ + {1, 57, 79}, + {1, 58, 80}, + {1, 59, 81}, + {1, 60, 82}, + {1, 61, 83}, + {1, 62, 84}, + {1, 63, 85}, + {1, 64, 86}, + {1, 65, 87}, + {1, 66, 88}, + + /* 90 */ + {1, 67, 89}, + {1, 68, 90}, + {1, 69, 91}, + {1, 70, 92}, + {1, 71, 93}, + {1, 72, 94}, + {1, 73, 95}, + {1, 74, 96}, + {1, 75, 97}, + {1, 76, 98}, + + /* 100 */ + {1, 77, 99}, + {1, 78, 100}, + {1, 79, 101}, + {1, 80, 102}, + {1, 81, 103}, + {1, 82, 104}, + {1, 83, 105}, + {1, 84, 106}, + {1, 85, 107}, + {1, 86, 108}, + + /* 110 */ + {1, 87, 109}, + {1, 88, 110}, + {1, 89, 111}, + {1, 90, 112}, + {1, 91, 113}, + {1, 92, 114}, + {1, 93, 115}, + {1, 94, 116}, + {1, 95, 117}, + {1, 96, 118}, + + /* 120 */ + {1, 97, 119}, + {1, 98, 120}, + {1, 99, 121}, + {1, 100, 122}, + {1, 101, 123}, + {1, 102, 124}, + {1, 103, 125}, + {1, 104, 126}, + {1, 105, 127}, + {1, 106, 128}, + + /* 130 */ + {1, 107, 129}, + {1, 108, 130}, + {1, 109, 131}, + {1, 110, 132}, + {1, 111, 133}, + {1, 112, 134}, + {1, 113, 135}, + {1, 114, 136}, + {1, 115, 137}, + {1, 116, 138}, + + /* 140 */ + {1, 117, 139}, + {1, 118, 140}, + {1, 119, 141}, + {1, 120, 142}, + {1, 121, 143}, + {1, 122, 144}, + {1, 123, 145}, + {1, 124, 146}, + {1, 125, 147}, + {1, 126, 148}, + + /* 150 */ + {1, 127, 149}, + {1, 128, 150}, + {1, 129, 151}, + {1, 130, 152}, + {1, 131, 153}, + {1, 132, 154}, + {1, 133, 155}, + {1, 134, 156}, + {1, 135, 157}, + {1, 136, 158}, + + /* 160 */ + {1, 137, 159}, + {1, 138, 160}, + {1, 139, 161}, + {1, 140, 162}, + {1, 141, 163}, + {1, 142, 164}, + {1, 143, 165}, + {1, 144, 166}, + {1, 145, 167}, + {1, 146, 168}, + + /* 170 */ + {1, 147, 169}, + {1, 148, 170}, + {1, 149, 171}, + {1, 150, 172}, + {1, 151, 173}, + {1, 152, 174}, + {1, 153, 175}, + {1, 154, 176}, + {1, 155, 177}, + {1, 156, 178}, + + /* 180 */ + {1, 157, 179}, + {1, 158, 180}, + {1, 159, 181}, + {1, 160, 182}, + {1, 161, 183}, + {1, 162, 184}, + {1, 163, 185}, + {1, 164, 186}, + {1, 165, 187}, + {1, 166, 188}, + + /* 190 */ + {1, 167, 189}, + {1, 168, 190}, + {1, 169, 191}, + {1, 170, 192}, + {1, 171, 193}, + {1, 172, 194}, + {1, 173, 195}, + {1, 174, 196}, + {1, 175, 197}, + {1, 176, 198}, + + /* 200 */ + {1, 177, 199}, + {1, 178, 200}, + {1, 179, 201}, + {1, 180, 202}, + {1, 181, 203}, + {1, 182, 204}, + {1, 183, 205}, + {1, 184, 206}, + {1, 185, 207}, + {1, 186, 208}, + + /* 210 */ + {1, 187, 209}, + {1, 188, 210}, + {1, 189, 211}, + {1, 190, 212}, + {1, 191, 213}, + {1, 192, 214}, + {1, 193, 215}, + {1, 194, 216}, + {1, 195, 217}, + {1, 196, 218}, + + /* 220 */ + {1, 197, 219}, + {1, 198, 220}, + {1, 199, 221}, + {1, 200, 222}, + {1, 201, 223}, + {1, 202, 224}, + {1, 203, 225}, + {1, 204, 226}, + {1, 205, 227}, + {1, 206, 228}, + + /* 230 */ + {1, 207, 229}, + {1, 208, 230}, + {1, 209, 231}, + {1, 210, 232}, + {1, 211, 233}, + {1, 212, 234}, + {1, 213, 235}, + {1, 214, 236}, + {1, 215, 237}, + {1, 216, 238}, + + /* 240 */ + {1, 217, 239}, + {1, 218, 240}, + {1, 219, 241}, + {1, 220, 242}, + {1, 221, 243}, + {1, 222, 244}, + {1, 223, 245}, + {1, 224, 246}, + {1, 225, 247}, + {1, 226, 248}, + + /* 250 */ + {1, 227, 249}, + {1, 228, 250}, + {1, 229, 251}, + {1, 230, 252}, + {1, 231, 253}, + {1, 232, 254}, + {1, 233, 255}, + {1, 234, 256}, + {1, 235, 257}, + {1, 236, 258}, + + /* 260 */ + {1, 237, 259}, + {1, 238, 260}, + {1, 239, 261}, + {1, 240, 262}, + {1, 241, 263}, + {1, 242, 264}, + {1, 243, 265}, + {1, 244, 266}, + {1, 245, 267}, + {1, 246, 268}, + + /* 270 */ + {1, 247, 269}, + {1, 248, 270}, + {1, 249, 271}, + {1, 250, 272}, + {1, 251, 273}, + {1, 252, 274}, + {1, 253, 275}, + {1, 254, 276}, + {1, 255, 277}, + {2, 0, 278}, + + /* 280 */ + {2, 1, 279}, + {2, 2, 280}, + {2, 3, 281}, + {2, 4, 282}, + {2, 5, 283}, + {2, 6, 284}, + {2, 7, 285}, + {2, 8, 286}, + {2, 9, 287}, + {2, 10, 288}, + + /* 290 */ + {2, 11, 289}, + {2, 12, 290}, + {2, 13, 291}, + {2, 14, 292}, + {2, 15, 293}, + {2, 16, 294}, + {2, 17, 295}, + {2, 18, 296}, + {2, 19, 297}, + {2, 20, 298}, + + /* 300 */ + {2, 21, 299}, + {2, 22, 300}, + {2, 23, 301}, + {2, 24, 302}, + {2, 25, 303}, + {2, 26, 304}, + {2, 27, 305}, + {2, 28, 306}, + {2, 29, 307}, + {2, 30, 308}, + + /* 310 */ + {2, 31, 309}, + {2, 32, 310}, + {2, 33, 311}, + {2, 34, 312}, + {2, 35, 313}, + {2, 36, 314}, + {2, 37, 315}, + {2, 38, 316}, + {2, 39, 317}, + {2, 40, 318}, + + /* 320 */ + {2, 41, 319}, + {2, 42, 320}, + {2, 43, 321}, + {2, 44, 322}, + {2, 45, 323}, + {2, 46, 324}, + {2, 47, 325}, + {2, 48, 326}, + {2, 49, 327}, + {2, 50, 328}, + + /* 330 */ + {2, 51, 329}, + {2, 52, 330}, + {2, 53, 331}, + {2, 54, 332}, + {2, 55, 333}, + {2, 56, 334}, + {2, 57, 335}, + {2, 58, 336}, + {2, 59, 337}, + {2, 60, 338}, + + /* 340 */ + {2, 61, 339}, + {2, 62, 340}, + {2, 63, 341}, + {2, 64, 342}, + {2, 65, 343}, + {2, 66, 344}, + {2, 67, 345}, + {2, 68, 346}, + {2, 69, 347}, + {-1, -1, 355}, + + /* 350 */ + {-1, -1, 356}, + {-1, -1, 357}, + {-1, -1, 358}, + {-1, -1, 359}, + {-1, -1, 360}, + {-1, -1, 361}, + {-1, -1, 362}, + {-1, -1, 363}, + {-1, -1, 364}, + {-1, -1, 365}, + + /* 360 */ + {-1, -1, 366}, + {-1, -1, 367}, + {-1, -1, 368}, + {-1, -1, 369}, + {-1, -1, 370}, + {-1, -1, 371}, + +}; + +static struct mtk_device_info mt6873_devices_peri[] = { + /* sys_idx, ctrl_idx, vio_idx */ + /* 0 */ + {0, 0, 0}, + {0, 1, 1}, + {0, 2, 2}, + {0, 3, 3}, + {0, 4, 4}, + {0, 5, 5}, + {0, 6, 6}, + {0, 7, 7}, + {0, 8, 8}, + {0, 9, 9}, + + /* 10 */ + {0, 10, 10}, + {0, 11, 11}, + {0, 12, 13}, + {0, 13, 14}, + {0, 14, 15}, + {0, 15, 16}, + {0, 16, 17}, + {0, 17, 18}, + {0, 18, 19}, + {0, 19, 20}, + + /* 20 */ + {0, 20, 21}, + {0, 21, 23}, + {0, 22, 24}, + {0, 23, 25}, + {0, 24, 26}, + {0, 25, 27}, + {0, 26, 28}, + {0, 27, 29}, + {0, 28, 30}, + {0, 29, 31}, + + /* 30 */ + {0, 30, 32}, + {0, 31, 33}, + {0, 32, 34}, + {0, 33, 35}, + {0, 34, 36}, + {0, 35, 37}, + {0, 36, 38}, + {0, 37, 62}, + {0, 38, 63}, + {0, 39, 64}, + + /* 40 */ + {0, 40, 65}, + {0, 41, 66}, + {0, 42, 67}, + {0, 43, 68}, + {0, 44, 69}, + {0, 45, 70}, + {0, 46, 71}, + {0, 47, 72}, + {0, 48, 73}, + {0, 49, 74}, + + /* 50 */ + {0, 50, 119}, + {0, 51, 120}, + {0, 52, 121}, + {0, 53, 122}, + {0, 54, 123}, + {0, 55, 124}, + {0, 56, 125}, + {0, 57, 126}, + {0, 58, 127}, + {0, 59, 128}, + + /* 60 */ + {0, 60, 129}, + {0, 61, 130}, + {0, 62, 137}, + {0, 63, 143}, + {0, 64, 144}, + {0, 65, 145}, + {0, 66, 146}, + {0, 67, 147}, + {0, 68, 148}, + {0, 69, 149}, + + /* 70 */ + {0, 70, 150}, + {0, 71, 151}, + {0, 72, 152}, + {0, 73, 153}, + {0, 74, 154}, + {0, 75, 155}, + {0, 76, 156}, + {0, 77, 157}, + {0, 78, 158}, + {0, 79, 159}, + + /* 80 */ + {0, 80, 160}, + {0, 81, 161}, + {0, 82, 162}, + {0, 83, 163}, + {0, 84, 164}, + {0, 85, 165}, + {0, 86, 166}, + {0, 87, 167}, + {0, 88, 168}, + {0, 89, 169}, + + /* 90 */ + {0, 90, 170}, + {0, 91, 171}, + {0, 92, 174}, + {0, 93, 175}, + {0, 94, 176}, + {0, 95, 177}, + {0, 96, 178}, + {0, 97, 179}, + {0, 98, 180}, + {0, 99, 181}, + + /* 100 */ + {0, 100, 182}, + {0, 101, 183}, + {0, 102, 184}, + {0, 103, 185}, + {0, 104, 186}, + {1, 0, 39}, + {1, 1, 40}, + {1, 2, 41}, + {1, 3, 42}, + {1, 4, 43}, + + /* 110 */ + {1, 5, 44}, + {1, 6, 45}, + {1, 7, 46}, + {1, 8, 47}, + {1, 9, 48}, + {1, 10, 49}, + {1, 11, 50}, + {1, 12, 51}, + {1, 13, 52}, + {1, 14, 53}, + + /* 120 */ + {1, 15, 54}, + {1, 16, 55}, + {1, 17, 56}, + {1, 18, 57}, + {1, 19, 58}, + {1, 20, 59}, + {1, 21, 60}, + {1, 22, 61}, + {1, 23, 76}, + {1, 24, 77}, + + /* 130 */ + {1, 25, 78}, + {1, 26, 79}, + {1, 27, 80}, + {1, 28, 81}, + {1, 29, 82}, + {1, 30, 83}, + {1, 31, 84}, + {1, 32, 85}, + {1, 33, 86}, + {1, 34, 87}, + + /* 140 */ + {1, 35, 88}, + {1, 36, 89}, + {1, 37, 90}, + {1, 38, 91}, + {1, 39, 92}, + {1, 40, 93}, + {1, 41, 94}, + {1, 42, 95}, + {1, 43, 96}, + {1, 44, 97}, + + /* 150 */ + {1, 45, 98}, + {1, 46, 99}, + {1, 47, 100}, + {1, 48, 101}, + {1, 49, 102}, + {1, 50, 103}, + {1, 51, 104}, + {1, 52, 105}, + {1, 53, 106}, + {1, 54, 107}, + + /* 160 */ + {1, 55, 108}, + {1, 56, 109}, + {1, 57, 110}, + {1, 58, 111}, + {1, 59, 112}, + {1, 60, 113}, + {1, 61, 114}, + {1, 62, 115}, + {1, 63, 116}, + {1, 64, 117}, + + /* 170 */ + {1, 65, 118}, + {2, 0, 75}, + {-1, -1, 187}, + {-1, -1, 188}, + {-1, -1, 189}, + {-1, -1, 190}, + {-1, -1, 191}, + {-1, -1, 192}, + {-1, -1, 193}, + {-1, -1, 194}, + + /* 180 */ + {-1, -1, 195}, + {-1, -1, 196}, + {-1, -1, 197}, + {-1, -1, 198}, + {-1, -1, 199}, + {-1, -1, 200}, + {-1, -1, 201}, + {-1, -1, 202}, + {-1, -1, 203}, + {-1, -1, 204}, + + /* 190 */ + {-1, -1, 205}, + {-1, -1, 206}, + {-1, -1, 207}, + {-1, -1, 208}, + {-1, -1, 209}, + {-1, -1, 210}, + {-1, -1, 211}, + {-1, -1, 212}, + {-1, -1, 213}, + {-1, -1, 214}, + + /* 200 */ + {-1, -1, 215}, + {-1, -1, 216}, + {-1, -1, 217}, + {-1, -1, 218}, + {-1, -1, 219}, + {-1, -1, 220}, + {-1, -1, 221}, + {-1, -1, 222}, + {-1, -1, 223}, + {-1, -1, 224}, + + /* 210 */ + {-1, -1, 225}, + {-1, -1, 226}, + {-1, -1, 227}, + {-1, -1, 228}, + {-1, -1, 229}, + {-1, -1, 230}, + {-1, -1, 231}, + {-1, -1, 232}, + {-1, -1, 233}, + {-1, -1, 234}, + + /* 220 */ + {-1, -1, 235}, + {-1, -1, 236}, + {-1, -1, 237}, + {-1, -1, 238}, + {-1, -1, 239}, + {-1, -1, 240}, + {-1, -1, 241}, + {-1, -1, 242}, + {-1, -1, 243}, + {-1, -1, 244}, + + /* 230 */ + {-1, -1, 245}, + {-1, -1, 246}, + {-1, -1, 247}, + {-1, -1, 248}, + {-1, -1, 249}, + {-1, -1, 250}, + {-1, -1, 251}, + {-1, -1, 252}, + {-1, -1, 253}, + {-1, -1, 254}, + + /* 240 */ + {-1, -1, 255}, + {-1, -1, 256}, + {-1, -1, 257}, + {-1, -1, 258}, + {-1, -1, 259}, + {-1, -1, 260}, + {-1, -1, 261}, + {-1, -1, 262}, + {-1, -1, 263}, + {-1, -1, 264}, + + /* 250 */ + {-1, -1, 265}, + {-1, -1, 266}, + {-1, -1, 267}, + {-1, -1, 268}, + {-1, -1, 269}, + {-1, -1, 270}, + {-1, -1, 271}, + {-1, -1, 272}, + {-1, -1, 273}, + {-1, -1, 274}, + + /* 260 */ + {-1, -1, 275}, + {-1, -1, 276}, + {-1, -1, 277}, + {-1, -1, 278}, + {-1, -1, 279}, + {-1, -1, 280}, + {-1, -1, 281}, + {-1, -1, 282}, + {-1, -1, 283}, + {-1, -1, 284}, + + /* 270 */ + {-1, -1, 285}, + {-1, -1, 286}, + {-1, -1, 287}, + {-1, -1, 288}, + {-1, -1, 289}, + {-1, -1, 290}, + {-1, -1, 291}, + {-1, -1, 292}, + {-1, -1, 293}, + {-1, -1, 294}, + + /* 280 */ + {-1, -1, 295}, + {-1, -1, 296}, + {-1, -1, 297}, + {-1, -1, 298}, + +}; + +static struct mtk_device_info mt6873_devices_peri2[] = { + /* sys_idx, ctrl_idx, vio_idx */ + /* 0 */ + {0, 0, 0}, + {0, 1, 1}, + {0, 2, 2}, + {0, 3, 3}, + {0, 4, 4}, + {0, 5, 5}, + {0, 6, 6}, + {0, 7, 7}, + {0, 8, 8}, + {0, 9, 9}, + + /* 10 */ + {0, 10, 10}, + {0, 11, 11}, + {0, 12, 12}, + {0, 13, 13}, + {0, 14, 14}, + {0, 15, 15}, + {0, 16, 16}, + {0, 17, 17}, + {0, 18, 18}, + {0, 19, 19}, + + /* 20 */ + {0, 20, 20}, + {0, 21, 21}, + {0, 22, 22}, + {0, 23, 23}, + {0, 24, 24}, + {0, 25, 25}, + {0, 26, 26}, + {0, 27, 27}, + {0, 28, 28}, + {0, 29, 29}, + + /* 30 */ + {0, 30, 30}, + {0, 31, 31}, + {0, 32, 32}, + {0, 33, 33}, + {0, 34, 34}, + {0, 35, 35}, + {0, 36, 36}, + {0, 37, 37}, + {0, 38, 38}, + {0, 39, 39}, + + /* 40 */ + {0, 40, 40}, + {0, 41, 41}, + {0, 42, 42}, + {0, 43, 43}, + {0, 44, 44}, + {0, 45, 45}, + {0, 46, 46}, + {0, 47, 47}, + {0, 48, 48}, + {0, 49, 49}, + + /* 50 */ + {0, 50, 50}, + {0, 51, 51}, + {0, 52, 52}, + {0, 53, 53}, + {0, 54, 54}, + {0, 55, 55}, + {0, 56, 56}, + {0, 57, 57}, + {0, 58, 58}, + {0, 59, 59}, + + /* 60 */ + {0, 60, 60}, + {0, 61, 61}, + {0, 62, 62}, + {0, 63, 63}, + {0, 64, 64}, + {0, 65, 65}, + {0, 66, 66}, + {0, 67, 67}, + {0, 68, 68}, + {0, 69, 69}, + + /* 70 */ + {0, 70, 70}, + {0, 71, 71}, + {0, 72, 72}, + {0, 73, 73}, + {0, 74, 74}, + {0, 75, 75}, + {0, 76, 76}, + {0, 77, 77}, + {0, 78, 78}, + {0, 79, 79}, + + /* 80 */ + {0, 80, 80}, + {0, 81, 81}, + {0, 82, 82}, + {0, 83, 83}, + {0, 84, 84}, + {0, 85, 85}, + {0, 86, 86}, + {0, 87, 87}, + {0, 88, 88}, + {0, 89, 89}, + + /* 90 */ + {0, 90, 90}, + {0, 91, 91}, + {0, 92, 92}, + {0, 93, 93}, + {0, 94, 94}, + {0, 95, 95}, + {0, 96, 96}, + {0, 97, 97}, + {0, 98, 98}, + {0, 99, 99}, + + /* 100 */ + {0, 100, 100}, + {0, 101, 103}, + {0, 102, 104}, + {0, 103, 105}, + {0, 104, 106}, + {0, 105, 107}, + {0, 106, 108}, + {0, 107, 109}, + {0, 108, 110}, + {0, 109, 111}, + + /* 110 */ + {0, 110, 112}, + {0, 111, 113}, + {0, 112, 114}, + {0, 113, 115}, + {0, 114, 116}, + {-1, -1, 117}, + {-1, -1, 118}, + {-1, -1, 119}, + {-1, -1, 120}, + {-1, -1, 121}, + + /* 120 */ + {-1, -1, 122}, + {-1, -1, 123}, + {-1, -1, 124}, + {-1, -1, 125}, + {-1, -1, 126}, + {-1, -1, 127}, + {-1, -1, 128}, + {-1, -1, 129}, + {-1, -1, 130}, + {-1, -1, 131}, + + /* 130 */ + {-1, -1, 132}, + {-1, -1, 133}, + {-1, -1, 134}, + {-1, -1, 135}, + {-1, -1, 136}, + {-1, -1, 137}, + {-1, -1, 138}, + {-1, -1, 139}, + {-1, -1, 140}, + {-1, -1, 141}, + + /* 140 */ + {-1, -1, 142}, + {-1, -1, 143}, + {-1, -1, 144}, + {-1, -1, 145}, + {-1, -1, 146}, + {-1, -1, 147}, + {-1, -1, 148}, + {-1, -1, 149}, + {-1, -1, 150}, + {-1, -1, 151}, + + /* 150 */ + {-1, -1, 152}, + {-1, -1, 153}, + {-1, -1, 154}, + {-1, -1, 155}, + {-1, -1, 156}, + {-1, -1, 157}, + {-1, -1, 158}, + {-1, -1, 159}, + {-1, -1, 160}, + {-1, -1, 161}, + + /* 160 */ + {-1, -1, 162}, + {-1, -1, 163}, + {-1, -1, 164}, + {-1, -1, 165}, + {-1, -1, 166}, + {-1, -1, 167}, + {-1, -1, 168}, + {-1, -1, 169}, + {-1, -1, 170}, + {-1, -1, 171}, + + /* 170 */ + {-1, -1, 172}, + {-1, -1, 173}, + {-1, -1, 174}, + {-1, -1, 175}, + {-1, -1, 176}, + {-1, -1, 177}, + {-1, -1, 178}, + {-1, -1, 179}, + {-1, -1, 180}, + {-1, -1, 181}, + + /* 180 */ + {-1, -1, 182}, + {-1, -1, 183}, + {-1, -1, 184}, + {-1, -1, 185}, + {-1, -1, 186}, + {-1, -1, 187}, + {-1, -1, 188}, + {-1, -1, 189}, + {-1, -1, 190}, + {-1, -1, 191}, + + /* 190 */ + {-1, -1, 192}, + {-1, -1, 193}, + {-1, -1, 194}, + {-1, -1, 195}, + {-1, -1, 196}, + {-1, -1, 197}, + {-1, -1, 198}, + {-1, -1, 199}, + {-1, -1, 200}, + {-1, -1, 201}, + + /* 200 */ + {-1, -1, 202}, + {-1, -1, 203}, + {-1, -1, 204}, + {-1, -1, 205}, + {-1, -1, 206}, + {-1, -1, 207}, + {-1, -1, 208}, + {-1, -1, 209}, + {-1, -1, 210}, + {-1, -1, 211}, + + /* 210 */ + {-1, -1, 212}, + {-1, -1, 213}, + {-1, -1, 214}, + {-1, -1, 215}, + {-1, -1, 216}, + {-1, -1, 217}, + {-1, -1, 218}, + {-1, -1, 219}, + {-1, -1, 220}, + {-1, -1, 221}, + + /* 220 */ + {-1, -1, 222}, + {-1, -1, 223}, + {-1, -1, 224}, + {-1, -1, 225}, + {-1, -1, 226}, + {-1, -1, 227}, + {-1, -1, 228}, + {-1, -1, 229}, + {-1, -1, 230}, + {-1, -1, 231}, + + /* 230 */ + {-1, -1, 232}, + {-1, -1, 233}, + {-1, -1, 234}, + {-1, -1, 235}, + {-1, -1, 236}, + {-1, -1, 237}, + {-1, -1, 238}, + {-1, -1, 239}, + {-1, -1, 240}, + {-1, -1, 241}, + + /* 240 */ + {-1, -1, 242}, + {-1, -1, 243}, + {-1, -1, 244}, + {-1, -1, 245}, + {-1, -1, 246}, + {-1, -1, 247}, + {-1, -1, 248}, + +}; + +static struct mtk_device_info mt6873_devices_peri_par[] = { + /* sys_idx, ctrl_idx, vio_idx */ + /* 0 */ + {0, 0, 0}, + {0, 1, 1}, + {0, 2, 2}, + {0, 3, 3}, + {0, 4, 4}, + {0, 5, 5}, + {0, 6, 6}, + {0, 7, 7}, + {0, 8, 8}, + {0, 9, 9}, + + /* 10 */ + {0, 10, 10}, + {0, 11, 11}, + {0, 12, 12}, + {0, 13, 13}, + {0, 14, 14}, + {0, 15, 15}, + {0, 16, 16}, + {0, 17, 17}, + {0, 18, 18}, + {0, 19, 19}, + + /* 20 */ + {0, 20, 20}, + {0, 21, 21}, + {0, 22, 22}, + {0, 23, 23}, + {0, 24, 24}, + {0, 25, 25}, + {0, 26, 26}, + {-1, -1, 27}, + {-1, -1, 28}, + {-1, -1, 29}, + + /* 30 */ + {-1, -1, 30}, + {-1, -1, 31}, + {-1, -1, 32}, + {-1, -1, 33}, + {-1, -1, 34}, + {-1, -1, 35}, + {-1, -1, 36}, + {-1, -1, 37}, + {-1, -1, 38}, + {-1, -1, 39}, + + /* 40 */ + {-1, -1, 40}, + {-1, -1, 41}, + {-1, -1, 42}, + {-1, -1, 43}, + {-1, -1, 44}, + {-1, -1, 45}, + {-1, -1, 46}, + {-1, -1, 47}, + {-1, -1, 48}, + {-1, -1, 49}, + + /* 50 */ + {-1, -1, 50}, + {-1, -1, 51}, + {-1, -1, 52}, + {-1, -1, 53}, + {-1, -1, 54}, + {-1, -1, 55}, + {-1, -1, 56}, + {-1, -1, 57}, + +}; + +static struct mtk_device_num mtk6873_devices_num[] = { + {SLAVE_TYPE_INFRA, VIO_SLAVE_NUM_INFRA}, + {SLAVE_TYPE_PERI, VIO_SLAVE_NUM_PERI}, + {SLAVE_TYPE_PERI2, VIO_SLAVE_NUM_PERI2}, + {SLAVE_TYPE_PERI_PAR, VIO_SLAVE_NUM_PERI_PAR}, +}; + +static struct INFRAAXI_ID_INFO peri_mi_id_to_master[] = { + {"THERM2", 0x0, 0x7}, + {"SPM", 0x2, 0x7}, + {"CCU", 0x4, 0x7}, + {"THERM", 0x6, 0x7}, + {"SPM_DRAMC", 0x3, 0x7}, +}; + +static struct INFRAAXI_ID_INFO infra_mi_id_to_master[] = { + {"CONNSYS_WFDMA", 0x0, 0x3fff}, + {"CONNSYS_ICAP", 0x10, 0x3fff}, + {"CONNSYS_MCU_SYS", 0x20, 0x3fff}, + {"CONNSYS_GPS", 0x30, 0x3fff}, + {"Tinysys", 0x2, 0x3c0f}, + {"CQ_DMA", 0x4, 0x3c7f}, + {"DebugTop", 0x14, 0x3f7f}, + {"SSUSB", 0x24, 0xfff}, + {"SSUSB2", 0x424, 0xfff}, + {"NOR", 0x824, 0xfff}, + {"PWM", 0xc24, 0x3fff}, + {"SPI6", 0x2c24, 0x3fff}, + {"SPI0", 0x3c24, 0x3fff}, + {"APU", 0xa4, 0x33ff}, + {"SPI2", 0x124, 0x3fff}, + {"SPI3", 0x524, 0x3fff}, + {"SPI4", 0x924, 0x3fff}, + {"SPI5", 0xd24, 0x3fff}, + {"SPI7", 0x1a4, 0x3fff}, + {"Audio", 0x9a4, 0x3fff}, + {"SPI1", 0xda4, 0x3fff}, + {"AP_DMA_EXT", 0x224, 0x23ff}, + {"THERM2", 0x2a4, 0x3fff}, + {"SPM", 0x6a4, 0x3fff}, + {"CCU", 0xaa4, 0x3fff}, + {"THERM", 0xea4, 0x3fff}, + {"DX_CC", 0x34, 0x387f}, + {"GCE", 0x44, 0x3e7f}, + {"PCIE", 0x64, 0x307f}, + {"DPMAIF", 0x6, 0x3f0f}, + {"SSPM", 0x8, 0x3f8f}, + {"UFS", 0xa, 0x3f9f}, + {"MSDC0", 0x1a, 0x3fff}, + {"MSDC1", 0x3a, 0x3fff}, + {"MSDC2", 0x7a, 0x3fff}, + {"CPUEB", 0xc, 0x3c0f}, + {"APMCU_write", 0x1, 0x3fe1}, + {"APMCU_write", 0x81, 0x3fe1}, + {"APMCU_write", 0x201, 0x3e01}, + {"APMCU_read", 0x1, 0x3fe1}, + {"APMCU_read", 0x81, 0x3fe1}, + {"APMCU_read", 0x101, 0x3ffd}, + {"APMCU_read", 0x105, 0x3ffd}, + {"APMCU_read", 0x201, 0x3e01}, + {"APMCU_read", 0x401, 0x3c01}, +}; + +static const char *infra_mi_trans(u32 bus_id) +{ + int master_count = ARRAY_SIZE(infra_mi_id_to_master); + const char *master = "UNKNOWN_MASTER_FROM_INFRA"; + int i; + + for (i = 0; i < master_count; i++) { + if ((bus_id & infra_mi_id_to_master[i].mask) == + infra_mi_id_to_master[i].bus_id) + master = infra_mi_id_to_master[i].master; + } + + return master; +} + +static const char *peri_mi_trans(u32 bus_id) +{ + int master_count = ARRAY_SIZE(peri_mi_id_to_master); + const char *master = "UNKNOWN_MASTER_FROM_PERI"; + int i; + + if ((bus_id & 0x3) == 0x0) + return infra_mi_trans(bus_id >> 2); + else if ((bus_id & 0x3) == 0x2) + return "MD_AP_M"; + else if ((bus_id & 0x3) == 0x3) + return "AP_DMA_M"; + + bus_id = bus_id >> 2; + + for (i = 0 ; i < master_count; i++) { + if ((bus_id & peri_mi_id_to_master[i].mask) == + peri_mi_id_to_master[i].bus_id) + master = infra_mi_id_to_master[i].master; + } + + return master; +} + +static const char *mt6873_bus_id_to_master(u32 bus_id, u32 vio_addr, + int slave_type, int shift_sta_bit, + int domain) +{ + u8 h_1byte; + + if (bus_id == 0x0 && vio_addr == 0x0) + return NULL; + + h_1byte = (vio_addr >> 24) & 0xFF; + + if (slave_type == SLAVE_TYPE_INFRA) { + if (vio_addr <= 0x1FFFFF) { + if ((bus_id & 0x1) == 0) + return "EMI_L2C_M"; + + return infra_mi_trans(bus_id >> 1); + + } else if (shift_sta_bit == 3) { + if ((bus_id & 0x1) == 0) + return "EMI_L2C_M"; + + return infra_mi_trans(bus_id >> 1); + + } else if (shift_sta_bit == 4) { + if ((bus_id & 0x1) == 1) + return "GCE_M"; + + return infra_mi_trans(bus_id >> 1); + } + + return infra_mi_trans(bus_id); + + } else if (slave_type == SLAVE_TYPE_PERI) { + if ((h_1byte >= 0x14 && h_1byte < 0x18) || + (h_1byte >= 0x1A && h_1byte < 0x1C) || + (h_1byte >= 0x1F && h_1byte < 0x20)) { + if ((bus_id & 0x1) == 1) + return "GCE_M"; + + return infra_mi_trans(bus_id >> 1); + } + + if (shift_sta_bit == 3 || shift_sta_bit == 4 || + shift_sta_bit == 8) { + if ((bus_id & 0x1) == 0) + return "MD_AP_M"; + + return peri_mi_trans(bus_id >> 1); + } + return peri_mi_trans(bus_id); + + } else if (slave_type == SLAVE_TYPE_PERI2) { + return peri_mi_trans(bus_id); + + } else if (slave_type == SLAVE_TYPE_PERI_PAR) { + return peri_mi_trans(bus_id); + } + + return "UNKNOWN_MASTER"; +} + +static void mm2nd_vio_handler(void __iomem *infracfg, + struct mtk_devapc_vio_info *vio_info, + bool mdp_vio, bool disp2_vio, bool mmsys_vio) +{ + u32 vio_sta, vio_dbg, rw; + u32 vio_sta_num; + u32 vio0_offset; + char mm_str[64] = {0}; + void __iomem *reg; + int i; + + if (!infracfg) + return; + + if (mdp_vio) { + vio_sta_num = INFRACFG_MDP_VIO_STA_NUM; + vio0_offset = INFRACFG_MDP_SEC_VIO0_OFFSET; + + strncpy(mm_str, "INFRACFG_MDP_SEC_VIO", + sizeof("INFRACFG_MDP_SEC_VIO")); + + } else if (mmsys_vio) { + vio_sta_num = INFRACFG_MM_VIO_STA_NUM; + vio0_offset = INFRACFG_MM_SEC_VIO0_OFFSET; + + strncpy(mm_str, "INFRACFG_MM_SEC_VIO", + sizeof("INFRACFG_MM_SEC_VIO")); + + } else { + pr_err(PFX "%s: param check failed, mdp_vio:%s, disp2_vio:%s, mmsys_vio:%s\n", + __func__, mdp_vio ? "true" : "false", + disp2_vio ? "true" : "false", + mmsys_vio ? "true" : "false"); + return; + } + + /* Get mm2nd violation status */ + for (i = 0; i < vio_sta_num; i++) { + reg = infracfg + vio0_offset + i * 4; + vio_sta = readl(reg); + if (vio_sta) + pr_info(PFX "MM 2nd violation: %s%d:0x%x\n", + mm_str, i, vio_sta); + } + + /* Get mm2nd violation address */ + reg = infracfg + vio0_offset + i * 4; + vio_info->vio_addr = readl(reg); + + /* Get mm2nd violation information */ + reg = infracfg + vio0_offset + (i + 1) * 4; + vio_dbg = readl(reg); + + vio_info->domain_id = (vio_dbg & INFRACFG_MM2ND_VIO_DOMAIN_MASK) >> + INFRACFG_MM2ND_VIO_DOMAIN_SHIFT; + + vio_info->master_id = (vio_dbg & INFRACFG_MM2ND_VIO_ID_MASK) >> + INFRACFG_MM2ND_VIO_ID_SHIFT; + + rw = (vio_dbg & INFRACFG_MM2ND_VIO_RW_MASK) >> + INFRACFG_MM2ND_VIO_RW_SHIFT; + vio_info->read = (rw == 0); + vio_info->write = (rw == 1); +} + +static u32 mt6873_shift_group_get(int slave_type, u32 vio_idx) +{ + if (slave_type == SLAVE_TYPE_INFRA) { + if ((vio_idx >= 0 && vio_idx <= 8) || vio_idx == 355) + return 0; + else if ((vio_idx >= 9 && vio_idx <= 14) || vio_idx == 356) + return 1; + else if ((vio_idx >= 15 && vio_idx <= 19) || vio_idx == 357) + return 2; + else if ((vio_idx >= 20 && vio_idx <= 21) || vio_idx == 358) + return 3; + else if (vio_idx >= 22 && vio_idx <= 347) + return 4; + else if ((vio_idx >= 348 && vio_idx <= 354) || + (vio_idx >= 359 && vio_idx <= 365) || + vio_idx == 366) + return 5; + + pr_err(PFX "%s:%d Wrong vio_idx:0x%x\n", + __func__, __LINE__, vio_idx); + + } else if (slave_type == SLAVE_TYPE_PERI) { + if (vio_idx >= 0 && vio_idx <= 4) + return 0; + else if (vio_idx >= 5 && vio_idx <= 6) + return 1; + else if ((vio_idx >= 7 && vio_idx <= 38) || vio_idx == 187 || + (vio_idx >= 188 && vio_idx <= 219) || + vio_idx == 286) + return 2; + else if ((vio_idx >= 39 && vio_idx <= 61) || vio_idx == 220) + return 3; + else if ((vio_idx >= 62 && vio_idx <= 72) || vio_idx == 221) + return 4; + else if ((vio_idx >= 73 && vio_idx <= 74) || vio_idx == 222) + return 5; + else if (vio_idx == 75 || vio_idx == 223) + return 6; + else if ((vio_idx >= 76 && vio_idx <= 118) || vio_idx == 224) + return 7; + else if ((vio_idx >= 119 && vio_idx <= 121) || vio_idx == 225) + return 8; + if (vio_idx >= 122 && vio_idx <= 125) + return 9; + else if (vio_idx == 126 || (vio_idx >= 226 && vio_idx <= 227) || + vio_idx == 287) + return 10; + if (vio_idx >= 127 && vio_idx <= 128) + return 11; + if (vio_idx >= 129 && vio_idx <= 130) + return 12; + else if ((vio_idx >= 131 && vio_idx <= 141) || + (vio_idx >= 228 && vio_idx <= 238) || + vio_idx == 288) + return 13; + else if ((vio_idx >= 142 && vio_idx <= 143) || + (vio_idx >= 239 && vio_idx <= 240) || + vio_idx == 289) + return 14; + else if ((vio_idx >= 144 && vio_idx <= 173) || vio_idx == 241 || + (vio_idx >= 242 && vio_idx <= 271) || + vio_idx == 290) + return 15; + else if ((vio_idx >= 174 && vio_idx <= 186) || vio_idx == 272 || + (vio_idx >= 273 && vio_idx <= 285) || + vio_idx == 291) + return 16; + + pr_err(PFX "%s:%d Wrong vio_idx:0x%x\n", + __func__, __LINE__, vio_idx); + + } else if (slave_type == SLAVE_TYPE_PERI2) { + if ((vio_idx >= 0 && vio_idx <= 12) || vio_idx == 117 || + (vio_idx >= 118 && vio_idx <= 130) || + vio_idx == 234) + return 0; + else if (vio_idx >= 13 && vio_idx <= 16) + return 1; + else if (vio_idx >= 17 && vio_idx <= 20) + return 2; + else if ((vio_idx >= 21 && vio_idx <= 36) || vio_idx == 131 || + (vio_idx >= 132 && vio_idx <= 147) || + vio_idx == 235) + return 3; + else if ((vio_idx >= 37 && vio_idx <= 44) || vio_idx == 148 || + (vio_idx >= 149 && vio_idx <= 156) || + vio_idx == 236) + return 4; + else if ((vio_idx >= 45 && vio_idx <= 60) || vio_idx == 157 || + (vio_idx >= 158 && vio_idx <= 173) || + vio_idx == 237) + return 5; + else if ((vio_idx >= 61 && vio_idx <= 76) || vio_idx == 174 || + (vio_idx >= 175 && vio_idx <= 190) || + vio_idx == 238) + return 6; + else if ((vio_idx >= 77 && vio_idx <= 84) || vio_idx == 191 || + (vio_idx >= 192 && vio_idx <= 199) || + vio_idx == 239) + return 7; + else if ((vio_idx >= 85 && vio_idx <= 105) || vio_idx == 200 || + (vio_idx >= 201 && vio_idx <= 221) || + vio_idx == 240) + return 8; + else if ((vio_idx >= 106 && vio_idx <= 116) || vio_idx == 222 || + (vio_idx >= 223 && vio_idx <= 233) || + vio_idx == 241) + return 9; + + pr_err(PFX "%s:%d Wrong vio_idx:0x%x\n", + __func__, __LINE__, vio_idx); + + } else if (slave_type == SLAVE_TYPE_PERI_PAR) { + if ((vio_idx >= 0 && vio_idx <= 23) || vio_idx == 27 || + (vio_idx >= 28 && vio_idx <= 51) || + vio_idx == 56) + return 0; + else if ((vio_idx >= 24 && vio_idx <= 26) || vio_idx == 52 || + (vio_idx >= 53 && vio_idx <= 55) || + vio_idx == 57) + return 1; + + pr_err(PFX "%s:%d Wrong vio_idx:0x%x\n", + __func__, __LINE__, vio_idx); + + } else { + pr_err(PFX "%s:%d Wrong slave_type:0x%x\n", + __func__, __LINE__, slave_type); + } + + return 31; +} + +static struct mtk_devapc_dbg_status mt6873_devapc_dbg_stat = { + .enable_ut = PLAT_DBG_UT_DEFAULT, + .enable_dapc = PLAT_DBG_DAPC_DEFAULT, +}; + +static const char * const slave_type_to_str[] = { + "SLAVE_TYPE_INFRA", + "SLAVE_TYPE_PERI", + "SLAVE_TYPE_PERI2", + "SLAVE_TYPE_PERI_PAR", + "WRONG_SLAVE_TYPE", +}; + +static int mtk_vio_mask_sta_num[] = { + VIO_MASK_STA_NUM_INFRA, + VIO_MASK_STA_NUM_PERI, + VIO_MASK_STA_NUM_PERI2, + VIO_MASK_STA_NUM_PERI_PAR, +}; + +static struct mtk_devapc_vio_info mt6873_devapc_vio_info = { + .vio_mask_sta_num = mtk_vio_mask_sta_num, + .sramrom_vio_idx = SRAMROM_VIO_INDEX, + .mdp_vio_idx = MDP_VIO_INDEX, + .disp2_vio_idx = MDP_VIO_INDEX, + .mmsys_vio_idx = MMSYS_VIO_INDEX, + .sramrom_slv_type = SRAMROM_SLAVE_TYPE, + .mm2nd_slv_type = MM2ND_SLAVE_TYPE, +}; + +static const struct mtk_infra_vio_dbg_desc mt6873_vio_dbgs = { + .vio_dbg_mstid = INFRA_VIO_DBG_MSTID, + .vio_dbg_mstid_start_bit = INFRA_VIO_DBG_MSTID_START_BIT, + .vio_dbg_dmnid = INFRA_VIO_DBG_DMNID, + .vio_dbg_dmnid_start_bit = INFRA_VIO_DBG_DMNID_START_BIT, + .vio_dbg_w_vio = INFRA_VIO_DBG_W_VIO, + .vio_dbg_w_vio_start_bit = INFRA_VIO_DBG_W_VIO_START_BIT, + .vio_dbg_r_vio = INFRA_VIO_DBG_R_VIO, + .vio_dbg_r_vio_start_bit = INFRA_VIO_DBG_R_VIO_START_BIT, + .vio_addr_high = INFRA_VIO_ADDR_HIGH, + .vio_addr_high_start_bit = INFRA_VIO_ADDR_HIGH_START_BIT, +}; + +static const struct mtk_sramrom_sec_vio_desc mt6873_sramrom_sec_vios = { + .vio_id_mask = SRAMROM_SEC_VIO_ID_MASK, + .vio_id_shift = SRAMROM_SEC_VIO_ID_SHIFT, + .vio_domain_mask = SRAMROM_SEC_VIO_DOMAIN_MASK, + .vio_domain_shift = SRAMROM_SEC_VIO_DOMAIN_SHIFT, + .vio_rw_mask = SRAMROM_SEC_VIO_RW_MASK, + .vio_rw_shift = SRAMROM_SEC_VIO_RW_SHIFT, +}; + +static const u32 mt6873_devapc_pds[] = { + PD_VIO_MASK_OFFSET, + PD_VIO_STA_OFFSET, + PD_VIO_DBG0_OFFSET, + PD_VIO_DBG1_OFFSET, + PD_VIO_DBG2_OFFSET, + PD_APC_CON_OFFSET, + PD_SHIFT_STA_OFFSET, + PD_SHIFT_SEL_OFFSET, + PD_SHIFT_CON_OFFSET, +}; + +static struct mtk_devapc_soc mt6873_data = { + .dbg_stat = &mt6873_devapc_dbg_stat, + .slave_type_arr = slave_type_to_str, + .slave_type_num = SLAVE_TYPE_NUM, + .device_info[SLAVE_TYPE_INFRA] = mt6873_devices_infra, + .device_info[SLAVE_TYPE_PERI] = mt6873_devices_peri, + .device_info[SLAVE_TYPE_PERI2] = mt6873_devices_peri2, + .device_info[SLAVE_TYPE_PERI_PAR] = mt6873_devices_peri_par, + .ndevices = mtk6873_devices_num, + .vio_info = &mt6873_devapc_vio_info, + .vio_dbgs = &mt6873_vio_dbgs, + .sramrom_sec_vios = &mt6873_sramrom_sec_vios, + .devapc_pds = mt6873_devapc_pds, + .master_get = &mt6873_bus_id_to_master, + .mm2nd_vio_handler = &mm2nd_vio_handler, + .shift_group_get = mt6873_shift_group_get, +}; + +static const struct of_device_id mt6873_devapc_dt_match[] = { + { .compatible = "mediatek,mt6873-devapc" }, + {}, +}; + +static int mt6873_devapc_probe(struct platform_device *pdev) +{ + return mtk_devapc_probe(pdev, &mt6873_data); +} + +static int mt6873_devapc_remove(struct platform_device *dev) +{ + return mtk_devapc_remove(dev); +} + +static struct platform_driver mt6873_devapc_driver = { + .probe = mt6873_devapc_probe, + .remove = mt6873_devapc_remove, + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = mt6873_devapc_dt_match, + }, +}; + +module_platform_driver(mt6873_devapc_driver); + +MODULE_DESCRIPTION("Mediatek MT6873 Device APC Driver"); +MODULE_AUTHOR("Neal Liu "); +MODULE_LICENSE("GPL"); diff --git a/drivers/soc/mediatek/devapc/devapc-mt6873.h b/drivers/soc/mediatek/devapc/devapc-mt6873.h new file mode 100644 index 0000000..16be09e --- /dev/null +++ b/drivers/soc/mediatek/devapc/devapc-mt6873.h @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 MediaTek Inc. + */ + +#ifndef __DEVAPC_MT6873_H__ +#define __DEVAPC_MT6873_H__ + +/****************************************************************************** + * VARIABLE DEFINITION + ******************************************************************************/ +/* dbg status default setting */ +#define PLAT_DBG_UT_DEFAULT false +#define PLAT_DBG_DAPC_DEFAULT false + +/****************************************************************************** + * STRUCTURE DEFINITION + ******************************************************************************/ +enum DEVAPC_SLAVE_TYPE { + SLAVE_TYPE_INFRA = 0, + SLAVE_TYPE_PERI, + SLAVE_TYPE_PERI2, + SLAVE_TYPE_PERI_PAR, + SLAVE_TYPE_NUM, +}; + +enum DEVAPC_VIO_MASK_STA_NUM { + VIO_MASK_STA_NUM_INFRA = 12, + VIO_MASK_STA_NUM_PERI = 10, + VIO_MASK_STA_NUM_PERI2 = 8, + VIO_MASK_STA_NUM_PERI_PAR = 2, +}; + +enum DEVAPC_VIO_SLAVE_NUM { + VIO_SLAVE_NUM_INFRA = 366, + VIO_SLAVE_NUM_PERI = 284, + VIO_SLAVE_NUM_PERI2 = 247, + VIO_SLAVE_NUM_PERI_PAR = 58, +}; + +enum DEVAPC_PD_OFFSET { + PD_VIO_MASK_OFFSET = 0x0, + PD_VIO_STA_OFFSET = 0x400, + PD_VIO_DBG0_OFFSET = 0x900, + PD_VIO_DBG1_OFFSET = 0x904, + PD_VIO_DBG2_OFFSET = 0x908, + PD_APC_CON_OFFSET = 0xF00, + PD_SHIFT_STA_OFFSET = 0xF20, + PD_SHIFT_SEL_OFFSET = 0xF30, + PD_SHIFT_CON_OFFSET = 0xF10, +}; + +#define SRAMROM_SLAVE_TYPE SLAVE_TYPE_INFRA /* Infra */ +#define MM2ND_SLAVE_TYPE SLAVE_TYPE_PERI /* Peri */ + +enum OTHER_TYPES_INDEX { + SRAMROM_VIO_INDEX = 367, + CONN_VIO_INDEX = 75, /* starts from 0x18 */ + MDP_VIO_INDEX = 292, + MMSYS_VIO_INDEX = 294, +}; + +enum INFRACFG_MM2ND_VIO_NUM { + INFRACFG_MM_VIO_STA_NUM = 2, + INFRACFG_MDP_VIO_STA_NUM = 8, +}; + +enum INFRACFG_MM2ND_OFFSET { + INFRACFG_MM_SEC_VIO0_OFFSET = 0xB30, + INFRACFG_MDP_SEC_VIO0_OFFSET = 0xB40, +}; + +struct INFRAAXI_ID_INFO { + const char *master; + u32 bus_id; + u32 mask; +}; + +/****************************************************************************** + * PLATFORM DEFINATION + ******************************************************************************/ + +/* For Infra VIO_DBG */ +#define INFRA_VIO_DBG_MSTID 0xFFFFFFFF +#define INFRA_VIO_DBG_MSTID_START_BIT 0 +#define INFRA_VIO_DBG_DMNID 0x0000003F +#define INFRA_VIO_DBG_DMNID_START_BIT 0 +#define INFRA_VIO_DBG_W_VIO 0x00000040 +#define INFRA_VIO_DBG_W_VIO_START_BIT 6 +#define INFRA_VIO_DBG_R_VIO 0x00000080 +#define INFRA_VIO_DBG_R_VIO_START_BIT 7 +#define INFRA_VIO_ADDR_HIGH 0x00000F00 +#define INFRA_VIO_ADDR_HIGH_START_BIT 8 + +/* For SRAMROM VIO */ +#define SRAMROM_SEC_VIO_ID_MASK 0x00FFFF00 +#define SRAMROM_SEC_VIO_ID_SHIFT 8 +#define SRAMROM_SEC_VIO_DOMAIN_MASK 0x0F000000 +#define SRAMROM_SEC_VIO_DOMAIN_SHIFT 24 +#define SRAMROM_SEC_VIO_RW_MASK 0x80000000 +#define SRAMROM_SEC_VIO_RW_SHIFT 31 + +/* For MM 2nd VIO */ +#define INFRACFG_MM2ND_VIO_DOMAIN_MASK 0x00000030 +#define INFRACFG_MM2ND_VIO_DOMAIN_SHIFT 4 +#define INFRACFG_MM2ND_VIO_ID_MASK 0x00FFFF00 +#define INFRACFG_MM2ND_VIO_ID_SHIFT 8 +#define INFRACFG_MM2ND_VIO_RW_MASK 0x01000000 +#define INFRACFG_MM2ND_VIO_RW_SHIFT 24 + +#endif /* __DEVAPC_MT6873_H__ */ diff --git a/drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.c b/drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.c new file mode 100644 index 0000000..6c4a8ec --- /dev/null +++ b/drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.c @@ -0,0 +1,756 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "devapc-mtk-multi-ao.h" + +/* + * mtk_devapc_pd_get - get devapc pd_types of register address. + * + * Returns the value of reg addr + */ +static void __iomem *mtk_devapc_pd_get(struct mtk_devapc_context *devapc_ctx, + int slave_type, + enum DEVAPC_PD_REG_TYPE pd_reg_type, + u32 index) +{ + struct mtk_devapc_vio_info *vio_info = devapc_ctx->soc->vio_info; + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + const u32 *devapc_pds = devapc_ctx->soc->devapc_pds; + void __iomem *reg; + + if (!devapc_pds) + return NULL; + + if ((slave_type < slave_type_num && + index < vio_info->vio_mask_sta_num[slave_type]) && + pd_reg_type < PD_REG_TYPE_NUM) { + reg = devapc_ctx->devapc_pd_base[slave_type] + + devapc_pds[pd_reg_type]; + + if (pd_reg_type == VIO_MASK || pd_reg_type == VIO_STA) + reg += 0x4 * index; + + } else { + pr_err(PFX "Out Of Boundary, slave_type:0x%x/pd_reg_type:0x%x/index:0x%x\n", + slave_type, pd_reg_type, index); + return NULL; + } + + return reg; +} + +/* + * sramrom_vio_handler - clean sramrom violation & print violation information + * for debugging. + */ +static void sramrom_vio_handler(struct mtk_devapc_context *devapc_ctx) +{ + const struct mtk_sramrom_sec_vio_desc *sramrom_vios; + struct mtk_devapc_vio_info *vio_info; + struct arm_smccc_res res; + size_t sramrom_vio_sta; + int sramrom_vio; + u32 rw; + + sramrom_vios = devapc_ctx->soc->sramrom_sec_vios; + vio_info = devapc_ctx->soc->vio_info; + + arm_smccc_smc(MTK_SIP_KERNEL_CLR_SRAMROM_VIO, + 0, 0, 0, 0, 0, 0, 0, &res); + + sramrom_vio = res.a0; + sramrom_vio_sta = res.a1; + vio_info->vio_addr = res.a2; + + if (sramrom_vio == SRAM_VIOLATION) + pr_info(PFX "SRAM violation is triggered\n"); + else if (sramrom_vio == ROM_VIOLATION) + pr_info(PFX "ROM violation is triggered\n"); + else + return; + + vio_info->master_id = (sramrom_vio_sta & sramrom_vios->vio_id_mask) + >> sramrom_vios->vio_id_shift; + vio_info->domain_id = (sramrom_vio_sta & sramrom_vios->vio_domain_mask) + >> sramrom_vios->vio_domain_shift; + rw = (sramrom_vio_sta & sramrom_vios->vio_rw_mask) >> + sramrom_vios->vio_rw_shift; + + if (rw) + vio_info->write = 1; + else + vio_info->read = 1; + + pr_info(PFX "%s: master_id:0x%x, domain_id:0x%x, rw:%s, vio_addr:0x%x\n", + __func__, vio_info->master_id, vio_info->domain_id, + rw ? "Write" : "Read", vio_info->vio_addr); +} + +static void mask_module_irq(struct mtk_devapc_context *devapc_ctx, + int slave_type, u32 module, bool mask) +{ + struct mtk_devapc_vio_info *vio_info = devapc_ctx->soc->vio_info; + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + u32 apc_register_index; + u32 apc_set_index; + void __iomem *reg; + + apc_register_index = module / (MOD_NO_IN_1_DEVAPC * 2); + apc_set_index = module % (MOD_NO_IN_1_DEVAPC * 2); + + if (slave_type < slave_type_num && + apc_register_index < vio_info->vio_mask_sta_num[slave_type]) { + reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_MASK, + apc_register_index); + + if (mask) + writel(readl(reg) | (1 << apc_set_index), reg); + else + writel(readl(reg) & (~(1 << apc_set_index)), reg); + + } else { + pr_err(PFX "%s: Out Of Boundary, slave_type:0x%x, module_index:0x%x, mask:%s\n", + __func__, slave_type, module, mask ? "true" : "false"); + } +} + +static int check_vio_mask(struct mtk_devapc_context *devapc_ctx, int slave_type, + u32 module) +{ + struct mtk_devapc_vio_info *vio_info = devapc_ctx->soc->vio_info; + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + u32 apc_register_index; + u32 apc_set_index; + void __iomem *reg; + + apc_register_index = module / (MOD_NO_IN_1_DEVAPC * 2); + apc_set_index = module % (MOD_NO_IN_1_DEVAPC * 2); + + if (slave_type < slave_type_num && + apc_register_index < vio_info->vio_mask_sta_num[slave_type]) + reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_MASK, + apc_register_index); + else + return -EOVERFLOW; + + if (readl(reg) & (0x1 << apc_set_index)) + return VIOLATION_MASKED; + + return 0; +} + +static int32_t check_vio_status(struct mtk_devapc_context *devapc_ctx, + int slave_type, u32 module) +{ + struct mtk_devapc_vio_info *vio_info = devapc_ctx->soc->vio_info; + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + u32 apc_register_index; + u32 apc_set_index; + void __iomem *reg; + + apc_register_index = module / (MOD_NO_IN_1_DEVAPC * 2); + apc_set_index = module % (MOD_NO_IN_1_DEVAPC * 2); + + if (slave_type < slave_type_num && + apc_register_index < vio_info->vio_mask_sta_num[slave_type]) { + reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_STA, + apc_register_index); + + } else { + pr_err(PFX "%s: Out Of Boundary, slave_type:0x%x, module_index:0x%x\n", + __func__, slave_type, module); + return -EOVERFLOW; + } + + if (readl(reg) & (0x1 << apc_set_index)) + return VIOLATION_TRIGGERED; + + return 0; +} + +static int32_t clear_vio_status(struct mtk_devapc_context *devapc_ctx, + int slave_type, u32 module) +{ + struct mtk_devapc_vio_info *vio_info = devapc_ctx->soc->vio_info; + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + u32 apc_register_index; + u32 apc_set_index; + void __iomem *reg; + + apc_register_index = module / (MOD_NO_IN_1_DEVAPC * 2); + apc_set_index = module % (MOD_NO_IN_1_DEVAPC * 2); + + if (slave_type < slave_type_num && + apc_register_index < vio_info->vio_mask_sta_num[slave_type]) { + reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_STA, + apc_register_index); + writel(0x1 << apc_set_index, reg); + + } else { + pr_err(PFX "%s: Out Of Boundary, slave_type:0x%x, module_index:0x%x\n", + __func__, slave_type, module); + return -EOVERFLOW; + } + + if (check_vio_status(devapc_ctx, slave_type, module)) + return -EIO; + + return 0; +} + +static void devapc_vio_info_print(struct mtk_devapc_context *devapc_ctx) +{ + struct mtk_devapc_vio_info *vio_info; + + vio_info = devapc_ctx->soc->vio_info; + + /* Print violation information */ + if (vio_info->write) + pr_info(PFX "Write Violation\n"); + else if (vio_info->read) + pr_info(PFX "Read Violation\n"); + + pr_info(PFX "%s%x, %s%x, %s%x, %s%x\n", + "Vio Addr:0x", vio_info->vio_addr, + "High:0x", vio_info->vio_addr_high, + "Bus ID:0x", vio_info->master_id, + "Dom ID:0x", vio_info->domain_id); +} + +/* + * check_type2_vio_status - there are type 2 slaves which violation information + * is stored in different register bank. + * + * Returns true if type2 violation is triggered. + */ +static bool check_type2_vio_status(struct mtk_devapc_context *devapc_ctx, + int slave_type, int *vio_idx, int *index) +{ + u32 sramrom_vio_idx, mdp_vio_idx, disp2_vio_idx, mmsys_vio_idx; + const struct mtk_device_info **device_info; + const struct mtk_device_num *ndevices; + int sramrom_slv_type, mm2nd_slv_type; + bool mdp_vio, disp2_vio, mmsys_vio; + int i; + + sramrom_slv_type = devapc_ctx->soc->vio_info->sramrom_slv_type; + sramrom_vio_idx = devapc_ctx->soc->vio_info->sramrom_vio_idx; + + mm2nd_slv_type = devapc_ctx->soc->vio_info->mm2nd_slv_type; + mdp_vio_idx = devapc_ctx->soc->vio_info->mdp_vio_idx; + disp2_vio_idx = devapc_ctx->soc->vio_info->disp2_vio_idx; + mmsys_vio_idx = devapc_ctx->soc->vio_info->mmsys_vio_idx; + + device_info = devapc_ctx->soc->device_info; + ndevices = devapc_ctx->soc->ndevices; + + /* check SRAMROM violation */ + if (slave_type == sramrom_slv_type && + check_vio_status(devapc_ctx, slave_type, sramrom_vio_idx)) { + pr_info(PFX "SRAMROM violation is triggered\n"); + sramrom_vio_handler(devapc_ctx); + + *vio_idx = sramrom_vio_idx; + for (i = 0; i < ndevices[slave_type].vio_slave_num; i++) { + if (device_info[slave_type][i].vio_index == *vio_idx) + *index = i; + } + + return true; + } + + /* check MM 2nd level violation */ + if (slave_type == mm2nd_slv_type) { + mdp_vio = check_vio_status(devapc_ctx, slave_type, + mdp_vio_idx) == + VIOLATION_TRIGGERED; + disp2_vio = check_vio_status(devapc_ctx, slave_type, + disp2_vio_idx) == + VIOLATION_TRIGGERED; + mmsys_vio = check_vio_status(devapc_ctx, slave_type, + mmsys_vio_idx) == + VIOLATION_TRIGGERED; + + if (mdp_vio || disp2_vio || mmsys_vio) { + pr_info(PFX "MM2nd violation is triggered\n"); + devapc_ctx->soc->mm2nd_vio_handler + (devapc_ctx->infracfg_base, + devapc_ctx->soc->vio_info, + mdp_vio, + disp2_vio, + mmsys_vio); + } else { + return false; + } + + if (mdp_vio) + *vio_idx = mdp_vio_idx; + else if (disp2_vio) + *vio_idx = disp2_vio_idx; + else if (mmsys_vio) + *vio_idx = mmsys_vio_idx; + + for (i = 0; i < ndevices[slave_type].vio_slave_num; i++) { + if (device_info[slave_type][i].vio_index == *vio_idx) + *index = i; + } + + devapc_vio_info_print(devapc_ctx); + return true; + } + + return false; +} + +/* + * sync_vio_dbg - start to get violation information by selecting violation + * group and enable violation shift. + * + * Returns sync done or not + */ +static u32 sync_vio_dbg(struct mtk_devapc_context *devapc_ctx, int slave_type, + u32 shift_bit) +{ + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + void __iomem *pd_vio_shift_sta_reg; + void __iomem *pd_vio_shift_sel_reg; + void __iomem *pd_vio_shift_con_reg; + u32 shift_count; + u32 sync_done; + + if (slave_type >= slave_type_num || + shift_bit >= (MOD_NO_IN_1_DEVAPC * 2)) { + pr_err(PFX "param check failed, slave_type:0x%x, shift_bit:0x%x\n", + slave_type, shift_bit); + return 0; + } + + pd_vio_shift_sta_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_STA, 0); + pd_vio_shift_sel_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_SEL, 0); + pd_vio_shift_con_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_CON, 0); + + writel(0x1 << shift_bit, pd_vio_shift_sel_reg); + writel(0x1, pd_vio_shift_con_reg); + + for (shift_count = 0; (shift_count < 100) && + ((readl(pd_vio_shift_con_reg) & 0x3) != 0x3); + ++shift_count) + ; + + if ((readl(pd_vio_shift_con_reg) & 0x3) == 0x3) + sync_done = 1; + else + sync_done = 0; + + /* Disable shift mechanism */ + writel(0x0, pd_vio_shift_con_reg); + writel(0x0, pd_vio_shift_sel_reg); + writel(0x1 << shift_bit, pd_vio_shift_sta_reg); + + return sync_done; +} + +static const char * const perm_to_str[] = { + "NO_PROTECTION", + "SECURE_RW_ONLY", + "SECURE_RW_NS_R_ONLY", + "FORBIDDEN", + "NO_PERM_CTRL" +}; + +static const char *perm_to_string(u8 perm) +{ + if (perm < PERM_TYPE_NUM) + return perm_to_str[perm]; + else + return perm_to_str[PERM_TYPE_NUM]; +} + +static void devapc_vio_reason(u8 perm) +{ + pr_info(PFX "Permission setting: %s\n", perm_to_string(perm)); + + if (perm == NO_PROTECTION || perm >= PERM_TYPE_NUM) + pr_info(PFX "Reason: power/clock is not enabled\n"); + else if (perm == SEC_RW_ONLY || + perm == SEC_RW_NS_R || + perm == FORBIDDEN) + pr_info(PFX "Reason: might be permission denied\n"); +} + +/* + * get_permission - get slave's access permission of domain id. + * + * Returns the value of access permission + */ +static u8 get_permission(struct mtk_devapc_context *devapc_ctx, int slave_type, + int module_index, int domain) +{ + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + const struct mtk_device_info **device_info; + const struct mtk_device_num *ndevices; + int sys_index, ctrl_index, vio_index; + struct arm_smccc_res res; + u32 ret, apc_set_index; + + ndevices = devapc_ctx->soc->ndevices; + + if (slave_type >= slave_type_num || + module_index >= ndevices[slave_type].vio_slave_num) { + pr_err(PFX "%s: param check failed, slave_type:0x%x, module_index:0x%x\n", + __func__, slave_type, module_index); + return 0xFF; + } + + device_info = devapc_ctx->soc->device_info; + + sys_index = device_info[slave_type][module_index].sys_index; + ctrl_index = device_info[slave_type][module_index].ctrl_index; + vio_index = device_info[slave_type][module_index].vio_index; + + if (sys_index == -1 || ctrl_index == -1) + return 0xFF; + + arm_smccc_smc(MTK_SIP_KERNEL_DAPC_PERM_GET, slave_type, sys_index, + domain, ctrl_index, vio_index, 0, 0, &res); + ret = res.a0; + + if (ret == DEAD) { + pr_err(PFX "permission get failed, ret:0x%x\n", ret); + return 0xFF; + } + + apc_set_index = ctrl_index % MOD_NO_IN_1_DEVAPC; + ret = (ret & (0x3 << (apc_set_index * 2))) >> (apc_set_index * 2); + + return (ret & 0x3); +} + +/* + * mtk_devapc_vio_check - check violation shift status is raised or not. + * + * Returns the value of violation shift status reg + */ +static void mtk_devapc_vio_check(struct mtk_devapc_context *devapc_ctx, + int slave_type, int *shift_bit) +{ + struct mtk_devapc_vio_info *vio_info; + u32 vio_shift_sta; + int i; + + vio_info = devapc_ctx->soc->vio_info; + vio_shift_sta = readl(mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_STA, 0)); + + if (!vio_shift_sta) { + pr_info(PFX "violation is triggered before. shift_bit:0x%x\n", + *shift_bit); + + } else if (vio_shift_sta & (0x1UL << *shift_bit)) { + pr_debug(PFX "vio_shift_sta:0x%x is matched with shift_bit:%d\n", + vio_shift_sta, *shift_bit); + + } else { + pr_info(PFX "vio_shift_sta:0x%x is not matched with shift_bit:%d\n", + vio_shift_sta, *shift_bit); + + for (i = 0; i < MOD_NO_IN_1_DEVAPC * 2; i++) { + if (vio_shift_sta & (0x1 << i)) { + *shift_bit = i; + break; + } + } + } + + vio_info->shift_sta_bit = *shift_bit; +} + +static void devapc_extract_vio_dbg(struct mtk_devapc_context *devapc_ctx, + int slave_type) +{ + void __iomem *vio_dbg0_reg, *vio_dbg1_reg, *vio_dbg2_reg; + const struct mtk_infra_vio_dbg_desc *vio_dbgs; + struct mtk_devapc_vio_info *vio_info; + u32 dbg0; + + vio_dbg0_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_DBG0, 0); + vio_dbg1_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_DBG1, 0); + vio_dbg2_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_DBG2, 0); + + vio_dbgs = devapc_ctx->soc->vio_dbgs; + vio_info = devapc_ctx->soc->vio_info; + + /* Extract violation information */ + dbg0 = readl(vio_dbg0_reg); + vio_info->master_id = readl(vio_dbg1_reg); + vio_info->vio_addr = readl(vio_dbg2_reg); + + vio_info->domain_id = (dbg0 & vio_dbgs->vio_dbg_dmnid) + >> vio_dbgs->vio_dbg_dmnid_start_bit; + vio_info->write = ((dbg0 & vio_dbgs->vio_dbg_w_vio) + >> vio_dbgs->vio_dbg_w_vio_start_bit) == 1; + vio_info->read = ((dbg0 & vio_dbgs->vio_dbg_r_vio) + >> vio_dbgs->vio_dbg_r_vio_start_bit) == 1; + vio_info->vio_addr_high = (dbg0 & vio_dbgs->vio_addr_high) + >> vio_dbgs->vio_addr_high_start_bit; + + devapc_vio_info_print(devapc_ctx); +} + +/* + * mtk_devapc_dump_vio_dbg - shift & dump the violation debug information. + */ +static bool mtk_devapc_dump_vio_dbg(struct mtk_devapc_context *devapc_ctx, + int slave_type, int *vio_idx, int *index) +{ + const struct mtk_device_info **device_info; + const struct mtk_device_num *ndevices; + void __iomem *pd_vio_shift_sta_reg; + u32 shift_bit; + int i; + + if (!vio_idx) + return NULL; + + device_info = devapc_ctx->soc->device_info; + ndevices = devapc_ctx->soc->ndevices; + + pd_vio_shift_sta_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_STA, 0); + + for (i = 0; i < ndevices[slave_type].vio_slave_num; i++) { + *vio_idx = device_info[slave_type][i].vio_index; + + if (check_vio_mask(devapc_ctx, slave_type, *vio_idx)) + continue; + + if (check_vio_status(devapc_ctx, slave_type, *vio_idx) != + VIOLATION_TRIGGERED) + continue; + + shift_bit = devapc_ctx->soc->shift_group_get(slave_type, + *vio_idx); + + mtk_devapc_vio_check(devapc_ctx, slave_type, &shift_bit); + + if (!sync_vio_dbg(devapc_ctx, slave_type, shift_bit)) + continue; + + devapc_extract_vio_dbg(devapc_ctx, slave_type); + *index = i; + + return true; + } + + return false; +} + +/* + * start_devapc - initialize devapc status and start receiving interrupt + * while devapc violation is triggered. + */ +static void start_devapc(struct mtk_devapc_context *devapc_ctx) +{ + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + const struct mtk_device_info **device_info; + const struct mtk_device_num *ndevices; + void __iomem *pd_vio_shift_sta_reg; + void __iomem *pd_apc_con_reg; + int slave_type, i, vio_idx, index; + u32 vio_shift_sta; + + ndevices = devapc_ctx->soc->ndevices; + + device_info = devapc_ctx->soc->device_info; + + for (slave_type = 0; slave_type < slave_type_num; slave_type++) { + pd_apc_con_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + APC_CON, 0); + pd_vio_shift_sta_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_STA, 0); + + if (!pd_apc_con_reg || !pd_vio_shift_sta_reg || !device_info) + return; + + /* Clear DEVAPC violation status */ + writel(BIT(31), pd_apc_con_reg); + + /* Clear violation shift status */ + vio_shift_sta = readl(pd_vio_shift_sta_reg); + if (vio_shift_sta) + writel(vio_shift_sta, pd_vio_shift_sta_reg); + + /* Clear type 2 violation status */ + check_type2_vio_status(devapc_ctx, slave_type, &vio_idx, &i); + + /* Clear violation status */ + for (i = 0; i < ndevices[slave_type].vio_slave_num; i++) { + vio_idx = device_info[slave_type][i].vio_index; + if ((check_vio_status(devapc_ctx, slave_type, vio_idx) + == VIOLATION_TRIGGERED) && + clear_vio_status(devapc_ctx, slave_type, + vio_idx)) { + pr_warn(PFX "Clear vio status failed, slave_type:0x%x, vio_index:0x%x\n", + slave_type, vio_idx); + + index = i; + mtk_devapc_dump_vio_dbg(devapc_ctx, slave_type, + &vio_idx, &index); + i = index - 1; + } + + mask_module_irq(devapc_ctx, slave_type, vio_idx, false); + } + } +} + +static DEFINE_SPINLOCK(devapc_lock); + +/* + * devapc_violation_irq - the devapc Interrupt Service Routine (ISR) will dump + * violation information including which master violates + * access slave. + */ +static irqreturn_t devapc_violation_irq(int irq_number, + struct mtk_devapc_context *devapc_ctx) +{ + u32 slave_type_num = devapc_ctx->soc->slave_type_num; + const struct mtk_device_info **device_info; + struct mtk_devapc_vio_info *vio_info; + int slave_type, vio_idx, index; + const char *vio_master; + unsigned long flags; + u8 perm; + + spin_lock_irqsave(&devapc_lock, flags); + + device_info = devapc_ctx->soc->device_info; + vio_info = devapc_ctx->soc->vio_info; + vio_idx = -1; + index = -1; + + /* There are multiple DEVAPC_PD */ + for (slave_type = 0; slave_type < slave_type_num; slave_type++) { + if (!check_type2_vio_status(devapc_ctx, slave_type, &vio_idx, + &index)) + if (!mtk_devapc_dump_vio_dbg(devapc_ctx, slave_type, + &vio_idx, &index)) + continue; + + /* Ensure that violation info are written before + * further operations + */ + smp_mb(); + + mask_module_irq(devapc_ctx, slave_type, vio_idx, true); + + clear_vio_status(devapc_ctx, slave_type, vio_idx); + + perm = get_permission(devapc_ctx, slave_type, index, + vio_info->domain_id); + + vio_master = devapc_ctx->soc->master_get + (vio_info->master_id, + vio_info->vio_addr, + slave_type, + vio_info->shift_sta_bit, + vio_info->domain_id); + + if (!vio_master) + vio_master = "UNKNOWN_MASTER"; + + pr_info(PFX "Violation - slave_type:0x%x, sys_index:0x%x, ctrl_index:0x%x, vio_index:0x%x\n", + slave_type, + device_info[slave_type][index].sys_index, + device_info[slave_type][index].ctrl_index, + device_info[slave_type][index].vio_index); + + pr_info(PFX "Violation Master: %s\n", vio_master); + + devapc_vio_reason(perm); + + mask_module_irq(devapc_ctx, slave_type, vio_idx, false); + } + + spin_unlock_irqrestore(&devapc_lock, flags); + return IRQ_HANDLED; +} + +int mtk_devapc_probe(struct platform_device *pdev, struct mtk_devapc_soc *soc) +{ + struct device_node *node = pdev->dev.of_node; + struct mtk_devapc_context *devapc_ctx; + u32 slave_type_num; + int slave_type; + int ret; + + if (IS_ERR(node)) + return -ENODEV; + + devapc_ctx = devm_kzalloc(&pdev->dev, sizeof(struct mtk_devapc_context), + GFP_KERNEL); + if (!devapc_ctx) + return -ENOMEM; + + devapc_ctx->soc = soc; + slave_type_num = devapc_ctx->soc->slave_type_num; + + for (slave_type = 0; slave_type < slave_type_num; slave_type++) { + devapc_ctx->devapc_pd_base[slave_type] = + of_iomap(node, slave_type); + if (!devapc_ctx->devapc_pd_base[slave_type]) + return -EINVAL; + } + + devapc_ctx->infracfg_base = of_iomap(node, slave_type_num + 1); + if (!devapc_ctx->infracfg_base) + return -EINVAL; + + devapc_ctx->devapc_irq = irq_of_parse_and_map(node, 0); + if (!devapc_ctx->devapc_irq) + return -EINVAL; + + /* CCF (Common Clock Framework) */ + devapc_ctx->devapc_infra_clk = devm_clk_get(&pdev->dev, + "devapc-infra-clock"); + + if (IS_ERR(devapc_ctx->devapc_infra_clk)) + return -EINVAL; + + if (clk_prepare_enable(devapc_ctx->devapc_infra_clk)) + return -EINVAL; + + start_devapc(devapc_ctx); + + ret = devm_request_irq(&pdev->dev, devapc_ctx->devapc_irq, + (irq_handler_t)devapc_violation_irq, + IRQF_TRIGGER_NONE, "devapc", devapc_ctx); + if (ret) + return ret; + + return 0; +} + +int mtk_devapc_remove(struct platform_device *dev) +{ + return 0; +} + +MODULE_DESCRIPTION("Mediatek Device APC Driver"); +MODULE_AUTHOR("Neal Liu "); +MODULE_LICENSE("GPL"); diff --git a/drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.h b/drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.h new file mode 100644 index 0000000..1e58a3e --- /dev/null +++ b/drivers/soc/mediatek/devapc/devapc-mtk-multi-ao.h @@ -0,0 +1,182 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 MediaTek Inc. + */ + +#ifndef __DEVAPC_MTK_MULTI_AO_H__ +#define __DEVAPC_MTK_MULTI_AO_H__ + +#include +#include + +/****************************************************************************** + * VARIABLE DEFINATION + ******************************************************************************/ +#define MOD_NO_IN_1_DEVAPC 16 +#define VIOLATION_TRIGGERED 1 +#define VIOLATION_MASKED 1 +#define DEAD 0xdeadbeaf +#define PFX "[DEVAPC]: " +#define SLAVE_TYPE_NUM_MAX 5 + +#define devapc_log(p, s, fmt, args...) \ + do { \ + typeof(p) (_p) = (p); \ + ((_p) += scnprintf(_p, sizeof(s) - strlen(s), fmt, ##args)); \ + } while (0) + +#define UNUSED(x) (void)(x) + +/****************************************************************************** + * DATA STRUCTURE & FUNCTION DEFINATION + ******************************************************************************/ +enum DEVAPC_PD_REG_TYPE { + VIO_MASK = 0, + VIO_STA, + VIO_DBG0, + VIO_DBG1, + VIO_DBG2, + APC_CON, + VIO_SHIFT_STA, + VIO_SHIFT_SEL, + VIO_SHIFT_CON, + PD_REG_TYPE_NUM, +}; + +enum DEVAPC_UT_CMD { + DEVAPC_UT_DAPC_VIO = 1, + DEVAPC_UT_SRAM_VIO, +}; + +enum DEVAPC_DOM_ID { + DOMAIN_0 = 0, + DOMAIN_1, + DOMAIN_2, + DOMAIN_3, + DOMAIN_4, + DOMAIN_5, + DOMAIN_6, + DOMAIN_7, + DOMAIN_8, + DOMAIN_9, + DOMAIN_10, + DOMAIN_11, + DOMAIN_12, + DOMAIN_13, + DOMAIN_14, + DOMAIN_15, + DOMAIN_OTHERS, +}; + +enum SRAMROM_VIO { + ROM_VIOLATION = 0, + SRAM_VIOLATION, +}; + +enum DEVAPC_PERM_TYPE { + NO_PROTECTION = 0, + SEC_RW_ONLY, + SEC_RW_NS_R, + FORBIDDEN, + PERM_TYPE_NUM, +}; + +struct mtk_devapc_dbg_status { + bool enable_ut; + bool enable_dapc; /* dump APC */ +}; + +struct mtk_device_info { + int sys_index; + int ctrl_index; + int vio_index; +}; + +struct mtk_device_num { + int slave_type; + u32 vio_slave_num; +}; + +struct mtk_devapc_vio_info { + bool read; + bool write; + u32 vio_addr; + u32 vio_addr_high; + u32 master_id; + u32 domain_id; + int *vio_mask_sta_num; + int sramrom_slv_type; + int sramrom_vio_idx; + int mm2nd_slv_type; + int mdp_vio_idx; + int disp2_vio_idx; + int mmsys_vio_idx; + int shift_sta_bit; +}; + +struct mtk_infra_vio_dbg_desc { + u32 vio_dbg_mstid; + u8 vio_dbg_mstid_start_bit; + u32 vio_dbg_dmnid; + u8 vio_dbg_dmnid_start_bit; + u32 vio_dbg_w_vio; + u8 vio_dbg_w_vio_start_bit; + u32 vio_dbg_r_vio; + u8 vio_dbg_r_vio_start_bit; + u32 vio_addr_high; + u8 vio_addr_high_start_bit; +}; + +struct mtk_sramrom_sec_vio_desc { + u32 vio_id_mask; + u8 vio_id_shift; + u32 vio_domain_mask; + u8 vio_domain_shift; + u32 vio_rw_mask; + u8 vio_rw_shift; +}; + +struct mtk_devapc_pd_desc { + u32 pd_vio_mask_offset; + u32 pd_vio_sta_offset; + u32 pd_vio_dbg0_offset; + u32 pd_vio_dbg1_offset; + u32 pd_apc_con_offset; + u32 pd_shift_sta_offset; + u32 pd_shift_sel_offset; + u32 pd_shift_con_offset; +}; + +struct mtk_devapc_soc { + struct mtk_devapc_dbg_status *dbg_stat; + const char * const *slave_type_arr; + u32 slave_type_num; + const struct mtk_device_info *device_info[SLAVE_TYPE_NUM_MAX]; + const struct mtk_device_num *ndevices; + struct mtk_devapc_vio_info *vio_info; + const struct mtk_infra_vio_dbg_desc *vio_dbgs; + const struct mtk_sramrom_sec_vio_desc *sramrom_sec_vios; + const u32 *devapc_pds; + + /* platform specific operations */ + const char* (*master_get)(u32 bus_id, u32 vio_addr, + int slave_type, int shift_sta_bit, + int domain); + void (*mm2nd_vio_handler)(void __iomem *infracfg, + struct mtk_devapc_vio_info *vio_info, + bool mdp_vio, bool disp2_vio, bool mmsys_vio); + u32 (*shift_group_get)(int slave_type, u32 vio_index); +}; + +struct mtk_devapc_context { + struct clk *devapc_infra_clk; + u32 devapc_irq; + void __iomem *devapc_pd_base[4]; + void __iomem *infracfg_base; + struct mtk_devapc_soc *soc; +}; + +int mtk_devapc_probe(struct platform_device *pdev, struct mtk_devapc_soc *soc); +int mtk_devapc_remove(struct platform_device *dev); + +#endif /* __DEVAPC_MTK_MULTI_AO_H__ */ -- 1.7.9.5 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel